Bonjour à tous ,

Je souhaite changer dans le prg ci dessous la librairie pour passer d'un SSD1306 (128x64) à un SH1107 (128x128)
Je précise que le croquis fonctionne actuellement
l'enjeu est donc de passer de la librairie <Adafruit_SH1106.h> à la libraire <U8g2lib.h>
la seule qui semble accepter ce type de OLED
si la plupart des "Keywords" se ressemblent , je bloque sur l’équivalence de certains comme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
 display.setTextSize(1);                    // Régler la taille de la police par défaut
 display.setTextColor(WHITE);               // Régler la police pour afficher la couleur sur fond noir
 display.invertDisplay(0);                  // Régler l'affichage sur la vidéo normale
et je souhaiterai donc par quoi je peux les remplacer
ma demarche n'est peut-être pas la bonne mais si vous avez des suggestions je suis preneur

Mille mercis
pascal




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
 
//****************************************************************************
#include <SPI.h> //Library for Adafruit communication to OLED display
#include <Wire.h> //I2C communication library
#include "ds3231.h" //Real Time Clock library
#include <Adafruit_GFX.h> //Graphics library
#include <Adafruit_SH1106.h> //OLED display library
#include <splash.h>
#include <EEPROM.h> //This library allows reading and writing to the EEPROM
//*****************************************************************************
 
//****************************************************************************
// broche 10 lorsque l'alarme est activée
//****************************************************************************
#define voltage //Décommentez si la broche 10 est connectée à un dispositif d'alarme nécessitant une sortie constante pendant que l'alarme est activée
 
//****************************************************************************
// Gestion de l'Affichage 
//****************************************************************************
#define dimming
boolean dim  ;
 
//****************************************************************************
// Variables 
//****************************************************************************
unsigned long prev, interval = 100; //Variables for display/clock update rate
byte flash = 0;                     //Drapeau pour l'affichage clignotant - basculer une fois par intervalle de mise à jour
byte mode = 0;                      //Mode de fixation de l'heure et de la date
byte tempset;                       //Variable temporaire pour le réglage de l'heure/la date
byte framecount = 3;                //Compteur de cadres pour l'animation. Initialisé à la dernière image pour démarrer l'animation à la première image
byte framecount2 = 0;               //Compteur pour le nombre de périodes de mise à jour de l'affichage - pour la synchronisation des changements d'images
byte imagecounter = 4;              //Compteur pour l'affichage d'une nouvelle image statique - Initialisé à 4 pour démarrer l'affichage de l'image statique au début
const uint8_t PROGMEM secset = 0; //Index for second RTC setting
const uint8_t PROGMEM minset = 1; //Index for minute RTC setting
const uint8_t PROGMEM hourset = 2; //Index for hour RTC setting
const uint8_t PROGMEM wdayset = 3; //Index for weekday RTC setting
const uint8_t PROGMEM mdayset = 4; //Index for date RTC setting
const uint8_t PROGMEM monset = 5; //Index for month RTC setting
const uint8_t PROGMEM yearset = 6; //Index for year RTC setting
//****************************************************************************
uint8_t wake_HOUR = 0;   // Heure du Sommeil
uint8_t wake_MINUTE = 0;
uint8_t wake_SECOND = 0;
 
uint8_t wake_HOUR2 = 0;  // Heure du réveil 
uint8_t wake_MINUTE2 = 0;
 
uint8_t wake_SET = 1; //Alarme par défaut sur ON en cas de coupure de courant ou de réinitialisation
uint8_t wake_SET2 = 1; //Alarme par défaut sur ON en cas de coupure de courant ou de réinitialisation
//****************************************************************************
 
 
//****************************************************************************
// Gestion OLED SH1106
//****************************************************************************
#define OLED_RESET 4 //Define reset for OLED display
Adafruit_SH1106 display(OLED_RESET); //Reset OLED display
//****************************************************************************
 
int beepcount = 0; //Variable pour le nombre d'intervalles de 100ms depuis que l'alarme a commencé à sonner
const byte alarmEE = 0; //Lieu de stockage de l'état d'alarme de l'EEPROM
const byte alarmEE2 = 50; //Lieu de stockage de l'état d'alarme de l'EEPROM
boolean alreadyRun = false;
 
//ADDITIONAL START
////////////////////////////////////////////////////////////////////////////
 
//Pusheen Teacup static image
static const unsigned char PROGMEM pusheen_teacup[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x38, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xE6, 0x0C, 0x61, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x00,
  0x00, 0x83, 0xF8, 0x3E, 0x3D, 0xF0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x38, 0xF8, 0x00, 0x00,
  0x0F, 0x80, 0x00, 0x3C, 0x00, 0xFC, 0x00, 0x00, 0x3F, 0x9C, 0xC7, 0x3F, 0x00, 0x6E, 0x00, 0x00,
  0x0F, 0x1C, 0xE7, 0x3D, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x1D, 0xF3, 0x1E, 0x00, 0x03, 0x80, 0x00,
  0x13, 0x01, 0x80, 0x02, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
  0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08,
  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x8C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC4,
  0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xC6,
  0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xC6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xC4,
  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x88,
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x38,
  0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x70, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC0,
  0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x07, 0x80, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x06, 0x3E, 0x00,
  0x00, 0x60, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00,
  0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
  0x00, 0x07, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x00,
  0x00, 0x00, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
//Pusheen Artist static image
static const unsigned char PROGMEM pusheen_artist[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x3E, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x37, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x33, 0xFC,
  0xCF, 0x80, 0x00, 0x00, 0x00, 0x63, 0xF8, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x60, 0xF0, 0x41, 0xF8,
  0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0xCE, 0x00, 0x00,
  0x0F, 0xDC, 0xC6, 0x00, 0x0F, 0x00, 0x00, 0x03, 0x9C, 0xCE, 0x7C, 0x0F, 0x80, 0x00, 0x0F, 0x8F,
  0xEE, 0x1C, 0x01, 0x80, 0x00, 0x0F, 0x00, 0x60, 0x60, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x70,
  0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x02, 0x00, 0x00, 0x18, 0x00, 0xC0,
  0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06,
  0x00, 0x00, 0x00, 0x00, 0x60, 0x07, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0xFA, 0x00, 0x00,
  0x00, 0x00, 0xDC, 0x07, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x06, 0xFB, 0x00, 0x00, 0x00, 0x00,
  0xDE, 0x04, 0xCF, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x04, 0xCD, 0x80, 0x00, 0x00, 0x01, 0xFE, 0x04,
  0xE9, 0xC0, 0x00, 0x00, 0x03, 0xFE, 0x07, 0xF8, 0xE0, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFE,
  0x00, 0x00, 0x0F, 0xF8, 0x00, 0x0F, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x7C, 0x01, 0xFF, 0xCF,
  0xF8, 0x00, 0x38, 0x60, 0x00, 0xF7, 0xFF, 0xE0, 0x00, 0x7C, 0x70, 0x00, 0x03, 0x01, 0x80, 0x00,
  0x7C, 0x38, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x7C, 0x1C, 0x00, 0x3C, 0x18, 0x0F, 0xC0, 0x6C, 0x07,
  0x00, 0xF0, 0xFF, 0x8F, 0xFF, 0x6C, 0x03, 0x83, 0xC1, 0xCB, 0xC7, 0xFF, 0x6C, 0x01, 0xEF, 0x03,
  0x1E, 0xF7, 0xFF, 0x3C, 0x10, 0x7C, 0x03, 0xD7, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x07, 0xFD, 0xD8,
  0x00, 0x00, 0x2E, 0x00, 0x07, 0xE1, 0xD8, 0x00, 0x00, 0x3F, 0x00, 0x07, 0xE3, 0x98, 0x00, 0x00,
  0x1F, 0x0F, 0x86, 0xC7, 0x38, 0x00, 0x00, 0x00, 0x3F, 0x86, 0x77, 0x70, 0x00, 0x00, 0x00, 0x7F,
  0x86, 0xF7, 0xE0, 0x00, 0x00, 0x00, 0x7F, 0x03, 0xF1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF3,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00
};
 
//Pusheen Scooter static image
static const unsigned char PROGMEM pusheen_scooter[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x66, 0x03, 0x80, 0x00, 0x00, 0x0C, 0xC3, 0x07, 0xC0, 0x00, 0x00, 0x0F, 0x83,
  0xFC, 0xC0, 0x00, 0x00, 0x3B, 0x83, 0xF8, 0x40, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x7C, 0x00, 0x00,
  0x07, 0x38, 0x00, 0xFC, 0x00, 0x00, 0x06, 0x39, 0x80, 0xFC, 0x00, 0x00, 0x0C, 0x03, 0xCC, 0x7C,
  0x00, 0x00, 0x08, 0x00, 0xCC, 0x47, 0x80, 0x00, 0x18, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x18, 0x00,
  0x00, 0x07, 0xF0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x30, 0x00, 0x00, 0x00, 0x7C, 0x00,
  0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00,
  0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0F, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x78, 0x00, 0x00, 0x03, 0xFC, 0x03, 0xFF,
  0x00, 0x00, 0x07, 0xFE, 0x01, 0xFB, 0xC1, 0xC0, 0x1F, 0xFE, 0x01, 0x60, 0x79, 0xE0, 0x7B, 0xF8,
  0x03, 0x60, 0x1F, 0xFF, 0xE0, 0x00, 0x03, 0x20, 0x1F, 0xFF, 0x80, 0x00, 0x02, 0x30, 0x1F, 0xFF,
  0xC0, 0x00, 0x02, 0x30, 0x1F, 0xFF, 0x80, 0x00, 0x1E, 0x18, 0x18, 0x01, 0x80, 0x1E, 0x38, 0x0C,
  0x30, 0x01, 0x86, 0x3E, 0x6F, 0xEC, 0x30, 0xF8, 0xCF, 0x3A, 0x5C, 0x64, 0x61, 0xDC, 0xDF, 0xBE,
  0x7F, 0xFF, 0xE7, 0xFE, 0x5F, 0x9E, 0x7C, 0x78, 0x07, 0x8F, 0x4F, 0x00, 0x7B, 0xAF, 0xFF, 0x77,
  0xCE, 0x00, 0x1B, 0xA5, 0xFB, 0x75, 0xC0, 0x00, 0x19, 0x20, 0x03, 0x24, 0x00, 0x00, 0x0C, 0x60,
  0x01, 0x8C, 0x00, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
//Pusheen Cookie static image
static const unsigned char PROGMEM pusheen_cookie[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x0C, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x73, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x60, 0xC0, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0xFF, 0x81, 0x00,
  0x00, 0x00, 0x00, 0x1E, 0xC0, 0x6F, 0x81, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x6D, 0x01, 0x9E,
  0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0xF6, 0x80, 0x00, 0x01, 0xC0,
  0x00, 0x00, 0x00, 0x1F, 0x07, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3B, 0x07, 0x04, 0x3C, 0xFF,
  0x00, 0x00, 0x00, 0x70, 0x07, 0x0C, 0x3C, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x7F, 0x18, 0x40,
  0x00, 0x00, 0x03, 0x80, 0x00, 0xE1, 0xC0, 0x40, 0x00, 0x00, 0x07, 0x00, 0x01, 0xC3, 0x60, 0x60,
  0x00, 0x00, 0x0C, 0x00, 0x03, 0x83, 0x30, 0x60, 0x00, 0x00, 0x18, 0x00, 0x03, 0x32, 0x30, 0x60,
  0x00, 0x00, 0x30, 0x00, 0x01, 0x30, 0x30, 0x20, 0x00, 0x00, 0x60, 0x00, 0x01, 0x87, 0x30, 0x20,
  0x00, 0x00, 0xC0, 0x00, 0x01, 0x87, 0x70, 0x20, 0x00, 0x01, 0x80, 0x00, 0x00, 0xF7, 0xF0, 0x20,
  0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x30, 0x00, 0x03, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x30,
  0x00, 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
  0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
  0x00, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x60, 0x00, 0x08, 0x00, 0xE7, 0xBE, 0x00, 0x00, 0x60,
  0x00, 0x08, 0x01, 0xBF, 0xF7, 0x00, 0x00, 0x60, 0x00, 0x08, 0x03, 0x60, 0x1D, 0xE0, 0x00, 0x40,
  0x00, 0x0C, 0x03, 0xC0, 0x06, 0xF0, 0x00, 0xC0, 0x00, 0x04, 0x07, 0x80, 0x00, 0x10, 0x00, 0xC0,
  0x1F, 0xFE, 0x07, 0x80, 0x00, 0x90, 0x01, 0x80, 0x7E, 0x6E, 0x07, 0x00, 0x00, 0x90, 0x01, 0xC0,
  0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x9F, 0xFF, 0xC0, 0x7F, 0xE0, 0x05, 0x00, 0x00, 0x9F, 0xFF, 0xC0,
  0x00, 0x00, 0x05, 0x00, 0x00, 0x97, 0x80, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x9F, 0x80, 0x00,
  0x00, 0x00, 0x07, 0x80, 0x00, 0xBD, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0x80, 0x00, 0xB3, 0x80, 0x0C,
  0x00, 0x00, 0x03, 0xC0, 0x06, 0x31, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0x77, 0xBD, 0xE3, 0x30, 0x00,
  0x00, 0x00, 0x01, 0xDF, 0xFF, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00
};
 
//Pusheen Marshmallow static image
static const unsigned char PROGMEM pusheen_marshmallow[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x80, 0x00, 0x00, 0x00, 0x1E, 0x07, 0xC7,
  0xF0, 0x00, 0x00, 0x36, 0x0C, 0xDF, 0xF8, 0x00, 0x00, 0x33, 0x7C, 0x79, 0xDE, 0x00, 0x00, 0x63,
  0xF8, 0x63, 0xDF, 0x00, 0x00, 0x41, 0xF0, 0x1E, 0x1F, 0x00, 0x0F, 0xC0, 0x00, 0x3C, 0x1D, 0x80,
  0x1F, 0xC0, 0x00, 0x30, 0x01, 0xC0, 0x00, 0xD8, 0x01, 0xBE, 0x00, 0xC0, 0x0F, 0x9E, 0x67, 0x00,
  0x00, 0x60, 0x1D, 0x8E, 0x70, 0x00, 0x00, 0x60, 0x01, 0x80, 0x60, 0x00, 0x00, 0x60, 0x01, 0x80,
  0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x80, 0x00, 0x00, 0x00, 0x30, 0x0F, 0xC0, 0x00, 0x00,
  0x00, 0x38, 0x0C, 0xE0, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x38, 0x00, 0x00, 0x02, 0x66, 0x30, 0x7E,
  0x00, 0x00, 0x0F, 0xE6, 0x30, 0x67, 0x80, 0x00, 0x1F, 0xC2, 0x20, 0x21, 0xF8, 0x00, 0x7F, 0x83,
  0x60, 0x30, 0x3F, 0xFF, 0xEE, 0x03, 0x60, 0x30, 0x03, 0xFF, 0xFC, 0x03, 0x40, 0x30, 0x00, 0x00,
  0x78, 0x01, 0x40, 0x30, 0x00, 0x00, 0x70, 0x01, 0xC0, 0x10, 0x00, 0x00, 0x70, 0x01, 0xC0, 0x10,
  0x00, 0x00, 0x60, 0x01, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x01,
  0xC0, 0x10, 0x00, 0x00, 0x00, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x01, 0x80, 0x10, 0x00, 0x00,
  0x00, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x30,
  0x00, 0x00, 0x00, 0x01, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x20, 0x00, 0x00, 0x00, 0x03,
  0x40, 0x60, 0x00, 0x00, 0x00, 0x03, 0x60, 0x60, 0x00, 0x00, 0x00, 0x03, 0x60, 0xC0, 0x00, 0x00,
  0x00, 0x02, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x06, 0x39, 0x80, 0x00, 0x00, 0x00, 0x06, 0x1C, 0x00,
  0x00, 0x00, 0x00, 0x06, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x1C, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8
};
 
//ADDITIONAL FINISH
 
///////////////////////////////////////////////////////
/////////////////  SETUP //////////////////////////////
///////////////////////////////////////////////////////
 
void setup()
{
 
  Serial.begin(9600);  //Initialiser le port série, si nécessaire (non utilisé)
  Wire.begin(); //Initialiser la bibliothèque de communication I2C
  DS3231_init(0x00); //Initialisation de l'horloge temps réel pour une sortie en onde carrée de 1 Hz (pas d'alarme RTC sur la broche de sortie)
 
  //****************************************************************************
  // Init Connectique externe
  //****************************************************************************
  pinMode(7, INPUT); //Définir le pin pour le bouton de Eteint/Allumer
  digitalWrite(7, HIGH); //Turn on pullup resistors
 
  pinMode(8, INPUT); //Définir le pin pour le bouton de mode 
  digitalWrite(8, HIGH); //Turn on pullup resistors
 
  pinMode(9, INPUT); //Set pin pour le bouton de réglage 
  digitalWrite(9, HIGH); //Turn on pullup resistors
 
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
 
  //**************************************************************************** 
  // Init Phase Réveil 
  //****************************************************************************
  Wire.beginTransmission(44); // Envoyer vers device #44
  Wire.write(1); // Envoi un 1
  Wire.endTransmission(1000); // Arreter la transmissionndelay(1000); 
  //****************************************************************************
 
 
  //**************************************************************************** 
  // Lecture de l'état des alarmes mémorisées et initialisation sur on à la première exécution ou sur erreur
  //****************************************************************************
  wake_SET = EEPROM.read(alarmEE);
  if (wake_SET != 0 && wake_SET != 1) {
    wake_SET = 1;
    EEPROM.write(alarmEE, wake_SET);
	}
	wake_SET2 = EEPROM.read(alarmEE2);
  if (wake_SET2 != 0 && wake_SET2 != 1) {
    wake_SET2 = 1;
    EEPROM.write(alarmEE2, wake_SET2);
  }
 
  //****************************************************************************
  // par défaut, la haute tension à partir de la ligne 3,3v en interne ! 
  //****************************************************************************
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);  // initialiser avec l'addr I2C 0x3C (pour l'affichage OLED 128x64)
  display.setTextSize(1);                    // Régler la taille de la police par défaut
  display.setTextColor(WHITE);               // Régler la police pour afficher la couleur sur fond noir
  display.invertDisplay(0);                  // Régler l'affichage sur la vidéo normale
  dim = 1 ;                                  // Affichage allumé
 
}
//// //////////  FIN SETUP ////////////////////////////
 
///////////////////////////////////////////////////////
/////////////// BOUCLE LOOP  //////////////////////////
///////////////////////////////////////////////////////
 
void loop()
{
  char tempF[6];                             //Variable locale pour stocker les relevés de température convertis à partir du module d'horloge en temps réel
  float temperature;                         //Variable de température intermédiaire pour convertir les Celsius en Farenheit
  unsigned long now = millis();              //Variable locale réglée sur la valeur actuelle de la minuterie interne d'Arduino en millisecondes
  struct ts t;                               //Structure de récupération et de stockage des données de date et d'heure de l'horloge en temps réel
 
//****************************************************************************
// Dessiner et mettre à jour l'affichage à chaque période de rafraîchissement (100ms)
//****************************************************************************
  if ((now - prev > interval)) {           //Déterminer s'il faut lancer une mise à jour de l'heure et de l'écran
	framecount2 = framecount2 + 1;           //Compteur de mise à jour des périodes de rafraîchissement
	if (framecount2 > 300) {
		framecount2 = 0;                 //Remontez le compteur de période de rafraîchissement à 0 après 300 mises à jour,
		mode = 0;                        //Remise à zéro du mode normal à chaque cycle, sauf si les boutons de réglage sont actionnés pour remettre le compteur de cycles à zéro
	}
	if (flash == 0) {
	   flash = 1;                          //Basculer le drapeau flash pour que le curseur clignote plus tard
	   } else {
		flash = 0;
	}
 
//****************************************************************************	
//  Obtenir Données DS3231 & Alarmes
//****************************************************************************
    DS3231_get(&t);                          //Obtenir l'heure et la date et enregistrer dans la structure t
    get_alarm();                             //Récupérer le réglage actuel de l'alarme 1
	get_alarm2();                            //Récupérer le réglage actuel de l'alarme 2
 
    display.invertDisplay(0);             //Retour à l'affichage normal après l'arrêt de l'alarme - aucun effet si l'alarme n'est pas activée
 
//***********************************************************************
// température 
//***********************************************************************
 
    //if ((DS3231_get_addr(0x0E) & 0x20) == 0) {
    //  DS3231_init(0x20);               //Vérifiez d'abord le drapeau CONV pour voir si la conversion est en cours, sinon commencez la conversion
    //}
    temperature = DS3231_get_treg();     //Obtenir la température à partir d'une horloge en temps réel
    dtostrf(temperature, 3, 0, tempF);   //Convertir la température en chaîne pour l'affichage
 
 
    display.clearDisplay();              // Effacer le tampon d'affichage du dernier rafraîchissement
    Indic();                             // Recharger les Etats des Alarmes S et R
 
    if (mode < 1) {  	// Indicateurs d'alarme et actions en mode d'affichage normal et programmé uniquement
 
      if (wake_SET) {                    // Affichage de l'alarme sur l'indicateur si l'alarme est activée
        display.setCursor(74, 18); 		 // Positionner le curseur de texte pour l'alarme sur l'indicateur
		display.print(F("S"));           // Imprimer le caractère entre l'heure et la température si l'alarme est activée
      }
	  if (wake_SET2) {                   // Affichage de l'alarme sur l'indicateur si l'alarme est activée
        display.setCursor(110,18);       // Positionner le curseur de texte pour l'alarme sur l'indicateur
        display.print(F("R"));           // Imprimer le caractère entre l'heure et la température si l'alarme est activée
      }
    } else {
		 display.setCursor(74, 18); 		 // Positionner le curseur de texte pour l'alarme sur l'indicateur
		 display.print(F(" "));  
		 display.setCursor(110,18);       // Positionner le curseur de texte pour l'alarme sur l'indicateur
         display.print(F(" "));
	}		 
 
 
	///*********************************************************************************************
	/// Traitement de l'Alarme 1 = Sommeil   
	///*********************************************************************************************
		if (wake_SET && DS3231_triggered_a1()) { //Affichage/Alarme sonore si activée et déclenchée => Sommeil
 
		  //**************************************************
			Wire.beginTransmission(44); // Envoyer vers device #44
			Wire.write(2); // Envoi un 2
			Wire.endTransmission(1000); // Arreter la transmissionndelay(1000); // Attendre 1s
		  //**************************************************
 
		}
	///**********************************************************************************************
	/// Traitement de l'Alarme 2 = Reveil  
	///**********************************************************************************************
		if (wake_SET2 && DS3231_triggered_a2()) { //Affichage/Alarme sonore si activée et déclenchée => Reveil 
 
		  //******************************************************
			Wire.beginTransmission(44); // Envoyer vers device #44
			Wire.write(1); // Envoi un 1
			Wire.endTransmission(1000); // Arreter la transmissionndelay(1000); // Attendre 1s
		  //*******************************************************
 
	    }
 
	//*********************************************************************************************
	// Extinction & Allumage Ecran 	
	//*********************************************************************************************
		#if defined(dimming) 
            if (!digitalRead(7) && (dim==1) ) {
              //Serial.println("Eteint");
              display.SH1106_command (SH1106_DISPLAYOFF) ;   // Eteindre l'affichage 
              delay(200);
              dim = 0 ;
              delay(200);
            }
            if (!digitalRead(7) && (dim==0) ) {
              //Serial.println("Allumé");
              display.SH1106_command (SH1106_DISPLAYON);   //Sinon, Allumer
              delay(500);
              dim = 1 ;
            }
        #endif	
 
 
   if (mode < 1 ) {
 
	  //*************************************************************************
      ///////////////// Affichage Date Jour Mois et Année //////////////////////
	  //*************************************************************************
 
	    display.setCursor(1, 4);               //Positionner le curseur pour l'affichage du jour de la semaine // 12,4
	    printDay(t.wday);                       //Recherche de la chaîne du jour de la semaine à partir des données RTC récupérées et écriture dans le tampon d'affichage
        if (t.mday < 10) {display.print("0");}  //Ajouter le zéro à l'affichage de la date si la date est à un seul chiffre
	    display.print(t.mday);                  //Ecrire la date pour afficher le tampon
	    display.print(" ");                     //Écrivez les espaces et la virgule entre les jours et la date
        printMonth(t.mon);                      //Recherche de la chaîne de mois à partir des données du RTC récupérées et écriture dans la mémoire tampon d'affichage
        display.print(t.year);                  //Ecrire l'année pour afficher le tampon
 
 
	  //*************************************************************************
      ///////////////// Affichage Heure : Minute : Seconde  //////////////////////
	  //*************************************************************************
	  if (framecount2 > 25) {
 
		 display.clearDisplay(); 
         Indic();		 
	     display.setCursor(0, 0); //Positionner le curseur du texte pour l'affichage de l'heure
	     display.fillRect(0, 0, 128, 8, BLACK); 
	     display.setTextSize(2); // Draw 2X-scale text
	     display.setCursor(16,0); //Positionner le curseur du texte pour l'affichage de l'heure
	    // HEURE /////
         if (t.hour < 13 && t.hour >= 10) {
           display.print(t.hour); //Il suffit d'afficher l'heure si l'heure à deux chiffres
         } else if (t.hour < 10) {
           display.print(F(" "));  //S'il s'agit d'une heure à un chiffre, ajouter un espace en tête
           display.print(t.hour);
         } else {
         display.print(t.hour);
         }
         display.print(F(":"));   //Afficher le séparateur heure-minute
 
      // MINUTE /////	  
         if (t.min < 10) {
           display.print(F("0")); //Add zéro de tête si minute à un chiffre
         }
         display.print(t.min);    //Afficher le procès-verbal récupéré
         display.print(F(":"));   //Afficher le séparateur minutes-secondes
 
	  // SECONDE ////
	     display.setTextSize(1); // Draw 1X-scale text 
         if (t.sec < 10) {
         display.print(F("0")); //Ajouter un zéro de tête pour les secondes à un chiffre
         }
         display.print(t.sec);    //Affichage des secondes récupérées
 
	  }
    //*************************************************************************
	  // Affichage de l'Horloge
	  //*************************************************************************
 
      // Maintenant, dessinez le cadran de l'horloge
      display.drawCircle(display.width() / 2 + 30, display.height() / 2 + 8, 20, WHITE); //Dessiner et positionner le cercle extérieur de l'horloge
      if (flash) {
        display.drawCircle(display.width() / 2 + 30, display.height() / 2 + 8, 2, WHITE); //Dessiner, positionner et faire clignoter un petit cercle intérieur
      }
      display.drawRect(71, 17, 47, 47, WHITE);   // Dessiner la Boîte autour de l'Horloge
     //Positionner et dessiner des coches horaires
      for ( int z = 0; z < 360; z = z + 30 ) { 
         //Commencer à 0° et s'arrêter à 360°.
         float angle = z ;
         angle = (angle / 57.29577951) ;       //Convertir les degrés en radians
         int x2 = (94 + (sin(angle) * 20));
         int y2 = (40 - (cos(angle) * 20));
         int x3 = (94 + (sin(angle) * (20 - 5)));
         int y3 = (40 - (cos(angle) * (20 - 5)));
         display.drawLine(x2, y2, x3, y3, WHITE);
      }
 
      //Position et affichage de l'aiguille des secondes 
      float angle = t.sec * 6 ;            //Récupérez les secondes stockées et appliquez
      angle = (angle / 57.29577951) ;      //Convertir les degrés en radians
      int x3 = (94 + (sin(angle) * (20)));
      int y3 = (40 - (cos(angle) * (20)));
      display.drawLine(94, 40, x3, y3, WHITE);
 
      //Position et affichage de l'aiguille des minutes
      angle = t.min * 6; //Récupérez les minutes stockées et appliquez
      angle = (angle / 57.29577951) ; //Convertir les degrés en radians
      x3 = (94 + (sin(angle) * (20 - 3)));
      y3 = (40 - (cos(angle) * (20 - 3)));
      display.drawLine(94, 40, x3, y3, WHITE);
 
      //Position et affichage de l'aiguille des heures
      angle = t.hour * 30 + int((t.min / 12) * 6); //Récupérer les heures et les minutes enregistrées et les appliquer
      angle = (angle / 57.29577951) ; //Convertir les degrés en radians
      x3 = (94 + (sin(angle) * (20 - 11)));
      y3 = (40 - (cos(angle) * (20 - 11)));
      display.drawLine(94, 40, x3, y3, WHITE);
 
	  //************************************************************************** 
 
 
      if (framecount2 > 50) { //Afficher une image statique pour 250 des 300 images
 
	  		if (framecount2 == 51) { //Augmenter l'image à afficher une fois par 300 images
			  imagecounter = imagecounter + 1; //Avancer le compteur d'images
			}
			display.fillRect(2, 16, 64, 48, WHITE); //Dessinez un fond "blanc" pour l'affichage d'une image statique sur la moitié gauche de l'écran
			if (imagecounter > 4) {
			  imagecounter = 0; //Passez sur le compteur d'images après que toutes les images aient été séquencées
			}
			if (imagecounter == 0) {
			  display.drawBitmap(0, 16, pusheen_teacup, 64, 48, BLACK); //Position and draw static bitmap
			}
			if (imagecounter == 1) {
			  display.drawBitmap(5, 16, pusheen_artist, 56, 48, BLACK); //Position and draw static bitmap
			}
			if (imagecounter == 2) {
			  display.drawBitmap(10, 16, pusheen_scooter, 48, 48, BLACK); //Position and draw static bitmap
			}
			if (imagecounter == 3) {
			  display.drawBitmap(0, 16, pusheen_cookie, 64, 48, BLACK); //Position and draw static bitmap
			}
			if (imagecounter == 4) {
			  display.drawBitmap(10, 16, pusheen_marshmallow, 48, 48, BLACK); //Position and draw static bitmap
			}
	  }
 
    // Affichage Température ******************************************   
	  if (framecount2 <= 50) {  
        display.setCursor(0,16);
        display.fillRect(0, 16, 64, 48, BLACK); 
		display.drawRect(0, 16, 64, 48, WHITE); 
		display.setTextSize(2); // Draw 2X-scale text
        display.setCursor(0,32);              //Set curseur pour l'affichage de la température
        display.print(tempF);                 //Envoyer la température au tampon d'affichage
        display.drawCircle(40, 32, 2, WHITE); //Dessiner le symbole du degré après la température
        display.print(F(" c"));
		display.setTextSize(1); // Draw 1X-scale text
	  }
 
    }
 
    if (mode >= 1) {   // Mode permettant la mise à jour des données
 
	   display.clearDisplay();  
	  //*********************************************************************
 	  // Heure 
	  //*********************************************************************
 
	     display.clearDisplay(); 	
	     display.setCursor(0, 0); //Positionner le curseur du texte pour l'affichage de l'heure
	     display.fillRect(0, 0, 128, 8, BLACK); 
	     display.setTextSize(2); // Draw 2X-scale text
	     display.setCursor(16,0); //Positionner le curseur du texte pour l'affichage de l'heure
	    // HEURE /////
         if (t.hour < 13 && t.hour >= 10) {
           display.print(t.hour); //Il suffit d'afficher l'heure si l'heure à deux chiffres
         } else if (t.hour < 10) {
           display.print(F(" "));  //S'il s'agit d'une heure à un chiffre, ajouter un espace en tête
           display.print(t.hour);
         } else {
         display.print(t.hour);
         }
         display.print(F(":"));   //Afficher le séparateur heure-minute
 
      // MINUTE /////	  
         if (t.min < 10) {
           display.print(F("0")); //Add zéro de tête si minute à un chiffre
         }
         display.print(t.min);    //Afficher le procès-verbal récupéré
         display.print(F(":"));   //Afficher le séparateur minutes-secondes
 
	  // SECONDE ////
	     display.setTextSize(1); // Draw 1X-scale text 
         if (t.sec < 10) {
         display.print(F("0")); //Ajouter un zéro de tête pour les secondes à un chiffre
         }
         display.print(t.sec);    //Affichage des secondes récupérées 	
 
      //************************************************************************	 
	  // Date 	
	  //************************************************************************
 
	    display.setCursor(12,24);               //Positionner le curseur pour l'affichage du jour de la semaine
	    printDay(t.wday);                       //Recherche de la chaîne du jour de la semaine à partir des données RTC récupérées et écriture dans le tampon d'affichage
        if (t.mday < 10) {display.print("0");}  //Ajouter le zéro à l'affichage de la date si la date est à un seul chiffre
	    display.print(t.mday);                  //Ecrire la date pour afficher le tampon
	    display.print(" ");                     //Écrivez les espaces et la virgule entre les jours et la date
        printMonth(t.mon);                      //Recherche de la chaîne de mois à partir des données du RTC récupérées et écriture dans la mémoire tampon d'affichage
        display.print(t.year);                  //Ecrire l'année pour afficher le tampon
 
	  // Alarme 1 ////////////////////////////////////
      display.setCursor(0, 40); //Positionner le curseur sur le texte
      display.print(F("ALarme-1: "));
      if (wake_SET) {
        display.print(F("ON"));
      } else {
          display.print(F("OFF"));
      }
 
      display.setCursor(80, 40); //Positionner le curseur du texte pour l'affichage de l'heure
      if (wake_HOUR < 13 && wake_HOUR >= 10) {
        display.print(wake_HOUR); //Il suffit d'afficher l'heure si l'heure à deux chiffres
      } else if (wake_HOUR < 10) {
        display.print(F(" "));  //S'il s'agit d'une heure à un chiffre, ajouter un espace en tête
        display.print(wake_HOUR);
        } else {
          display.print(wake_HOUR);
      }
 
      display.print(F(":")); //Afficher le séparateur heure-minute
      if (wake_MINUTE < 10) {
        display.print(F("0")); //Ajouter le zéro de tête s'il s'agit d'une minute à un chiffre
      }
      display.print(wake_MINUTE); //Afficher le procès-verbal récupéré
 
 
	  //Alarme 2 /////////////////////////////////////////////////////
	  display.setCursor(0, 54); //Positionner le curseur sur le texte
      display.print(F("Alarme-2: "));
      if (wake_SET2) {
        display.print(F("ON"));
      } else {
          display.print(F("OFF"));
      }
 
      display.setCursor(80, 54); //Positionner le curseur du texte pour l'affichage de l'heure
 
      if (wake_HOUR2 < 13 && wake_HOUR2 >= 10) {
        display.print(wake_HOUR2); //Il suffit d'afficher l'heure si l'heure à deux chiffres
      } else if (wake_HOUR2 < 10) {
        display.print(F(" "));  //S'il s'agit d'une heure à un chiffre, ajouter un espace en tête
        display.print(wake_HOUR2);
        } else {
          display.print(wake_HOUR2);
      }
 
      display.print(F(":")); //Afficher le séparateur heure-minute
      if (wake_MINUTE2 < 10) {
        display.print(F("0")); //Ajouter le zéro de tête s'il s'agit d'une minute à un chiffre
      }
      display.print(wake_MINUTE2); //Afficher le procès-verbal récupéré
 
    }
 
 
    //Traitement du bouton de réglage de l'heure/date et clignotement du curseur
    //Mise à jour de l'affichage numérique et analogique de l'heure et de la date avec de nouveaux réglages à 5Hz au fur et à mesure des modifications
    switch (mode)
	{
 
 
      case 0:
        if (wake_SET && DS3231_triggered_a1()) { //Display/sound alarm if enabled and triggered
          //ne rien faire
          //Serial.println ("No delay durning alarm flash") ;
        }
        else {
 
          //delay(800) ; // cette valeur est utilisée pour que la boucle dure environ 1 seconde.
          //Serial.println("Délai 810 pour réduire la charge") ;
        }
        break;
      case 1: // Jour de la Semaine
 
        if (flash) {
          display.drawRect(12, 24, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.wday; //Get the current weekday and save in temporary variable
          tempset = tempset + 1; //Increment the day at 5Hz rate
          if (tempset > 7) {
            tempset = 1; //Roll over after 7 days
          }
          t.wday = tempset; //After each update, write the day back to the time structure
          set_rtc_field(t, wdayset); //Write the set field only back to the real time clock module after each update
        }
        break;
 
      case 2: // Fixation du Jour 
 
        if (flash) {
          display.drawRect(36, 24, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.mday; //Get the current date and save in temporary variable
          tempset = tempset + 1; //Increment the date at 5Hz rate
          //(RTC allows incorrect date setting for months < 31 days, but will use correct date rollover for subsequent months.
          if (tempset > 31) {
            tempset = 1; //Roll over after 31 days
          }
          t.mday = tempset; //After each update, write the date back to the time structure
          set_rtc_field(t, mdayset); //Write the set field only back to the real time clock module after each update
        }
        break;
 
      case 3: //Fixation du mois
	    if (flash) {
          display.drawRect(54, 24, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.mon; //Get the current month and save in temporary variable
          tempset = tempset + 1; //Increment the month at 5Hz rate
          if (tempset > 12) {
            tempset = 1; //Roll over after 12 months
          }
          t.mon = tempset; //After each update, write the month back to the time structure
          set_rtc_field(t, monset); //Write the set field only back to the real time clock module after each update
        }
        break;
 
      case 4: //Fixation de l'année
        if (flash) {
          display.drawRect(78,24, 24, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.year; //Get the current year and save in temporary variable
          tempset = tempset + 1; //Increment the year at 5Hz rate
          //RTC allows setting from 1900, but range limited here to 2000 to 2099
          if (tempset > 2099) {
            tempset = 2000; //Roll over after 2099 to 2000
          }
          t.year = tempset; //After each update, write the year back to the time structure
          set_rtc_field(t, yearset); //Write the set field only back to the real time clock module after each update
        }
        break;
      case 5: //Fixation de l'heure
 
	     if (flash) {
          display.drawRect(15, 0, 24, 16, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.hour; //Get the current hour and save in temporary variable
          tempset = tempset + 1; //Increment the hour at 5Hz rate
          if (tempset > 23) {
            tempset = 0; //Roll over hour after 23rd hour (setting done in 24-hour mode)
          }
          t.hour = tempset; //After each update, write the hour back to the time structure
          set_rtc_field(t, hourset); //Write the set field only back to the real time clock module after each update
        }
	  break;
 
 
      case 6: //Réglage des minutes
        if (flash) {
          display.drawRect(51, 0, 24, 16, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = t.min; //Get the current minute and save in temporary variable
          tempset = tempset + 1; //Increment the minute at 5Hz rate
          if (tempset > 59) {
            tempset = 0; //Roll over minute to zero after 59th minute
          }
          t.min = tempset; //After each update, write the minute back to the time structure
          set_rtc_field(t, minset); //Write the set field only back to the real time clock module after each update
        }
      break;   
 
      //Set clock + 1 minute, puis appuyez et maintenez pour geler le réglage de la seconde.
      //Release button at 00 seconds to synchronize clock to external time source.
 
	  ////////////////////////////////////////////////////////////////////////////////////////
      case 7: //Second synchronization
        if (flash) {
          display.drawRect(87, 0, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Réinitialisation de la seconde à zéro au taux de 5Hz si le bouton est maintenu enfoncé
          t.sec = 0; //Après chaque mise à jour, réinscrivez la seconde mise à zéro dans la structure temporelle
          set_rtc_field(t, secset); //Ne réinscrire le champ set que dans le module d'horloge en temps réel après chaque mise à jour
        }
      break;
      ///////////////////////////////////////////////////////////////////////////////////////// 
 
      case 8: //Alarm1 enable/disable
	    if (flash) {
          display.drawRect(54, 40, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          if (wake_SET) {
            wake_SET = 0; //Toggle alarm on/of variable at 5 Hz
          } else {
            wake_SET = 1;
          }
          EEPROM.write(alarmEE, wake_SET); //Save alarm enable setting to EEPROM
        } 
	  break;
 
       case 9: //Alarm1 heure setting
        if (flash) {
          display.drawRect(80, 40, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = wake_HOUR; //Get the current hour and save in temporary variable
		  tempset = tempset + 1; //Increment the hour at 5Hz rate
          if (tempset > 23) {
            tempset = 0; //Roll over hour after 23rd hour (setting done in 24-hour mode)
          }
          wake_HOUR = tempset; //After each update, write the hour back to the alarm variable
		  set_alarm(); //Write the alarm setting back to the RTC after each update
        }
      break;
 
      case 10: //Alarm1 minute setting
	   if (flash) {
          display.drawRect(98, 40, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = wake_MINUTE; //Get the current minute and save in temporary variable
          tempset = tempset + 1; //Increment the minute at 5Hz rate
          if (tempset > 59) {
            tempset = 0; //Roll over minute to zero after 59th minute
          }
          wake_MINUTE = tempset; //After each update, write the minute back to the alarm variable
          set_alarm(); //Write the alarm setting back to the RTC after each update
        }
 
      break;
 
	  //////////////////////////////////////////////////////////////////////////////////////////////
	  case 11: //Alarm2 enable/disable
	    if (flash) {
          display.drawRect(54, 54, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          if (wake_SET2) {
            wake_SET2 = 0; //Toggle alarm on/of variable at 5 Hz
          } else {
            wake_SET2 = 1;
          }
          EEPROM.write(alarmEE2, wake_SET2); //Save alarm enable setting to EEPROM
        }
		break;
 
 
      case 12: //Alarm2 Hour setting
	    if (flash) {
          display.drawRect(80, 54, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = wake_HOUR2; //Get the current hour and save in temporary variable
		  tempset = tempset + 1; //Increment the hour at 5Hz rate
          if (tempset > 23) {
            tempset = 0; //Roll over hour after 23rd hour (setting done in 24-hour mode)
          }
          wake_HOUR2 = tempset; //After each update, write the hour back to the alarm variable
		  set_alarm2(); //Write the alarm setting back to the RTC after each update
        }
	    break;
 
      case 13: //Alarm2 enable/disable
	    if (flash) {
          display.drawRect(98, 54, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
        }
        if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
          tempset = wake_MINUTE2; //Get the current minute and save in temporary variable
          tempset = tempset + 1; //Increment the minute at 5Hz rate
          if (tempset > 59) {
            tempset = 0; //Roll over minute to zero after 59th minute
          }
          wake_MINUTE2 = tempset; //After each update, write the minute back to the alarm variable
          set_alarm2(); //Write the alarm setting back to the RTC after each update
        }
        break;
 
 
    }
 
    prev = now; //Reset variable for display and time update rate
    display.display(); //Display the constructed frame buffer for this framecount
  }
 
  //Clock setting mode set - outside time/display update processing for faster button response
  if (!digitalRead(8)) { //Read setting mode button
    delay(25); //100ms debounce time
    if (!digitalRead(8)) { //Activate setting mode change after 100ms button press
      mode = mode + 1; //Increment the time setting mode on each button press
      framecount2 = 0;  //Reset cycle counter if button pressed to delay auto return to normal mode
      if (mode > 13) {
        mode = 0; //Roll the mode setting after 7th mode
      }
      while (!digitalRead(8)) {} //Wait for button release (freezes all display processing and time updates while button held, but RTC continues to keep time)
    }
  }
 
  if (!digitalRead(9)) { //Reset alarm flag if set button pressed
    delay(25); //25ms debounce time
    if (!digitalRead(9)) {
      DS3231_clear_a1f(); //Reset cycle counter if button pressed to delay auto return to normal mode
	  DS3231_clear_a2f(); //Reset cycle counter if button pressed to delay auto return to normal mode
      beepcount = 0; //Reset alarm timeout counter if alarm stopped by pushing button
      framecount2 = 0;
    }
  }
 
}
 
 
 
//Function to display month string from numerical month argument
void printMonth(int month)
{
  switch (month)
  {
    case 1: display.print(F("Jan ")); break;
    case 2: display.print(F("Fev ")); break;
    case 3: display.print(F("Mar ")); break;
    case 4: display.print(F("Avr ")); break;
    case 5: display.print(F("Mai ")); break;
    case 6: display.print(F("Jun ")); break;
    case 7: display.print(F("Jul ")); break;
    case 8: display.print(F("Aut ")); break;
    case 9: display.print(F("Sep ")); break;
    case 10: display.print(F("Oct ")); break;
    case 11: display.print(F("Nov ")); break;
    case 12: display.print(F("Dec ")); break;
    default: display.print(F("--- ")); break; //Affichage des tirets en cas d'erreur - évite le brouillage de l'affichage
  }
}
 
 
//Fonction permettant d'afficher la chaîne du jour de la semaine à partir de l'argument numérique du jour de la semaine
void printDay(int day)
{
  switch (day)
  {
    case 1: display.print(F("Lundi ")); break;
    case 2: display.print(F("Mardi ")); break;
    case 3: display.print(F("Mercredi ")); break;
    case 4: display.print(F("Jeudi ")); break;
    case 5: display.print(F("Vendredi ")); break;
    case 6: display.print(F("Samedi ")); break;
    case 7: display.print(F("Dimanche ")); break;
    default: display.print(F("--- ")); break; //Affichage des tirets en cas d'erreur - évite le brouillage de l'affichage
  }
}
 
//Sous-routine pour ajuster un seul champ de date/heure dans le RTC
void set_rtc_field(struct ts t,  uint8_t index)
{
  uint8_t century;
 
  if (t.year > 2000) {
    century = 0x80;
    t.year_s = t.year - 2000;
  } else {
    century = 0;
    t.year_s = t.year - 1900;
  }
 
  uint8_t TimeDate[7] = { t.sec, t.min, t.hour, t.wday, t.mday, t.mon, t.year_s };
 
  Wire.beginTransmission(DS3231_I2C_ADDR);
  Wire.write(index);
  TimeDate[index] = dectobcd(TimeDate[index]);
  if (index == 5) {
    TimeDate[5] += century;
  }
  Wire.write(TimeDate[index]);
  Wire.endTransmission();
 
  //Ajuster le réglage du mois, par fiche, si l'année est modifiée
  if (index == 6) {
    Wire.beginTransmission(DS3231_I2C_ADDR);
    Wire.write(5);
    TimeDate[5] = dectobcd(TimeDate[5]);
    TimeDate[5] += century;
    Wire.write(TimeDate[5]);
    Wire.endTransmission();
  }
}
 
///////////////////////////////////////////////////////////////
//Subroutine to set alarm 1  //////////////////////////////////
///////////////////////////////////////////////////////////////
void set_alarm()
{
 
  // flags define what calendar component to be checked against the current time in order
  // to trigger the alarm - see datasheet
  // A1M1 (seconds) (0 to enable, 1 to disable)
  // A1M2 (minutes) (0 to enable, 1 to disable)
  // A1M3 (hour)    (0 to enable, 1 to disable)
  // A1M4 (day)     (0 to enable, 1 to disable)
  // DY/DT          (dayofweek == 1/dayofmonth == 0)
  byte flags[5] = { 0, 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match
 
  // set Alarm1
  DS3231_set_a1(0, wake_MINUTE, wake_HOUR, 0, flags); //Set alarm 1 RTC registers
 
}
 
///////////////////////////////////////////////////////////////
//Subroutine to set alarm 2 //////////////////////////////////
///////////////////////////////////////////////////////////////
void set_alarm2()
{
 
// A2M2 (minutes) (0 to enable, 1 to disable)
// A2M3 (hour) (0 to enable, 1 to disable)
// A2M4 (day) (0 to enable, 1 to disable)
// DY/DT (dayofweek == 1/dayofmonth == 0)
 
byte flags[4] = { 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match
 
// set Alarm2
DS3231_set_a2( wake_MINUTE2, wake_HOUR2,0, flags); //Set alarm 2 RTC registers
 
}
 
 
////////////////////////////////////////////////////////////////
// Subroutine Valeur alarm 1  /////////////////////////////////
/////////////////////////////////////////////////////////////// 
 
void get_alarm()
{
  uint8_t n[4];
  uint8_t t[4];               //second,minute,hour,day
  uint8_t f[5];               // flags
  uint8_t i;
 
  Wire.beginTransmission(DS3231_I2C_ADDR); // Adresse = 0x68
  Wire.write(DS3231_ALARM1_ADDR); // Adresse = 0x07
  Wire.endTransmission();
 
  Wire.requestFrom(DS3231_I2C_ADDR, 4);
 
  for (i = 0; i <= 3; i++) {
    n[i] = Wire.read();
	f[i] = (n[i] & 0x80) >> 7;
	t[i] = bcdtodec(n[i] & 0x7F);
 
  }
 
  f[4] = (n[3] & 0x40) >> 6;
  t[3] = bcdtodec(n[3] & 0x3F);
 
  wake_SECOND = t[0];
  wake_MINUTE = t[1];
  wake_HOUR = t[2];
 
}
 
////////////////////////////////////////////////////////////////
// Subroutine Valeur alarm 2  /////////////////////////////////
/////////////////////////////////////////////////////////////// 
void get_alarm2()
{
uint8_t n[3];
uint8_t t[3]; // minute,hour,day
uint8_t f[4]; // flags
uint8_t i;
Wire.beginTransmission(DS3231_I2C_ADDR); // 0x68
Wire.write(DS3231_ALARM2_ADDR); // 0x0B
Wire.endTransmission();
 
Wire.requestFrom(DS3231_I2C_ADDR, 3);
 
for (i = 0; i <= 2; i++) {
n[i] = Wire.read();
f[i] = (n[i] & 0x80) >> 11; 
t[i] = bcdtodec(n[i] & 0x7F); 
}
 
f[3] = (n[2] & 0x40) >> 6;
t[2] = bcdtodec(n[2] & 0x3F);
 
wake_MINUTE2 = t[0];
wake_HOUR2 = t[1];
 
}
 
///////////////////////////////////////////////////////////////
////////// Indicateurs d'alarmes  /////////////////////////////
///////////////////////////////////////////////////////////////
 
void Indic() {
 
    //NOTE : Les indicateurs d'alarme sont écrasés dans la mémoire tampon d'affichage si une animation plein écran est affichée, donc pas de contrôle pour cela
    if (mode <= 7) {  	// Indicateurs d'alarme et actions en mode d'affichage normal et programmé uniquement
 
      if (wake_SET) {                    // Affichage de l'alarme sur l'indicateur si l'alarme est activée
        display.setCursor(74, 18); 		// Positionner le curseur de texte pour l'alarme sur l'indicateur
		display.print(F("S"));           // Imprimer le caractère entre l'heure et la température si l'alarme est activée
      }
	  if (wake_SET2) {                    // Affichage de l'alarme sur l'indicateur si l'alarme est activée
        display.setCursor(110,18);        // Positionner le curseur de texte pour l'alarme sur l'indicateur
        display.print(F("R"));          // Imprimer le caractère entre l'heure et la température si l'alarme est activée
      }
    }
}