Malfunzionamenti multiplexer I2C TCA9548A

Ragazzacci, prima di tutto ciao a tutti, è una vita che non partecipo più al forum, ma ho poco tempo da dedicare alla programmazione e per fortuna alle volte escono progetti nuovi che sono un buon motivo per impicciarsi il cervello e quindi vi pongo il mio problema:

Il sistema deve leggere n sensori e scriverne i valori su 2 display i2c che hanno lo stesso indirizzo, quindi per risolvere il problema ho preso il suddetto multiplexer con il quale pensavo di aver risolto il problema, ma con il tempo uno dei 2 display stentava ad avviarsi

ecco il codice base:

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>

//Costante pin lettura sensori
const int sens1 = A0;  // Analog input pin that the potentiometer is attached to

//Variabili semplici
int variabile1 = 0;

//Contatori per delay
unsigned long previousMillis1 = 0;
unsigned long interval = 150;
extern unsigned long timer0_millis;

//Set display I2C
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0); //U8G2_R0 rotazione 0°, U8G2_R1 rotazione 90°,U8G2_R2 rotazione 180°,U8G2_R3 rotazione 270°, U8G2_MIRROR specchio,

void TCA9548A(uint8_t bus) {

  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
}

void setup() {

  u8g2.begin();

  Serial.begin(9600);

}

void loop() {

  Sensors();
  Display1();
  Display2();
}

void Sensors() {

  // Assegnazione sennsori
  if (millis() - previousMillis1 > 15) {

    previousMillis1 = millis();

    variabile1 = map(analogRead(sens1), 0, 1023, 0, 255);
  }
}


void Display1() {

  if (millis() - previousMillis1 > interval) {

    previousMillis1 = millis();

    //Scrittura valori display1
    TCA9548A(0); // select I2C multiplexer 0x70 bus port

    u8g2.begin();
    u8g2.clearBuffer();				        	  // clear the internal memory
    u8g2.setContrast(255);               //Regola contrasto display
    /*
      // Colore 0 spento, 1 acceso, 2 differenziato: 0 (clear pixel value in the display RAM), 1 (set pixel value) or 2 (XOR mode)
      u8g2.setDrawColor(1);                 //Imposta colore sfondo bianco
      u8g2.drawBox(0, 0, 128, 32);          //Imposta area
      u8g2.setDrawColor(0);                 //Imposta colore scritte
    */
    u8g2.setFont(u8g2_font_ncenB18_tf);
    //u8g2.setFontDirection(0);            //Rotazione font 0=0°, 1=90°, 2=180°, 3=270°
    u8g2.setCursor(0, 18);                 //Imposta posizione inizio
    u8g2.print(variabile1, 0);                 //Scrivi valore variabile
    u8g2.setFont(u8g2_font_profont12_mf);
    u8g2.drawStr(0, 30, "Display 1");
    u8g2.sendBuffer();					            // transfer internal memory to the display
  }

}

void Display2() {

  if (millis() - previousMillis2 > interval) {

    previousMillis2 = millis();

    //Scrittura valori display1
    TCA9548A(1); // select I2C multiplexer 0x70 bus port

    //u8g2.begin();
    u8g2.clearBuffer();                    // clear the internal memory
    u8g2.setContrast(255);               //Regola contrasto display
    u8g2.setFont(u8g2_font_ncenB18_tf);
    //u8g2.setFontDirection(2);            //Rotazione font 0=0°, 1=90°, 2=180°, 3=270°
    u8g2.setCursor(0, 18);                 //Imposta posizione inizio
    u8g2.print(variabile1, 0);                 //Scrivi valore variabile
    u8g2.setFont(u8g2_font_profont12_mf);
    u8g2.drawStr(0, 30, "Display2");
    
    u8g2.sendBuffer();                     // transfer internal memory to the display
    //delay(300);

  }
}

dopo qualche ora di prove, al momento in cui ho tolto alimentazione il display della porta 0 multiplexer partiva dopo qualche reset, quindi ho pensato che il display non ricevesse in tempo il comando u8g2.begin(); quindi l’ho aggiunto al loop, ed in effetti si sono avviati entrambi ma la cosa comportava un naturale reset continuo dei suddetti, quindi ho pensato di fare un mini loop nel setup ed ho messo questo:

void setup() {

  delay(100);

  TCA9548A(0); // select I2C multiplexer 0x70 bus port
  u8g2.begin();
  delay(100);
  TCA9548A(1); // select I2C multiplexer 0x70 bus port
  u8g2.begin();
  delay(100);
  TCA9548A(0); // select I2C multiplexer 0x70 bus port
  u8g2.begin();
  delay(100);
  TCA9548A(1); // select I2C multiplexer 0x70 bus port
  u8g2.begin();

  Serial.begin(9600);

}

ed ho avuto di nuovo riscontro positivo, ma solo per qualche ora, adesso mi si avvia in ogni modo possibile solo il display porta 1, ovviamente ho provato tutti i componenti e singolarmente vanno bene, ho pensato di testare il multiplexer con questo codice:

void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCA9548A);
  Wire.write(1 << i);
  Wire.endTransmission();  
}


// standard Arduino setup()
void setup()
{
    
}

void testTCA(){
  while (!Serial);
    delay(1000);

    Wire.begin();
    
    Serial.begin(9600);
    Serial.println("\nTCAScanner ready!");
    
    for (uint8_t t=0; t<8; t++) {
      tcaselect(t);
      Serial.print("TCA Port #"); Serial.println(t);

      for (uint8_t addr = 0; addr<=127; addr++) {
        if (addr == TCA9548A) continue;
      
        uint8_t data;
        if (! twi_writeTo(addr, &data, 0, 1, 1)) {
           Serial.print("Found I2C 0x");  Serial.println(addr,HEX);
        }
      }
    }
    Serial.println("\ndone");
}


void loop() 
{
  testTCA();
  delay(1500);
}

trovato in rete ma funziona, mi da l’indirizzo dei 2 display sulle 2 porte su cui sono collegati al multiplexer, ora non so quasi nulla di programmazione, mi arrangio quando mi serve qualcosa ma quì qualcosa non torna, perchè un programma per un po funziona e poi fa guai? C’è qualche errore nella mia logica?

Ho scoperto l'inghippo ma non mi spiego il problema...

void Display1() {

  if (millis() - previousMillis1 > interval) {

    previousMillis1 = millis();

    //Scrittura valori display1
    TCA9548A(0); // select I2C multiplexer 0x70 bus port

    u8g2.begin();
    u8g2.clearBuffer();				        	  // clear the internal memory
    u8g2.setContrast(255);               //Regola contrasto display
    /*
      // Colore 0 spento, 1 acceso, 2 differenziato: 0 (clear pixel value in the display RAM), 1 (set pixel value) or 2 (XOR mode)
      u8g2.setDrawColor(1);                 //Imposta colore sfondo bianco
      u8g2.drawBox(0, 0, 128, 32);          //Imposta area
      u8g2.setDrawColor(0);                 //Imposta colore scritte
    */
    u8g2.setFont(u8g2_font_ncenB18_tf);
    //u8g2.setFontDirection(0);            //Rotazione font 0=0°, 1=90°, 2=180°, 3=270°
    u8g2.setCursor(0, 18);                 //Imposta posizione inizio
    u8g2.print(variabile1, 0);                 //Scrivi valore variabile
    u8g2.setFont(u8g2_font_profont12_mf);
    u8g2.drawStr(0, 30, "Display 1");
    u8g2.sendBuffer();					            // transfer internal memory to the display
    //delay(150);
  }

}

in pratica se elimino l'if per l'aggiornamento display e riabilito il delay funziona tutto corretto, ma non capisco il problema :fearful:

Niente ragazzi, mi sento deficiente.... ho preso un'altro multiplexer e mi dava lo stesso errore quindi ho ricominciato a far prove, come scritto su togliendo l'if millis andava bene quindi non capivo il motivo, e invece il motivo c'era... resettavo tipo 3 volte per ciclo previousMillis1 e quindi funzionava nel primo if ma negli altri non era mai vero l'if e quindi l'evento non accadeva mai!

Che brutto fare ste figuracce XD rimanga come monito per chi mi leggerà XD