Svegliare Arduino con... Arduino!

Salve a tutti!

sto realizzando un progettino dove utilizzo due Arduino, che chiamerò A e B.

A e B sono indipendenti ed entrano dopo aver svolto il loro lavoro in modalità sleep per risvegliarsi sempre autonomamente.

Ogni tanto però A deve svegliare B.

In B ho settato l interrupt 0 con evento CHANGE, ed ho collegato il pin digitale 2 a 5v. se manualmente cortocircuito il pin a GND causo il risveglio.

Come devo settare e collegare A con B affinché possa simulare questo collegamento a GND per risvegliare B?
Pensate sia un buon metodo?

Grazie!!!

secondo me devi portare un pin di A a LOW (GND) cambiare da CHANGE a FALLING e un antidebounce

Pubblica lo sketch o per lo meno la parte riguardante lo sleep.
In alcune modalità di sleep funziona solo l'evento interrupt LOW, ossia che il pin viene sganciato dal clock di sistema e non può più leggere cambi di tipo CHANGE, RISING e FALLING.

Questo è lo sketch completo di B. Cortocircuitando il pin digitale 2 a GND causa l'interrupt. Ho implementato anche il riavvio ogni tot secondi e funziona regolarmente

//-----------------------------------------------SLEEP
#include <avr/sleep.h>
#include <avr/wdt.h>

byte SleepTime = 5;
//-----------------------------------------------SLEEP_fine

//-----------------------------------------------INTERRUPT
volatile boolean clockInterrupt = false;   //This will be set TRUE when there is an interrupt
//-----------------------------------------------INTERRUPT_fine

//-----------------------------------------------SHT21
#include <Wire.h>
#include <LibHumidity.h>

LibHumidity humidity = LibHumidity(0);

float tempCur = 0;
float tempMin = 100;
float tempMax = 0;

float humCur = 0;
float humMin = 100;
float humMax = 0;
//-----------------------------------------------SHT21_fine

const byte LED = 13;

void flash ()
  {
  pinMode (LED, OUTPUT);
  for (byte i = 0; i < 2; i++)
    {
    digitalWrite (LED, HIGH);
    delay (25);
    digitalWrite (LED, LOW);
    delay (25);
    }
    
  pinMode (LED, INPUT);
    
}


//---------------------------------------------------------------------------------------------------------SLEEP INTERRUPT
//watchdog interrupt
ISR (WDT_vect) 
{
   wdt_disable();  // disable watchdog
}

void clockTrigger() {
     clockInterrupt = true;  //don't do any other processing in this subroutine
}

void wake ()
{
  clockTrigger();
  // cancel sleep as a precaution
  sleep_disable();
  // must do this as the pin will probably stay low for a while
  detachInterrupt (0);
  
}  // end of wake


void clearClockTrigger() {
  clockInterrupt=false;                 //Finally clear the flag we use to indicate the trigger occurred
}

void SleepInt() {
  
  // disable ADC
  ADCSRA = 0;  

  // clear various "reset" flags
  MCUSR = 0;     
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval 
  //WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0);    // set WDIE, and 8 seconds delay
  WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1);    // set WDIE, and 1 second delay
  wdt_reset();  // pat the dog
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  noInterrupts ();           // timed sequence follows
  sleep_enable();
  
  // will be called when pin 
  attachInterrupt (0, wake, CHANGE);
 
  // turn off brown-out enable in software
  // BODS must be set to one and BODSE must be set to zero within four clock cycles
  MCUCR = bit (BODS) | bit (BODSE);
  // The BODS bit is automatically cleared after three clock cycles
  MCUCR = bit (BODS); 
  
  // We are guaranteed that the sleep_cpu call will be done
  // as the processor executes the next instruction after
  // interrupts are turned on.
  interrupts ();  // one cycle
  sleep_cpu ();   // one cycle
  sleep_disable();
}
//---------------------------------------------------------------------------------------------------------SLEEP INTERRUPT

void setup ()
{
  delay(1000);
  Serial.begin(115200);
  
  //-----------------------------------------------SLEEP INTERRUPT
  digitalWrite (2, HIGH);
  clearClockTrigger();
  //-----------------------------------------------SLEEP INTERRUPT
  
  //-----------------------------------------------I2C
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);  //GND pin
  pinMode(17, OUTPUT);
  digitalWrite(17, HIGH); //VCC pin
  //-----------------------------------------------I2C_fine
} 

void loop ()
{
  flash ();
  tempCur = humidity.GetTemperatureC();
  if ( tempCur < tempMin ) tempMin = tempCur;
  if ( tempCur > tempMax ) tempMax = tempCur;
  
  humCur = humidity.GetHumidity();
  if ( humCur < humMin ) humMin = humCur;
  if ( humCur > humMax ) humMax = humCur;
  
  if(clockInterrupt){
    Serial.println();
    //Serial.println("INTERRUPT!!");
    Serial.print("T");
    Serial.print(tempCur);
    Serial.print("-");
    Serial.print(tempMin);
    Serial.print("-");
    Serial.println(tempMax);
    Serial.print("H");
    Serial.print(humCur);
    Serial.print("-");
    Serial.print(humMin);
    Serial.print("-");
    Serial.println(humMax);
    Serial.println();  
    clearClockTrigger();
  }
  
  //Serial.println("Unsleep");
  for (int i = 0; i < (SleepTime); i++) {
    clearClockTrigger();
    delay(10); 
    SleepInt();   
  }
}
SLEEP_MODE_PWR_DOWN

In Power Down sui pin INT0 e INT1 funziona solo la lettura dello stato LOW.

Ok, settando l'interrupt a LOW, quindi va bene collegare il pin 2 a 5V e portarlo a GND per farlo scattare, no?

Ma come configurare l'Arduino A? Come già consigliato dovrei utilizzare un pin che normalmente sta su HIGH da portare a LOW per forzare il risveglio di B.

Ma quando A va in standby il pin che valore assume?

Potresti impostare il pin che collega A all'INT0 di B come input con pull-up interna attiva prima di andare in sleep, così la piccola corrente che scorre sul pin dovrebbe bastare a mantenere a livello alto il pin INT0 di B. E poi rimetti su output appena risvegliato.

Alternativamente metti una pull-up esterna da 20/30K sulla linea che va da A al pin INT0 di B. Così non devi preoccuparti di come sta il pin di A.

in quest'ultimo modo non appena setto il pin di A a low attivo l interrupt?

la pull-up va su 5v giusto?

Ho cambiato l'interrupt in LOW ma ancora non andava. Avevo dimenticato di dichiarare ad output il pin di risveglio in A:

void loop() {
  if ((millis() - maintime) <= timeout) {
    if (Serial.available())
      Serial.write(Serial.read());
    if (Serial.available())
      Serial.write(Serial.read());
  }
  else {
    for (int i = 0; i < 5; i++) {
      delay(10); 
      Dormi();   
    }
    maintime = millis();
    Serial.println();
    Serial.println("Risveglio");
    pinMode (5, OUTPUT);
    digitalWrite (5, LOW);
    delay(50);
    digitalWrite (5, HIGH);
  }
}