Problemi con I2C

Salve a tutti,
mi spiace sempre chiedere di visionare ad altri i propri codici ma è da qualche mese che cerco di far comunicare il mio Arduino con un wattmetro e amperometro digitale quale l'INA219 senza successo. Qui riporto solo una minima parte dello sketch.
Ad oggi sto cercando di risolvere il problema del mancato riconoscimento dello slave da parte del master. Caricando queste righe soltanto non ricevo comunque risposta secondo voi a cosa può essere imputabile?
Grazie in anticipo

//lettura INA219                             
                                              
#define SCL A5
#define SDA A4
#define impulsoAlto {digitalWrite(SDA, HIGH); digitalWrite(SCL, LOW); digitalWrite(SCL, HIGH); delayMicroseconds(250); digitalWrite(SCL, LOW);}
#define impulsoBasso {digitalWrite(SDA, LOW); digitalWrite(SCL, LOW); digitalWrite(SCL, HIGH); delayMicroseconds(250); digitalWrite(SCL, LOW);}

byte b [7]={1,0,0,0,0,0,1};

void setup() {
  Serial.begin(9600);
  pinMode(PB5, OUTPUT);
  digitalWrite(PB5, HIGH);
}

void loop() {
  Serial.print("Prova all'indirizzo ");
  for(int a=0;a<7;a++){                       //modifica casualmente l'indirizzo
    b[a]=random(0,2);
    if(a!=6){
      Serial.print(b[a]);
    }
    if(a==6){
      Serial.println(b[a]);
    }
  }
  //start
  delayMicroseconds(250);
  digitalWrite(SDA,LOW); 
  delayMicroseconds(250);
  digitalWrite(SCL,LOW);
  delayMicroseconds(250);
  //sollecita slave all'indirizzo...
  for(int a=0;a<7;a++){
    if (b[a]==0){
      impulsoBasso;
    }
    if (b[a]==1){
      impulsoAlto;
    }
    if(a==7){
      //b=b+1;
    }
  }
  //R/W basso
  impulsoBasso;
  //attende acknowledge             
  digitalWrite(SCL, LOW);
  digitalWrite(SCL, HIGH);
  delayMicroseconds(200);
  if(digitalRead(SDA)==LOW){                            //se lo trova...
    digitalWrite(SCL, LOW);
    Serial.print("ACKNOWLEDGE all'indirizzo ");
    for(int a=0;a<7;a++){
      Serial.println(b[a]);
    }
    digitalWrite(PB5, LOW);
    delay(2000);
    digitalWrite(PB5, HIGH);
    delay(2000);
  }
  digitalWrite(SCL, LOW);
  //se non lo trova 
  digitalWrite(SDA,LOW);
  digitalWrite(SCL,LOW);
  delayMicroseconds(250);
  digitalWrite(SCL,HIGH);
  delayMicroseconds(250);
  digitalWrite(SDA,HIGH); 
  delayMicroseconds(250);
  digitalWrite(SCL,LOW);
  delay(1);
}

Che c...o fai? I2C è un Bus, non puoi metterlo a HIGH con un uscita.
Usa la libreria Wire Wire - Arduino Reference per usare l' interfacca I2C.
Usa una libreria per il INA219

Ciao Uwe

Si ok è pulluppato ma se lo metto high semplicemente il bus rimane high quindi non dovrebbe comportare errori giusto?

Non capisco perché cerchi di reinventare l'acqua calda ... oltretutto il protocollo I2C non è affatto così semplice come sembra ... ::slight_smile:

Direi che, se proprio sei curioso di vedere come va gestito, apri i sorgenti della libreria Wire e ti vedi la complessità della cosa.

Guglielmo

mentorade:
Si ok è pulluppato ma se lo metto high semplicemente il bus rimane high quindi non dovrebbe comportare errori giusto?

No. Un HIGH dato da una resistenza Pullup é una cosa diversa da un HIGH dato da un uscita Portata a HIGH da un transistore.
Visto che su un bus I2C ci sono piú dispositivi che devono potere portare a LOW il segnale. Con un Pullup funziona. Con un HIGH da un uscita con un altra uscita mesa a LOW fai un cortocircuito.

Visto che un Slave deve poter sia mettere a LOW il Clock che poter rispondere mandando dati al master.

Informati come funziona il BUS I2C. Usa librerie che esistono giá.
Come per esempio ( i primi che ho trovato )

Le librerie hanno anche sempre esempi per sapere che funzionalitá ha la libreria e per provare se il INA219 funziona.

Ciao Uwe

Grazie ad entrambi,
il fatto è che avendo già gestito in precedenza un bus di comunicazione in parallelo senza avvalermi di librerie mi piaceva fare lo stesso con la I2C per ragioni di ottimizzazione del codice e per comprendere pienamente il suo funzionamento.

mentorade:
... il fatto è che avendo già gestito in precedenza un bus di comunicazione in parallelo senza avvalermi di librerie mi piaceva fare lo stesso con la I2C per ragioni di ottimizzazione del codice ...

Normalmente, salvo casi particolari, un bus parallelo, è molto più semplice da gestire ... I2C, nonostante l'innocua apparenza, è in realtà una brutta bestia e, probabilmente, neanche la libreria Wire di Arduino copre tutti i casi e le eccezioni che esso può avere (basta andare a prendere difatti alcune librerie I2C di Microchip per le MCU PIC per rendersene conto !!!). In ogni caso essa è già ottimizzata e difficilmente a mano, pur conoscendo bene il I2C, si riesce ad ottimizzare molto di più.

Come ti ho detto, prenditi i sorgenti della libreria e studiateli ... è la cosa migliore per capire quello che c'è dietro.

Guglielmo

Speravo in una precisazione del genere, da autodidatta parecchie considerazioni sfuggono.
Di nuovo grazie
PS complice anche l inesperienza credevo davvero fosse semplice la I2C

mentorade:
Grazie ad entrambi,
il fatto è che avendo già gestito in precedenza un bus di comunicazione in parallelo senza avvalermi di librerie mi piaceva fare lo stesso con la I2C per ragioni di ottimizzazione del codice e per comprendere pienamente il suo funzionamento.

Allora per favore informati prima delle specifiche e del funzionamento del BUS per poter programmarlo in modo giusto.

Ciao Uwe