Ce que l'élève n'a pas à faire...

ComplémentProgramme pour l'Arduino

Les micro-contrôleurs Arduino sont déjà programmés. Dans le cadre de l'enseignement de physique-chimie, on peut se satisfaire d'un programme standard permettant la communication entre l'ordinateur et la carte Arduino via le port série.

Sur le site de Frédéric Legrand[1], professeur d'informatique appliquée aux sciences physiques en cpge, on peut lire :

Le protocole Firmata permet de commander un Arduino depuis un programme tournant sur un ordinateur (en langage Python, Java, etc). Le programme tournant sur l'arduino reçoit des ordres correspondant aux commandes standard (par exemple digitalWrite) de la part du programme de l'ordinateur.

Ce type d'interface est intéressant pour effectuer des tâches simples ne nécessitant pas de réaction en temps réel de la part de l'Arduino. Il peut aussi servir pour vérifier le fonctionnement d'un circuit électronique relié à l'Arduino, avant de mettre en place une solution en temps réel complète.

Le programme en C++ à téléverser au micro-contrôleur est disponible dans l'archive loi_ohm.zip [zip].

1
#define PIN_MODE 100
2
#define DIGITAL_WRITE 101
3
#define DIGITAL_READ 102
4
#define ANALOG_WRITE 103
5
#define ANALOG_READ 104
6
              
7
void setup() {
8
  char c;
9
  Serial.begin(500000);
10
  Serial.flush();
11
  c = 0;
12
  Serial.write(c);
13
  c = 255;
14
  Serial.write(c);
15
  c = 0;
16
  Serial.write(c);
17
}
18
              
19
void loop() {
20
  char commande;  
21
  if (Serial.available()>0) {
22
     commande = Serial.read();
23
     if (commande==PIN_MODE) commande_pin_mode();
24
     else if (commande==DIGITAL_WRITE) commande_digital_write();
25
     else if (commande==DIGITAL_READ) commande_digital_read();
26
     else if (commande==ANALOG_WRITE) commande_analog_write();
27
     else if (commande==ANALOG_READ) commande_analog_read();
28
  }
29
  // autres actions à placer ici
30
}
31
              
32
void commande_pin_mode() {
33
    char pin,mode;
34
    while (Serial.available()<2);
35
    pin = Serial.read(); // pin number
36
    mode = Serial.read(); // 0 = INPUT, 1 = OUTPUT
37
    pinMode(pin,mode);
38
}
39
              
40
void commande_digital_write() {
41
   char pin,output;
42
   while (Serial.available()<2);
43
   pin = Serial.read(); // pin number
44
   output = Serial.read(); // 0 = LOW, 1 = HIGH
45
   digitalWrite(pin,output);
46
}
47
              
48
void commande_digital_read() {
49
   char pin,input;
50
   while (Serial.available()<1);
51
   pin = Serial.read(); // pin number
52
   input = digitalRead(pin);
53
   Serial.write(input);
54
}
55
              
56
void commande_analog_write() {
57
   char pin,output;
58
   while (Serial.available()<2);
59
   pin = Serial.read(); // pin number
60
   output = Serial.read(); // PWM value between 0 and 255
61
   analogWrite(pin,output);
62
}
63
              
64
void commande_analog_read() {
65
   char pin;
66
   int value;
67
   while (Serial.available()<1);
68
   pin = Serial.read(); // pin number
69
   value = analogRead(pin);
70
   Serial.write((value>>8)&0xFF); // 8 bits de poids fort
71
   Serial.write(value & 0xFF); // 8 bits de poids faible
72
}
73
              
74

ComplémentProgrammer la lecture d'une entrée analogique

Les fonctions, comme analogRead(pin), sont toutes incluses dans une classe appelée Arduino. Le programme Python utilise le module pyserial (librairie serial).

Le programme Python est donné ci-dessous :

1
# -*- coding: utf-8 -*-
2
import serial
3
4
class Arduino():
5
    def __init__(self,port):
6
        self.ser = serial.Serial(port, baudrate=500000)
7
        c_recu = self.ser.read(1)
8
        while ord(c_recu)!=0:
9
            c_recu = self.ser.read(1)
10
        c_recu = self.ser.read(1)
11
        while ord(c_recu)!=255:
12
            c_recu = self.ser.read(1)
13
        c_recu = self.ser.read(1)
14
        while ord(c_recu)!=0:
15
            c_recu = self.ser.read(1)
16
        self.PIN_MODE = 100
17
        self.DIGITAL_WRITE = 101
18
        self.DIGITAL_READ = 102
19
        self.ANALOG_WRITE = 103
20
        self.ANALOG_READ = 104
21
        self.INPUT = 0
22
        self.OUTPUT = 1
23
        self.LOW = 0
24
        self.HIGH = 1
25
26
    def close(self):
27
        self.ser.close()
28
29
    def pinMode(self,pin,mode):
30
        self.ser.write(bytes(chr(self.PIN_MODE), "utf8"))
31
        self.ser.write(bytes(chr(pin), "utf8"))
32
        self.ser.write(bytes(chr(mode), "utf8"))
33
34
    def digitalWrite(self,pin,output):
35
        self.ser.write(bytes(chr(self.DIGITAL_WRITE), "utf8"))
36
        self.ser.write(bytes(chr(pin), "utf8"))
37
        self.ser.write(bytes(chr(output), "utf8"))
38
39
    def digitalRead(self,pin):
40
        self.ser.write(bytes(chr(self.DIGITAL_READ), "utf8"))
41
        self.ser.write(bytes(chr(pin), "utf8"))
42
        x = self.ser.read(1)
43
        return ord(x)
44
45
    def analogWrite(self,pin,output):
46
        self.ser.write(bytes(chr(self.ANALOG_WRITE), "utf8"))
47
        self.ser.write(bytes(chr(pin), "utf8"))
48
        self.ser.write(bytes(chr(output), "utf8"))
49
50
    def analogRead(self,pin):
51
        self.ser.write(bytes(chr(self.ANALOG_READ), "utf8"))
52
        self.ser.write(bytes(chr(pin), "utf8"))
53
        c1 = ord(self.ser.read(1))
54
        c2 = ord(self.ser.read(1))
55
        return c1*0x100+c2
56
57