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();
}
}
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.