Delay in while cycle

Buonasera a tutti, utilizzo due mega che comunicano in i2c, in sostanza il master, con l’ethernet shield gestisce gli input e poi comunica allo slave gli output da attivare.

Il mio problema è relativo a un delay nella funzione receiveevent della libreria wire:

void setup()
{
  Serial.begin(9600);
  Wire.begin(5);
  Wire.onReceive(receiveEvent);
  for (int pin = 22; pin <= 53; pin++)
  {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  Serial.println("Arduino Mega Slive initialization done.");
}

void receiveEvent(int howMany)
{
  byte c;
  while (Wire.available())
  {
    c = Wire.read();
    
    digitalWrite(pin, LOW);
    delay(500);
    digitalWrite(pin, HIGH);
  }
}

Il delay nella funzione receiveevent dovrebbe eccitare un relè per mezzo secondo ma per far questo devo settare il delay a 15000 ms : delay(15000). Comè possibile?

Grazie

pin nel codice si riferisce a c ovviamente.

Dacci un codice compilabile senza errori e non solo una parte. Ciao Uwe

Il codice completo è questo:

La parte che mi interessa è nella funzione setLight, dove il delay di mezzo secondo dura molto ma molto meno

#include <Wire.h>

#define TAPPARELLA_FINESTRONE_SALA_SU_PIN 51
#define TAPPARELLA_FINESTRONE_SALA_GIU_PIN 50
#define TAPPARELLA_SALA_SU_PIN 49
#define TAPPARELLA_SALA_GIU_PIN 48
#define TAPPARELLA_CUCINA_SU_PIN 47
#define TAPPARELLA_CUCINA_GIU_PIN 46
#define TAPPARELLA_NORMA_SU_PIN 43
#define TAPPARELLA_NORMA_GIU_PIN 44
#define TAPPARELLA_CAMERA_SU_PIN 45
#define TAPPARELLA_CAMERA_GIU_PIN 42

#define TIME_RIS_DISC_TAPPARELLA_CUCINA 16000
#define TIME_RIS_DISC_TAPPARELLA_SALA 16000
#define TIME_RIS_DISC_TAPPARELLA_FINESTRONE_SALA 23000
#define TIME_RIS_DISC_TAPPARELLA_NORMA 22000
#define TIME_RIS_DISC_TAPPARELLA_CAMERA 16000

unsigned long timeTapparellaFinestroneSala = 0;
unsigned long timeTapparellaFinestroneSalaMeta = 0;
unsigned long timeTapparellaSala = 0;
unsigned long timeTapparellaCucina = 0;
unsigned long timeTapparellaNorma = 0;
unsigned long timeTapparellaCamera = 0;


boolean tapparellaFinestroneSalaInMovimento = false;
boolean tapparellaSalaInMovimento = false;
boolean tapparellaCucinaInMovimento = false;
boolean tapparellaNormaInMovimento = false;
boolean tapparellaCameraInMovimento = false;

boolean tapparellaFinestroneSalaMeta = false;
boolean tapparellaFinestroneSalaMetaInMovimento = false;

void setup()
{
  Serial.begin(9600);
  Wire.begin(5);
  Wire.onReceive(receiveEvent);
  for (int pin = 22; pin <= 53; pin++)
  {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  
  Serial.println("Arduino Mega Slive initialization done.");
}

void loop()
{
  stopTapparellaFinestroneSala();
  stopTapparellaSala();
  stopTapparellaCucina();
  stopTapparellaNorma();
  stopTapparellaCamera();
  stopTapparellaFinestroneSalaMeta();
}

void receiveEvent(int howMany)
{
  byte c;
  while (Wire.available())
  {
    c = Wire.read();
    Serial.println(c);
    if (c == 000)
    {
      tapparelleTutteGiu();
    }
    else if (c == 111)
    {
      tapparelleTutteSu();
    }
    else if (c == 222)
    {
      tapparelleZonaGiornoSu();
    }
    else if (c == 221)
    {
      tapparelleZonaGiornoGiu();
    }
    else if (c == 224)
    {
      tapparelleZonaNotteSu();
    }
    else if (c == 223)
    {
      tapparelleZonaNotteGiu();
    }
    else if (c == 225)
    {
      tapparellaFinestroneSala(1);
    }
    else if (c == 226)
    {
      tapparellaFinestroneSala(0);
    }
    else if (c == 227)
    {
      tapparellaSala(1);
    }
    else if (c == 228)
    {
      tapparellaSala(0);
    }
    else if (c == 229)
    {
      tapparellaCucina(1);
    }
    else if (c == 230)
    {
      tapparellaCucina(0);
    }
    else if (c == 231)
    {
      tapparellaNorma(1);
    }
    else if (c == 232)
    {
      tapparellaNorma(0);
    }
    else if (c == 233)
    {
      tapparellaCamera(1);
    }
    else if (c == 234)
    {
      tapparellaCamera(0);
    }
    else if (c == 235)
    {
      allDownFinestroneMeta();
    }
    else if (c == 236)
    {
      zonaGiornoGiuFinestroneMeta();
    }
    else
    {
      setLight(c);
    }
  }
}


void setLight(byte pin)
{
  digitalWrite(pin, LOW);
  delay(500);
  digitalWrite(pin, HIGH);
}

void tapparelleZonaNotteSu()
{
  tapparellaNorma(1);
  tapparellaCamera(1);
}

void tapparelleZonaNotteGiu()
{
  tapparellaNorma(0);
  tapparellaCamera(0);
}

void tapparelleZonaGiornoSu()
{
  tapparellaFinestroneSala(1);
  tapparellaSala (1);
  tapparellaCucina(1);
}

void tapparelleZonaGiornoGiu()
{
  tapparellaFinestroneSala(0);
  tapparellaSala (0);
  tapparellaCucina(0);
}

void tapparelleTutteSu()
{
  tapparellaFinestroneSala(1);
  tapparellaSala (1);
  tapparellaCucina(1);
  tapparellaNorma(1);
  tapparellaCamera(1);
}

void tapparelleTutteGiu()
{
  tapparellaFinestroneSala(0);
  tapparellaSala (0);
  tapparellaCucina(0);
  tapparellaNorma(0);
  tapparellaCamera(0);
}

void allDownFinestroneMeta()
{
  tapparellaFinestroneSalaMeta = true;
  tapparellaFinestroneSala(1);
  tapparellaSala (0);
  tapparellaCucina(0);
  tapparellaNorma(0);
  tapparellaCamera(0);
}

void zonaGiornoGiuFinestroneMeta()
{
  tapparellaFinestroneSalaMeta = true;
  tapparellaFinestroneSala(1);
  tapparellaSala (0);
  tapparellaCucina(0);
}

void tapparellaFinestroneSala (int dir)
{
  int pin = (dir == 1) ? TAPPARELLA_FINESTRONE_SALA_SU_PIN : TAPPARELLA_FINESTRONE_SALA_GIU_PIN;
  if (!tapparellaFinestroneSalaInMovimento)
  {
    Serial.println("tapparellaFinestroneSala");
    digitalWrite(pin, LOW);
    tapparellaFinestroneSalaInMovimento = true;
    timeTapparellaFinestroneSala = millis();
  }
  else
  {
    Serial.println("tapparellaFinestroneSala gia in movimento");
  }
}

void tapparellaSala (int dir)
{
  int pin = (dir == 1) ? TAPPARELLA_SALA_SU_PIN : TAPPARELLA_SALA_GIU_PIN;
  if (!tapparellaSalaInMovimento)
  {
    Serial.println("tapparellaSalaInMovimento");
    digitalWrite(pin, LOW);
    tapparellaSalaInMovimento = true;
    timeTapparellaSala = millis();
  }
  else
  {
    Serial.println("tapparellaSalaInMovimento gia in movimento");
  }
}

void tapparellaCucina (int dir)
{
  int pin = (dir == 1) ? TAPPARELLA_CUCINA_SU_PIN : TAPPARELLA_CUCINA_GIU_PIN;
  if (!tapparellaCucinaInMovimento)
  {
    Serial.println("tapparellaCucinaInMovimento");
    digitalWrite(pin, LOW);
    tapparellaCucinaInMovimento = true;
    timeTapparellaCucina = millis();
  }
  else
  {
    Serial.println("tapparellaCucinaInMovimento gia in movimento");
  }
}

void tapparellaNorma (int dir)
{
  int pin = (dir == 1) ? TAPPARELLA_NORMA_SU_PIN : TAPPARELLA_NORMA_GIU_PIN;
  if (!tapparellaNormaInMovimento)
  {
    Serial.println("tapparellaNormaInMovimento");
    digitalWrite(pin, LOW);
    tapparellaNormaInMovimento = true;
    timeTapparellaNorma = millis();
  }
  else
  {
    Serial.println("tapparellaNormaInMovimento gia in movimento");
  }
}

void tapparellaCamera (int dir)
{
  int pin = (dir == 1) ? TAPPARELLA_CAMERA_SU_PIN : TAPPARELLA_CAMERA_GIU_PIN;
  if (!tapparellaCameraInMovimento)
  {
    Serial.println("tapparellaCameraInMovimento");
    digitalWrite(pin, LOW);
    tapparellaCameraInMovimento = true;
    timeTapparellaCamera = millis();
  }
  else
  {
    Serial.println("tapparellaCameraInMovimento gia in movimento");
  }
}

void stopTapparellaFinestroneSala()
{
  if ((timeTapparellaFinestroneSala + TIME_RIS_DISC_TAPPARELLA_FINESTRONE_SALA) < millis() && tapparellaFinestroneSalaInMovimento == true)
  {
    digitalWrite(TAPPARELLA_FINESTRONE_SALA_SU_PIN, HIGH);
    if (tapparellaFinestroneSalaMeta)
    {
      tapparellaFinestroneSalaMetaInMovimento = true;
      digitalWrite(TAPPARELLA_FINESTRONE_SALA_GIU_PIN, LOW);
      timeTapparellaFinestroneSalaMeta = millis();
    }
    else
    {
      digitalWrite(TAPPARELLA_FINESTRONE_SALA_GIU_PIN, HIGH);
    }
    tapparellaFinestroneSalaInMovimento = false;
  }
}

void stopTapparellaFinestroneSalaMeta()
{
  if ((timeTapparellaFinestroneSalaMeta + 5500) < millis() && tapparellaFinestroneSalaMetaInMovimento == true)
  {
    digitalWrite(TAPPARELLA_FINESTRONE_SALA_GIU_PIN, HIGH);
    tapparellaFinestroneSalaMetaInMovimento = false;
    tapparellaFinestroneSalaMeta = false;
  }
}

void stopTapparellaSala()
{
  if ((timeTapparellaSala + TIME_RIS_DISC_TAPPARELLA_SALA) < millis() && tapparellaSalaInMovimento == true)
  {
    digitalWrite(TAPPARELLA_SALA_SU_PIN, HIGH);
    digitalWrite(TAPPARELLA_SALA_GIU_PIN, HIGH);
    tapparellaSalaInMovimento = false;
  }
}

void stopTapparellaCucina()
{
  if ((timeTapparellaCucina + TIME_RIS_DISC_TAPPARELLA_CUCINA) < millis() && tapparellaCucinaInMovimento == true)
  {
    digitalWrite(TAPPARELLA_CUCINA_SU_PIN, HIGH);
    digitalWrite(TAPPARELLA_CUCINA_GIU_PIN, HIGH);
    tapparellaCucinaInMovimento = false;
  }
}

void stopTapparellaNorma()
{
  if ((timeTapparellaNorma + TIME_RIS_DISC_TAPPARELLA_NORMA) < millis() && tapparellaNormaInMovimento == true)
  {
    digitalWrite(TAPPARELLA_NORMA_SU_PIN, HIGH);
    digitalWrite(TAPPARELLA_NORMA_GIU_PIN, HIGH);
    tapparellaNormaInMovimento = false;
  }
}

void stopTapparellaCamera()
{
  if ((timeTapparellaCamera + TIME_RIS_DISC_TAPPARELLA_CAMERA) < millis() && tapparellaCameraInMovimento == true)
  {
    digitalWrite(TAPPARELLA_CAMERA_SU_PIN, HIGH);
    digitalWrite(TAPPARELLA_CAMERA_GIU_PIN, HIGH);
    tapparellaCameraInMovimento = false;
  }
}

Googlando ho letto che i metodi Wire.onReceive() Wire.onRequest() sono degli interrupts e quindi i delay() non funzionano, che alternativa posso utilizzare considerando che ho 20 input da gestire? 20 variabili con millis() mi sembra una soluzione un po' scomoda. Che ne pensate?

yaroslavpopovic: ... posso utilizzare considerando che ho 20 input da gestire? 20 variabili con millis() mi sembra una soluzione un po' scomoda. Che ne pensate?

Sul resto non mi pronuncio, ma su questa tua specifica domanda penso ...

... che, se scegli questa strada, per semplicità e chiarezza del codice, NON usare 20 variabili ma un array di 20 elementi di tipo unsigned long così hai UNA sola variabile ed un indice ;)

Guglielmo

Ci avevo pensato anch'io ma i pin non hanno un numero logico e crescente, come faccio a dichiararli?

yaroslavpopovic: Ci avevo pensato anch'io ma i pin non hanno un numero logico e crescente, come faccio a dichiararli?

... un secondo piccolo "byte array" in cui ad ogni indice metti il numero di "pin" giusto ? :D :D :D

Così hai un unico indice che ti controlla tutto ;)

Guglielmo

gpb01: ... un secondo piccolo "byte array" in cui ad ogni indice metti il numero di "pin" giusto ? :D :D :D

Così hai un unico indice che ti controlla tutto ;)

Guglielmo

Scusami ma sono un po' tugno :'( , riesci a farmi un esempio?

Grazie

Un array lo usi per i millis() e uno per il numero di pin ... dopo di che usi l'indice per scegliere su quale operare ...

...
unsigned long mieiMillis[20];
byte mieiPin[20] = {45,40,50,55,42,41, ........};
byte indice;
...
...
indice = 3; // valore che corrisponde al pin 55, quarto elemento dell'array
...
if (digitalRead(mieiPin[indice])) ... // qui è come se verificassi il pin 55
...
mieiMillis[indice] = millis()
...

praticamente indice può andare da 0 a 19, per ogni valore ti sarai memorizzato il pin e il mills() e solo cambiando l'indice selezioni ciò che ti interessa ;)

Più difficile a dirsi che a farsi ...

Guglielmo

Ottimo! Capito il senso, adesso ci provo.

Intanto grazie