- Objectif :Mesurer et transmettre différentes mesures.
- Moyen:
- Utilisation d'un processeur principal ATmega328P sur Arduino Nano
- Processeur esclave Attiny "One Wire" <8mA
- Énergie utilisée : Transformateur 230V/5V
- Mesures : Capteurs
- AM2320 Capteur d'humidité et de température I²C - single-bus
- Alimentation: 3,1 à 5,5 Vcc
- Consommation maxi: 1,5 mA ; En Stand-by : 950μA
- Plage de mesure:
- température: -40 à +80°C
- humidité: 0 à 99,9% HR
- Précision:
- température: ± 0,5°C
- humidité: ± 3% HR
- Dimensions: 15 x 12,1 x 4,5 mm
- GPL, de CO (Monoxide de carbone) ou de fumées
- MQ-2
- Consommation maxi: 160 mA
- Penser à refaire une calibration périodiquement à l'air pure (Je ne sais pas encore combien)
- Module détecteur de Mouvement infrarouge pyroelectrique PIR
- Un Buzzer actif Ø10mm 25mA à 35mA
- DS3231 AT24C32 Module I2C Horloge de précision
- AM2320 Capteur d'humidité et de température I²C - single-bus
- Communication : One Wire
- Sauvegarde des données? : Periode ?? temps ?? Où?
Les détecteurs "one wire"
Composés de d'un Attiny (adresse entre 0x10 et 0x50), PIR 1 bit, d'un MQ-2 (GPL, CO, fumées ) 2 Octets, d'un AM2320 (détecteur de température et d'humidité) 2 Octets+2 Octets, et enfin d'un Buzzer.. Le tout alimenté sous forme filaire
Les règles de fonctionnement
Il est nécessaire de prévoir un balayage et un stockage des données :
TinyAL | Adresse 8 bits | Adresse 64 bits | CRC | |
---|---|---|---|---|
1 | 00010000 | 0x10 | 2810101010101010 | 0x01 |
2 | 00100000 | 0x20 | 2820202020202020 | 0x68 |
3 | 00110000 | 0x30 | 2830303030303030 | 0x4F |
4 | 01000000 | 0x40 | 2840404040404040 | 0xBA |
5 | 01010000 | 0x50 | 2850505050505050 | 0x9D |
CRC X^8 + X^5 + X^4 + X^0 |
Les commandes
0x55 : MATCH ROM COMMAND0x4E : WRITE SCRATCHPAD Juste pour écrire RO en RAM (2 octets)
0x48 : WRITE DATA TO RAM
- 0x17 : ALARME BUZZER ACTIVE
- Paramètre 0x00 : Alarme inactive par défaut 1
- Paramètre 0x01 : Alarme uniquement ce TinyAL sans ordre 0, il continue de sonner
- Paramètre 0x02 : Alarme tous les TinyAL sans ordre 0, il continue de sonner
- Paramètre 0x03 : Surveillance2 si 0 pas de d'alarme présence (par défaut), sinon 1 alarme présence
- Paramètre 0x04 : Alarme température supérieure à 50°C
1En cas d'alarme fumées, le paramètre d'alarme passe automatiquement à 0x02 sur le TinyAL et l'information est donnée au Master, qui diffuse l'information
2En cas d'alarme présence et Paramètre à 0x03(1), l'alarme passe automatiquement à 0x01 sur le TinyAL et l'information est donnée au Master, qui diffuse l'information.
Calibration du capteur MQ-2
Attention pour calibrer le capteur MQ-2, il est nécessaire de le mettre dans un lieu à environs 20°C avec de l'air pur durant environs 48h.Il est donc nécessaire d'utiliser une procédure pour récupérer la valeur de RO.
Lire les données
0xBE : Load data to RAM : READ SCRATCHPAD Renvoyer la table de données suivante :Adresse | Donnée | Exemple |
---|---|---|
0x00 | Valeur analogique brute MQ-2 GPL, de CO (Monoxyde de carbone) ou de fumées (High byte) | 0x96 |
0x01 | Valeur analogique brute MQ-2 GPL, de CO (Monoxyde de carbone) ou de fumées (Low byte) | 0x14 |
0x02 | AM2320 (high humidity bytes) | 0x01 |
0x03 | AM2320 (low humidity bytes) | 0xF4 |
0x04 | AM2320 (high temperature bytes) | 0x00 |
0x05 | AM2320 (low temperature bytes) | 0xFA |
0x06 | PIR état 0/1 | 0x01 |
0x07 | ALARME 0, 1, 2, 3 et 4 | 0x01 |
0x08 | Version 01 | 0x01 |
0x09 | Révision 03 | 0x03 |
0x0A | FAMILYCODE | 0x28 |
0x0B | DEVICE ID (N°TinyAL) | 0x10 |
0x0C | Valeur analogique brute MQ-2 RO high | 0x96 |
0x0D | Valeur analogique brute MQ-2 RO high | 0x14 |
0x0E | CRC 8bits "one-wire" | 0x6A |
Les composants
- Sur l'esclave:AM2320
Branchement I²C | Branchement "single bus" |
; ;single_bus.inc ; ;single_bus.as ;______________________________________ ; GESTION Single-Bus ; Matériel : ATtiny 85 16MHz 5V ; (c) sammy76.free.fr 23/09/2018 ;V1.0 ; ATtiny85 ; +-\/-+ ; PB5 1|- -|8 Vcc ;DTH22/AM2320 SDA PB3 2|- -|7 PB2 ; PB4 3|- -|6 PB1 ; GND 4|- -|5 PB0 ; +----+ ;______________________________________ ;FUSE H:FE, E:DD, L:E1 ;w lfuse 0 0xe1 ;w hfuse 0 0xdd ;w efuse 0 0xfe ;.CSEG ;.include "tn85def.inc" ;.def A =r16 ; GENERAL PURPOSE ACCUMULATOR ;.def tmp1 =r2 ;pour Single-bus .def timeL =r4 .def timeH =r5 .equ timeout =(F_CPU*1000)/(9000000) ;nombre de cycle pour timeout .equ bSDA = PB3 ;* SDA Port B, PB1 Pin 6 .equ mSDA = (1<<bSDA);Calculate binary value corresponding to I/O port bit for masking ; MIN TYP MAX UNIT .equ Tbe =10 ; 0.8 1 20 ms .equ Tgo =40 ; 20 30 200 us .equ Tre =80 ; 75 80 85 us ;.equ TLOW=50 ; 48 50 55 us ;.equ TH0 =26 ; 22 26 30 us ;.equ TH1 =70 ; 68 70 75 us ;.equ Ten =50 ; 45 50 55 us read_single: push ZH push ZL ;Go into high impedence state to let pull-up raise data line level and ;start the reading process. cbi DDRB,bSDA ; SDA en entrée sbi PORTB,bSDA ; HIGH avec Résistance de pullup ldi A,250 rcall WaitMiliseconds ;Host the start signal down time ;First set data line low for Tbe milliseconds. sbi DDRB,bSDA ; SDA en sortie cbi PORTB,bSDA ; LOW ldi A,Tbe rcall WaitMiliseconds cli ;clear interrupt ;Bus master has released time Tgo sbi PORTB,bSDA ; HIGH ;End the start signal by setting data line high for 40 microseconds. ldi XH,HIGH(C4PUS*Tgo) ;Tgo ldi XL,LOW(C4PUS*Tgo) rcall Wait4xCycles ;Wait Tbe us cbi DDRB,bSDA ; SDA en entrée, sbi PORTB,bSDA ; pull-up activé nop rcall expectPulseLOW ;(4 cycles) Trel rcall expectPulseHIGH ;(4 cycles) Treh ldi A,5 ;5x8 bits=40 bits ;1 cy mov tmp1,A ;1 cy bc_octets: ldi A,8 ;8 bits ;1 cy clr DATA ;1 cy bc_8bits: rcall expectPulseLOW ;4 cy mov timeH,XH ;1 cy mov timeL,XL ;1 cy adiw XH:XL,10 ;Rattrapage du décalage rcall expectPulseHIGH ;4 cy lsl DATA ;1 cy cp XL,timeL ; Compare low byte ; 1 cy cpc XH,timeH ; Compare high byte ; 1 cy brlo bitZero ; HIGHT<LOW 1 cy false 2 cy true ori DATA,1 ;1 cy bitZero: dec A brne bc_8bits ; < 1 cy false 2 cy true st Z+,DATA ;1 cy dec tmp1 ;1 cy brne bc_octets ; < 1 cy false 2 cy true pop ZL pop ZH ; verif CRC ldi ZL, low(AllData) ;RAM les 5 octets ldi ZH, high(AllData) ldi A,4 ;4 données mov tmp1,A clr A whitoutCRC: ld DATA,Z+ add A,DATA dec tmp1 brne whitoutCRC ld DATA,Z cp A,DATA ;Si = pas d'erreur, sinon erreur, BRNE -> ERREUR ret expectPulseLOW: ;compte le temps ou SDA et à 0 clr XL ;1 cy x=0 clr XH ;count ;1 cy push timeL push timeH push A ldi A,HIGH(timeout) mov timeH,A ldi A,LOW(timeout) mov timeL,A bc_expectPulseLOW: sbic PINB,bSDA ; if SDA clear, skip increment ; false (1 cycle)/true (2cycles) rjmp fin_expectPulseLOW ; 2 cy adiw XH:XL, 1 ; x++ (2 cycles) 9cycles par boucles ;compare tmp avec 1ms ;si tmp>1ms -> Erreur timeout ;sinon valeur de tmp cp XL,timeL ; Compare low byte ; 1 cy cpc XH,timeH ; Compare high byte ; 1 cy brsh fin_expectPulseLOW ; >timeout false (1 cycle)/true (2cycles) rjmp bc_expectPulseLOW ;jump if not zero (2 cycles) fin_expectPulseLOW: pop A pop timeH pop timeL ret ; (4 cycles) expectPulseHIGH: ;compte le temps ou SDA et à 1 clr XL ;(1 cycle) x=0 clr XH ;count ;(1 cycle) push timeL push timeH push A ldi A,HIGH(timeout) mov timeH,A ldi A,LOW(timeout) mov timeL,A bc_expectPulseHIGH: sbis PINB,bSDA ; if SDA set, skip increment rjmp fin_expectPulseHIGH adiw XH:XL, 1 ; x++ (2 cycles) 9cycles par boucles ;compare tmp avec 1ms ;si tmp>1ms -> Erreur timeout ;sinon valeur de tmp cp XL,timeL ; Compare low byte ; 1 cy cpc XH,timeH ; Compare high byte ; 1 cy brsh fin_expectPulseHIGH ; >timeout false (1 cycle)/true (2cycles) rjmp bc_expectPulseHIGH fin_expectPulseHIGH: pop A pop timeH pop timeL ret
MQ2
Ce capteur est conçu pour détecter le LPG, i-butane, propane, méthane ,alcool, hydrogene et la fumée.
Il a une grande sensibilité et un temps de réponse rapide. Sa sensibilité peut d'ailleurs être ajustée par potentiomètre.
Le MQ2 doit être alimenté en 5V pour le capteur physico-chimique puisse atteindre sa température de fonctionnement. Il faut par ailleurs attendre 24 heures de préchauffage pour améliorer la précision des mesures.
Il dispose d’une sortie analogique et d’un réglage de la sensibilité par potentiomètre.
Consommation <800mW soit environ 160mA.
Attention : le MQ2 ne peut être utilisé que pour des expérimentations et pas pour des dispositifs de sécurité car il n’est pas homologué pour cela.
Cependant, je l'utilise pour mon système qui de toutes façons ne sera pas homologué.Principe de lecture du capteur
RS/Ro log101,6=0,2 log100,26=−0.6 | PPM log10200=2,3 log1010000=4 | |
Pente de la droite : XB−XAYB−YA=−0,6−0,24−2,3=−0,81,7=−0,24 pente = -0,47 = \dfrac{log_{10} (RS/R0) – 0,2}{ log_{10}(ppm) -2.3} donc log_{10} (ppm) = 2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47} soit ppm = 10^{2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47}} | ||
RS/Ro log_{10}5=0,2 log_{10}1,5=-0.6 | PPM log_{10}200=2,3 log_{10}10000=4 | |
Pente de la droite : \dfrac{X_B-X_A}{Y_B-Y_A}=\dfrac{-0,6-0,2}{4-2,3}=\dfrac{-0,8}{1,7}=-0,47 pente = -0,47 = \dfrac{log_{10} (RS/R0) – 0,2}{ log_{10}(ppm) -2.3} donc log_{10} (ppm) = 2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47} soit ppm = 10^{2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47}} | ||
RS/Ro log_{10}1,6=0,2 log_{10}0,26=-0.6 | PPM log_{10}200=2,3 log_{10}10000=4 | |
Pente de la droite : \dfrac{X_B-X_A}{Y_B-Y_A}=\dfrac{-0,6-0,2}{4-2,3}=\dfrac{-0,8}{1,7}=-0,47 pente = -0,47 = \dfrac{log_{10} (RS/R0) – 0,2}{ log_{10}(ppm) -2.3} donc log_{10} (ppm) = 2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47} soit ppm = 10^{2,3 + \dfrac{log_{10} (RS/R0) – 0,2}{–0,47}} |
Le programme qui vas me permettre de convertir les données sur le maitre, étalonner le capteur, récupérer R_0,…
/*******************Demo for MQ-2 Gas Sensor Module V1.0***************************** Support: Tiequan Shao: support[at]sandboxelectronics.com Lisence: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) Note: Ce morceau de code source est censé être utilisé comme démonstration UNIQUEMENT. Un étalonnage plus sophistiqué est requis pour les applications industrielles. Sandbox Electronics 2011-04-25 ************************************************************************************/ /************************Hardware Related Macros************************************/ #define MQ_PIN (0) //définir le canal d'entrée analogique que vous allez utiliser #define RL_VALUE (5) //définir la résistance de charge sur la carte, en kilo ohms #define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR = (résistance du capteur en air propre) / RO, //dérivée du tableau de la fiche technique /***********************Software Related Macros************************************/ #define CALIBARAION_SAMPLE_TIMES (50) //définir combien d'échantillons vous allez prendre dans la phase d'étalonnage #define CALIBRATION_SAMPLE_INTERVAL (500) //définir l'intervalle de temps (en milliseconde) entre chaque échantillon dans la phase de cablibration #define READ_SAMPLE_INTERVAL (50) //définir combien d'échantillons vous allez prendre en fonctionnement normal #define READ_SAMPLE_TIMES (5) //définir l'intervalle de temps (en milliseconde) entre chaque échantillon en fonctionnement normal /**********************Application Related Macros**********************************/ #define GAS_LPG (0) #define GAS_CO (1) #define GAS_SMOKE (2) /*****************************Globals***********************************************/ float LPGCurve[3] = {2.3,0.21,-0.47}; //deux points sont pris de la courbe avec ces deux points, //une ligne est formée qui est "approximativement équivalente" à la courbe originale. //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59) float COCurve[3] = {2.3,0.72,-0.34}; //deux points sont pris de la courbe avec ces deux points, //une ligne est formée qui est "approximativement équivalente" à la courbe originale. //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15) float SmokeCurve[3] ={2.3,0.53,-0.44}; //deux points sont pris de la courbe avec ces deux points, //une ligne est formée qui est "approximativement équivalente" à la courbe originale. //data format:{ x, y, slope}; point1: (lg200, 0.53), point2: (lg10000, -0.22) float Ro = 10; //Ro est initialisé à 10 kilo ohms void setup() { Serial.begin(9600); //UART setup, baudrate = 9600bps Serial.print("Calibrating...\n"); Ro = MQCalibration(MQ_PIN); //Calibrage du capteur. //Assurez-vous que le capteur est à l’air pur lorsque vous effectuez l’étalonnage Serial.print("Calibration is done...\n"); Serial.print("Ro="); Serial.print(Ro); Serial.print("kohm"); Serial.print("\n"); } void loop() { Serial.print("LPG:"); Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) ); Serial.print( "ppm" ); Serial.print(" "); Serial.print("CO:"); Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) ); Serial.print( "ppm" ); Serial.print(" "); Serial.print("SMOKE:"); Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) ); Serial.print( "ppm" ); Serial.print("\n"); delay(200); } /****************** MQResistanceCalculation **************************************** Input: raw_adc - valeur brute lue à partir de adc, qui représente la tension Output: la résistance du capteur calculée Remarks: Le capteur et la résistance de charge forment un diviseur de tension. Compte tenu de la tension aux bornes de la résistance de charge et de sa résistance, la résistance du capteur pourrait être déduite. ************************************************************************************/ float MQResistanceCalculation(int raw_adc) { return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); } /***************************** MQCalibration **************************************** Input: mq_pin - canal analogique Output: Ro du capteur Remarks: Cette fonction suppose que le capteur est à l'air pur. Il utilise MQResistanceCalculation pour calculer la résistance du capteur à l'air pur et la divise ensuite avec RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR est d'environ 10, ce qui diffère légèrement entre les différents capteurs. ************************************************************************************/ float MQCalibration(int mq_pin) { int i; float val=0; for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //prendre plusieurs échantillons val += MQResistanceCalculation(analogRead(mq_pin)); delay(CALIBRATION_SAMPLE_INTERVAL); } val = val/CALIBARAION_SAMPLE_TIMES; //calculer la valeur moyenne val = val/RO_CLEAN_AIR_FACTOR; //divisé par RO_CLEAN_AIR_FACTOR //donne le Ro selon le tableau de la fiche technique return val; } /***************************** MQRead ********************************************* Input: mq_pin - analog channel Output: Rs du capteur Remarks: Cette fonction utilise MQResistanceCalculation pour calculer la résistance du capteur (Rs). Le Rs change à mesure que le capteur se trouve dans la concentration différente du gaz cible. Les temps d'échantillonnage et l'intervalle de temps entre les échantillons peuvent être configurés en modifiant la définition des macros. ************************************************************************************/ float MQRead(int mq_pin) { int i; float rs=0; for (i=0;i<READ_SAMPLE_TIMES;i++) { rs += MQResistanceCalculation(analogRead(mq_pin)); delay(READ_SAMPLE_INTERVAL); } rs = rs/READ_SAMPLE_TIMES; return rs; } /***************************** MQGetGasPercentage ********************************** Input: rs_ro_ratio - Rs divisé par Ro gas_id - type de gaz cible Output: ppm du gaz cible Remarks: Cette fonction transmet différentes courbes à la fonction MQGetPercentage qui calcule les ppm (parties par million) du gaz cible. ************************************************************************************/ int MQGetGasPercentage(float rs_ro_ratio, int gas_id) { if ( gas_id == GAS_LPG ) { return MQGetPercentage(rs_ro_ratio,LPGCurve); } else if ( gas_id == GAS_CO ) { return MQGetPercentage(rs_ro_ratio,COCurve); } else if ( gas_id == GAS_SMOKE ) { return MQGetPercentage(rs_ro_ratio,SmokeCurve); } return 0; } /***************************** MQGetPercentage ********************************** Input: rs_ro_ratio - Rs divisé par Ro pcurve - pointeur sur la courbe du gaz cible Output: ppm du gaz cible Remarks: En utilisant la pente et un point de la ligne. Le x (valeur logarithmique de ppm) de la ligne pourrait être dérivé si y (rs_ro_ratio) est fourni. Comme il s'agit d'une coordonnée logarithmique, la puissance de 10 est utilisée pour convertir le résultat en valeur non logarithmique ************************************************************************************/ int MQGetPercentage(float rs_ro_ratio, float *pcurve) { return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0]))); }
10^{\dfrac{log_{10}(Ro)-pt_1}{pt_2}+pt_0}
HC SR501 PIR Analogique
- Capteur de type HC SR501
- Tension de fonctionnement : 5V à 20V continu (DC).
- Consommation statique de 65 micro Ampères
- Niveaux de sortie : High 3.3 V, Low 0 V.
- Temps de délai ajustable de 0.3 secondes à 18 secondes.
- Temps mort 0.2 secondes.
- Déclenchement : L sans répétition , H répétition possible, valeur H par défaut.
- Portée de détection : angle de moins de 120°, 7 mètres.
- Température de fonctionnement de -15°C à +70 °C.
- Dimensions du PCB 32x24 mm
- Ecart entre les trous de 28mm, diamètre de vis du capteur de 2 mm
- Capteur de 23 mm de diamètre.
init_PIR: cbi DDRB,PIR ;Broche en entrée, attendre 30s pour initialisation, ldi A,29 ;30s rcall waitseconds ret load_PIR: sbis PINB,PIR ;skip si PIR haut rjmp PIRLOW PIRHIGHT: cp pirState,zero brne endloadPIR inc pirState rjmp PIRHIGHTLOW PIRLOW: cp pirState,zero breq endloadPIR clr pirState PIRHIGHTLOW: st Y+,pirState ldi A,200 ;200ms rcall WaitMiliseconds endloadPIR: ret
BUZZER Actif
Material: ABS
Color: Black
Rated Current (MAX): 30 mA
Min Sound Output at 10cm: 85 dB
Resonant Frequency: 2300±300 Hz
Operating Temperature: -27°C ~ +70°C
Storage Temperature: -30°C ~ +105°C
Weight : 2g
DS3231 AT24C32 I²c
- DS3231 AT24C32 Module I2C precision Horloge en temps reel
- DS3231 : 0xC0
- Générateur d'horloge en temps réel, minutes, heures, jour, date, mois et année, et valable jusqu'à l'an 2100
- Alimentation: 3,3 à 5,5 Vcc
- Réveil calendrier avec deux sortie d'onde carrée programmable
- Le capteur de température précision de ± 3° C
- mémoire: AT24C32 (capacité de stockage 32kbits soit 8koctets) 0x57
- Communication : I2C maximale de 400KHz
- Adresse modifiable, par défaut est 0x57
- Dimensions: 38 x 22 x 14mm
- Masse : 8 g
Lecteur micro SD SPI
Stockage des données sur le maitre
Les valeurs de MQ-2
Elles vont être décomposées par calcul en fonction de R_o en 3 valeurs GPL,CO, fumées sur 16 bits puis stockées.Et enfin comparé au valeur admissible (A définir).
La valeur de AM2320
Les valeurs de température et hygrométrie sur 16 bits vont être stockées.Et enfin comparé au valeur admissible (A définir).
La valeur du PIR
Juste mémorisétable de stockage maitre
Adresse | Donnée |
---|---|
0x00 | NO TinyAL + bit haut PIR |
0x01 | MQ-2 - GPL (High byte) |
0x02 | MQ-2 - GPL (Low byte) |
0x03 | MQ-2 - CO (High byte) |
0x04 | MQ-2 - CO (Low byte) |
0x05 | MQ-2 - fumées (High byte) |
0x06 | MQ-2 - fumées (Low byte) |
0x07 | AM2320 - Humidité (High bytes) |
0x08 | AM2320 - Humidité (Low byte) |
0x09 | AM2320 - température (High bytes) |
0x0A | AM2320 - température (Low byte) |
0x0B | Heure du jour |
0x0C | Minute du jour |
La sauvegarde se fera toute les 30s dans un premier temps sur l'EEPROM de l'AT24C32
Durant 1h cela représente 120 sauvegardes soit 7800 octets sur un EEPROM de 8ko.
Ensuite, toute les heures la sauvegarde s'effectuera de l'EEPROM vers une carte micro SD de 16Go
Une carte SD formater en FAT32!!!
Un fichier à chaque fin d'une heure nommé YYMMJJHH.TAL, donc avec Année, mois, jour, heure précédente
avec une fichier qui aura une taille en fonction de la taille des clusters soit 8192 octets.
Ce qui vas représenté un maximum d'environs 2097152 heures soit 12483 semaines, ou 240.1 années , ce qui est plus que correct, mais sans utilité.
Il faudrait par contre qu'à partir du moment ou une alarme se déclenche, les données soient sauvegardées.
Si je me base sur une semaine de sauvegarde, j'ai besoin de 1279.6875 ko
Le DS3231 permettra de sauvegarder à heure fixe.