Robot

Commande bluetooth

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à toutes et à tous,

J'éditerai ce post au fur et à mesure de l'avancée du projet, et des suggestions qui me seront proposées

Je créer ce post pour vous présenter mon WIP : un robot 2 roues, le robot tournera en jouant avec une différence de vitesse entre les deux roues, basé sur une arduino UNO.

Il serait commandé par bluetooth vie le module HC-05 (~4 euros chez dealextreme).

Il y aurait deux système de commande distincts :

  • Soit par un smartphone, via une appli que je créerai

  • Soit par une nunchuck de Wii, mais toujours par bluetooth

Mécanique :

Châssis :

Voici une photo du châssis actuel :

châssis

J'attend de placer tout les composants avant de le couper dans le sens de la longueur.

Moteurs :

J'ai récupéré des moteurs DC 9v dans une vielle voiture RC. les voici :

moteur

Pour les fixer sur le chassis, j'ai pris les anciens emplacement :

moteurs + fixation

moteur sur châssis

moteur sur châssis (dessous)

Electronique :

Général :

Pour les deux types de comande, j'utiliserai une carte moteur de ma création à partir du CI L298HN (voir ce post)

Je la réaliserai bientôt, mais j'ai besoin de matos qui est au lycée.

J'utiliserai aussi une arduino UNO pour le traitement des données reçues, et le module bluetooth HC-05 pour la communication.

Je compléterai aussi cette partie quand je serai chez moi

nunchuck Wii

Pour pouvoir accèder aux données de la nunchuk, je l'ai un peu modifier en lui ajoutant une prise USB :

Image utilisateur

pour pouvoir la relier au boîtier émetteur où sera situé ma ardunio nano et un des HC-05 comme ceci :

Image utilisateur

J'ai cherché sur le net quelques infos, et j'a trouvé ça.

La nunchuk communiquera avec la arduino via la communication I2C, avec les pins 4 et 5 analogiques prévus pour ça. Pour faciliter le code, j'ai utilisé cette librairie (Une que j'ai trouvé sur internet, mais que j'ai modifié légèrement.

Pour l'utiliser : Copier le dossier WiiChuck dans le dossier librairies (dans le dossier de votre IDE arduino).

Pour diriger le robot, j'utiliserai uniquement le joystick et les boutons c et z pour l'instant.

Voici les codes : (Pas encore testés)

Test du joystick : Vidéo du code

 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
#include "Wire.h"
#include "WiiChuck.h"

WiiChuck chuck = WiiChuck();

int vitesse = 0;

void setup() 
{
  Serial.begin(9600);
  chuck.begin();
  chuck.update();
}

void loop() {
  delay(50);
  chuck.update(); 
  
  if(chuck.zPressed() && chuck.cPressed())
    chuck.calibrateJoy();
    
  if(chuck.zPressed() && !chuck.cPressed())
  {
    vitesse --;
    if(vitesse < 0)
      vitesse = 0;
  }
  
  if(chuck.cPressed() && !chuck.zPressed())
  {
    vitesse ++;
    if(vitesse > 3)
      vitesse = 3;
  }
    
  if(chuck.rightJoy())
  {
    Serial.print("Droite  ");
    Serial.println(vitesse);
  }
    
  if(chuck.leftJoy())
  {
    Serial.print("Gauche  ");
    Serial.println(vitesse);
  }
    
  if(chuck.topJoy())
  {
    Serial.print("Avancer  ");
    Serial.println(vitesse);
  }
    
  if(chuck.botJoy())
  {
    Serial.print("Reculer  ");
    Serial.println(vitesse);
  }
}
 

Filaire :

  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
143
144
145
146
147
148
149
150
151
152
#include "Wire.h"
#include "WiiChuck.h"

#define FAST  255
#define MED   100
#define SLOW   50

WiiChuck chuck = WiiChuck(); // Notre nunchuk

int vitesse1 = 0; // Variable qui va être modifiée via les boutons "c" et "z"

//Moteur A
int enA = 5;
int in1 = 2;
int in2 = 3;

//Moteur B
int enB = 6;
int in3 = 4;
int in4 = 7;

void setup() 
{
  pinMode(enA, OUTPUT); // On définit les moteurs en sortie
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
  digitalWrite(enA, LOW);
  digitalWrite(enB, LOW); // On les éteints
  
  chuck.begin(); // On initialse la communication avec la manette
  chuck.update();
  chuck.calibrateJoy(); 
}

void loop() 
{
  delay(20);
  chuck.update(); 
  
  if(chuck.zPressed()) // Si le bouton "z" est pressé
  {
    vitesse1 --; // On réduit la vitesse
    if(vitesse1 < 0)
      vitesse1 = 0;
  }
  
  if(chuck.cPressed()) // SI c'est le "c"
  {
    vitesse1 ++; // On l'augmente
    if(vitesse1 > 3)
      vitesse1 = 3;
  }
   
  if(chuck.topJoy()) // Si le joystick est dirigé vers le haut
  {
    switch(vitesse1) // On avance selon la vitesse actuelle
    {
      case 0 : frein();
      break;
      case 1 : avancer(SLOW);
      break;
      case 2 : avancer(MED);
      break;
      case 3 : avancer(FAST);
    }
  }  
  
  else if(chuck.botJoy()) // Sinon, s'il est vers la bas, on recule selon la vitesse actuelle
  {
    switch(vitesse1)
    {
      case 0 : frein();
      break;
      case 1 : reculer(SLOW);
      break;
      case 2 : reculer(MED);
      break;
      case 3 : reculer(FAST);
    }
  }
 
  else // Sinon (il est au milieu de l'axe y)
    frein(); // On freine
  
  if(chuck.rightJoy()) // Si le joystick est vers la droite
    droite(); // Beeeen... On tourne à droite ^^
    
  else if(chuck.leftJoy()) // Mais s'il est vers la gauche
    gauche(); // On tourne à gauche
    
  else // Sinon (il est au milieu, sur l'axe x)
    frein(); // On freine
}

// Cette partie est un peu évidente :p

void droite(void) 
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, HIGH);
  
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(enB, HIGH);
}

void gauche(void)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(enA, HIGH);
  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  digitalWrite(enB, HIGH);
}

void reculer(int vitesse)
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, vitesse);
  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, vitesse);
}


void avancer(int vitesse)
{
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, vitesse);
  
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, vitesse);
}

void frein(void) // Frein magnétique
{
  digitalWrite(in1, HIGH);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, HIGH);
}

Bluetooth - Master :

 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
#include "Wire.h"
#include "WiiChuck.h"
#include <SoftwareSerial.h>

SoftwareSerial bt(5, 6); // Notre module Bluetooth
WiiChuck chuck = WiiChuck(); // Notre nunchuk

int led1 = 7; // Leds pour la vitesse
int led2 = 8;
int led3 = 9;

int vitesse = 0;

void setup()
{
  bt.begin(9600); // On commence la communication série avec le HC-05
  
  pinMode(led1, OUTPUT); // Les leds seront en sortie
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  
  chuck.begin(); // On initialse la communication avec la manette
  chuck.update();
  chuck.calibrateJoy(); 
  
  bt.begin(9600);
}

void loop()
{
  delay(50);
  chuck.update();
  
  if(chuck.zPressed() && !chuck.cPressed()) // Si uniquement le bonton z est appuié
  {
    vitesse --;
    if(vitesse < 0)
      vitesse = 0;
    bt.write('z'); // On le dit au bluetooth pour que la arduino de reception commande la carte moteur en fonction
  }
    
  if(chuck.cPressed() && !chuck.zPressed()) // Si uniquement le bonton c est appuié
  {
    vitesse ++;
    if(vitesse > 3)
      vitesse = 3;
    bt.write('c'); // Idem
  }
    
  if(chuck.cPressed() && chuck.zPressed()) // Si les deux en même temps
    chuck.calibrateJoy(); // On met le joystick à 0
    
  if(chuck.topJoy()) // Si le joystcik est vers le haut
    bt.write('t');
    
  if(chuck.botJoy()) // Si le joystcik est vers le bas
    bt.write('b');
    
  if(chuck.rightJoy()) // Si le joystcik est vers la droite
    bt.write('r');
    
  if(chuck.leftJoy()) // Si le joystcik est vers la gauche
    bt.write('l');
    
  switch(vitesse)
  {
    case 1 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      break;
    case 2 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      break;
    case 3 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      break;
} 

Bluetooth - Slave :

  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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <SoftwareSerial.h>

#define SLOW 50
#define MED 100
#define FAST 255

SoftwareSerial bt(7, 8); // On définit les pins de notre bluetooth

int vitesse1 = 0;

//Moteur A
int enA = 6;
int in1 = 5;
int in2 = 4;

//Moteur B
int enB = 10;
int in3 = 11;
int in4 = 12;

//LEDs pour indiquer la vitesse
int led1 = 2;
int led2 = 9;
int led3 = 13;

char value;

void setup()
{
  pinMode(enA, OUTPUT); // On définit les sorties
  pinMode(enB, OUTPUT);
  
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  
  bt.begin(9600);
}

void loop()
{
  delay(50);
  if(bt.available())
    value = bt.read();
  
  if(value == 'z')
  {
    vitesse1 --; // On réduit la vitesse
    if(vitesse1 < 0) // On verifie que vitesse ne passe pas en dessous de 0
      vitesse1 = 0;
  }
  
  else if(value == 'c')
  {
    vitesse1 ++; // On l'augmente
    if(vitesse1 > 3) // On verifie que vitesse ne passe pas au dessus de 3
      vitesse1 = 3;
  }
  
  else if (value == 't') // Si le joystick est dirigé vers le haut
  {
    switch(vitesse1) // On avance selon la vitesse actuelle
    {
      case 0 : frein();
      break;
      case 1 : avancer(SLOW);
      break;
      case 2 : avancer(MED);
      break;
      case 3 : avancer(FAST);
    }
  }  
  
  else if(value == 'b') // Sinon, s'il est vers la bas
  {
    switch(vitesse1) //On recule selon la vitesse actuelle
    {
      case 0 : frein();
      break;
      case 1 : reculer(SLOW);
      break;
      case 2 : reculer(MED);
      break;
      case 3 : reculer(FAST);
    }
  }
  
  else if (value == 'r') // Si il est vers la droite
    droite(); // Beeeen... On tourne à droite ^^
    
  else if (value == 'l') // Mais s'il est vers la gauche
    gauche(); // On tourne à gauche
    
  ledVitesse();
}

void ledVitesse(void) // Fonction pour allumer ou eteindre les led selon la vitesse
{
  switch(vitesse1)
  {
    case 0 : 
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      break;
      
    case 1 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      break;
      
    case 2 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      break;
      
    case 3 :
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      break;
  }
}

// Cette partie est un peu évidente :p

void droite(void) 
{
  delay(50);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, HIGH);
  delay(50);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(enB, HIGH);
  delay(50);
}

void gauche(void)
{
  delay(50);
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(enA, HIGH);
  delay(50);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  digitalWrite(enB, HIGH);
  delay(50);
}

void reculer(int vitesse)
{
  delay(50);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  analogWrite(enA, vitesse);
  delay(50);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  analogWrite(enB, vitesse);
  delay(50);
}


void avancer(int vitesse)
{
  delay(50);
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  analogWrite(enA, vitesse);
  delay(50);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  analogWrite(enB, vitesse);
  delay(50);
}

void frein(void) // Frein magnétique
{
  delay(50);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

Merci de donner vos avis ;)

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+1 -0
Auteur du sujet

Arf chui bete :) J'ai lu trop vite je me suis contente de me dire "pas de Serial.print dans la loop" mais je viens de voir que c'est dans le parse XD Du coup j'ai rien dit :D

^^

Edit : J'ai mis le début du code pour la récéption de données.

Je commenterai les codes ce soirpour la lisibilité ;)

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Gros édit sur ce post, au niveau du code et de la conception (J'utilise la nunchuk branché en filaire, et non par bluetooth -> pour l'instant).

Ce week-end, peut-être le remplissage de la section Mécanique ;)

Sinon, à quand les balises "secret", comme dans l'ancien SdZ ? C'est tellement utile ces trucs ^^

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Merci, c'est plus lisible maintenant (sourtout que je vais mettre des photos, ça aurait été le gros bordel à lire ^^ )

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

EDIT : J'ai mis un code pour tester le joystick, et une vidéo de démonstration de ce code. J'ai aussi mis les deux schémas (Emission et réception)

Les pins utilisés dans les codes ne sont pas les mêmes que sur les schémas, à vous d'adapter

Je commande les deux HC-05, la arduino nano et le L298HN cette aprèm ;)

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Bien le bon jour tout le monde ! Cela fait un moment que je ne vous ai pas fait part des avancées du projet.

J'ai reçu les HC-05 et ma arduino nano, j'ai réussi à en mettre un en slave et un en master, et à "binder" les deux. Je peut donc maintenant faire communiquer mes deux cartes. Je peut aussi envoyer des informations au HC-05 slave via un vieux smartphone sous Android, grâce à une petite application toute simple que j'ai créé avec App Inventor.

J'ai coupé le câble de ma nunchuk, puis ressoudé par dessus l’ancienne prise pour que la nunchuk soit toujours utilisable, et une prise USB Mâle pour pouvoir brancher la nunchuk au boîtier émetteur via une prise USB femelle sur celui-ci. (voir photos)

J'ai vérifié les connexions : toutes bonnes. Mais quand je branche le câble "Clock" au pin analogique 4 de ma arduino, (comme fait dans la vidéo postée) cela coupe toute communication série avec le PC. Je me suis donc dis que c'était un faux contact qui faisait cours-circuit, mais quand je fait le test avec une nunchuk "non trafiquée", il se passe exactement la même chose.

D'où cela peut-il venir ?

Merci de votre aide, et n'hésitez pas à donner vos impressions et conseils au fur et à mesure que le projet avance ;)

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Juste la connexion je pense car quand je lui fait faire une boucle qui envoi un mot en série a l'ordi, dès que je connecte la clock, la carte n'envoie plus rien.

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Au début, j'avait mis cela juste pour faire un test d'envoie de données:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "Wire.h"
#include "WiiChuck.h"
#include <SoftwareSerial.h>

SoftwareSerial bt(5,6);
Wiichuck chuck = Wiichuck();

void setup()
{
  Serial.begin(9600);
  bt.begin(9600);
  chuck.begin();
  chuck.update();
}

void loop()
{
  chuck.update()
  if(chuck.cPressed())
  {
    Serial.println('c');
    bt.write('c');
  }
}

Donc, comme j'ai vu que ma carte arduino n'envoyait rien, j'y ai mis ce code :

1
2
3
4
5
6
7
8
void setup()
{
  Serial.begin(9600);
} 
void loop()
{
  Serial.println("test");
}

Et avec celui-ci, quand je branche la clock, la carte cesse d'envoyer le "test"

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Après quelques tests un peu au pif, quand je branche ma clock sur reset, lorsque je l'enlève, la led L clignote quelques fois, et idem avec le fil data. Normal ou pas ?

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Auteur du sujet

Le fil qui vient de ma nunchuck appelé "clock", quand je le branche sur l'entré "reset" de ma arduino, et que je l'enlève, ça reset ma arduino.

Et sinon, oui la led continue à clignoter même avec mon fil de branché.

Édité par Roumil

Pourquoi faore simple quand on peut faire compliquer ? ;)

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte