Défi Robot : Aerocat BT⚓
L'Aerocat BT est un modèle réduit d'aéroglisseur commandé en Bluetooth via une application Android. A l'issue des 36 heures de projet un concours suivant 3 épreuves sera organisé :
1. Le plus rapide en ligne droite
2. Le plus maniable parcours en slalomant
3. Le plus endurant
La solution doit être démontable : Tous les composants fournis peuvent être démontés à l'aide d'outils classique.
Composants
Programme test sans Appli Android
Pour piloter à la'ide deux moniteur série, le servo-moteur et le moteur Brushless vous pouvez utiliser le programme ci-dessous :
1
/*2
3
Moteur Brushless et SERVO controle grace au moniteur serie :4
5
Pour le pilotage du moteur brushless l'intialisation doit se faire a la vitesse min 6
7
L'utilisateur envoie 2 nombres separes par un espace au terminal serie 8
Le premier est un identifiant :9
- 200 pour la commande du brushless 10
- 201 pour la commande du SERVO 11
Le second est l'angle ou la vitesse compris entre 0 et 180.12
13
Exemple : 14
Si on souhaite piloter le servo a un angle 90 l'appli envoie15
201 90.16
17
Pour piloter le brushless a une vitess de 50 on envoie18
200 50. 19
*/20
21
22
Servo servo;
23
Servo brushless;
24
25
const int SERVO_PIN = 16;
26
const int BRUSHLESS_PIN = 18;
27
28
const int VITESSE_MAX = 100;
29
30
int code = 0;
31
int value = 0;
32
33
// buffer réception34
char buffer[32];
35
uint8_t idx = 0;
36
37
void setup() {
38
Serial.begin(9600);
39
40
servo.attach(SERVO_PIN,544, 2400);
41
brushless.attach(BRUSHLESS_PIN, 1000, 2000);
42
43
servo.write(90);
44
brushless.write(0);
45
46
Serial.println("System ready");
47
}
48
49
void loop() {
50
while (Serial.available() > 0) {
51
char c = Serial.read();
52
53
// fin de trame54
if (c == '\n') {
55
buffer[idx] = '\0';
56
parseBuffer();57
idx = 0;
58
}
59
else {60
if (idx < sizeof(buffer) - 1) {
61
buffer[idx++] = c;
62
}
63
}
64
}
65
}
66
67
void parseBuffer() {
68
int c = 0;
69
int v = 0;
70
71
// parsing simple "code value"72
if (sscanf(buffer, "%d %d", &c, &v) == 2) {
73
code = c;
74
value = v;
75
76
executeCommand(code, value);
77
}
78
else {79
Serial.println("Parse error");
80
}
81
}
82
83
void executeCommand(int code, int value) {
84
85
if (code == 200) {
86
// brushless (ESC)87
value = constrain(value, 0, VITESSE_MAX);
88
//brushless.writeMicroseconds(map(value, 0, 100, 1000, 2000));89
brushless.write(value);
90
Serial.print("ESC: ");
91
Serial.println(value);
92
}
93
94
else if (code == 201) {
95
// servo96
value = constrain(value, 0, 180);
97
servo.write(value);
98
99
Serial.print("SERVO: ");
100
Serial.println(value);
101
}
102
103
else {104
Serial.println("Unknown code");
105
}
106
}
Configuration du module :
1
// Definition des fonctions 2
3
// sendATCommand permet d'envoyer des commande AT pour configurer le module BT4
// cmd : chaine de commande AT ("AT")5
// timeout : 2000 ms pat defaut si pas de reception6
// retourne 7
// Vrai si la la commande a bien ete prise en compte8
// Faux si timout depasse9
// 10
bool sendATCommand(const char* cmd, unsigned long timeout = 2000);
11
12
// fatalError Affiche un message d'erreur et boucle indefiniement en faisant 13
// clignoter la LED et affiche le message d'erreur au terminal serie 14
void fatalError(const char* message);
15
16
// requireATCommand Teste la commande AT cmd saisie en paramètre avec gestion 17
// de l'erreur si reponse trop logue 18
void requireATCommand(const char* cmd);
19
20
// Efface le buffer de Serial1. vider complètement le buffer série… et s’assurer 21
// qu’il n’y a plus rien qui arrive pendant un certain temps22
void clearSerial1Buffer(unsigned long silenceMs=200);
23
void setup()
24
{25
pinMode(LED_BUILTIN,OUTPUT);
26
Serial.begin(9600);
27
while (!Serial); // Attendre que Serial dispo
28
29
Serial1.begin(9600); // Commande AT
30
requireATCommand("AT"); // AT
31
requireATCommand("AT+DEFAULT"); // AT+DEFAULT
32
requireATCommand("AT+NAMEMyBT"); // AT+NAME MyBT
33
requireATCommand("AT+PIN1234"); // AT+PIN 1234
34
clearSerial1Buffer();35
}
36
void loop()
37
{38
}
39
void requireATCommand(const char* cmd) {
40
if (!sendATCommand(cmd)) {
41
fatalError(cmd);
42
}
43
}
44
45
void fatalError(const char* message) {
46
Serial.println(message);
47
48
while (true) {
49
digitalWrite(LED_BUILTIN, HIGH);
50
delay(100);
51
digitalWrite(LED_BUILTIN, LOW);
52
delay(900);
53
}
54
}
55
56
bool sendATCommand(const char* cmd, unsigned long timeout)
57
{58
while (Serial1.available() > 0) { // Vider le buffer
59
Serial1.read();
60
}
61
Serial1.print(cmd); // Envoyer la commande AT
62
63
unsigned long start = millis(); // memoriser l'instant avant la boucle
64
char buffer[32] = "";
65
uint8_t index = 0;
66
67
while (millis() - start < timeout) { // Tant que temps dans la boucle pas dépassé
68
if (Serial1.available()) { //
69
char c = Serial1.read(); // On lit la réponse du module
70
71
if (index < sizeof(buffer) - 1) { // on evite les deassement du buffer
72
buffer[index++] = c; // on stoque le caractere dans le buffer
73
buffer[index] = '\0'; // Met caractère fin de chaine
74
}
75
76
if (strstr(buffer, "OK") != nullptr) { // Si la chaîne buffer contient le texte "OK"
77
Serial.println("OK recu"); //
78
return true;
79
}
80
}
81
}
82
83
Serial.println("Timeout");
84
return false;
85
}
86
void clearSerial1Buffer(unsigned long silenceMs)
87
{88
unsigned long lastByteTime = millis();
89
90
while (millis() - lastByteTime < silenceMs) {
91
while (Serial1.available() > 0) {
92
Serial1.read();
93
lastByteTime = millis();
94
}
95
}
96
}
Programme final :
1
/*2
3
Moteur Brushless et SERVO connectes :4
5
Pour le pilotage du moteur brushless l'intialisation doit se faire a la vitesse min 6
Le smartphone envoit 2 octets bruts 7
Le premier est un identifiant :8
- 200 pour la commande du brusless 9
- 201 pour la commande du SERVO 10
Le second est l'angle ou la vitesse compris entre 0 et 180.11
Si on souhaite piloter le servo a un angle 90 l'appli envoit en BT 201 puis 90.12
Pour piloter le brushless a une vitess de 50 on envoit 200 puis 50. 13
*/14
15
16
const int VITESSE_MAX = 100;
17
const int VITESSE_MIN = 0;
18
const int BRUSHLESS_PIN = 18;
19
Servo brushless;
20
21
const int SERVO_PIN = 16;
22
Servo servo;
23
24
void setup()
25
{26
Serial.begin(9600);
27
Serial1.begin(9600);
28
servo.attach(SERVO_PIN,544, 2400);
29
brushless.attach(BRUSHLESS_PIN, 1000, 2000); // Brushless sur la broche 9
30
brushless.write(0); // vitess min
31
Serial.println("commande moteur brushless ");
32
33
}
34
void loop()
35
{36
uint8_t Code = 0; // Donnee transmise par le module Bluetooth
37
uint8_t Angle = 0;
38
if(Serial1.available()==2) // Si 2 octets sont disponible pour etre lu
39
{40
Code = Serial1.read(); // Lecture du code 200 pour vitesse et 201 pour l'angle du servo
41
42
Serial.print("code = ");
43
Serial.println(Code); //
44
if(Code == 200)
45
{46
Angle = Serial1.read(); // Lecture de l'angle
47
Serial.print("angle = ");
48
Serial.println(Angle); //
49
50
if (Angle>= 0 && Angle <= 180)
51
{52
if(Angle > VITESSE_MAX ) Angle = VITESSE_MAX;
53
if(Angle < VITESSE_MIN ) Angle = VITESSE_MIN;
54
brushless.write(Angle);
55
}
56
}else if (Code == 201)
57
{ 58
Angle = Serial1.read(); // Lecture de l'angle
59
60
Serial.print("angle = ");
61
Serial.println(Angle); //
62
if (Angle>= 0 && Angle <= 180)
63
{64
servo.write(Angle);
65
}
66
67
}
68
}
69
}





