Innehållsförteckning:

Icke -blockerande APDS9960 gestsensorimplementering: 5 steg
Icke -blockerande APDS9960 gestsensorimplementering: 5 steg

Video: Icke -blockerande APDS9960 gestsensorimplementering: 5 steg

Video: Icke -blockerande APDS9960 gestsensorimplementering: 5 steg
Video: David Icke talks conspiracy theories - BBC News 2024, November
Anonim
Icke -blockerande APDS9960 gestsensorimplementering
Icke -blockerande APDS9960 gestsensorimplementering
Icke -blockerande APDS9960 gestsensorimplementering
Icke -blockerande APDS9960 gestsensorimplementering
Icke -blockerande APDS9960 gestsensorimplementering
Icke -blockerande APDS9960 gestsensorimplementering

Inledning

Denna instruktion beskriver hur du skapar en icke-blockerande implementering av APDS9960 gestsensor med SparkFun_APDS-9960_Sensor_Arduino_Library.

Introduktion

Så du frågar dig förmodligen vad som är icke-blockerande? Eller till och med blockera för den delen?

Ännu viktigare varför är det viktigt att ha något som inte blockerar rätt?

Ok, så när en mikroprocessor kör ett program kör det sekventiellt kodrader och gör därmed samtal till och återgår från funktioner enligt den ordning du skrev dem.

Ett blockerande samtal är bara ett samtal till någon form av funktionalitet som orsakar stopp av körning, vilket innebär ett funktionssamtal där den som ringer inte kommer att återuppta körningen förrän den uppringda funktionen är utförd.

Så varför är detta viktigt?

I det fall du har skrivit en kod som regelbundet måste utföra många funktioner i följd, till exempel att läsa en temperatur, läsa en knapp och uppdatera en display, om koden för att uppdatera displayen skulle vara ett blockerande samtal, svarar ditt system inte på knapptryckningar och temperaturändringar, eftersom processorn kommer att spendera all sin tid på att vänta på att skärmen ska uppdateras och inte läsa av knappstatus eller senaste temperatur.

För egen del vill jag skapa en MQTT via WiFi -kompatibel IoT -stationär enhet som läser både lokala och fjärrvärden för temp/luftfuktighet, omgivande ljusnivåer, barometertryck, håller reda på tiden, visar alla dessa parametrar på en LCD, loggar till en usd kort i realtid, läs knappinmatningar, skriv till utgående lysdioder och övervaka gester för att styra saker i min IoT-infrastruktur och som alla ska styras av en ESP8266-12.

Tyvärr var de enda två källorna till APDS9960 -biblioteket jag kunde hitta SparkFun- och AdaFruit -biblioteken, som båda rippade från applikationskoden från Avago (ADPS9960 -tillverkaren) och har ett samtal med namnet ‘readGesture’ som innehåller en stund (1) {}; slinga som vid användning i projektet ovan gör att ESP8266-12E återställs när ADPS9960-sensorn blev mättad (dvs. när ett objekt förblev i närheten eller det fanns en annan IR-källa som belyste sensorn).

Följaktligen för att lösa detta beteende valde jag att flytta bearbetningen av gesterna till en andra processor varigenom ESP8266-12E blev huvudmikrokontrollern och detta system slaven, som visas i bilderna 1 & 2 ovan, systemöversikten respektive systemkompositionsdiagrammen. Bild 3 visar prototypkretsen.

För att begränsa de ändringar jag behövde göra i min befintliga kod skrev jag också en omslagsklass/bibliotek som fantasifullt hette 'APDS9960_NonBlocking'.

Det som följer är en detaljerad förklaring av den icke-blockerande lösningen.

Vilka delar behöver jag?

Om du vill konstruera I2C -lösningen som fungerar med biblioteket APDS9960_NonBlocking behöver du följande delar.

  1. 1 rabatt på ATMega328P här
  2. 1 rabatt på PCF8574P här
  3. 6 av 10K -resistorer här
  4. 4 av 1K -resistorer här
  5. 1 av 1N914 -diod här
  6. 1 av PN2222 NPN Transistor här
  7. 1 av 16MHz kristall här
  8. 2 av 0.1uF -kondensatorer här
  9. 1 av 1000uF elektrolytkondensator här
  10. 1 av 10uF elektrolytkondensator här
  11. 2 av 22pF -kondensatorer här

Om du vill läsa gest -sensorutmatningen via det parallella gränssnittet kan du släppa PCF8574P och tre av 10K -motstånd.

Vilken programvara behöver jag?

Arduino IDE 1.6.9

Vilka färdigheter behöver jag?

För att konfigurera systemet, använd källkoden (tillhandahålls) och skapa den nödvändiga kretsen du behöver följande;

  • Ett minimalt grepp om elektronik,
  • Kunskap om Arduino och dess IDE,
  • En förståelse för hur man programmerar en inbäddad Arduino (Se Instruerbar 'Programmering av ATTiny85, ATTiny84 och ATMega328P: Arduino As ISP')
  • Lite tålamod.

Ämnen som behandlas

  • Kort översikt över kretsen
  • Kort översikt över programvaran
  • Testar APDS9960 Gesture Sensing Device
  • Slutsats
  • Referenser

Steg 1: Kretsöversikt

Kretsöversikt
Kretsöversikt

Kretsen är uppdelad i två sektioner;

  • Den första är den seriella I2C till parallellomvandlingen som åstadkoms via motstånden R8 … 10 och IC1. Här ställer R8… R10 in I2C -adressen för 8 -bitars I/O -expanderchipet IC1 till en NXP PCF8574A. Giltiga adressintervall för denna enhet är 0x38… 0x3F respektive. I exemplet med I2C -programvaran "I2C_APDS9960_TEST.ino" skulle #define GESTURE_SENSOR_I2C_ADDRESS behöva ändras för att passa detta adressintervall.
  • Alla andra komponenter bildar en slavinbäddad Arduino Uno och har följande funktioner;

    • R1, T1, R2 och D1 tillhandahåller en ingång för återställning av slavenheter. Här kommer en aktiv hög puls på IC1 - P7 att tvinga U1 att återställa.
    • R3, R4, är strömbegränsande motstånd för den inbäddade enheten som programmerar TX/RX -linjer.
    • C5 och R7 tillåter Arduino IDE att automatiskt programmera U1 via en puls på DTR -linjen på en ansluten FTDI -enhet.
    • R5 och R6 är I2C -uppdragningsmotstånd för APDS9960 med C6 som tillhandahåller lokal avkoppling av leveransskenor.
    • U1, C1, C2 och Q1 bildar den inbäddade Arduino Uno respektive klockan.
    • Slutligen tillhandahåller C3 och C4 lokal avkoppling av leveransjärnväg för U1.

Steg 2: Programöversikt

Programvaruöversikt
Programvaruöversikt
Programvaruöversikt
Programvaruöversikt
Programvaruöversikt
Programvaruöversikt

Inledning

För att lyckas kompilera denna källkod behöver du följande extra bibliotek för att programmera den inbäddade Arduino Uno U1;

SparkFun_APDS9960.h

  • Av: Steve Quinn
  • Syfte: Detta är en gaffelversion av SparkFun APDS9960-givaren gafflad från jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Den har några modifikationer för att hjälpa till med felsökning och har en avkänslig detektor för att minska falsk utlösning.
  • Från:

APDS9960_NonBlocking.h

  • Av: Steve Quinn
  • Syfte: Ger ett rent gränssnitt för att bädda in denna icke-blockerande implementering av APDS9960 Gest Sensor i din Arduino-kod.
  • Från:

Se följande instruktioner om hur du programmerar en inbäddad Arduino Uno (ATMega328P) mikrokontroller om du inte är bekant med hur du uppnår detta;

PROGRAMMERING AV ATTINY85, ATTINY84 OCH ATMEGA328P: ARDUINO AS ISP

Funktionsöversikt

ATMega328P inbäddad slavmikrokontroller undersöker INT -linjen från ADPS9960. När denna rad går låg läser mikrokontrollern ADPS9960 -registren och avgör om det har avkänts en giltig gest. Om en giltig gest har upptäckts placeras koden för denna gest 0x0 … 0x6, 0xF på Port B och 'nGestureAvailable' görs låg.

När Master -enheten ser 'nGestureAvailable' aktivt läser den värdet på Port B och pulserar 'nGestureClear' lågt för att bekräfta mottagandet av data.

Slavanordningen avaktiverar sedan 'nGestureAvailable' high och rensar data på Port B. Bild 5 ovan visar ett skärmgrepp som tagits från en logisk analysator under en fullständig detekterings-/läscykel.

Kodöversikt

Bild 1 ovan beskriver hur programvaran i U1 den inbäddade slaven Arduino Uno fungerar, tillsammans med Pic 2 hur de två bakgrunds-/förgrundsuppgifterna interagerar. Bild 3 är ett kodsegment som beskriver hur man använder APDS9960_NonBlockingbiblioteket. Pic 4 ger en kartläggning mellan Arduino Uno Digital Pins och faktiska hårdvarustift på ATMega328P.

Efter återställning initierar den inbäddade slavmikrokontrollern APDS9960 så att gestdetektering kan utlösa dess INT -utgång och konfigurerar dess I/O, kopplar avbrottsrutin (ISR) 'GESTURE_CLEAR ()' för att avbryta vektorn INT0 (Digital pin 2, Hardware IC pin 4), konfigurera den för en fallande kantutlösare. Detta bildar nGestureClear -ingången från huvudenheten.

Interrupt -utgångsstiftet 'INT' från APDS9960 är anslutet till Digital Pin 4, Hardware IC Pin 6 som är konfigurerad som en ingång till U1.

Signallinjen 'nGestureAvailable' på Digital pin 7, Hardware IC pin 13 är konfigurerad som en utgång och hög, inaktiv (av-påstådd).

Slutligen konfigureras Port B -bitarna 0… 3 respektive som utgångar och sätts lågt. Dessa bildar datanummer som representerar de olika upptäckta gesttyperna; None = 0x0, Error = 0xF, Up = 0x1, Down = 0x2, Left = 0x3, Right = 0x4, Near = 0x5 and Far = 0x6.

Bakgrundsuppgiften 'Loop' är schemalagd som kontinuerligt avfrågar APDS9960 Interrupt -utgången INT via avläsning av digital stift 4. När INT -utgången från APDS9960 blir aktiv låg indikerar att sensorn har utlösts försöker mikrokontrollern tolka varje gest genom att ringa 'readGesture () 'med det medan (1) {}; ändlös slinga.

Om en giltig gest har detekterats skrivs detta värde till Port B, utskriften 'nGestureAvailable' bekräftas och den booleska semaforen 'bGestureAvailable' ställs in, vilket förhindrar att ytterligare gester loggas.

När befälhavaren upptäcker den aktiva "nGestureAvailable" -utgången läser den detta nya värde och pulserar "nGestureClear" aktiv låg. Denna fallande kant utlöser förgrundsuppgiften 'ISR GESTURE_CLEAR ()' för att planeras avbryta utförandet av bakgrundsuppgiften 'Loop', rensa Port B, 'bGestureAvailable' semafor och 'nGestureAvailable' utdata.

Förgrundsuppgiften 'GESTURE_CLEAR ()' är nu avstängd och bakgrundsuppgiften 'Loop' omplaneras. Ytterligare gester från APDS9960 kan nu avkännas.

Genom att använda avbrutna utlösta förgrunds-/bakgrundsuppgifter på detta sätt kommer den potentiella oändliga slingan i 'readGesture ()' för slavanordningen inte att påverka masterenheten från att fungera och inte heller hindra utförandet av slavenheten. Detta utgör grunden för ett mycket enkelt realtidsoperativsystem (RTOS).

Obs: prefixet 'n' betyder aktiv låg eller påstås som i 'nGestureAvailable'

Steg 3: Testa den icke -blockerande APDS9960 gestavkänningsenheten

Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten
Testar den icke -blockerande APDS9960 gestavkänningsenheten

Inledning

Även om APDS9960-modulen levereras med +5v använder den en inbyggd +3v3-regulator vilket betyder att I2C-linjerna är +3v3-kompatibla och inte +5v. Det är därför jag valde att använda den +3v3 -kompatibla Arduino Due som testmikrokontrollen för att undvika behovet av nivåväxlare.

Om du däremot vill använda en verklig Arduino Uno måste du nivåskifta I2C -linjerna till U1. Se följande Instructable där jag har bifogat ett användbart bildspel (I2C_LCD_With_Arduino) som ger massor av praktiska tips om hur du använder I2C.

I2C -gränssnittstestning

Bilderna 1 och 2 ovan visar hur du konfigurerar och programmerar systemet för I2C -gränssnittet. Du måste ladda ner och installera APDS9960_NonBlocking -biblioteket först. här

Parallellt gränssnittstest

Bilderna 3 och 4 beskriver samma sak för det parallella gränssnittet

Steg 4: Slutsats

Slutsats
Slutsats

Allmän

Koden fungerar bra och detekterar gester responsivt utan några falska positiva. Det har varit igång i några veckor nu som en slavenhet i mitt nästa projekt. Jag har försökt många olika misslyckanden (och det har också den nyfikna Quinn-hushållsmoggien) som tidigare resulterat i en ESP8266-12-återställning, utan negativ effekt.

Möjliga förbättringar

  • Det uppenbara. Skriv om biblioteket APDS9960 Gesture Sensor igen så att det inte blockerar.

    Jag kontaktade faktiskt Broadcom som skickade mig till en lokal distributör som omedelbart ignorerade min begäran om support, jag är bara inte en SparkFun eller AdaFruit, antar jag. Så detta får nog vänta ett tag

  • Porta koden till en mindre slavmikrokontroller. Att använda en ATMega328P för en uppgift är lite av en överkillning. Även om jag först tittade på ATTiny84, slutade jag inte använda en eftersom jag tyckte att den sammanställda storleken på koden var en gränslinje. Med den extra kostnaden för att behöva ändra APDS9960 -biblioteket för att arbeta med ett annat I2C -bibliotek.

Steg 5: Referenser

Krävs för att programmera den inbäddade arduino (ATMega328P - U1)

SparkFun_APDS9960.h

  • Av: Steve Quinn
  • Syfte: Detta är en gaffelversion av SparkFun APDS9960-givaren gafflad från jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Den har några modifikationer för att hjälpa till med felsökning och har en avkänslig detektor för att minska falsk utlösning.
  • Från:

Krävs för att bädda in denna icke-blockerande funktionalitet i din arduino-kod och ge utarbetade exempel

APDS9960_NonBlocking.h

  • Av: Steve Quinn
  • Syfte: Ger ett rent gränssnitt för att bädda in denna icke-blockerande implementering av APDS9960 Gest Sensor i din Arduino-kod.
  • Från:

Realtid operativsystem

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

APDS9960 Datablad

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

PCF8574A datablad

Rekommenderad: