chiarimenti sugli interrupt

Quoto lesto.
La libreria è scritta per gli Atmega168/328.
Se il numero di PCINT da gestire non è elevato, conviene andare di codice, senza stare a scrivere una libreria apposita. Alla fine, si tratta di configurare una manciata di registri del micro.

eheh spero di non essere l'unico ad aver bisogno di usare qualche interrupt sul mega :sweat_smile:
comunque leggevo sulla pagina dell'arduino mega http://arduino.cc/en/Main/ArduinoBoardMega2560

External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.

quindi ho già 6 interrupts disponibili, no? potrebbero anche bastarmi, ma io voevo usarne di più per poter fare una specie di sistema multitask...

un'altra domanda: se io ho un interrupt durante la funzione pulseIn, cosa succede? mi interrope il processo o no?
grazie :wink:

L'interrupt interrompe qualsiasi cosa sia in corso , altrimenti devi usare un detachinterrupt
Ciao Niko

er_like_no_other:
eheh spero di non essere l'unico ad aver bisogno di usare qualche interrupt sul mega :sweat_smile:
comunque leggevo sulla pagina dell'arduino mega http://arduino.cc/en/Main/ArduinoBoardMega2560

External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.

La gestione degli INT è integrata in Arduino per cui la gestione di essi non comporta problemi.

quindi ho già 6 interrupts disponibili, no? potrebbero anche bastarmi, ma io voevo usarne di più per poter fare una specie di sistema multitask...

Anche se tempo fa sono stato affascinato dai sistemi operativi multitasking per micro ad 8 bit, col tempo ho poi riflettuto sulle complicazioni che essi hanno.
Questi SO usano interrupt per suddividere il tempo di calcolo della Cpu del micro tra i vari processi. Ma se un processo è agganciato ad una funzione HW che richiede un certo tempo per essere eseguita, come ad esempio la lettura di un pin analogico, che si fa? Si interrompe il processo falsando così la lettura o la si fa terminare, alterando i tempi di esecuzione degli altri processi?

un'altra domanda: se io ho un interrupt durante la funzione pulseIn, cosa succede? mi interrope il processo o no?
grazie :wink:

Sì, quindi si torna a ciò che ti ho detto poco sopra.

ok quindi provo a guardare se riesco a trovare qualcosa di già pronto per il mega e poi vedo di inventarmi qualcosa da SW per creare una specie di multitask...
ma terminato l'interrupt il programma riprende dal punto in cui era stato interrotto no? quindi il problema è solo nell'interropere le funzioni di lettura che richiedono un po' di tempo per essere eseguite, tipo il pulseIn e l'analogRead, come dici te...potrei fare che quando finisce l'interrupt va a ripetere la misura che stava facendo, se stava facendo una misura... comunque, però, vado a buttare dei microsecondi...
grazie per l'aiuto! vi so dire se trovo qualcosa per il mega :wink:

Bah... se strutturi bene il programma non hai bisogno di multitasking. Anche perché puoi simulare multitasking e tick usando bene millis e seguendo una buona logica dei compiti da eseguire.

sisi infatti, ci sto pensando :wink:

allora, stavo provando questo codice per leggere un sensore, da questo sensore ricevo un impulso di durata variabile... speravo di ottenere gli stessi risultati di quando uso la funzione pulseIn ma non è così... sembra che mettendo 2 tipi di interrupt sullo stesso pin non funzionino tutti e due ma uno solo, mi confermate questa cosa o ho sbagliato da qualche altra parte?
grazie in anticipo! :wink:

unsigned long Time=0;
unsigned long t=0;

void setup()
{
 pinMode(2, INPUT);
 pinMode(3, OUTPUT); 
 Serial.begin(115200);
}

void loop()
{
 t=millis();

 digitalWrite(3, HIGH);  
 delayMicroseconds(10);
 digitalWrite(3, LOW); 

 attachInterrupt(0, StartTimer, RISING);
 attachInterrupt(0, StopTimer, FALLING);
 while(millis()-t<=50){}

 detachInterrupt(0);
}

void StartTimer(){ Time=micros(); Serial.println("s");}
void StopTimer() { Time=(micros()-Time)/58; Serial.println(Time,DEC);}

sì, ora non ricordo se è un attachInterrupt alla volta o uno per pin...

@er:
mi spiace, non puoi fare una roba del genere :stuck_out_tongue_closed_eyes:
Prima attivi l'interrupt 0 con un tipo di segnale e poi dopo lo stesso interrupt con un altro segnale! E' normale che te ne venga eseguito solo 1 :stuck_out_tongue:
Anzi, mi meraviglio di come il compilatore non ti dia errore dicendoti che il vettore di interrupt risulta già dichiato :wink:

nel (vecchio) reference dicono che questo caso è preso in considerazione.
Il puntatore alla funzione di interrupt è sovrascritto.
ora, non ricordo se c'è un solo puntatore a funzione, o se ce ne è una per pin

INT è INT, non è PCINT. E l'INT0 è legato al pin digitale 2. Se dichiari 2 routine attachInterrupt(0) è normale che poi ne venga eseguita solo 1 perché l'INT0 è mappato su un piedino non modificabile.

si ho capito, ho risolto facendo col change e poi verificando se è alto o basso:

unsigned long Time=0;
unsigned long t=0;

void setup()
{
 Serial.begin(115200);
}

void loop()
{
 detachInterrupt(0);
 t=millis();
 
 pinMode(2, OUTPUT); 
 digitalWrite(2, HIGH);  
 delayMicroseconds(10);
 digitalWrite(2, LOW); 
 
 pinMode(2, INPUT);
 attachInterrupt(0, Timer, CHANGE);
 
 while(millis()-t<=50){}
 Serial.println(Time,DEC);
}

void Timer()
{ 
 if(digitalRead(2)) Time=micros(); 
 else Time=(micros()-Time)/58; 
}

se io uso lo stesso pin di interrupt per un periodo come output (vedi codice sopra) devo disattivare l'interrupt se no lo legge comunque il registro della porta, o no? ho fatto giusto nel codice sopra no?
grazie ancora :wink:

L'interrupt può essere attivo anche mentre usi il pin però poi ovviamente si attiva anche nell'uso normale.
Sinceramente non ho capito una cosa... ma che stai cercando di fare? :sweat_smile:

eh do un impulso di trigger al sensore che dura 10us, poi sullo stesso pin ho di ritorno dal sensore un impulso di lunghezza variabile, e io voglio leggere la durata di questo impulso... questa è solo una prova per cominciare :wink: i 50ms alla fine sono solo di pausa perchè tra un un segnale di trigger e quello sucessivo il sensore ha bisogno di una pausa...
mi chiedevo se durante quell'impulso è bene che l'interrupt sia disattivato per evitare che lo legga come un impulso anche quello...

se la risposta del sensore arriva in breve tempo ed e' di breve durata, perche' non fai tutto in polling ?
hai gia' provato ?

cosa intendi per "polling"?
il sensore è questo: SRF05 Technical Documentation
comunque questo è un codice di prova dopo avrò 4 di questi sensori e tante altre cose...

allora, nuova questione :sweat_smile: quel codice che ho postato prima funziona bene, devo sistemarlo ancora un po' ma per provare va bene... fin ora ho provato sugli INT0 e 1, ma avendo a disposizione altri 4 INT sul mega volevo usare anche quelli, il problema è che lo stesso codice con le opportune modifice da risultati strani su questi altri 4 pin... sembra che rillevi dei cambiamenti che in realtà non ci sono e che sugli INT0 e 1 non erano presenti... cosa può essere? non mi sembra di aver sbagliato niente perchè il codice è lo stesso... :~
confido nel vostro aiuto! grazie in anticipo! :wink:

Io continuo a non capire. Ma perché vuoi usare lo stesso pin per trasmettere il segnale e per leggerlo con un interrupt, essendo così costretto a disattivare l'interrupt per evitare letture errate?

  1. attivi l'INT0
  2. spedisci il treno di impulsi per attivare il sensore
  3. l'ISR a questo punto legge le risposte del sensore e le "presenta" al codice principale
  4. il codice gestisce le informazioni in ricezione e poi torna al punto 2)

perchè il sensore usa lo stesso pin per fare queste due operazioni...