Innehållsförteckning:
- Steg 1: Kretsöversikt
- Steg 2: Programöversikt
- Steg 3: Testa den icke -blockerande APDS9960 gestavkänningsenheten
- Steg 4: Slutsats
- Steg 5: Referenser
Video: Icke -blockerande APDS9960 gestsensorimplementering: 5 steg
2024 Författare: John Day | [email protected]. Senast ändrad: 2024-01-30 12:46
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 rabatt på ATMega328P här
- 1 rabatt på PCF8574P här
- 6 av 10K -resistorer här
- 4 av 1K -resistorer här
- 1 av 1N914 -diod här
- 1 av PN2222 NPN Transistor här
- 1 av 16MHz kristall här
- 2 av 0.1uF -kondensatorer här
- 1 av 1000uF elektrolytkondensator här
- 1 av 10uF elektrolytkondensator här
- 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
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
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
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
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:
Använda Python för att lära dig icke-engelska tangentbordslayouter: 8 steg
Använda Python för att lära dig icke-engelska tangentbordslayouter: Hej, jag heter Julien! Jag är en datavetenskapstudent och idag ska jag visa dig hur du kan använda Python för att lära dig tangentbordslayouten för ett icke-engelskt språk. Mycket språkinlärning händer online idag, och en sak kan människor reagera på
ThreadBoard (icke-3D-tryckt version): E-Textile Rapid Prototyping Board: 4 steg (med bilder)
ThreadBoard (icke-3D-tryckt version): E-Textile Rapid Prototyping Board: Instructable för den 3D-tryckta versionen av ThreadBoard V2 hittar du här. Version 1 av ThreadBoard finns här. Genom kostnadshinder, resor, pandemier och andra hinder, du kanske inte har tillgång till en 3D -skrivare men vill ha
Gör ditt eget Rock Band Ekit Adapter (utan Legacy Adapter), icke -destruktivt !: 10 steg
Gör din egen Rock Band Ekit -adapter (utan äldre adapter), icke -destruktivt !: Efter att ha hört en populär podcastvärd nämna sin oro över att hans trådbundna USB -adapter dör, letade jag efter en DIY -lösning för att ansluta en bättre/anpassad eKit till RB . Tack till Mr DONINATOR på Youtube som gjorde en video med detaljer om hans liknande sida
Icke-adresserbar RGB LED Strip Audio Visualizer: 6 steg (med bilder)
Icke-adresserbar RGB LED Strip Audio Visualizer: Jag har haft en 12v RGB LED-remsa runt mitt TV-skåp ett tag och den styrs av en tråkig LED-drivrutin som låter mig välja en av 16 förprogrammerade färger! Jag lyssnar på en mycket musik som håller mig motiverad men belysningen ställer bara inte in
Arduino -baserad icke -kontakt infraröd termometer - IR -baserad termometer med Arduino: 4 steg
Arduino -baserad icke -kontakt infraröd termometer | IR -baserad termometer med Arduino: Hej killar i dessa instruktioner kommer vi att göra en kontaktfri termometer med hjälp av arduino. Eftersom temperaturen på vätskan/fastämnet ibland är för hög eller för låg och då är det svårt att komma i kontakt med den och läsa dess temperaturen då i den scen