c'est un Bonne nouvelle !
Bonjour à tous
A n'en point douter, les évènements à l'est n'y sont pour rien, mais je galère sur une suite de ce problème que je pensais totalement résolu et qui me fait tourner en bourrique, depuis que j'ai installé mes guirlandes de Noël, commandées par une des pistes, et que je dois modifier son programme.
Je n'ai rien changé au programme Arduino, mais les corrections du programme des séquences qui génèrent les quatre voies sont devenues totalement anarchiques.
Ce que je programme est bien programmé, mais une multitude de "parasites" sont ajoutés dans la mémoire EEPROM, à des adresses anarchiques et de quantités différentes.
Chaque ajout dans la séquence, consiste à ajouter un bit (1, 2, 8 ou 8) à une série d'adresses eeprom consécutives. Ces adresses vont de 0 à 10079 pour les 10080 minutes d'une semaine. Mon dernier exemple pratiqué juste avant de rédiger mon SOS:
- je programme des 1 (voie 1) entre 5h du matin dimanche et 8h00. C'est bien là, mais un contrôle fait apparaître des 1 aussi ailleurs. Sur ce coup deux fois mais ce n'est pas systématique. là j'ai:
- mercredi entre 1h16 et 4h15;
-vendredi entre 21h32 et samedi 0h22.
J'ai mis plein de témoins pour essayer de comprendre, en vain.
Tout à l'heure, j'avais trouvé une solution radicale (je pensais), en réduisant la vitesse de l'impression du moniteur, au point que je pensais le problème résolu, puis j'ai supprimé toutes mes impressions (du programme Arduino) pour me générer mon EEPROM finale. Catastrophe! il y a plein de parasites.
J'ai repris ma version de programme avec les impressions et ce qui semblait parfait ne l'est plus. Mais je ne suis plus en 115200 bauds mais en 57600 voire moins mais je n'y gagne rien.
Je suis tenté d'essayer de réduire la fréquence des échanges I2C, fixée à lire les infos à 100kHz. Je lis qu'on peut l'augmenter mais pas qu'on peut la réduire.
Serait-il possible de réduire cette fréquence, pour le cas où mes EEPROM ne suivraient pas? ce sont des FT24C256. Je n'ai pas besoin de vitesse pour les écritures en EEPROM, car je pense que c'est cette opération (d'écriture) qui semble apporter les parasites. Les lectures, qui elles sont permanentes en fonctionnement normal, sont toujours bonnes.
Les résistances de pullup sont de 1k.
Merci d'avance pour le futur déblocage.
Pouvez vous poster le code ?
Bien sûr, le voilà, mais depuis ma question posée, et sans rien avoir changé, plus rien ne fonctionne. Impossible de téléverser: le port COM n'est plus accessible ni sélectionnable, et le moniteur série inaccessible.
Que s'est-il passé?
C'est la fonction void stockageAllumageExtinction () // 32 place en mémoire le bit relais dans la zone EEPROM qui se charge d'écrire dans l'EEPROM
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
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639 // Version_44.ino 8 dec 2022 c'est V43T3 // devrait être la version finale // Problème des "parasites" RESOLU par baisse vitesse impression 57600 // comporte erase journalier et pas de clear général //Il est acquis que le problème EEPROM a été réglé par les pull up sur I2C // suppression des affichages impressions devenus inutoles (je pense, à vérifier) // ========================================================================== #include <I2C_eeprom.h> #include "RTClib.h" // supposé être complété de déclarations #include "LiquidCrystal_I2C.h" //librairie lcd I2C_eeprom memoire ( 0x50 , I2C_DEVICESIZE_24LC256 ) ; // AT24C256 en 0x50 LiquidCrystal_I2C lcd ( 0x27 , 20 , 4 ) ; // afficheur 4 lignes RTC_DS1307 rtc ; // horloge RAM DS1307 uint16_t minuteDeSemaine ; unsigned int clavier ; // lecture hard du clavier sur 3 bits bit à bit unsigned int KB ; // clavier converti unsigned int lectBouton ; // lecture du bouton unsigned int bouton ; // état status du bouton uint8_t Heure ; // heure actuelle uint8_t Jour ; // jour actuel uint8_t Minute ; // minute actuelle uint8_t Second ; // seconde actuelle // ajouté pour tests 17 juin 2021 uint8_t sortieRelais ; // la mémoire des relais de sortie uint8_t refreshDisplayDone ; // mémoire de refresh visu unique uint8_t choixManuel = 1 ; // voie en réglage manuel. 1 = SBWC par défaut au lancement int dureeManuelle ; // programmation d'une durée qui sera à affecter supprimé unsigned pour le pb du zéro // ============================= Devront être en RAM sauvegardée =================== int manuelCuisine ; // valeurs des manuels sauvegardés lors des coupures int pour éviter des négatifs int manuelSbWc ; int manuelBalneo ; int manuelChristmas ; // ======================================================================================== uint16_t minuteDebutAllumage ; // l'équivalent de minuteDeSemaine mais pour début (allumage) programmation uint16_t minuteFinAllumage ; // même chose mais pour la fin de séquence. uint8_t destinataireProgrammation ; // A qui appartient la programmation? 0 = cuisine (int ?) uint8_t posCurseurLigneProg ; // positions du curseur uint8_t posCurseurColonneProg ; uint16_t adressage ; // contiendra l'adresse à lire ou écrire uint16_t boucleDestination ; // je programme la destination uint16_t boucleAllumage ; // programmation de l'allumage uint16_t boucleExtinction ; // programmation de l'extinction uint16_t tempo ; // mémoire temporaire uint8_t colonneDestination ; // la colonne ??? uint16_t boucleHeureProg ; // je suis dans une boucle programmation heures (all/ext) uint16_t boucleMinuteProg ; // je suis dans une boucle programmation min (all/ext) uint16_t lastMinuteTraitee ; // = 0 ; // dernière minute affichée char daysOfTheWeek[7][4] = {"DIM", "LUN", "MAR", "MER", "JEU", "VEN", "SAM"}; //dim passé à 4 car 3 car // essai 4 dec 2022 programm heures extict // uint16_t HeureDebutExtinction ; // création/sauvegarde temporaire heure de base extintion lors programm // essai de structure dateHeure struct dateHeure // elle va contenir les membres à extraire et à utiliser pour adresser { uint8_t Jour ; // le jour de la semaine de 0 à 6 uint8_t Heure ; // heure du jour de 0 à 23 uint8_t Minute ; // la minute de 0 à 59 } maDateHeure ; // déclarations pour nouvelles fonctions: clavier, ... uint8_t programmeAEnregistrer ; // indique qu'il faut enregistrer uint8_t octetLu ; // lu sur eeprom à une adresse uint8_t octetAEcrire ; // l'octet à recopier en eeprom uint8_t readByte ( const uint16_t memoryAddress ) ; // proto readByte uint16_t memoryAddress ; // adresse en eeprom uint8_t bitRelais ; // le bit à monter lors des programmations. Dépend de destinataireProgrammation uint16_t nombreDeMinAProgrammer ; // itération de l'allumage en test uint16_t cpt ; // compteur de boucle uint8_t lastBouton ; // état du dernier bouton rafraîchi par la visu (détection de rotation) uint16_t compteurBoucle ; // pour actionner l'extinction afficheur uint16_t clignotant ; // change d'état par division compteur de boucle uint16_t minuteAncienne ; // pour test de nouvelle minute uint16_t quickHorloge ; // horloge rapide balayage const uint16_t adresseMotMagique = 0 ; const uint32_t motMagique = 0xB0CAD0 ; const uint16_t adresseDebut = adresseMotMagique + sizeof motMagique ; const uint16_t tailleRequise = 10080; // 7 jours * 24 heures * 60 minutes uint16_t temoinDeBoucle ; // compteur de boucle recherche zone (éluder premier passage) enum tJour : byte { Lundi = 0 , Mardi , Mercredi , Jeudi , Vendredi , Samedi , Dimanche } ; const char * jours [] = { "LUN" , "MAR" , "MER" , "JEU" , "VEN" , "SAM" , "DIM" } ; uint16_t newYear ; uint16_t newMonth ; uint16_t newDay ; uint16_t newHour ; uint16_t newMinut ; uint16_t newSecond ; uint8_t valeurVariable ; // curseur program année ... secondes (1 à 6) // 29 déc 2021 motsMemoires uint8_t motProgramme ; // mot des relais à afficher uint8_t motManuels ; // le mot des manuels à afficher uint8_t motRelais ; // combinaison des deux uint8_t seconde ; // seconde de l'horloge uint16_t tempoP ; // temporaire Programme 02 janvier 2022 uint16_t tempoM ; // temporaire Manuel uint16_t tempoC ; // Cuisine uint16_t tempoS ; // SB uint16_t tempoB ; // Balneo uint16_t tempoN ; // Noel uint16_t tempoPx ; // isole le Programme de ligne uint16_t tempoMx ; // isole le Manuel de ligne uint16_t resteJour ; // reste du % heures et minutes dans le jou uint16_t saveJour ; // pour sauvegardes uint16_t saveHeure ; uint16_t saveMinute ; uint8_t RlCuis ; // relais cuisine uint8_t RlSb ; // relais salle de bain uint8_t RlBal ; // relais balnéo uint8_t RlNoel ; // relais Noël uint8_t temoin ; // pour avoir résultat opération /// 5 dec 2022 int adresseBase ; // lundi avec sauts de 1440 int offsetEeprom = 0 ; // essai de décalage dans eeprom uint8_t toBeWritten ; // octet devant être écrit uint8_t byteLu ; // octet lu uint16_t newAddressW ; // nouvelle adresse où écire en eeprom uint16_t newAddressR ; // nouvelle adresse où lire en eeprom // les fonctions qui vont lire et écrire un octet void writeEeprom () ; // écrit un octet là où ça pointe void readEeprom () ; // lit un octet // ====================déclarations des fonctions ================================= void displayLigneUneNormale () ; // 01 void displayDateHeure () ; // 02 affiche DAY XXHYY à la ligne reçue void readRTC () ; // lecture 1307 void cycleNormal () ; // 03 reste coincé tant que manuel non validé void cycleControle () ; // 04 lecture du programme void displayLigneUneManuel () ; // 05 commande manuelle void displayLigneUneProgrammation () ; // 06 void refreshRelais () ; // 07 void clearLigneZero ( ) ; // 08 effacement de ligne 1 void clearLigneUn ( ) ; // 09 effacement de ligne 2 void clearLigneDeux ( ) ; // 10 effacement de ligne 3 void clearLigneTrois ( ) ; // 11 effacement de ligne 4 void effaceVingtCaracteres () ; // 12 envoie 20 espaces à partir du curseur void afficheChoixVoieManuelle () ; // 13 affiche la voie manuelle en réglage void affichageDureeManuelle () ; // 14 affichage de la durée en cours de programmation non encore affectée void readClavier () ; // 15 lecture clavier non nettoyé void displayDestinataire () ; // 16 affichage en ligne 2 de la voie programmée void preparationProgrammation () ; // 17 textes préparatifs void curseurClignoteProg () ; // 18 mise en clignotement du curseur pour avertir où on programme void afficheAllumage () ; // 20 affiche DateHeure à une position demandée void boucleProgrammationDestinataire () ; // 21 ne sortira que programmer allulmage void boucleProgrammationAllumage () ; // 22 pour programmer allumage void boucleProgrammationExtinction () ; // 23 à présent, enregistrer void programmationJourAllumage () ; // 24 boucle programmation réservée void programmationHeureAllumage () ; // 25 boucle programmation réservée void programmationMinuteAllumage () ; // 26 boucle programmation réservée void programmationJourExtinction () ; // 27 boucle programmation réservée void programmationHeureExtinction () ; // 28 boucle programmation réservée void programmationMinuteExtinction () ; // 29 boucle programmation réservée void readBouton () ; // 30 lecture du bouton void debugClavier () ; // 31 Débogage clavier void stockageAllumageExtinction () ; // 32 place en mémoire le bit relais dans la zone EEPROM void incrementDateHeure () ; // 33 incrémentation de la structure incrementDateHeure void allumeRouge () ; // 35 Voyants de test void eteintRouge () ; // 36 void allumeBleu () ; // 37 void eteintBleu () ; // 38 void allumeJaune () ; // 39 void eteintJaune () ; // 40 void afficheDestinAbrege () ; // 41 txt et pas nb void positionTroisVerificationsEeprom () ; // 42 les vérifications eeprom void dumpAdresseZero () ; // 43 Pour tests eeprom void decodageJHM () ; // 44 décode minuteDebutAllumage en Jour Heure et Minute void clearEcran () ; // 45 nettoyage complet d'ecran void creationBitRelais () ; // 47 remplissage de la mémoire bitRelais de la valeur destinataire void afficheLesManuels () ; // 52 affiche en ligne 3 du LCD les 4 temps manuels void gestionDesManuels () ; // 53 refresh des manuels par l'horloge puisque nouvelle minute void ajoutDeBoucle () ; // 54 Ajout dans le lopp sans trop décaler les listings void nettoyageEtoilesRelais () ; // 56 pour supprimer les parasites du manuel void boutonEgaleZero () ; // 57 position normale void boutonEgaleUn () ; // 58 Position commandes manuelles void boutonEgaleDeux () ; // 59 PROGRAMMATION des séquences de chaque voie vers la mémoire void boutonEgaleTrois () ; // 60 contrôles void detectionRotationBouton () ; // 61 détection de rotation de bouton void copieValeursManuellesEnNvram () ; // 61 mémorisation des manuels en RAM 1307 void initialisationDesManuelsAuSetup () ; // 62 transfert de RAM sauvegardée vers manuels au boot void testNouvelleMinute () ; // détection d'une nouvelle minute à rafraîchir void displayLigneUneMah () ; // message ligne 1 mise à l'heure void boutonEgaleTrois () ; /// 60 fonction 3 contrôles 28/12/2021 nouvelles fonctions eeprom void balayerLaSemaine () ; // balayage rapide (auto?) de la semaine void refreshMemoireRelaisQuick () ; // transfère état relais de eeprom vers sortieRelais (mémoire) void avorte () ; // affiche message avortement void creationMotManuel () ; // création du mot à mixer avec motProgramme pour display * void afficheProgrammation () ; /// 19 refraîchit la programmation suite à une modification void listeLesNonZero () ; // établit la liste des minutes NZ dans EEPROM 4 janvier 2022 void toBeDoneQuickly () ; // ce qui est à faire dans la boucle rapide: vite Up, lentement Down // 5 dec 2022 ajout d'effacement journalier void eraseUnJour () ; // efface un jour à définir void afficheLeJour () ; // affiche le jour en Eeprom fonction de adresseBase void eraseLeJour () ; // efface le four en Eeprom choisi par adresseBase void tempoMilleJaune () ; // tempo de 1000 et voyant jaune // ===== Fin des déclarations ==== // ========================== SET UP ============================ void setup () { // pour eeprom // Serial.begin ( 115200 ) ; // essai à demi vitesse Serial.begin ( 57600 ) ; // essai vitesse réduite memoire.begin () ; // essais pour débogage seulement ou kit pinMode ( 8 , OUTPUT ) ; // borne 8 en sortie LED BLEU pinMode ( 11 , OUTPUT ) ; // borne 8 en sortie LED ROUGE pinMode ( 12 , OUTPUT ) ; // borne 8 en sortie LED JAUNE clavier = 0 ; KB = 0 ; lcd.init(); // nécessaire pour l'afficheur lcd.backlight() ; lcd.setCursor( 0 , 0 ) ; refreshDisplayDone = 0 ; // mémoire de refresh visu unique initialisée destinataireProgrammation = 0 ; // cuisine par défaut. Sera modifié par clavier // on fixe 5 6 et 7 en entrées pour clavier // programmation des pins logiques 6 7 et 8 pour clavier en entrées pinMode ( 9 , OUTPUT ) ; // les 4 sorties pour les relais pinMode ( 2 , OUTPUT ) ; pinMode ( 3 , OUTPUT ) ; pinMode ( 4 , OUTPUT ) ; pinMode ( 5 , INPUT ) ; pinMode ( 6 , INPUT ) ; pinMode ( 7 , INPUT ) ; // les 3 entrees clavier pinMode ( A0 , INPUT ) ; // les entrees bouton b0 2 seuls utilisés pinMode ( A1 , INPUT ) ; readBouton () ; lastBouton = bouton ; // init lastBouton compteurBoucle = 0 ; clignotant = 0 ; // pour actionner l'extinction afficheur digitalWrite ( 13 , LOW ) ; // sort 0 digitalWrite ( 8 , LOW ) ; // les LED éteintes digitalWrite ( 11 , LOW ) ; digitalWrite ( 9 , LOW ) ; // 1 // les relais à zéro digitalWrite ( 2 , LOW ) ; // 2 digitalWrite ( 3 , LOW ) ; // 3 digitalWrite ( 4 , LOW ) ; // 4 initialisationDesManuelsAuSetup () ; // 62 transfert de RAM sauvegardée vers manuels au boot eteintRouge () ; // exticntion tous les voyants eteintBleu () ; eteintJaune () ; DateTime now = rtc.now () ; // Lecture RTC Minute = now.minute () ; // et prêt à lemploi pour la valeur actuelle afficheLesManuels () ; // éventuellement pour la première minute "aveugle" minuteAncienne = Minute ; // initialisation préalable newYear = 2021 ; newMonth = 10 ; newDay = 21 ; newHour = 12 ; newMinut = 0 ; newSecond = 0 ; valeurVariable = 1 ; // année } // ===================== entrée en loop ====================== // ====================================================== void loop () { DateTime now = rtc.now () ; // Lecture RTC Heure = now.hour () ; // A laisser dans la boucle pour être rafraîchi Minute = now.minute () ; // et prêt à lemploi pour la valeur actuelle. La nouvelle Jour = now.dayOfTheWeek () ; // organisation modifie les valeurs pour d'autres affichages minuteDeSemaine = ( Jour * 1440 + Heure * 60 + Minute ) ; debugClavier () ; // lecture du clavier dans cette boucle loop readBouton () ; // lecture du bouton et mise à jour if ( bouton != 3 ) // initialiser zone de contrôle { maDateHeure.Jour = 0 ; maDateHeure.Heure = 0 ; maDateHeure.Minute = 0 ; } // =================== Choix des actions du BOUTON ================== if ( bouton == 0 ) boutonEgaleZero () ; // position normale if ( bouton == 1 ) boutonEgaleUn () ; // Position commandes manuelles if ( bouton == 2 ) boutonEgaleDeux () ; // PROGRAMMATION des séquences de chaque voie vers la mémoire if ( bouton == 3 ) boutonEgaleTrois () ; // vérification/lecture des programmes enregistrés ajoutDeBoucle () ; // 54 Ajout dans le loop sans trop décaler les listings } // ===================== Fin du programme principal ============== // ==================================================================== // ======================== Les fonctions et procédures ================== void displayLigneUneNormale () // 01 Affichage NORMAL et identifications des lignes { lcd.setCursor ( 0 , 0 ) ; // ligne 1 // 31 dec 2021 déplacemnt des secondes affichage lcd.print ( "NORMAL" ) ; // texte complet 20 caractères lcd.setCursor ( 12 , 0 ) ; // ligne 1 lcd.print ( "C S B N " ) ; // texte complet 20 caractères } // =========================== void displayDateHeure ( ) // 02 affiche DAY XXHYY à la ligne reçue { lcd.setCursor ( posCurseurColonneProg , posCurseurLigneProg ) ; // la nouvelle organisation if ( Jour == 0 ) lcd.print ( "DIM" ) ; if ( Jour == 1 ) lcd.print ( "LUN" ) ; // va utiliser le routine if ( Jour == 2 ) lcd.print ( "MAR" ) ; // plusieurs fois, avec des arguments différents if ( Jour == 3 ) lcd.print ( "MER" ) ; // et des positions différentes if ( Jour == 4 ) lcd.print ( "JEU" ) ; if ( Jour == 5 ) lcd.print ( "VEN" ) ; if ( Jour == 6 ) lcd.print ( "SAM" ) ; if ( Jour >= 7 ) lcd.print ( "ERR" ) ; // OK ou erreur // L'heure lcd.print ( " " ) ; // espace séparateur if ( Heure <= 9 ) lcd.print ( "0" ) ; // ajoute le zéro avant lcd.print ( Heure , DEC ) ; // HeureDebutExtinction = Heure ; // test pour conservation lcd.print ( "H" ) ; // sep heures if ( Minute <= 9 ) lcd.print ( "0" ) ; lcd.print ( Minute , DEC ) ; lcd.print ( " " ) ; // ajouté deux blanc après } // ========================================== // cycle normal qui reçoit minuteDeSemaine et arrive en bouton 0 void cycleNormal () // 03 reste coincé tant que manuel non validé { displayLigneUneNormale () ; } // ======================================= void cycleControle () // 04 lecture du programme { lcd.setCursor ( 0, 0 ) ; // ligne 1 lcd.print ( " CONTROLE PROGRAMME " ) ; // sep heures le texte complet 19 caractères } // ================================= void displayLigneUneManuel () // 05 commande manuelle { lcd.setCursor ( 0, 0 ) ; // ligne 1 lcd.print ( "MANUEL " ) ; // sep heuresle texte complet 19 caractères } // =================================== void displayLigneUneProgrammation () // 06 commande manuelle { lcd.setCursor ( 0, 0 ) ; // ligne 1 lcd.print ( "PROGRAMMATION " ) ; // le texte complet 19 caractères enlevé des car pour placer témoins } // ====================================================== void refreshRelais ( ) // 07 int dateHeureEnMinutes ) { // motRelais supposé mis à jour gestionDesManuels () ; // c'est la fonction qui décrémente les manuels cpt = motRelais & 1 ; // test relais 1 if ( cpt == 1 ) digitalWrite ( 9 , HIGH ) ; else digitalWrite ( 9 , LOW ) ; // refresh cuisine cpt = motRelais & 2 ; // test relais 2 if ( cpt == 2 ) digitalWrite ( 2 , HIGH ) ; else digitalWrite ( 2 , LOW ) ; // refresh SB cpt = motRelais & 4 ; // test relais 3 if ( cpt == 4 ) digitalWrite ( 3 , HIGH ) ; else digitalWrite ( 3 , LOW ) ; // refresh Balneo cpt = motRelais & 8 ; // test relais 4 if ( cpt == 8 ) digitalWrite ( 4 , HIGH ) ; else digitalWrite ( 4 , LOW ) ; // refresh Christmas } // =================== effacements de lignes visu ==== void clearLigneZero ( ) // 08 effacement ligne 0 lcd { lcd.setCursor ( 0 , 0 ) ; effaceVingtCaracteres () ; // efface 20 caracteres depuis le curseur (ligne entière) } // ==================================== void clearLigneUn ( ) // 09 { lcd.setCursor ( 0 , 1 ) ; effaceVingtCaracteres () ; // efface 20 caracteres depuis le curseur (ligne entière) } // ==================================== void clearLigneDeux ( ) // 10 { lcd.setCursor ( 0 , 2 ) ; effaceVingtCaracteres () ; // efface 20 caracteres depuis le curseur (ligne entière) } // ======================================== void clearLigneTrois ( ) // 11 { lcd.setCursor ( 0 , 3 ) ; // Début ligne 4 effaceVingtCaracteres () ; } // =================================== void effaceVingtCaracteres () // 12 efface 20 caracteres depuis le curseur (ligne entière) { lcd.print ( " " ) ; // 20 espaces } // =================================== // affichage choix manuel en ligne 1 void afficheChoixVoieManuelle () // 13 { if ( choixManuel == 1 ) { lcd.setCursor ( 0 , 1 ) ; // ligne 2 centré lcd.print ( "MANUEL SALLE BAIN WC" ) ; // 20 caractères } if ( choixManuel == 0 ) { lcd.setCursor ( 0 , 1 ) ; // ligne 2 centré lcd.print ( " MANUEL CUISINE " ) ; // 20 caractères } if ( choixManuel == 2 ) { lcd.setCursor ( 0 , 1 ) ; // ligne 2 centré lcd.print ( " MANUEL BALNEO " ) ; // 20 caractères } if ( choixManuel == 3 ) { lcd.setCursor ( 0 , 1 ) ; // ligne 2 centré lcd.print ( " MANUEL CHRISTMAS " ) ; // 20 caractères } } // ========================================= void affichageDureeManuelle () // 14 affichage de la durée manuelle en programmation { lcd.setCursor ( 6 , 3 ) ; // ligne ligne 3 après DUREE: lcd.print ( dureeManuelle , DEC ) ; if (KB == 3 ) { dureeManuelle ++ ; if ( dureeManuelle >= 500 ) dureeManuelle = 500 ; // limitation delay ( 20 ) ; } if ( KB == 4 ) { dureeManuelle -- ; if ( dureeManuelle <= 1 ) dureeManuelle = 0 ; // limitation delay ( 20 ) ; } // Modification de la voie concernée variable par gauche/droite (5 ou 2) if ( KB == 5 ) // gauche { choixManuel -- ; if ( choixManuel <= 0 ) choixManuel = 0 ; // limitation afficheChoixVoieManuelle () ; delay ( 1000 ) ; } if ( KB == 2 ) // droite { choixManuel ++ ; if ( choixManuel >= 4 ) choixManuel = 3 ; // limitation afficheChoixVoieManuelle () ; delay ( 1000 ) ; } // Stockage if ( KB == 1 ) // ordre de stockage et fin { if ( choixManuel == 0 ) manuelCuisine = dureeManuelle ; // transfert au destinataire if ( choixManuel == 1 ) manuelSbWc = dureeManuelle ; // transfert au destinataire if ( choixManuel == 2 ) manuelBalneo = dureeManuelle ; // transfert au destinataire if ( choixManuel == 3 ) manuelChristmas = dureeManuelle ; // transfert au destinataire } } // ================================ void readClavier () // 15 lecture du clavier pour appels ponctuels { clavier = 0 ; // init avant lecture clavier = digitalRead ( 5 ); // lecture bit 0 if ( clavier == 1 ) KB = 1 ; else KB = 0 ; // LSb recopié clavier = digitalRead ( 6 ) ; // lecture bit 1 if ( clavier == 1 ) KB += 2 ; // mise à jour de KB clavier = digitalRead ( 7 ) ; // lecture bit 2 if ( clavier == 1 ) KB += 4 ; // mise à jour de KB } // ================================= void displayDestinataire () // 16 le destinataire est en destinataireProgrammation { lcd.setCursor ( 0 , 1 ) ; // position d'affichage if ( destinataireProgrammation == 0 ) lcd.print ( " CUISINE " ) ; if ( destinataireProgrammation == 1 ) lcd.print ( " SALLE DE BAIN WC " ) ; if ( destinataireProgrammation == 2 ) lcd.print ( " BALNEO " ) ; if ( destinataireProgrammation == 3 ) lcd.print ( " GUIRLANDES NOEL " ) ; } // ================================ void preparationProgrammation () // 17 { readBouton () ; // pour sortir si nécessaire if ( bouton != 2 ) return ; //goto sortie ; lcd.setCursor ( 0 , 2) ; lcd.print ( "ALL:" ); lcd.setCursor ( 0 , 3) ; lcd.print ( "EXT:" ); Jour = 0 ; Heure = 12 ; Minute = 0 ; // initialisations pour la programmation posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; displayDateHeure () ; // affiche pour allumage posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; // affiche pour extinction posCurseurLigneProg = 1 ; // ligne -> 1 c'est c'est la voie (cuisine ...) boucleDestination = 1 ; // programmation de destination boucleAllumage = 0 ; // pas encore en dateHeure boucleExtinction = 0 ; // pas encore dateHeure displayLigneUneProgrammation () ; // essai displayDestinataire () ; // essai curseurClignoteProg () ; // positionne le curseur et le fait clignoter } // ====================================== void curseurClignoteProg () // 18 pour voir, en programmation, qui est modifié { lcd.setCursor ( posCurseurColonneProg , posCurseurLigneProg ) ; // c'est la position lcd.blink () ; // le curseur clignote } // ==================================== void afficheProgrammation () /// 19 refraîchit la programmation suite à une modification { lcd.setCursor ( 0 , 1 ) ; // curseur ligne 2 col 1 displayDestinataire () ; // valeur chahgeante posCurseurLigneProg = 1 ; posCurseurColonneProg = 0 ; curseurClignoteProg () ; // positionne le curseur et clignote } // ==================================================== void afficheAllumage () // 20 affiche DateHeure à une position demandée { posCurseurColonneProg = 4 ; // colonne 5 posCurseurLigneProg = 2 ; // ligne 3 displayDateHeure () ; curseurClignoteProg () ; // } // ================================================================ void boucleProgrammationDestinataire () // 21 ne sortira que pour programmer allumage { afficheProgrammation () ; posCurseurLigneProg = 1 ; // prog dest boucleDestination = 1; boucleAllumage = 0 ; boucleExtinction = 0 ; while ( KB != 1 ) // normalement, seul le 1 est supposé provoquer la validation et enregistrement { readBouton () ; // pour sortie éventuelle if ( bouton != 2 ) return ; debugClavier () ; if ( KB == 3 ) // UP change de destinataire seulement et tourne en boucle (modifié 19/04/2021) { destinataireProgrammation ++ ; // change de destinataire if ( destinataireProgrammation == 4 ) destinataireProgrammation = 3 ; // limitation if ( destinataireProgrammation == 4 ) destinataireProgrammation = 0 ; // ne pas sortir des clous afficheProgrammation () ; } if ( KB == 4 ) // DOWN change de destinataire { destinataireProgrammation -- ; // change de destinataire if ( destinataireProgrammation > 3 ) destinataireProgrammation = 0 ; // limitation afficheProgrammation () ; } delay ( 200 ) ; // delai symbolique pour ne pas aller trop vite } lcd.setCursor ( 0 , 0 ) ; lcd.print ( "DESTIN CONNU:" ) ; afficheDestinAbrege () ; // txt et pas nb lcd.setCursor ( 19 , 0 ) ; lcd.print ( bitRelais , HEX ) ; // doit être 1, 2, 4 ou 8 } // ======================================================================= void boucleProgrammationAllumage () // 22 pour programmer allumage { boucleDestination = 0 ; // fin de la destination boucleAllumage = 1 ; boucleExtinction = 0 ; boucleHeureProg = 0 ; boucleMinuteProg = 0 ; // jour seul posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all debugClavier () ; // ce read clavier est NECESSAIRE sinon skip delay ( 100 ) ; programmationJourAllumage () ; // programmation jour allumage programmationHeureAllumage () ; // programmation heure allumage programmationMinuteAllumage () ; // programmation heure allumage lcd.setCursor ( 0 , 0 ) ; lcd.print ( "ALLUMAGE: " ) ; lcd.print ( minuteDebutAllumage , DEC ) ; lcd.print ( "mn" ) ; // pour vérification } // =============================================== void boucleProgrammationExtinction () // 23 à présent, enregistrer { boucleDestination = 0 ; // fin de la destination boucleAllumage = 0 ; boucleExtinction = 1 ; boucleHeureProg = 0 ; boucleMinuteProg = 0 ; // jour seul posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all debugClavier () ; // ce read clavier est NECESSAIRE sinon skip delay ( 100 ) ; programmationJourExtinction () ; // programmation jour allumage programmationHeureExtinction () ; // programmation heure allumage programmationMinuteExtinction () ; // programmation heure allumage debugClavier () ; if ( KB == 1 ) // enregistrement { Serial.println ( "Je vais enregistrer" ) ; // minuteFinAllumage = 60 ; // une heure nombreDeMinAProgrammer = ( minuteFinAllumage - minuteDebutAllumage ) ; // nombre de mn allumé memoryAddress = minuteDebutAllumage ; Serial.print ( "Depuis: " ) ; Serial.print ( minuteDebutAllumage , DEC ) ; Serial.print ( " Durée: " ) ; Serial.println ( nombreDeMinAProgrammer , DEC ) ; programmeAEnregistrer = 1 ; // indique qu'il faut enregistrer } } // ============================================= void programmationJourAllumage () // 24 boucle programmation réservée { delay ( 500 ) ; KB = 0 ; while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { debugClavier () ; if ( ( KB == 3 ) && ( boucleAllumage == 1 ) && ( boucleHeureProg == 0 ) && ( boucleMinuteProg == 0 ) ) // montée pour les jours { Jour ++ ; if ( Jour == 7 ) Jour = 6 ; // limitation displayDateHeure () ; // affiche la nouvelle valeur posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all delay ( 200 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } if ( ( KB == 4 ) && ( boucleAllumage == 1 ) && ( boucleHeureProg == 0 ) && ( boucleMinuteProg == 0 ) ) // descente { Jour -- ; if ( Jour > 6 ) Jour = 0 ; // limitation displayDateHeure () ; // affiche la nouvelle valeur posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all delay ( 200 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } } // je dois passer en heures allumage boucleHeureProg = 1 ; } // ============================================= void programmationHeureAllumage () // 25 boucle programmation réservée { delay ( 500 ) ; // allongé le délai // verification du bit de voie creationBitRelais () ; // 47 remplissage de la mémoire bitRelais de la valeur destinataire lcd.setCursor ( 19 , 0 ) ; lcd.print ( bitRelais , HEX ) ; // doit être 1, 2, 4 ou 8 KB = 0 ; // essai pour purger KB while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { posCurseurLigneProg = 2 ; posCurseurColonneProg = 8 ; curseurClignoteProg () ; // heure all debugClavier () ; if ( KB == 3 ) // comme en dessous, une seule condition { Heure ++ ; if ( Heure == 24 ) Heure = 23 ; // limitation posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 150 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; // est-il pertinant de lire le clavier qui valide une valeur? } if ( KB == 4 ) // down { Heure -- ; if ( Heure > 23 ) Heure = 0 ; // limitation posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 150 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; // est-il pertinant de lire le clavier qui valide une valeur? // HeureDebutExtinction = Heure ; // save heure } } // passer en minutes boucleHeureProg = 0 ; boucleMinuteProg = 1 ; } // ===================================== void programmationMinuteAllumage () // 26 boucle programmation réservée { delay ( 500 ) ; KB = 0 ; while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { posCurseurLigneProg = 2 ; posCurseurColonneProg = 11 ; curseurClignoteProg () ; // minute all debugClavier () ; if ( KB == 3 ) { Minute ++ ; if ( Minute == 60 ) Minute = 59 ; // limitation posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 100 ) ; debugClavier () ; } if ( KB == 4 ) // down { Minute -- ; if ( Minute > 59 ) Minute = 0 ; // limitation posCurseurLigneProg = 2 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 100 ) ; debugClavier () ; } } // passer en extinction minuteDebutAllumage = ( Jour * 1440 + Heure * 60 + Minute ) ; // à utiliser pour stockage boucleAllumage = 0 ; // préparation à la boucle d'extinction boucleHeureProg = 0 ; boucleMinuteProg = 0 ; boucleExtinction = 1 ; } // ============================================= void programmationJourExtinction () // 27 boucle programmation réservée { displayDateHeure () ; // affiche la nouvelle valeur posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all delay ( 500 ) ; KB = 0 ; // il est probable que le 1 soit resté des minutes allumage while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { debugClavier () ; if ( KB == 3 ) // montée pour les jours { if ( ( boucleExtinction == 1 ) && ( boucleHeureProg == 0 ) && ( boucleMinuteProg == 0 ) ) { Jour ++ ; if ( Jour == 7 ) Jour = 6 ; // limitation displayDateHeure () ; // affiche la nouvelle valeur posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all delay ( 200 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } } if ( KB == 4 ) // down jours { if ( ( boucleExtinction == 1 ) && ( boucleHeureProg == 0 ) && ( boucleMinuteProg == 0 ) ) { Jour -- ; if ( Jour > 6 ) Jour = 0 ; // limitation displayDateHeure () ; // affiche la nouvelle valeur posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; curseurClignoteProg () ; // jour all delay ( 200 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } } } // je dois passer en heures allumage } // ============================================= void programmationHeureExtinction () // 28 boucle programmation réservée { delay ( 500 ) ; KB = 0 ; // essai pour purger KB while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { posCurseurLigneProg = 3 ; posCurseurColonneProg = 8 ; curseurClignoteProg () ; // heure all debugClavier () ; if ( KB == 3 ) // montée pour heures { Heure ++ ; if ( Heure == 24 ) Heure = 23 ; // limitation posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 150 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } if ( KB == 4 ) // down pour heures { Heure -- ; if ( Heure > 23 ) Heure = 0 ; // limitation posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 150 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } } // passer en minutes } // ===================================== void programmationMinuteExtinction () // 29 boucle programmation réservée { Minute = 0 ; // test initialisation pas ici posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 500 ) ; KB = 0 ; while ( KB != 1 ) // pareil, on sort par validation pour aller à l'extinction { posCurseurLigneProg = 3 ; posCurseurColonneProg = 11 ; curseurClignoteProg () ; // minute all debugClavier () ; if ( KB == 3 ) // montée pour les minutes { Minute ++ ; if ( Minute == 60 ) Minute = 59 ; // limitation posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 100 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } if ( KB == 4 ) // down minutes { Minute -- ; if ( Minute > 59 ) Minute = 0 ; // limitation posCurseurLigneProg = 3 ; posCurseurColonneProg = 4 ; displayDateHeure () ; delay ( 100 ) ; // provisoire long pour blocage devrait être LUN (DIM + 1) debugClavier () ; } } minuteFinAllumage = ( Jour * 1440 + Heure * 60 + Minute ) ; // à utiliser pour stockage } // ============================================= void readBouton () // 30 lecture du bouton { lectBouton = digitalRead ( A0 ); // lecture bit 0 if ( lectBouton == 1 ) bouton = 1 ; else bouton = 0 ; // recopie lectBouton = digitalRead ( A1 ) ; // lecture bit 1 if ( lectBouton == 1 ) bouton += 2 ; // mise à jour de bouton } // =========================================================== void debugClavier () // 31 Débogage clavier { char valeurLue = 0 ; // première valeur relevée à comparer avec une autre repriseClavier: // si valeur non confirmée readClavier () ; if ( KB != 0 ) { compteurBoucle = 0 ; // pour rallumage si action clavier valeurLue = KB ; delay ( 15 ) ; readClavier () ; if ( KB != valeurLue ) goto repriseClavier ; } } // ===================================================== void incrementDateHeure () // 33 incrémentation de la structure si besoin est { maDateHeure.Minute ++ ; if ( maDateHeure.Minute == 60 ) { maDateHeure.Minute = 0 ; maDateHeure.Heure ++ ; } if ( maDateHeure.Heure == 24 ) { maDateHeure.Heure = 0 ; maDateHeure.Jour ++ ; } if ( maDateHeure.Jour == 7 ) maDateHeure.Jour = 0 ; } // les membres de la structure sont lisibles // ====================================================== // gestion des voyants de test rouge bleu jaune // ==================== Allumage/extinction LED =============== void allumeRouge () // 35 { digitalWrite ( 11 , HIGH ) ; // allume ROUGE } // ========================================= void eteintRouge () //36 { digitalWrite ( 11 , LOW ) ; // éteint ROUGE } // ======================================== void allumeBleu () //37 { digitalWrite ( 8 , HIGH ) ; // allume BLEU } // ========================================= void eteintBleu () //38 { digitalWrite ( 8 , LOW ) ; // éteint BLEU } // ======================================== void allumeJaune () //39 { digitalWrite ( 12 , HIGH ) ; // allume JAUNE } // ========================================= void eteintJaune () // 40 { digitalWrite ( 12 , LOW ) ; // éteint JAUNE } // ======================================== void afficheDestinAbrege () // 41 txt et pas nb { if ( destinataireProgrammation == 0 ) lcd.print ( "CUIS" ) ; if ( destinataireProgrammation == 1 ) lcd.print ( "SBWC" ) ; if ( destinataireProgrammation == 2 ) lcd.print ( "BALN" ) ; if ( destinataireProgrammation == 3 ) lcd.print ( "NOEL" ) ; } // ============================================ void decodageJHM () // 44 décode minuteDebutAllumage en Jour Heure et Minute { Serial.print ( "JHM -> " ) ; // Test conversions écritures Jour = minuteDebutAllumage / 1440 ; // entier jour Serial.print ( "J" ) ; Serial.print ( Jour , DEC ) ; Serial.print ( " " ) ;// Jour et séparateur Heure = Minute / 60 ; // entier heure Serial.print ( " H -> " ) ; Serial.print ( Heure , DEC ) ; Serial.print ( ":" ) ; // Heure Minute = minuteDebutAllumage - ( Jour * 1440 ) ; // temporaire. Minute sera définitif à la fin Serial.print ( Minute , DEC ) ; Serial.print ( "\t" ) ; // séparation Serial.print ( "mnDAll=" ) ; Serial.println ( minuteDebutAllumage , DEC ) ; } // ========================================== 22 avril 2021 ====== void clearEcran () // 45 nettoyage complet d'ecran { clearLigneZero () ; clearLigneUn () ; clearLigneDeux () ; clearLigneTrois () ; } // ================================================================ void creationBitRelais () // 47 remplissage de la mémoire bitRelais de la valeur destinataire { if ( destinataireProgrammation == 0 ) bitRelais = 1 ; // cuisine if ( destinataireProgrammation == 1 ) bitRelais = 2 ; // SB WC if ( destinataireProgrammation == 2 ) bitRelais = 4 ; // Balnéo if ( destinataireProgrammation == 3 ) bitRelais = 8 ; // Noël } // ================================================================= void gestionDesManuels () // 53 refresh des manuels par l'horloge puisque nouvelle minute { if ( lastMinuteTraitee == minuteDeSemaine ) return ; // affichage déjà fait pour cette minute if ( ( manuelCuisine + manuelSbWc + manuelBalneo + manuelChristmas ) == 0 ) return ; // aucun manuel // manuel cuisine ? if ( manuelCuisine >= 1 ) { manuelCuisine -- ; sortieRelais |= 1 ; // commande la cuisine } if ( manuelCuisine == 1 ) manuelCuisine = 0 ; if ( manuelCuisine == 0 ) sortieRelais &= 0x0E ; // arrêt cuisine // manuel SB WC ? if ( manuelSbWc >= 1 ) { manuelSbWc -- ; sortieRelais |= 2 ; // commande la SB } if ( manuelSbWc == 1 ) manuelSbWc = 0 ; if ( manuelSbWc == 0 ) sortieRelais &= 0x0D ; // arrêt SB // manuel Balnéo ? if ( manuelBalneo >= 1 ) { manuelBalneo -- ; sortieRelais |= 4 ; // commande la balneo } if ( manuelBalneo == 1 ) manuelBalneo = 0 ; if ( manuelBalneo == 0 ) sortieRelais &= 0x0B ; // arrêt balneo // manuel Guirlandes ? if ( manuelChristmas >= 1 ) { manuelChristmas -- ; sortieRelais |= 8 ; // commande la guirlandes } if ( manuelChristmas == 1 ) manuelChristmas = 0 ; if ( manuelChristmas == 0 ) sortieRelais &= 0x07 ; // arrêt guirlandes // afficheLesManuels () ; // pour ne pas répéter lastMinuteTraitee = minuteDeSemaine ; // puisque durées manuelles gérées ici } // ============================================== void ajoutDeBoucle () // 54 Ajout sans trop décaler les listings 28 mai 23021 { nettoyageEtoilesRelais () ; // pour supprimer les parasites du manuel detectionRotationBouton () ; // 61 détection de rotation de bouton copieValeursManuellesEnNvram () ; // 61 mémorisation des manuels en RAM 1307 // comptage boucle en vue de l'extinction LCD compteurBoucle ++ ; // pour actionner l'extinction afficheur if ( compteurBoucle > 3000 ) lcd.noBacklight () ; // extinction afficheur else lcd.backlight () ; testNouvelleMinute () ; // test de nouvelle minute arrivée } // ================================================== void nettoyageEtoilesRelais () // 56 pour supprimer les parasites du manuel { // à n'autoriser qu'en mode zéro readBouton () ; if ( bouton != 0 ) return ; lcd.setCursor ( 11 , 1 ) ; lcd.print ( " " ) ; // 1 espaces lcd.setCursor ( 13 , 1 ) ; lcd.print ( " " ) ; // 1 espace lcd.setCursor ( 15 , 1 ) ; lcd.print ( " " ) ; // 1 espace lcd.setCursor ( 17 , 1 ) ; lcd.print ( " " ) ; // 1 espace lcd.setCursor ( 19 , 1 ) ; lcd.print ( " " ) ; // 1 espace } // ========================================================= // =================== Choix des actions du BOUTON ====================== void boutonEgaleZero () // 57 fonction zéro normal { creationMotManuel () ; // création du mot à mixer avec motProgramme pour display * refreshDisplayDone = 0 ; // mémoire de refresh visu unique displayLigneUneNormale () ; posCurseurLigneProg = 1 ; // ligne 2 posCurseurColonneProg = 0 ; // début de ligne displayDateHeure () ; afficheLesManuels () ; dureeManuelle = 0 ; // initialisation de la durée manuelle // pour mise à l'heure if ( KB == 7 ) { miseALHeure () ; // boucle indépendante qui s'achève par mise à l'heure } } // ============================================= void boutonEgaleUn () // 58 fonction 1 manuel { if ( refreshDisplayDone == 0 ) // premier affichage donc nettoyage des inutiles { clearLigneUn ( ) ; displayLigneUneManuel () ; // commande manuelle refreshDisplayDone = 1 ; // mémoire de refresh visu unique clearLigneDeux () ; clearLigneTrois () ; // effacement lignes inutiles } afficheChoixVoieManuelle () ; lcd.setCursor (0, 3 ) ; lcd.print ( "DUREE:" ) ; // affichage d'essai ne devra pas persister lcd.blink () ; // curseur affichageDureeManuelle () ; } // ============================================================= void boutonEgaleDeux () // 59 fonction 2 programmation { clearEcran () ; readBouton () ; if ( bouton != 2 ) goto sortie ; // pour sortir preparationProgrammation () ; refreshDisplayDone = 0 ; boucleProgrammationDestinataire () ; // ne sortira que programmer allulmage readBouton () ; if ( bouton != 2 ) goto sortie ; // pour sortir boucleProgrammationAllumage () ; // pour programmer allumage readBouton () ; if ( bouton != 2 ) goto sortie ; // pour sortir boucleProgrammationExtinction () ; // pour programmer extinction if ( programmeAEnregistrer != 0 ) stockageAllumageExtinction () ; // enregistrer sortie: readBouton () ; } // ================================================ void boutonEgaleTrois () /// 60 fonction 3 contrôles 28/12/2021 nouvelles fonctions eeprom { positionTroisVerificationsEeprom () ; // les vérifications eeprom } // ========================================================= void detectionRotationBouton () // 61 détection de rotation de bouton { readBouton () ; // lecture état actuel à comparer avec lastBouton if ( bouton != lastBouton ) // différence avec le passé { delay ( 100 ) ; lastBouton = bouton ; // acquittement lastMinuteTraitee -- ; // pour forcer refresh minuteDeSemaine if ( bouton == 0 ) boutonEgaleZero () ; if ( bouton == 1 ) boutonEgaleUn () ; } } // ============================================================ void copieValeursManuellesEnNvram () // 61 { octetAEcrire = manuelCuisine / 256 ; // MSB cuisine rtc.writenvram ( 4 , octetAEcrire ) ; octetLu = octetAEcrire ; // pour calculer le LSB octetAEcrire = ( manuelCuisine - octetLu * 256 ) ; // LSB à écrire rtc.writenvram ( 5 , octetAEcrire ) ; // à répéter trois fois pour les autrtes voies octetAEcrire = manuelSbWc / 256 ; // MSB SbWc rtc.writenvram ( 6 , octetAEcrire ) ; octetLu = octetAEcrire ; // pour calculer le LSB octetAEcrire = ( manuelSbWc - octetLu * 256 ) ; // LSB à écrire rtc.writenvram ( 7 , octetAEcrire ) ; octetAEcrire = manuelBalneo / 256 ; // MSB balnéo rtc.writenvram ( 8 , octetAEcrire ) ; octetLu = octetAEcrire ; // pour calculer le LSB octetAEcrire = ( manuelBalneo - octetLu * 256 ) ; // LSB à écrire rtc.writenvram ( 9 , octetAEcrire ) ; octetAEcrire = manuelChristmas / 256 ; // MSB guirlandes rtc.writenvram ( 10 , octetAEcrire ) ; octetLu = octetAEcrire ; // pour calculer le LSB octetAEcrire = ( manuelChristmas - octetLu * 256 ) ; // LSB à écrire rtc.writenvram ( 11 , octetAEcrire ) ; } // ===================================================================== void initialisationDesManuelsAuSetup () // 62 transfert de RAM sauvegardée vers manuels au boot { tempo = rtc.readnvram ( 0x04 ) * 256 ; // MSB cuisine octetLu = rtc.readnvram ( 0x05 ) ; manuelCuisine = tempo + octetLu ; // cuisine rafraîchie tempo = rtc.readnvram ( 0x06 ) * 256 ; // MSB cuisine octetLu = rtc.readnvram ( 0x07 ) ; manuelSbWc = tempo + octetLu ; // SB rafraîchie tempo = rtc.readnvram ( 0x08 ) * 256 ; // MSB cuisine octetLu = rtc.readnvram ( 0x09 ) ; manuelBalneo = tempo + octetLu ; // balnéo rafraîchie tempo = rtc.readnvram ( 0x0A ) * 256 ; // MSB cuisine octetLu = rtc.readnvram ( 0x0B ) ; manuelChristmas = tempo + octetLu ; // guirlandes rafraîchies } // ==================================================== void testNouvelleMinute () // test de nouvelle minute arrivée { if ( minuteAncienne == Minute ) return ; // déjà traité afficheLesManuels () ; minuteAncienne = Minute ; // attente prochaine nouvelle minute } // ================ A ajouter pour mise à l'heure en renommant ====== void displayLigneUneMah () // message ligne 1 mise à l'heure { lcd.setCursor ( 0, 0 ) ; // ligne 1 lcd.print ( "REGLAGE RTC KB:" ) ; // sep heures le texte complet 19 caractères } // =================================== // ======= A ajouter à la version 31 =================== void afficheNewDateHeure () // affiche contenu de date à programmer en ligne 3 { lcd.setCursor ( 0 , 2 ) ; // année en 0 lcd.print ( newYear , DEC ) ; // année lcd.setCursor ( 5 , 2 ) ; // mois en 5 if ( newMonth < 10 ) lcd.print ( " " ) ; // pas dizaine lcd.print ( newMonth , DEC ) ; // mois lcd.setCursor ( 8 , 2 ) ; // jour if ( newDay < 10 ) lcd.print ( " " ) ; // pas dizaine lcd.print ( newDay , DEC ) ; // mois lcd.setCursor ( 11 , 2 ) ; // heure if ( newHour < 10 ) lcd.print ( " " ) ; // pas dizaine lcd.print ( newHour , DEC ) ; // mois lcd.setCursor ( 14 , 2 ) ; // minute if ( newMinut < 10 ) lcd.print ( " " ) ; // pas dizaine lcd.print ( newMinut , DEC ) ; // mois lcd.setCursor ( 17 , 2 ) ; // secondes if ( newSecond < 10 ) lcd.print ( " " ) ; // pas dizaine lcd.print ( newSecond , DEC ) ; // mois } // ================================== void gestionCurseur () // le curseur de la valeur réglée en cours { // commence par tous les éteindre lcd.setCursor ( 4 , 2 ) ; lcd.print ( " " ) ; lcd.setCursor ( 7 , 2 ) ; lcd.print ( " " ) ; lcd.setCursor ( 10 , 2 ) ; lcd.print ( " " ) ; lcd.setCursor ( 13 , 2 ) ; lcd.print ( " " ) ; lcd.setCursor ( 16 , 2 ) ; lcd.print ( " " ) ; lcd.setCursor ( 19 , 2 ) ; lcd.print ( " " ) ; // affiche < fonction de valeurVariable if ( valeurVariable == 1 ) { lcd.setCursor ( 4 , 2 ) ; lcd.print ( "<" ) ; } if ( valeurVariable == 2 ) { lcd.setCursor ( 7 , 2 ) ; lcd.print ( "<" ) ; } if ( valeurVariable == 3 ) { lcd.setCursor ( 10 , 2 ) ; lcd.print ( "<" ) ; } if ( valeurVariable == 4 ) { lcd.setCursor ( 13 , 2 ) ; lcd.print ( "<" ) ; } if ( valeurVariable == 5 ) { lcd.setCursor ( 16 , 2 ) ; lcd.print ( "<" ) ; } if ( valeurVariable == 6 ) { lcd.setCursor ( 19 , 2 ) ; lcd.print ( "<" ) ; } } // ================================================ void recordDateHeure () // enregistrement en RTC { // matérialisons par voyant rouge allumeRouge () ; delay ( 2000 ) ; rtc.adjust ( DateTime ( newYear , newMonth, newDay , newHour , newMinut , newSecond ) ) ; // chaîne de mise à l'heure eteintRouge () ; clearLigneDeux ( ) ; // 10 effacement de ligne 3 } // ================================================= void miseALHeure () // boucle indépendante qui s'achève par mise à l'heure // c'est cela que doit appeler le clavier si KB == 7 // on en sort mission accomplie par validation { while ( KB != 1 ) { displayLigneUneMah (); // message entête mise à l'heure readClavier () ; // KB contient valeur // affiche clavier lcd.setCursor ( 19 , 0 ) ; // fin ligne 1 lcd.print ( KB , DEC ) ; // valeur lue clavier readRTC () ; // lecture 1307 lcd.setCursor ( 7 , 1 ) ; // ligne 2 après annonce displayDateHeure ( ) ; // affiche date/heure afficheNewDateHeure () ; // affiche contenu de date à programmer en ligne 3 lcd.setCursor ( 0 , 2 ) ; // c'est la position curseur // modification année if ( KB == 3 && valeurVariable == 1 ) newYear ++ ; // test variable if ( KB == 4 && valeurVariable == 1 ) newYear -- ; if ( newYear > 2050 ) newYear = 2050 ; if ( newYear < 2000 ) newYear = 2000 ; // modification mois if ( KB == 3 && valeurVariable == 2 ) newMonth ++ ; // test variable if ( KB == 4 && valeurVariable == 2 ) newMonth -- ; if ( newMonth > 12 ) newMonth = 12 ; if ( newMonth < 1 ) newMonth = 1 ; // modification jour if ( KB == 3 && valeurVariable == 3 ) newDay ++ ; // test variable if ( KB == 4 && valeurVariable == 3 ) newDay -- ; if ( newDay > 31 ) newDay = 31 ; if ( newDay < 1 ) newDay = 1 ; // modification heure if ( KB == 3 && valeurVariable == 4 ) newHour ++ ; // test variable if ( KB == 4 && valeurVariable == 4 ) newHour -- ; if ( newHour > 23 ) newHour = 23 ; if ( newHour < 0 ) newHour = 0 ; // modification minute if ( KB == 3 && valeurVariable == 5 ) newMinut ++ ; // test variable if ( KB == 4 && valeurVariable == 5 ) newMinut -- ; if ( newMinut > 59 ) newMinut = 59 ; if ( newMinut < 0 ) newMinut = 0 ; // modification seconde if ( KB == 3 && valeurVariable == 6 ) newSecond ++ ; // test variable if ( KB == 4 && valeurVariable == 6 ) newSecond -- ; if ( newSecond > 59 ) newSecond = 59 ; if ( newSecond < 0 ) newSecond = 0 ; // modification curseur valeurVariable if ( KB == 2 ) { valeurVariable ++ ; // test variable delay ( 500 ) ; } if ( KB == 5 ) { valeurVariable -- ; delay ( 500 ) ; } if ( valeurVariable > 6 ) valeurVariable = 6 ; if ( valeurVariable < 1 ) valeurVariable = 1 ; gestionCurseur () ; // indique valeur en réglage if ( KB == 1 ) recordDateHeure () ; // enregistrement en RTC } } // ======================================== void readRTC () // Lecture RTC et refresh des mémoires d'affichage { DateTime now = rtc.now () ; // Lecture RTC Heure = now.hour () ; // A laisser dans la boucle pour être rafraîchi Minute = now.minute () ; // et prêt à lemploi pour la valeur actuelle. La nouvelle Jour = now.dayOfTheWeek () ; // organisation modifie les valeurs pour d'autres affichages } // =================================== // ==== 28 décembre 2021 modifications de position 3 pour gestion Eeprom /// ============================================ /// ============================================ void positionTroisVerificationsEeprom () // les vérifications eepro { int comptage ; clearEcran ( ) ; lcd.setCursor ( 0 , 0 ) ; lcd.print ( "1 DUMP TOTAL EEPROM" ) ; // ligne 2 /// ATTENTION fonction à ne mettre que pour Reset/Cleat EEPROM provisoirement // lcd.setCursor ( 0 , 1 ) ; lcd.print ( "2 CLEAR EEPROM" ) ; // Clear optionnel lcd.setCursor ( 0 , 1 ) ; lcd.print ( "3 BALAYAGE PROGRAMME" ) ; // Ligne 3 lcd.setCursor ( 0 , 2 ) ; lcd.print ( "4 RESET PAR JOUR" ) ; // Titre suppression/décalage debugClavier () ; delay ( 1000 ) ; // tempo pour relance if ( KB == 1 ) dumpAdresseZero () ; // "imprime" le contenu EEPROM if ( KB == 3 ) balayerLaSemaine () ; // balayage rapide (auto?) de la semaine if ( KB == 4 ) eraseUnJour () ; // efface un jour à définir clearEcran ( ) ; } // ===================================================== void balayerLaSemaine () // balayage rapide (auto?) de la semaine { clearEcran ( ) ; saveJour = Jour ; // sauvegardes saveHeure = Heure ; saveMinute = Minute ; // c'est une boucle qui simule en GV le déroulement semaine quickHorloge = 0 ; // on part d'ici: du début EEPROM while ( 1 ) // boucle dont on ne sortira que par touche 5 { toBeDoneQuickly () ; // ce qui est à faire dans la boucle rapide: vite Up, lentement Down Looop: // boucle attente de poursuite de balayage debugClavier () ; // pour sortir prématurément sur 5 if ( KB == 5 ) goto Sortie ; // sortie prématurée demandée if ( KB == 3 ) quickHorloge += 4 ; // augmente vite 2TAIT 8 MOD 4 DEC 2022 if ( quickHorloge > 10080 ) quickHorloge = 10080 ; // limitation if ( KB == 4 ) { quickHorloge -= 1 ; // diminue lentement if ( quickHorloge > 10080 ) quickHorloge = 0 ; // limitation delay ( 500 ) ; // pour ajuster fin } lcd.setCursor ( 0 , 3 ) ; lcd.print ( "Heure= " ) ; // Ligne 3 info lcd.setCursor ( 7 , 3 ) ; lcd.print ( quickHorloge , DEC ) ; // Ligne 3 info } Sortie: if ( KB == 5 ) avorte () ; // Il y a stop à affichaer Jour = saveJour ; // Rétablissement contexte Heure = saveHeure ; Minute = saveMinute ; } // =============================== void refreshMemoireRelaisQuick () // 55 transfère état relais de eeprom vers sortieRelais (mémoire) // et y ajoute les manuels s'il y a lieu { // lire minuteDeSemaine et adresser eeprom adressage = quickHorloge ; // octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture LIGNE 1249 // intro de l'offset newAddressR = adressage ; readEeprom () ; // lecture octet eeprom octetLu = byteLu ; // lecture passée octetLu &= 0x0F ; // ne conserve que les 4 bits du bas // mise en service de témoin temoin = octetLu & 1 ; // cuisine if ( temoin == 1 ) RlCuis = 1 ; else RlCuis = 0 ; // refresh RlCuis temoin = octetLu & 2 ; // SB if ( temoin == 2 ) RlSb = 1 ; else RlSb = 0 ; // refresh RlCuis temoin = octetLu & 4 ; // balneo if ( temoin == 4 ) RlBal = 1 ; else RlBal = 0 ; // refresh RlCuis temoin = octetLu & 8 ; // noel if ( temoin == 8 ) RlNoel = 1 ; else RlNoel = 0 ; // refresh RlCuis lcd.setCursor ( 12 , 1 ) ; if ( RlCuis == 1 ) lcd.print ( "*" ) ; else lcd.print ( " " ) ; lcd.setCursor ( 14 , 1 ) ; if ( RlSb == 1 ) lcd.print ( "*" ) ; else lcd.print ( " " ) ; lcd.setCursor ( 16 , 1 ) ; if ( RlBal == 1 ) lcd.print ( "*" ) ; else lcd.print ( " " ) ; lcd.setCursor ( 18 , 1 ) ; if ( RlNoel == 1 ) lcd.print ( "*" ) ; else lcd.print ( " " ) ; } // ======================================================== void avorte () // affiche message avortement du dump { lcd.setCursor ( 0 , 3 ) ; lcd.print ( "STOP MANUEL" ) ; // Ligne 3 delay ( 1000 ) ; } // ==================================== void creationMotManuel () // création es mots à mixer avec motProgramme pour display * { // int seconde ; DateTime now = rtc.now(); // refresh clock seconde = now.second () ; motManuels = 0 ; // init préalable if ( manuelCuisine != 0 ) motManuels += 1 ; if ( manuelSbWc != 0 ) motManuels += 2 ; if ( manuelBalneo != 0 ) motManuels += 4 ; if ( manuelChristmas != 0 ) motManuels += 8 ; // motManuel contient les manuels minuteDeSemaine = ( Jour * 1440 + Heure * 60 + Minute ) ; // refresh car n'est pas calculé! adressage = minuteDeSemaine ; // octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture LIGNE 1284 // intro de l'offset newAddressR = adressage ; readEeprom () ; // lecture octet eeprom octetLu = byteLu ; // lecture passée octetLu &= 0x0F ; // ne conserve que les 4 bits du bas sortieRelais = octetLu ; motProgramme = octetLu ; // motManuel, motProgramme connus mais encore indépendants motRelais = motProgramme | motManuels ; refreshRelais () ; // on sort le mot } // ======================================================== void afficheLesManuels () // 52 affiche en ligne 3 du LCD les 4 temps manuels et témoins relais { // ne doit se faire que si mode zéro 23 juin readBouton () ; if ( bouton != 0 ) return ; minuteDeSemaine = ( Jour * 1440 + Heure * 60 + Minute ) ; // refresh car n'est pas calculé! lcd.setCursor ( 0 , 3 ) ; lcd.print ( "C" ) ; // C de cuisine lcd.setCursor ( 5 , 3 ) ; lcd.print ( "W" ) ; // CW pour WC SB lcd.setCursor ( 10 , 3 ) ; lcd.print ( "B" ) ; // B de balneo lcd.setCursor ( 15 , 3 ) ; lcd.print ( "N" ) ; // N de Noël lcd.setCursor ( 1 , 3 ) ; lcd.print ( " " ) ; // nettoyage initial lcd.setCursor ( 1 , 3 ) ; lcd.print ( manuelCuisine , DEC ) ; // C de cuisine lcd.setCursor ( 6 , 3 ) ; lcd.print ( " " ) ; // nettoyage initial lcd.setCursor ( 6 , 3 ) ; lcd.print ( manuelSbWc , DEC ) ; // CW pour WC SB lcd.setCursor ( 11 , 3 ) ; lcd.print ( " " ) ; // nettoyage initial lcd.setCursor ( 11 , 3 ) ; lcd.print ( manuelBalneo , DEC ) ; // B de balneo lcd.setCursor ( 16 , 3 ) ; lcd.print ( " " ) ; // nettoyage initial lcd.setCursor ( 16 , 3 ) ; lcd.print ( manuelChristmas , DEC ) ; // N de Noël // Gestion des "voyants" de relais sur l'afficheur LCD à partir de sortieRelais //// ======= place un des quatre choix possibles tempoP = motProgramme & 0x0F ; tempoM = motManuels ; // les deux sont connus, afficher les 4 cas possibles tempo = tempoP | tempoM ; // global lcd.setCursor ( 12 , 1 ) ; // Cuisine et 01 tempoC = tempo & 1 ; // if ( tempoC == 0 ) lcd.print ( " " ) ; // blanc ou espace tempoPx = tempoP & 1 ; // isole programme cuisine tempoMx = tempoM & 1 ; // isole programme cuisine if ( tempoPx == 1 && tempoMx == 1 ) lcd.print ( ( char ) 256 ) ; // 4 barres horizontales if ( tempoPx == 1 && tempoMx == 0 ) lcd.print ( ( char ) 61 ) ; // = if ( tempoPx == 0 && tempoMx == 1 ) lcd.print ( ( char ) 95 ) ; // _ lcd.setCursor ( 14 , 1 ) ; // SB et 02 tempoS = tempo & 2 ; // if ( tempoS == 0 ) lcd.print ( " " ) ; tempoPx = tempoP & 2 ; // isole programme SB tempoMx = tempoM & 2 ; // isole programme SB if ( tempoPx == 2 && tempoMx == 2 ) lcd.print ( ( char ) 256 ) ; // 4 barres if ( tempoPx == 2 && tempoMx == 0 ) lcd.print ( ( char ) 61 ) ; // = if ( tempoPx == 0 && tempoMx == 2 ) lcd.print ( ( char ) 95 ) ; // _ lcd.setCursor ( 16 , 1 ) ; // Balnéo et 04 tempoB = tempo & 4 ; // if ( tempoB == 0 ) lcd.print ( " " ) ; tempoPx = tempoP & 4 ; // isole programme balnéo tempoMx = tempoM & 4 ; // isole programme balnéo if ( tempoPx == 4 && tempoMx == 4 ) lcd.print ( ( char ) 256 ) ; // 4 barres if ( tempoPx == 4 && tempoMx == 0 ) lcd.print ( ( char ) 61 ) ; // = if ( tempoPx == 0 && tempoMx == 4 ) lcd.print ( ( char ) 95 ) ; // _ lcd.setCursor ( 18 , 1 ) ; // Noel et 08 tempoN = tempo & 8 ; // if ( tempoN == 0 ) lcd.print ( " " ) ; tempoPx = tempoP & 8 ; // isole programme noel tempoMx = tempoM & 8 ; // isole programme noel if ( tempoPx == 8 && tempoMx == 8 ) lcd.print ( ( char ) 256 ) ; // 4 barres if ( tempoPx == 8 && tempoMx == 0 ) lcd.print ( ( char ) 61 ) ; // = if ( tempoPx == 0 && tempoMx == 8 ) lcd.print ( ( char ) 95 ) ; // _ if ( seconde >= 10 ) { lcd.setCursor ( 7 , 0 ) ; lcd.print ( seconde , DEC ) ; // 2 chiffres } else { lcd.setCursor ( 7 , 0 ) ; lcd.print ( "0" ) ; lcd.print ( seconde , DEC ) ; // seconde pour contrôle } // affichage de version lcd.setCursor ( 0 , 2 ) ; lcd.print ( " V44" ) ; // Version programme } // ============================================================================== void toBeDoneQuickly () // ce qui est à faire dans la boucle rapide: vite Up, lentement Down { Jour = quickHorloge / 1440 ; // entier du jour resteJour = quickHorloge % 1440 ; // heures + minutes dans le jour Heure = resteJour / 60 ; Minute = ( quickHorloge - ( Jour * 1440 ) - ( Heure * 60 ) ) ; // refreshDisplayDone = 0 ; // mémoire de refresh visu unique displayLigneUneNormale () ; posCurseurLigneProg = 1 ; // ligne 2 posCurseurColonneProg = 0 ; // début de ligne displayDateHeure () ; refreshMemoireRelaisQuick () ; // afficheLesManuels () ; // sortie des relais } // ======================================================== copie de version 35 === void dumpAdresseZero () // lit la totalité de l'EEPROM et imprime sur moniteur série { allumeBleu () ; // allumage témoin bleu sur kit clearLigneTrois ( ) ; // effacement initial lcd.setCursor ( 0 , 3 ) ; lcd.print ( " DUMP EN COURS " ) ; // Ligne 3 int HeureDump = 0 ; // heure d'affichage du dump // vérification au delà Serial.println ( "Vérification EEPROM depuis adresse zéro" ) ; Serial.println ( "Dimanche" ) ; // premier jour if ( HeureDump < 10 ) Serial.print ( "0" ) ; Serial.print ( HeureDump , DEC ) ; Serial.print ( " H " ) ; // heure première ligne for ( cpt = 1 ; cpt < 10080 ; cpt ++ ) // était 1, repasse à 1 mais lit en -1 { // octetLu = memoire.readByte ( cpt -1 ) ; // lecture (supprimé 4 offset?) LIGNE 1389 // intro de l'offset newAddressR = cpt - 1 ; readEeprom () ; // lecture octet eeprom octetLu = byteLu ; // lecture passée if ( octetLu == 0 ) { Serial.print ( "-- " ) ; goto suiteAff ; // c'est fini pour cet octet } if ( octetLu < 16 ) Serial.print ( " " ) ; Serial.print ( octetLu , HEX ) ; Serial.print ( " " ) ; suiteAff : if ( cpt % 10 == 0 ) Serial.print ( " " ) ; // séparateur if ( cpt % 60 == 0 ) { Serial.print ( "\n" ) ; HeureDump ++ ; // incrémentation if ( HeureDump < 24 ) // on n'affiche que des heures valides { if ( HeureDump < 10 ) Serial.print ( "0" ) ; Serial.print ( HeureDump , DEC ) ; Serial.print ( " H " ) ; // heure première ligne } if ( HeureDump == 24 ) HeureDump = 0 ; // init si 24 heures = zéro heure } if ( cpt % 1440 == 0 ) // nouvelle journée { if ( cpt / 1440 == 1 ) Serial.println ( "Lundi" ) ; // marque le jour if ( cpt / 1440 == 2 ) Serial.println ( "Mardi" ) ; // marque le jour if ( cpt / 1440 == 3 ) Serial.println ( "Mercredi" ) ; // marque le jour if ( cpt / 1440 == 4 ) Serial.println ( "Jeudi" ) ; // marque le jour if ( cpt / 1440 == 5 ) Serial.println ( "Vendredi" ) ; // marque le jour if ( cpt / 1440 == 6 ) Serial.println ( "Samedi" ) ; // marque le jour if ( HeureDump < 10 ) Serial.print ( "0" ) ; Serial.print ( HeureDump , DEC ) ; Serial.print ( " H " ) ; // heure première ligne } } Serial.print ( "\n" ) ; // saut de ligne séparatif en fin de liste eteintBleu () ; // extinction témoin clearLigneTrois ( ) ; // effacement final } // ======================================= void eraseUnJour () // efface un jour à définir { clearEcran ( ) ; adresseBase = 0 ; // lundi avec sauts de 1440 lcd.setCursor ( 0 , 0 ) ; lcd.print ( " CLEAR JOURNALIER " ) ; //Titre delay ( 100 ) ; // tempo pour relance while ( 1 ) // boucle dont on ne sortira que par touche 5 { debugClavier () ; // pour sortir prématurément sur 5 lcd.setCursor ( 0 , 1 ) ; lcd.print ( "EFFACER " ) ; // Clear optionnel afficheLeJour () ; // affiche le jour en Eeprom fonction de adresseBase if ( KB == 5 ) goto Sortie ; // sortie prématurée demandée if ( KB == 3 ) // incrémente jour { adresseBase += 1440 ; // pas des jours en Eeprom if ( adresseBase > 8640 ) adresseBase = 8640 ; // limitation delay ( 100 ) ; // tempo } if ( KB == 4 ) // décrémente jour { adresseBase -= 1440 ; // pas des jours en Eeprom if ( adresseBase < 0 ) adresseBase = 0 ; // limitation delay ( 100 ) ; // tempo } if ( KB == 1 ) /// validation { eraseLeJour () ; delay ( 1000 ) ; // pour ne pas répéter // avorte () ; goto Sortie ; } } Sortie: avorte () ; // Il y a stop à affichaer } // ============================ void afficheLeJour () // affiche le jour en Eeprom fonction de adresseBase { if ( adresseBase == 0 ) { lcd.print ( " DIMANCHE " ) ; } if ( adresseBase == 1440 ) { lcd.print ( " LUNDI " ) ; } if ( adresseBase == 2880 ) { lcd.print ( " MARDI " ) ; } if ( adresseBase == 4320 ) { lcd.print ( " MERCREDI " ) ; } if ( adresseBase == 5760 ) { lcd.print ( " JEUDI " ) ; } if ( adresseBase == 7200 ) { lcd.print ( " VENDREDI " ) ; } if ( adresseBase == 8640 ) { lcd.print ( " SAMEDI " ) ; } } //// ========================= void eraseLeJour () // efface le four en Eeprom choisi par adresseBase { int comptage = 0 ; //comptage des affichages // ajout de message moniteur série pour dépouillement Serial.println ( "================" ) ; // séparateur Serial.println ( "Clear d'un jour EEPROM " ) ; allumeRouge () ; // sur kit lcd.setCursor ( 0 , 1 ) ; lcd.print ( "EFFACE " ) ; // Ligne 3 delay ( 500 ) ; // pour avoir le temps d'observer for ( cpt = adresseBase ; cpt < ( adresseBase + 1440 ) ; cpt ++ ) { adressage = ( cpt ) ; // octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture LIGNE 1508 // intro de l'offset newAddressR = adressage ; readEeprom () ; // lecture octet eeprom octetLu = byteLu ; // lecture passée // N'écrire que si not égal à 0 if ( octetLu != 0 ) { // delay ( tempoRW ) ; // tempo if ( comptage % 50 == 0 ) Serial.println () ; // saut de ligne Serial.print ( "@" ) ; Serial.print ( adressage , DEC ) ; Serial.print ( "," ) ; // memoire.updateByte ( adressage , 0 ) ; // écriture LIGNE 1515 // intro de l'offset toBeWritten = 0 ; // clear newAddressW = adressage ; writeEeprom () ; // écriture faite comptage ++ ; } } Serial.println ( "\n=== Exécuté ===" ) ; // séparateur de fin eteintRouge () ; } // ================================ void stockageAllumageExtinction () // 32 place en mémoire le bit relais dans la zone EEPROM { // témoins lumineux allumeBleu () ; decodageJHM () ; // Jour Heure et Minute connus creationBitRelais () ; // remplissage de la mémoire bitRelais de la valeur destinataire for ( cpt = 1 ; cpt < nombreDeMinAProgrammer + 1 ; cpt ++ ) { adressage = ( minuteDebutAllumage + cpt - 1 ) ; // adressage pointe la mémoire à mettre à jour // octetLu = memoire.readByte ( adressage ) ; // lecture du contenu avant mise à jour LIGNE 1533 // intro de l'offset newAddressR = adressage ; readEeprom () ; // lecture octet eeprom // octetLu = byteLu ; // lecture passée mais faire double lecture // Serial.print ( "(lu: " ) ; Serial.print ( byteLu , DEC ) ; Serial.print ( " ) \t" ) ; // lecture passée // readEeprom () ; // lecture octet eeprom // octetLu = byteLu ; // lecture passée mais faire double lecture // Serial.print ( "(lu: " ) ; Serial.print ( byteLu , DEC ) ; Serial.print ( " ) \t" ) ; // lecture passée // readEeprom () ; // lecture octet eeprom // verification du bit de voie lcd.setCursor ( 19 , 0 ) ; lcd.print ( bitRelais , HEX ) ; // doit être 1, 2, 4 ou 8 // débogage // Serial.print ( "A ajouter:" ) ; Serial.print ( bitRelais , DEC ) ; // Serial.print ( "\t à: " ) ; Serial.print ( byteLu , DEC ) ; octetAEcrire = byteLu | bitRelais ; // memoire.updateByte ( adressage , octetAEcrire ) ; // écriture de la mise à jour LIGNE 1537 // intro de l'offset // Serial.print ( "\tsoit: " ) ; Serial.println ( octetAEcrire , DEC ) ; toBeWritten = octetAEcrire ; // écriture vraie newAddressW = adressage ; writeEeprom () ; // écriture faite // if ( cpt % 60 == 0 ) // { // tempoMilleJaune () ; // tempo sur record de moins de 50 minutes // Serial.println ( "boucle % 60" ) ; // confirmation // } } // fin de la boucle Serial.print ( "Nombre enregistrements = " ) ; Serial.print ( cpt - 1 , DEC ) ; // -1 compense le ++ effectué avant Serial.print ( " (" ) ; Serial.print ( nombreDeMinAProgrammer , DEC ) ; Serial.print ( ")" ) ; // confirmation Serial.print ( "\n" ) ; delay ( 1000 ) ; programmeAEnregistrer = 0 ; // acquittement eteintBleu () ; tempoMilleJaune () ; // tempo de 1000 et voyant jaune } // ========================================================== void tempoMilleJaune () // tempo de 1000 et voyant jaune { allumeJaune () ; delay ( 1000 ) ; eteintJaune () ; } // ======================================= /* /// 5 dec 2022 int adresseBase ; // lundi avec sauts de 1440 int offsetEeprom = 10000 ; // essai de décalage dans eeprom qui peut être de 0 uint8_t toBeWritten ; // octet devant être écrit uint8_t byteLu ; // octet lu uint16_t newAddressW ; // nouvelle adresse où écire en eeprom uint16_t newAddressR ; // nouvelle adresse où lire en eeprom // les fonctions qui vont lire et écrire un octet void writeEeprom () ; // écrit un octet là où ça pointe void readEeprom () ; // lit un octet memoire.updateByte ( adressage , 0 ) ; // écriture memoire.updateByte ( adressage , octetAEcrire ) ; // écriture de la mise à jour octetLu = memoire.readByte ( adressage ) ; // lecture du contenu avant mise à jour octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture octetLu = memoire.readByte ( cpt -1 ) ; // lecture (supprimé 4 offset?) octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture octetLu = memoire.readByte ( adressage ) ; // nouvelle lecture */ // ========================================== void writeEeprom () // écrit un octet là où ça pointe { newAddressW += offsetEeprom ; // introduction offset memoire.updateByte ( newAddressW , toBeWritten ) ; // écriture } // ========================================== void readEeprom () // écrit un octet là où ça pointe { newAddressR += offsetEeprom ; // introduction offset byteLu = memoire.readByte ( newAddressR ) ; // nouvelle lecture } // ==========================================
Les complications ajoutées (ajout d'offset) étaient destinées à décaler (de la valeur d'offset) les écritures dans l'eeprom pensant que le début pouvais être malade. Cette disposition n'a pas fonctionné.
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