Bonjour à tous.
Ce post risque d'être long je vous préviens.
J'ai un petit problème de programmation.
En fait, je me sers d'un arduino uno wifi pour piloter une porte de poulailler depuis internet (donc n'importe ou dans le monde...).
J'ai déjà fait ce programme qui fonctionne :
C'est assez indigeste je vous l'accorde.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 #include <Wire.h> #include <Servo.h> #include <UnoWiFiDevEd.h> #include <Adafruit_MotorShield.h> const unsigned char fdc_bas = 2; // Initialise la constante (const) de type caractère (char) et de nom "fdc_bas" à la valeur "2" : broche arduino sur laquelle ce trouve l'information du fin de course bas. const unsigned char fdc_haut = 3; // Initialise la constante (const) de type caractère (char) et de nom "fdc_haut" à la valeur "3" : broche arduino sur laquelle ce trouve l'information du fin de course haut. const unsigned char pin_alim_relais = 4; const unsigned char pos_init_servo_gauche = 5; // Initialise la constante (const) de type caractère (char) et de nom "pos_init_servos" à la valeur "90" : position initiale des servos moteurs. const unsigned char pos_init_servo_droit = 175; const unsigned char pin_analog_tension_batterie = 0; const float valeur_max_tension_mesuree_batterie = 4.53; const float valeur_min_tension_mesuree_batterie = 3.76; bool valeur_fdc_haut = false; // Initialise la variable de type booléen et de nom "valeur_fdc_haut" à l'état bas (0, "false"). bool valeur_fdc_bas = false; // Initialise la variable de type booléen et de nom "valeur_fdc_bas" à l'état bas (0, "false"). bool erreur = false; // Initialise la variable de type booléen et de nom "erreur" à l'état bas (0, "false"). bool porte_fermee = true; Adafruit_MotorShield motorshield_1 = Adafruit_MotorShield(); // Crée un objet "Adafruit_MotorShield" (qui est un shield adafruit controleur moteur), de nom "motorshield_1", avec l'adresse I2C par defaut (sans cavaliers sur la carte pour les adresses). Adafruit_StepperMotor *moteur = motorshield_1.getStepper(200, 2); // Créé un objet "Adafruit_StepperMotor" (moteur pas à pas), de nom "moteur", avec en paramètres, nombre de pas par tours ("200"), et port sur le shield : ("2" : M3 et M4) Servo servo_gauche; // Créé un objet "Servo" de nom "servo_gauche", représentant le servomoteur de gauche. Servo servo_droit; // Créé un objet "Servo" de nom "servo_droit", représentant le servomoteur de droite. void setup() { pinMode (fdc_haut, INPUT); // Définit la pin "fdc_haut" (3), comme etant une entrée ("INPUT"). pinMode (fdc_bas, INPUT); // Définit la pin "fdc_bas" (2), comme etant une entrée ("INPUT"). pinMode (pin_alim_relais, OUTPUT); digitalWrite (pin_alim_relais, HIGH); motorshield_1.begin(); // Initialise la communication avec shield à la fréquence max ; par defaut : 1.6KHz (1600 bauds/s). moteur->setSpeed(350); // Initialise la vitesse max du moteur "moteur" à 350 rpm. servo_gauche.attach(9); // Définit la pin "9", comme etant la sortie du signal pour le servomoteur de gauche : "servo_gauche". servo_droit.attach(10); // Définit la pin "10", comme etant la sortie du signal pour le servomoteur de droite : "servo_droit". Wifi.begin(); // Initialise le serveur wifi. Wifi.println(F("Web Server is up")); // Préviens le serveur que tout est ok et prêt à etre utilisé. } void loop() { while(Wifi.available()) { process(Wifi); } delay(50); } void process(WifiData client) { String command = client.readStringUntil('/'); if (command == "webserver") { WebServer(&client); } } void WebServer(WifiData *client) { int index = -1; unsigned long int temps = millis(); index = client->parseInt(); client->println("HTTP/1.1 200 OK"); client->println("Content-Type: text/html"); client->println(); client->println(F("<!DOCTYPE html>")); client->println(F("<html>")); client->println(F("<head>")); client->println(F("<meta charset=\"utf-8\">")); if (index == 1) { valeur_fdc_haut = digitalRead(fdc_haut); valeur_fdc_bas = digitalRead(fdc_bas); if (erreur || (valeur_fdc_haut && valeur_fdc_bas) || (!valeur_fdc_haut && !valeur_fdc_bas)) { page_erreur_ouverture(client); servo_gauche.write(pos_init_servo_gauche); delay(20); servo_droit.write(pos_init_servo_droit); delay(20); if (!porte_fermee) { do { moteur->step(3, BACKWARD, INTERLEAVE); valeur_fdc_bas = digitalRead(fdc_bas); } while (valeur_fdc_bas && millis() - temps < 12000); // Valeur 1 = inactif, 0 = actif. porte_fermee = true; } moteur->release(); erreur = false; } else if (valeur_fdc_haut && !valeur_fdc_bas) // Si le fin de course bas est actif et le fdc haut inactif (porte fermée) : Valeur 1 = inactif, 0 = actif. { page_ouverture(client); unsigned long int temps = millis(); servo_gauche.write(pos_init_servo_gauche); delay(20); servo_droit.write(pos_init_servo_droit); delay(20); do { moteur->step(3, FORWARD, DOUBLE); valeur_fdc_haut = digitalRead(fdc_haut); } while (valeur_fdc_haut && millis() - temps < 6000); // Valeur 1 = inactif, 0 = actif. porte_fermee = false; if (valeur_fdc_haut) { erreur = true; } else { servo_gauche.write(92); delay(20); servo_droit.write(90); delay(1020); moteur->release(); } } else if (!valeur_fdc_haut && valeur_fdc_bas) { page_ouverture_fini(client); } } else if (index == 0) { valeur_fdc_haut = digitalRead(fdc_haut); valeur_fdc_bas = digitalRead(fdc_bas); if (erreur || (valeur_fdc_haut && valeur_fdc_bas) || (!valeur_fdc_haut && !valeur_fdc_bas)) { page_erreur_fermeture(client); moteur->step(1, BACKWARD, MICROSTEP); servo_gauche.write(pos_init_servo_gauche); delay(20); servo_droit.write(pos_init_servo_droit); delay(20); if (!porte_fermee) { do { moteur->step(3, BACKWARD, MICROSTEP); valeur_fdc_bas = digitalRead(fdc_bas); } while (valeur_fdc_bas && millis() - temps < 12000); // Valeur 1 = inactif, 0 = actif. porte_fermee = true; } moteur->release(); erreur = false; } else if (valeur_fdc_bas && !valeur_fdc_haut) // Si la porte est ouverte : Valeur 1 = inactif, 0 = actif. { page_fermeture(client); moteur->step(1, BACKWARD, MICROSTEP); // Verrouille la porte pour eviter qu'elle tombe. servo_gauche.write(pos_init_servo_gauche); delay(20); servo_droit.write(pos_init_servo_droit); delay(1020); unsigned long int temps = millis(); do { moteur->step(3, BACKWARD, INTERLEAVE); valeur_fdc_bas = digitalRead(fdc_bas); } while (valeur_fdc_bas && millis() - temps < 12000); // Valeur 1 = inactif, 0 = actif. porte_fermee = true; if (valeur_fdc_bas) { erreur = true; } delay(1000); moteur->release(); } else if (!valeur_fdc_bas && valeur_fdc_haut) { page_fermeture_fini(client); digitalWrite (pin_alim_relais, LOW); } } else if (index == 10) { page_etat(client); } } }
Du coups j'ai voulu le rendre plus lisible avec des classes.
J'ai donc créé 2 classes :
une classe "Motorisation" et une autre "Pages_Web".
Mon fichier ino est a présent plus léger :
Même si il reste encore quelques éléments qui peuvent être modifiés.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include <UnoWiFiDevEd.h> #include "Motorisation.h" #include "Pages_Web.h" const unsigned short int pin_analog_tension_batterie = 0; const float valeur_max_tension_mesuree_batterie = 4.53; const float valeur_min_tension_mesuree_batterie = 3.76; void setup() { pinMode (PIN_RELAIS_ALIM, OUTPUT); digitalWrite (PIN_RELAIS_ALIM, HIGH); Wifi.begin(); // Initialise le serveur wifi. Wifi.println(F("Web Server is up")); // Préviens le serveur que tout est ok et prêt à etre utilisé. Motorisation moteur(POS_INIT_SERVO_GAUCHE, POS_INIT_SERVO_DROIT, PIN_FDC_BAS, PIN_FDC_HAUT); Page_Web pageWeb(); } void loop() { while(Wifi.available()) { process(Wifi); } delay(50); } void process(WifiData client) { String command = client.readStringUntil('/'); if (command == "webserver") { WebServer(&client); } } void WebServer(WifiData *client) { int index = -1; unsigned long int temps = millis(); index = client->parseInt(); client->println("HTTP/1.1 200 OK"); client->println("Content-Type: text/html"); client->println(); client->println(F("<!DOCTYPE html>")); client->println(F("<html>")); client->println(F("<head>")); client->println(F("<meta charset=\"utf-8\">")); if (index == 1) { moteur.ouverture_porte(); } else if (index == 0) { moteur.fermeture_porte(); } else if (index == 10) { pageWeb.page_etat(); } }
Mon fichier Pages_Web.h lui est comme ceci :
Mon problème viens du fichier Motorisation.h...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #ifndef PAGES_WEB_H #define PAGES_WEB_H #include <Arduino.h> #include "Motorisation.h" #include "defines.h" #include <UnoWiFiDevEd.h> class Page_Web { public : Page_Web(); void page_etat(); void page_ouverture(); void page_fermeture(); void page_ouverture_fini(); void page_fermeture_fini(); void page_erreur_ouverture(); void page_erreur_fermeture(); private : }; #endif
Lors de la compilation, il me ressort une erreur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #ifndef MOTORISATION #define MOTORISATION #include <Wire.h> #include <Servo.h> #include "Defines.h" #include <Arduino.h> #include "Pages_Web.h" #include <Adafruit_MotorShield.h> class Motorisation { public : Motorisation(); Motorisation(const unsigned char pos_serv_gauche_init, const unsigned char pos_serv_droit_init, const unsigned char pin_fdc_bas, const unsigned char pin_fdc_haut); void ouverture_porte(); void fermeture_porte(); bool get_valeur_fdc_haut(); bool get_valeur_fdc_bas(); private : Page_Web *pPageWeb; unsigned char fdc_bas; // Initialise la constante (const) de type caractère (char) et de nom "fdc_bas" à la valeur "2" : broche arduino sur laquelle ce trouve l'information du fin de course bas. unsigned char fdc_haut; // Initialise la constante (const) de type caractère (char) et de nom "fdc_haut" à la valeur "3" : broche arduino sur laquelle ce trouve l'information du fin de course haut. unsigned char pos_init_servo_droit; // Initialise la constante (const) de type caractère (char) et de nom "pos_init_servo_droit" à la valeur "pos_serv_droit_init" : position initiale du servo moteur de droite. unsigned char pos_init_servo_gauche; // Initialise la constante (const) de type caractère (char) et de nom "pos_init_servo_gauche" à la valeur "pos_serv_gauche_init" : position initiale du servo moteur de gauche. bool erreur = false; // Initialise la variable de type booléen et de nom "erreur" à l'état bas (0, "false"). bool porte_ouverte = false; // Initialise la variable de type booléen et de nom "porte_ouverte" à l'état bas (0, "false"). bool valeur_fdc_bas = false; // Initialise la variable de type booléen et de nom "valeur_fdc_bas" à l'état bas (0, "false"). bool valeur_fdc_haut = false; // Initialise la variable de type booléen et de nom "valeur_fdc_haut" à l'état bas (0, "false"). Adafruit_MotorShield motorshield_1 = Adafruit_MotorShield(); // Crée un objet "Adafruit_MotorShield" (qui est un shield adafruit controleur moteur), de nom "motorshield_1", avec l'adresse I2C par defaut (sans cavaliers sur la carte pour les adresses). Adafruit_StepperMotor *moteur = motorshield_1.getStepper(200, 2); // Créé un objet "Adafruit_StepperMotor" (moteur pas à pas), de nom "moteur", avec en paramètres, nombre de pas par tours ("200"), et port sur le shield : ("2" : M3 et M4) Servo servo_droit; // Créé un objet "Servo" de nom "servo_droit", représentant le servomoteur de droite. Servo servo_gauche; // Créé un objet "Servo" de nom "servo_gauche", représentant le servomoteur de gauche. }; #endif
et m'affiche la ligne :
In file included from sketch\Pages_Web.h:5:0,
from sketch\Pages_Web.cpp:1:
Motorisation.h:29: error: 'Page_Web' does not name a type
Page_Web *pPageWeb;
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_etat()':
Pages_Web.cpp:18: error: 'pMoteur' was not declared in this scope
pMoteur->get_valeur_fdc_haut = digitalRead(fdc_haut);
^
Pages_Web.cpp:18: error: 'fdc_haut' was not declared in this scope
pMoteur->get_valeur_fdc_haut = digitalRead(fdc_haut);
^
Pages_Web.cpp:19: error: 'fdc_bas' was not declared in this scope
pMoteur->get_valeur_fdc_bas = digitalRead(fdc_bas);
^
Pages_Web.cpp:21: error: 'pin_analog_tension_batterie' was not declared in this scope
valeur_tension_batterie_lue = analogRead(pin_analog_tension_batterie); // Renvoie une valeur comprise entre 0 et 1023.
^
Pages_Web.cpp:25: error: 'valeur_min_tension_mesuree_batterie' was not declared in this scope
tension_batterie_pourcent = ((tension_batterie - valeur_min_tension_mesuree_batterie) * 100) / (valeur_max_tension_mesuree_batterie - valeur_min_tension_mesuree_batterie); // max = 4.53 min = 3.76
^
Pages_Web.cpp:25: error: 'valeur_max_tension_mesuree_batterie' was not declared in this scope
tension_batterie_pourcent = ((tension_batterie - valeur_min_tension_mesuree_batterie) * 100) / (valeur_max_tension_mesuree_batterie - valeur_min_tension_mesuree_batterie); // max = 4.53 min = 3.76
^
Pages_Web.cpp:29: error: 'client' was not declared in this scope
client->print(F("<title> Porte Poulailler St Baudille : Etat. </title>"));
^
Pages_Web.cpp:40: error: 'valeur_fdc_haut' was not declared in this scope
if (valeur_fdc_haut && !valeur_fdc_bas) // Valeur 1 = inactif, 0 = actif.
^
Pages_Web.cpp:40: error: 'valeur_fdc_bas' was not declared in this scope
if (valeur_fdc_haut && !valeur_fdc_bas) // Valeur 1 = inactif, 0 = actif.
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_ouverture()':
Pages_Web.cpp:61: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/ouverture.html\">"));
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_fermeture()':
Pages_Web.cpp:70: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/fermeture.html\">"));
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_ouverture_fini()':
Pages_Web.cpp:79: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/ouverture_fini.html\">"));
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_fermeture_fini()':
Pages_Web.cpp:88: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/fermeture_fini.html\">"));
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_erreur_ouverture()':
Pages_Web.cpp:97: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/erreur_ouverture.html\">"));
^
sketch\Pages_Web.cpp: In member function 'void Page_Web::page_erreur_fermeture()':
Pages_Web.cpp:106: error: 'client' was not declared in this scope
client->print(F("<meta http-equiv=\"refresh\" content=\"0.1; URL=http://poulaillerstbaudille.free.fr/erreur_fermeture.html\">"));
^
exit status 1
'Page_Web' does not name a type(ligne suivant "private:" de mon fichier "Motorisation.h" en rouge.Page_Web *pPageWeb;
Je sais qu'il y à d'autres erreurs mais celle là je n'arrive pas à la contourner...
Si quelqu'un à une idée, piste, solution, je prendrais de bon coeur.
Désolé pour la longueur du post...
Merci d'avoir pris le temps de me lire.
Partager