Inhaltsverzeichnis:

Implementierung des nicht blockierenden APDS9960-Gestensensors - Gunook
Implementierung des nicht blockierenden APDS9960-Gestensensors - Gunook

Video: Implementierung des nicht blockierenden APDS9960-Gestensensors - Gunook

Video: Implementierung des nicht blockierenden APDS9960-Gestensensors - Gunook
Video: Hochauflösende und nicht-blockierende Benutzeroberflächen mit der VCL 2024, November
Anonim
Nicht blockierende APDS9960-Gestensensor-Implementierung
Nicht blockierende APDS9960-Gestensensor-Implementierung
Nicht blockierende APDS9960-Gestensensor-Implementierung
Nicht blockierende APDS9960-Gestensensor-Implementierung
Nicht blockierende APDS9960-Gestensensor-Implementierung
Nicht blockierende APDS9960-Gestensensor-Implementierung

Präambel

Diese Anleitung beschreibt, wie Sie eine nicht blockierende Implementierung des APDS9960-Gestensensors mit der SparkFun_APDS-9960_Sensor_Arduino_Library erstellen.

Einführung

Sie fragen sich wahrscheinlich, was nicht blockierend ist? Oder sogar blockieren?

Noch wichtiger, warum ist es wichtig, ein nicht-blockierendes Recht zu haben?

Okay, wenn ein Mikroprozessor ein Programm ausführt, führt er sequentiell Codezeilen aus und ruft dabei Funktionen auf und kehrt von ihnen in der Reihenfolge zurück, in der Sie sie geschrieben haben.

Ein blockierender Aufruf ist nur ein Aufruf einer beliebigen Art von Funktionalität, die ein Anhalten der Ausführung verursacht, d. h. ein Funktionsaufruf, bei dem der Aufrufer die Ausführung nicht wiederaufnimmt, bis die aufgerufene Funktion die Ausführung beendet hat.

Warum ist das wichtig?

Für den Fall, dass Sie Code geschrieben haben, der regelmäßig viele Funktionen nacheinander ausführen muss, z Tastendrücke und Temperaturänderungen, da der Prozessor die ganze Zeit darauf wartet, dass die Anzeige aktualisiert wird, und nicht den Tastenstatus oder die neueste Temperatur liest.

Ich für meinen Teil möchte ein MQTT over WiFi-fähiges IoT-Desktop-Gerät erstellen, das sowohl lokale als auch entfernte Temperatur- / Feuchtigkeitswerte, Umgebungslichtwerte, Luftdruck liest, die Zeit verfolgt, alle diese Parameter auf einem LCD anzeigt, auf einer uSD protokolliert Karte in Echtzeit lesen, Tasteneingaben lesen, in Ausgangs-LEDs schreiben und Gesten überwachen, um Dinge in meiner IoT-Infrastruktur zu steuern und dies alles von einem ESP8266-12 gesteuert werden soll.

Leider waren die einzigen beiden Quellen der APDS9960-Bibliothek, die ich finden konnte, die Bibliotheken SparkFun und AdaFruit, die beide aus dem Anwendungscode von Avago (dem ADPS9960-Hersteller) gerippt wurden und einen Aufruf namens "readGesture" besitzen, der eine Weile (1) {}; Schleife, die bei Verwendung im obigen Projekt bewirkt, dass der ESP8266-12E zurückgesetzt wird, wenn der ADPS9960-Sensor gesättigt wurde (dh wenn ein Objekt in unmittelbarer Nähe blieb oder eine andere IR-Quelle den Sensor beleuchtete).

Um dieses Verhalten zu beheben, entschied ich mich daher, die Verarbeitung der Gesten auf einen zweiten Prozessor zu verlagern, wobei der ESP8266-12E der Master-Mikrocontroller und dieses System der Slave wurde, wie in den Bildern 1 und 2 oben, der Systemübersicht bzw. der Systemzusammensetzungsdiagramme dargestellt. Bild 3 zeigt die Prototypenschaltung.

Um die Änderungen, die ich an meinem vorhandenen Code vornehmen musste, einzuschränken, habe ich auch eine Wrapper-Klasse/-Bibliothek mit dem fantasievollen Namen „APDS9960_NonBlocking“geschrieben.

Was folgt, ist eine detaillierte Erläuterung der nicht-blockierenden Lösung.

Welche Teile benötige ich?

Wenn Sie die I2C-Lösung aufbauen möchten, die mit der Bibliothek APDS9960_NonBlocking arbeitet, benötigen Sie die folgenden Teile.

  1. 1 Stück ATMega328P hier
  2. 1 Stück PCF8574P hier
  3. 6 von 10K Widerständen hier
  4. 4 von 1K-Widerständen hier
  5. 1 von 1N914 Diode hier
  6. 1 aus PN2222 NPN Transistor hier
  7. 1 von 16MHz Quarz hier
  8. 2 von 0,1uF Kondensatoren hier
  9. 1 von 1000uF Elektrolytkondensator hier
  10. 1 von 10uF Elektrolytkondensator hier
  11. 2 von 22pF Kondensatoren hier

Wenn Sie die Ausgabe des Gestensensors über die parallele Schnittstelle auslesen möchten, können Sie den PCF8574P und drei 10K-Widerstände entfernen.

Welche Software benötige ich?

Arduino-IDE 1.6.9

Welche Fähigkeiten brauche ich?

Verwenden Sie zum Einrichten des Systems den Quellcode (mitgeliefert) und erstellen Sie die erforderliche Schaltung. Sie benötigen Folgendes:

  • Ein minimales Verständnis von Elektronik,
  • Kenntnisse von Arduino und seiner IDE,
  • Ein Verständnis, wie man ein eingebettetes Arduino programmiert (siehe Instructable 'Programming the ATTiny85, ATTiny84 und ATMega328P: Arduino als ISP')
  • Etwas Geduld.

Behandelten Themen

  • Kurzer Überblick über die Schaltung
  • Kurzübersicht der Software
  • Testen des Gestensensors APDS9960
  • Abschluss
  • Verweise

Schritt 1: Schaltungsübersicht

Schaltungsübersicht
Schaltungsübersicht

Die Strecke ist in zwei Abschnitte unterteilt;

  • Die erste ist die serielle I2C-Parallel-Umwandlung, die über die Widerstände R8…10 und IC1 durchgeführt wird. Hier stellen R8…R10 die I2C-Adresse für den 8-Bit-I/O-Expander-Chip IC1 und NXP PCF8574A ein. Gültige Adressbereiche für dieses Gerät sind jeweils 0x38 … 0x3F. Im bereitgestellten I2C-Softwarebeispiel müsste 'I2C_APDS9960_TEST.ino' '#define GESTURE_SENSOR_I2C_ADDRESS' geändert werden, um diesem Adressbereich zu entsprechen.
  • Alle anderen Komponenten bilden einen Slave eingebetteten Arduino Uno und haben die folgenden Funktionen;

    • R1, T1, R2 und D1 stellen einen Reset-Eingang für ein Slave-Gerät bereit. Hier zwingt ein aktiver High-Impuls auf IC1 - P7 U1 zum Zurücksetzen.
    • R3, R4 sind Strombegrenzungswiderstände für die TX/RX-Leitungen der eingebetteten Vorrichtung, die programmiert.
    • C5 und R7 ermöglichen es der Arduino IDE, U1 über einen Impuls auf der DTR-Leitung eines angeschlossenen FTDI-Geräts automatisch zu programmieren.
    • R5 und R6 sind I2C-Pull-Up-Widerstände für den APDS9960, wobei C6 die lokale Versorgungsschienenentkopplung bietet.
    • U1, C1, C2 und Q1 bilden das eingebettete Arduino Uno bzw. seine Uhr.
    • Schließlich sorgen C3 und C4 für die Nahversorgungsschienenentkopplung für U1.

Schritt 2: Softwareübersicht

Software-Übersicht
Software-Übersicht
Software-Übersicht
Software-Übersicht
Software-Übersicht
Software-Übersicht

Präambel

Um diesen Quellcode erfolgreich zu kompilieren, benötigen Sie die folgenden zusätzlichen Bibliotheken, um das eingebettete Arduino Uno U1 zu programmieren;

SparkFun_APDS9960.h

  • Von: Steve Quinn
  • Zweck: Dies ist eine gegabelte Version des SparkFun APDS9960 Sensors von jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library gegabelt. Es enthält einige Modifikationen, die beim Debuggen helfen, und verfügt über einen desensibilisierten Detektor, um Fehlauslösungen zu reduzieren.
  • Von:

APDS9960_NonBlocking.h

  • Von: Steve Quinn
  • Zweck: Bietet eine saubere Schnittstelle zum Einbetten dieser nicht blockierenden Implementierung des APDS9960-Gestensensors in Ihren Arduino-Code.
  • Von:

Siehe die folgende Anleitung zum Programmieren eines eingebetteten Arduino Uno (ATMega328P) -Mikrocontrollers, wenn Sie nicht damit vertraut sind, wie Sie dies erreichen können;

PROGRAMMIERUNG DES ATTINY85, ATTINY84 UND ATMEGA328P: ARDUINO AS ISP

Funktionsübersicht

Der eingebettete Slave-Mikrocontroller ATMega328P fragt die INT-Leitung vom ADPS9960 ab. Wenn diese Leitung auf Low geht, liest der Mikrocontroller die ADPS9960-Register und stellt fest, ob eine gültige Geste erkannt wurde. Wenn eine gültige Geste erkannt wurde, wird der Code für diese Geste 0x0…0x6, 0xF auf Port B platziert und 'nGestureAvailable' wird als niedrig bestätigt.

Wenn das Master-Gerät 'nGestureAvailable' als aktiv sieht, liest es den Wert an Port B und pulst dann 'nGestureClear' vorübergehend auf Low, um den Empfang der Daten zu bestätigen.

Das Slave-Gerät deaktiviert dann 'nGestureAvailable' high und löscht die Daten an Port B. Bild 5 oben zeigt einen Screenshot von einem Logikanalysator während eines vollständigen Erkennungs-/Lesezyklus.

Codeübersicht

Bild 1 oben zeigt, wie die Software in U1 der eingebettete Slave Arduino Uno funktioniert, zusammen mit Bild 2, wie die beiden Hintergrund- / Vordergrundaufgaben interagieren. Bild 3 ist ein Codesegment, das die Verwendung der APDS9960_NonBlockinglibrary beschreibt. Bild 4 zeigt eine Zuordnung zwischen Arduino Uno Digital Pins und tatsächlichen Hardware-Pins auf dem ATMega328P.

Nach dem Zurücksetzen initialisiert der eingebettete Slave-Mikrocontroller den APDS9960, sodass die Gestenerkennung seinen INT-Ausgang auslöst und seine E/A konfiguriert., konfigurieren Sie es für einen fallenden Flankentrigger. Dies bildet den nGestureClear-Eingang vom Master-Gerät.

Der Interrupt-Ausgangspin 'INT' des APDS9960 ist mit Digital Pin 4, Hardware IC Pin 6 verbunden, der als Eingang für U1 konfiguriert ist.

Die 'nGestureAvailable'-Signalleitung an Digital-Pin 7, Hardware-IC-Pin 13 ist als Ausgang konfiguriert und auf High, inaktiv (de-asserted) gesetzt.

Schließlich werden die Bits 0…3 von Port B jeweils als Ausgänge konfiguriert und auf Low gesetzt. Diese bilden das Datennibble, das die verschiedenen erkannten Gestentypen repräsentiert; None = 0x0, Error = 0xF, Up = 0x1, Down = 0x2, Left = 0x3, Right = 0x4, Near = 0x5 und Far = 0x6.

Die Hintergrundaufgabe 'Loop' ist geplant, die kontinuierlich den Interrupt-Ausgang INT des APDS9960 über das Lesen von Digital Pin 4 abfragt.)' mit seinem while (1) {}; Endlosschleife.

Wenn eine gültige Geste erkannt wurde, wird dieser Wert auf Port B geschrieben, der Ausgang 'nGestureAvailable' wird bestätigt und der boolesche Semaphor 'bGestureAvailable' wird gesetzt, wodurch verhindert wird, dass weitere Gesten protokolliert werden.

Sobald der Master den aktiven 'nGestureAvailable'-Ausgang erkennt, liest er diesen neuen Wert und pulst 'nGestureClear' aktiv niedrig. Diese fallende Flanke löst aus, dass die Vordergrundtask 'ISR GESTURE_CLEAR()' geplant wird, wodurch die Ausführung der Hintergrundtask 'Loop' ausgesetzt wird, Port B, 'bGestureAvailable' Semaphore und 'nGestureAvailable' Ausgabe gelöscht werden.

Die Vordergrundaufgabe 'GESTURE_CLEAR()' wird nun ausgesetzt und die Hintergrundaufgabe 'Loop' neu geplant. Weitere Gesten des APDS9960 können jetzt wahrgenommen werden.

Durch die Verwendung von Interrupt-getriggerten Vordergrund-/Hintergrund-Tasks auf diese Weise wird die potenzielle Endlosschleife in 'readGesture()' des Slave-Geräts den Betrieb des Master-Geräts nicht beeinträchtigen und auch die Ausführung des Slave-Geräts nicht behindern. Dies bildet die Grundlage für ein sehr einfaches Echtzeitbetriebssystem (RTOS).

Hinweis: Das Präfix 'n' bedeutet aktiv niedrig oder bestätigt wie in 'nGestureAvailable'

Schritt 3: Testen des nicht blockierenden APDS9960-Gestensensors

Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors
Testen des nicht blockierenden APDS9960-Gestensensors

Präambel

Obwohl das APDS9960-Modul mit +5V versorgt wird, verwendet es einen integrierten +3V3-Regler, was bedeutet, dass seine I2C-Leitungen +3V3- und nicht +5V-kompatibel sind. Aus diesem Grund habe ich mich für den +3v3-kompatiblen Arduino Due als Test-Mikrocontroller entschieden, um die Notwendigkeit von Level-Shiftern zu vermeiden.

Wenn Sie jedoch ein tatsächliches Arduino Uno verwenden möchten, müssen Sie die I2C-Leitungen auf U1 verschieben. Siehe das folgende Instructable, in dem ich ein nützliches Folienset (I2C_LCD_With_Arduino) angebracht habe, das viele praktische Tipps zur Verwendung von I2C enthält.

I2C-Schnittstellentest

Die Bilder 1 und 2 oben zeigen, wie das System für die I2C-Schnittstelle eingerichtet und programmiert wird. Sie müssen zuerst die Bibliothek APDS9960_NonBlocking herunterladen und installieren. Hier

Parallele Schnittstellenprüfung

Bilder 3 und 4 zeigen dasselbe für die parallele Schnittstelle

Schritt 4: Fazit

Abschluss
Abschluss

Allgemein

Der Code funktioniert gut und erkennt Gesten reaktionsschnell ohne Fehlalarme. Es ist jetzt seit einigen Wochen als Slave-Gerät in meinem nächsten Projekt in Betrieb. Ich habe viele verschiedene Fehlermodi ausprobiert (und auch der neugierige Quinn-Haushaltsmoggie), der zuvor zu einem ESP8266-12-Reset führte, ohne negative Auswirkungen.

Mögliche Verbesserungen

  • Das Offensichtliche. Schreiben Sie die APDS9960-Gestensensor-Bibliothek neu, sodass sie nicht blockierend ist.

    Tatsächlich habe ich Broadcom kontaktiert, die mich an einen lokalen Distributor vermittelt haben, der meine Anfrage nach Support sofort ignoriert hat, ich bin einfach kein SparkFun oder AdaFruit, denke ich. Das wird also wohl noch eine Weile warten müssen

  • Portieren Sie den Code auf einen kleineren Slave-Mikrocontroller. Die Verwendung eines ATMega328P für eine Aufgabe ist ein bisschen übertrieben. Obwohl ich mir anfangs den ATTiny84 angesehen habe, habe ich aufgehört, einen zu verwenden, da ich der Meinung war, dass die kompilierte Größe des Codes eine Grenzlinie war. Mit dem zusätzlichen Aufwand, die APDS9960-Bibliothek modifizieren zu müssen, um mit einer anderen I2C-Bibliothek zu arbeiten.

Schritt 5: Referenzen

Erforderlich, um das eingebettete Arduino (ATMega328P - U1) zu programmieren

SparkFun_APDS9960.h

  • Von: Steve Quinn
  • Zweck: Dies ist eine gegabelte Version des SparkFun APDS9960 Sensors von jonn26/SparkFun_APDS-9960_Sensor_Arduino_Library gegabelt. Es enthält einige Modifikationen, die beim Debuggen helfen, und verfügt über einen desensibilisierten Detektor, um Fehlauslösungen zu reduzieren.
  • Von:

Erforderlich, um diese nicht blockierende Funktionalität in Ihren Arduino-Code einzubetten und funktionierende Beispiele zu geben

APDS9960_NonBlocking.h

  • Von: Steve Quinn
  • Zweck: Bietet eine saubere Schnittstelle zum Einbetten dieser nicht blockierenden Implementierung des APDS9960-Gestensensors in Ihren Arduino-Code.
  • Von:

Echtzeit-Betriebssystem

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

APDS9960 Datenblatt

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

Empfohlen: