Sommario:

Implementazione del sensore di gesti non bloccante APDS9960: 5 passaggi
Implementazione del sensore di gesti non bloccante APDS9960: 5 passaggi

Video: Implementazione del sensore di gesti non bloccante APDS9960: 5 passaggi

Video: Implementazione del sensore di gesti non bloccante APDS9960: 5 passaggi
Video: Le IMPOSTAZIONI da ATTIVARE ASSOLUTAMENTE sul tuo SAMSUNG Galaxy A54 5G ! 2024, Dicembre
Anonim
Implementazione del sensore di gesti APDS9960 non bloccante
Implementazione del sensore di gesti APDS9960 non bloccante
Implementazione del sensore di gesti APDS9960 non bloccante
Implementazione del sensore di gesti APDS9960 non bloccante
Implementazione del sensore di gesti APDS9960 non bloccante
Implementazione del sensore di gesti APDS9960 non bloccante

Preambolo

Questo Instructable descrive in dettaglio come creare un'implementazione non bloccante del sensore di gesti APDS9960 utilizzando SparkFun_APDS-9960_Sensor_Arduino_Library.

introduzione

Quindi probabilmente ti starai chiedendo cos'è il non bloccante? O addirittura bloccando per quella materia?

Ancora più importante, perché è importante avere qualcosa di non bloccante giusto?

Ok, quindi quando un microprocessore esegue un programma esegue in sequenza righe di codice e nel farlo effettua chiamate e ritorna dalle funzioni secondo l'ordine in cui le hai scritte.

Una chiamata di blocco è solo una chiamata a qualsiasi tipo di funzionalità che provoca l'interruzione dell'esecuzione, ovvero una chiamata di funzione in cui il chiamante non riprenderà l'esecuzione fino a quando la funzione chiamata non avrà terminato l'esecuzione.

Quindi perchè è importante?

Nel caso in cui tu abbia scritto del codice che deve eseguire regolarmente molte funzioni in sequenza come leggere una temperatura, leggere un pulsante e aggiornare un display, se il codice per aggiornare il display fosse una chiamata di blocco, il tuo sistema non risponderà a pressione dei pulsanti e variazioni di temperatura, poiché il processore trascorrerà tutto il tempo in attesa che il display si aggiorni e non leggerà lo stato del pulsante o l'ultima temperatura.

Da parte mia, voglio creare un dispositivo desktop IoT compatibile con MQTT su WiFi che legga i valori di temperatura/umidità locali e remoti, i livelli di luce ambientale, la pressione barometrica, tenga traccia del tempo, visualizzi tutti questi parametri su un LCD, acceda a un uSD scheda in tempo reale, leggere gli ingressi dei pulsanti, scrivere sui LED di uscita e monitorare i gesti per controllare le cose nella mia infrastruttura IoT e tutto ciò che deve essere controllato da un ESP8266-12.

Sfortunatamente le uniche due fonti della libreria APDS9960 che ho trovato sono state le librerie SparkFun e AdaFruit, entrambe estratte dal codice dell'applicazione da Avago (il produttore di ADPS9960) e possiedono una chiamata chiamata "readGesture" che contiene a while(1){}; loop che, se utilizzato nel progetto precedente, provoca il ripristino dell'ESP8266-12E ogni volta che il sensore ADPS9960 si satura (ad es. quando un oggetto è rimasto nelle immediate vicinanze o c'era un'altra sorgente IR che illuminava il sensore).

Di conseguenza, per risolvere questo comportamento ho scelto di spostare l'elaborazione dei gesti su un secondo processore per cui ESP8266-12E è diventato il microcontrollore master e questo sistema lo slave, come illustrato rispettivamente nelle immagini 1 e 2 sopra, nei diagrammi Panoramica del sistema e Composizione del sistema. La figura 3 mostra il circuito prototipo.

Per limitare le modifiche che dovevo apportare al mio codice esistente, ho anche scritto una classe/libreria wrapper dal nome fantasioso "APDS9960_NonBlocking".

Quella che segue è una spiegazione dettagliata della soluzione non bloccante.

Di quali parti ho bisogno?

Se vuoi costruire la soluzione I2C che funziona con la libreria APDS9960_NonBlocking avrai bisogno delle seguenti parti.

  1. 1 sconto ATMega328P qui
  2. 1 sconto PCF8574P qui
  3. 6 resistori da 10K qui
  4. 4 off 1K resistori qui
  5. 1 diodo 1N914 qui
  6. 1 off PN2222 NPN Transistor qui
  7. 1 fuori da 16 MHz di cristallo qui
  8. 2 condensatori da 0.1uF qui
  9. 1 condensatore elettrolitico da 1000uF qui
  10. 1 condensatore elettrolitico da 10uF qui
  11. 2 condensatori da 22 pF qui

Se si desidera leggere l'uscita del sensore gestuale tramite l'interfaccia parallela, è possibile eliminare il PCF8574P e tre resistori da 10K.

Di che software ho bisogno?

Arduino IDE 1.6.9

Di quali competenze ho bisogno?

Per configurare il sistema, usa il codice sorgente (fornito) e crea i circuiti necessari di cui avrai bisogno quanto segue;

  • Una conoscenza minima dell'elettronica,
  • Conoscenza di Arduino e del suo IDE,
  • Una comprensione di come programmare un Arduino incorporato (vedi Instructable "Programmazione di ATTiny85, ATTiny84 e ATMega328P: Arduino come ISP")
  • Un po' di pazienza.

Argomenti trattati

  • Breve panoramica del circuito
  • Breve panoramica del software
  • Test del dispositivo di rilevamento dei gesti APDS9960
  • Conclusione
  • Riferimenti

Passaggio 1: panoramica del circuito

Panoramica del circuito
Panoramica del circuito

Il circuito è diviso in due sezioni;

  • Il primo è la conversione seriale da I2C a parallelo realizzata tramite i resistori R8…10 e IC1. Qui R8…R10 imposta l'indirizzo I2C per il chip di espansione I/O a 8 bit IC1 e NXP PCF8574A. Gli intervalli di indirizzi validi per questo dispositivo sono rispettivamente 0x38 … 0x3F. Nell'esempio del software I2C fornito 'I2C_APDS9960_TEST.ino' '#define GESTURE_SENSOR_I2C_ADDRESS' dovrebbe essere modificato per adattarsi a questo intervallo di indirizzi.
  • Tutti gli altri componenti formano un Arduino Uno slave embedded e hanno le seguenti funzioni;

    • R1, T1, R2 e D1 forniscono un ingresso di reset del dispositivo slave. Qui un impulso alto attivo su IC1 - P7 forzerà il reset di U1.
    • R3, R4, sono resistori di limitazione di corrente per le linee TX/RX di programmazione del dispositivo integrato.
    • C5 e R7 consentono all'IDE Arduino di programmare automaticamente U1 tramite un impulso sulla linea DTR di un dispositivo FTDI collegato.
    • R5 e R6 sono resistori pull-up I2C per APDS9960 con C6 che fornisce il disaccoppiamento della linea di alimentazione locale.
    • U1, C1, C2 e Q1 formano rispettivamente l'Arduino Uno integrato e il suo orologio.
    • Infine C3 e C4 forniscono il disaccoppiamento della linea di alimentazione locale per U1.

Passaggio 2: panoramica del software

Panoramica del software
Panoramica del software
Panoramica del software
Panoramica del software
Panoramica del software
Panoramica del software

Preambolo

Per compilare correttamente questo codice sorgente avrai bisogno delle seguenti librerie extra per programmare l'Arduino Uno U1 integrato;

SparkFun_APDS9960.h

  • Di: Steve Quinn
  • Scopo: questa è una versione biforcuta del sensore SparkFun APDS9960 biforcato da jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Ha alcune modifiche per aiutare con il debug e ha un rilevatore desensibilizzato per ridurre l'attivazione spuria.
  • Da:

APDS9960_NonBlocking.h

  • Di: Steve Quinn
  • Scopo: fornisce un'interfaccia pulita per incorporare questa implementazione non bloccante del sensore di gesti APDS9960 nel codice Arduino.
  • Da:

Vedere il seguente Instructable su come programmare un microcontrollore Arduino Uno (ATMega328P) integrato se non si ha familiarità con come ottenere ciò;

PROGRAMMAZIONE DI ATTINY85, ATTINY84 E ATMEGA328P: ARDUINO COME ISP

Panoramica funzionale

Il microcontrollore slave incorporato ATMega328P interroga la linea INT dall'ADPS9960. Quando questa linea diventa bassa, il microcontrollore legge i registri ADPS9960 e determina se è stato rilevato un gesto valido. Se è stato rilevato un gesto valido, il codice per questo gesto 0x0…0x6, 0xF viene posizionato sulla porta B e 'nGestureAvailable' viene dichiarato basso.

Quando il dispositivo Master vede 'nGestureAvailable' attivo, legge il valore sulla porta B, quindi emette temporaneamente un segnale basso di 'nGestureClear' per confermare la ricezione dei dati.

Il dispositivo slave quindi de-asserisce 'nGestureAvailable' alto e cancella i dati sulla porta B. La figura 5 sopra mostra una schermata presa da un analizzatore di stati logici durante un ciclo completo di rilevamento/lettura.

Panoramica del codice

La figura 1 sopra descrive come funziona il software in U1 lo slave Arduino Uno incorporato, insieme alla figura 2 come interagiscono le due attività in background / in primo piano. La figura 3 è un segmento di codice che illustra come utilizzare APDS9960_NonBlockinglibrary. La figura 4 fornisce una mappatura tra i pin digitali Arduino Uno e i pin hardware effettivi sull'ATMega328P.

Dopo il ripristino, il microcontrollore slave incorporato inizializza l'APDS9960 consentendo al rilevamento dei gesti di attivare la sua uscita INT e configura il suo I/O, collegando la routine di servizio di interrupt (ISR) 'GESTURE_CLEAR()' al vettore di interruzione INT0 (pin 2 digitale, pin 4 hardware IC)., configurandolo per un trigger sul fronte di discesa. Questo costituisce l'input nGestureClear dal dispositivo master.

Il pin di uscita Interrupt 'INT' dall'APDS9960 è collegato al Pin digitale 4, Hardware IC Pin 6 che è configurato come ingresso a U1.

La linea di segnale 'nGestureAvailable' sul pin 7 digitale, pin 13 hardware IC è configurata come uscita e impostata su alta, inattiva (de-asserta).

Infine, i bit 0…3 della porta B rispettivamente sono configurati come uscite e impostati a livello basso. Questi formano il nibble di dati che rappresenta i vari tipi di gesto rilevati; Nessuno = 0x0, Errore = 0xF, Su = 0x1, Giù = 0x2, Sinistra = 0x3, Destra = 0x4, Vicino = 0x5 e Lontano = 0x6.

L'attività in background 'Loop' è pianificata che interroga continuamente l'Interrupt output INT di APDS9960 tramite la lettura del Pin digitale 4. Quando l'output INT dell'APDS9960 diventa attivo basso indicando che il sensore è stato attivato, il microcontrollore tenta di interpretare qualsiasi gesto chiamando 'readGesture()' con mentre (1) {}; ciclo infinito.

Se è stato rilevato un gesto valido, questo valore viene scritto sulla porta B, viene asserito l'output 'nGestureAvailable' e viene impostato il semaforo booleano 'bGestureAvailable', impedendo la registrazione di ulteriori movimenti.

Una volta che il master rileva l'uscita 'nGestureAvailable' attiva, legge questo nuovo valore e emette un segnale 'nGestureClear' attivo basso. Questo fronte di discesa attiva la pianificazione dell'attività in primo piano 'ISR GESTURE_CLEAR()', sospendendo l'esecuzione dell'attività in background 'Loop', cancellando la porta B, il semaforo 'bGestureAvailable' e l'output 'nGestureAvailable'.

L'attività in primo piano 'GESTURE_CLEAR()' è ora sospesa e l'attività in background 'Loop' è stata riprogrammata. È ora possibile rilevare ulteriori gesti dall'APDS9960.

Utilizzando in questo modo attività in primo piano/in background attivate da interrupt, il potenziale ciclo infinito in 'readGesture()' del dispositivo slave non influenzerà il funzionamento del dispositivo master e non ostacolerà nemmeno l'esecuzione del dispositivo slave. Ciò costituisce la base di un sistema operativo in tempo reale molto semplice (RTOS).

Nota: il prefisso "n" significa attivo basso o asserito come in "nGestureAvailable"

Passaggio 3: test del dispositivo di rilevamento dei gesti non bloccante APDS9960

Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960
Test del dispositivo di rilevamento dei gesti non bloccante APDS9960

Preambolo

Anche se il modulo APDS9960 è fornito con +5v, utilizza un regolatore +3v3 a bordo, il che significa che le sue linee I2C sono compatibili con +3v3 e non +5v. Questo è il motivo per cui ho scelto di utilizzare Arduino Due conforme a +3v3 come microcontrollore di prova, per ovviare alla necessità di traslatori di livello.

Se, tuttavia, desideri utilizzare un vero Arduino Uno, dovrai spostare le linee I2C su U1. Vedere il seguente Instructable in cui ho allegato un utile set di diapositive (I2C_LCD_With_Arduino) che fornisce molti suggerimenti pratici sull'utilizzo di I2C.

Test dell'interfaccia I2C

Le immagini 1 e 2 sopra mostrano come impostare e programmare il sistema per l'interfaccia I2C. Dovrai prima scaricare e installare la libreria APDS9960_NonBlocking. qui

Test dell'interfaccia parallela

Le immagini 3 e 4 mostrano lo stesso dettaglio per l'interfaccia parallela

Passaggio 4: conclusione

Conclusione
Conclusione

Generale

Il codice funziona bene e rileva i gesti in modo reattivo senza falsi positivi. È stato installato e funzionante per alcune settimane come dispositivo slave nel mio prossimo progetto. Ho provato molte diverse modalità di errore (e così ha fatto il curioso gatto domestico Quinn) che in precedenza aveva provocato un reset di ESP8266-12, senza alcun effetto negativo.

Possibili miglioramenti

  • L'ovvio. Riscrivi la libreria del sensore di gesti APDS9960 in modo che non sia bloccante.

    In realtà ho contattato Broadcom che mi ha messo in contatto con un distributore locale che ha prontamente ignorato la mia richiesta di supporto, ma non sono uno SparkFun o AdaFruit, immagino. Quindi questo probabilmente dovrà aspettare un po'

  • Porta il codice su un microcontrollore slave più piccolo. L'utilizzo di un ATMega328P per un'attività è un po' eccessivo. Anche se inizialmente ho guardato ATTiny84, ho smesso di usarne uno perché sentivo che la dimensione compilata del codice era una linea di confine. Con l'ulteriore sovraccarico di dover modificare la libreria APDS9960 per lavorare con una diversa libreria I2C.

Passaggio 5: riferimenti

Necessario per programmare l'arduino integrato (ATMega328P - U1)

SparkFun_APDS9960.h

  • Di: Steve Quinn
  • Scopo: questa è una versione biforcuta del sensore SparkFun APDS9960 biforcato da jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Ha alcune modifiche per aiutare con il debug e ha un rilevatore desensibilizzato per ridurre l'attivazione spuria.
  • Da:

Necessario per incorporare questa funzionalità non bloccante nel codice Arduino e fornire esempi funzionati

APDS9960_NonBlocking.h

  • Di: Steve Quinn
  • Scopo: fornisce un'interfaccia pulita per incorporare questa implementazione non bloccante del sensore di gesti APDS9960 nel codice Arduino.
  • Da:

Sistema operativo in tempo reale

https://en.wikipedia.org/wiki/Sistema_operativo_in tempo reale

Scheda tecnica APDS9960

https://cdn.sparkfun.com/assets/learn_tutorials/3/2/1/Avago-APDS-9960-datasheet.pdf

Consigliato: