Projet domotique : teleinfo + 4 relais + T°C 1wire

 #include "print.h"
#include "string.h"
#include "etherShield.h"
#include "stdio.h"
#include "Time.h" 
#include "EEPROM.h"
#include "param.h"
time_t prevDisplay = 0; // when the digital clock was displayed

#include "teleinfo.h"
#include "log.h"
#include "serveur_web.h"
#include "ntp.h"
char power;
char index;
void setup()
{
  init_ethernet();
  Serial.begin(1200);
          // parite paire E
          // 7 bits data
  UCSR0C = B00100100;
         ///////////////////////////////////////////////////////////////////////////
         // Avec cette commande serial monitor ne fonctionne pas normalement!
         // il faut etablir une liaison avec hyperterminal
         // attention l'uploading necessite de déconnecter la pin0 Rx
         ////////////////////////////////////////////////////////////////////////////
  setSyncInterval(interval_synchro);    
  setSyncProvider( client_process_NTP);  //set function to call when sync required
////////////////////////////////////////////////////////////////////////////////////////////////////
//Taille des piles d'enregistrement mémoire Max 1024 Bits
///////////////////////////////////////////////////////////////////////////////////////////////////
  test_init_pile ( 30, 500, 60, 1); // init de la pile (Offset, longueur, Intervall temps, N°pile)
  test_init_pile (540, 450, 1800, 0); // init de la pile (Offset, longueur, Intervall temps, N°pile)
}

void loop()
{
  web_server();
  read_teleinfo();

    // display heure
  if( now() != prevDisplay) //update the display only if the time has changed
  {
      power=papp/40;
      Write_log( now(), power, 1);                // Ecriture pile Puissnce
     
      if (ptec[1]=='C') index = (hchc/1000)%250;  // Sauve Index Heure Creuse
      else index = (hchp/1000)%250;               // Sauve Index Heure Creuse
      Write_log( now(), index, 0);                // Ecriture Pile Index Kw/h

      prevDisplay = now();
     // digitalClockDisplay();  
  }
}

//*****************************************************************************************
//
// Function : Affichage liaison serie
//
//*****************************************************************************************

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

************le .pde

J'ai bien des ex de code pour le onewire + dallas mais c'est où les placer dans mon code (enfin le code que j'ai trouvé) et les incorporer aussi sur une des 4 page web ou rajouter une 5eme page.
pareil pour les relais (contact on/off).

Pas facile ou plus de place mem. ou j'ai loupé un épisode :cry:

// get current temperature
#define TEMP_PIN  3
void getCurrentTemp( int *sign, int *whole, int *fract);

je pense le mettre en pageweb 1 (si cela fonctionne j'essaierai de le mettre en page 5 à créer).

   // initialize DS18B20 datapin
    digitalWrite(TEMP_PIN, LOW);
    pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)

et celui là après //init the ethernet/ ip layer:

        getCurrentTemp(temp_string);
        
        plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0  </h1></p> "));
         
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr>
<form METHOD=get action=\""));
        plen=es.ES_fill_tcp_data(buf,plen,baseurl);
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("\">"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h2> Current Temperature is </h2> "));
       plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));
         
       
        while (temp_string[i]) {
                buf[TCP_CHECKSUM_L_P+3+plen]=temp_string[i++];
                plen++;
        }

       plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("  &#176C</font></h1>
 ") );
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=1>"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Get Temperature\"></form>"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p> V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));

et ce code dans la pageweb 1 entre la ligne :
sprintf (test, "%ld&chds=0,8000&chl=%ld'>" ,papp, papp) ;

et celle qui suit
plen=es_fill_tcp_data_p (buf, plen, test);

Pour afficher en page 1 la T°C.

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }

      d=d>>1; // now the next bit is in the least sig bit position.
   }
   
}

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}


void getCurrentTemp(char *temp)
{  
  int HighByte, LowByte, TReading, Tc_100, sign, whole, fract;

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0xbe);

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  sign = TReading & 0x8000;  // test most sig bit
  if (sign) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  whole = Tc_100 / 100;  // separate off the whole and fractional portions
  fract = Tc_100 % 100;


      if(sign) temp[0]='-';
      else              temp[0]='+';
      
        if(whole/100==0)
           temp[1] =' ';
        else
        temp[1]= whole/100+'0';
      temp[2]= (whole-(whole/100)*100)/10 +'0' ;
      temp[3]= whole-(whole/10)*10 +'0';
      
      temp[4]='.';
      temp[5]=fract/10 +'0';
      temp[6]=fract-(fract/10)*10 +'0';
      
      temp[7] = '\0';


      
}

Celui là je pense le mettre tout à la fin.

Voilà, vous en pensez quoi ? des erreurs ?

PS : après, je verrai pour les relais ON/OFF simple.

int8_t analyse_cmd(char *str)
{
        int8_t r=-1;
     
        if (find_key_val(str,"cmd")){
                if (*strbuf < 0x3a && *strbuf > 0x2f){
                        // is a ASCII number, return it
                        r=(*strbuf-0x30);
                }
        }
        return r;
}

Il y a ce code qui est diffèrent entre les deux (le mien et celui mis pour la T°C juste au dessus). Je pense qu'il risque d'y avoir conflit si je le rajoute ? ou si je le transforme ?
Je me demande si ce n'est pas là mon problème pour joindre les deux :-/

Ou cela concerne juste l'appel de la page ?

Bon, mon projet ne semble intéresser personne. Dommage pour moi.

Détrompe toi, je pense plutôt que tu n'as pas de réponse parce que ton code dépasse largement les compétences de beaucoup d'entre nous.

Ce n'est malheureusement pas le mien mais j'ai l'autorisation de l'auteur pour l'utiliser et le mettre ici. Je ne pouvais pas plus l'embêter pour m'aider car déjà son boulot est superbe.

D'après lui, le rajout n'est pas difficile mais je comprends pourquoi car son niveau est déjà important.

Je vais essayer de modifier tout seul et de mettre les résultats et les erreurs peut-être cela fera avancer.

Oui, ce sera mieux de présenter l'évolution de ton travail par étape, ce sera aussi plus facile pour la compréhension et l'aide qui pourrait t'être apportée.

si t'es hyper newby, t'as pas chois la facilité, car d'apres ton code tu as un shield ethernet plus compliqué que l'officiel à programmer me semble-t-il
es-tu vraiment dans ce cas ?
as tu encore le choix, de prendre un shield officiel de qq euros plus cher mais bien plus simple à programmer ?

J'ai donc collé les lignes que j'avais marqué précédemment :

  • // get current temperature
  • // initialize DS18B20 datapin
  • getCurrentTemp
  • void onewirereset

A la compilation j'obtiens les erreurs :
1/ serveur_web.h : in fonction 'uint16_t print_webpage (uint8_t*)':
2/ serveur_web.h : 208 error 'temp_string' was not declared in this scope
3/ serveur_web.h : 214 error 'baseur1' was not declared in this scope
4/ serveur_web.h : 220 error 'i' was not declared in this scope

Il me faut rajouter quoi ou changer ?

PS : le code télé info fonctionne parfaitement - je cherche juste à rajouter si possible la T°C et relay.

salut,

je veux bien t'aider, mais là j'avoue que je n'arrive pas à avoir une vision d'ensemble de ton problème, j'ai du mal à suivre :-/
Il y a des bouts de code qui se ballade un peu partout dans le topic. Quel est le code de départ, et que veux-tu rajouter ?
Quel shield Ethernet utilises-tu ?

Gromain

Je vais essayer de reprendre :
mon post 5 et 6 (les deux premiers codes) correspondent au serveur_web.h
le post 7 (qui suit) c'est le teleinfo.pde

***Là, c'est ce qui est existant et qui fonctionne super bien.

A cela, je désirerais rajouter une ou des sondes DS18B20 (en onewire) et si il reste de la place 4 relais simple on/off (sur la même page web ou sur une autre).

J'ai trouvé des exemples de codes que j'ai mis dans mes "reply #9, 10 et 11" et que j'ai essayé d'intégrer. Apres compilation, il m'a sorti les erreurs que j'ai décrit (reply#18).

J'utilise le enc28j60.

A la compilation j'obtiens les erreurs :
1/ serveur_web.h : in fonction 'uint16_t print_webpage (uint8_t*)':
2/ serveur_web.h : 208 error 'temp_string' was not declared in this scope
3/ serveur_web.h : 214 error 'baseur1' was not declared in this scope
4/ serveur_web.h : 220 error 'i' was not declared in this scope

As-tu déjà testé séparément le code pour le DS18b20 ?
l'idéal c'est de faire tourner ce code seul dans un sketch, valider son fonctionnement, et ensuite l'intégrer au reste.
Car là il te manque pas mal de chose à mon avis, comme la déclaration de 'temp_string' en tête de sketch (erreur n°2)

Tu veux que je le teste comment ?

J'attend un shield v4 pour tester avec un DS18B20 et 2 relays

Salut,

ci-dessous un exemple fonctionnel de gestion de multiple DS18b20.
Le code est configuré pour un fonctionnement en mode parasite (2 fils). Si tu utilises le mode normal, les performances seront améliorées (tps de réponse plus court), mais il faudra modifier quelques paramètres (voir dans les commentaires).
Quand ce sera ok chez toi:

  • copier le code dans un fichier que tu appelleras DS18b20.pde
  • copier ce fichier dans le répertoire "monprojet": il sera ajouté automatiquement à ce projet.
  • supprimer la routine loop() de DS18b20.pde
  • renommer setup() du sketch DS18b20.pde en setup_DS18b20()
  • ajouter un appel de la routine "setup_DS18b20" dans le setup() de monprojet.pde
  • ajouter un appel de la routine "gestion_temperature" dans le loop() de monprojet.pde
#include <stdio.h>
#include <string.h>
#include <OneWire.h>

#define NBRE_CAPTEUR 1 // nombre de capteur sur l'arduino

// *********** declararation des variables gestion des capteurs de temperature  *******************
typedef struct Temperature Temperature;
struct Temperature
{
      float valeur;                              // temperature en Celsius, 1 chiffre apres la virgule
      byte addr[8];                              // identifiant capteur
      int pin;                              // numero de pin a utiliser
      char mnemo[32];                              // mnemonique de la variable
};

Temperature temperature[NBRE_CAPTEUR];            //creation des instances

// *********** fin declararation des variables gestion des capteurs de temperature  *******************


void setup(){
  
            Serial.begin(9600);                        // initialisation de la liaison serie

      
// *********** initialisation des variables gestion des capteurs de temperature  *******************


      temperature[0].addr[0]= 0x10;      // identifiant capteur
      temperature[0].addr[1]=      0x5;
      temperature[0].addr[2]=      0x81;
      temperature[0].addr[3]=      0x94;
      temperature[0].addr[4]=      0x1;
      temperature[0].addr[5]=      0x8;
      temperature[0].addr[6]=      0x0;
      temperature[0].addr[7]=      0x24;
      temperature[0].pin=4;
      temperature[0].valeur=0;                  // temperature en °C, 1 chiffre apres la virgule
        strcpy(temperature[0].mnemo,"temp_salon");      // ex: salon

      
  
}


void loop(){
  
  
gestion_temperature();

delay(5000);

}


void gestion_temperature()
{

/********************************************************************************
      Cette fonction permet d'interroger tous les capteurs de temperature OneWire
      qui ont ete declare dans "temperature[i]"
********************************************************************************/

      byte i=0;

      for(i=0; i<NBRE_CAPTEUR; i++){

             Serial.print(temperature[i].mnemo);
            Serial.print(" => ");
            temperature[i].valeur =getStuff(temperature[i].addr,temperature[i].pin);
            Serial.print(temperature[i].valeur);
            Serial.println(" C ");
            delay(100);
            
      }

}


float getStuff(byte addr[8], int pin) // indiquer le n[ch65533] de pin [ch65533] utiliser
{

/********************************************************************************
      Cette fonction permet d'interroger le capteur de temperature OneWire
      qui a [ch65533]t[ch65533] d[ch65533]clar[ch65533] dans "temperature[i]"
********************************************************************************/

  OneWire  ds(pin);  // creation d'un objet OneWire avec le bon n[ch65533] de pin

      byte i;
      byte present = 0;
      byte data[12];

      float real_temp;
      float temp_count;
      float read_temp; 

 // Fonction recherche d[ch65533]sactiv[ch65533]e car non utilis[ch65533]e
 /*if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
 }
 
 
      Serial.print("R=");
      for( i = 0; i < 8; i++) {
            Serial.print(addr[i], HEX);
            Serial.print(" ");
      }

      if ( OneWire::crc8( addr, 7) != addr[7]) {
            Serial.print("CRC is not valid!\n");
            return 998;
      }
  
      if ( addr[0] != 0x10) {
            Serial.print("Device is not a DS18S20 family device.\n");
            return 999;
      }
*/
      ds.reset();
      ds.select(addr);
      ds.write(0x44,1); // start conversion, with parasite power off at the end (1=parasite mode)
  
      delay(1000);     // delay de 1s si mode parasite. 100ms en mode normal
  // 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


    for ( i = 0; i < 9; i++) {           // we need 9 bytes
            data[i] = ds.read();
      }

      read_temp=((data[1]<<8) | data[0]) >> 1 ;            // Divide the temperature by 2
      temp_count=float(data[7] - data[6])/(float)data[7];  // Convert to real temperature
      real_temp = ((float)read_temp-0.25)+temp_count;
       
      // arrondi 1 chiffre apres la virgule
      int temp = real_temp*10;
      real_temp = (float)temp/10;
      
      // Serial.println();
  
  return real_temp;
}

Si tu ne connais pas l'adresse de tes DS18b20, décommente provisoirement les lignes, ou plus simple, utilises le code sample.c fournis avec la lib OneWire pour déterminer toutes les adresses.

Gromain

Merci, des que je reçois mon shield je teste.

Par contre, j'ai fini par trouver un sketch incluant télé info et T°C (2analogique et 1 digit.). Je sais que la partie info fonctionne et il me reste à tester l'autre (dés réception aussi de ma plaquette DS18B20 pour le shield).
Il est plus simple que le premier et sans sauvegarde. Dommage mais bon ... veux tu que je le place ici ?

Ensuite, j'ai trouvé un sketch switch 4 on/off qui semble fonctionner.

*******PS : suite ici : http://arduino.cc/forum/index.php/topic,82555.0.html