Je comprends la démarche, mais l'utilisation des interruptions ne me laisse pas beaucoup de possibilité. Refaire en "poolant" régulièrement les ports analogiques ?
Voici le script :
Cordialement
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490 /* PC > Arduino [A P O] A = Amperemetre (non utilisé) B = Bouton B - 3 - on ou off D = Départ (pas écrit) (non utilisé) I = IR I - 3 - on ou off P = Potence (non utilisé) R = Relai R - n°Relai - On ou off - si jaune clignote S = Stand (non utilisé) Arduino ==> PC [A P VVVV] A = Mesure ampères (non utilisé) B = Bouton B - n° Bouton X = ACK (non utilisé) P = Piste P - n° Piste Z = ACK T Z - nb pistes V = Mesure volt (non utilisé) */ #include <PinChangeInt.h> const int delailoop = 1 ; // rapidité de l'Arduino en ms const long delailed = 1000 ; // Durée allumage LED en ms const byte PinIRail1 = A0 ; const byte PinIRail2 = A1 ; const byte PinPotence1 = 4 ; const byte PinPotence2 = 5 ; const int wascii = 48 ; volatile int comptageP [] = { 0 , 0 , 0 } ; int volt = A4 ; char TabJelis [21] ; char jelis ; int wdiz ; String b ; int comptoctets ; int wpiste ; char waction ; int wvaleur ; int onoff ; int compteur ; int indice ; int onoffmoteur [] = {0 , 0 , 0} ; char frein [] = {0 , 7 , 8 } ; char moteur [] = {0 , 9 , 10 } ; char bouton [] = {0 , 2 , 3 } ; int amp [] = {0 , A2 , A3} ; int rgb [] = {0 , 4 , 5 , 0 } ; // vert - rouge - libre //int valeurjaune = 50 ; int nbstop = 0 ; int oldbouton [] = {0 , 0 , 0 } ; char ledpasse [] = {0 , 11, 12} ; char ledtest = 13 ; long tpsled [] = {0, 0, 0 } ; unsigned long nextBlink [4] ; int ledState [4] ; unsigned long now [] = {0 , 0 , 0 , 0 } ; // rgb, B , R , Y int delta = 10 ; int JeClignote [] = {0 , 0, 0 , 0 } ; float value = 0 ; int moyenne [] = {0 , 0 , 0 } ; boolean onoff_frein = false ; boolean onoff_B = false ; boolean onoff_P = false ; boolean flagbouton ; boolean flagled [] = {false , false , false } ; boolean flagserie = false ; boolean flagdepart = false ; boolean flagamp = false ; boolean flagrgb = false ; int comptampe [] = {0 , 0 , 0 } ; int nombrepistes = 2 ; void interruptILS1 () { comptageP [1] = 1 ; } void interruptILS2 () { comptageP [2] = 1 ; } /* void interruptP1 () { comptageP [1] = 1 ; } void interruptP2 () { comptageP [2] = 1 ; } */ void setup() { pinMode ( PinIRail1 , INPUT_PULLUP ) ; // A0 ILS1 pinMode ( PinIRail2 , INPUT_PULLUP ) ; // A1 ILS2 /* pinMode (amp [ 1 ] , INPUT ) ; // A2 ---- non connecté pinMode (amp [ 2 ] , INPUT ) ; // A3 ---- non connecté pinMode (volt , INPUT ) ; // A4 ---- non connecté // A5 ---- */ pinMode ( bouton [ 1 ] , INPUT_PULLUP ) ; // D2 Bouton pinMode ( bouton [ 2 ] , INPUT_PULLUP ) ; // D3 Bouton /* pinMode ( rgb [ 1 ] , OUTPUT ) ; // D4 Vert non connecté pinMode ( rgb [ 2 ] , OUTPUT ) ; // D5 Rouge non connecté //pinMode ( rgb [ 3 ] , OUTPUT ) ; // D6 Rien */ pinMode ( frein [ 1 ] , OUTPUT ) ; // D7 Coupure pinMode ( frein [ 2 ] , OUTPUT ) ; // D8 Coupure pinMode ( moteur [ 1 ] , OUTPUT ) ; // D9 Alime pinMode ( moteur [ 2 ] , OUTPUT ) ; // D10 Alime pinMode ( ledpasse [ 1 ] , OUTPUT ) ; // D11 Led pinMode ( ledpasse [ 2 ] , OUTPUT ) ; // D12 Led pinMode ( ledtest , OUTPUT ) ; // D13 Led Serial.begin(9600); for (indice = 1 ; indice < 3 ; indice++) { digitalWrite( frein [ indice ] , HIGH) ; analogWrite ( moteur [indice] , 255 ); ledState [indice] = LOW ; nextBlink [indice] = 0; } onoff_P = true ; PCintPort::attachInterrupt ( PinIRail1 , interruptILS1 , RISING ) ; PCintPort::attachInterrupt ( PinIRail2 , interruptILS2 , RISING ) ; } void stoptous () { //Serial.println ( nbstop ) ; nbstop = 2 ; digitalWrite( frein [ 1 ] , onoff_frein ) ; onoffmoteur [ 1 ] = onoff ; JeClignote [ 1 ] = 0 ; digitalWrite(ledpasse [1], LOW); digitalWrite( frein [ 2 ] , onoff_frein ) ; onoffmoteur [ 2 ] = onoff ; JeClignote [ 2 ] = 0 ; digitalWrite(ledpasse [2], LOW); if (flagrgb == true ) { if (wvaleur == 0 ) { digitalWrite( rgb [ 2 ] , HIGH ) ; } else { JeClignote [3] = 1 ; } digitalWrite( rgb [ 1 ] , LOW ) ; } else //flagrgb = false { JeClignote [3] = 1 ; } } void blink (const int wled) { now [wled] = millis(); if (now [wled] >= nextBlink [wled] ) { nextBlink [wled] = now [wled] + 200; if (ledState [wled] == LOW) { digitalWrite(delta + wled, HIGH) ; ledState [wled] = HIGH; } else { digitalWrite(delta + wled, LOW); ledState [wled] = LOW; } } } void loop() { // ======================= Lecture port série ================ if (Serial.available() > 0) { jelis = char(Serial.read () ); if ( jelis == '[' ) { comptoctets = 1 ; } else { if ( jelis == ']' ) { comptoctets = comptoctets - 1 ; flagserie = true ; waction = char (TabJelis [1] ) ; wpiste = TabJelis [2] - wascii ; onoff = TabJelis [3] - wascii ; wdiz = 1 ; wvaleur = 0 ; for (indice = comptoctets ; indice > 3 ; indice --) { wvaleur = wvaleur + (TabJelis [indice] - wascii ) * wdiz ; wdiz = wdiz * 10 ; } } else { TabJelis [comptoctets] = jelis ; comptoctets = comptoctets + 1 ; } } } else { flagserie = false ; } // Y'avait qqchose et on traite if (flagserie == true ) { switch (waction) { case 'A': // ==== Gestion ou non Lecture Ampérage === flagamp = onoff ; // Serial.println ( "[X]" ) ; digitalWrite( ledtest , onoff) ; flagserie = false ; break; case 'B': // ==== Gestion ou non des boutons === if ( onoff == 1 ) { onoff_B = true ; } else { onoff_B = false ; } // Serial.println ( "[X]" ) ; flagserie = false ; break; /* case 'I': // ==== Gestion ou non des IR Rail === if ( onoff == 1 ) { PCintPort::attachInterrupt ( PinIRail1 , interruptILS1 , RISING ) ; PCintPort::attachInterrupt ( PinIRail2 , interruptILS2 , RISING ) ; onoff_P = true ; } else { detachInterrupt ( PinIRail1 ) ; detachInterrupt ( PinIRail2 ) ; onoff_P = false ; } flagserie = false ; break; */ case 'G': // ==== Gestion ou non des Feux tricolores === if ( onoff == 1 ) { flagrgb = true ; digitalWrite( rgb [1] , HIGH ) ; digitalWrite( rgb [2] , LOW ) ; } else { digitalWrite( rgb [1] , LOW ) ; digitalWrite( rgb [2] , LOW ) ; flagrgb = false ; } flagserie = false ; break; case 'M': // ==== Gestion du voltage === if ( wpiste == 1 || wpiste == 3 ) { analogWrite ( moteur [ 1 ] , wvaleur ); } if ( wpiste == 2 || wpiste == 3 ) { analogWrite ( moteur [ 2 ] , wvaleur ); } flagserie = false ; break; case 'R': // ==== Gestion des coupures === onoff_frein = false ; if ( onoff == 0 ) { onoff_frein = true ; if ( wpiste == 3 ) { nbstop = 0 ; digitalWrite( frein [ 1 ] , onoff_frein ) ; onoffmoteur [1] = onoff ; JeClignote [1] = 0 ; digitalWrite( frein [ 2 ] , onoff_frein ) ; onoffmoteur [2] = onoff ; JeClignote [2] = 0 ; digitalWrite(ledpasse [2], LOW); JeClignote [3] = 0 ; digitalWrite(ledtest, LOW) ; } else // wpiste 1 ou 2 { nbstop = nbstop - 1 ; if (nbstop < 0) { nbstop = 0 ; } digitalWrite( frein [ wpiste ] , onoff_frein ) ; onoffmoteur [wpiste] = onoff ; JeClignote [wpiste] = LOW ; digitalWrite(ledpasse [wpiste], LOW) ; JeClignote [ 3 - wpiste ] = onoffmoteur [ 3 - wpiste ] ; JeClignote [3] = LOW ; digitalWrite(ledtest , LOW); } if (flagrgb == true ) { digitalWrite( rgb [ 1 ] , HIGH ) ; digitalWrite( rgb [ 2 ] , LOW ) ; } } else ///onoff = 1 { if (wpiste == 3 ) { stoptous () ; } else { nbstop = nbstop + 1 ; if (nbstop > 1 ) { stoptous () ; } else { digitalWrite( frein [ wpiste ] , onoff_frein ) ; JeClignote [wpiste] = 1 ; } } } flagserie = false ; break; case 'T': // ==== Test de démarrage == nombrepistes = wpiste ; if ( nombrepistes <= 0 ) { nombrepistes = 2 ; } Serial.print ("[Z" ) ; Serial.print (nombrepistes) ; Serial.println ("]" ) ; digitalWrite(ledpasse[1] , HIGH) ; digitalWrite(ledpasse[2] , HIGH) ; delay ( delailed ) ; digitalWrite(ledtest, LOW) ; digitalWrite(ledpasse[1] , LOW) ; digitalWrite(ledpasse[2] , LOW) ; flagserie = false ; break; case 'V': // ==== Recherche voltage == value = analogRead ( volt ) ; //Serial.println ( volt ) ; value = (value * 50.0 / 1024.0 ) * 5.2 ; Serial.print ("[") ; Serial.print ("V") ; Serial.print ("3") ; Serial.print (value , 0) ; Serial.println ("]") ; flagserie = false ; break ; default: // ==== Sinon ... == Serial.print ( "[" ) ; Serial.print ( waction ) ; Serial.println ( "?]" ) ; flagserie = false ; break; } } // ================== fin du switch ============================ for (indice = 1 ; indice < 3 ; indice++) { if ( comptageP [indice] && onoff_P == true ) { comptageP [indice] = 0 ; Serial.print ( "[P" ) ; Serial.print ( indice ) ; Serial.println ( "]") ; digitalWrite ( ledpasse [indice] , HIGH) ; tpsled [indice] = millis () ; flagled [indice] = true ; } else { if ( flagdepart == false) { if (tpsled [indice] + delailed < millis() && flagled [indice ] == true ) { digitalWrite ( ledpasse [indice] , LOW) ; flagled [indice] = false ; } } else { flagdepart = false ; } } } // ====================== Détection Boutons 1 & 2 ==================== if ( onoff_B == true ) { for (indice = 1 ; indice < 3 ; indice++) { if (digitalRead( bouton [indice] ) == HIGH ) { if (oldbouton [indice] == 20 / delailoop ) { Serial.print ("[") ; Serial.print ("B") ; Serial.print(indice); Serial.println ("]") ; } oldbouton [indice] = oldbouton [indice] + 1 ; } else { if (oldbouton [indice] > 0) { oldbouton [indice] = 0 ; } } } } // =================== Mesure des Ampères ================= if ( flagamp == true ) { for (indice = 1 ; indice < 3 ; indice ++ ) { value = analogRead ( amp [ indice ] ) ; value = value * 1000 ; value = (value * 5 ) / 1024 ; if (comptampe [indice ] == 1000 / delailoop ) { moyenne [ indice ] = moyenne [ indice ] / comptampe [ indice ] ; if (moyenne [ indice ] > 0 ) { Serial.print ( "[A" ) ; Serial.print ( indice ) ; Serial.print ( moyenne [ indice ] ) ; Serial.println ( "]" ) ; } comptampe [ indice ] = 0 ; moyenne [ indice ] = 0 ; } else { comptampe [ indice ] ++ ; moyenne [ indice ] = moyenne [ indice ] + value ; } } } // ====================== On clignote ? ==================== for ( indice = 0 ; indice < 4 ; indice++ ) { if (JeClignote [indice] == 1) { blink ( indice ) ; } } delay ( delailoop ) ; }
JF
si vous le pouvez, passez Serial à un débit beaucoup plus important pour ne pas avoir de blocages lors de l'émission s'il y a bcp de "bavardage"
vous devriez traiter le tableau comptageP utilisé dans les interruptions en section critique dans la loop. de plus vous faites un tableau d'entier (4 octets) alors que vous les utilisez comme des booléens
déclarez le tableau comme celales interruptions deviennent
Code : Sélectionner tout - Visualiser dans une fenêtre à part volatile bool comptageP [3] = { false} ;
et on crée une copie du tableau en section critique
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void interruptILS1 () { comptageP [1] = true ; } void interruptILS2 () { comptageP [2] = true ; }
et bien sûr ensuite dans la boucle for vous utilisez la copie
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 // ================== fin du switch ============================ bool copieComptageP[sizeof comptageP]; // on travaille sur une copie // section critique noInterrupts(); memcpy(copieComptageP, comptageP, sizeof comptageP); // https://www.cplusplus.com/reference/cstring/memcpy/ memset(comptageP, false, sizeof comptageP); // https://www.cplusplus.com/reference/cstring/memset/?kw=memset interrupts();
notez aussi que si vous laissez le système allumé longtemps cette partie du code va mal gérer le rollover de millis()
il vaut mieux écrire (et on peut se passer du == true)
Code : Sélectionner tout - Visualiser dans une fenêtre à part if (tpsled [indice] + delailed < millis() && flagled [indice ] == true )
Code : Sélectionner tout - Visualiser dans une fenêtre à part if ((millis() - tpsled [indice] >= delailed) && flagled [indice ] )
PS: c'est ballot de perdre l'entrée 0 de tous vos tableaux vous devriez compter depuis l'index 0
Bonjour,
Comme déjà mentionné, l'usage des interruptions n'apporte rien ici : au lieu de lire une entrée dans loop() on lit une variable actualisée par interruption. L'imprécision étant liée au rythme de lecture, il n'y a aucun gain.
Je propose donc de revenir en scan classique, et pour éviter de prendre en compte des impulsions parasites courtes, les "oublier".
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int compte = -1; unsigned long T_up, T_dn; while(compte <= 10) { while(!digitalRead(pinHall)); // attendre impulsion signalant tour effectué T_up = micros(); while(digitalRead(pinHall)); // Attendre fin de l'impulsion T_dn = micros(); if(T_dn - T_up < TPULSE_MIN) continue; // Si impulsion trop courte on l'ignore if(compte < 0) { // 1e impulsion : démarrage du décompte des tours depart = millis(); Serial.println(depart,DEC); } compte++; } arrivee = millis()=; // on a effectué 10 tours
Bien sûr il faut régler la valeur de TPULSE_MIN en us (il semble que l'impulsion normal soit de l'ordre de la ms (cf. problème rencontré initialement) d'où l'usage de micros(). Je suis revenu en ms pour les durées de tour mais on pourrait rester en us (je ne pense pas qu'il faille plus de 70 mn pour faire 10 tours).
On pourrait détecter également si on est supérieur à une durée minimale de tour avec une troisième variable qui garderait le temps du dernier front montant de l'impulsion : T_upOld et un seuil TTOUR_MIN.
Salutations
Code C++ : 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 int compte = -1; unsigned long T_up, T_dn; unsigned long T_upOl = dmillis() + TTOUR_MIN; // On s'assure d'un premier tour fictif normal while(compte <= 10) { while(!digitalRead(pinHall)); // Attendre impulsion signalant tour effectué T_up = micros(); if(T_up - T_upOld < TTOUR_MIN) continue; // Si tour trop court on ignore cette impulsion while(digitalRead(pinHall)); // Attendre fin de l'impulsion T_dn = micros(); if(T_dn - T_up < TPULSE_MIN) continue; // Si impulsion trop courte on l'ignore T_upOld = T_up; if(compte < 0) { // 1ère impulsion : début du décompte des tours depart = millis(); Serial.println(depart,DEC); } compte++; } arrivee = millis(); // on a effectué 10 tours
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)
Bonsoir slotizer
J'ai relu, un peu le sujet et ceci, en particulier.
C'est très étonnant quand même que cela empire le problème?
As-tu, déjà, en coupant toutes les alimentations, mesuré point à point, au moyen d'un ohmmètre, la résistance entre le GND de l'Arduino et celui de chaque ILS, entre le +5V de l'Arduino et le +5V de chaque ILS, entre les sorties du signal des ILS et de leurs entrées respectives sur l'Arduino?
A+
Cordialement
jpbbricole
L'expérience est la seule chose qu'il ne faut acheter que d'occasion!
Bonjour Messieurs qui me donnent plein de pistes,
Ayant été informaticien dans ma vie professionnelle, je vais essayer de "cacher" le problème. Je viens de faire un logiciel qui donne les valeurs lues dans analogread de chaque piste, et regarder le nombre d'occurrences au passage des autos. Je pourrais peut-être ainsi créer un filtre logiciel...
La semaine prochaine, je vais être indisponible pour ces tests, donc silencieux sur le forum.
En tout cas merci pour vos aides électronique et logicielle .
A bientôt
Cordialement
Jean-François
Bonjour,
Je parlais d'une vraie photo, du câblage réel Avec quelques notes du genre : alimentation, etc...
Le problème que tu rencontres me fait furieusement penser à un câblage qui ramasse le champ électromagnétique causé par des pointes de courant. Dans le labo de CEM où je bossais c'est même un des tests qu'on réalise volontairement sur nos câbles pour voir comment se comporte l'électronique qui y est relié ; on fait varier un fort courant à proximité du câble, un peu comme tes voitures si je comprends bien
C'est pour ça que je voulais voir une photo réelle du câblage et non un schéma du câblage
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Bonjour,
Pour être plus près de ce code qu'un exemple tiré d'un sujet similaire, je l'ai regardé et l'ai un peu retravaillé (homogénéisation des noms et formats entre autres).
J'ai également introduit la gestion de tours trop courts ou trop longs ainsi que des impulsions trop courtes pour se prémunir un peu des parasites (les durées sont à affiner). Cela amène à gérer les interruptions sur changement pour récupérer les 2 fronts.
J'ai transformé le suivi du courant pour en faire une moyenne glissante en minimisant les calculs flottants. Ensuite je me suis aperçu que ce code n'est pas appelable car la broche n'est pas connectée
Il y a beaucoup de variables globales. J'en ai fait disparaître un certain nombre mais j'en ai certainement oublié.
On a l'impression que c'est un programme partiel car il y a des déclarations sans usage, des éléments déclarés mais non connectés
Comme je n'ai pas le montage rien n'a été testé.
Code INO : 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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 /* PC > Arduino [A P O] A = Amperemetre (non utilisé) B = pinBtn B - 3 - on ou off D = Départ (pas écrit) (non utilisé) I = IR I - 3 - on ou off P = Potence (non utilisé) R = Relai R - n°Relai - On ou off - si jaune clignote S = Stand (non utilisé) Arduino ==> PC [A P VVVV] A = Mesure ampères (non utilisé) B = pinBtn B - n° pinBtn X = ACK (non utilisé) P = Piste P - n° Piste Z = ACK T Z - nb pistes V = Mesure pinVolt (non utilisé) */ #include <PinChangeInt.h> #define TPULSEMIN 400UL // 400 us soit impulsion de largeur mini 0.4 ms #define TTOURMIN 4000000UL // 4 s au moins pour un tour #define TTOURMAX 2147483648UL // 35'47" au plus pour un tour const byte pinRail1 = A0 ; const byte pinRail2 = A1 ; // const byte PinPotence1 = 4; // Inutilisé !!! // const byte PinPotence2 = 5; // Inutilisé !!! const byte pinLedTst = 13 ; const byte pinFrein[] = {0, 7 8}; const byte pinMoteur[] = {0, 9, 10}; const byte pinBtn[] = {0, 2, 3}; const byte pinLeds[] = {0, 11, 12}; // Broches non connectées const byte pinAmp[] = {0, A2, A3}; const byte pinVolt = A4 ; const byte pinRGB[] = {0, 4, 5, 0}; // vert - rouge - libre const int DelayLoop = 1 ; // rapidité de l'Arduino en ms const int wascii = 48 ; const long delailed = 1000 ; // Durée allumage LED en ms volatile int8_t Pulse[] = {0, 0, 0} ; // -1 front descendant, +1 front montant char Lus[21]; int Lus_nb; int wpiste; int wvaleur; //int valeurjaune = 50 ; int nbstop = 0; int BtnVal[] = {0, 0, 0}; int ledState[4]; int delta = 10 ; int32_t Avg[] = {0 , 0 , 0}; // Moyenne glissante entière unsigned long Avg_T[] = {0 , 0, 0}; // Temps du dernier affichage de la moyenne unsigned long TPulseUp[] = {0, 0, 0}; // Front d'impulsion montant OK unsigned long TPulseNew[] = {0, 0, 0}; // Front d'impulsion montant à vérifier unsigned long nextBlink[4]; bool AmpOn = false; bool BlinkOn[] = {false, false, false, false}; bool BtnOn = false; bool FreinOn = false; bool LedsOn [] = {false, false , false}; bool PulseOn = false; bool MotorOn[] = {false, false, false}; bool RGBOn = false; void Interrupt_1() { Pulse[1] = digitalRead(pinRail1) ? 1 : -1; } void Interrupt_2() { Pulse[2] = digitalRead(pinRail2) ? 1 : -1; } void setup() { Serial.begin(9600); pinMode(pinRail1, INPUT_PULLUP); // A0 Détecteur 1 pinMode(pinRail2, INPUT_PULLUP); // A1 Détecteur 2 pinMode(pinLedTst, OUTPUT); // D13 Led test // pinMode(pinVolt, INPUT); // A4 Tension générale !!! non connecté !!! // pinMode(pinRGB[3], OUTPUT); // D6 !!! Rien !!! for(int i = 2; i > 0; --i) { pinMode(pinBtn[i], INPUT_PULLUP); // D2 Bouton voie i pinMode(pinFrein[i], OUTPUT); // D7 Coupure voie i pinMode(pinLeds[i], OUTPUT); // D11 Led voie i pinMode(pinMoteur[i], OUTPUT); // D9 Alimentation voie i // pinMode(pinAmp[i], INPUT); // A2 Courant voie i !!! non connecté !!! // pinMode(pinRGB[i], OUTPUT); // D4 Tricolore !!! non connecté !!! digitalWrite(pinFrein [i], HIGH) ; analogWrite (pinMoteur[i], 255); ledState[i] = LOW ; nextBlink[i] = 0; TPulseUp[i] = micros() - TTOURMAX; // Eviter un comptage au démarrage } PCintPort::attachInterrupt(pinRail1, Interrupt_1, CHANGE); PCintPort::attachInterrupt(pinRail2, Interrupt_2, CHANGE); PulseOn = true ; } void StopAll() { nbstop = 2 ; for(int i = 2; i > 0; --i) { MotorOn[i] = true; BlinkOn[i] = false; digitalWrite(pinFrein[i], LOW); digitalWrite(pinLeds[i], LOW); } if(RGBOn) { if(wvaleur == 0) digitalWrite(pinRGB[2], HIGH); else BlinkOn[3] = 1; digitalWrite(pinRGB[1], LOW); } else BlinkOn[3] = 1; // RGBOn = false } void Blink(const int wled) { unsigned long T = millis(); if(T - nextBlink[wled] < 200) return; nextBlink[wled] = T; ledState[wled] = ledState[wled] == LOW ? HIGH: LOW; digitalWrite(delta + wled, ledState[wled]); } void loop() { int i; float value; bool OnOff, SerialOK = false; unsigned long T; //========== Lecture port série ============== if(Serial.available() > 0) { char Lu = char(Serial.read()); if(Lu == '[' ) Lus_nb = 1; else { if(Lu == ']') { SerialOK = true ; wpiste = Lus[2] - wascii ; OnOff = (Lus[3] - wascii) > 0; wvaleur = 0 ; for(i = 4; i < Lus_nb; ++i) wvaleur = wvaleur*10 + Lus[i] - wascii; } else { Lus[Lus_nb] = Lu ; Lus_nb++; } } } // Y'avait qqchose et on traite if(SerialOK) { SerialOK = false ; switch(Lus[1]) { case 'A': // === Gérer ou non le courant === AmpOn = OnOff; digitalWrite(pinLedTst, OnOff); break; case 'B': // === Gestion ou non des boutons === BtnOn = OnOff; break; case 'G': // === Gérer ou non les Feux tricolores === RGBOn = OnOff; // if(RGBOn) { // !!! Non connecté !!! // digitalWrite(pinRGB[1], HIGH); // digitalWrite(pinRGB[2], LOW); // } else { // digitalWrite(pinRGB[1], LOW); // digitalWrite(pinRGB[2], HIGH); // !!! Si pas HIGH, à sortir du test // } break; case 'M': // === Gérer l'alimentation moteur === if(wpiste & 1) analogWrite(pinMoteur[1], wvaleur); if(wpiste & 2) analogWrite(pinMoteur[2], wvaleur); break; case 'R': // === Gérer les coupures === FreinOn = ! OnOff; if(FreinOn) { if(wpiste == 3) { nbstop = 0 ; digitalWrite(pinFrein[1], FreinOn); MotorOn[1] = OnOff; BlinkOn[1] = false; digitalWrite(pinFrein[2], FreinOn); MotorOn[2] = OnOff; BlinkOn[2] = false; digitalWrite(pinLeds[2], LOW); } else { // wpiste 1 ou 2 if(nbstop > 0) nbstop--; digitalWrite(pinFrein[wpiste], FreinOn); MotorOn[wpiste] = OnOff; BlinkOn[wpiste] = false ; digitalWrite(pinLeds[wpiste], LOW) ; BlinkOn[3 - wpiste] = MotorOn[3 - wpiste]; } BlinkOn[3] = false ; digitalWrite(pinLedTst, LOW); if(RGBOn) { digitalWrite(pinRGB[1], HIGH); digitalWrite(pinRGB[2], LOW); } } else { // OnOff = true <=> FreinOn = false if(wpiste == 3) StopAll(); else { if(++nbstop > 1) StopAll(); else { digitalWrite(pinFrein[wpiste], 0); BlinkOn[wpiste] = 1; } } } break; case 'T': // === Test de démarrage === Serial.print("[Z"); Serial.print(wpiste <= 0 ? 2 : wpiste); Serial.println("]"); digitalWrite(pinLeds[1], HIGH); digitalWrite(pinLeds[2], HIGH); delay(delailed); // Dangereux digitalWrite(pinLedTst, LOW); digitalWrite(pinLeds[1], LOW); digitalWrite(pinLeds[2], LOW); break; case 'V': // === Recherche voltage === !!! non connecté !!! // i = analogRead(pinVolt); // Serial.print("[V3"); // Serial.print((i + i >> 6) >> 2) ; // 50.0*5.2/1024.0 <> 65/256 = (64/256 +1/256) // Serial.println("]"); break ; default: // === Sinon === Serial.print("[" ) ; Serial.print(Lus[1]); Serial.println("?]"); } } //...fin du switch... // Traiter et filtrer les impulsions ========= for(i = 2 ; i > 0 ; --i) { if(Pulse[i] && PulseOn) { T = micros(); if(Pulse[i] > 0) // / Front montant ? TPulseNew[i] = T - TPulseUp[i] >= TTOURMIN ? T : TPulseUp[i]; else // \ Sinon front descendant if((TPulseNew[i] != TPulseUp[i] // Si idem => impulsion rejetée && (T - TPulseNew[i] >= TPULSEMIN)) {// Impulsion OK si pas trop courte if(TPulseNew[i] - TPulseUp[i] < TTOURMAX) { Serial.print("[P"); // Impulsion OK et tour plausible => tour validé Serial.print(i); Serial.println("]"); digitalWrite(pinLeds[i], HIGH) ; LedsOn[i] = true; } TPulseUp[i] = TPulseNew[i]; // Une impulsion OK devient un début de tour } Pulse[i] = 0; } else if(LedsOn[i] && (micros() - TPulseUp[i]) > 500000UL)) { digitalWrite(pinLeds[i], LOW) ; LedsOn[i] = false ; } } // Boutons 1 & 2 ==============================// Géré mais non utilisé !!! // if(BtnOn) { // for(i = 2 ; i > 0; --i) { // if(digitalRead(pinBtn[i])) { // if(BtnVal[i] > 20) { // Serial.print("[B") ; // Serial.print(i); // Serial.println("]") ; // BtnVal[i] = 20; // } // else BtnVal[i] += DelayLoop; // } else if(BtnVal[i] > 0) BtnVal[i] = 0 ; // } // } // Mesure du courant ==========================// !!! Non connecté !!! // if(AmpOn) { // for(i = 2; i > 0; --i) { // Avg = Avg + (x*2^16 - y)/256, a = 1/256 // Avg[i] += int32_t(analogRead(pinAmp[i])) << 8 - (Avg[i] >> 8); // T = millis(); // if(T - Avg_T[i] > 1000) { // Affichage toutes les secondes // Avg_T[i] = T; // value = Avg[i] * 7.4505806e-5; // value = (Avg[i] * 5000)/ (1024 * 65536) // Serial.print("[A"); // Serial.print(i); // Serial.print(value); // Serial.println("]") ; // } // } // } // ====================== On clignote ? ==================== for(i = 3 ; i < 4 ; i++) if(BlinkOn[i]) Blink(i); delay(DelayLoop) ; }
En espérant que cela sera utile.
Salutations
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)
Bonjour Guesset,
Merci pour tout ce travail. En effet, ce programme est partiel …et évolutif. Etant un « vieil » informaticien, aux méthodes anciennes, j’ai mis en place une architecture maître esclave, où l’arduino ne prend aucune décision : il détecte une impulsion, il envoie un message à un programme sur PC qui sait quoi en faire.
Toutefois, en lisant ton script, je me suis aperçu (en créant un pgm spécfique) que chaque voiture qui passe envoie 4 ou 5 signaux (au 1/1000 s). J’ai donc décidé de ne considérer que la présence du 3ème signal, en espérant qu’un parasite ne fera qu’1 ou 2 signaux successifs.
Le résultat est que les détections aléatoires ont disparu durant toute une soirée, A confirmer toutefois.
Mais le problème « électronique » reste entier, et j’aimerais bien le résoudre.
Mais comme le dit jpbricole, il faut vivre avec ces phénomènes et les contourner =)))
Bonjour,
Si j'ai bien compris tu as détourner la fourche optique en la remplaçant par des ILS ?
Est ce que tu peux annoter un peu l'image pour que je sache quel fil sert à quoi, et où il va ? Un peu comme j'ai fait en dessous mais avec une meilleur qualité
La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
Richard Feynman
Pour donner quelques explications ; il s'agit d'une piste-bois, où pour la détection des autos, le guide de celles-ci passe entre l'émetteur et le récepteur du LM393. Pour des raisons pratiques, j'ai découpé un bout d'environ 30 cm que je peux ainsi retourner et bricoler (cf la photo). Il y a interruption de la tresse de la piste pour y insérer les LM393. Donc une réalimentation est indispensable.
Voici la légende sur la photo
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager