I am trying to use the Adafruit PCA9546A with two Adafruit SHT41 Temperature/Humidity sensors. I am using a ARDUINO PRO MICRO.
The following code compiles and runs but the temperature and humidity are not displayed. The code seems to hang up when sht4_1.getEvent(&humidity1,&temp1) is called(line 48. I think the problem is that the Adafruit_SHT4x.h library does not allow for the calling for tempetature and humidity separately but I am nor really sure.
Any help getting it to work will be appreciated.
// 1/9?2024 TEST SKETCH FOR SHT41 MULTIPLEXER
#include <Wire.h> //used for i2c bus, external EEPROM,ADAFRUIT SHT31-D
#include "Adafruit_SHT4x.h" //added for I2C multipleser ADAFRUIT PART #5664
#define TCAADDR 0x70 //added for I2C multipleser ADAFRUIT PART #5664
Adafruit_SHT4x sht4_1 = Adafruit_SHT4x(); //added for I2C multipleser ADAFRUIT PART #5664 in channel 0
Adafruit_SHT4x sht4_2 = Adafruit_SHT4x(); //added for I2C multipleser ADAFRUIT PART #5664 in channel 1
void setup()
{
Serial.begin(9600);
delay(10000);
Serial.println("SHT41_multiplexer_for_POND");
Wire.begin();
Serial.println("HERE IN SETUP");
// initalize sensors
tcaselect(0);
sht4_1.begin(0x44);
//if (!sht4_1.begin(0x44))
//{
// Serial.println("Could not find Sht4_1");
//}
tcaselect(1);
sht4_2.begin(0x44);
//if (!sht4_2.begin(0x44))
//{
// Serial.println("Could not find Sht4_2");
//}
Serial.println("STARTING_2");
}
void loop()
{
sensors_event_t humidity1, temp1; //added for I2C multipleser ADAFRUIT PART #5664
sensors_event_t humidity2, temp2; //added for I2C multipleser ADAFRUIT PART #5664
tcaselect(0);
Serial.println("HERE AT SENTENCE_2");
delay(10);
sht4_1.getEvent(&humidity1, &temp1);// added for I2C multipleser ADAFRUIT PART #5664, populate temp and humidity objects with fresh data
Serial.println("HERE AT SENTENCE_2-2");
tcaselect(1);
Serial.println("HERE AT SENTENCE_2-3");
sht4_2.getEvent(&humidity2, &temp2);// added for I2C multipleser ADAFRUIT PART #5664, populate temp and humidity objects with fresh data
Serial.print("temp_f1 = ");Serial.println(temp1.temperature);
Serial.print("humidity1 = ");Serial.println(humidity1.relative_humidity);
Serial.print("temp_f2 = ");Serial.println(temp2.temperature);
Serial.print("humidity2 = ");Serial.println(humidity2.relative_humidity);
}
void tcaselect(uint8_t i)
{
Serial.println("HERE AT tcaselect");
if(i>4) return;
Wire.beginTransmission(TCAADDR);
Serial.println("HERE AT tcaselect #2");
Wire.write(1<<i);
Serial.println("HERE AT tcaselect #3");
Wire.endTransmission();
Serial.println("HERE AT tcaselect #4");
//return;
}
At first glance, I see no problem with the components, the library and your sketch.
The only thing that stands out, is that the "Pro Micro" is not a board made by Arduino and you are missing a delay(1000); at the end in the loop() function. It runs too fast now.
I think that we have to look further.
Can you show a photo of your I2C bus, with everything that is connected to it and with all the wires of the I2C bus.
The promicro is a SPARKFUN creation but everthing says its the same. I tried using a genuine ARDUINO MICRO but I ran into another problem; when I connected and i2c device to the MICRO, the usb port would disconnect; any ideas, I tried two different MICROS and different i2c devices.
.
In the picture the blue wire connects to pin 2(SDA) and the yellow wire connects to pin 3 (SCL)
There might be something wrong with the USB cable or the USB connector. There might also be a shortcut somewhere. Can you try another USB cable ?
Can you untwist the wires wires to the sensors ? The I2C bus can not deal with crosstalk between SDA and SCL, keep SDA and SCL away from each other. Please confirm that you have untwisted those wires.
You use the 5V from the Pro Micro.
How is the PCA9546A board set on the back side ? Is VOUT connected to V+ ?
The SDA and SCL have still to go through a level shifter, even if that is useless.
Then you have 5V on the wires to the sensors with a 5V I2C bus.
The SHT41 modules have a voltage regulator and level shifters for the I2C bus.
Do you have a multimeter ? Can you run an sketch with only Wire.begin() in setup() and a empty loop() and check all the voltage levels. The sensors should get 5V and the SDA and SCL on all the wires should be near 5V.
What did work before ? Have you connected a single SHT41 to the Pro Micro board and nothing else ? Find a I2C Scanner sketch, connect one SHT41 sensor, then the other one, then the PCA9546A, then a PCA9546A + SHT41 and so on.
I would like to solve the problem with the Arduino Micro as well. It might be the same problem.
If everything works, but not this combination, then you can remove the level shifters on the PCA9546A module.
Koepel;
Thanks for you guidance.
I found that the multiplexer was faulty and after replacing that the ARDUINO MICO worked fine.
I revised the code and I know know that the SHT41 sensors are recognized and all hardware is working. but the code is not.
The monitor is giving me the following:
SHT41_multiplexer_for_POND
HERE IN SETUP
HERE AT tcaselect
HERE AT SETUP #2
HERE AT SETUP #3
Found I2C 0x0
Found I2C 0x44
HERE AT tcaselect
HERE AT SETUP #4
HERE AT SETUP #5
Found I2C 0x0
Found I2C 0x44
STARTING_2
HERE AT tcaselect
HERE AT SENTENCE_2
HERE AT SENTENCE_2-2
I suspect that there is an error in my code
sht4_2.getEvent(&humidity2, &temp2);
but I'm stuck on how to fix it.
Your help appreciated.
Bill
// 1/9?2024 TEST SKETCH FOR SHT41 MULTUPLEXER
#include <Wire.h> //used for i2c bus, external EEPROM,ADAFRUIT SHT31-D
#include "Adafruit_SHT4x.h" //added for I2C multipleser ADAFRUIT PART #5664
#define TCAADDR 0x70 //added for I2C multipleser ADAFRUIT PART #5664
Adafruit_SHT4x sht4_1 = Adafruit_SHT4x(); //added for I2C multipleser ADAFRUIT PART #5664 in channel 0
Adafruit_SHT4x sht4_2 = Adafruit_SHT4x(); //added for I2C multipleser ADAFRUIT PART #5664 in channel 1
void setup()
{
Serial.begin(9600);
delay(2000);
Serial.println("SHT41_multiplexer_for_POND");
Wire.begin();
Serial.println("HERE IN SETUP");
tcaselect(0);
//sht4_1.begin(0x44);
Serial.println("HERE AT SETUP #2");
//if (!sht4_1.begin(0x44))
//{
// Serial.println("Could not find Sht4_1");
//}
Serial.println("HERE AT SETUP #3");
for (uint8_t addr = 0; addr<=127; addr++)
{
if (addr == TCAADDR) continue;
Wire.beginTransmission(addr);
if (!Wire.endTransmission())
{
Serial.print("Found I2C 0x"); Serial.println(addr,HEX);
}
}
tcaselect(1);
//sht4_1.begin(0x44);
Serial.println("HERE AT SETUP #4");
//if (!sht4_1.begin(0x44))
//{
// Serial.println("Could not find Sht4_1");
//}
Serial.println("HERE AT SETUP #5");
for (uint8_t addr = 0; addr<=127; addr++)
{
if (addr == TCAADDR) continue;
Wire.beginTransmission(addr);
if (!Wire.endTransmission())
{
Serial.print("Found I2C 0x"); Serial.println(addr,HEX);
}
}
Serial.println("STARTING_2");
}
void loop()
{
tcaselect(0);
Serial.println("HERE AT SENTENCE_2");
sensors_event_t humidity1, temp1; //added for I2C multipleser ADAFRUIT PART #5664
delay(10);
Serial.println("HERE AT SENTENCE_2-2");
sht4_1.getEvent(&humidity1, &temp1);// added for I2C multipleser ADAFRUIT PART #5664, populate temp and humidity objects with fresh data
Serial.println("HERE AT SENTENCE_2-3");
tcaselect(1);
sensors_event_t humidity2, temp2; //added for I2C multipleser ADAFRUIT PART #5664
sht4_2.getEvent(&humidity2, &temp2);// added for I2C multipleser ADAFRUIT PART #5664, populate temp and humidity objects with fresh data
Serial.print("temp_f1 = ");Serial.println(temp1.temperature);
Serial.print("humidity1 = ");Serial.println(humidity1.relative_humidity);
Serial.print("temp_f2 = ");Serial.println(temp2.temperature);
Serial.print("humidity2 = ");Serial.println(humidity2.relative_humidity);
delay(1000);
}
void tcaselect(uint8_t i)
{
Serial.println("HERE AT tcaselect");
if(i>4) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1<<i);
Wire.endTransmission();
}
You have to call the .begin() functions for both sensors.
// Initialize the object for the sensors,
// and check if the sensor is found on the I2C bus.
if (sht4_1.begin()) // initialize the first sensor
Serial.println("SH41 1 found");
if (sht4_2.begin()) // initialize the second sensor
Serial.println("SH41 2 found");
I prefer to put that information in variables and then decide what to do according those variables:
bool sht4_1_found = sht4_1.begin();
bool sht4_2_found = sht4_2.begin();
if(!sht4_1_found)
Serial.println("Where is the first SHT41 ?");
if(!sht4_2_found)
Serial.println("Where is the second SHT41 ?");
If one sensor is not working, then you might continue the sketch and read only the sensor that is found, using that boolean variable.
Tips:
Use the "F()" macro:
Serial.println("SHT41_multiplexer_for_POND"); // uses SRAM
Serial.println(F("SHT41_multiplexer_for_POND")); // uses no SRAM
The Wire.endTransmisson() returns an integer number with an error code. It is weird to apply a boolean 'not' on that. This code is nicer:
if (Wire.endTransmission() == 0) // something found ?
I often use Serial.println('A'); (with the 'A' from A to Z) in the sketch to tell where the sketch is. It is shorter to type.
While fiddling around I used another approach; use the ADAFRUIT SHT41(Part#5776, i2c address 0x44) and for the second sensor use a ADAFRUIT SHTC3(Part#4636, i2c address 70). The both have the QWIiC packaging and work well.
Thanks again, I really appreciate it.