Table des matières:

Implémentation du capteur de mouvement APDS9960 non bloquant : 5 étapes
Implémentation du capteur de mouvement APDS9960 non bloquant : 5 étapes

Vidéo: Implémentation du capteur de mouvement APDS9960 non bloquant : 5 étapes

Vidéo: Implémentation du capteur de mouvement APDS9960 non bloquant : 5 étapes
Vidéo: Arduino nano 33 1/10 , Comment utiliser le capteur APDS9960 pour détecter la couleur 2024, Novembre
Anonim
Implémentation du capteur de mouvement APDS9960 non bloquant
Implémentation du capteur de mouvement APDS9960 non bloquant
Implémentation du capteur de mouvement APDS9960 non bloquant
Implémentation du capteur de mouvement APDS9960 non bloquant
Implémentation du capteur de mouvement APDS9960 non bloquant
Implémentation du capteur de mouvement APDS9960 non bloquant

Préambule

Ce Instructable détaille comment créer une implémentation non bloquante du capteur de geste APDS9960 à l'aide de SparkFun_APDS-9960_Sensor_Arduino_Library.

introduction

Alors vous vous demandez probablement ce qui n'est pas bloquant ? Ou même bloquant d'ailleurs ?

Plus important encore, pourquoi est-il important d'avoir un droit non bloquant?

Ok, donc quand un microprocesseur exécute un programme, il exécute séquentiellement des lignes de code et, ce faisant, appelle et retourne des fonctions selon l'ordre dans lequel vous les avez écrites.

Un appel bloquant est simplement un appel à tout type de fonctionnalité qui provoque un arrêt de l'exécution, c'est-à-dire un appel de fonction où l'appelant ne reprendra pas l'exécution tant que la fonction appelée n'aura pas fini de s'exécuter.

Donc pourquoi est-ce important?

Dans le cas où vous avez écrit un code qui doit exécuter régulièrement de nombreuses fonctions de manière séquentielle, telles que lire une température, lire un bouton et mettre à jour un affichage, si le code pour mettre à jour l'affichage est un appel bloquant, votre système ne répondra pas à pressions sur les boutons et changements de température, car le processeur passera tout son temps à attendre que l'affichage se mette à jour et ne lira pas l'état du bouton ou la dernière température.

Pour ma part, je souhaite créer un appareil de bureau IoT compatible MQTT sur WiFi qui lit les valeurs de température/humidité locales et distantes, les niveaux de lumière ambiante, la pression barométrique, garde une trace du temps, affiche tous ces paramètres sur un écran LCD, se connecte à un uSD carte en temps réel, lire les entrées des boutons, écrire sur les LED de sortie et surveiller les gestes pour contrôler les éléments de mon infrastructure IoT et tout cela devant être contrôlé par un ESP8266-12.

Malheureusement, les deux seules sources de la bibliothèque APDS9960 que j'ai pu trouver étaient les bibliothèques SparkFun et AdaFruit, toutes deux extraites du code de l'application d'Avago (le fabricant de l'ADPS9960) et possédant un appel nommé « readGesture » qui contient un while(1){}; boucle qui, lorsqu'elle est utilisée dans le projet ci-dessus, entraîne la réinitialisation de l'ESP8266-12E chaque fois que le capteur ADPS9960 est saturé (c'est-à-dire lorsqu'un objet reste à proximité ou qu'une autre source IR éclaire le capteur).

Par conséquent, pour résoudre ce comportement, j'ai choisi de déplacer le traitement des gestes vers un deuxième processeur, l'ESP8266-12E devenant le microcontrôleur maître et ce système l'esclave, comme illustré sur les photos 1 et 2 ci-dessus, les diagrammes de présentation du système et de composition du système respectivement.. La photo 3 montre le circuit prototype.

Afin de limiter les modifications que je devais apporter à mon code existant, j'ai également écrit une classe/bibliothèque wrapper nommée de manière imaginative «APDS9960_NonBlocking».

Ce qui suit est une explication détaillée de la solution non bloquante.

De quelles pièces ai-je besoin ?

Si vous souhaitez construire la solution I2C qui fonctionne avec la bibliothèque APDS9960_NonBlocking, vous aurez besoin des pièces suivantes.

  1. 1 sur ATMega328P ici
  2. 1 sur PCF8574P ici
  3. 6 résistances 10K ici
  4. 4 résistances 1K ici
  5. 1 diode 1N914 ici
  6. 1 transistor NPN PN2222 ici
  7. 1 cristal de 16 MHz ici
  8. 2 condensateurs de 0,1 uF ici
  9. 1 sur condensateur électrolytique 1000uF ici
  10. 1 sur condensateur électrolytique 10uF ici
  11. 2 condensateurs 22pF ici

Si vous souhaitez lire la sortie du capteur de mouvement via l'interface parallèle, vous pouvez supprimer le PCF8574P et trois résistances 10K.

De quel logiciel ai-je besoin ?

IDE Arduino 1.6.9

De quelles compétences ai-je besoin ?

Pour configurer le système, utilisez le code source (fourni) et créez les circuits nécessaires dont vous aurez besoin:

  • Une connaissance minimale de l'électronique,
  • Connaissance d'Arduino et de son IDE,
  • Une compréhension de la façon de programmer un Arduino intégré (voir Instructable 'Programming the ATTiny85, ATTiny84 and ATMega328P: Arduino As ISP')
  • Un peu de patience.

Sujets couverts

  • Bref aperçu du circuit
  • Bref aperçu du logiciel
  • Test du dispositif de détection de geste APDS9960
  • Conclusion
  • Les références

Étape 1: Présentation du circuit

Aperçu du circuit
Aperçu du circuit

Le circuit est divisé en deux sections;

  • La première est la conversion série I2C vers parallèle réalisée via les résistances R8…10 et IC1. Ici, R8…R10 définissent l'adresse I2C pour la puce d'extension d'E/S 8 bits IC1 et NXP PCF8574A. Les plages d'adresses valides pour cet appareil sont respectivement 0x38 … 0x3F. Dans l'exemple de logiciel I2C fourni, 'I2C_APDS9960_TEST.ino' '#define GESTURE_SENSOR_I2C_ADDRESS' devrait être modifié pour s'adapter à cette plage d'adresses.
  • Tous les autres composants forment un Arduino Uno esclave embarqué et ont les fonctions suivantes;

    • R1, T1, R2 et D1 fournissent une entrée de réinitialisation de dispositif esclave. Ici, une impulsion haute active sur IC1 - P7 forcera U1 à se réinitialiser.
    • R3, R4, sont des résistances de limitation de courant pour les lignes TX/RX de programmation du dispositif embarqué.
    • C5 et R7 permettent à l'IDE Arduino de programmer automatiquement U1 via une impulsion sur la ligne DTR d'un périphérique FTDI connecté.
    • R5 et R6 sont des résistances de rappel I2C pour l'APDS9960 avec C6 assurant le découplage du rail d'alimentation local.
    • U1, C1, C2 et Q1 forment respectivement l'Arduino Uno intégré et son horloge.
    • Enfin C3 et C4 assurent le découplage local du rail d'alimentation pour U1.

Étape 2: Présentation du logiciel

Présentation du logiciel
Présentation du logiciel
Présentation du logiciel
Présentation du logiciel
Présentation du logiciel
Présentation du logiciel

Préambule

Pour compiler avec succès ce code source, vous aurez besoin des bibliothèques supplémentaires suivantes pour programmer l'Arduino Uno U1 intégré;

SparkFun_APDS9960.h

  • Par: Steve Quinn
  • Objectif: Il s'agit d'une version fourchue du capteur SparkFun APDS9960 fourchu de jonne26/SparkFun_APDS-9960_Sensor_Arduino_Library. Il a quelques modifications pour aider au débogage et dispose d'un détecteur désensibilisé pour réduire les déclenchements parasites.
  • De:

APDS9960_NonBlocking.h

  • Par: Steve Quinn
  • Objectif: Fournit une interface propre pour intégrer cette implémentation non bloquante du capteur de geste APDS9960 dans votre code Arduino.
  • De:

Voir l'Instructable suivant sur la façon de programmer un microcontrôleur Arduino Uno (ATMega328P) intégré si vous ne savez pas comment y parvenir;

PROGRAMMATION DES ATTINY85, ATTINY84 ET ATMEGA328P: ARDUINO COMME FAI

Présentation fonctionnelle

Le microcontrôleur esclave intégré ATMega328P interroge la ligne INT de l'ADPS9960. Lorsque cette ligne devient basse, le microcontrôleur lit les registres ADPS9960 et détermine si un geste valide a été détecté. Si un geste valide a été détecté, le code pour ce geste 0x0…0x6, 0xF est placé sur le port B et 'nGestureAvailable' est affirmé bas.

Lorsque l'appareil maître voit 'nGestureAvailable' actif, il lit la valeur sur le port B puis envoie temporairement 'nGestureClear' au niveau bas pour accuser réception des données.

Le périphérique esclave désactive ensuite « nGestureAvailable » et efface les données sur le port B. L'image 5 ci-dessus montre une capture d'écran prise à partir d'un analyseur logique pendant un cycle complet de détection/lecture.

Présentation des codes

L'image 1 ci-dessus détaille le fonctionnement du logiciel dans U1 l'esclave Arduino Uno intégré, ainsi que l'image 2 comment les deux tâches d'arrière-plan/de premier plan interagissent. L'image 3 est un segment de code décrivant comment utiliser la bibliothèque APDS9960_NonBlockinglibrary. L'image 4 donne un mappage entre les broches numériques Arduino Uno et les broches matérielles réelles de l'ATMega328P.

Après la réinitialisation, le microcontrôleur esclave intégré initialise l'APDS9960 permettant à la détection de geste de déclencher sa sortie INT et configure ses E/S, en attachant la routine de service d'interruption (ISR) 'GESTURE_CLEAR()' pour interrompre le vecteur INT0 (broche numérique 2, broche IC matérielle 4), en le configurant pour un déclenchement sur front descendant. Cela forme l'entrée nGestureClear de l'appareil maître.

La broche de sortie d'interruption 'INT' de l'APDS9960 est connectée à la broche numérique 4, la broche matérielle IC 6 qui est configurée comme une entrée à U1.

La ligne de signal « nGestureAvailable » sur la broche numérique 7, la broche matérielle IC 13 est configurée en tant que sortie et définie sur haut, inactive (désactivée).

Enfin, les bits 0…3 du port B sont respectivement configurés comme sorties et mis à l'état bas. Ceux-ci forment le quartet de données qui représente les différents types de gestes détectés; Aucun = 0x0, Erreur = 0xF, Haut = 0x1, Bas = 0x2, Gauche = 0x3, Droite = 0x4, Près = 0x5 et Loin = 0x6.

La tâche d'arrière-plan « Loop » est planifiée qui interroge continuellement la sortie d'interruption APDS9960 INT via la lecture de la broche numérique 4. Lorsque la sortie INT de l'APDS9960 devient active basse indiquant que le capteur a été déclenché, le microcontrôleur essaie d'interpréter tout geste en appelant « readGesture()' avec c'est while (1) {}; boucle sans fin.

Si un geste valide a été détecté, cette valeur est écrite sur le port B, la sortie 'nGestureAvailable' est affirmée et le sémaphore booléen 'bGestureAvailable' est défini, empêchant tout autre geste d'être enregistré.

Une fois que le maître a détecté la sortie active « nGestureAvailable », il lit cette nouvelle valeur et émet des impulsions « nGestureClear » actif bas. Ce front descendant déclenche la planification de la tâche de premier plan 'ISR GESTURE_CLEAR()', suspendant l'exécution de la tâche d'arrière-plan 'Loop', effaçant le port B, le sémaphore 'bGestureAvailable' et la sortie 'nGestureAvailable'.

La tâche de premier plan 'GESTURE_CLEAR()' est maintenant suspendue et la tâche d'arrière-plan 'Loop' replanifiée. D'autres gestes de l'APDS9960 peuvent maintenant être détectés.

En utilisant des tâches de premier plan/arrière-plan déclenchées par interruption de cette manière, la boucle infinie potentielle dans 'readGesture()' du périphérique esclave n'affectera pas le fonctionnement du périphérique maître et n'empêchera pas non plus l'exécution du périphérique esclave. Cela constitue la base d'un système d'exploitation en temps réel (RTOS) très simple.

Remarque: Le préfixe « n » signifie actif bas ou affirmé comme dans « nGestureAvailable »

Étape 3: Test du dispositif de détection de gestes non bloquant APDS9960

Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960
Test du dispositif de détection de gestes non bloquant APDS9960

Préambule

Même si le module APDS9960 est fourni avec +5v, il utilise un régulateur +3v3 intégré, ce qui signifie que ses lignes I2C sont compatibles +3v3 et non +5v. C'est pourquoi j'ai choisi d'utiliser l'Arduino Due compatible +3v3 comme microcontrôleur de test, pour éviter le besoin de décaleurs de niveau.

Si toutefois, vous souhaitez utiliser un Arduino Uno réel, vous devrez alors décaler les lignes I2C vers U1. Voir l'Instructable suivant où j'ai joint un jeu de diapositives utile (I2C_LCD_With_Arduino) qui donne de nombreux conseils pratiques sur l'utilisation d'I2C.

Test d'interface I2C

Les photos 1 et 2 ci-dessus montrent comment configurer et programmer le système pour l'interface I2C. Vous devrez d'abord télécharger et installer la bibliothèque APDS9960_NonBlocking. ici

Test d'interface parallèle

Les photos 3 et 4 détaillent la même chose pour l'interface parallèle

Étape 4: Conclusion

Conclusion
Conclusion

Général

Le code fonctionne bien et détecte les gestes de manière réactive sans aucun faux positif. Il est opérationnel depuis quelques semaines maintenant en tant qu'appareil esclave dans mon prochain projet. J'ai essayé de nombreux modes de défaillance différents (tout comme le moggie domestique curieux de Quinn) qui avait précédemment entraîné une réinitialisation de l'ESP8266-12, sans effet négatif.

Améliorations possibles

  • L'évidence. Réécrivez la bibliothèque APDS9960 Gesture Sensor pour qu'elle ne soit pas bloquante.

    En fait, j'ai contacté Broadcom qui m'a mis en contact avec un distributeur local qui a rapidement ignoré ma demande d'assistance, je ne suis tout simplement pas un SparkFun ou un AdaFruit, je suppose. Il faudra donc probablement attendre un peu

  • Portez le code sur un microcontrôleur esclave plus petit. L'utilisation d'un ATMega328P pour une tâche est un peu exagérée. Bien que j'ai d'abord regardé l'ATTiny84, je me suis arrêté avant d'en utiliser un car je sentais que la taille compilée du code était à la limite. Avec la surcharge supplémentaire de devoir modifier la bibliothèque APDS9960 pour qu'elle fonctionne avec une bibliothèque I2C différente.

Étape 5: Références

Nécessaire pour programmer l'arduino intégré (ATMega328P - U1)

SparkFun_APDS9960.h

  • Par: Steve Quinn
  • Objectif: Il s'agit d'une version fourchue du capteur SparkFun APDS9960 fourchu de jonne26/SparkFun_APDS-9960_Sensor_Arduino_Library. Il a quelques modifications pour aider au débogage et dispose d'un détecteur désensibilisé pour réduire les déclenchements parasites.
  • De:

Nécessaire pour intégrer cette fonctionnalité non bloquante dans votre code arduino et donner des exemples travaillés

APDS9960_NonBlocking.h

  • Par: Steve Quinn
  • Objectif: Fournit une interface propre pour intégrer cette implémentation non bloquante du capteur de geste APDS9960 dans votre code Arduino.
  • De:

Système d'exploitation en temps réel

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

Fiche technique APDS9960

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

Conseillé: