Problem communicating with DFRobot light sensor SEN0390

This light sensor works fine by itself. But when another I2C device is included in an Arduino circuit, like an OLED or LCD to display lux values, everything stops working. This isn’t the first time I’ve had this kind of problem where I2C devices that are SUPPOSED to work together on the same circuit, stop working when some I2C devices are hooked up in the circuit. Can anyone explain this problem to me and how to fix it? Thank you.

1 Like

Hello @brooksdr and welcome to the RobotShop forum,

Each device on an I2C bus must have a unique address, so you need to set a different address for each device to avoid collisions. On the DFRobot Wiki they state that the I2C address of the SEN0390 sensor cannot be revised so you may have to change the I2C address on your display or any other device you want to use on the same circuit.

1 Like

There is no address conflicts with these sensors (checked with a sketch that reads the I2C addresses). It is VERY rare to find address conflicts and I have NEVER found a conflict between a sensor and a display device – rarely, different but “related” sensors from the same manufacturer will have the same hardware address. Those problems can be fixed with an I2C multiplexer board, but even that won’t solve this problem! This problem is not with address conflicts, but apparently with the I2C implementation on the SEN0390 itself. I have had this same problem with other I2C devices from “offshore” sources.

There is no address conflicts with these sensors (checked with a sketch that reads the I2C addresses)
This problem is not with address conflicts, but apparently with the I2C implementation on the SEN0390 itself.

It seems like you are onto something! I did some research and you are not the only one who has had this problem check this post:

In which a user proposed this possible solution:

1. Typos in the DFRobot Library
I too had another look at the DFRobot library for the Ambient Light Sensor (GitHub - DFRobot/DFRobot_B_LUX_V30B) and noticed a couple of errors in their code.In that library in DFRobot_B_LUX_V30B.cpp they seem to very manually toggle or bit bang the I2C protocol onto the pins. Seems odd but anyway, in two of the functions they incorrectly reference the pins, they use “SDA” instead of “_SDA”, so they are messing with pins referenced outside their library. So to fix that you need to change any instance of “SDA” in their library to “_SDA”.This alone did not fix the issue, see item 2 below.
2. Keep the Ambient Light Sensor on dedicated SDA/SCL pins
The DFRobot library has the ability to let the user specify which pins are used for SDA and SCL (as it seems intent on bit banging the I2C Proto).For example you can tell it to use pin 6 for SCL and pin 5 for SDA with the following (ignore the 13 for now)DFRobot_B_LUX_V30B myLux(13,6,5);If you do that, and wire it there appropriately, then everything works. I can read from the SHT31 and the Ambient light sensor in the same sketch.

Let us know if it works for you!

Geraldinebc15 Resolver II
Right off the top, THANKS! I asked several sources about this problem and you are the only one to provide help for an actual solution. As for the “Typos in the DFRobot Library” solution, I didn’t do anything about that. Maybe it doesn’t matter and maybe DFRobot fixed their library – I don’t know. For my project I wanted to use the light sensor as a “lux meter” with an OLED display to show the values. With both devices connected to A4 and A5, the “standard” SDA/SCL pins, nothing worked. But when I put the SEN0390 light sensor on dedicated digital pins as indicated in solution 2 – SCL=6 and SDA=5 – and left the OLED on pins A4 and A5, everything works as it should.
I would say there is a good chance that this fix for the I2C connection will work when using the SEN0390 with other I2C devices, too, as the problem seems to be solved by removing the SEN0390 from the “standard” SCL/SDA pins. I suppose it’s possible that some other “problem” I2C devices (from DFRobot?) would work together if they were assigned to different SCL/SDA pin pairs. If anybody has thoughts about this, please let me know.
Here’s the code for this project. Note that I used an I2C OLED from IZOKEE. There are several of these small OLEDs available online from different sources. They all look pretty much the same, but the device specification (the line starting U8X*_SSD1306…) may be different for OLEDs from different sources. The U8x8lib library is a “character only” subset of the larger graphics-inclusive library for these devices, widely available online.
Finally, note that I converted the lux value to an integer because I intended to use the lux meter outdoors in bright light, where it can exceed 100,000 lux in midday full sun. Default for the println() function is 2 digits to right of the decimal point, but even in moderately lit indoor conditions there’s no justification for displaying lux as anything but a rounded off whole number. It’s necessary to clear the display for each trip through the loop so if the lux value falls significantly, say from 4 digits to 3 digits, you need to remove the rightmost digit in the 4 digit lux value before displaying a 3 digit value. I used a 16x16 font rather than a default 8x8 font, which is pretty hard to read even on these very sharp OLED screens.
Please feel free to use the code as you like, although I would appreciate a citation for it.

// LuxMeter.ino, D. Brooks, April 2021
// Displays lux from DFRobot SEN0390 sensor on
// 128x64 px IZOKEE 0.96" OLED.
// Some commented code to read voltage from a battery is
// intended for future use with Adafruit feather 32u4 basic proto board.
// This code was tested with Adafruit Metro Mini (UNO compatible).
#include <Wire.h>
#include <DFRobot_B_LUX_V30B.h>
DFRobot_B_LUX_V30B myLux(13,6,5);
#include "U8x8lib.h"
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); 
//#define VBATPIN A9 // Pick up LiPo voltage from digital pin 9.
const long int delayTime=2000L;
//float batV;
void setup(void) {
  Wire.begin();u8x8.begin();
  myLux.begin(); // Serial.begin(9600); // Just for testing...
}
void loop() {
  u8x8.clear();
  u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);  
  //u8x8.setFont(u8x8_font_chroma48medium8_r);  
  u8x8.setCursor(0,1);
  u8x8.println(" lux=");
  // Read lux data...
  u8x8.println((int)myLux.lightStrengthLux());  
  //batV=3.3*(analogRead(VBATPIN)*2)/1023; // See Adafruit docs.
  //u8x8.print(" Vbat = ");u8x8.println(batV);
  delay(delayTime);
}

Right off the top, THANKS! I asked several sources about this problem and you are the only one to provide help for an actual solution.

You’re welcome, I’m glad I could help :grin:

I would say there is a good chance that this fix for the I2C connection will work when using the SEN0390 with other I2C devices, too, as the problem seems to be solved by removing the SEN0390 from the “standard” SCL/SDA pins. I suppose it’s possible that some other “problem” I2C devices (from DFRobot?) would work together if they were assigned to different SCL/SDA pin pairs. If anybody has thoughts about this, please let me know.

Most likely yes, it would be a matter of testing it.

Here’s the code for this project…

Thanks for sharing your code! And also thanks for notifying us that the solution worked!

Good luck with your project :smiley: