[arduino] code pour la machine à mots

Ce post s’adresse aux étudiants CVM de Rennes, mais pourrait servir à d’autres.

Le code permet de piloter deux servos (en rajouter un troisième est facile) en “pas à pas”…

L’idée initiale (celle que j’utilise) est un demi-disque sur lesquels sont collés des mots (sur les rayons), en pivotant, le demi-disque aligne un mot.
Suivant le nombre de mots sur le demi-disque, on obtient des pas de rotation de différents angles.

Lorsque le disque passe d’un mot à l’autre, pas à pas afin de conserver un semblant de justesse, il effectue des micro-pauses entre chaque pas.
Le son généré est assez agréable (moi qui ai des souvenirs que les moins de 20 ans…. me rappelle les panneaux électromécaniques des panneaux d’affichages de gares (celui de la Gare du Nord, il y a peu était encore là)).
Pour aller du mot 1 à 5, il passe donc par 2, 3, puis 4 et enfin 5 avec une micro pause entre chaque pas.
La pause entre chaque pas est à adapter en fonction des servos.
Les HD1440 et SG90 sont destinés à des hélicoptères radio-commandés et sont donc plutôt rapides.
Les servos de base pour hobbyistes (genre RS-2) sont plus lents, il faudra donc adapter la variable delayPas en fonction de la vitesse angulaire des servos (0,12s/60° pour le SG-90, 0,10s/60° pour le HD1440A, 0,19 pour le RS-2)

Pour mon usage personnel, j’ai utilisé des micro-servos SG-90 de Tower Pro. Ils sont plus gros et plus lents mais semblent plus précis que les HD1440A de Power HD.
Les servos pour comparersg-90 de Tower Prohd1440a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// oupopo 001 à 2 servos
// by eric choisy
// This example code is in the public domain.
 
#include  <Servo.h>
 
const int nbrPas = 8;         // nbr de pas (mots sur le disque)
const int led= 13;              // pin pour led
const int delayPas= 100;   // delai entre chaque mot (défilement)
const int attente = 3000;  // durée entre chaque phrase;
 
int motEncoursA = 0;        // position sur les 8 pas servo1
int motAncienA = 0;
int motEncoursB = 0;        // position sur les 8 pas servo2
int motAncienB = 0;
 
Servo monServoA;             // création du premier servo
Servo monServoB;             // création du second servo
 
// { motAncien, motEncours, index tServo(le servo), pin}
int tableA[4] = {motAncienA,motEncoursA,0,9};
int tableB[4] = {motAncienB,motEncoursB,1,10};
Servo tServo[2] = {monServoA, monServoB};
 
void setup()
{
  // init des i/o
  pinMode(led, OUTPUT);
 
  // attache des servos
  monServoA.attach(9, 580, 2580);
  monServoB.attach(10, 580, 2580);
  // init debug
  Serial.begin(9600);
  // position initiale du servo
  monServoA.write(0);
  delay(100);
  monServoB.write(0);
  delay(100);
  // clignotement led
  digitalWrite(led, HIGH);
  delay(50);
  digitalWrite(led, LOW);
  delay(50);
  digitalWrite(led, HIGH);
  delay(50);
  digitalWrite(led, LOW);
   delay(50);
  digitalWrite(led, HIGH);
  delay(50);
  digitalWrite(led, LOW);
  // attente
  delay(1800);
  // un petit clignotement de plus
  digitalWrite(led, HIGH);
  delay(50);
  digitalWrite(led, LOW);
  delay(150);
} 
 
void loop()
{
    /* ------ debut aleatoire -------*/
    //digitalWrite(led,HIGH);
    while (motEncoursA == motAncienA) {
      motEncoursA = int(random(nbrPas));
    }
    Serial.print("\nmotEncoursA: ");
    Serial.print(motEncoursA);
    Serial.print(" / ");
    Serial.println(motAncienA);
    /* ------- fin aleatoire -------*/
    tableA[0] = motAncienA;
    tableA[1] = motEncoursA;
    // déplacement
    deplacement(tableA);
    // fin app
    while (motEncoursB == motAncienB) {
      motEncoursB = int(random(nbrPas));
    }
    Serial.print("\nmotEncoursB: ");
    Serial.print(motEncoursB);
    Serial.print(" / ");
    Serial.println(motAncienB);
    /* ------- fin aleatoire -------*/
    tableB[0] = motAncienB;
    tableB[1] = motEncoursB;
    // déplacement
    deplacement(tableB);
    //digitalWrite(led,LOW);
    delay(attente);
}
 
/////////////////////////
/* code de déplacement */
/////////////////////////
void deplacement(int* tRef) {
 
  volatile int motEncours = tRef[1];
  volatile int motAncien = tRef[0];
  Servo servo = Servo(tServo[tRef[2]]);
 
  if (!servo.attached()) {
    servo.attach(tRef[3], 580, 2580);
  }
 
  if (motEncours > motAncien) {
    // avance
    for (int i = motAncien+1; i<= motEncours; i++) {
      if (i== 0) {
        servo.write(5);
      } else {
        servo.write(i*(180/nbrPas));
      }
      Serial.print(i);
      delay(delayPas);
    }
  } else {
    // recule
    for (int i=motAncien-1; i>= motEncours; i--) {
      if (i== 0) {
        servo.write(5);
      } else {
        servo.write(i*(180/nbrPas));
      }
      Serial.print(i);
      delay(delayPas);
    }
  }
  if (motEncours== 0) {
    servo.write(5);
  } else {
    servo.write(motEncours*(180/nbrPas));
  }
  delay(100);
  if (tRef[2] == 0) {
    motAncienA = motEncoursA;
  } else {
    motAncienB = motEncoursB;
  }
  servo.detach();
}

montage avec 2 servos:
montage avec 2 servos

montage avec 3 servos:
montage avec 3 servos


À propos de cet article