Aujourd’hui, nous nous intéresserons à comment commander le circuit de l’article précédent depuis le PC. On se servira de la liaison USB à cette fin. La première chose à faire est d’écrire le sketch pour la carte Arduino. Voici celui que j’ai créé :
// the pin in which the transistor's base is attached to
const int pannelPin = 9;
void setup()
{
// initialize the serial communication:
Serial.begin(9600);
// initialize the pin as an output:
pinMode(pannelPin, OUTPUT);
}
void loop()
{
byte intensity;
// check if data has been sent from the computer:
if (Serial.available())
{
// read the most recent byte (which will be from 0 to 255):
intensity = Serial.read();
// re-send value for debugging
Serial.println(int(intensity));
// set the PWM output according to this value:
analogWrite(pannelPin, intensity);
}
}
La principale nouveauté ici concerne la classe Serial. En effet, la carte utilise une communication série, via les pins TX/RX ou via USB.
- Serial.begin(9600) spécifie le débit de la communication. On peut aller jusqu’à 115200 baud, mais pour le moment on reste à 9600, plus standard.
- Serial.available() retourne le nombre d’octets dans le buffer du port série. On s’en sert pour savoir s’il y a un nouveau message qui est arrivé.
- Serial.read() dépile un octet du buffer.
- Serial.println() envoie le message passé en argument sur le port série, suivi d’un retour à la ligne.
Ce sketch lis le nombre qui arrive par le port série, codé sur 1 octet. Un octet permet de stocker un nombre compris entre 0 et 255. Notre ampèremètre ne pourra donc prendre qu’un nombre assez limité de positions, car le PWM n’est pas plus précis que ça. C’est une limitation technique, mais on verra que cela suffit largement. Après cela, le sketch renvoie ce nombre, pour que l’on puisse voir que tout fonctionne, et « écrit » cette valeur sur le pin qu’on a spécifié.
Voilà pour le micro-contrôleur, maintenant penchons-nous du côté du PC. L’IDE de l’Arduino intègre directement un outil pour dialoguer avec le port série, nommé Serial Monitor, nous allons donc le tester ! On le lance (ce qui au passage reset la carte Arduino et relance le sketch), la vitesse de transfert est par défaut à 9600 baud, et il ne fait pas de retour à la ligne, donc rien à changer. Une petite note en passant, si votre console affiche n’importe quoi, c’est que vous avez sans doute réglé une vitesse de transfert différente entre la carte et Serial Monitor. Le sketch qui tourne sur l’Arduino n’attend qu’un nombre, on va donc en taper un. Disons 42 (choisi totalement aléatoirement :)). Et voici le retour dans la console :
Euh ? On a 2 lignes, et qui en plus ne correspondent pas à 42 ! Notre programme ne fonctionne pas ? En fait si, tout est normal, c’est simplement que Serial Monitor traite 42 comme une chaine de caractère : le 4, qui correspond au code ascii 52, et le 2, qui possède le code ascii 50.
Il va falloir remédier à ce problème, et à première vue on a seulement le choix entre modifier notre sketch pour qu’il convertisse la chaine de caractère en nombre, ou envoyer le caractère qui possède le code ascii que l’on désire. Aucune des deux solutions ne me semblent élégante. Mais au final, on n’utilisera pas Serial Monitor, alors autant s’en passer tout de suite !
Pour le remplacer, j’ai écrit un petit script python, car j’aime bien le python, et car il se prête parfaitement bien à la réalisation de petites choses comme ça ! Nativement, Python ne permet pas de dialoguer sur un port série. Pour pallier à cela, il existe le module pySerial, relativement simple d’utilisation et présentant tout ce dont on a besoin.
Voici le script :
#_*_ coding:utf-8 _*_
import serial # require the pySerial module
import struct
ser = serial.Serial(2) # open COM3 serial port
while 1:
input = raw_input( "Enter byte value : " )
if input == "q":
break
try:
integer = int(input)
if integer < 0 or integer > 255:
raise ValueError()
except:
print "Bad input"
continue
# this doesn't matter here, as we pass an unsigned value,
# but Arduino processor is little indian
byte = struct.pack("<B", integer) # pack as an unsigned byte
ser.write(byte) # send value via the serial port
print ser.readline() # read and print response
ser.close() # close port
Il demande à l’utilisateur de taper le nombre à envoyer, entre 0 et 255, puis l’encode dans le bon format et l’envoie.
Ce coup-ci, tout se déroule comme prévu ! On va pouvoir connecter le circuit, et tester réellement !
Tout fonctionne parfaitement bien ! Si on entre 0, notre ampèremètre affiche 0, et si on entre 255, il est également au maximum ! Pour afficher 42 avec les graduations d’origine, il faut envoyer 214 (42 * 255 / 50).
Dans le prochain article, j’expliquerais comment commander plusieurs ampèremètres.
Ca ferait un super mod case tout ca
« j’ai écrit un petit script python, car j’aime bien le python » nooooooooooo!
Effectivement, un ou deux ampèremètres comme ça, ça peut le faire comme mod. Mais mon PC est par terre, et je compte rajouter 2-3 trucs en plus, donc je vais rester sur un boitier dédié (que je n’ai toujours pas trouvé :)).
Peut être une mini tour en mini/micro ATX ? ca doit pas couter très cher si t’as pas envie de la faire en DIY aussi 😉