lkoepsel / I2C

Exploring the Pico and multiple I2C interfaces
1 stars 1 forks source link

Simple 2x I2C management ? #1

Open navivfr opened 11 months ago

navivfr commented 11 months ago

hello, No issue, but I would like to contact you about this project. I try to understand what you done, but without any success. My project is based on a RP2040 Zero with Arduino IDE. I have 3 Probes (ATH25 & BME820), and 2 of have the same ID (ATH25). The 2 other devices: a RTC (I2C) and Lora Module RA-02 (SPI). I chose RP2040 because seems to handle 2x I2C Chanels, this to avoid a multiplexer. I search a lot without finding a working solution. Seems you have a solution. Please can you help me ?

lkoepsel commented 11 months ago

I recommend you start here:

Using Arduino on the RP2040: I2C

I also recommend you use the scanner program to continually confirm your hardware matches the software.

navivfr commented 11 months ago

Thx for reply. I did a scanner. all the devices are seen on there proper wire... Still, I watched you code, make a kind of adaptation of what you coded. but the RP2040 seems to crash (uploaded, never start).

navivfr commented 11 months ago
#include <Wire.h>
#include <AHT20.h>

// 2 Temp Sensors
AHT20 aht25_a;
AHT20 aht25_b;

// define all I2C devices with a name
// Use I2C_Scanner to confirm/get information on I2C devices
#define max_I2C 2
enum device {temp_1, temp_2};
struct I2C_device 
{
  unsigned int SDA; // the GP for SDA
  unsigned int SCL; // the GP for SCL
  byte address;     // device address
} ;
struct I2C_device devices[max_I2C];

// init device used to make setup of I2C interface easier
// use same index for init_d and init_Wire
void init_d(unsigned int index, unsigned int SDA, unsigned int SCL, byte address);

// initialize the messages array
void init_m(unsigned int index, unsigned int delay, unsigned int times);

// init_Wire: setup wire interface for each time it is used
// previous Wire interface setup must be closed wire.end()
// Only call init_Wire once each time to setup, 
// even if there are >1 devices on the I2C interface
void init_Wire(unsigned int index, TwoWire &Wire);

// show temp 1
void showTemp_1();

// show temp 2
void showTemp_2();

// status: delay for n seconds, blinking 2n times per second
void status(unsigned int msg);

void setup() {
    init_d(temp_1, 0, 1, 0x38);   // IR temp sensor on Wire
    init_d(temp_2, 14, 15, 0x38);   // IR temp sensor on Wire
    Serial.begin(9600);
}

void loop() 
{
    showTemp_1();
    delay(1000);
    showTemp_2();
}

void init_d(unsigned int index, unsigned int SDA,
             unsigned int SCL, byte address)
{
    devices[index].SDA = SDA;
    devices[index].SCL = SCL;
    devices[index].address = address;
}

void init_Wire(unsigned int index, TwoWire &Wire)
{
    Wire.setSDA(devices[index].SDA);
    Wire.setSCL(devices[index].SCL);
    Wire.begin();

}

void showTemp_1()
{
    aht25_a.begin();
    //Get the new temperature and humidity value
    float temperature = aht25_a.getTemperature();
    float humidity = aht25_a.getHumidity();
    //Print the results
    Serial.print("A Temperature: ");
    Serial.print(temperature, 2);
    Serial.println(" C\t");
    Serial.print("A Humidity: ");
    Serial.print(humidity, 2);
    Serial.println("% RH");
    Wire.end();
}

void showTemp_2()
{
    init_Wire(temp_2, Wire1);
    aht25_b.begin();
    //Get the new temperature and humidity value
    float temperature = aht25_b.getTemperature();
    float humidity = aht25_b.getHumidity();
    //Print the results
    Serial.print("B Temperature: ");
    Serial.print(temperature, 2);
    Serial.println(" C\t");
    Serial.print("B Humidity: ");
    Serial.print(humidity, 2);
    Serial.println("% RH");
    Wire.end();
    Wire1.end();
}
lkoepsel commented 11 months ago

Yeah...this is where it gets tough to debug from afar... :)

  1. I would debug using print statements and starting right after Serial.begin in the setup loop. Print to confirm setup is happening then print to confirm the program is entering loop(). And so on...

  2. I wasn't using a serial interface, which is why I used init_m to setup an led to blink. It doesn't appear you are using this method so I would remove init_m().

  3. It also appears the program is missing a init_Wire() at the beginning of showTemp_1(). Make sure it has one.

navivfr commented 11 months ago

Finaly I changed the library for the AHT, since the one I used doesn't support Twowire ! I switched to the Ardafruit AHTXO library.

After declaring wire and wire1 GPIO's, just need to do this : aht.begin() for the 1st Sensor aht2.begin(&Wire1, 0, AHT25_ADDRESS) for the second. And work like a charm.

THX A LOT FOR YOUR TIME AND SUPPORT.

lkoepsel commented 11 months ago

That's great!

Happy to help and glad you reached out!