Télécharger le code C++ d'optipan:
Visualiser le code C++ d'optipan:
1
/************************************************
2
************** Soleil, où es-tu? ****************
3
*************************************************
4
5
Ce programme permet de faire orienter un panneau
6
photovoltaique perpendiculairement à la plus
7
grande source lumineuse.
8
9
** Code développé par Yassine Bouanane **********
10
** Contact: yassine@optipan.com *****************
11
** Code disponible sur http://www.optipan.com/ **
12
** Veuillez demander l'autorisation avant de ****
13
** copier, de modifier ou d'utiliser ce code en *
14
** me contactant. *******************************
15
************************************************/
16
17
18
19
/*** Réglages ***/
20
//Vitesse du moteur - de 0 à 255
21
const int vMoteurX = 255;
22
const int vMoteurY = 255;
23
const int vMoteurPX = 150;
24
const int vMoteurPY = 150;
25
26
27
//Sensibilité - Pourcentage
28
const double precisionX = 95;
29
const double precisionY = 95;
30
const double precisionRX = 85;
31
const double precisionRY = 85;
32
const double precisionBalX = 10;
33
const double precisionBalY = 10;
34
35
//Intervale entre les revérification de la position du panneau - millisecondes
36
const int intervale = 200;
37
38
//Delai pour que les moteur tournent de 90 degrés - millisecondes
39
const int delai90X = 900;
40
const int delai90Y = 1000;
41
42
//Facteurs multiplicateurs
43
const double fmX1 = 1.0;
44
const double fmX2 = 0.9503;
45
const double fmY1 = 1.0;
46
const double fmY2 = 1.0132;
47
48
//Combien de fois le cinquiemme panneau doit produire plus que la moyenne des quatre autres pour que le panneau fasse un tour à 180 degrés
49
const double facteurP5 = 0.90;
50
51
//Latence avant qu'un moteur puisse changer de direction - en millisecondes
52
const int latMotX = 0;
53
const int latMotY = 0;
54
55
56
/*** Pins ***/
57
//Pin analogue du mini panneau 1, 2, 3, 4 et 5
58
const int pinPX1 = 0;
59
const int pinPX2 = 1;
60
const int pinPY1 = 2;
61
const int pinPY2 = 3;
62
const int pinP5 = 4;
63
64
//Pin transistor mini panneaux (Verification / Rechargement des batteries)
65
const int pinVerif = 2;
66
const int pinRecha = 3;
67
68
//Pin transistor des moteurs (X et Y) + (horaire et antihoraire) (Doivent être des pins PWM - Pulse With Modulation - pour pouvoir gerer la vitesse)
69
const int pinMotXH = 5;
70
const int pinMotXA = 6;
71
const int pinMotYH = 9;
72
const int pinMotYA = 10;
73
74
//Pin interrupteur de limitation de la rotation
75
const int pinLimiteX = 4;
76
const int pinLimiteY = 7;
77
78
const int pinAuto = 8;
79
80
/*** Variables ***/
81
//Ces variables sont utilisée pour le fonctionnement interne du programme,
82
//vous ne devez pas les modifier à moins d'avoir fait des modifications dans le programme.
83
boolean balance = true;
84
boolean balanceX = false;
85
boolean balanceY = false;
86
boolean retour = false;
87
boolean retourX = false;
88
boolean retourY = false;
89
boolean retourXL = false;
90
boolean rotationXH = HIGH;
91
boolean rotationYH = LOW;
92
unsigned long chrono = 0;
93
unsigned int chronoX = 0;
94
unsigned int chronoY = 0;
95
double pX1_val = 0;
96
double pX2_val = 0;
97
double pY1_val = 0;
98
double pY2_val = 0;
99
double p5_val = 0;
100
101
void maj_val()
102
{
103
//Mode Vérification
104
digitalWrite(pinRecha, LOW);
105
digitalWrite(pinVerif, HIGH);
106
delay(5);
107
//Mise à jour des variables contenant le niveau d'intensité de chacun des panneaux
108
pX1_val = (double) analogRead(pinPX1) * fmX1;
109
pX2_val = (double) analogRead(pinPX2) * fmX2;
110
pY1_val = (double) analogRead(pinPY1) * fmY1;
111
pY2_val = (double) analogRead(pinPY2) * fmY2;
112
p5_val = (double) analogRead(pinP5);
113
114
//Mode Rechargement
115
digitalWrite(pinVerif, LOW);
116
digitalWrite(pinRecha, HIGH);
117
}
118
//Cacul permettant de déterminer si selon une sensibilité donnée (précision en pourcentage), il fait faire tourner les moteurs
119
boolean calcul_precision(double val1, double val2, float precision)
120
{
121
if(calcul_precision(val1, val2)<precision)
122
{
123
return true;
124
}
125
else
126
{
127
return false;
128
}
129
}
130
//Cacul permettant de determiner le niveau de precision actuel
131
int calcul_precision(double val1, double val2)
132
{
133
double pourcentage;
134
if(val1<val2)
135
{
136
pourcentage = val1/val2*100.0;
137
}
138
else
139
{
140
pourcentage = val2/val1*100.0;
141
}
142
return floor(pourcentage);
143
}
144
void setup()
145
{
146
//Initialisation des pins
147
pinMode(pinVerif, OUTPUT);
148
pinMode(pinRecha, OUTPUT);
149
pinMode(pinMotXH, OUTPUT);
150
pinMode(pinMotXA, OUTPUT);
151
pinMode(pinMotYH, OUTPUT);
152
pinMode(pinMotYA, OUTPUT);
153
pinMode(pinAuto, INPUT);
154
pinMode(pinLimiteX, INPUT);
155
pinMode(pinLimiteY, INPUT);
156
}
157
void loop()
158
{
159
if(digitalRead(pinAuto)==HIGH)
160
{
161
balance = true;
162
//Si l'interrupteur de l'axe des Y est activé, on fait une rotation de 90 degrés dans l'axe des Y
163
if(digitalRead(pinLimiteY) == HIGH)
164
{
165
if(rotationYH==HIGH)
166
{
167
digitalWrite(pinMotYH, LOW);
168
analogWrite(pinMotYA, vMoteurY);
169
}
170
else
171
{
172
digitalWrite(pinMotYA, LOW);
173
analogWrite(pinMotYH, vMoteurY);
174
}
175
chrono = millis();
176
chronoY = delai90Y;
177
retour = true;
178
retourY = true;
179
while(retour)
180
{
181
if((millis()-chrono)>=chronoY)
182
{
183
retour = false;
184
digitalWrite(pinMotYH, LOW);
185
digitalWrite(pinMotYA, LOW);
186
}
187
delay(2);
188
}
189
}
190
//Si l'interrupteur de l'axe des X est activé, on arrete simplement les moteurs de l'axe des X
191
if(digitalRead(pinLimiteX) == HIGH)
192
{
193
digitalWrite(pinMotXH, LOW);
194
digitalWrite(pinMotXA, LOW);
195
}
196
//Mise à jour des variables
197
maj_val();
198
//Verification de l'axe des X
199
if((!balanceX && calcul_precision(pX1_val, pX2_val, precisionX)) || (calcul_precision(pX1_val, pX2_val, precisionX-precisionBalX)))
200
{
201
balance = false;
202
balanceX = false;
203
int v = vMoteurPX;
204
if(calcul_precision(pX1_val, pX2_val)<precisionRX)
205
{
206
v = vMoteurX;
207
}
208
if(pX1_val>pX2_val)
209
{
210
if(!(digitalRead(pinLimiteX) == HIGH && rotationXH == HIGH))
211
{
212
if(rotationXH!=HIGH)
213
{
214
digitalWrite(pinMotXH, LOW);
215
digitalWrite(pinMotXA, LOW);
216
delay(latMotX);
217
}
218
digitalWrite(pinMotXA, LOW);
219
analogWrite(pinMotXH, v);
220
if(digitalRead(pinLimiteX) == HIGH)
221
{
222
while(digitalRead(pinLimiteX) == HIGH)
223
{
224
delay(5);
225
}
226
}
227
rotationXH = HIGH;
228
}
229
}
230
else
231
{
232
if(!(digitalRead(pinLimiteX) == HIGH && rotationXH == LOW))
233
{
234
if(rotationXH!=LOW)
235
{
236
digitalWrite(pinMotXH, LOW);
237
digitalWrite(pinMotXA, LOW);
238
delay(latMotX);
239
}
240
digitalWrite(pinMotXH, LOW);
241
analogWrite(pinMotXA, v);
242
if(digitalRead(pinLimiteX) == HIGH)
243
{
244
while(digitalRead(pinLimiteX) == HIGH)
245
{
246
delay(5);
247
}
248
}
249
rotationXH = LOW;
250
}
251
}
252
}
253
else
254
{
255
balanceX = true;
256
digitalWrite(pinMotXH, LOW);
257
digitalWrite(pinMotXA, LOW);
258
}
259
//Verification de l'axe des Y
260
if((!balanceY && calcul_precision(pY1_val, pY2_val, precisionY)) || (calcul_precision(pY1_val, pY2_val, precisionY-precisionBalY)))
261
{
262
balance = false;
263
balanceY = false;
264
int v = vMoteurPY;
265
if(calcul_precision(pY1_val, pY2_val)<precisionRY)
266
{
267
v = vMoteurY;
268
}
269
if(pY1_val>pY2_val)
270
{
271
if(rotationYH!=HIGH)
272
{
273
digitalWrite(pinMotYH, LOW);
274
digitalWrite(pinMotYA, LOW);
275
delay(latMotY);
276
}
277
digitalWrite(pinMotYA, LOW);
278
analogWrite(pinMotYH, v);
279
rotationYH = HIGH;
280
}
281
else
282
{
283
if(rotationYH!=LOW)
284
{
285
digitalWrite(pinMotYH, LOW);
286
digitalWrite(pinMotYA, LOW);
287
delay(latMotY);
288
}
289
digitalWrite(pinMotYH, LOW);
290
analogWrite(pinMotYA, v);
291
rotationYH = LOW;
292
}
293
}
294
else
295
{
296
balanceY = true;
297
digitalWrite(pinMotYH, LOW);
298
digitalWrite(pinMotYA, LOW);
299
}
300
301
//Si le panneau est bien positionné (les quatres mini panneaux produisent environ la même quantité d'energie)
302
if(balance)
303
{
304
//Si le cinquieme panneau * facteurP5 produit plus d'energie que la moyenne des quatre autres, alors on fait un tour de 90 degrés dans l'axe des X
305
if(p5_val*facteurP5 >= max(pX1_val, max(pX2_val, max(pY1_val, pY2_val))))
306
{
307
chrono = millis();
308
chronoX = delai90X;
309
retourX = true;
310
retourXL = true;
311
if(digitalRead(pinLimiteX) == HIGH)
312
{
313
retourXL = false;
314
}
315
if(rotationXH==HIGH)
316
{
317
digitalWrite(pinMotXH, LOW);
318
analogWrite(pinMotXA, vMoteurX);
319
}
320
else
321
{
322
digitalWrite(pinMotXA, LOW);
323
analogWrite(pinMotXH, vMoteurX);
324
}
325
while(retourX)
326
{
327
if(retourXL && digitalRead(pinLimiteX)==HIGH)
328
{
329
if(rotationXH)
330
{
331
digitalWrite(pinMotXA, LOW);
332
analogWrite(pinMotXH, vMoteurX);
333
}
334
else
335
{
336
digitalWrite(pinMotXH, LOW);
337
analogWrite(pinMotXA, vMoteurX);
338
}
339
chronoX = 2*(millis()-chrono)+delai90X;
340
retourXL = false;
341
}
342
if(retourX && (millis()-chrono)>=chronoX)
343
{
344
retourX = false;
345
digitalWrite(pinMotXH, LOW);
346
digitalWrite(pinMotXA, LOW);
347
}
348
else
349
{
350
delay(10);
351
}
352
}
353
}
354
//Arrêt des moteurs
355
digitalWrite(pinMotXH, LOW);
356
digitalWrite(pinMotXA, LOW);
357
digitalWrite(pinMotYH, LOW);
358
digitalWrite(pinMotYA, LOW);
359
//Intervale avant revérification
360
delay(intervale);
361
}
362
else
363
{
364
delay(1);
365
}
366
}
367
else
368
{
369
digitalWrite(pinMotXH, LOW);
370
digitalWrite(pinMotXA, LOW);
371
digitalWrite(pinMotYH, LOW);
372
digitalWrite(pinMotYA, LOW);
373
}
374
}