Sorties analogiques (DAC)

Ce que l'on va faire ici

Ici, nous allons voir comment utiliser les broches GPIO en sortie analogiques "vraies" avec MicroPython. On parle ici de sorties analogiques "vraies" car on va pouvoir créer un niveau de tension en sortie réel, qui plus est de forme souhaitée (sinusoïdal, etc.).

Par opposition à la sortie "PWM" qui est une sortie analogique "simulée" par moyenne de tension de sortie au cours du temps.

Liens utiles :

Les broches GPIO de la Pyboard

La Pyboard dispose de 30 broches GPIO utilisables en entrée ou en sortie.

Ces broches sont dénommées :

  • X1 à X22
  • Y1 à Y8

Les broches analogiques sont :

  • X1 à X8, X11, X12
  • Y11, Y12
  • X19, X20, X21 et X22 qui sont connectées à des éléments de la carte pour mesure température, batterie, etc.

Infos techniques utiles

  • Les broches de sorties analogiques DAC produisent une tension entre 0 et 3.3V sur 8 (0-255) ou 12 bits (0-4095) soit une précision potentielle de 0,8mV !

  • Cette fonction est disponible uniquement sur les broches X5 et X6.

Instructions Micropython utiles

Déclaration

On définit une broche analogique grâce à la classe DAC() :

DAC(port,[bits=8] ) 
  • port : 1 pour la broche X5 et 2 pour la broche X6

Attention : on n'utilise pas l'objet Pin ici mais un identifiant 1 ou 2 )

Utilisation

Plusieurs fonctions potentiellement très pratiques sont disponibles :

  • .noise(freq) : génére un signal aléatoire à la fréquence donnée
  • .triangle(freq) : génère un signal triangulaire
  • .write(value) : applique la valeur voulue. Valeur max = 2**bits -1 soit 255 en 8 bits et 4095 en 12 bits
  • .write_timed(data, freq,*,[mode=DAC.NORMAL] : charge en mémoire le tableau des valeurs à utilisé (bytearray en 8 bits et half-words array en 12 bits)
    • freq : soit la fréquence seule (utilise timer 6) soit le Timer(id, frequence) avec id parmi 2,4,5,6,7 et 8
    • mode : parmi DAC.NORMAL et DAC.CIRCULAR : défile en boucle

Tout simplement sympathique cette fonctionnalité. Et les tests réalisés en 8 bits ont permis de monter à 100 000 Hz !

Exemple : Générer une sinusoidale en 8 bits (bytearray)

Le circuit à réaliser est le suivant :

Le code est le suivant :

import math
import pyb

# création d'un tableau d'octet contenant l'onde sinusoidale
buf = bytearray(100) # tableau de 100 valeurs
for i in range(len(buf)): # on défile le tableau
    buf[i] = 128 + int(127.0 * math.sin(2.0 * math.pi * i / len(buf))*0.7) # onde centrée sur 128 + coeff pleine échelle

# sortie à 400 hz
dac = DAC(1) # sortie analogique X5
dac.write_timed(buf, 400 * len(buf), mode=pyb.DAC.CIRCULAR) # sortie analogique "en boucle"

Oh la jolie sinusoïde... ! Et on peut monter en fréquence jusqu'à 50 000 Hz et plus sans souci !

Remarquer au passage :

  • comment faire un tableau de valeur numérique math
  • comment microPython supporte les calculs math imbriqués sans sourciller...

Exemple : Générer un signal triangulaire

Exemple : Générer une sinusoidale en 12 bits (half-words array)

TODO