Pages: [1]   Go Down
Author Topic: Demande d'infos relevé de température avec sauvegarde sur microSD et visu.  (Read 3082 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Je possède une carte Arduino UNO R2 et récemment j'ai acheté une carte shield Ethernet afin de pouvoir faire une station de mesure de température avec des sondes DS18S20 dans une premier temps. J'utilise la version 0022 pour écrire le programme (car la version 1.0 pose problème  smiley-sad-blue)

J'ai commencé à faire un programme pour mesurer la température avec 3 sondes (1-wire), grâce au forum, j'ai pu récupérer les informations nécessaires pour ce programme. Le programme de base mesure trois température toutes les 10 minutes. Nickel.

Grâce au shield Ethernet équipe d'un micro SD, je voudrais pouvoir faire des relevés de température toutes les 10 minutes et les sauvegardes dans un fichiers .txt, le bout de code est créé est fonctionne, mais il faut que je lise la carte SD sur le PC pour voir les valeurs.

J'ai essayé de regrouper le tout, mon besoin est de faire des relevés toutes les 10 minutes avec sauvegarde sur microSD et de pouvoir visualiser les températures dans mon navigateur internet quand je veux, est-ce que c'est possible car je bloque avec le relevé toutes les 10 minutes qui me bloque le demande de visu de température sur Firefox.


Est-ce que quelqu'un peux-me donner son avis ou une autre solution je suis preneur, je bloque dessus depuis 1 semaine.  smiley-twist
Merci
Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

bonjour,
sujet déjà traité il y a peu de temps.

pourquoi ne pas monter un petit server apache  avec mysql?
au lieu d'écrire sur la SD tu fais un GET vers ton server en mettant la valeur relevée.
dans le fichier php qui sera demandé tu fais un INSERT dans la bdd
ca te permet par la suite de faire des courbes de températures, des moyennes, etc... smiley-wink
style :
Code:
   
client.print("GET /temp.php?temp=");
client.print(temperature);
client.stop();

dans ton fichier temp.php
Code:
<php
include("conecbdd.php");
if (isset($_GET['temp'])){
$temp=$_GET['temp'];
mysql_query("INSERT INTO temperturebdd (`date`,`temp`) VALUE (NOW(),$temp)");
Logged

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

Merci pour les informations,

Je vais essayer de suivre cette piste.

 smiley
Logged

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

Bonjour,

J'ai un programme qui fonctionne sur arduino, relevé de température, par contre la partie transfert vers la base de données ne fonctionne pas.

J'ai un serveur XAMPP qui tourne sous windows en local (adresse ip 10.0.0.60).
Partie du programme arduino ou j'ai un doute:

Serial.print(tempC);
Serial.println(" C ");
client.print("GET ");
client.print("/http://10.0.0.60/arduino/arduino01.php HTTP/1.1");
client.print("&TEMP=tempC");           
client.print("Host: ");
client.println("http://10.0.0.60/");
client.println("");

Serial.println(" envoi effectué  --OK-- ");

tempC est la mesure de température que je dois mettre dans la base de données.

La synthaxe est-elle bonne ? faut-il envoyer un bloc ou séparer les données je ne sais pas, quelqu'un peut-il m'aider.

Une autre question, comment peut-on savoir que l'arduino envoie bien les données ?

Programme arduino01.php:
<?php

include("db.php");

if (isset($_GET['tempC']))  {   
   $tempC = ($_GET['tempC']);
   echo $tempC;
   $data = mysql_query("INSERT INTO mySQL_table1 (DATE,tempC)   VALUES (now(), $tempC )");
}
?>

   

Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

je verrais plus un truc comme ca
Code:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //mac de ton arduino
byte ip[] = { 10,0,0,100 }; //son ip sur le réseau
byte server[] = {10,0,0,60 }; //ip de ton server
byte gateway[] = { 192,168,1,1 }; //passerelle pour accéder au server a modifier en fonction
byte subnet[] = { 255, 255, 255, 0 };  //mask réseau


Serial.print(tempC);
Serial.println(" C ");
 if (client.connect()) {
    Serial.println("Connexion au server");
    Serial.println();
    delay(1000);
    Serial.println("connected envoi donnees");
   client.print("GET /arduino/arduino01.php?TEMP=");
   client.println("tempC");           
   client.stop();
   Serial.println("Déonnexion au server");
}

Quote
Une autre question, comment peut-on savoir que l'arduino envoie bien les données ?
en regardant dans ta bdd smiley-wink sinon dans les logs pour voir les erreurs héhé
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

Tu peux également dans un premier temps entrer le lien qui est normalement envoyé par ton arduino directement dans ton navigateur et vérifier que cela remplie bien ta bdd.
Cela te permettra déjà de vérifier que ton code php fonctionne.

Restera à te concentrer sur ton sketch arduino  smiley-wink

Voici actuellement le type de trame que j'envoie sur mon serveur, j'ai inclu également la date et l'heure :

update_db.php?degres=22.5&Jour=2012/03/16&Heure=18h40
Tu peux voir le résultat en test ici : http://electronic.myftp.org

++
Logged

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

Salut,

Je voulais faire à peu près la même chose que toi, et je pense j'ai réussi.
J’écris dans la carte SD, toutes les 10 secondes, les valeurs d'une sonde, et je rajoute sur chaque ligne, le timestamp unix, retrouvé en NTP.
IL y a aussi j'ai un petit serveur web qui me permet d'aller télécharger le fichier.

Je ne voulais pas dépendre d'un serveur "extérieur", le but de mon projet étant de diminuer ma facture electrique en réglant mes chauffages via l'arduino, c'est pas pour avoir un serveur qui tourne 100% du temps !
J'ai mon Arduino depuis 5 heures.. un peu d'indulgence dans la programmation, j'ai encore du mal avec les String, par exemple !

J'ai pas encore bossé sur les sondes, J'ecris la valeur de A0, mais tu dois pouvoir mettre autre chose

Code:
/*
  Syslog + Web Server to download the syslog file

 
 
 created 16 Mars 2012
 by Cédric2, libre de tous droit.
 Premier programme...
 
 */

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 2);
char Fichier[] = "logfile5.txt";

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);


//Déclaration pour client NTP
unsigned int localPort = 8888;      // local port to listen for UDP/NTP packets
//IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
IPAddress timeServer(192, 168, 1, 254); // NTP server freebox, donc fonctionne même si adsl down :-)
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;


long i = 50000;  // petit compteur pour ne pas ecrire trop souvent//

void setup()
{

  // start the Ethernet connection and the server:
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
  pinMode(10, OUTPUT);

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.begin(9600);
  Udp.begin(localPort);
}

void loop()
{
  //Ecriture sur SD carte toutes les 50000 itérations (Environs toutes les 5s)// a améliorer
  if (i >= 50000)
  {

    Serial.println("Debut ecriture du fichier");
    //je commence par demander à la freebox l'heure
    sendNTPpacket(timeServer); // send an NTP packet to a time server
    // wait to see if a reply is available
    delay(1000);  
    if ( Udp.parsePacket() ) {  
      // We've received a packet, read the data from it
      Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

      //the timestamp starts at byte 40 of the received packet and is four bytes,
      // or two words, long. First, esxtract the two words:

      unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
      unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
      // combine the four bytes (two words) into a long integer
      // this is NTP time (seconds since Jan 1 1900):
      unsigned long secsSince1900 = highWord << 16 | lowWord;  

      // now convert NTP time into everyday time:
      Serial.print("Unix time = ");
      // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
      const unsigned long seventyYears = 2208988800UL;    
      // subtract seventy years:
      unsigned long epoch = secsSince1900 - seventyYears;  //Unix time
      // print Unix time:
      Serial.println(epoch);                              
      int sensorValue = analogRead(A0);
      //int  sensorValue = 120;


      File dataFile_write = SD.open(Fichier, FILE_WRITE);
      // if the file is available, write to it:
      String tmp_string = String("<unixtime>"+String(epoch)+"</unixtime>"+"<sensorValue>"+sensorValue+"<sensorValue>");
      if (dataFile_write) {
        dataFile_write.println(tmp_string);
        dataFile_write.close();
        // print to the serial port too:
        Serial.println(tmp_string);
        i=1;   // tout est OK, je re-initialise mon compteur.
      }  
      // if the file isn't open, pop up an error:
      else {
        Serial.println("error opening datalog.txt");
      }
    }
    else
    {
      Serial.println("Pas recu de réponse NTP");
    }
  }
  else
  {
    i++;
  }
  //partie serveur Web
  EthernetClient client = server.available();
  if (client) {
    Serial.println("client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: plain/text");
          client.println();

          // output the value of each analog input pin
          File
            myFile = SD.open(Fichier);
          if (myFile) {
            Serial.print("Open file ");
            Serial.println(
            Fichier);


            // read from the file until there's nothing else in it:
            while (myFile.available()) {
              char read_file = myFile.read();
              Serial.write(read_file);

              client.write(read_file);


            }
            // close the file:
            myFile.close();
          }
          else {
            // if the file didn't open, print an error:
            Serial.println("error opening test.txt");
          }
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}



// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:  
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}






« Last Edit: March 16, 2012, 06:03:53 pm by cedric2 » Logged

france
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bonjour.

Quote
Je voulais faire à peu près la même chose que toi, et je pense j'ai réussi.
J’écris dans la carte SD, toutes les 10 secondes, les valeurs d'une sonde, et je rajoute sur chaque ligne, le timestamp unix, retrouvé en NTP.
IL y a aussi j'ai un petit serveur web qui me permet d'aller télécharger le fichier.

Je ne voulais pas dépendre d'un serveur "extérieur", le but de mon projet étant de diminuer ma facture electrique en réglant mes chauffages via l'arduino, c'est pas pour avoir un serveur qui tourne 100% du temps !

je suis presque dans le même cas que toi aussi. je ne veut pas de PC qui tourne 24/24h juste pour cela. pour ma part je désire logger les données d'un port serie qui envoie des data toutes les seconde , un enregistrement toutes les 5min me suffise. avec insertion de l'heure c'est tip top je vais étudié ton prog !

je viens de le testé:
quand tu tape ton adresse dans ton navigateur il télécharge direct ? dans mon cas ça m'ouvre une fenêtre pour DL un fichier télécharger et il faut que je renomme le fichier avec la bonne extension.

se matin j'ai essayé un serveur ou il été possible de voir les fichiers sur la SD. http://www.ladyada.net/learn/arduino/ethfiles.html
il fonctionné bien. je débute tout juste.
« Last Edit: March 17, 2012, 07:40:08 am by maccoa » Logged

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

Slt,

J'ai pas mal bossé sur le programme, J'ai eu plein de problèmes bizarres car j'utilisais trop la mémoire. (probablement un problème de newbiz !!)
Après qque recherche, il me semble que La library sd prend 1400 octed des 2000 octed disponible, il faut donc trouver des solutions pour limiter à max l'utilisation de variable...
J'ai donc diminué au max les variables et les chaines, c'est moins lisible, mais le programme ne crash plus aléatoirement.
Coté http, c'est un minimum plus joli. Coté Ntp aussi.

Voila une version qui fonctionne mieux coté http (V14 pour le moment)

http://code.google.com/p/arduino-domotique-cedric2/downloads/list
« Last Edit: March 18, 2012, 05:33:20 pm by cedric2 » Logged

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

J'ai trouvé une solution à mes problèmes mémoires grâce à
http://ed.zehome.com/blog/limiter-la-consommation-ram-sur-avr-arduino
(donc vraiment une erreur de newbiz pour moi)

Pour ceux que cela interesse, la V15 a parfaitement fonctionné toute la nuit sans cracher, et il reste plein de mémoire disponible pour le reste :-)

Todo :
- lister les fichiers.
- Tourner/Supprimer les fichiers de log.
- Faire de jolie pages, stockée dans la SD.
Et après je m'attaque à la gestion des chauffages... mais c'est hors sujet dans ce topic

Edit : Publication de la V16 / Ajout d'un client FTP qui fonctionne avec la freebox V6, pour downloader un fichier sur la freebox
   (vu sur arduino.cc/forum/index.php?topic=93502 avec un petit patch pour le V6)
http://code.google.com/p/arduino-domotique-cedric2/downloads/list
« Last Edit: March 19, 2012, 07:01:25 pm by cedric2 » Logged

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

Bonjour,

J'ai aujourd'hui un programme sur arduino UNO qui fonctionne, le but était de mesurer une température et d'envoyer les données dans une table Mysql.

#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
//#include <Udp.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 7  // 1-wire sur borne 7

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// MAC adresse et paramétres pour le réseau
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x02, 0x98 };
byte ip[] = { 10,0,0,20 };
byte passerelle[] = { 10,0,0,1 };
byte masque[] = { 255,255,255,0 };

byte serverip[] = { 10,0,0,60};  // adresse du serveur ou arduino envoi les données

// Création de l'objet serveur Client xxxx (ip, port)
Client client(serverip, 80);

char c;

int i = 0;    // comptage du nbre envoi au serveur

// adresses des capteurs de temperatures DS18S20
DeviceAddress insideThermometer = { 0x10, 0xA3, 0x4C, 0x9C, 0x01, 0x08, 0x00, 0x18 };
//DeviceAddress outsideThermometer = { 0x10, 0xA3, 0x3A, 0x9C, 0x01, 0x08, 0x00, 0xE9 };
//DeviceAddress dogHouseThermometer = { 0x10, 0xD2, 0xAD, 0x71, 0x01, 0x08, 0x00, 0x74 };

void setup()
{
  //Serial.begin(9600);
  sensors.begin();    // ativation capteurs de température
 
  // résolution pour le capteur 10 bits
  sensors.setResolution(insideThermometer, 10);
  //sensors.setResolution(outsideThermometer, 10);
  //sensors.setResolution(dogHouseThermometer, 10);
 
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, passerelle, masque);
  delay(2000);
 
  //serveurHTTP.begin();  // init du serveur
  delay(5000); // Attente mise en marche serveur

  // info sur utilisation de la mémoire
  //Serial.println("\n[memCheck]");
  //Serial.println(freeRam());
   
}

void loop()
{
 
    if (client.connect())
    {

      delay(250000); // 1000 = 1 seconde 600000 -> 10 minutes
      //Serial.println("Prise de temperature");
      i = i +1;
      sensors.requestTemperatures();
     
     
      float tempC = sensors.getTempC(insideThermometer);
      if (tempC == -127.00)
          {
            //Serial.println("Erreur mesure");
          }
       else
          {

            delay(1000);
            client.print("GET http://xx.xx.xx.xx/arduino/arduino03.php?TEMP=");
            //client.print("=");
            client.println(tempC);
           
          }
    }
    else
    {
      //Serial.println("CONNEXION NON POSSIBLE");
    }
   if (client.available())
  {
     char c = client.read();
     //Serial.print(c);
  }
  delay(1000);
  client.stop();
  client.flush();
}
// lecture mémoire restante
int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

Il reste un petit problème concernant le temps entre chaque mesure, si je mets delay > 250000 le programme ne fonctionne pas. Est-ce que la fonction delay n'autorise pas de plus grandes valeurs ?

Logged

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

C'est "unsigned long", tu devais pouvoir mettre plus.
tu as essayé delay(unsigned long(100000));
Sinon maintenant, j'uilise la lib #include <Time.h> , je peux donc utiliser minute()
Logged

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

Bonsoir,

J'ai testé mon programme pendant plusieurs jours avec 3 sondes de températures, le fonctionnement est nickel. Concernant le temps entre chaque mesure, j'ai essayé avec la lib <Time.>, ne fonctionnait pas avec le programme arduino 022. J'ai trouvé une solution avec une boucle qui compte les minutes et je règle un compteur.

J'envisage d'ajouter la lecture des entrées Analogiques et des sorties numériques. j'ai fait des tests et apparemment non concluant. je n'arrive pas à me connecter pour afficher la page web.

Est-ce que c'est possible ? je pense que ça ne fonctionne pas à cause de ma tempo pour le relevé de température et l'envoi à ma base de données. Y a t-il une solution pour réaliser le relevé de température avec transfert vers mon serveur (base Mysql) plus un affichage sur un page web en interrogeant l'arduino.
Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

tu peux mettre une condition du style
Code:
if(client.connect.....
afficahge de la page web
}else{
envoie des données sur le server
}
regarde aussi les interruptions
Logged

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

Bonjour,

Suite à quelques modifications du programme, j'arrive aujourd'hui à relever les 3 températures (envoyées vers serveur + mysql), l'état des entrées analogiques (envoyées vers serveur + mysql). J'ai une boucle qui permet un relevé toutes les 2 minutes pour les entrées analogiques et toutes les 15  minutes pour les températures.
Le programme tourne depuis 2 semaines et je m’aperçois qu'il a bloquer 2 fois.

J'ai regarder pour mettre un watchdog permettant de vérifier le bon fonctionnement du programme et de pouvoir le relancer s'il  bloque. Quelqu'un a-t-il des infos à me donner sur le sujet car ça me parait obscure. L'utilisation de wdt.h  smiley-eek-blue
Comment le mettre en place dans un programme ? existe-t-il un tuto ?

Merci
Logged

Pages: [1]   Go Up
Jump to: