Inhoudsopgave:

NonBlocking APDS9960 Gebaar Sensor Implementatie - Ajarnpa
NonBlocking APDS9960 Gebaar Sensor Implementatie - Ajarnpa

Video: NonBlocking APDS9960 Gebaar Sensor Implementatie - Ajarnpa

Video: NonBlocking APDS9960 Gebaar Sensor Implementatie - Ajarnpa
Video: How to use Arduino Gesture Sensor with Arduino | APDS9960 Sensor with Arduino Gesture Control DIY 2024, November
Anonim
Non-Blocking APDS9960 Gebaar Sensor Implementatie
Non-Blocking APDS9960 Gebaar Sensor Implementatie
Non-Blocking APDS9960 Gebaar Sensor Implementatie
Non-Blocking APDS9960 Gebaar Sensor Implementatie
Non-Blocking APDS9960 Gebaar Sensor Implementatie
Non-Blocking APDS9960 Gebaar Sensor Implementatie

Preambule

Deze Instructable beschrijft hoe u een niet-blokkerende implementatie van de APDS9960-gebaarsensor kunt maken met behulp van de SparkFun_APDS-9960_Sensor_Arduino_Library.

Invoering

Dus je vraagt je waarschijnlijk af wat niet-blokkerend is? Of zelfs blokkeren?

Wat nog belangrijker is, waarom is het belangrijk om iets niet-blokkerend te hebben?

Oké, dus wanneer een microprocessor een programma uitvoert, voert het sequentieel coderegels uit en roept daarbij functies aan en keert terug van functies in de volgorde waarin je ze hebt geschreven.

Een blokkerende aanroep is slechts een aanroep van elke vorm van functionaliteit die ervoor zorgt dat de uitvoering wordt stopgezet, wat betekent dat een functieaanroep de uitvoering niet hervat totdat de aangeroepen functie is uitgevoerd.

Dus waarom is dit belangrijk?

In het geval dat u een code hebt geschreven die regelmatig veel functies achter elkaar moet uitvoeren, zoals het lezen van een temperatuur, het lezen van een knop en het bijwerken van een display, als de code om het display bij te werken een blokkerende oproep is, zal uw systeem niet reageren op druk op de knop en veranderingen in temperatuur, aangezien de processor al zijn tijd zal besteden aan het wachten tot het display is bijgewerkt en niet de knopstatus of de laatste temperatuur afleest.

Van mijn kant wil ik een MQTT over WiFi-compatibel IoT-desktopapparaat maken dat zowel lokale als externe temperatuur- / vochtigheidswaarden, omgevingslichtniveaus, barometrische druk leest, de tijd bijhoudt, al deze parameters op een LCD-scherm weergeeft, in een uSD logt kaart in realtime, lees knopinvoer, schrijf naar uitvoer-LED's en controleer gebaren om dingen in mijn IoT-infrastructuur te besturen en die allemaal worden bestuurd door een ESP8266-12.

Helaas waren de enige twee bronnen van de APDS9960-bibliotheek die ik kon vinden de SparkFun- en AdaFruit-bibliotheken, die beide zijn geript van applicatiecode van Avago (de ADPS9960-fabrikant) en een aanroep hebben met de naam 'readGesture' die een while(1){}; lus die bij gebruik in het bovenstaande project ervoor zorgt dat de ESP8266-12E wordt gereset wanneer de ADPS9960-sensor verzadigd raakt (dwz wanneer een object in de buurt bleef of er een andere IR-bron was die de sensor verlichtte).

Om dit gedrag op te lossen, heb ik ervoor gekozen om de verwerking van de gebaren naar een tweede processor te verplaatsen, waarbij de ESP8266-12E de master-microcontroller werd en dit systeem de slave, zoals weergegeven in respectievelijk afbeeldingen 1 en 2, het systeemoverzicht en de systeemsamenstellingsdiagrammen. Pic 3 toont het prototype circuit.

Om de wijzigingen die ik moest aanbrengen in mijn bestaande code te beperken, schreef ik ook een wrapper-klasse/bibliotheek met de fantasierijke naam 'APDS9960_NonBlocking'.

Wat volgt is een gedetailleerde uitleg van de niet-blokkerende oplossing.

Welke onderdelen heb ik nodig?

Als u de I2C-oplossing wilt bouwen die werkt met de APDS9960_NonBlocking-bibliotheek, heeft u de volgende onderdelen nodig.

  1. 1 korting op ATMega328P hier
  2. 1 uit PCF8574P hier
  3. 6 off 10K Weerstanden hier
  4. 4 off 1K Weerstanden hier
  5. 1 uit 1N914 Diode hier
  6. 1 uit PN2222 NPN Transistor hier
  7. 1 off 16MHz kristal hier
  8. 2 off 0.1uF condensatoren hier
  9. 1 off 1000uF elektrolytische condensator hier
  10. 1 off 10uF elektrolytische condensator hier
  11. 2 van 22pF condensatoren hier

Als u de uitvoer van de gebarensensor via de parallelle interface wilt lezen, kunt u de PCF8574P en drie 10K-weerstanden laten vallen.

Welke software heb ik nodig?

Arduino IDE 1.6.9

Welke vaardigheden heb ik nodig?

Om het systeem in te stellen, gebruikt u de broncode (meegeleverd) en maakt u de benodigde schakelingen. U hebt het volgende nodig;

  • Een minimale kennis van elektronica,
  • Kennis van Arduino en zijn IDE,
  • Een goed begrip van het programmeren van een embedded Arduino (zie Instructable 'Programmeren van de ATTiny85, ATTiny84 en ATMega328P: Arduino als ISP')
  • Wat geduld.

Behandelde onderwerpen

  • Kort overzicht van het circuit
  • Kort overzicht van de software
  • Het APDS9960-apparaat voor bewegingsdetectie testen
  • Conclusie
  • Referenties

Stap 1: Circuitoverzicht

Circuitoverzicht
Circuitoverzicht

Het circuit is verdeeld in twee secties;

  • De eerste is de seriële I2C-naar-parallel-conversie die wordt bereikt via weerstanden R8…10 en IC1. Hier stelt R8…R10 het I2C-adres in voor de 8 bit I/O-expanderchip IC1 en NXP PCF8574A. Geldige adresbereiken voor dit apparaat zijn respectievelijk 0x38 … 0x3F. In het meegeleverde I2C-softwarevoorbeeld 'I2C_APDS9960_TEST.ino' zou '#define GESTURE_SENSOR_I2C_ADDRESS' moeten worden aangepast aan dit adresbereik.
  • Alle andere componenten vormen een slave embedded Arduino Uno en hebben de volgende functies;

    • R1, T1, R2 en D1 bieden een slave-apparaatresetingang. Hier zal een actieve hoge puls op IC1 - P7 U1 dwingen te resetten.
    • R3, R4 zijn stroombeperkende weerstanden voor de ingebedde apparaatprogrammering van TX/RX-lijnen.
    • Met C5 en R7 kan de Arduino IDE U1 automatisch programmeren via een puls op de DTR-lijn van een aangesloten FTDI-apparaat.
    • R5 en R6 zijn I2C pull-up weerstanden voor de APDS9960, waarbij C6 zorgt voor ontkoppeling van de lokale voedingsrail.
    • U1, C1, C2 en Q1 vormen respectievelijk de embedded Arduino Uno en zijn klok.
    • Tot slot zorgen C3 en C4 voor lokale ontkoppeling van de bevoorrading van U1.

Stap 2: Software-overzicht

Software-overzicht
Software-overzicht
Software-overzicht
Software-overzicht
Software-overzicht
Software-overzicht

Preambule

Om deze broncode succesvol te compileren heb je de volgende extra bibliotheken nodig om de embedded Arduino Uno U1 te programmeren;

SparkFun_APDS9960.h

  • Door: Steve Quinn
  • Doel: Dit is een gevorkte versie van de SparkFun APDS9960 Sensor gevorkt van jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Het heeft een paar aanpassingen om te helpen bij het opsporen van fouten en heeft een ongevoelige detector om valse triggering te verminderen.
  • Van:

APDS9960_NonBlocking.h

  • Door: Steve Quinn
  • Doel: Biedt een schone interface om deze niet-blokkerende implementatie van de APDS9960 Gesture Sensor in uw Arduino-code in te bedden.
  • Van:

Zie de volgende Instructable over het programmeren van een ingebouwde Arduino Uno (ATMega328P) microcontroller als u niet bekend bent met hoe u dit kunt bereiken;

PROGRAMMERING VAN DE ATTINY85, ATTINY84 EN ATMEGA328P: ARDUINO ALS ISP

Functioneel overzicht

De ATMega328P embedded slave-microcontroller peilt de INT-lijn van de ADPS9960. Wanneer deze lijn laag wordt, leest de microcontroller de ADPS9960-registers en bepaalt of er een geldig gebaar is gedetecteerd. Als een geldig gebaar is gedetecteerd, wordt de code voor dit gebaar 0x0…0x6, 0xF op poort B geplaatst en wordt 'nGestureAvailable' als laag ingesteld.

Wanneer het Master-apparaat 'nGestureAvailable' actief ziet, leest het de waarde op poort B en pulseert vervolgens 'nGestureClear' tijdelijk laag om de ontvangst van de gegevens te bevestigen.

Het slave-apparaat de-bevestigt vervolgens 'nGestureAvailable' hoog en wist de gegevens op poort B. Afbeelding 5 hierboven toont een schermopname die is genomen van een logische analysator tijdens een volledige detectie-/leescyclus.

Codeoverzicht

Pic 1 hierboven beschrijft hoe de software in U1 de embedded slave Arduino Uno functioneert, samen met Pic 2 hoe de twee achtergrond-/voorgrondtaken op elkaar inwerken. Pic 3 is een codesegment dat beschrijft hoe de APDS9960_NonBlockinglibrary moet worden gebruikt. Pic 4 geeft een mapping tussen Arduino Uno Digital Pins en daadwerkelijke hardwarepinnen op de ATMega328P.

Na het resetten initialiseert de ingebouwde slave-microcontroller de APDS9960, waardoor bewegingsdetectie de INT-uitgang kan activeren en de I/O configureert, waarbij de interruptservice-routine (ISR) 'GESTURE_CLEAR()' wordt aangesloten om vector INT0 (digitale pin 2, hardware-IC-pin 4) te onderbreken, configureren voor een vallende randtrigger. Dit vormt de nGestureClear-invoer van het hoofdapparaat.

De Interrupt output pin 'INT' van de APDS9960 is verbonden met Digital Pin 4, Hardware IC Pin 6 die is geconfigureerd als een input naar U1.

De 'nGestureAvailable'-signaallijn op Digital pin 7, Hardware IC pin 13 is geconfigureerd als een uitgang en ingesteld op hoog, inactief (niet-bevestigd).

Ten slotte worden poort B-bits 0…3 respectievelijk als uitgangen geconfigureerd en laag ingesteld. Deze vormen de gegevensknabbel die de verschillende gedetecteerde gebarentypes vertegenwoordigt; Geen = 0x0, Fout = 0xF, Omhoog = 0x1, Omlaag = 0x2, Links = 0x3, Rechts = 0x4, Dichtbij = 0x5 en Veraf = 0x6.

De achtergrondtaak 'Loop' is gepland die continu de APDS9960 Interrupt-uitgang INT peilt via het lezen van Digital Pin 4. Wanneer de INT-uitgang van de APDS9960 laag wordt, wat aangeeft dat de sensor is geactiveerd, probeert de microcontroller elk gebaar te interpreteren door 'readGesture(aan te roepen))' met zijn while (1) {}; eindeloze cirkel.

Als een geldig gebaar is gedetecteerd, wordt deze waarde naar poort B geschreven, wordt de uitvoer 'nGestureAvailable' bevestigd en wordt de booleaanse semafoor 'bGestureAvailable' ingesteld, waardoor wordt voorkomen dat verdere gebaren worden vastgelegd.

Zodra de master de actieve 'nGestureAvailable'-uitgang detecteert, leest deze deze nieuwe waarde en pulseert 'nGestureClear' actief laag. Deze dalende flank zorgt ervoor dat de voorgrondtaak 'ISR GESTURE_CLEAR()' wordt gepland om de uitvoering van de achtergrondtaak 'Loop' op te schorten, poort B, 'bGestureAvailable' semafoor en 'nGestureAvailable' uitvoer te wissen.

De voorgrondtaak 'GESTURE_CLEAR()' is nu opgeschort en de achtergrondtaak 'Loop' opnieuw gepland. Verdere gebaren van de APDS9960 kunnen nu worden gedetecteerd.

Door op deze manier door interrupt geactiveerde voorgrond-/achtergrondtaken te gebruiken, zal de potentiële oneindige lus in 'readGesture()' van het slave-apparaat geen invloed hebben op de werking van het master-apparaat en zal de uitvoering van het slave-apparaat ook niet belemmeren. Dit vormt de basis van een zeer eenvoudig realtime besturingssysteem (RTOS).

Opmerking: het voorvoegsel 'n' betekent actief laag of beweerd zoals in 'nGestureAvailable'

Stap 3: Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen

Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen
Het niet-blokkerende APDS9960-apparaat voor bewegingsdetectie testen

Preambule

Hoewel de APDS9960-module wordt geleverd met +5v, gebruikt deze een ingebouwde +3v3-regelaar, wat betekent dat de I2C-lijnen +3v3-compatibel zijn en niet +5v. Daarom heb ik ervoor gekozen om de +3v3-compatibele Arduino Due als testmicrocontroller te gebruiken, om de noodzaak voor niveauverschuivers te voorkomen.

Als u echter een echte Arduino Uno wilt gebruiken, moet u de I2C-lijnen naar U1 verschuiven. Zie de volgende Instructable waar ik een handige diaset (I2C_LCD_With_Arduino) heb bijgevoegd die veel praktische tips geeft over het gebruik van I2C.

I2C-interface testen

Foto's 1 en 2 hierboven laten zien hoe u het systeem instelt en programmeert voor de I2C-interface. U moet eerst de APDS9960_NonBlocking-bibliotheek downloaden en installeren. hier

Parallelle interfacetests

Pics 3 en 4 detail hetzelfde voor de parallelle interface

Stap 4: Conclusie

Conclusie
Conclusie

Algemeen

De code werkt goed en detecteert gebaren responsief zonder valse positieven. Het is nu een paar weken in gebruik als een slave-apparaat in mijn volgende project. Ik heb veel verschillende storingsmodi geprobeerd (en de nieuwsgierige Quinn-huishoudster ook) die eerder resulteerde in een ESP8266-12-reset, zonder negatief effect.

Mogelijke verbeteringen

  • Het overduidelijke. Herschrijf de APDS9960 Gesture Sensor-bibliotheek zodat deze niet-blokkerend is.

    Ik heb inderdaad contact opgenomen met Broadcom die me doorverbonden met een lokale distributeur die mijn verzoek om ondersteuning onmiddellijk negeerde, ik ben gewoon geen SparkFun of AdaFruit, denk ik. Dit zal dus waarschijnlijk nog even moeten wachten

  • Port de code naar een kleinere slave-microcontroller. Het gebruik van een ATMega328P voor één taak is een beetje een overkill. Hoewel ik in eerste instantie naar de ATTiny84 keek, stopte ik er een te gebruiken omdat ik vond dat de gecompileerde grootte van de code een grenslijn was. Met de extra overhead van het moeten wijzigen van de APDS9960-bibliotheek om met een andere I2C-bibliotheek te werken.

Stap 5: Referenties

Vereist om de ingebouwde arduino te programmeren (ATMega328P - U1)

SparkFun_APDS9960.h

  • Door: Steve Quinn
  • Doel: Dit is een gevorkte versie van de SparkFun APDS9960 Sensor gevorkt van jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library. Het heeft een paar aanpassingen om te helpen bij het opsporen van fouten en heeft een ongevoelige detector om valse triggering te verminderen.
  • Van:

Vereist om deze niet-blokkerende functionaliteit in uw Arduino-code in te bedden en uitgewerkte voorbeelden te geven

APDS9960_NonBlocking.h

  • Door: Steve Quinn
  • Doel: Biedt een schone interface om deze niet-blokkerende implementatie van de APDS9960 Gesture Sensor in uw Arduino-code in te bedden.
  • Van:

Realtime besturingssysteem

https://en.wikipedia.org/wiki/Realtime_operating_system

APDS9960 Gegevensblad

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

Aanbevolen: