Buongiorno, sto creando un progetto che lavorerà tramite batterie e quindi ho la necessità di attivare la funzione sleepmode. Al mio Arduino è collegato un modulo con fotoresistenza con un'uscita digitale DO. Il mio intento sarebbe quello di fare risvegliare Arduino solo ed esclusivamente quando il sensore rileva luce o buio e deve rimanere attivo per 2 minuti per poi tornare in sleepmode. Farlo risvegliare quando il sensore rileva luce non è un problema in quanto il contatto va su HIGH, ma come faccio a risvegliarlo anche quando va su LOW ovvero con il buio? Scusate se ho detto qualche stupidata non sono espertissimo, ma non riesco a venirne a capo
Se non ho capito male il tuo modulo manda a HIGH quando c'è luce e torna a LOW quando fa buio.
Se è così puoi impostare l'interrupt non come RISING o FALLING ma CHANGE in questo modo l'ISR scatterà in entrambe le condizioni e starà a te (da programma) sapere se stai passando dalla luce al buio o viceversa
Grazie mille. Quindi se ho capito bene, utilizzando questo metodo qualsiasi cosa accada sul pin dove è collegata l'uscita digitale della fotoresistenza, risveglierebbe Arduino e gli farebbe ripartire il Loop dove ho le varie istruzioni che deve compiere?
si ma prima parte l'ISR collegata all'interrupt
Scusa la mia ignoranza... cos'è l'ISR?
Gentilissimo grazie
Buongiorno, ho provato ieri sera ad eseguire il codice ma non ho capito una cosa. Io devo fare in modo che quando la fotoresistenza rileva un cambio di stato, parta un servomotore o in un senso o nell'altro. Sono riuscito a fare andare Arduino in sleepMode per 20 secondi ma non esegue le istruzioni relative al servomotore. In sostanza non ho capito dove devo inserire le istruzioni..Nel Loop? O quando richiamo con interrupt? Se non inserisco nel codice le istruzioni del servo, Arduino va in sleep e quando il sensore rileva un cambio si risveglia per i 20 secondi e poi torna in sleep. Ma appena inserisco nel loop le istruzioni servo, basta, non va più nulla..non va be'anche in sleep
Quando dorme... dorme non esegue nessuna istruzione. Anche perché se si potesse ottenere il solito risultato della normale operatività in sleep consumando molta meno energia questa diverrebbe la normale operatività
Senza vedere il codice però non è che si possa dire molto...
Si in effetti hai ragione. Adesso posto il codice, in poche parole adesso riesco a far funzionare tutto, arduino appena acceso va in sleepMode, e quando il sensore rileva luce o buio, il programma parte e il motore stepper parte. Unica cosa che non funziona è il ritorno in sleepMode dopo la "chiusira porta".
#include <avr/sleep.h>
#include <Stepper.h>
Stepper myStepper(2048, 11, 9, 10, 8); //definisco i pin stepper
int count = 0; // contatore
volatile boolean stepper_on= LOW;
int pinSensore =2; // pin fotoresistenza ingresso digitale
void setup() {
pinMode(2, INPUT);
myStepper.setSpeed(10);
Serial.begin(9600);
attachInterrupt(0, wakeUpNow, CHANGE); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
Serial.println("sleep...");
delay(3000);
sleepNow();
}
void sleepNow() {
digitalWrite(13, LOW);
// Serial.print("sto dormendo");
/*
* The 5 different modes are:
* SLEEP_MODE_IDLE -the least power savings
* SLEEP_MODE_ADC
* SLEEP_MODE_PWR_SAVE
* SLEEP_MODE_STANDBY
* SLEEP_MODE_PWR_DOWN -the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
/* Now it is time to enable an interrupt. We do it here so an
* accidentally pushed interrupt button doesn't interrupt
* our running program. if you want to be able to run
* interrupt code besides the sleep function, place it in
* setup() for example.
*
* In all but the IDLE sleep modes only LOW can be used.
*
*/
attachInterrupt(0,wakeUpNow, CHANGE); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.
}
int secondi=0;
void loop() {
while (stepper_on){ // qui faccio un giro di 180 con il motore e chiudo la porta se è buio
// ma non torna in modalita sleepMode
float gradi = 180;
gradi = map(gradi, 0, 360, 0, 2048);
if ( digitalRead(pinSensore)== HIGH){
myStepper.step(gradi);
delay(1000);
//if(digitalRead(pinSensore)== LOW){
// delay(3000);
Serial.println("Chiudo porta");
break;
}
}
while (stepper_on){ // qui faccio un giro di 180 con il motore e chiudo la porta se è giorno
// subito dopo torna in sleepMode
float gradi = 180;
gradi = map(gradi, 0, 360, 0, 2048);
if ( digitalRead(pinSensore)== LOW){
myStepper.step(-gradi);
delay(1000);
//if(digitalRead(pinSensore)== LOW){
// delay(3000);
Serial.println("Apro porta");
break;
}
}
secondi++;
Serial.print("Awake for ");
Serial.print(count);
Serial.println("sec");
count++;
delay(1000); // waits for a second
if(secondi == 1) { //modalità per tornare in sleepMode
Serial.println("Sleep!");
delay(200);
secondi = 0;
count=0;
sleepNow();
}
}
void wakeUpNow() {
stepper_on = !stepper_on;
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
// we don't really need to execute any special functions here, since we
// just want the thing to wake up
//digitalWrite(13, HIGH);
}
Primo consiglio indenta bene il codice (Ctrl+T nell'IDE) perché capirai meglio il codice e, soprattutto, chi di aiuta fa molta meno fatica.
Non ti entrerà mai più in sleep perché l'ISR mette a true stepper_on e nessuno la mette mai a false e quindi non esci più dal while
Altra cosa da rivedere è la parte finale dove usi due variabili per decidere se tornare a "dormire", per come è fatto il codice è inutile, se anche tu lo avessi implementato per aspettare più di un secondo le due variabili sono superflue, ne basta una.
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.