Table des matières:

Tensions analogiques super rapides d'Arduino : 10 étapes (avec photos)
Tensions analogiques super rapides d'Arduino : 10 étapes (avec photos)

Vidéo: Tensions analogiques super rapides d'Arduino : 10 étapes (avec photos)

Vidéo: Tensions analogiques super rapides d'Arduino : 10 étapes (avec photos)
Vidéo: Tuto Live Arduino épisode 6 : Les entrées analogiques 2024, Novembre
Anonim
Image
Image

Ce Instructable montre comment générer des changements de tension analogiques super rapides à partir d'un Arduino et d'une simple paire de résistance et de condensateur. Une application où cela est utile est la génération de graphiques sur un oscilloscope. Il y a plusieurs autres projets qui ont fait cela. Johngineer montre un arbre de Noël simple utilisant la modulation de largeur d'impulsion (PWM). D'autres ont amélioré ce projet en utilisant une échelle de résistances ou en utilisant une puce de conversion numérique-analogique dédiée.

L'utilisation de PWM provoque beaucoup de scintillement, tandis que l'utilisation d'une échelle de résistances ou d'un convertisseur numérique-analogique nécessite plus de broches de sortie et de composants qui peuvent ne pas être facilement disponibles. Le circuit que j'utilise est la même paire de résistances et de condensateurs simples que celle utilisée dans la démo de l'arbre de Noël, mais fonctionne avec beaucoup moins de scintillement.

Tout d'abord, je vais vous guider tout au long du processus de construction du circuit. Ensuite, je vais vous apprendre à ajouter votre propre image. Enfin, je présenterai la théorie sur ce qui le rend plus rapide.

Si vous avez aimé ce Instructable, veuillez envisager de voter pour lui !:)

Étape 1: Construire le circuit

Construire le circuit
Construire le circuit

Pour construire le circuit, vous aurez besoin des éléments suivants:

a) Un Arduino basé sur l'Atmel 16MHz ATmega328P, tel qu'un Arduino Uno ou un Arduino Nano.

b) Deux résistances de valeur R d'au moins 150Ω.

c) Deux condensateurs de valeur C tels que C = 0,0015 / R, exemples:

  • R = 150Ω et C = 10µ
  • R = 1.5kΩ et C = 1µ
  • R = 15kΩ et C = 100nF
  • R = 150kΩ et C = 10nF

Les raisons du choix de ces valeurs sont doubles. Principalement, nous voulons maintenir le courant sur les broches de l'Arduino en dessous du courant nominal maximum de 40mA. L'utilisation d'une valeur de 150 Ω limite le courant à 30 mA lorsqu'il est utilisé avec la tension d'alimentation Arduino de 5 V. Des valeurs plus élevées de R diminueront le courant et sont donc acceptables.

La deuxième contrainte est que nous voulons garder le temps constant, qui est le produit de R et C, égal à environ 1,5 ms. Le logiciel a été spécialement réglé pour cette constante de temps. Bien qu'il soit possible d'ajuster les valeurs de R et C dans le logiciel, il existe une plage étroite autour de laquelle cela fonctionnera, alors choisissez des composants aussi proches que possible du rapport suggéré.

Une explication plus approfondie sur l'importance de la constante RC sera donnée dans la section théorie, après vous avoir montré comment assembler le circuit de démonstration.

Étape 2: configuration de l'oscilloscope

Configuration de l'oscilloscope
Configuration de l'oscilloscope

La démonstration nécessite un oscilloscope réglé en mode X/Y. Les cordons de test doivent être branchés comme indiqué sur les schémas. Votre oscilloscope sera différent du mien, mais je vais parcourir les étapes nécessaires pour configurer le mode X/Y sur mon appareil:

a) Réglez le balayage horizontal à contrôler par le canal B (l'axe X).

b) Réglez l'oscilloscope en mode double canal.

c) Réglez les volts/div sur les deux canaux afin qu'il puisse afficher des tensions de 0V à 5V. J'ai mis le mien à 0.5V/div.

d) Réglez le mode de couplage sur DC sur les deux canaux.

e) Ajustez la position de X et Y de sorte que le point soit dans le coin inférieur gauche de l'écran lorsque l'Arduino est éteint.

Étape 3: Téléchargez et exécutez le logiciel

Image
Image

Téléchargez le logiciel à partir du référentiel Fast Vector Display For Arduino. Le logiciel est sous licence GNU Affero Public License v3 et peut être librement utilisé et modifié selon les termes de cette licence.

Ouvrez le fichier "fast-vector-display-arduino.ino" dans l'IDE Arduino et téléchargez-le sur votre Arduino. Momentanément, vous verrez une animation "Bonne année" sur l'écran de votre oscilloscope.

J'ai développé ce projet en tant que hackaton personnel dans les semaines qui ont précédé Noël, il y a donc un message sur le thème de Noël et du Nouvel An que vous pouvez voir en modifiant la variable PATTERN dans le code.

Étape 4: créez votre propre dessin personnalisé

Comprendre pourquoi PWM est si lent
Comprendre pourquoi PWM est si lent

Si vous souhaitez créer votre propre dessin, vous pouvez coller les coordonnées des points dans l'esquisse Arduino sur la ligne qui définit USER_PATTERN.

J'ai trouvé qu'Inkscape est un très bon outil pour faire un dessin personnalisé:

  1. Créez du texte en utilisant une grande police audacieuse telle que Impact.
  2. Sélectionnez l'objet texte et sélectionnez "Objet vers chemin" dans le menu "Chemin".
  3. Sélectionnez des lettres individuelles et superposez-les pour créer une forme connectée
  4. Sélectionnez "Union" dans le menu "Chemin" pour les combiner en une seule courbe.
  5. S'il y a des trous dans des lettres, découpez une petite encoche en dessinant un rectangle avec l'outil rectangle et soustrayez-le du contour à l'aide de l'outil "Différence".
  6. Double-cliquez sur le chemin pour afficher les nœuds.
  7. Rectangle sélectionnez tous les nœuds et cliquez sur l'outil "Créer le coin des nœuds sélectionnés".
  8. Enregistrez le fichier SVG.

L'important est que votre dessin ait un seul chemin fermé et aucun trou. Assurez-vous que votre conception a moins d'environ 130 points.

Étape 5: Collez les coordonnées du fichier SVG dans l'IDE Arduino

  1. Ouvrez le fichier SVG et copiez les coordonnées. Ceux-ci seront intégrés dans l'élément "path". La première paire de coordonnées peut être ignorée; remplacez-les par 0, 0.
  2. Collez les coordonnées dans le croquis Arduino à l'intérieur des crochets juste après "#define USER_PATTERN".
  3. Remplacez tous les espaces par des virgules, sinon vous obtiendrez une erreur de compilation. L'outil "Remplacer et rechercher" peut être utile.
  4. Compilez et lancez !
  5. Si vous rencontrez des problèmes, surveillez la console série pour détecter d'éventuelles erreurs. En particulier, vous verrez des messages si votre motif a trop de points pour le tampon interne. Dans de tels cas, l'image présentera un scintillement excessif.

Étape 6: comprendre pourquoi PWM est si lent

Pour commencer, examinons le comportement d'un condensateur pendant qu'il se charge.

Un condensateur connecté à une source de tension Vcc augmentera sa tension selon une courbe exponentielle. Cette courbe est asymptotique, ce qui signifie qu'elle ralentira à l'approche de la tension cible. À toutes fins utiles, la tension est "assez proche" après 5 secondes RC. La RC est appelée la "constante de temps". Comme nous l'avons vu précédemment, c'est le produit des valeurs de la résistance et du condensateur de votre circuit. Le problème est que 5 RC est un temps assez long pour mettre à jour chaque point dans un affichage graphique. Cela conduit à beaucoup de scintillement!

Lorsque nous utilisons la modulation de largeur d'impulsion (PWM) pour charger un condensateur, nous ne sommes pas mieux lotis. Avec PWM, la tension bascule rapidement entre 0V et 5V. En pratique, cela signifie que nous alternons rapidement entre pousser la charge dans le condensateur et en retirer un peu tout de suite - cette poussée et traction, c'est un peu comme essayer de courir un marathon en faisant un grand pas en avant puis un petit pas en arrière encore et encore.

Lorsque vous faites la moyenne, le comportement de charge d'un condensateur à l'aide de PWM est exactement le même que si vous aviez utilisé une tension constante de Vpwm pour charger le condensateur. Il nous faut encore environ 5 secondes RC pour que nous nous approchions "assez près" de la tension souhaitée.

Étape 7: Passez de a à B, un peu plus vite

Passez de a à B, un peu plus vite
Passez de a à B, un peu plus vite

Supposons que nous ayons un condensateur déjà chargé jusqu'à Va. Supposons que nous utilisions analogWrite() pour écrire la nouvelle valeur de b. Quel est le temps minimum d'attente pour que la tension Vb soit atteinte ?

Si vous avez deviné 5 secondes RC, c'est génial ! En attendant 5 secondes RC, le condensateur va se charger à très près de Vb. Mais si on veut, on peut en fait attendre un peu moins.

Regardez la courbe de charge. Vous voyez, le condensateur était déjà à Va quand nous avons commencé. Cela signifie que nous n'avons pas à attendre le temps t_a. Nous n'aurions à le faire que si nous chargeions le condensateur à partir de zéro.

Donc, en n'attendant pas ce moment-là, nous constatons une amélioration. Le temps t_ab est en fait un peu plus court que 5 RC.

Mais attendez, nous pouvons faire tellement mieux ! Regardez tout cet espace au-dessus de v_b. C'est la différence entre Vcc, la tension maximale dont nous disposons, et le Vb que nous avons l'intention d'atteindre. Pouvez-vous voir comment cette tension supplémentaire peut nous aider à arriver là où nous voulons aller beaucoup plus rapidement ?

Étape 8: Passez de a à B, avec un chargeur turbo

Passez de a à B, avec un chargeur turbo !
Passez de a à B, avec un chargeur turbo !

C'est exact. Au lieu d'utiliser le PWM à la tension cible V_b, nous le maintenons à un Vcc constant pendant une période de temps beaucoup, beaucoup plus courte. C'est ce que j'appelle la méthode Turbo Charger et elle nous amène là où nous voulons aller très, très vite ! Après la temporisation (que nous devons calculer), nous appuyons sur les freins en basculant sur PWM à V_b. Cela empêche la tension de dépasser la cible.

Avec cette méthode, il est possible de changer la tension dans le condensateur de V_a à V_b en une fraction du temps qu'en utilisant simplement PWM. C'est comme ça que tu obtiens des places, bébé!

Étape 9: comprendre le code

Comprendre le code
Comprendre le code

Une image vaut mille mots, le diagramme montre donc les données et les opérations qui sont effectuées dans le code. De gauche à droite:

  • Les données graphiques sont stockées dans PROGMEM (c'est-à-dire dans la mémoire flash) sous la forme d'une liste de points.
  • Toute combinaison d'opérations de translation, de mise à l'échelle et de rotation est combinée dans une matrice de transformation affine. Ceci est fait une fois au début de chaque image d'animation.
  • Les points sont lus un par un à partir des données graphiques et sont chacun multipliés par la matrice de transformation stockée.
  • Les points transformés sont alimentés par un algorithme de cisaillement qui recadre tous les points en dehors de la zone visible.
  • À l'aide d'une table de recherche de retard RC, les points sont convertis en tensions de commande et en retards. La table de recherche de retard RC est stockée dans l'EEPROM et peut être réutilisée pour plusieurs exécutions du code. Au démarrage, l'exactitude de la table de recherche RC est vérifiée et toutes les valeurs incorrectes sont mises à jour. L'utilisation de l'EEPROM permet d'économiser une mémoire RAM précieuse.
  • Les tensions de commande et les retards sont écrits dans la trame inactive dans le tampon de trame. Le tampon de trame contient de l'espace pour une trame active et une trame inactive. Une fois qu'une trame complète est écrite, la trame inactive est rendue active.
  • Une routine de service d'interruption redessine continuellement l'image en lisant les valeurs de tension et les retards à partir du tampon de trame actif. Sur la base de ces valeurs, il ajuste les rapports cycliques des broches de sortie. La minuterie 1 est utilisée pour mesurer le retard jusqu'à quelques nanosecondes de précision, tandis que la minuterie 2 est utilisée pour contrôler le rapport cyclique des broches.
  • La broche avec le plus grand changement de tension est toujours « turbo chargée » avec un rapport cyclique de zéro ou 100 %, offrant le temps de charge ou de décharge le plus rapide. La broche avec un moindre changement de tension est entraînée avec un rapport cyclique choisi pour correspondre au temps de transition de la première broche. Cette correspondance de temps est importante pour s'assurer que les lignes sont tracées directement sur l'oscilloscope.

Étape 10: Avec une grande vitesse, vient une grande responsabilité

Puisque cette méthode est tellement plus rapide que PWM, pourquoi analogWrite() ne l'utilise-t-elle pas ? Eh bien, parce qu'utiliser uniquement le PWM est suffisant pour la plupart des programmes et est beaucoup plus indulgent. La méthode "Turbo Charger" nécessite cependant un codage minutieux et ne convient que pour des cas particuliers:

  1. Il est extrêmement sensible au timing. Une fois que nous atteignons le niveau de tension cible, la broche d'entraînement doit être immédiatement commutée en mode PWM normal afin d'éviter de dépasser la tension cible.
  2. Elle nécessite la connaissance de la constante RC, ces valeurs doivent donc être saisies au préalable. Avec des valeurs incorrectes, la synchronisation sera erronée et les tensions seront incorrectes. Avec un PWM normal, il y a une garantie que vous vous installerez sur la tension correcte après un certain temps, même si la constante RC n'est pas connue.
  3. Le calcul de l'intervalle de temps précis pour charger le condensateur nécessite des équations logarithmiques trop lentes pour un calcul en temps réel sur l'Arduino. Ceux-ci doivent être pré-calculés avant chaque image d'animation et mis en cache quelque part en mémoire.
  4. Les programmes traitant de cette méthode doivent composer avec le fait que les retards sont très non linéaires (ils sont, en fait, exponentiels). Les tensions cibles proches de Vcc ou GND prendront plusieurs ordres de grandeur plus longtemps à atteindre que les tensions proches du point médian.

Pour surmonter ces limitations, mon code graphique vectoriel effectue les opérations suivantes:

  1. Il utilise la minuterie 1 à 16 kHz et une routine de service d'interruption pour une manipulation et une synchronisation précises de la sortie.
  2. Il nécessite l'utilisation d'une valeur spécifique de constante de temps RC, limitant les choix des valeurs du condensateur et de la résistance.
  3. Il stocke les délais de tous les points d'une image d'animation dans une mémoire tampon. Cela signifie que la routine qui calcule les retards s'exécute à un rythme beaucoup plus lent que la routine de service d'interruption qui met à jour les broches de sortie. Une trame donnée peut être peinte plusieurs dizaines de fois avant qu'un nouvel ensemble de délais pour la trame suivante ne soit prêt à être utilisé.
  4. L'utilisation d'une mémoire tampon impose une contrainte sur le nombre de points pouvant être tracés par trame. J'utilise un encodage peu encombrant pour tirer le meilleur parti de la RAM disponible, mais il est toujours limité à environ 150 points. Au-delà d'une centaine de points environ, l'affichage commencerait de toute façon à clignoter, c'est donc un point discutable !

Conseillé: