Salve amici di arduino chiedo se e possibile tramite arduino 2560 se ho una funzione millis()
che controlla in diverse fasi degli eventi e se ha una determinata fase avviene un evento
esterno mi attiva un interups per bloccare il ciclo di Loop() per poi ripartire dalla stessa
fase esempio se nella fase 2 si attiva un interup al piedino 3 del 2560 il tempo trascorso quando interups si disattiva dovrebbe partire dalla fase 2 dove si era interrotto non so se sono stato chiaro grazie.
#include <Arduino.h>
#define interupcontrollo 3
int fase = 1;
unsigned long intervallo1 ;
unsigned long intervallo2 = 15000;
unsigned long intervallo3 = 10000;
unsigned long intervallo4 = 30000;
unsigned long previousMillis = 0;
void setup () {
Serial.begin(9600);
pinMode (interupcontrollo,INPUT_PULLUP);
}
void funzione1()
{
Serial.print ("Interup");
}
void loop ()
{
attachInterrupt(1,funzione1, CHANGE);
if ((fase == 1) and (millis() - previousMillis > intervallo1)) {
previousMillis = millis();
fase = 2 ;
}
if ((fase == 2) and (millis() - previousMillis > intervallo2)) {
previousMillis = millis();
fase = 3 ;
}
if ((fase == 3) and (millis() - previousMillis > intervallo3)) {
previousMillis = millis();
fase = 4 ;
}
if ((fase == 4) and (millis() - previousMillis > intervallo4)) {
previousMillis = millis();
fase = 1 ;
}
if (fase == 1) {
}
if (fase == 2) {
Serial.println("fase2");
}
if (fase == 3) {
Serial.println("fase3");
}
if (fase == 4) {
Serial.println("fase4");
}
}
Non ho tanta esperienza con Mega, ma puoi attaccare un interrupt agli specifici piedini che accettano interrupt. La funzione millis() dovrebbe continuare il conteggio, salvo che vai a toccare noInterrupts() che interferisce con il prosieguo di tutti gli interrupts.
Piccole MCU a 8 bit, come quella usata su Arduino, nonrmalmente NON hanno una prioritizzazione degli interrupt, e, quando si entra in una ISR, gli interrupt vengono disabilitati automaticamnete e riabilitati quando si esce, da cui ...
le ISR DEVONO essere le più rapide possibile
NON puoi chiamare nulla che usa gli interrupt (tipo i metodi della Serial)
altre cose comandate da interrupt si fermano ... anche l'avanzamento del contatore di millis()
Quindi ... nella ISR tu setti solo una flag ed esci immediatamente, tutto il resto lo devi fare nel loop() controllando se la flag è attiva o meno e facendo quello che è necessario.
Guglielmo
P.S.: Anche se è possibile dentro una ISR riattivare manualmente gli interrupts, è cosa che ti sconsiglio caldamente senza la necessaria esperienza dato che, a quel punto, se non sai bene come vanno le cose, cominci ad avere ISR che si accavallano l'una sull'altra, con le dovute conseguenze.
grazie per L'aiuto gpb01 forse sto sbagliando a voler usare interup
nel mio caso ,se ad esempio ho il counter millis() in cui lo metto ha
confronto con le mie variabili intervallo tramite if ((fase == 1) lesempio
del codice che ho postato se in una di queste fasi avviene unevento
esterno sia seriale oppure attraverso un interruttore.
vorrei interrompere e uguale dove si trova la variabile fase quindi il
counter millis() , per poi anche dopo un po di tempo attraverso
una condizione da me inserita una variabile messa a true
che mi parta esattamente da quel punto dove lo lasciata.
forse si deve usare una ruoitine per questo caso mi puo fare un piccolo unesempio.
Perdona, ma .. non ho capito quello che devi/vuoi fare ...
Il suggerimento è comunque usare delle "flag" che ti indicano determinate condizioni e tu, in base a queste condizioni, fai una cosa piuttosto che un'altra.
Attraverso degli interrupt puoi facilmente settare e resettare delle flag ... sono operazioni veloci e non creano problemi ...
Un evento ha solo due modi per essere attualizzato. O si continua a controllare che l' evento avvenga (polling), altrimenti si mette un interrupt che genera un richiamo. Ma nel secondo caso, si deve fare attenzione che non vada a disturbare (eccessivamente) anche altre funzioni che girano tramite interrupt.
Se fai il polling, già nella loop hai dei periodi molto brevi per non perdere l' evento, salvo che non si voglia interferire con altri eventi che potrebbero essere bloccanti, come un delay() o un altro loop. Allora si prende la via dell' interrupt che prende il sopravvento all' evento in corso.
Guglielmo ha spiegato bene, unica cosa che quello che metti nell ISR deve essere dichiarato come volatile. Comunque attachinterrupt perché lo hai messo nel loop? Poi il pin uno non può essere usato come isr