comunicazione I2C arduino mega e attiny

Buondì, sto avendo qualche difficoltà a capire come comunicano arduino e attiny tramite i2c oppure sono io che voglio fargli fare qualcosa che nn può fare, al momento è strutturato così:

arduino mega è il master a cui ho collegato un sensore sharp infrarosso, fa le letture e in base alla distanza con una condizione if gli dico se minore di tot invia un byte nominato a; se invece è maggiore di tot invia un byte nominato b;

da quanto ho capito nn posso inviare parole intere, in questa maniera è anche più semplice e assomiglia alle funzioni switch case.

lo slave un attiny84 dovrebbe ricevere i byte dal master e in base a questo ho messo altre 2 condizioni if se legge a dovrebbe farmi lampeggiare un led ad una frequenza veloce, se legge b dovrebbe farmi lampeggiare un secondo led ad una frequenza più lenta, ma questo nn avviene : Smiley-cry: il primo led si accende perchè lo messo nel setup prima dell'avvio ma poi più niente, ogni tanto si accende ma mai nei tempi che ho impostato : Smiley-urlare:

… magari se posti il codice che usi per lo “slave” è meglio … dato che altrimenti possiamo fare solo gli indovini :smiling_imp:

Guglielmo

ciao ...non conosco gli attiny...se dai uno sguardo agli esempi dello scambio dati con I2C vedrai che puoi trasmettere un treno di byte "senza problemi". Detto questo ti conviene allegare i due programmi (master e slave) che ci diamo un occhio...secondo me il problema sta in come gestisci il dato ricevuto...o come lo invii.

si avete ragione :smiley:

codice master ma ne sto modificando lo sketch perchè avevo trovato 2 esempi diversi uno lo usava per vedere una distanza a 30cm usando una funzione pow, poi ho sfogliato il manuale che ho di arduino ma nn ho ancora finito di sistemarlo per usare solo la parte che mi serve :stuck_out_tongue:

#include <Wire.h>

const int sensore = A0;
const long rifMv = 5000;

byte ID = 2; 

void setup() {
  Wire.begin();
  Serial.begin(9600);
}

void loop() {
  Wire.beginTransmission(2);
  
  int V = analogRead(sensore);
  //andare avanti da qui con la modifica
  int distanza = 13*pow(V, -1);

  if (distanza <=30) {
    Wire.requestFrom(2, 'a');
    Serial.println(distanza);
    }
  else  if (distanza > 30) {
    Wire.requestFrom(2, 'b');
    Serial.println(distanza);
    }
    Wire.endTransmission();
    delay(500);
}

mentre qui c’è lo sketch per lo slave

#include <TinyWire.h>

byte ID = 2; 


int led1 = 7;
int led2 = 9;
int led3 = 10;

void setup(){ 
 TinyWire.begin(ID);
 TinyWire.onReceive(riceveEventi);
  pinMode (led1, OUTPUT); 
  pinMode (led2, OUTPUT); 
  pinMode (led3, OUTPUT);
  
  digitalWrite(led1, HIGH); 
  delay(2000); 
  digitalWrite(led1, LOW);  
  delay(2000);
  
  digitalWrite(led2, HIGH); 
  delay(2000); 
  digitalWrite(led2, LOW);  
  delay(2000);
   
  digitalWrite(led3, HIGH); 
  delay(2000); 
  digitalWrite(led3, LOW);  
  delay(2000);  
  
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  delay(500);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  delay(500);

}

void loop (){
  digitalWrite(led3, HIGH);
  delay(1500);
  digitalWrite(led3, LOW);
  delay(1500);
  }
  
void riceveEventi(){
 if (TinyWire.read() == 'a'){
digitalWrite(led1, HIGH); 
  delay(250); 
  digitalWrite(led1, LOW);  
  delay(250);  
  }
  else if (TinyWire.read() == 'b'){
digitalWrite(led2, HIGH);  
  delay(1000); 
  digitalWrite(led2, LOW);  
  delay(1000); 
  }
 }

Perché sul master fai requestFrom() quando devi inviare? Solito copia&incolla a caso, eh? Si usa per leggere! Usa write() o direttamente print().

Questo poi è davvero un uso sconsiderato della funzione pow():

int distanza = 13*pow(V, -1);

visto che basterebbe fare:

int distanza = 13 / V;

Comunque la formula mi puzza un po'. E non sono nemmeno sicuro che int sia il tipo di dato più appropriato da usare in questo caso.

mi sono affidato molto agli esempi nell'ide di arduino devo aver fatto un pò di casino nel tenerli aperti :P

questo è il sito dove ho preso l’esempio per leggere i valori del sensore infrarosso https://www.instructables.com/id/How-to-Use-the-Sharp-IR-Sensor-GP2Y0A41SK0F-Arduin/

l’ho modificato prendendo la parte che più mi interessava dal libro arduino progetti e soluzioni dove c’è un’esempio con lo sharp, ora ho una lettura quasi più omogenea, tra un range di 60 e 80, con dei picchi ogni 6-7 letture a 140-160

void loop() {
  Wire.beginTransmission(2);
  
  int V = analogRead(sensore);
 
  int distanza = (V * rifMv)/1023;
  Serial.println(distanza);
  
  if (distanza <=200) {
    Wire.write('a');
    
    }
  else  if (distanza > 200) {
    Wire.write('b');
   
    }
    Wire.endTransmission();
    delay(2000);
}

però cmq nn comunica, i led continuano a rimanere spenti…

P.S. ma se ho un altro dispositivo attiny con un altro indirizzo, come faccio a dirgli esegui il comando ‘a’ sull’indirizzo 2 e esegui il comando ‘a’ oppure ‘b’ sull’indirizzo 3? mi basta aggiungere la rigra Wire.beginTransmission(3) sotto a quello del 2?

Ma quale libreria stai usando per l'Attiny84 ? Non mi tornano i pin, visto che SDA e SCL dovrebbero essere il 7 e 9

la libreria l'ho presa qui https://github.com/lucullusTheOnly/TinyWire

per i collegamenti ho usato questa immagine https://www.google.it/search?q=attiny84+pinout&tbm=isch&source=iu&ictx=1&fir=WoFQeboJlk0nvM%253A%252CpheObArhZFdHzM%252C_&usg=AFrqEzeobRKqfSeauAZz-iAgsCYOYOq_fQ&sa=X&ved=2ahUKEwir59rF-PHcAhWLLlAKHRItBtcQ9QEwAHoECAYQBA#imgrc=WoFQeboJlk0nvM:

i pin SDA e SCL sono il 7 e 9 dell'attiny ma nn sono quelli che chiamo nel programma, se no avrei proprio cagato fuori dal vaso, ho usato le diciture dei rettangoli grigi che fanno riferimento ai pin digitali