Pages: [1]   Go Down
Author Topic: Integrer Horloge DS1307 à mon sketch  (Read 914 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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
Logged

Ales
Offline Offline
Faraday Member
**
Karma: 29
Posts: 3193
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

un DS1307 c'est en i2c, pas en onewire
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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
Logged

Ales
Offline Offline
Faraday Member
**
Karma: 29
Posts: 3193
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 (...)
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Ales
Offline Offline
Faraday Member
**
Karma: 29
Posts: 3193
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...
Logged

Ales
Offline Offline
Faraday Member
**
Karma: 29
Posts: 3193
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 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:
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 !
Logged


France S-O ou exil en IDF
Offline Offline
Edison Member
*
Karma: 25
Posts: 1904
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

« Last Edit: January 30, 2013, 09:46:18 am by 68tjs » Logged

France
Offline Offline
Faraday Member
**
Karma: 52
Posts: 5341
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

France S-O ou exil en IDF
Offline Offline
Edison Member
*
Karma: 25
Posts: 1904
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: