Cuprins:

Implementarea senzorului de gest APDS9960 NonBlocking: 5 pași
Implementarea senzorului de gest APDS9960 NonBlocking: 5 pași

Video: Implementarea senzorului de gest APDS9960 NonBlocking: 5 pași

Video: Implementarea senzorului de gest APDS9960 NonBlocking: 5 pași
Video: Control Arduino with Python using Firmata / PyFirmata 2024, Noiembrie
Anonim
Implementarea senzorului de gest APDS9960 NonBlocking
Implementarea senzorului de gest APDS9960 NonBlocking
Implementarea senzorului de gest APDS9960 NonBlocking
Implementarea senzorului de gest APDS9960 NonBlocking
Implementarea senzorului de gest APDS9960 NonBlocking
Implementarea senzorului de gest APDS9960 NonBlocking

Preambul

Acest instructabil detaliază cum să creați o implementare non-blocantă a senzorului de gest APDS9960 utilizând SparkFun_APDS-9960_Sensor_Arduino_Library.

Introducere

Deci, probabil, vă întrebați ce este non-blocarea? Sau chiar blocarea pentru asta?

Mai important, de ce este important să aveți ceva care nu blochează, nu?

Ok, deci atunci când un microprocesor rulează un program, execută secvențial linii de cod și, în acest fel, face apeluri și revine din funcții în funcție de ordinea în care le-ați scris.

Un apel de blocare este doar un apel către orice fel de funcționalitate care determină oprirea executării, ceea ce înseamnă un apel funcțional în care apelantul nu va relua execuția până când funcția apelată nu se termină de executat.

Deci, de ce este important acest lucru?

În cazul în care ați scris un cod care trebuie să execute în mod regulat o mulțime de funcții secvențial, cum ar fi citirea unei temperaturi, citirea unui buton și actualizarea unui afișaj, în cazul în care codul pentru actualizarea afișajului este un apel de blocare, sistemul dvs. nu va răspunde la butoanele apăsate și modificările de temperatură, deoarece procesorul își va petrece tot timpul așteptând actualizarea afișajului și nu citind starea butonului sau cea mai recentă temperatură.

La rândul meu, vreau să creez un dispozitiv desktop IoT compatibil MQTT prin WiFi, care citește atât valorile temp / umiditate locale, cât și la distanță, nivelurile de lumină ambientală, presiunea barometrică, ține evidența timpului, afișează toți acești parametri pe un LCD, conectează-te la un uSD card în timp real, citiți intrările butoanelor, scrieți la LED-urile de ieșire și monitorizați gesturile pentru a controla lucrurile din infrastructura mea IoT și toate acestea să fie controlate de un ESP8266-12.

Din păcate, singurele două surse de bibliotecă APDS9960 pe care le-am putut găsi au fost bibliotecile SparkFun și AdaFruit, ambele extrase din codul aplicației de la Avago (producătorul ADPS9960) și care posedă un apel numit „readGesture” care conține un timp (1) {}; buclă care, atunci când este utilizată în proiectul de mai sus, determină resetarea ESP8266-12E ori de câte ori senzorul ADPS9960 s-a saturat (de exemplu, atunci când un obiect a rămas în imediata apropiere sau a existat o altă sursă IR care luminează senzorul).

În consecință, pentru a rezolva acest comportament, am ales să mut procesarea Gesturilor la un al doilea procesor prin care ESP8266-12E a devenit microcontrolerul principal și acest sistem sclav, așa cum este descris în imaginile 1 și 2 de mai sus, schemele de ansamblu ale sistemului și respectiv ale compoziției sistemului.. Pic 3 arată circuitul prototip.

Pentru a limita modificările pe care trebuia să le fac la codul meu existent, am scris și o clasă / bibliotecă de împachetare numită „APDS9960_NonBlocking”.

Ceea ce urmează este o explicație detaliată a soluției non-blocante.

De ce piese am nevoie?

Dacă doriți să construiți soluția I2C care funcționează cu biblioteca APDS9960_NonBlocking, veți avea nevoie de următoarele părți.

  1. 1 de pe ATMega328P aici
  2. 1 off PCF8574P aici
  3. 6 rezistențe 10K aici
  4. 4 off rezistențe 1K aici
  5. 1 off 1N914 Diode aici
  6. 1 off PN2222 NPN tranzistor aici
  7. 1 off cristal de 16 MHz aici
  8. 2 off 0.1uF condensatori aici
  9. 1 off 1000uF condensator electrolitic aici
  10. 1 off condensator electrolitic 10uF aici
  11. 2 off 22pF condensatori aici

Dacă doriți să citiți ieșirea senzorului de gest prin interfața paralelă, puteți renunța la PCF8574P și trei rezistențe de 10K.

De ce software am nevoie?

Arduino IDE 1.6.9

De ce abilități am nevoie?

Pentru a configura sistemul, utilizați codul sursă (furnizat) și creați circuitele necesare, veți avea nevoie de următoarele;

  • O înțelegere minimă a electronicii,
  • Cunoașterea Arduino și a IDE-ului său,
  • O înțelegere a modului de programare a unui Arduino încorporat (vezi instructabil „Programarea ATTiny85, ATTiny84 și ATMega328P: Arduino ca ISP”)
  • Ceva răbdare.

Subiecte acoperite

  • Scurtă prezentare generală a circuitului
  • Scurtă prezentare generală a software-ului
  • Testarea dispozitivului de detectare a gesturilor APDS9960
  • Concluzie
  • Referințe

Pasul 1: Prezentare generală a circuitului

Prezentare generală a circuitului
Prezentare generală a circuitului

Circuitul este împărțit în două secțiuni;

  • Primul este conversia serial I2C în paralel realizată prin rezistoarele R8 … 10 și IC1. Aici R8 … R10 setează adresa I2C pentru cipul de expansiune I / O de 8 biți IC1 un NXP PCF8574A. Intervalele de adrese valide pentru acest dispozitiv sunt respectiv 0x38… 0x3F. În exemplul de software I2C furnizat, „I2C_APDS9960_TEST.ino” „#define GESTURE_SENSOR_I2C_ADDRESS” ar trebui modificat pentru a se potrivi acestui interval de adrese.
  • Toate celelalte componente formează un Arduino Uno încorporat în sclav și au următoarele funcții;

    • R1, T1, R2 și D1 furnizează o intrare de resetare a dispozitivului slave. Aici, un impuls activ activ pe IC1 - P7 va forța U1 să reseteze.
    • R3, R4, sunt rezistențe de limitare a curentului pentru dispozitivul încorporat care programează liniile TX / RX.
    • C5 și R7 permit Arduino IDE să programeze automat U1 printr-un impuls pe linia DTR a unui dispozitiv FTDI atașat.
    • R5 și R6 sunt rezistențe I2C pentru APDS9960 cu C6 care asigură decuplarea șinei de alimentare locale.
    • U1, C1, C2 și Q1 formează Arduino Uno încorporat și respectiv ceasul său.
    • În cele din urmă, C3 și C4 asigură decuplarea șinelor de alimentare locală pentru U1.

Pasul 2: Prezentare generală a software-ului

Prezentare generală a software-ului
Prezentare generală a software-ului
Prezentare generală a software-ului
Prezentare generală a software-ului
Prezentare generală a software-ului
Prezentare generală a software-ului

Preambul

Pentru a compila cu succes acest cod sursă, veți avea nevoie de următoarele biblioteci suplimentare pentru a programa Arduino Uno U1 încorporat;

SparkFun_APDS9960.h

  • De: Steve Quinn
  • Scop: Aceasta este o versiune bifurcată a senzorului SparkFun APDS9960 bifurcat de la jonn26 / SparkFun_APDS-9960_Sensor_Arduino_Library. Are câteva modificări pentru a ajuta la depanare și are un detector desensibilizat pentru a reduce declanșarea falsă.
  • De la:

APDS9960_NonBlocking.h

  • De: Steve Quinn
  • Scop: Oferă o interfață curată pentru a încorpora această implementare fără blocare a senzorului de gest APDS9960 în codul dvs. Arduino.
  • De la:

Consultați următoarele Instrucțiuni despre cum să programați un microcontroler încorporat Arduino Uno (ATMega328P) dacă nu sunteți familiarizat cu cum să realizați acest lucru;

PROGRAMAREA ATTINY85, ATTINY84 ȘI ATMEGA328P: ARDUINO CA ISP

Prezentare generală funcțională

Microcontrolerul slave încorporat ATMega328P sondează linia INT din ADPS9960. Când această linie scade, microcontrolerul citește registrele ADPS9960 și determină dacă a existat un gest valid detectat. Dacă a fost detectat un gest valid, codul pentru acest gest 0x0 … 0x6, 0xF este plasat pe portul B și „nGestureAvailable” este afirmat scăzut.

Când dispozitivul Master vede activ „nGestureAvailable”, citește valoarea din portul B, apoi pulsează „nGestureClear” temporar pentru a confirma primirea datelor.

Dispozitivul sclav anulează apoi „nGestureAvailable” ridicat și șterge datele din portul B. Imaginea 5 de mai sus arată o captură a ecranului preluată de la un analizor logic în timpul unui ciclu complet de detectare / citire.

Prezentare generală a codului

Imaginea 1 de mai sus detaliază modul în care funcționează software-ul din U1 sclavul încorporat Arduino Uno, împreună cu Imaginea 2 modul în care interacționează cele două sarcini de fundal / prim plan. Pic 3 este un segment de cod care prezintă modul de utilizare a bibliotecii APDS9960_NonBlocking. Pic 4 oferă o mapare între pinii Arduino Uno digitale și pinii hardware reali de pe ATMega328P.

După resetare, microcontrolerul încorporat inițializează APDS9960 permițând detectarea gesturilor să declanșeze ieșirea INT și configurează I / O, atașând rutina de servicii de întrerupere (ISR) 'GESTURE_CLEAR ()' pentru a întrerupe vectorul INT0 (pin digital 2, pin IC 4 hardware), configurându-l pentru un declanșator de margine de cădere. Aceasta formează intrarea nGestureClear de pe dispozitivul principal.

Pinul de ieșire de întrerupere „INT” de la APDS9960 este conectat la pinul digital 4, pinul IC 6 hardware care este configurat ca intrare la U1.

Linia de semnal „nGestureAvailable” de pe pinul digital 7, pinul IC 13 hardware este configurat ca o ieșire și setat ridicat, inactiv (dezactivat).

În cele din urmă, biții de port B 0 … respectiv 3 sunt configurați ca ieșiri și stabiliți scăzut. Acestea formează nibble de date care reprezintă diferitele tipuri de gesturi detectate; None = 0x0, Error = 0xF, Up = 0x1, Down = 0x2, Left = 0x3, Right = 0x4, Near = 0x5 și Far = 0x6.

Este programată sarcina de fundal „Buclă” care sondează continuu APDS9960 întrerupe ieșirea INT prin citirea Pinului digital 4. Când ieșirea INT de la APDS9960 devine activă, indicând că senzorul a fost declanșat, microcontrolerul încearcă să interpreteze orice gest apelând „readGesture () 'cu it's while (1) {}; bucla nesfârșită.

Dacă a fost detectat un gest valid, această valoare este scrisă în portul B, ieșirea „nGestureAvailable” este afirmată și semaforul boolean „bGestureAvailable” este setat, împiedicând înregistrarea oricăror alte gesturi.

Odată ce masterul detectează ieșirea activă „nGestureAvailable”, citește această nouă valoare și pulsează „nGestureClear” activ scăzut. Această margine descendentă declanșează sarcina de prim-plan „ISR GESTURE_CLEAR ()” pentru a fi programată suspendarea executării sarcinii de fundal „Buclă”, ștergerea portului B, semaforul „bGestureAvailable” și ieșirea „nGestureAvailable”.

Sarcina de prim-plan „GESTURE_CLEAR ()” este acum suspendată și sarcina de fundal „Buclă” a fost reprogramată. Acum pot fi sesizate alte gesturi de la APDS9960.

Prin utilizarea sarcinilor de prim-plan / fundal declanșate de întrerupere în acest mod, bucla infinită potențială din „readGesture ()” a dispozitivului slave nu va afecta dispozitivul master să funcționeze și nici nu va împiedica executarea dispozitivului slave. Aceasta constituie baza unui sistem de operare foarte simplu în timp real (RTOS).

Notă: Prefixul „n” înseamnă activ scăzut sau afirmat ca în „nGestureAvailable”

Pasul 3: Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking

Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking
Testarea dispozitivului de detectare a gesturilor APDS9960 NonBlocking

Preambul

Chiar dacă modulul APDS9960 este furnizat cu + 5v, folosește un regulator de bord + 3v3, ceea ce înseamnă că liniile I2C sunt compatibile cu + 3v3 și nu + 5v. Acesta este motivul pentru care am ales să folosesc Arduino Due compatibil cu + 3v3 ca microcontroler de testare, pentru a înlătura necesitatea schimbătorilor de nivel.

Cu toate acestea, dacă doriți să utilizați un Arduino Uno real, atunci ar trebui să schimbați liniile I2C la U1. Consultați Instrucțiunile următoare în care am atașat un set de diapozitive utile (I2C_LCD_With_Arduino) care oferă o mulțime de sfaturi practice despre utilizarea I2C.

Testarea interfeței I2C

Imaginile 1 și 2 de mai sus arată cum să configurați și să programați sistemul pentru interfața I2C. Mai întâi va trebui să descărcați și să instalați biblioteca APDS9960_NonBlocking. Aici

Testarea interfeței paralele

Fotografiile 3 și 4 detaliază același lucru pentru interfața paralelă

Pasul 4: Concluzie

Concluzie
Concluzie

General

Codul funcționează bine și detectează gesturile în mod responsabil, fără falsuri pozitive. Funcționează de câteva săptămâni acum ca dispozitiv sclav în următorul meu proiect. Am încercat multe moduri de eșec diferite (la fel și curiosul moggie Quinn de uz casnic) care a dus anterior la o resetare ESP8266-12, fără efect negativ.

Posibile îmbunătățiri

  • Evidentul. Re-scrieți biblioteca APDS9960 Gesture Sensor pentru a nu fi blocantă.

    De fapt, am luat legătura cu Broadcom, care m-a adresat unui distribuitor local care a ignorat prompt solicitarea mea de asistență, cred că nu sunt SparkFun sau AdaFruit. Deci, probabil că va trebui să aștepte un timp

  • Portează codul pe un microcontroler slave mai mic. Utilizarea unui ATMega328P pentru o sarcină este un pic excesivă. Deși m-am uitat inițial la ATTiny84, am încetat să mai folosesc unul, deoarece am simțit că dimensiunea compilată a codului era potrivită pentru linia de frontieră. Cu cheltuielile suplimentare adăugate de a trebui să modificați biblioteca APDS9960 pentru a funcționa cu o altă bibliotecă I2C.

Pasul 5: Referințe

Necesar pentru programarea arduino-ului încorporat (ATMega328P - U1)

SparkFun_APDS9960.h

  • De: Steve Quinn
  • Scop: Aceasta este o versiune bifurcată a senzorului SparkFun APDS9960 bifurcat de la jonn26 / SparkFun_APDS-9960_Sensor_Arduino_Library. Are câteva modificări pentru a ajuta la depanare și are un detector desensibilizat pentru a reduce declanșarea falsă.
  • De la:

Este necesar să încorporați această funcționalitate care nu blochează în codul dvs. arduino și să dați exemple funcționale

APDS9960_NonBlocking.h

  • De: Steve Quinn
  • Scop: Oferă o interfață curată pentru a încorpora această implementare fără blocare a senzorului de gest APDS9960 în codul dvs. Arduino.
  • De la:

Sistem de operare în timp real

https://en.wikipedia.org/wiki/Real-time_operating_system

Foaie de date APDS9960

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

Recomandat: