venerdì 28 febbraio 2014

Arduino - come contare un numero di eventi occorsi in X secondi evitando l'effetto bouncing

La prova del funzionamento dello sketch può essere fatta facendo parlare in Python un Linux con Arduino, avendo installato la libreria sysv_ipc dal sito http://semanchuk.com/philip/sysv_ipc/.

L'utilizzo di un sistema di controllo per evitare conflitti, come quello fornito dai Linux Semaphores, è altamente consigliabile per risorse che per natura effettuano operazioni su risorse di comunicazione condivise. La risorsa in questione è l'interfaccia Serial di Arduino connessa con l'interfaccia USB del Linux, che fisicamente sono connesse tramite un bus RS485. Con i Linux Semaphores si è sicuri di evitare conflitti su questo tipo di risorse.

Alla fine dell'articolo si trovano due script in Python, leggi_da_nano.py e scrivi_su_nano.py (il mio Arduino è un Nano). Ognuno può fare operazioni sul bus RS485, quindi si usa un semaforo per evitare conflitti.

/*

Simulazione con input da Serial di un programma

per contare il numero di eventi validi in una finestra

temporale di X secondi.

 

Qualsiasi byte ricevuto su Serial e' considerato

come evento.

 

Il programma evita l'effetto bouncing, con un timer

configurabile.

 

Si veda lo schema annesso.

 

*/

 

#define AMPIEZZA_FINESTRA 2000  // Ampiezza temporale della

                                // finestra di lettura,

                                // in millisecondi.

 

#define TIMER_ANTIBOUNCING 500  // Viene contato un solo

                                // evento valido nel

                                // timer antibouncing.

 

char lettera;                   // Per svuotare gli eventi che

                                // arrivano da Serial.

 

int conteggio_eventi;           // Numero di eventi

                                // da contare.

 

boolean finestra_lettura;       // Indica se la finestra di

                                // lettura e' aperta.

 

boolean blocca_conteggio;       // Indica se il conteggio e'

                                // bloccato per evitare

                                // l'effetto bouncing.

 

unsigned long baseTime_finestra_lettura;

// Riferimento temporale per la finestra di lettura.

// In relazione con la variabile finestra_lettura.

 

unsigned long baseTime_blocca_conteggio;

// Riferimento temporale per il blocco del conteggio di eventi

// non validi. In relazione con la variabile blocca_conteggio.

 

void setup() {

  finestra_lettura = false;

  blocca_conteggio = true;

  Serial.begin(38400);

  baseTime_finestra_lettura = 0;

  baseTime_blocca_conteggio = 0;

  conteggio_eventi = 0;

}

 

void loop() {

 

  if (Serial.available() > 0) {

    lettera = Serial.read();

 

    // Detection Point #1

    if (finestra_lettura == false) {

      finestra_lettura = true;

      baseTime_finestra_lettura = millis();

      blocca_conteggio = false;

      baseTime_blocca_conteggio = millis();

      conteggio_eventi += 1;

      blocca_conteggio = true;

    }

    else {

      // Detection Point #3

      if (blocca_conteggio == false) {    

        baseTime_blocca_conteggio = millis();

        conteggio_eventi += 1;

        blocca_conteggio = true;

      }

    }

  }

 

  if (finestra_lettura == true) {

    // Detection Point #2

    if ((millis() - baseTime_blocca_conteggio) >= TIMER_ANTIBOUNCING) {

      blocca_conteggio = false;

      baseTime_blocca_conteggio = 0;

    }

  }

 

  if ((millis() - baseTime_finestra_lettura) >= AMPIEZZA_FINESTRA) {

    // Detection Point #4

    if (finestra_lettura == true) {

      Serial.print("Ho ricevuto ");

      Serial.print(conteggio_eventi);

      Serial.print(" eventi");

    }

    baseTime_finestra_lettura = 0;

    finestra_lettura = false;

    baseTime_blocca_conteggio = 0;

    blocca_conteggio = true;

    conteggio_eventi = 0;

  }

 

}

 

 

 


leggi_da_nano.py

#!/usr/bin/env python

import serial
import time
import sysv_ipc

ser = serial.Serial('/dev/ttyUSB0')
ser.baudrate = 38400
ser.timeout = 0.05

try:
    semaforo = sysv_ipc.Semaphore(1235, sysv_ipc.IPC_CREX, mode = 0666, initial_value = 1)
except:
    semaforo = sysv_ipc.Semaphore(1235)

try:
    while True:
        semaforo.acquire()
        a = ser.read(255)
        semaforo.release()
        if a != '':
            print a

except KeyboardInterrupt:
    semaforo.remove()
    print "Ciao ciao"



scrivi_su_nano.py

#!/usr/bin/env python

import serial
import time
import sysv_ipc
ser = serial.Serial('/dev/ttyUSB0')
ser.baudrate = 38400
ser.timeout = 0.05
try:
    semaforo = sysv_ipc.Semaphore(1235, sysv_ipc.IPC_CREX, mode = 0666, initial_value = 1)
except:
    semaforo = sysv_ipc.Semaphore(1235)

try:
    while True:
        semaforo.acquire()
        ser.write('P')
        semaforo.release()
        time.sleep(0.2)
        semaforo.acquire()
        ser.write('P')
        semaforo.release()
        time.sleep(0.9)

except KeyboardInterrupt:
    semaforo.remove()
    print "Ciao ciao"


Nessun commento:

Posta un commento