datalogger autonome

Un log shield sur carte SD avec horloge RTC et zone de prototypage à pastilles carrées

datalogger autonome

Message non lude xanadu » Mar 8 Oct 2013 21:34

Bonsoir,
j'essaye de créer un data logger (enregistreur de données) autonome, fonctionnant sur batteries, qui enregistre les données horodatées d'un capteur sur une carte SD.
Je travaille à partir d'un arduino uno + le shield mémoire Snootlab (livraison rapide, produit au top ! ;) ).
La batterie est pour le moment une pile de 9V branchée sur l'alim DC de l'arduino.
J'ai réalisé le montage et développé le code (ça fonctionne :) ) mais je n'arrive pas à obtenir une durée de vie des batteries satisfaisante... :( (en test je fais une mesure toutes les 2 minutes, en routine je prévois une mesure toute les heures, la durée de vie souhaitée est de quelques mois)
j'ai intégré une routine pour endormir l'arduino mais cela ne marche pas ...
Code: Tout sélectionner
void sleepytime()                  // based on Narcoleptic library routine
{
    ADCSRA = 0;                              // disable ADC

  for(byte i=1; i<=sleepint; i++)            // loop through several times
  {
    Narcoleptic.delay(8000);                 // maximium sleep for ATmega328 is 8 sec
  } 
  ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);     // set prescaler to 128 and enable ADC
}


une idée pour optimiser la durée de vie des batteries ???
peut-on couper l'alimentation du shield mémoire entre 2 mesures ?
comment éteindre la led d'alimentation de l'arduino uno ?
merci pour toute suggestion !!!
xanadu
 
Messages: 4
Inscription: Mar 8 Oct 2013 21:22

Re: datalogger autonome

Message non lude xanadu » Jeu 10 Oct 2013 09:11

est-ce que le shield mémoire peut fontionner sous 3.3 V ?
xanadu
 
Messages: 4
Inscription: Mar 8 Oct 2013 21:22

Re: datalogger autonome

Message non lude xanadu » Ven 11 Oct 2013 08:19

pour info, je poursuis mes tests.
j'ai essayé de brancher l'alim 5 v du shield mémoire sur un pin pour pouvoir couper l'alimentation du shield entre 2 mesures, histoire d'économiser de la batterie...cela génère quelques problèmes :
1. j'ai l'erreur suivante quand j'essaye de télécharger dans l'arduino le sketch : avrdude: stk500_getsync(): not in sync: resp=0x00
2. en modifiant le circuit après le téléchargement du sketch, j'arrive à enregistrer la première mesure dans la carte SD mais pas les suivantes...
xanadu
 
Messages: 4
Inscription: Mar 8 Oct 2013 21:22

Re: datalogger autonome

Message non lude xanadu » Mar 3 Déc 2013 11:10

dommage que je sois obligé de faire les questions et les réponses sur ce forum...
pour ceux qui malgré tout serait intéressé par le sujet, je vous donne les dernières infos :

après quelques recherches, j'en ai conclu que le shield mémoire n'est pas adapté à une utilisation sur batteries. en effet, même en programmant en mode sleep, la consommation résiduelle reste trop élevée pour espérer une durée de vie supérieure à une dizaine de jour.
il faut REPENSER le shield en utilisant une horloge de type DS1337S+, sur laquelle une alarme est programmable. Reliée à un MOSFET elle permettra de couper complétement l'alimentation de l'arduino entre 2 mesures, à un pas de temps décidé par l'utilisateur. L'alarme ouvre l'alimentation, l'arduino se lance, fait la mesure et la stocke dans une carte SD, puis l'alimentation est de nouveau coupée.
bref, j'invite Snootlab à proposer un shield avec ce principe de fonctionnement pour les applications demandant une autonomie importante, cas pour lesquels je DECONSEILLE l'utilisation du shield mémoire de snootlab.
xanadu
 
Messages: 4
Inscription: Mar 8 Oct 2013 21:22

Re: datalogger autonome

Message non lude fred » Mar 31 Déc 2013 17:20

En effet, le shield n'est pas pensé pour une utilisation basse consommation (ne serait-ce que du fait de la présence de la Led power toujours allumée). La prochaine version Mémoire 2.0 (qui arrive début 2014) permet entre-autre de débrancher la Led ou de l'affecter à une pin et donc d'être "utilisable".

Comme on aime bien le Sablier qui dispose de cette fonctionnalité, on aura aussi une version de Mémoire 2.0 avec le DS3231 monté.

Les utilisations basse consommation de l'Arduino nécessitent de reprendre pas mal de code. C'est au programme dans le cadre des développements que l'on fait en ce moment pour Akeru

A suivre donc.
Avatar de l’utilisateur
fred
 
Messages: 216
Inscription: Lun 20 Déc 2010 15:32
Localisation: Toulouse

Re: datalogger autonome

Message non lude EricDuino » Mar 31 Déc 2013 23:34

OUI mais NON :D

Pour calculer la durée d'alimentation avec une réserve, il suffit de connaitre ou mesurer sa conso instantanée ou moyenne puis connaitre ou estimer sa réserve et une petite règle de 3 plus tard on estime la durée, on confirme ensuite par l’expérimentation :!:

C'est sur que vouloir tenir 3 semaines et expérimenter avec une réserve branchée sur une alim régulée avec un rendement de 60% pour 8 heures c'est déroutant...

Le problème est situé entre le montage et la chaise :!:

Adios 2013...
Avatar de l’utilisateur
EricDuino
 
Messages: 233
Inscription: Sam 5 Mai 2012 10:10
Localisation: Toulouse

Re: datalogger autonome

Message non lude Vince » Lun 12 Jan 2015 20:09

Bonjour,
Je viens de terminer un datalogger avec un UNO, un shield SD+RTC, un shield LCD keypad et une sonde de température DS18B20.
Ça consomme 30 mA en veille et 110mA lorsque l'affichage s'allume pendant 15 secondes à chaque écriture sur la carte SD.
Ça prend un point horodaté avec un échantillonnage entre 1mn et 1heure ce que l'on choisit par navigation avec les boutons du Keypad shield. Autre fonction, ça donne la température la plus haute et la plus basse avec l'horodatage associé. Le fichier créé sur la carte SD est un .CSV directement utilisable pour faire un graphique Excel car la date est au format 01/01/2015, l'heure au format 01:05 avec les zéros ajoutés et la température avec une virgule et pas un point.
Pour les shields, il n'y a que quelques modif mineures : le retrait des led rouges sur le UNO et le shield (RTC + SD) ; j'ai laissé celle sur le shield du dessus (le LCD) pour voir quand le circuit tourne. Autre modif : la coupure de la piste qui fait le lien entre le CS et la D10 sur le shield RTC+ SD. Effet D10 sert déjà au rétro éclairage du LCD, j'ai donc rerouté le CS en D3, c'est fait pour.
Pour la sonde de température, elle entre en D2 par un bus spécifique relié au plus 5V par une résistance d'environ 5kohm. Pour le câblage de la sonde, les fils de couleur ne veulent rien dire et il faut rechercher le moins par la fonction test diode du multimètre : la seule patte qui affiche quelque chose avec le plus (rouge) du multimètre dessus et le moins (noir) du multimètre sur les 2 autres fils (pas en même temps bien sûr) est le 0V (ici, sur ma sonde, c'est le fil jaune !). Ensuite avec le code couleur on retrouve le +5V (plutôt le rouge) et le dernier fil est le data...(le vert sur ma sonde).

Le code est dispo, je peux le mettre sur ce forum s'il vous intéresse (et que quelqu'un veut bien m'expliquer comment insérer la jolie fenêtre avec ascenseur sur le code).
Vincent
Fichiers joints
DSC03760.JPG
lien entre CS et D10 coupé. Pont entre CS et D3.
DSC03760.JPG (147.92 Kio) Vu 6518 fois
Vince
 
Messages: 22
Inscription: Sam 27 Déc 2014 11:25

Re: datalogger autonome

Message non lude Vince » Lun 12 Jan 2015 20:19

Quelques photos supplémentaires :
Fichiers joints
DSC03754.JPG
Lien entre CS et la patte D10 coupé au niveau du départ vers D10 sur le RTC/SD shield
DSC03754.JPG (105.26 Kio) Vu 6518 fois
DSC03753.JPG
SD + RTC datalogger, seul shield modifié (hormis le retrait de la led Power du UNO)
DSC03753.JPG (122.65 Kio) Vu 6518 fois
DSC03752.JPG
Vu générale
DSC03752.JPG (118.62 Kio) Vu 6518 fois
Vince
 
Messages: 22
Inscription: Sam 27 Déc 2014 11:25

Re: datalogger autonome

Message non lude Vince » Lun 12 Jan 2015 20:59

Ça y est, j'ai trouvé...

Code: Tout sélectionner
// Appel des bibliothèques
#include <LiquidCrystal.h>    // appelle la librairie pour l'afficheur
#include <Wire.h> // appelle la libriarie pour je en sais plus quoi
#include "RTClib.h" // appelle la librairie pour la fonction heure du RTC
#include <OneWire.h> // Inclusion de la librairie OneWire pour la sonde de température
#include <SPI.h> // librairie pour la gestion de la carte SD
#include <SD.h> // librairie pour la gestion de la carte SD

// définition des variables du débur car je n'aime pas les variables qui trainent partout bien qu'il en reste...
#define BOUTONS A0 // je ne sais pas activer la patte A0 autrement
#define DS18B20 0x28     // Adresse 1-Wire du DS18B20, détectée en chargeant un utilitaire qui la renvoie sur le PC
#define BROCHE_ONEWIRE 2 // Broche utilisée pour le bus 1-Wire


long trigg; // variable qui scrute le cumul des secondes depuis 1970 renvoyé par le module RTC pour déclencher l'echantillonnage
long triggbis = 0; // variable mémoire de trigg pour suivre les évolution et paramétrer l'échantillonnage
long echant ; //périodicité d'échantillonnage du moment (évolutif) en secondes
long echant1 = 3600; //périodicité d'échantillonnage en secondes - 1h
long echant2 = 1800; //périodicité d'échantillonnage en secondes - 30 mn
long echant3 = 600; //périodicité d'échantillonnage en secondes - 10 mn
long echant4 = 300; //périodicité d'échantillonnage en secondes - 5mn
long echant5 = 60; // périodicité d'échantillonnage en secondes - 1mn
const int chipSelect = 3; // recablage du CS (chip select) de la liaison avec la carte SD sur la patte digital  3 au lieu de 10 utilisée par l'afficheur
OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds en intégrant le fait que ça se passe sur la patte 2 définie ci dessus dans les variables
float tempmax = 0 ; // variable d'enregistrement de la tempérarure max, initialisée à 0 pour être sur de la changer à la première boucle
float tempmin = 40 ; // variable d'enregistrement de la tempérarure min, initialisée à 40 pour être sur de la changer à la première boucle
String heuretempmax =""; //enregistrement de l'heure de la temp max
String heuretempmin =""; //enregistrement de l'heure de la temp min
float temp; //température en degré


RTC_DS1307 RTC; // formule toute faite indispensable au lancement de la RTC

int adc_key_val[5] = { // chaines de caractères avec les valeurs ana des boutons sur A0
   30,150,360,535,760};
int NUM_KEYS = 5; // variable de suivi des touches initialisée à 5
int adc_key_in; // variable de suivi des touches
int key=-1; // variable de suivi des touches initialisée à -1
int oldkey=-1; // variable de suivi des touches initialisée à -1
int A=0; // variable interne de suivi des appuis sur les touches pour savoir on en est sur les choix
int B=0; // variable interne de suivi des appuis sur les touches pour savoir on en est sur les choix
int C=0; // variable interne de suivi des appuis sur les touches pour savoir on en est sur les choix
int D ; // variable de collecte des info horaires pour mise en forme de l'affichage
int E ; // compteur d'extinction de l'affichage qui s'incrémente à chaque boucle dans loop et finit par arréter l'afficheur

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  //  définition de l'écran LCD avec le cablage des pattes (RS, Enable, D4, D5, D6, D7)

// FONCTION récupérant la température depuis le DS18B20 - pompée toute faite sur internet. Casse pied à décortiquer car relève de la lecture de messages série.
// Retourne true si tout va bien, ou false en cas d'erreur sur la variable booléan
boolean getTemperature(float *temp){
  byte data[9], addr[8];
  // data : Données lues depuis le scratchpad
  // addr : adresse du module 1-Wire détecté
 
  if (!ds.search(addr)) { // Recherche un module 1-Wire
    ds.reset_search();    // Réinitialise la recherche de module
    return false;         // Retourne une erreur
  }
   
  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
    return false;                        // Si le message est corrompu on retourne une erreur
 
  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
    return false;         // Si ce n'est pas le cas on retourne une erreur
 
  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20
   
  ds.write(0x44, 1);      // On lance une prise de mesure de température
  delay(800);             // Et on attend la fin de la mesure
   
  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20
  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad
 
  for (byte i = 0; i < 9; i++) // On lit le scratchpad
    data[i] = ds.read();       // Et on stock les octets reçus
   
  // Calcul de la température en degré Celsius
  *temp = ((data[1] << 8) | data[0]) * 0.0625;
   
  // Pas d'erreur
  return true;
}
//fin de la fonction de lecture de la température depuis le DS18B20 - pompée toute faite sur internet.


//lancement du setup qui comporte les affichages de lancement
void setup()
{
  lcd.begin(16,2); //initialise l'ecran LCD en 16 caractères 2 lignes
  lcd.clear(); // éfface l'écran
  delay(100); //attends 0.1s
  lcd.setCursor(0,0);    // se place sur la première ligne, 1er caractère qui s'appellent tous deux zéro !                       
  lcd.print("  Surveillance  ");            // affiche le message
  lcd.setCursor(0,1);                       // met le curseur en ligne 2
  lcd.print("   température  ");            // affiche le message
  delay (3000);                             // laisse le message 3 secondes
  lcd.clear();                              // efface l'écran
  lcd.print("               ");            // affiche le nom de l'auteur
  lcd.setCursor(0,1);                       // met le curseur en ligne 2
  lcd.print("30 novembre 2014");            // affiche le message
  delay (3000);                              // laisse le message 3 secondes
  lcd.clear();                              // efface l'écran
  delay(10);                                // attend 0.01s

  //Gestion maintenant de la carte SD
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) { //s'il n'y a pas de retour d'une carte SD présente en activant le CS sur la patte 3 alors
    lcd.setCursor(0,0); // met le curseur en caractère 1 ligne 1
    lcd.print("ERREUR CARTE SD"); // affiche le message
    delay (1000); } else { // attend 1s et sinon
    lcd.setCursor(0,0); // met le curseur en caractère 1 ligne 1
    lcd.print(" CARTE SD OK "); // affiche le message
    delay (3000); // attend 3s
    lcd.clear(); // éfface l'écran
    File dataFile = SD.open("rucheA00.csv", FILE_WRITE); // fonction fondamentale qui crée et ouvre le fichier appelé "rucheA.csv" en écrivant sur la carte SD
    dataFile.println("jour/mois/annee;heure:minute;temp"); // 2eme fonction fondamentale qui écrit la ligne des titres
    dataFile.close(); // fermeture du fichier sur la carte SD
}
Wire.begin(); //activation du bus Wire pour je en sais plus quelle fonction
RTC.begin(); // activation de l'horloge RTC
E = 0 ; // remet à 0 le compteur de boucles pour la gestion de l'affichage
echant=echant1 ; // initialise le taux d'échantillonnage à 1h
A = 4 ; // met en cohérence A avec le taux d'échantillonnage par défaut de 1 h
// RTC.adjust(DateTime(__DATE__, __TIME__)); // ligne tres importante : retirer les // du début pour mise à l'heure de l'horloge RTC à l'heure du PC
}
// fin de la séquence d'initialisation

// début des boucles du programme
void loop()
{
  DateTime now = RTC.now(); //lecture de l'heure
   E = E+1 ; // compteur de boucles
   lcd.setCursor(0,0); // met le curseur en caractère 1 ligne 1
   lcd.print("  /  /       :  "); // Affiche le format de la date/heure
   lcd.setCursor(0,0);// met le curseur en caractère 1 ligne 1
   D = now.day(), DEC; // D devient la valeur du jour non mise en forme
   if (D < 10){ // si D<10, il faut rajouter un zéro devant juste pour l'affichage
   lcd.print("0"); // voila le 0 affiché...
   lcd.setCursor(1,0); // décalage du curseur pour afficher la date
   lcd.print(D);    // affiche la date si < 10
   }
   else { //sinon
   lcd.print(D); // affiche directement la date en position ligen1 curseur 1 si elle est supérieure à 10
   }
   lcd.setCursor(3,0);                // met le curseur en position 4 ligne 1
   D = now.month(), DEC; // pareil pour le mois en utilisant toujours la variable D ce qui permet de faire du copier coller sur l'écriture du programme
   if (D < 10){
   lcd.print("0");
   lcd.setCursor(4,0);
   lcd.print(D);   
   }
   else {
   lcd.print(D);
   }   
   lcd.setCursor(6,0);               
   lcd.print(now.year(), DEC); // pour l'année, comme elle est au format "2014" par de mise en forme nécessaire
   lcd.setCursor(11,0);                 
   D = now.hour(), DEC; // maintenant la variable D s'occupe de l'heure
   if (D < 10){
   lcd.print("0");
   lcd.setCursor(12,0);
   lcd.print(D);   
   }
   else {
   lcd.print(D);
   } 
   lcd.setCursor(14,0);                 
   D = now.minute(), DEC; // et on termine en s'occupant des minutes
   if (D < 10){
   lcd.print("0");
   lcd.setCursor(15,0);
   lcd.print(D);   
   }
   else {
   lcd.print(D);
   } // c'est enfin fini pour afficher la date et l'heure avec des zéros.
   
   if (E > 30){ // compteur pour eteindre la LED du rétroéclairage et le LCD au bout de 30 boucles (environ 15 secondes)
   lcd.noDisplay(); // éteint le LCD
   digitalWrite(10, LOW); //éteint le rétro éclairage
   E = 256 ; // fixe la valeur de E pour éviter à terme un dépassement du compteur en incrémentant tout le temps à chaque boucle
   B = 0 ; // remet à zéro les compteurs de touche pour après
   C = 0 ; // remet à zéro les compteurs de touche pour après
   }
 
   // début de la routine d'affichage de la température
   if(getTemperature(&temp)) { // Lit la température ambiante à ~1Hz dans la fonction déja vue en début de programme et pompée intégrale
   lcd.setCursor(0,1);
   lcd.print(temp); // Affiche la température
   lcd.setCursor(5,1); // place le curseur en 6éme position ligne 2
   lcd.print((char)223); // affiche le caractère ascii °
   lcd.print("C"); // affiche le message C
   } // fin de la routine d'affichage de la température
   
   if (temp > tempmax) { // enregistrement de la température max, si la température lue est sup à la température max archivée alors
     tempmax = temp ; //la nouvelle température max devient la température lue
    heuretempmax =""; //et la chaine de caractère nomée heuretempmax et réduite à 0 caractère par cette fonction ...
    heuretempmax += String(now.day(), DEC); // commence à se remplir du jour
    heuretempmax += " ";// avec un espace
    heuretempmax += String(now.month(), DEC);//suivie du mois
    heuretempmax += " ";//avec un espace
    heuretempmax += String(now.year(), DEC);//suivie de l'année
    heuretempmax += " ";//avec un espace
    heuretempmax += String(now.hour(), DEC);//suivie de l'heure
    heuretempmax += ":";//avec un espace
    heuretempmax += String(now.minute(), DEC);//suivie des minutes
     } // fin de cette collecte de la température max
     
   if (temp < tempmin) {// enregistrement de la température min, si la température lue est inf à la température min archivée alors
    tempmin = temp ;
    heuretempmin ="";
    heuretempmin += String(now.day(), DEC);
    heuretempmin += " ";
    heuretempmin += String(now.month(), DEC);
    heuretempmin += " ";
    heuretempmin += String(now.year(), DEC);
    heuretempmin += " ";
    heuretempmin += String(now.hour(), DEC);
    heuretempmin += ":";
    heuretempmin += String(now.minute(), DEC);
   } // fin de la collecte de la température min
 
 
 // fonction suivante : enregistrement du point daté sur la carte SD
 trigg = (now.unixtime()/echant); //division du compteur des secondes cumulées depuis 1970 par le pas d'échantillonnage
  if ( trigg != triggbis) { //si apres cette division, le nombre a évolué, alors...
  File dataFile = SD.open("rucheA00.csv", FILE_WRITE); // ouvre le fichier rucheA00.csv pour y écrire
  String dataString = ""; // remise à blanc de la chaine de caractères dataString
   
  if (dataFile) {  // si le fichier demandé ci dessus est bien présent, alors
    E= 0 ; // relance le compteur de l'affichage pour ne pas l'arréter à ce moment là
    lcd.display(); // allume le LCD
    digitalWrite(10, HIGH); // allume le rétroéclairage
    lcd.setCursor(0,1); //met le curseur en carcatère 1 ligne 2
    lcd.print("ECRITURE SUR SD"); // affiche le message pour ne pas arréter maintenant la carte SD
    D = now.day(), DEC; // acquisition du jour
    if (D < 10){
    dataString += "0"; // ajout d'un zéro
    dataString += String(D);// ajout du jour sur 1 caractère
    }
    else {
    dataString += String(D);// ajout du jour sur 2 caractères
    }
    dataString += "/";//ajout du /
    D = now.month(), DEC; // acquisition du mois
    if (D < 10){
    dataString += "0"; // ajout d'un zéro
    dataString += String(D);// ajout du mois sur 1 caractère
    }
    else {
    dataString += String(D);// ajout du mois sur 2 caractères
    }
    dataString += "/";//ajout du ;
    D = now.year(), DEC; // acquisition du jour
    if (D < 10){
    dataString += "0"; // ajout d'un zéro
    dataString += String(D);// ajout de l'année sur 1 caractère
    }
    else {
    dataString += String(D);// ajout de l'année sur 2 caractères
    }
    dataString += ";";//ajout du ;
    D = now.hour(), DEC; // on s'occupe des heures
    if (D < 10){
    dataString += "0"; // ajout d'un zéro
    dataString += String(D);// ajout des heures sur 1 caractère
    }
    else {
    dataString += String(D);// ajout des heures sur 2 caractères
    }
    dataString += ":";//ajout du :
    D = now.minute(), DEC; // et on termine en s'occupant des minutes
    if (D < 10){
    dataString += "0"; // ajout d'un zéro
    dataString += String(D);// ajout des minutes sur 1 caractère
    }
    else {
    dataString += String(D);// ajout des minutes sur 2 caractères
    }
    dataString += ";";//ajout du ;
    dataString += String(temp); // ajout de la température
    dataString.replace(".", ",");
       
    dataFile.println(dataString); // envoie de la chaine de caractère en écriture sur le fichier rucheA00.csv de la carte SD
    dataFile.close(); //fermeture du fichier
    triggbis = trigg; //réinitialisation du compteur horaire pour les enregistrements
    delay (1000); // attente 1s
    lcd.clear();// RAZ de l'affichage
  }
  //fin de la procédure d'écriture s'il n'y a pas de problème sinon
  else { // if the file isn't open, pop up an error:
   lcd.setCursor(0,1);
    lcd.print("ERREUR CARTE SD");// affiche le message
    delay (1000);// attente 1s
    lcd.clear(); // RAZ de l'affichage
  }}
// fin complète de la routine d'écriture sur la carte SD

//A partir de là, on gère les boutons et ce qu'on leur attribue comme fonction
adc_key_in=analogRead(BOUTONS); //charge la variable adc_key_in, qui a un nom à coucher dehors, de la lecture analogique sur la patte A0
key=get_key(adc_key_in); // lance la routine en dessous pour dire quelle touche a été enfoncée
if(key !=oldkey) { //si le bouton a changé
 delay(20); //attendre0.02s
 adc_key_in=analogRead(BOUTONS); //refaire une nouvelle acquisition
 key=get_key(adc_key_in); // relance la routine en dessous encore une fois pour dire quelle touche a été enfoncée
 if(key !=oldkey) {//si le bouton a toujours changé
 oldkey=key; //la valeur de oldkey devient le retour de la fonction, entre -1 et 4, ce qui donne le bouton appuyé suffisament longtemps
 if ( key >=0 ){       // programe d'utilisation avec les touches droite=2   haut=1   bas=0   gauche=3    OK=4  rien=-1
  if (key==1){        // si on est sur haut appuyé
  //  Action à faire avec le bouton haut appuyé
   E=0; //RAZ le compteur d'affichage
    lcd.clear(); //efface l'écran
    lcd.setCursor(0,0);                // met le curseur en position 1 ligne 1
    lcd.print(heuretempmax);           // affiche la valeur de la chaine de caractères température max, sans mise en forme 
    lcd.setCursor(0,1);                // met le curseur en position 1 ligne 2
    lcd.print(tempmax);                // affiche la valeur de la température max enregistrée
    lcd.print(" Deg C MAX ");          // message de mise en forme
    delay (5000);                      // attends 5 s
    lcd.clear(); //efface l'écran
  }
  if (key==3){      // si on est sur gauche appuyé
  //  Action à faire avec le bouton gauche appuyé
  E=0;//RAZ le compteur d'affichage
  A = A-1; //décrémente la variable A
  lcd.setCursor(0,1);               // met le curseur en position 1 ligne 2
  lcd.print("ECHANT ");             // affiche le message
  lcd.setCursor(8,1);               // met le curseur en position 9 ligne 2
  if (A <= 0) {    //si la variable A est inférieure ou égale à 0, alors
  A=0; // on confirme A à zéro pour ne pas permettre d'excursion de la valeur
  echant = echant5; //le taux d'échantillonnage devient le 5éme
  lcd.print("1 mn"); //on affiche le message associé soir 1 minute
  }
  if (A == 1) { //si la variable A vaut 1 ...et ainsi de suite 4 fois
  echant = echant4;
  lcd.print("5 mn");
  }
  if (A == 2) {
  echant = echant3;
  lcd.print("10 mn");
  }
  if (A == 3) {
  echant = echant2;
  lcd.print("30 mn");
  }
  if (A >= 4) {//si la variable A est supérieure ou égale à 4, alors
  A=4; // on confirme A à 4 pour ne pas permettre d'excursion de la valeur
  echant = echant1;
  lcd.print("1 h");
  }
  delay (1000); // attente 1 seconde
  lcd.setCursor(0,1);                // met le curseur en position 1 ligne 2
  lcd.print("                ");    // reset l'affichage de la 2éme ligne
  }
  if (key==2){      // si la touche bas est appuyé
    //  Action à faire avec le bouton bas appuyé
    E=0;//RAZ le compteur d'affichage
    lcd.clear();//efface l'écran
    lcd.setCursor(0,0);         // met le curseur en position 1 ligne 1
    lcd.print(heuretempmin);    // affiche la valeur de la chaine de caractères température min, sans mise en forme 
    lcd.setCursor(0,1);        // met le curseur en position 1 ligne 2
    lcd.print(tempmin);       // affiche la valeur de la température min enregistrée
    lcd.print(" Deg C MINI"); // message de mise en forme
    delay (5000);// attends 5 s
    lcd.clear();//efface l'écran
  }
  if (key==0){      //si c'est le bouton droite appuyé
   //  Action à faire avec le bouton droite appuyé
  E=0;//RAZ le compteur d'affichage
  A = A+1; //cette fois ci on incrémente le compteur A
  lcd.setCursor(0,1);                // met le curseur en position 1 ligne 2
  lcd.print("ECHANT ");              // affiche le message 
  lcd.setCursor(8,1);                // met le curseur en position 9 ligne 2
  if (A <= 0) {  //si la variable A est inférieure ou égale à 0, alors
  A=0; // on confirme A à zéro pour ne pas permettre d'excursion de la valeur
  echant = echant5; // déja expliqué au dessus
  lcd.print("1 mn");
  }
  if (A == 1) {
  echant = echant4;
  lcd.print("5 mn");
  }
  if (A == 2) {
  echant = echant3;
  lcd.print("10 mn");
  }
  if (A == 3) {
  echant = echant2;
  lcd.print("30 mn");
  }
  if (A >= 4) {
  A=4;
  echant = echant1;
  lcd.print("1 h");
  }
  delay (1000);
  lcd.setCursor(0,1);                // met le curseur en position 1 ligne 2
  lcd.print("                ");     // reset l'affichage de la 2éme ligne   
  }
 
  if (key==4){       // si c'est le bouton OK appuyé
   //  Action à faire avec le bouton OK appuyé
   E=0;//RAZ le compteur d'affichage
   lcd.display(); // allume le LCD
   digitalWrite(10, HIGH); // allume le rétroéclairage
         
   
}}}} //refermeture de toutes les boucles de if
 
 
} //refermeture de la boucle loop


//fonction de détermination de la touche enfoncée nommée get_key - un peu compliquée à comprendre et reprise du livre de Christian Tavernier
int get_key(unsigned int input){ // fontion get_key qui attend une variable nomée "input" de nature entier non signé (unsigned int)
  int k; // k est une variable du type integer, entier
  for (k=0;k<NUM_KEYS;k++){ //pour k allant de 0 à NUM_KEYS qui vaut 5, ajouter 1 à chaque boucle
    if(input<adc_key_val[k]){ //tant que "input" est inférieur à la valeur renvoyée par la chaine de caractères adc_key_val[k] pour le caractère k
      return k; //renvoyer k, c'est à dire le numéro d'ordre dans la chaine de caractères
    }}
  if (k>=NUM_KEYS){ //si k est plus grand ou égal au nombre de valeurs de la chaine de caractères
  k=-1; //fixe k à la valeur -1 qui veut dire "pas de bouton appuyé"
  }
return k; //renvoyer k, c'est à dire le numéro d'ordre dans la chaine de caractères ou -1 s'il n'y a pas de bouton appuyé
}


Qu'il me soit permis de remercier Maître Christian Tavernier pour le code des boutons. Son ouvrage "Arduino, Maîtrisez sa programmation et ses cartes d'interface (shields)" fût le livre qui me permit d'être capable de programmer ça.
Dernière édition par Vince le Dim 7 Fév 2016 19:07, édité 2 fois.
Vince
 
Messages: 22
Inscription: Sam 27 Déc 2014 11:25

Re: datalogger autonome

Message non lude FSR » Dim 25 Jan 2015 21:46

Bonjour,

Je démarre avec arduino, et je cherche à faire quelque chose de très semblable à toi.
J'ai un arduino Mega 2560R3 et une carte datalogging shield V1.0

Mais je ne comprends pas ... beaucoup de chose.
J'ai installé le soft sans trop de problème.
J'ai installé la libraire RTClib.h et RTClib.cpp dans le répertoire C:\Program Files (x86)\Arduino\libraries\RTClib.
J'ai utiliser le programme ds1307.ino dans le repertoire D:\users\franck\Mes documents\Arduino\perso\module_datalogger\ds1307.ino\ds1307
Je l'ai téléchargé sur l'arduino ce fichier.
Jusque la, tout va bien.

Mais lors de l’exécution j'ai invariablement les erreurs suivantes:

Code: Tout sélectionner
RTC is NOT running!
2165/165/165 165:165:85
 since midnight 1/1/1970 = 2028820689s = 23481d
 now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
 since midnight 1/1/1970 = 2028820689s = 23481d
 now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
 since midnight 1/1/1970 = 2028820689s = 23481d
 now + 7d + 30s: 2034/4/23 17:18:39

2165/165/165 165:165:85
 since midnight 1/1/1970 = 2028820689s = 23481d
 now + 7d + 30s: 2034/4/23 17:18:39

Autrement dit, le temps ne se met pas à l'heure (du PC) et l'heure n'évolue pas!

Si j'ai bien compris tu as modifier ton shield RTC/SD en coupant une piste
Est-ce que je dois faire la même chose?
FSR
 
Messages: 2
Inscription: Dim 25 Jan 2015 21:00

Re: datalogger autonome

Message non lude philippemartorell » Mer 28 Jan 2015 12:16

T'as mis une pile ?

( Je réponds comme n'importe quel assistance à distance qui te demande d'abord si tu a branché ton appareil, mais on sait jamais ...)
philippemartorell
 
Messages: 42
Inscription: Ven 9 Déc 2011 11:37

Re: datalogger autonome

Message non lude Vince » Mer 11 Fév 2015 10:31

Pour FSR,
Il y a une ligne de code dont il faut retirer les // pour que le RTC se mette à l'heure du PC lors d'un des premiers chargements du soft :

// RTC.adjust(DateTime(__DATE__, __TIME__)); // ligne très importante : retirer les // du début pour mise à l'heure de l'horloge RTC à l'heure du PC.
Ensuite si l'heure se met mal en place, il faut recommencer : vider le RTC en retirant la pile bouton et attendre quelques minutes que l'ultra faible conso du RTC vide les capacités. Puis recommencer le premier lancement : pas de soucis à recommencer, y'a pas beaucoup d'usure.

En ce qui concerne la coupure de la piste, cela relève de l'utilisation des broches : si vous avez un LCD keypad shield à empiler sur le RTC shield, il y a conflit pour l'affectation de la broche dite CS sur la broche D10 qui est câblée par défaut sur le RTC shield mais aussi sur le rétroéclairage du LCD : il faut donc alors faire un choix --> pour la simplicité de la chose j'ai choisi de couper la piste pour garder le lien par les broches entre D10 et le rétroéclairage et de réaffecter CS sur une autre broche en le précisant aussi coté logiciel.
Vince
 
Messages: 22
Inscription: Sam 27 Déc 2014 11:25

Re: datalogger autonome

Message non lude drastiquee » Mar 9 Juin 2015 14:49

Pourquoi ça ne marche pas ..


--------------------------
etui sony xperia z4
Housse silicone Sony Xperia Z4
drastiquee
 
Messages: 1
Inscription: Mar 9 Juin 2015 14:39


Retourner vers Mémoire

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron