Go Down

Topic: Integrer Horloge DS1307 à mon sketch (Read 1 time) previous topic - next topic

zebula

Salut à tous
Voila je viens de recevoir mon tiny RTC, j'utilise pour le moment un arduino nano avec divers capteurs, j'ai pu faire fonctionner l'horloge mais IMPOSSIBLE d' avoir l'heure ET la date...

Voici mon sketch, si quelqu'un peut m'aider à integrer l'heure et date sur mon LCD c'est pas de refus.
J'ai fouillé partout sur le net et à chaque fois il y a un truc qui va pas (comme la mise en memoire de la date en cas de coupure d'alim)

Code: [Select]
#define DHTPIN 3  // sonde dht (t/rh)
#define DHTTYPE DHT22 //#define DHTTYPE DHT11 (capteur DHT11)
#include <OneWire.h>   //capteur t
#include <LiquidCrystal.h>  //lcd
#include <DHT.h>            //capteur dht
DHT dht(DHTPIN, DHTTYPE);

float h = 0;
float t = 0;

OneWire  ds(4);  //capteur t
LiquidCrystal lcd(5, 6, 7, 8, 9, 10, 11);
int backLight = 12;    // pin 13 will control the backlight


void setup(void) {
  Serial.begin(9600);   //capteur t
  dht.begin();          //capteur dht
   pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on.
  lcd.begin(20,4);              // columns, rows. 
 


}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
 
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
 
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
 
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  lcd.begin(20,4);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
  lcd.print("Heure Date");    // change this text to whatever you like. keep it clean.
  lcd.setCursor(0,1);           // set cursor to column 0, row 1
  lcd.print(t = dht.readTemperature());
  lcd.setCursor(6,1);         // set cursor to column 0, row 3
  lcd.print("*C");
  lcd.setCursor(0,2);         // set cursor to column 0, row 2
  lcd.print(h = dht.readHumidity());
  lcd.setCursor(6,2);         // set cursor to column 0, row 3
  lcd.print("%RH");
  lcd.setCursor(0,3);         // set cursor to column 0, row 3
  lcd.print(celsius = (float)raw / 16.0);
  lcd.setCursor(6,3);         // set cursor to column 0, row 3
  lcd.print("*C");
  lcd.setCursor(12,3);         // set cursor to column 0, row 3
  lcd.print("temp ext");
 
  h = dht.readHumidity();
    t = dht.readTemperature();
    if (isnan(t) || isnan(h)){
        Serial.println( "Lecture impossible !");
    }else{
        Serial.print("Humidite :");
        Serial.print(h);
        Serial.print(" %\t");
        Serial.print("Temperature :");
        Serial.print(t);
        Serial.println(" *C");
    }
    delay(5000);
}


Merci d'avance

B@tto

un DS1307 c'est en i2c, pas en onewire
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

zebula

Salut, oui je sais, le code correspondant à l'horloge n'est pas dans le code que j'ai inscrit, c' est pour ca.

Voila mon code actuel :
Code: [Select]
#define DHTPIN 3  // sonde dht (t/rh)
#define DHTTYPE DHT22 //#define DHTTYPE DHT11 (capteur DHT11)
#include <OneWire.h>   //capteur t
#include <LiquidCrystal.h>  //lcd
#include <DHT.h>            //capteur dht
#include "RTClib.h"
#include <Wire.h>
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;
float h = 0;
float t = 0;

OneWire  ds(4);  //capteur t
LiquidCrystal lcd(5, 6, 7, 8, 9, 10, 11);
int backLight = 12;    // pin 13 will control the backlight


void setup(void) {
  Serial.begin(9600);   //capteur t
  dht.begin();          //capteur dht
   pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on.
  lcd.begin(20,4); 
  Wire.begin(); 
  RTC.begin();
 
if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));

}
}
void loop(void) {
  DateTime now = RTC.now();
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
 
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
 
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  }
  {Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
 
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  lcd.begin(20,4);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
  lcd.print(now.day(), DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.year(), DEC);
lcd.print(' ');
    lcd.print(now.hour(), DEC);
    lcd.print(':');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    lcd.print(now.second(), DEC);
  lcd.setCursor(0,1);           // set cursor to column 0, row 1
  lcd.print(t = dht.readTemperature());
  lcd.setCursor(6,1);         // set cursor to column 0, row 3
  lcd.print("*C");
  lcd.setCursor(0,2);         // set cursor to column 0, row 2
  lcd.print(h = dht.readHumidity());
  lcd.setCursor(6,2);         // set cursor to column 0, row 3
  lcd.print("%RH");
  lcd.setCursor(0,3);         // set cursor to column 0, row 3
  lcd.print(celsius = (float)raw / 16.0);
  lcd.setCursor(6,3);         // set cursor to column 0, row 3
  lcd.print("*C");
  lcd.setCursor(12,3);         // set cursor to column 0, row 3
  lcd.print("temp ext");
 
  h = dht.readHumidity();
    t = dht.readTemperature();
    if (isnan(t) || isnan(h)){
        Serial.println( "Lecture impossible !");
    }else{
        Serial.print("Humidite :");
        Serial.print(h);
        Serial.print(" %\t");
        Serial.print("Temperature :");
        Serial.print(t);
        Serial.println(" *C");
    }
    delay(1000);
}


Pour l'instant je n'arrive pas à comprendre pourquoi les secondes se rafraichissent toutes les 4 secondes.
Et comment passer au niveaux des chiffres de 1 à 01 par exemple 01/01/2013 et pas 1/1/2013

B@tto

Du coup est-ce que tu peux nous décrire exactement tes bugs, parce que entre ton premier post et le second on en est pas au même point !
Y'a que les secondes qui foirent ou bien la date complète ?

Sinon pour les "01" il suffit de faire un Serial.print("0") si ton nombre est inférieur à 10 ;)
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

zebula

En fait le probleme est que les secondes se rafraichissent toutes les 4 secondes alors que j'avais indiqué delay(1000)

Et le second probleme c'est pour les nombres inférieurs à 10.
Serial.print("0") ne vas pas juste afficher le nombre 0 dans le mode moniteur serie? Je sais pas comment placer if (...)

john_lenfr

Adapte ceci:

Quote
// starting sending paquet
   if (now.date ()< 10) //si le Jour inferieur à 10 alors
   { Serial.print('0'); } //afficher un 0
   Serial.print(now.date(), DEC);
   Serial.print('/');
   if (now.month ()< 10) //si le mois inferieur à 10 alors
   { Serial.print('0'); } //afficher un 0
   Serial.print(now.month(), DEC);
   Serial.print('/');
   Serial.print(now.year(), DEC);
   Serial.print(';');
   if (now.hour ()< 10) //si le heure inferieur à 10 alors
   { Serial.print('0'); } //afficher un 0
   Serial.print(now.hour(), DEC);
   Serial.print('h');
   if (now.minute ()< 10) //si le minutes inferieur à 10 alors
   { Serial.print('0'); } //afficher un 0
   Serial.print(now.minute(), DEC);
   Serial.print('m');
   if (now.second ()< 10) //si le sec inferieur à 10 alors
   { Serial.print('0'); } //afficher un 0
   Serial.print(now.second(), DEC);
   Serial.print("s");
   Serial.print(";");
   Serial.print(temp);
   Serial.print(";");
   Serial.println();
   // Ending sending paquet

B@tto

Ah ok donc ce n'est pas un problème d'heure mais de rafraichissement ? Tu as a bien la bonne heure mais elle ne se mets à jour dans le moniteur série que toutes les 4 secondes ?

Deja dans ton code il y a deux fois delay(1000) donc déjà une fois toutes les deux secondes. Après il y a pas mal de ligne, peut-être un ralentissement quelque part. Dans tous les cas je te conseille plus d'utiliser ta RTC plutot que des delay() :

Code: [Select]

DateTime now = RTC.now();
while(now.second()<=PreviousSecond) DateTime now = RTC.now() // bloque tant qu'une seconde ne s'est pas écoulée
PreviousSecond=now.second(); // stock la valeur pour le prochain test
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

zebula

Merci j'ai pu comprendre comment faire "un if" donc niveau date heure c'est reglé.
Sinon je sais pas comment reduire au maximum mon code...

B@tto

Il vaut mieux déjà, pour plus de lisibilité, utiliser des fonctions. Par exemple plutot que d'enchainer toutes les lignes, tu fais quelque chose comme :

Code: [Select]

void loop(){
MesureTemperature();
MAJLCD();
EnvoiSerie();
}


Après il vaut mettre ses déclarations de variable avant le setup. Enfin il y a des parties qui, à mon avis, n'ont pas leur place dans la loop, je pense à ce qui touche le onewire : je suis pas familier de ce protocole mais à la lecture du code, certain passage concerne la détection du capteur sur le reseau. Je vois plus ça dans le setup, tu vas pas modifier le montage en cours de route !
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

68tjs

#9
Jan 30, 2013, 03:30 pm Last Edit: Jan 30, 2013, 03:46 pm by 68tjs Reason: 1
La base :
setup() et loop() sont deux fonctions particulières mais il peut y en avoir autant que tu le veut.

Pour un micro-controleur il faut une boucle qui ne s'arrête jamais sinon le micro s'arrête : (Paroles de micro -> j'ai fais ce qu'on m'a dis, très bien maintenant dodo jusqu'à qu'on me fasse un "reset".
Avec la fonction loop() il ne peut jamais s'arréter, tant pis pour sa sieste.
C'est dans loop() qu'on écrit le programme proprement dit.

Avant d'exécuter loop() il y a des initialisations à faire.
Comme une initialisation ne se fait qu'une seule fois (comme l'a dit @B@to tu ne modifie pas ton câblage en cours de programme) on les fait dans la fonction setup() qui n'est exécutée qu'une seule fois.

Il se peut que tu ais besoin de variables globales il faut les déclarer avant les fonctions.

Toute nouvelle fonction doit être déclarée en tête de programme on parle de prototype de fonction.
L'IDE arduino s'attend à voir les deux fonctions setup() et loop() il n'y a rien à faire pour elles mais comme il ne s'attend pas aux tiennes il faut l'aider.
Le mieux est que tu consulte le "site du zéro" (déveloper en C : fonctions: partie 1 chapitre 9 et prototypes de fonction : partie 2 chapitre 1) c'est bien mieux expliqué que je ne pourrais le faire  :smiley-mr-green:.

On peut appeller autant de fonctions que l'on veut à partir soit de setup() soit de loop().
Comme je suis un peu feignant je m'arrange pour que le code d'une fonction ne dépasse jamais plus de 2 pages écran (une seule c'est encore mieux). Cela fait moins mal aux neurones quand il faut trouver des erreurs.


skywodd


L'IDE arduino s'attend à voir les deux fonctions setup() et loop() il n'y a rien à faire pour elles mais comme il ne s'attend pas aux tiennes il faut l'aider.

En fait l'ide cherche tout les prototypes de fonction autre que setup() et loop() pour les définir en "haut" du programme final.
Mais ça n'empêche pas qu'il faut déclarer le corps de la fonction quelque par dans le sketch.
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

68tjs

Quote
En fait l'ide cherche tout les prototypes de fonction autre que setup() et loop() pour les définir en "haut" du programme final

Je ne le savais pas.
Mais autant prendre tout de suite les bonnes habitudes si un jour il nous prenait le courage de comprendre comment on écrit un makefile  :smiley-mr-green:

Go Up