Analisi impulsi contatto a tapparella per antifurti

Bhe non utilizza interrupt, quindi alla fine è identico a quello che hai.
Cosa non capisci del codice di tux?
Possiamo sempre chiarirti qualcosa che non capisci invece di cambiare approccio,impari anche qualcosa di nuovo.

volatile byte cnt = 0;

cos'è volatile, che fa byte?

void isr() {
    cnt++;
}

cos'è isr? che fa ++ su cnt, incrementa di 1?

attachInterrupt(0, isr, FALLING);

cos'è attachInterrupt e perchè ci sono 3 voci anzichè 2 tra parentesi?

if (cnt >= MAX_IMPULSI) {
        cnt = 0;
        }

questo se ho capito bene dice che
se cnt raggiunge un valore maggiore o uguale a 5
riporta il suo valore a zero, giusto?

quindi prima di chiudere la parentesi graffa posso anche aggiungere

digitalWrite (ledPin, HIGH);
delay (3000);

anzichè la comunicazione su display, che non ho?

faccio impianti da 15 anni..

Caro diablotron ...finalmente un mio collega...anche io faccio il tuo mestiere da quasi 13 anni e sinceramente la tua trovata è almeno per me geniale...sai non ci avevo ancora pensato e per questo onore al merito...

Una scheda contaimpulsi per un solo contatto tapparella sappiamo bene quanto costa e con un solo arduino1 possiamo in pratica interfacciare 8 tapparelle come ingressi e ripetere lo stato allarme con 8 uscite a transistor oppure 8 relè con un semplice Uln2804...bravo...

Io poi sono di Chieti o meglio provincia...cià paesà...
Teniamoci in contatto e adesso provo anche io a fare quello che dici e in più ti dò un'altra idea o meglio si può anche pensare di usare una scheda Arduino 1 con una sola uscita relè da collegare alla centrale d'allarme e poi collegare un display lcd per la memoria...
Incomincio a smanettare...

pietro78:

faccio impianti da 15 anni..

Caro diablotron ...finalmente un mio collega...anche io faccio il tuo mestiere da quasi 13 anni e sinceramente la tua trovata è almeno per me geniale...sai non ci avevo ancora pensato e per questo onore al merito...

Una scheda contaimpulsi per un solo contatto tapparella sappiamo bene quanto costa e con un solo arduino1 possiamo in pratica interfacciare 8 tapparelle come ingressi e ripetere lo stato allarme con 8 uscite a transistor oppure 8 relè con un semplice Uln2804...bravo...

piano con le attribuzioni delle idee e dei meriti XD Quando ho realizzato a parlato dei miei nanetti voi forse qui ancora nemmeno c'eravate :wink:
Battute a parte io ho progettato i miei nanetti (chiamati così per le loro dimensioni e per il fatto che ne ho giusto sette montati su tutte le tapparelle di casa). Nel mio caso ho dovuto interfacciarli ai sensori tapparella rotativi, che sono terribili, dal punto di vista degli impulsi, e a dei trasmettitori radio,il tutto alimentato a batteria, visto che ho un sistema wireless. Da allora ho risolto il problema dei falsi allarmi delle mie tapparelle. Non badate alla parte "commerciale" perché non esiste: non produco e non fornisco né PCB né schemi e né circuito, è una cosa che ho fatto per me a scopo di studio e che probabilmente quest'anno sarà pubblicato come lavoro. :wink:

piano con le attribuzioni delle idee e dei meriti

Contentissimo di un suo intervento caro professore le posso dire con tutta onestà che non avevo dubbi riguardo alla sua genialità...
Semplicemente se mi permette la sua idea del nanetto è molto simpatica ma l'idea che ha avuto "diablotron" è forse un tantino più specializzata al nostro settore in quanto l'esigenza nostra è piu mirata sui sensori roller a filo quindi ad esempio:

Roller1---PIN2 Arduino1---che muove---PIN out 6---uscita transistor o relè a 12volt
Roller2---PIN3 Arduino1---che muove---PIN out 7---uscita transistor o relè a 12volt
Roller3---PIN4 Arduino1---che muove---PIN out 8---uscita transistor o relè a 12volt
Roller4---PIN5 Arduino1---che muove---PIN out 9---uscita transistor o relè a 12volt etc...etc.... alla modica cifra dell'arduino 1 e qualche transistor...

Resta comunque il merito che in tempi non sospetti lei aveva già acceso la lampadina dell'idea primordiale riguardo a tale argomento...ma per curiosità il chip in figura del nanetto è per caso un ATtiny xx ??

caro pietro78,
sono contento di aver trovato un collega che ha capito "pienamente"
il motivo per il quale sto cercando di realizzare tutto questo,
infatti la mia idea era quella di sfruttare 6 pin per input e 6 pin per output,
proprio come hai detto tu, per risparmiare il costo di una scheda di analisi
moltiplicata per 6..
è chiaro che, di centraline che non analizzano impulsi ce ne sono poche,
com'è anche chiaro che, e lo dico perchè questo è un forum pubblico,
non so fino a che punto "la legge" ci permetta di sfruttare Arduino
per realizzare un prodotto commerciale a tutti gli effetti,
che noi abbineremo agli impianti.

Per questo io ci tengo a precisare che tutto questo lo faccio per studio,
come forma di prototipazione di un qualcosa che poi andrei
a sviluppare personalmente con i miei mezzi e le mie (poche) conoscenze..
Un passo alla volta..

Non so tu a che livelli stai ma io per ora sono proprio principiante da far pena,
quindi se finisci prima di me fammi sapere! :smiley:

L'idea della segnalazione generica in centrale con memoria su display
e a dir poco geniale, non ci avevo proprio pensato,
forse proprio perchè ho appena cominciato con Arduino
e di idee di sviluppo ne ho ben poche..

buon lavoro allora!

molto interessanti questi nanetti,
potrebbero risolvermi un problema di sabotaggi che ho
su dei contatti radio.. Tali contatti hanno un ingresso AUX
che analizza impulsi dei contatti a fune, che io ho per l'appunto utilizzato..
Mi risultavano frequenti sabotaggi che non si sono più verificati
quando ho chiuso direttamente l'ingresso AUX verso GND, in gergo "ponticellato"..

Perciò, è chiaro che il problema stava nel circuito del contatto a fune..
Potrei provare con questi nanetti,
se si potesse avere lo schema..
:blush:

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.

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.

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

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,

niki77:
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..

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?

Arduino UNO rev.3

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 ?

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è

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

const int impulsoPin = 2;
void setup(){
pinMode(impulsoPin, INPUT);
}

di questo genere?

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.

// 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) :slight_smile:

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

diablotron:
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.

straordinario!

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

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!