Indholdsfortegnelse:

Ikke -blokerende APDS9960 gestusensorimplementering: 5 trin
Ikke -blokerende APDS9960 gestusensorimplementering: 5 trin

Video: Ikke -blokerende APDS9960 gestusensorimplementering: 5 trin

Video: Ikke -blokerende APDS9960 gestusensorimplementering: 5 trin
Video: 12V Bluetooth Relay to control AC or DC load using mobile Phone 2024, Juli
Anonim
Implementering af ikke -blokerende APDS9960 gestusensor
Implementering af ikke -blokerende APDS9960 gestusensor
Implementering af ikke -blokerende APDS9960 gestusensor
Implementering af ikke -blokerende APDS9960 gestusensor
Implementering af ikke -blokerende APDS9960 gestusensor
Implementering af ikke -blokerende APDS9960 gestusensor

Præambel

Denne instruktion beskriver, hvordan du opretter en ikke-blokerende implementering af APDS9960 gestusensoren ved hjælp af SparkFun_APDS-9960_Sensor_Arduino_Library.

Introduktion

Så du spørger sikkert dig selv, hvad der ikke blokerer? Eller endda blokering for den sags skyld?

Endnu vigtigere, hvorfor er det vigtigt at have noget, der ikke blokerer rigtigt?

Ok, så når en mikroprocessor kører et program, eksekverer det sekvensielt kodelinjer og foretager derved opkald til og vender tilbage fra funktioner i overensstemmelse med den rækkefølge, du skrev dem i.

Et blokerende opkald er blot et opkald til enhver form for funktionalitet, der forårsager standsning af eksekvering, hvilket betyder et funktionsopkald, hvor den, der ringer, ikke genoptager udførelsen, før den kaldte funktion er færdig med at udføre.

Så hvorfor er dette vigtigt?

I det tilfælde, hvor du har skrevet en kode, der regelmæssigt skal udføre masser af funktioner i rækkefølge, såsom at læse en temperatur, læse en knap og opdatere et display, hvis koden til opdatering af displayet er et blokerende opkald, reagerer dit system ikke på knappetryk og ændringer i temperatur, da processoren vil bruge al sin tid på at vente på, at displayet opdateres og ikke læser knapstatus eller seneste temperatur.

For mit vedkommende vil jeg oprette en MQTT over WiFi -kompatibel IoT -stationær enhed, der læser både lokale og fjerntemperatur-/fugtighedsværdier, omgivende lysniveauer, barometrisk tryk, holder styr på tiden, viser alle disse parametre på en LCD, logger på en uSD kort i realtid, læse knapindgange, skrive til udgangs-LED'er og overvåge bevægelser for at styre ting i min IoT-infrastruktur, og som alle skal styres af en ESP8266-12.

Desværre var de eneste to kilder til APDS9960 -biblioteket, jeg kunne finde, SparkFun- og AdaFruit -bibliotekerne, som begge blev revet fra applikationskode fra Avago (ADPS9960 -producenten) og besidder et opkald med navnet 'readGesture', som indeholder et stykke tid (1) {}; loop, som ved brug i projektet ovenfor får ESP8266-12E til at nulstille, hver gang ADPS9960-sensoren blev mættet (dvs. når et objekt forblev i umiddelbar nærhed, eller der var en anden IR-kilde, der belyste sensoren).

Følgelig for at løse denne adfærd valgte jeg at flytte behandlingen af bevægelserne til en anden processor, hvorved ESP8266-12E blev hovedmikrocontrolleren og dette system slave, som afbildet i billederne 1 & 2 ovenfor, henholdsvis systemoversigten og systemkomposition-diagrammerne. Billede 3 viser prototypekredsløbet.

For at begrænse de ændringer, jeg skulle foretage i min eksisterende kode, skrev jeg også en indpakningsklasse/bibliotek, der fantasifuldt hedder 'APDS9960_NonBlocking'.

Det følgende er en detaljeret forklaring af den ikke-blokerende løsning.

Hvilke dele har jeg brug for?

Hvis du vil konstruere I2C -løsningen, der fungerer med biblioteket APDS9960_NonBlocking, skal du bruge følgende dele.

  1. 1 rabat på ATMega328P her
  2. 1 rabat på PCF8574P her
  3. 6 fra 10K modstande her
  4. 4 off 1K modstande her
  5. 1 off 1N914 Diode her
  6. 1 off PN2222 NPN Transistor her
  7. 1 off 16MHz krystal her
  8. 2 off 0.1uF kondensatorer her
  9. 1 off 1000uF elektrolytkondensator her
  10. 1 off 10uF elektrolytkondensator her
  11. 2 off 22pF kondensatorer her

Hvis du vil læse gestusensorens output via det parallelle interface, kan du slippe PCF8574P og tre fra 10K modstande.

Hvilken software har jeg brug for?

Arduino IDE 1.6.9

Hvilke færdigheder har jeg brug for?

For at konfigurere systemet skal du bruge kildekoden (medfølger) og oprette det nødvendige kredsløb, du skal bruge følgende;

  • Et minimalt greb om elektronik,
  • Kendskab til Arduino og dens IDE,
  • En forståelse af, hvordan man programmerer en indlejret Arduino (Se Instructable 'Programmering af ATTiny85, ATTiny84 og ATMega328P: Arduino As ISP')
  • Noget tålmodighed.

Emner dækket

  • Kort oversigt over kredsløbet
  • Kort oversigt over softwaren
  • Test af APDS9960 Gesture Sensing Device
  • Konklusion
  • Referencer

Trin 1: Oversigt over kredsløb

Kredsløbsoversigt
Kredsløbsoversigt

Kredsløbet er opdelt i to sektioner;

  • Den første er den serielle I2C til parallel konvertering udført via modstande R8 … 10 og IC1. Her indstillede R8 … R10 I2C -adressen til 8 -bit I/O -ekspanderchippen IC1 og en NXP PCF8574A. Gyldige adresseområder for denne enhed er henholdsvis 0x38… 0x3F. I eksemplet på I2C -softwaren, der er givet 'I2C_APDS9960_TEST.ino', skal #define GESTURE_SENSOR_I2C_ADDRESS 'ændres, så det passer til dette adresseområde.
  • Alle andre komponenter danner en slave indlejret Arduino Uno og har følgende funktioner;

    • R1, T1, R2 og D1 giver input til nulstilling af slaveenheden. Her vil en aktiv høj puls på IC1 - P7 tvinge U1 til at nulstille.
    • R3, R4, er strømbegrænsende modstande for den integrerede enhed, der programmerer TX/RX -linjer.
    • C5 og R7 giver Arduino IDE mulighed for automatisk at programmere U1 via en puls på DTR -linjen på en tilsluttet FTDI -enhed.
    • R5 og R6 er I2C pull up -modstande til APDS9960 med C6, der leverer lokal afkobling af forsyningsskinner.
    • U1, C1, C2 og Q1 danner henholdsvis den integrerede Arduino Uno og dens ur.
    • Endelig giver C3 og C4 lokal afkobling af forsyningsskinner til U1.

Trin 2: Softwareoversigt

Softwareoversigt
Softwareoversigt
Softwareoversigt
Softwareoversigt
Softwareoversigt
Softwareoversigt

Præambel

For at kunne kompilere denne kildekode skal du bruge følgende ekstra biblioteker til at programmere den integrerede Arduino Uno U1;

SparkFun_APDS9960.h

  • Af: Steve Quinn
  • Formål: Dette er en forked version af SparkFun APDS9960-sensoren gafflet fra jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Det har et par ændringer til at hjælpe med fejlfinding og har en de-sensibiliseret detektor for at reducere falsk udløsning.
  • Fra:

APDS9960_NonBlocking.h

  • Af: Steve Quinn
  • Formål: Giver en ren grænseflade til at integrere denne ikke-blokerende implementering af APDS9960 Gesture Sensor i din Arduino-kode.
  • Fra:

Se følgende Instruktioner om, hvordan du programmerer en integreret Arduino Uno (ATMega328P) mikrokontroller, hvis du ikke er bekendt med, hvordan du opnår dette;

PROGRAMMERING AF ATTINY85, ATTINY84 OG ATMEGA328P: ARDUINO AS ISP

Funktionel oversigt

ATMega328P integreret slave -mikrokontroller undersøger INT -linjen fra ADPS9960. Når denne linje går lavt, læser mikrokontrolleren ADPS9960 -registre og afgør, om der er registreret en gyldig gestus. Hvis der er fundet en gyldig gestus, placeres koden for denne gestus 0x0 … 0x6, 0xF på Port B, og 'nGestureAvailable' gøres gældende lav.

Når Master -enheden ser 'nGestureAvailable' aktiv, læser den værdien på Port B, derefter pulserer 'nGestureClear' lavt midlertidigt for at bekræfte modtagelse af dataene.

Slaveenheden deaktiverer derefter 'nGestureAvailable' high og sletter dataene på Port B. Pic 5 ovenfor viser et skærmbillede taget fra en logisk analysator under en fuld registrerings-/læsecyklus.

Kodeoversigt

Billede 1 ovenfor beskriver, hvordan softwaren i U1 den integrerede slave Arduino Uno fungerer, sammen med Pic 2, hvordan de to baggrunds-/forgrundsopgaver interagerer. Pic 3 er et kodesegment, der beskriver, hvordan man bruger APDS9960_NonBlockinglibrary. Pic 4 giver en kortlægning mellem Arduino Uno Digital Pins og egentlige hardware -pins på ATMega328P.

Efter nulstilling initialiserer den indlejrede slave -mikrokontroller APDS9960, så bevægelsesdetektering kan udløse dens INT -output og konfigurerer dens I/O, vedhæfte afbrydelsesrutine (ISR) 'GESTURE_CLEAR ()' til at afbryde vektor INT0 (Digital pin 2, Hardware IC pin 4), konfigurere den til en faldende kantudløser. Dette danner nGestureClear -input fra master -enheden.

Interrupt output pin 'INT' fra APDS9960 er forbundet til Digital Pin 4, Hardware IC Pin 6, som er konfigureret som input til U1.

Signallinjen 'nGestureAvailable' på Digital pin 7, Hardware IC pin 13 er konfigureret som en udgang og indstillet høj, inaktiv (deaktiveret).

Endelig er Port B bits 0… 3 henholdsvis konfigureret som output og sat lavt. Disse danner datanibbe, der repræsenterer de forskellige detekterede gestus typer; None = 0x0, Error = 0xF, Up = 0x1, Down = 0x2, Left = 0x3, Right = 0x4, Near = 0x5 and Far = 0x6.

Baggrundsopgaven 'Loop' er planlagt, som kontinuerligt undersøger APDS9960 Interrupt -udgangen INT via aflæsning af Digital Pin 4. Når INT -output fra APDS9960 bliver aktiv lav, hvilket indikerer, at sensoren er blevet udløst, forsøger mikrokontrolleren at fortolke enhver gestus ved at kalde 'readGesture () 'med det mens (1) {}; endeløs sløjfe.

Hvis en gyldig gestus er blevet registreret, skrives denne værdi til Port B, output'en 'nGestureAvailable' bekræftes, og den boolske semafor 'bGestureAvailable' indstilles, hvilket forhindrer, at yderligere gestus logges.

Når masteren registrerer det aktive 'nGestureAvailable' output, læser den denne nye værdi og pulserer 'nGestureClear' aktiv lav. Denne faldende kant udløser forgrundsopgaven 'ISR GESTURE_CLEAR ()' til at blive planlagt til at suspendere udførelsen af baggrundsopgaven 'Loop', rydde Port B, 'bGestureAvailable' semafor og 'nGestureAvailable' output.

Forgrundsopgaven 'GESTURE_CLEAR ()' er nu suspenderet, og baggrundsopgaven 'Loop' omplanlægges. Yderligere gestus fra APDS9960 kan nu registreres.

Ved at bruge interrupt -udløste forgrunds-/baggrundsopgaver på denne måde vil den potentielle uendelige sløjfe i 'readGesture ()' af slaveenheden ikke påvirke master -enheden fra at fungere og vil heller ikke hæmme udførelsen af slaveenheden. Dette danner grundlaget for et meget simpelt realtidsoperativsystem (RTOS).

Bemærk: Præfikset 'n' betyder aktiv lav eller påstås som i 'nGestureAvailable'

Trin 3: Test af ikke -blokerende APDS9960 gestus -sensorenhed

Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed
Test af ikke -blokerende APDS9960 gestus -sensorenhed

Præambel

Selvom APDS9960-modulet leveres med +5v, bruger det en indbygget +3v3-regulator, hvilket betyder, at I2C-linjer er +3v3-kompatible og ikke +5v. Derfor valgte jeg at bruge den +3v3 -kompatible Arduino Due som testmikrokontroller for at undgå behovet for niveauskift.

Hvis du imidlertid ønsker at bruge en egentlig Arduino Uno, skal du niveauskifte I2C -linjerne til U1. Se følgende Instructable, hvor jeg har vedhæftet et nyttigt diassæt (I2C_LCD_With_Arduino), som giver masser af praktiske tips til brug af I2C.

I2C -interfacetest

Billeder 1 og 2 ovenfor viser, hvordan du konfigurerer og programmerer systemet til I2C -grænsefladen. Du skal først downloade og installere APDS9960_NonBlocking -biblioteket. her

Parallel interfacetest

Billeder 3 og 4 beskriver det samme for den parallelle grænseflade

Trin 4: Konklusion

Konklusion
Konklusion

Generel

Koden fungerer godt og registrerer gestus responsivt uden falske positive. Det har været i gang i et par uger nu som slaveenhed i mit næste projekt. Jeg har prøvet mange forskellige fejltilstande (og det samme har den nysgerrige Quinn husholdningsmoggie), som tidligere resulterede i en ESP8266-12 nulstilling, uden negativ effekt.

Mulige forbedringer

  • Det indlysende. Skriv APDS9960 Gesture Sensor-biblioteket igen, så det ikke blokerer.

    Faktisk kontaktede jeg Broadcom, som sendte mig til en lokal distributør, der straks ignorerede min anmodning om support, jeg er bare ikke en SparkFun eller AdaFruit. Så dette må nok vente et stykke tid

  • Port koden til en mindre slave -mikrokontroller. At bruge en ATMega328P til en opgave er lidt af en overkill. Selvom jeg i første omgang kiggede på ATTiny84, stoppede jeg med at bruge en, da jeg følte, at den kompilerede størrelse af koden var en grænselinje. Med den ekstra omkostning at skulle ændre APDS9960 -biblioteket til at arbejde med et andet I2C -bibliotek.

Trin 5: Referencer

Påkrævet for at programmere den integrerede arduino (ATMega328P - U1)

SparkFun_APDS9960.h

  • Af: Steve Quinn
  • Formål: Dette er en forked version af SparkFun APDS9960-sensoren gafflet fra jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Det har et par ændringer til at hjælpe med fejlfinding og har en de-sensibiliseret detektor for at reducere falsk udløsning.
  • Fra:

Påkrævet for at integrere denne ikke-blokerende funktionalitet i din arduino-kode og give gennemarbejdede eksempler

APDS9960_NonBlocking.h

  • Af: Steve Quinn
  • Formål: Giver en ren grænseflade til at integrere denne ikke-blokerende implementering af APDS9960 Gesture Sensor i din Arduino-kode.
  • Fra:

Realtid operativsystem

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

APDS9960 Datablad

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

Anbefalede: