qualcuno ha un listato x creare uno slave I2Ccon arduino?

ciao a tutti
sto cercando di automatizzare l'acquario e mi serve creare con degli arduini degli slave i2c in modo che si comportino come i dispositivi in commercio...
cioè abbiano un registro con alcuny byte (il protocollo ne prevede 32) e con un altro controllore possa chiedere di leggere sul bus un certo registro di una certa scheda..

io devo utilizzare un arduino x pilotare le luci, uno x gestire il ph e uno x gestire le temperature, e un controllore, oltre a leggere altri dispositivi I2c nativi sul bus deve leggere i dati dagli arduini.

ho già tutto assemblato a livello hardware, ma con la mia implementazione software gira un po e poi si blocca.

Non ho mai fatto quello che chiedi, ma scusa la curiosità, non ho ben capito: per controllare un acquario ti servono ben 4 Arduino??? :o C'è una ragione particolare che mi sfugge, o l'acquario ce l'hai a Genova? :smiley:
In ogni caso, se non ci condividi come hai collegato gli elementi, lo sketch che usi, e non spieghi cosa significa "poi si blocca" la vedo difficile senza l'aiuto del Mago Otelma.

quello di genova non è un acquario ma una grossa vasca x i pesci... ogni giorno una nave cisterna va a prendere acqua pulita al largo... e la cambiano.

un acquario è un sistema chiuso o quasi dove si cerca di replicare i cicli naturali.

io ho montato x ora 3 arduini
1 gestisce le luci, con le 6 uscite pwm gestisce 14 led per un totale di 150W con un un controllore in corrente swiching dimmerabile su ogni uscita, ha un display che visualizza ora e percentuale di potenza in uscita per ogni canale

il secondo misura la temperatura delk'acqua all'ingresso del filtro, all'uscita, le temperature di ingresso e di uscita dei tubi della caldaia e dell'impianto frigorifero, e con due relais attiva pompa caldaia o frigo

il terzo misura il ph dell'acqua e se è superiore a 8,1 apre l'elettrovalvola del CO2.

tutti e 3 sulla seriale hanno un display per visualizzare lo stato.

tutti e 3 hanno una connessione in I2C e sono slave con 4 indirizzi separati

il master sull'I2C è un raspberry che ogni minuto legge i dati, li archivia in un db e aggiorna il touch screen di controllo

se disattivo il master tutto funziona perfettamente, ma se inizio a leggere i dati in I2C dopo un po gli arduini iniziano a fare cose strane. resettando il singolo arduino riprende a funzionare x un po...

il codice per creare lo slave i2c l'ho trovato girovagando ma credo che abbia problemi.

ho bisogno di un codice stabile che mi permetta di leggere i dati che i vari processi mettono in un bettore di byte esattamente come fanno tutti i componenti in commercio...

Che differenza c'è tra questo topic e questo che hai aperto pochi giorni fa? Ti ripeto quello che ho detto di la... Se non dai i listati completi difficilmente qualcuno potrà aiutarti... Poi fai te, per me puoi anche aprire il terzo topic uguale...

qui cerco disperatamente qualcuno che abbia un listato x fare lo soave dell'i2c
poi ho risposto a una domanda,
ho poi anche pensato che forse nella sezione software era meglio...

Ok ti perdono :slight_smile:

Per avere un slave basta inizializzare la libreria on un numero che sará l' indirizzo I2C.
Ciao Uwe

si, lo so
ma quello che cerco è il codice completo..
di seguito posto il codice della sonda ph... completo

#include <SoftwareSerial.h>
#include <Wire.h>
#include <avr/wdt.h>
#define SLAVE_ADDRESS 0x06      //indirizzo i2c arduino
#define MY_SIZE 32             //dimensione matrice registro
#define rx 2
#define tx 3
SoftwareSerial myserial(rx, tx);

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

char ph_data[20];
char computerdata[20];
byte received_from_computer=0;
byte received_from_sensor=0;
byte arduino_only=0;

int buttonState1=0;
int buttonState2=0;
int buttonState3=0;

float setp=8.1;
int co2=1;
byte startup=0;
float ph=0;
byte string_received=0;

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 
pinMode(10, OUTPUT);           // Setto uscita per elettrovalvola

pinMode(11, INPUT);           // ingresso taratura 4
pinMode(12, INPUT);           // ingresso taratura 7
pinMode(13, INPUT);           // ingresso taratura 10

delay(800);
Serial.begin(9600);
 Serial.write(13);
 delay(200);
 Serial.print("\e[4L\e[20c");
 Serial.print("\e[2J");
 delay(50);
 Serial.print("\e[?25I");     // hide cursor
delay(200);
myserial.begin(9600);

delay(200);
Serial.println("");
Serial.println("   Sonda Ph         ver 1.0                                 by Monteferrario R");
delay(1200);
myserial.print('T,25.0\r');
wdt_enable(WDTO_8S); 
}

void serialEvent(){
if(arduino_only!=1){
received_from_computer=Serial.readBytesUntil(13,computerdata,20);
computerdata[received_from_computer]=0;
myserial.print(computerdata);
myserial.print('\r');
}
}

void loop(){
 buttonState1 = digitalRead(11);
 buttonState2 = digitalRead(12);
 buttonState3 = digitalRead(13);
 if (buttonState1==HIGH){ 
       delay(1000);
       Serial.println("calibrazione LOW 4.00");
       myserial.print("Cal,low,4.00\r");
       delay(1000);
       myserial.print("C,1\r");
       }
 if (buttonState2==HIGH){ 
       delay(1000);
       Serial.println("calibrazione MID 7.00");
       myserial.print("Cal,mid,7.00\r");
       delay(1000);
       myserial.print("C,1\r");
       }
 if (buttonState3==HIGH){
       delay(1000); 
       Serial.println("calibrazione HIGH 10.00");
       myserial.print("Cal,high,10.00\r");
       delay(1000);
       myserial.print("C,1\r");
       }
 if(myserial.available() > 0){
 received_from_sensor=myserial.readBytesUntil(13,ph_data,20);
 ph_data[received_from_sensor]=0;
 ph=atof(ph_data);
 valori[1]=int(ph*10);
 valori[2]=int(ph*10);
 valori[3]=int(((ph*10)-int(ph*10))*100);
 valori[4]=int(((ph*10)-int(ph*10))*100);
 
 string_received=1;
 //Serial.println(ph_data);
 Serial.print("Ph = ");
 Serial.print(ph_data);
 Serial.print("          Stato CO2: ");
 if (ph<setp) {
                  co2=0;
                  digitalWrite(10,HIGH);
                  Serial.print ("OFF");
                  valori[5]=0;
                  valori[6]=0;
                  
                  }
                  else
                  {
                  co2=1;
                  digitalWrite(10,LOW);
                  Serial.print ("ON");  
                  valori[5]=1;
                  valori[6]=1;
                    
                  }  
                  
 Serial.println("");
  }
  if(arduino_only==1){Arduino_Control();}
  wdt_reset();
}

void Arduino_Control(){
if(startup==0){
myserial.print("c,0\r");
delay(50);
myserial.print("c,0\r");
delay(50);
startup=1;
}
 delay(800);
 myserial.print("R\r");
 if(string_received==1){
  ph=atof(ph_data);
//   if(ph>=7.5){Serial.println("high\r");}
//   if(ph<7.5){Serial.println("low\r");}

  string_received=0;}
}


//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(){
// codice originale
//  char* txt = new char[ MY_SIZE-pointRegister + 1 ];// = valori;
//  memcpy( txt, &valori[pointRegister], MY_SIZE-pointRegister );
//  Wire.write(txt);

// codice alternativo
Wire.write(valori[pointRegister]);
}

ora leggendo tra le righe:
ho il vettore valori[] che nel ciclo principale viene caricato con il ph * 10 (parte decimale e parte intera e
lo stato dell'uscita, la parte centrale del programma non ha problemi...
le ultime 2 funzini che ho trovato su internet tempo fa gestiscono l'evento di richiesta su i2c da parte del master
come si puó vedere nell'ultima ho remmato le ultime 4 righe che creavano un puntatore al vettore e spedivano tutti i dati, ora ne spedisco uno solo per volta

normalmente tutto bene ma ogni tanto, se leggo sul bus mi capita per esempio che il programma entri nel ciclo di calibrazione (che dovrebbe avvenire solo premendo un pulsante e mandando a HIGH un ingresso che ha una resistenza di pull down)
non mi spiego come faccia l'uso dell'I2C a rendere errata una lettura digitalread su una specifica porta, ammenochè la libreria che uso non abbia un problema

con la modifica che ho fatto al codice la situazione è migliorata ma continua ogni tanto a fare di questi difetti

problema analogo con luci e controllo temperature

x iscrizione

Certe volte la 13 crea rotture di scatole.
Prova a cambiarla con un'altra.