Problema con slave I2c

Ciao a tutti
sto cercando di creare una serie di schede elettroniche che svolgano delle funzioni e vengano supervisionate con un bus I2c

a livello hardware nessun problema, ho messo in parallelo 3 schede arduino, con i cavi SDA SCL e GND e messo su ogni linea una resistenza di pull up. a supervisionare il tutto ho montato un raspberry

le 3 schede sono

  • un controller luci
  • un misuratore di ph (l'Arduino comunica via seriale con un chip della atlas scentific)
  • un controller di temperatura (l' Arduino legge 5 sensori Dallas su apposito bus e gestisce con le uscite digitali dei relais)

tutte 3 le schede usano la seriale dell' Arduino per pilotare un proprio display dove si può vedere lo stato..

fin qui tutto bene
a livello software dal lato raspberry nessun problema, un semplice comando permette di leggere e scriveresul bus i2c indirizzando il comando alla periferica di interesse...
sull'Arduino la cosa è un po più complicata

  1. innanzitutto il protocolla I2C permette di passare pacchetti di byte, avendo temperature del tipo 24,75° ho deciso di passare separatamente la parte intera e la parte decimale (2 cifre)
    ho quindi deciso di creare un vettore dy byte da trasmettere che per il protocollo può essere al
    massimo di 32 byte, ho deciso di dare alla scheda l'indirizzo 0x05:

```
*#include <Wire.h>
#include <OneWire.h>
#define SLAVE_ADDRESS 0x05   //indirizzo i2c arduino
#define MY_SIZE 32                 //dimensione matrice registro

int pointRegister;                      //puntatore all'area di memoria del registro
char valori[MY_SIZE];               //Matrice registri*
```

pointregister è un puntatore all'area di memoria (vettore VALORI) dove memorizzo nel programma i dati...

* *void setup()  {   wdt_disable();     Wire.begin(SLAVE_ADDRESS);    // Imposto i2c bus con indirizzo #5   Wire.onReceive(receiveEvent); // Gestione evento ricezione   Wire.onRequest(requestEvent); // register evento richiesta    wdt_enable(WDTO_8S);  }* *

nella funzione setup avvio l'I2C con indirizzo 5 e definisco 2 funzioni che vengono attivate quando sul bus avviene un evento
attivo anche il watch dog per evitare che il sistema si blocchi

```
*void loop()
 {

//...............  sequenza di istruzioni che non centrano nulla con I2C ma che leggono le temperature
  //               dalle sonde, attivano relai in uscita e soprattutto scrivono le temperature nel registro
  //               valori che viene richiamato dall' I2C come nelle 2 righe che seguono ........

valori[2]=int(T1);                             // scrivo in una cella di valori la parte intera della temperatura
  valori[3]=int((T1-int(T1))*100);         // scrivo nella cella successiva la parte decimale

wdt_reset();
 delay(1000);
 }*
```

il ciclo principale ha ben poco a che fare con I2C, esegue solo le funzioni sul bus dallas per leggere le temperature, scrive le temperature sul display, attiva relais, ecc
inoltre ogni giro attende un secondo e resetta il watchdog

```
*//Gestione dell'I2C
// Legge i dati quando il raspberry scrive su i2C
void receiveEvent(int howMany){
 pointRegister = Wire.read();
 int nextReg = pointRegister;
 while(Wire.available()) {
     valori[nextReg] = Wire.read();
     nextReg++;
 }          
}

// Manda i dati quando il raspberry legge su i2C
void requestEvent(){
 char* txt = new char[ MY_SIZE-pointRegister + 1 ];// = valori;
 memcpy( txt, &valori[pointRegister], MY_SIZE-pointRegister );
 Wire.write(txt);
}*
```

infine riporto qui sopra le due funzioni per la gestione del bus
le altre schede hanno un funzionamento analogo e il software ha la stessa identica struttura.

PROBLEMA!!!
io avvio il sistema e tutto funziona perfettamente, posso chiedere di leggere con un solo comando tutti e 12 i byte del registro e me li risponde perfettamente senza errori
su raspberry infatti ho un ciclo che ogni minuto interroga la cantralina...
dopo qualche minuto mi rendo conto che a partire dal fondo gli ultimi byte letti sono a 0
man mano che passa il tempo mi da corretti un numero minore di byte...
senza toccare il raspberry, se resetto l'arduino ricomincia a funzionare correttamente...

ho pensato che avesse problemi nella lettura multipla... per cui ho modificato il programma su raspberry per leggere un byte alla volta....

il programma parte e gira perfettamente ... poi ad un certo punto inizia a leggere il registro sfalsato di una posizione ( chiedo l'elemento 4 e mi da il 5.. chiedo il 5 e mi da il 6 ... e così via...
resetto Arduino e ricomincia a funzionare

allora decido di mette i valori su 2 celle contemporaneamente, il primo sull'uno e sul due, il secondo sul 3 e sul 4 e cos' via, leggo i dispari e se percaso ha deciso di scattare mi passa i pari che sono dello stesso valore.... cos' giro attorno al problema...

niente da fare! dopo un po il primo byte me lo legge ogni tanto a zero (solo quello)

insomma la lettura non è stabile, inoltre ogni tanto mi sballa l'output sul display o mi resetta la centralina... e per qualche secondo mi riscalda l'acqua già calda...

credo di aver spiegato tutto il problema
qualcuno riesce a capire come mai un software che gira bene dopo un po diventa instabile (solo quando leggo sull'i2c) o ha qualche idea per fare una lettura diversa dei dati?

Se non metti i listati completi sarà difficile che qualcuno possa capire dove sta il problema.

Ciao!

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

scusa
è che seguo tantissimi forum(cnc, 3dprinter,acquari,elettronica e ricordavo erroneamente di essermi già presentato...
seguo questo forum da una vita...

vado subito a scrivere la presentazione e leggo il regolamento che effettivamente qui non ho mai postato...
chiedo venia..

Scritta la presentazione...

Per quanto riguarda la completezza del codice...
Il codice sopra riportato, che adesso vado a inserire negli appositi tag... è completo,
nel senso che io ho 3 arduini collegati in parallelo con 3 funzioni diverse, quello riportato è la parte che tutti e 3 hanno in comune...
Poi:
1 gestisce unnorologio e in base all'ora controlla 6 uscite pwm e 2 digitali x pilotare le luci
2 si interfaccia a una sonda di ph e controlla un uscita x un elettrovalvola
3 si collega a 5 sonde di temperatura dallas e in base alla temperatura comanda le elettrovalvole del riscaldamento...
TUTTI hanno sulla seriale un display

tutti e 3 funzionano perfettamente...
ho poi inserito il bus I2C nel sistema e a tutti e 3 i codici ho messo delle inclusioni di librerie, dichiarato alcune variabili, effettuato delle inizializzazioni nel setup e aggiunto 2 funzioni nell'I2C
i codici dei 3 programmi sono indipendenti, l'unica operazione nel loop è scrivere in un registro (valori[]) il risultato ottenuro in mido che se il bus li interroga restituiscano il valore del processo