Comunicazione I2C tra arduini

Buongiorno a tutti

sto facendo delle esperienze di comunicazione I2C tra un UNO (Master) ed un nano (slave) utilizzando questo sketch ed inviando semplicemente un numero inferiore a 10:

#include <Wire.h>

int suono = 0;
int ledPin = 9;

void setup() {
  Serial.begin(9600);
  Wire.begin(7);
  Wire.onReceive(ricevi);

  pinMode(ledPin, OUTPUT);
}

void loop() {
  delay(1000);
}

void ricevi() {
  int dato = 0;
  while (Wire.available()) {
    dato = (Wire.read());
  }
  suono = dato -48 ;

  if (suono > 0) {
    for (int i = suono; i > 0; i--) {
      Serial.println(i); 
      Serial.println("");
//      digitalWrite(ledPin, HIGH);
      delay(1000);
//      digitalWrite(ledPin, LOW);
      delay(1000);

    }
  }
}

funziona, ma non considera i delay() !! Infatti mi scrive tutti i numeri decrescenti senza rispettare le pause.

Qualcuno mi sa indicare il perché?

Grazie anticipatamente + saluti

Enrico

Quali pause? Hai capito come funziona questo sketch? Sai che cos'è un interrupt?

x SukkoPerra: no, non ho mai avuto occasione/necessità di informarmi sugli interrupts , quello che pensavo di fare era un'azione tipo:

  • il master ha un suo programma da eseguire, ad un certo punto delega allo slave una richiesta poi continua a svolgere il suo compito

  • lo slave riceve una richiesta (tipo accendi/spegni x volte un LED ad intervalli di 1 secondo) si "sveglia" assolve l'incarico in modo autonomo e si rimette a "dormire".

Da una prima, superficiale lettura della spiegazione degli interrupts mi sembra che non sia possibile utilizzare il protocollo I2C per fare quanto sopra; è corretto?

Saluti + grazie della risposta

Enrico

Dipende da cosa significa la "richiesta": se dice "accendi il led" (o "spegni il led") e lo slave esegue il comando il più rapidamente possibile (cioé subito), se vuoi farlo lampeggiare ogni secondo allora devi mandare il comando giusto dal master a intervalli di un secondo.

Se invece la richiesta significa "accendi/spegni x volte un LED ad intervalli di 1 secondo", allora è lo slave che deve preoccuparsi di accendere, aspettare un secondo e spegnere, contando le x volte.

Insomma, i2c è solo un protocollo di comunicazione, recapita i messaggi e stop. La logica della gestione dei messaggi deve farla qualcos'altro.

Corretto, è esattamente quello che sto cercando di fare.... ma è come se, nel ciclo for, non venissero considerati i delay!

Ho provato anche a separare il ciclo for facendo un altro void ma il risultato non cambia, sembra che i delay non vengano considerati!!

Al momento non ho altre idee che provare a tramettere il comendo (fai lampeggiare la luce) via radio! (sono in attesa di alcuni HC-12).

Saluti

Enrico

La tua funzione viene richiamata da un interrupt handler. I delay() non funzionano in questi contesti.

Quel che sarebbe corretto fare nell'interrupt handler (che devono essere funzioni il più veloce possibile) è solo accodare quel che viene ricevuto in un array, e gestire quest'ultimo dal loop().

PS: Si chiamano FUNZIONI, non VOID!

GRAZIE, ho messo il ciclo for nel loop ed ora funziona.

Ancora grazie + saluti.

Enrico