Serratura con Encoder a Quadratura

Un’alternativa alla classica serratura dotata di codice di sicurezza inseribile tramite una tastiera, una chiave codificata o un RFID, è quella di utilizzare un encoder a quadratura, dotato di interruttore a pulsante.

un sistema paragonabile a quello di una cassaforte, apribile, ruotando a destra e a sinistra, una manopola numerata, con l’obbiettivo di indovinare i codici di apertura.

Il programma descritto di seguito utilizza un encoder a quadratura, per l’individuazione di due codici, limitati a due per semplicità di descrizione; aumentando le opzioni di “Switch Case”, è possibile rendere più difficile l’identificazione dei codici.

Il programma prevede la possibilità di commettere un errore su tre tentativi di inserimento, prima che scatti l’allarme, disinseribile unicamente con l’intervento di un operatore esterno.

 variabili

La variabile SwA di tipo Bool ha solo due stati, uno e zero; è assegnata al pulsante utilizzato per acquisire il valore dell’encoder.

La variabile CountSwA di tipo Byte, valori compresi tra 0 e 255; è utilizzata per lo Switch Case.

La variabile Count, di tipo Int, con valori compresi tra -32768 e + 3276; contiene il valore del contatore dell’encoder utilizzato dal Component Macro Count=QuadEncoder::ReadCounter().

La variabile Changed, di tipo Bool, contiene il valore della lettura dell’encode; utilizzato dal Component Macro Changed=QuadEncoder::CheckForChanges().

Le variabili COD1 e COD2, di tipo Int; utilizzate per gestire l’allarme e l’apertura della serratura.

La variabile Delay, di tipo Uint, valore compreso tra 0 e 65535; è utilizzata, alla fine del programma, in sostituzione della funzione Delay.

encoder glcd variabili

Pannello simulazione:  2D Dashboard Panel

encoder glcd dashboard

dal menu Inputs, inserisco l’encoder a quadratura della 2D Dashboard e tramite il pannello properties, lo collego ai bit 0 e 1 della porta D.

Dal menu Inputs, inserisco nella 2D dashboard il pulsante e lo collego al bit 6 della porta D.

Dal menu Outputs, inserisco nella 2D dashboard il led e lo collego al pin 7 della porta D.

Dal menu Displays, inserisco nella 2D Dashboard un pannello gLCD_ILI9341_SPI, e tramite il pannello Properties, verifico il collegamento MOSI, MISO e CLK alla porta B e imposto la visualizzazione in Bitmap

Diagramma di flusso

encoder glcd inizializ

inizializzazione:

  • gLCD_ILI9341_SPI::Initialize(): inizializzo il display grafico.
  • QuadEncoder::Enable(): abilito l’encoder a quadratura.
  • QuadEncoder::ResetCounter(): azzero il contatore dell’encoder.

Azzero le variabili con la funzione Calcolo:

  • $PORTD7= 0:  metto a zero il pin 7 della porta D.
  • COD1= 0:        azzero la variabile COD1.
  • COD2= 0:        azzero la variabile COD2.
  • Count= 0:       azzero la variabile Count.
encoder glcd ciclo codici

Imposto i codici per l’apertura della serratura:

funzione Calcolo:

  • Codice1 = 15
  • Codice2 = -11

Ciclo principale

encoder glcd ciclo

Controllo il movimento dell’encoder.

encoder glcd ciclo checkEncoder

Changed=QuadEncoder::CheckForChange()

Con il Component Macro QuadEncoder::CheckForChange(), verifico se l’encoder è stato mosso  controllando lo stato logico della variabile Changed.

encoder glcd ciclo push

controllo se il pulsante è premuto.

La variabile SwA, di tipo Bool, ha due possibili valori: 1 (tasto premuto) o 0 (tasto non premuto); è associata al pulsante Push, collegato al pin 6 della porta D.

Pulsante Push non premuto:If SwA ≠ 1?

Il programma prosegue diritto, dopo la funzione Decisione.

encoder glcd ciclo no push 2

gLCD_ILI9341_SPI::ClearDisplay()

Count=QuadEncoder::ReadCounter()

gLCD_ILI9341_SPI::printNumber(Count,100,10,12,0)

Delay 100ms

if SwA = 1?: pulsante premuto.

Delay 100 ms: ritardo antirimbalzo; serve per eliminare falsi segnali provenienti dall’encoder.

Il programma prosegue seguendo il percorso a destra della funzione Decisione.

encoder Switc Case

Switch Case

La variabile CountSwA, è incrementata ogni volta che si preme il pulsante Push.

encoder foreground
encoder drawcircle

SetForegroundColour: imposta il colore del testo

DrawCircle: disegna un punto colorato alla posizione indicata da X,Y.

encoder glcd1 SC comuni

Linee di codice comuni alle tre opzioni: lettura Encoder

  • Count=QuadEncoder::ReadCounter(): legge il contatore dell’encoder e lo immagazzina nella variabile Count.
  • gLCD_ILI9341_SPI::SetForegroundColour(0,0,255): imposta il colore visualizzato sul display della variabile Count.
  • gLCD_ILI9341_SPI::PrintNumber(Count,100,150,12,0): visualizza il valore della variabile Count.
  • Primo caso:

if Count ≠ Codice 1?       (inserimento Codice1  errato)

encoder glcd ciclo case1 falso
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0): colora il successivo oggetto in Rosso.
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1): posizione il punto Rosso.
  • Delay 500 ms
  • il programma esce da Switch case ed esegue l’istruzione successiva che verifica se i due codici inseriti sono corretti

if Count = Codice 1?

il numero inserito corrisponde al codice1

  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0): colora il successivo oggetto in Verde.
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1): disegna il punto verde.
encoder glcd ciclo case1 vero

COD1 = COUNT

se il numero inserito corrisponde al primo codice, assegna a COD1 il valore di Count.

  • Delay 500 ms
  • il programma esce da Switch case ed esegue l’istruzione successiva che verifica se i due codici inseriti sono corretti
  • Secondo caso:
encoder glcd secondo caso

if COD1? No: primo numero inserito è errato

Funzione Decisione: if Count = Codice1 ?: secondo tentativo

  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0): colora il successivo oggetto in Verde.
  • gLCD_ILI9341_SPI::DrawCircle 160,80,10,1,1): posizione il secondo punto verde.

COD1 = COUNT

  • se il numero inserito corrisponde al primo codice, assegna a COD1 il valore di Count.

 

    • Delay 500 ms: il programma esegue l’ istruzione successiva.
encoder glcd1 codice2

Funzione Decisione: if Count = Codice2 ?:

  • se il primo numero inserito è corretto, inserisco il secondo numero
  • se il numero inserito corrisponde al codice2
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0): setta il colore  che segue in Verde
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1):posiziona il primo punto Verde.
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0):setta  in Verde il colore.
  • gLCD_ILI9341_SPI::DrawCircle(160,80,10,1,1):posiziona il secondo punto Verde.

COD2 = COUNT

se il numero inserito corrisponde al secondo codice, assegna a COD2 il valore di Count.

 

  • Delay 500 ms:
  • il programma esce da SwitchCase ed esegue l’istruzione successiva che verifica se i due codici inseriti sono corretti

if COD1? No e if Count  Codice2 ? No

  • il programma esce da SwitchCase ed esegue l’istruzione successiva, quindi il ciclo si ripete, ma al successivo inserimento chiama la macro ” ALLARME” e si blocca.
  • Dopo il terzo inserimento, corretto o errato che sia, non è possibile indovinare il codice rimanente.

encoder glcd inserimento secondo numero

if COD1?Yes: primo numero inserito è corretto.

  • inserisco il secondo numero

if count diverso da Codice2?

il secondo numero inserito è errato.

 

  • gLCD_ILI9341_SPI::SetForegroundColour(255,0,0)
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1)

 

  • COD2 = 0: azzero COD2

 

  • Delay 500 ms

 

  • il programma esce da Switch case ed esegue l’istruzione successiva, quindi il ciclo si ripete, ma al successivo inserimento chiama la macro ” ALLARME” e si blocca.
  • Dopo il terzo inserimento, corretto o errato che sia, non è possibile indovinare il codice rimanente.

if count = Codice2?

il secondo numero inserito è corretto.

  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0)
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1)
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0)
  • gLCD_ILI9341_SPI::DrawCircle(160,80,10,1,1)

 

COD2 = Count

se il numero inserito corrisponde al secondo codice, assegna a COD2 il valore di Count.

  • Delay 500 ms

 

il programma esce da SwitchCase ed esegue il programma di verifica codici:

Se i due codici sono corretti, chiama la macro “APERTO”

Esegue l’utimo programma di Delay quindi il ciclo ricomincia dall’inizio

 

  • Terzo caso:
  • Count=QuadEncoder::ReadCounter(): legge il contatore dell’encoder e lo immagazzina nella variabile Count.
  • gLCD_ILI9341_SPI::SetForegroundColour(0,0,255): imposta il colore visualizzato sul display della variabile Count.
  • gLCD_ILI9341_SPI::PrintNumber(Count,100,150,12,0): visualizza il valore della variabile Count
encoder glcd terzo caso

if COD1? = No

chiama la macro “ALLARME

il programma si blocca con il display lampeggiante.

if COD1? = Yes

if Count = Codice2: no

Call Macro “ALLARME”

if Count = Codice2: yes

  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0)
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1)
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0)
  • gLCD_ILI9341_SPI::DrawCircle(160,80,10,1,1)

COD2 = Count

  • Delay 500 ms

Il programma esce da SwitchCase ed esegue il programma di verifica codici:

Se i due codici sono corretti, chiama la macro “APERTO”

 

Esegue l’utimo programma di Delay quindi il ciclo ricomincia dall’inizio.

programma di verifica Codici:

If COD1 = Codice1 AND COD2 = Codice2:

  • Call Macro “APERTO”

 

if COD1 ≠ Codice1 AND COD2 ≠ Codice2

 

  •    Count = 0: azzera la variabile Count.
  •   CountSwA = 0: azzera la variabile CountSwA; il ciclo SwitchCase riparte dall’inizio.

 

La Macro “APERTO”, è richiamata unicamente quando si verificano, ambedue, le condizioni.

COD1 = 1 e COD2 = 1 (AND booleano)

encoder cicli finali

Termine Ciclo principale.

  • If Delay > 2000 : Delay = 0
  • If Delay < 2000 :Delay = delay + 1

Il ciclo principale riparte dall’inizio.

 

encoder macro allarme

Loop macro “ALLARME

La macro “Allarme,” è un ciclo che si ripete continuamente, facendo lampeggiare i tre i punti e la scritta ALLARME con la cadenza di un secondo.

  • gLCD_ILI9341_SPI::SetForegroundColour(255,0,0): rosso
  • gLCD_ILI9341_SPI::Print(“ALLARME”,100,150,12,0): visualizza la scritta ALLARME in rosso.
  • gLCD_ILI9341_SPI::SetForegroundColour(255,0,0): setta il colore Rosso.
  • gLCD_ILI9341_SPI::DrawCircle(80,80,10,1,1): disegna il primo punto rosso.
  • gLCD_ILI9341_SPI::SetForegroundColour(255,0,0): setta il colore Rosso.
  • gLCD_ILI9341_SPI::DrawCircle(160,80,10,1,1): disegna il secondo punto rosso.
  • gLCD_ILI9341_SPI::SetForegroundColour(255,0,0): setta il colore Rosso.
  • gLCD_ILI9341_SPI::DrawCircle(160,80,10,1,1): disegna il terzo punto rosso.
  • Delay = 1 secondo
  • gLCD_ILI9341_SPI::ClearDisplay(): pulisce il display.
encoder macro aperto

Macro  “APERTO

  • gLCD_ILI9341_SPI::ClearDisplay(): pulisce il display.
  • gLCD_ILI9341_SPI::SetForegroundColour(0,255,0):setta il colore del display verde.
  • gLCD_ILI9341_SPI::Print(“APERTO”,100,150,12,0): visualizza la scritta “APERTO”

 

Output 1 -> D7: accende il led collegato al pin 7 della porta D.

Delay: 3 secondi: il led rimane acceso per 3 secondi.

Output 0 -> D7: spegne il led collegato al pin 7 della porta D.

 

  • Count = 0: azzera la variabile Count.
  • COD1 = 0: azzera la variabile COD1.
  • COD2 = 0: azzera la variabile COD2.
  • CountSwA = 0: azzera la variabile CountSwA.

 

  • gLCD_ILI9341_SPI::SetForegroundColour(0,0,255): setta il colore del display in Blue.

 

C Code

  • Count=QuadEncoder::ReadCounter(): legge il contatore dell’encoder e lo immagazzina nella variabile Count.
  • gLCD_ILI9341_SPI::SetForegroundColour(0,0,255): imposta il colore visualizzato sul display della variabile Count.
  • gLCD_ILI9341_SPI::PrintNumber(Count,100,150,12,0): visualizza il valore della variabile Count
encoder serratura

test serratura con encoder

rick 3Riccardo Monti