Pages: 1 2 [3] 4   Go Down
Author Topic: Analisi impulsi contatto a tapparella per antifurti  (Read 4306 times)
0 Members and 1 Guest are viewing this topic.
MC
Offline Offline
God Member
*****
Karma: 13
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Byte è un tipo di dato, accetta valori da 0 a 255.
Volatile è un qualificatore che permette di modificare la variabile al quale viene attribuito all'interno di una routine di interrupt.
Attachinterrupt serve appunto per abilitare la generazione di un determinato tipo di interrupt e legato ad una specifica routine.
In quel caso viene abilitato l'interrupt sul passaggio da livello logico basso ad alto dell ingresso pin 2 (interrupt 0)
Isr è la routine di interrupt,viene richiamata come ti ho spiegato la riga sopra.

Nota bene che con Arduino uno puoi gestire solo 2 interrupt legati agli ingressi,quindi se il tuo obiettivo è gestirne di più devi usare un approccio diverso.
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ti ringrazio per la spiegazione,
non fa niente se Arduino ne accetta solo 2 di interrupt,
mi interessa per il momento farlo funzionare,
finisco con questo approccio e poi ne proviamo un altro,
in modo da completare il topic per tutti.
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

se solo ci fosse un dizionario completo in italiano
per capire ogni dettaglio sul linguaggio di programmazione..
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

attachInterrupt(0, isr, FALLING);
mi da errore, mi dice "0 was not declared in this scope",
come lo devo dichiarare a inizio sketch?

seconda domanda,
In quel caso viene abilitato l'interrupt sul passaggio da livello logico basso ad alto dell ingresso pin 2 (interrupt 0)
perchè l'interrupt 0 è il pin 2?

proprio non riesco a capire come si fà questo sketch..
Logged

MC
Offline Offline
God Member
*****
Karma: 13
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Zero sta a significare INT0 ovvero l'interupt legato al cambio di stato del pin 2 , cosi come invece INT1 è legato al cambio di stato per il pin 3.
Ma che versione Arduino usi? E che scheda?
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino UNO rev.3
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per gestire più di due contatti a fune si potrebbe forse utilizzare un approccio diversi rispetto a  1 sensore == 1 interrupt pin.
Si potrebbe collegare ogni contatto ad un pin digitale "normale" (cioè non collegato ad un interrupt), e poi in qualche modo mettere in "OR" tutti i segnali dei sensori verso un interrupt pin. La ISR dovrebbe per prima cosa leggere lo stato dei vari pin per controllare quale di questi ha generato l'interrupt, e incrementare gli opportuni contatori di conseguenza.
Un sistema simile l'ho sperimentato con alcuni pulsanti collegati ad un PCF8574 (che lavora su i2c). In pratica viene generato uin interrupt qualunque pulsante sia premuto; la ISR chiede al chip lo stato dei suoi input e verifica così lo stato di tutti i pulsanti. Con un integrato del genere si potrebbero gestire 8 sensori.
L'unico dubbio è sulla tempistica, ovvero: il codice della ISR può essere sufficientemente veloce per gestire, ad esempio, due tapparelle che si muovono contemporaneamente ?
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

no no, meglio di no, a questo punto preferisco
una strada diversa da quella dell'interrupt..
comunque, tanto per finire la questione,
mi dici perchè
Code:
attachInterrupt(0, isr, FALLING);
mi da errore di attribuzione su 0?
se il pin 2 corrisponde all'interrupt0
non va più bene la dichiarazione della costante
Code:
const int impulsoPin = 2;
void setup(){
pinMode(impulsoPin, INPUT);
}
di questo genere?
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Questa nuova versione dovrebbe funzionare meglio (chiedo commenti). Inoltre ho aggiunto commenti sperando di chiarire meglio le istruzioni.

Credo che non ci sia alternativa all'uso degli interrupt.

Code:
// ogni quanti ms controllare il numero di impulsi
const unsigned long IMP_CHECK_INTERVAL_MS = 500;

// variabile utilizzata per la temporizzazione del controllo
// del numero di impulsi
unsigned long _impCheckIntervalPrevMillis = 0;

// se rilevo questo numero di impulsi nell'arco
// di tempo identificato da IMP_CHECK_INTERVAL_MS,
// segnalo allarme
const byte NUM_IMPULSI_ALLARME = 5;

// variabile utilizzata per contare gli impulsi
// il qualificatore "volatile" è necessario in quanto
// questa variabile viene utilizzata sia dalla ISR
// che dal ciclo principale
volatile byte numImpulsi = 0;


// funzione chiamata all'arrivo di un interrupt;
// il nome specifico non è importante;
// questa funzione deve essere il più breve possbile
void contaImpulsiISR() {
    numImpulsi++;
}


// funzione eseguita quando viene rilevata la condizione allarme
void allarmeRilevato() {
    // codice di esempio
    Serial.println("allarme");
}


void setup() {
    // impostazinoe della seriale hardware
    // il serial monitor dell'IDE deve essere impostato
    // sulla stessa velocità di tramissione
    Serial.begin(115200);
   
    // segnala che la funzione denominata "isr" va eseguita
    // quando lo stato del pin legato all'interrupt zero (su Arduino UNO è il pin 2)
    // cambia stato
    attachInterrupt(0, contaImpulsiISR, CHANGE);
}



void loop() {
   
    // ogni tot millisecondi controlla quanti impulsi sono stati contati
    // azzera il contatore per evitare che impulsi spuri (rumore)
    // si accumulino e generino dei falsi allarmi
    if (millis() - _impCheckIntervalPrevMillis >= IMP_CHECK_INTERVAL_MS) {
        _impCheckIntervalPrevMillis = millis();
       
        // disabilita gli interrupt per evitare che tra la lettura
        // venga eseguita la ISR
        noInterrupts();
        boolean allarme = (numImpulsi >= NUM_IMPULSI_ALLARME) ? true : false;
        numImpulsi = 0;
        // riabilita gli interrupt
        interrupts();
       
        // se il numero di impulsi conteggiati supera la soglia di allarme,
        // esegui la funzione di segnalazione allarme
        if (allarme) {
            allarmeRilevato();
        }
    }
}


Per capire il meccanismo che coinvolge millis() ti consiglio di studiare l'esempio denominato "blink without delay"(*). Tecnicamente la definirei temporizzazione non bloccante. E' una tecnica indispensabile per qualunque programma non banale, che sostituisce la funzione delay() (da abbandonare il prima possibile).

Se sei completamente a digiuno di C/C++, non credo tu possa andare molto lontano senza studiare almeno le basi del linguaggio indipendentemente da Arduino. Ti consiglio di dare un'occhiata qui: http://www.cplusplus.com/doc/tutorial/

Comunque su questo forum basta mostrare di metterci impegno e si ottiene tutto l'aiuto che si vuole (tempo permettendo) smiley

PS: il codice in questo post compila correttamente sotto Arduino 1.0.3, ma non l'ho provato nella pratica.

(*) Nell'IDE, seleziona File => Exempi => Digital => Blink without delay
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino UNO rev.3

E' necessario conoscere anche la versione del software che usi. Se hai scaricato il pacchetto dal sito ultimamente dovresti avere la 1.0.3.
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

straordinario!
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sei hai modo di provare il codice con un tuo sensore, ti sarei grato se postassi il risultato.  smiley
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

si, dunque ho aggiunto una costante output
per accendere il led in caso di allarme..
mi va in allarme dopo 2 click, si accende il led
ma mi rimane sempre acceso.. quindi semmai dovessi abilitare
un relè 5V su quella uscita, mi rimarrebbe perennemente eccitato.
cosa posso aggiungere per terminare l'attivazione dell'uscita?

per il resto tutto ok!
Logged

Vasto (CH)
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ma perchè si devono per forza usare gli interrupt,
con i wich, break e i goto e altra roba non si riesce?
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

si, dunque ho aggiunto una costante output
per accendere il led in caso di allarme..
mi va in allarme dopo 2 click, si accende il led
ma mi rimane sempre acceso.. quindi semmai dovessi abilitare
un relè 5V su quella uscita, mi rimarrebbe perennemente eccitato.
cosa posso aggiungere per terminare l'attivazione dell'uscita?

per il resto tutto ok!

Anche se intuisco cosa significhi "ho aggiunto una costante output", tecnicamente non significa nulla. Probabilmente hai aggiunto una riga come:
Code:
pinMode(relePin, OUTPUT);
nella funzione setup() e qualcosa come
Code:
digitalWrite(relePin, HIGH);
in loop().
Comunque per evitare fraintendimenti ti consiglio di postare il codice completo dello sketch modificato, eventualmente indicando le modifiche con un commento.

Nel merito:
- immagino che per "click" tu ti riferisca al rumore fatto dal sensore mentre tiri il filo... se è così il comportamento mi sembra corretto, in quanto ho messo 5 conteggi su un interrupt di tipo CHANGE e ogni "click" presumibilmente apre/chiude il contatto...
In sintesi: prova a modificare NUM_IMPULSI_ALLARME e a prendere nota di quanti "click" servono per andare in allarme.
- se il contatto è pulito, forse bisogna attivare il pullup interno o (forse meglio) mettere una resistenza sul pin 2 di Arduino da 10k verso 5V (qualche esperto di HW mi corregga se sbaglio)
- per quanto riguarda il passaggio dallo stato di allarme a quello di riposo, si potrebbe mettere un timeout, scaduto il quale viene chiamata una funzione tipo "allarmeTerminato", eventualmente affiancandolo da un pulsante che in un sistema reale sarebbe un segnale HIGH/LOW proveniente dal modulo tastiera, e che assume un particolare stato quando l'utente digita il codice corretto di disattivazione...
Logged

Pages: 1 2 [3] 4   Go Up
Jump to: