Aidez nous ! Projet - Gestion domotique

Cela a l'air pas mal et pas cher. (j'ai pas vu les frais de livraison)
Il faut que je recherche encore un peu, et que je valide les taille, mais

me semble pas mal adapté si je trouve un afficheur adaptable

Merci pour l'info, ces boîtiers ont l'air d'être bien adaptés pour la domotique, autant ceux pour rails DIN, qui sont à priori pas trop chers, que les autres. Il faut effectivement voir pour les frais de port, si quelqu'un a l'info ?

Les frais de livraison sont de 7,90€, livraison par UPS.
Mes commandes on été reçu 3-4 jours après payement par paypal.

J'ai commander ce boitier et je suis satisfait de cellui-ci.

je l'utilise pour 32 entrées et un autre pour 16 sortie avec relais.

Yop yop,
Vive les boiboites bien propre histoire de cacher un montage dégueulasse (les miens). :grin:
Sinon pour changer un peux j'ai remis mon shield eth sur ma mega, pour la partie couplage contrôleur web/bus, j'arrive à envoyer une commande avec retour de statut assé rapidement (une 20 ène de millis sec, avec bus à 112500baud).
Par contre je suis moyennement satisfait au niveau de la réactivité en ce qui concerne les commande local et statut je suis obligé de scruter tout les x ms si il y à eu un changement c'est loin d'être optimal.
Je met mon code d’expérimentation.

Code arduino (brouillon pas propre et non optimisé) :

#include <SPI.h>
#include <Ethernet.h>
#include <util/crc16.h>
#include <util/delay.h>
#include <avr/wdt.h>

#define DATA_LENGTH 6
#define ADDRESS 0x12
#define RECEIVER 0x10

#define RE_DE_ON PORTK|=128
#define RE_DE_OFF PORTK&=~(128) 
#define RE_DE_REG DDRK |= 128
#define BAUD 115200

#define _WAIT(_pres) _delay_us(_pres)
#define SERIAL_BUFFER_SIZE 16

byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0x6D, 0x86 };
byte ip[] = { 192,168,1,109 };

Server server(9390);
Client client = 0;

volatile uint8_t listener = 0;
volatile uint32_t delayWD = 0;

uint8_t bufferBusTx[DATA_LENGTH] = {0}; 
volatile uint8_t bufferBusRx[SERIAL_BUFFER_SIZE] = {0};
volatile uint8_t bufferTmp[32] = {0};
volatile uint8_t pos = 0;
volatile uint8_t available = 0;

uint32_t delayB = 0;
volatile uint8_t ack = 0;
uint8_t err = 0;

const uint32_t pres = 69120000/BAUD;
const uint32_t maxRec = 14000000/BAUD;
const uint32_t maxTrans = (32640000/(BAUD/100))+((ADDRESS*(pres*2)));


ISR(USART1_RX_vect)
{
  if((UCSR1B & (1<<RXB81)))
  {
    listener = UDR1;
    if(listener == ADDRESS || listener == 0x80 || (ack && listener == 0x81))
    {
      UCSR1A &= ~(1<<MPCM1);
      pos = 0;
      available = 0;
    }
    else
    {
      UCSR1A |= (1<<MPCM1);
    }
    
    delayWD = micros()+maxTrans; 
  }
  else
  {
    bufferBusRx[pos] = UDR1;
    
    if(pos == bufferBusRx[1]+4)
    {
      available = pos;
      pos = 0;
    }
    else
    {
      ++pos;
    }
  }
}

////////////////////////////////////////////////////////////////////////////

void setup()
{
  Ethernet.begin(mac,ip);
  server.begin();
  delay(1000);
  
  RE_DE_REG;
  DDRK &= ~(64);
  
  begin(BAUD);
}

////////////////////////////////////////////////////////////////////////

void loop()
{
  client = server.available();
  if(client.available()) 
  {
    int i = 0;
    while(client.available() > 0)
    {
      bufferBusTx[i] = client.read();
      i+=1;
    }
    
    if(bufferBusTx[1] == 0x12 && bufferBusTx[2] == 0x12)
    {
      if(bufferTmp[2])
      {
        writeAjax(client, bufferTmp);
          
        bufferBusTx[2] = 0;
        bufferTmp[2] = 0;
      }
    }
    else
    {
      while(client.connected())
      {
        if(available)
        {
          readData(); 
          available = 0;
        }
        else
        {
          sendData();
        }   
      }
    }
    client.flush();
    client.stop();
  }
  
  if(available)
  {
    readData();   
    available = 0; 
  }
  else
  {
    sendData();
  }
  
}

uint8_t sendData()
{
  if(bufferBusTx[2] && !listener) 
  {
    _WAIT(pres);
    writeData(bufferBusTx);
    ack = 1;
  }
  
  if(listener && micros() >= delayWD) 
  {
    listener = 0x00;
    ack = 0;
  }
}

void readData() 
{
    if(bufferBusRx[0] == 0x02 && bufferBusRx[bufferBusRx[1]+4] == 0x03) //debut de trame
    {
        if(checkData()) //crc ok
        {
          action();
        }
        else //sinon on retourne directement un message d'erreur crc à l'envoyeur
        {
          
          ackError(0x02);
        }
    }
    else //sinon on retourne directement un message d'erreur general de reception
    {
      ackError(0x01);
    }
       
}

void action()
{ 
    if(bufferBusRx[4] == 0xFF || err == 2)
    {
      bufferBusTx[2] = 0;
      _WAIT(pres);
      RE_DE_ON;
      write(0x00, 1);
      _WAIT(pres);
      RE_DE_OFF;
      ack = 0;
      err = 0;
      if(bufferBusRx[4] == 0xFF)
      {
        if(client.connected())
        {
          writeAjax(client, bufferBusRx);
        }
        else
        {
          for(int i = 0; i <= bufferBusRx[1]+1; i++)
          {
            bufferTmp[i] = bufferBusRx[i];
          }
        }
      }
    }    
    else
    {
      ++err;
      _WAIT(pres);
      writeData(bufferBusTx);
    }
}

void writeAjax(Client cli, volatile uint8_t* buf)
{
    client.print("{");

    for(int i = 0; i <= buf[1]; i++)
    {
      client.print("\"i");
      client.print(i);
      client.print("\":");
      client.print((int)buf[i+1]);
      if(i < buf[1])
      {
        client.print(",");
      }
    }
    client.print("}");
    
    client.flush();
    client.stop();
}

void writeData(uint8_t* data)
{
  uint16_t crc = 0xFFFF;
  
  for(uint8_t i=0; i <= data[0]; i++)
  {
    crc = _crc16_update(crc, data[i]);
  }
  
  RE_DE_ON;
  
  write(data[1], 1); 
  write(0x02, 0); 
  for(uint8_t i=0; i <= data[0]; i++) 
  {
    write(data[i], 0);
  }
  
  write(((crc & 0xFF00) >> 8), 0);
  write((crc & 0x00FF), 0);
  write(0x03, 0); 
  _WAIT(pres); 
  RE_DE_OFF;
}

uint8_t checkData()
{
  uint16_t crc = 0xFFFF;
  
  uint16_t _crc = (bufferBusRx[bufferBusRx[1]+2]<<8);
  _crc += bufferBusRx[bufferBusRx[1]+3];
  
  for(uint8_t i=1; i <= bufferBusRx[1]+1; i++)
  {
    crc = _crc16_update(crc, bufferBusRx[i]);    
  }

  if(crc == _crc)
  {
    return 1;
  }
  
  return 0;
}

void ackError(uint8_t ErrorNo)
{
  uint8_t data[5] = {0};
  data[0] = 0x04; 
  data[1] = 0x81;
  data[2] = ADDRESS;
  data[3] = 0xFE;
  data[4] = ErrorNo;
  _WAIT(pres);
  writeData(data);
}
//////////////////////////////////////////////////////////////////////////////////////////////////

void write(uint8_t data, uint8_t txb8)
{
  while (!((UCSR1A) & (1 << UDRE1)))
    ; 
  if(txb8)
  {
    UCSR1B |= (1<<TXB81);
  }
  else
  {   
    UCSR1B &= ~(1<<TXB81);
  }
  UDR1 = data;
}

void begin(uint32_t baud)
{
  uint16_t baud_setting;
  UCSR1A = 0;
  baud_setting = (F_CPU / 8 / baud - 1) / 2;

  UBRR1H = baud_setting >> 8;
  UBRR1L = baud_setting;
    
  UCSR1A |= (1<<MPCM1);
  UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<UCSZ12);
  UCSR1C = (3<<UCSZ10);
  UCSR1B &= ~(1<<UDRIE1);
}

Page index html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>DDuinoAjax</title>

    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
        
    <script src="webAjax.js"></script>
    <script src="response.js"></script>
    
   <link rel="stylesheet" type="text/css" href="style.css" media="screen" />

</head>
<body onload="init()">
 <h3>DD</h3>
 <div id="log"></div>
 


 <div><button id="dw0" onclick="digitalWrite(0, 1, 1)">on</button></div>
 <div><button id="dw1" onclick="digitalWrite(1, 1, 1)">on</button></div>
 <div><button id="dw2" onclick="digitalWrite(2, 1, 1)">on</button></div>
 <div><button id="dw3" onclick="digitalWrite(3, 1, 1)">on</button></div>
 <div><button id="dw4" onclick="digitalWrite(4, 1, 1)">on</button></div>
 <div><button id="dw5" onclick="digitalWrite(5, 1, 1)">on</button></div>
 <div><button id="dw6" onclick="digitalWrite(6, 1, 1)">on</button></div>
 <div><button id="dw7" onclick="digitalWrite(7, 1, 1)">on</button></div>
 
</body>
</html>

Code javascript:

function init()
{
	setInterval("getStatut()", 200);
}

function getStatut()
{
  var dataJSon = {"0":0x02,"1":0x12,"2":0x12 };
  send(dataJSon);
}

function parseJSon(dJson)
{
  var duino = eval('(' + dJson + ')');
  if(duino.i2 == 0x10)
  {
    log(dJson);
    for(var i = 0; i <= 7; i++)
    {
      id="dw"+i;
    
      if(duino.i5 & (1 << i))
      {
        $(id).innerHTML="off";
        $(id).setAttribute('onclick', "cmdIO("+i+", 0, 0)");
      }
      else
      {
        $(id).innerHTML="on";
        $(id).setAttribute('onclick', "cmdIO("+i+", 1, 0)");
      }
      //log(Date.now());
    }
  }
}

function cmdIO(pin, value, ack)
{
  //log(Date.now());
  var dataJSon = {"0":0x04,"1":0x10, "2":0x12, "3":value, "4":pin };
  send(dataJSon);
}

function send(dataJSon)
{
  jQuery.post("socket.php", dataJSon,
  function(data)
  {
    parseJSon(data);
  });
}

function $(id)
{
  return document.getElementById(id);
}

function log(msg)
{
  $("log").innerHTML+="
"+msg;
}

function sleep(milliseconds)
{
  var start = new Date().getTime();
  start+=milliseconds;
  
  while((new Date().getTime()) <= start)
  {
      
  } 
}

Code php:

<?php

$msg = "";
$buffer = null;

foreach($_POST as $element)
{
 $msg=$msg.chr($element);
}

$host="192.168.1.109";
$port=9390;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $host, $port);
socket_write($socket,$msg,strlen($msg));

do
{
    if(isset($buffer))
        echo $buffer;
}
while(@socket_recv($socket,$buffer,32,0) != 0);

socket_close($socket);

?>

Je songe à revenir vers les websocket mais serveur en java et communication avec le bus non plus avec shield eth mais via port serie du serveur (hard).

Bonsoir,

Je reviens vers vous, pour vous tenir au courant de l'avancement de mes travaux.
Je viens de finir mes essais et le schéma structurel de l'unité d'interfaçage arrosage.
Cette unité en I2C vient s'intercaler entre l'unité de gestion (arduino) et l'unité de commande arrosage.
Je joins le schéma à ce post.
N'hésitez pas à me faire des commentaires et des remarques.
Je vais la câbler dès que j'ai reçu tous les composants, il ne me manque plus grand chose.

Bien à vous tous

Schéma structuel unité d'interfaçage arrosage.pdf (137 KB)

Yep!

Je viens de jeter un oeil. J'ai presque tout compris à part les transistors sur les lignes scl et sda qui à mon goût ne servent pas à grand chose :grin:

En tout cas super boulot, faudra nous mettre une jolie photo kicad 3d XD

@+

Zoroastre.

En fait, j'ai repris un schéma que j'ai trouvé sur le net, et qui doit permettre d'augmenter la distance sur la liaison I2C, j'ai fait quelques essais avec une longueur de 10m cela fonctionne très bien.
En fait je n'ai besion que d'environ deux mètres, mais je préfère assurer.

J'enverrai des photos dès que j'aurai fini le câblage.
En attendant voici des photos de l'unité de commande arrosage et de l'unité de commande chauffage.

Yop Yop BriBri,
Tu as bien avancé, en tout cas super boulot qui devrait en inspiré plus d'un. :slight_smile:
Grâce à toi je viens de découvrir le pcf8574 :sweat_smile: qui m'apparait très intéressant pour étendre le nombre d'e/s. :open_mouth:

Pour l'instant je ne travaille plus trop sur le bus, je suis en train de me faire une application java serveur de websocket qui permettra la communication websocket<->arduino via shield ethernet mais également via port serie, ce qui permettra de lier web <-> arduino sans même être obligé de disposé d'un shield ethernet. :open_mouth:

osaka:
je viens de découvrir le pcf8574 :sweat_smile: qui m'apparait très intéressant pour étendre le nombre d'e/s. :open_mouth:

Le PCF8574 est très intéressant et facile à mettre en oeuvre avec un arduino.

osaka:
je suis en train de me faire une application java serveur de websocket qui permettra la communication websocket<->arduino via shield ethernet

Pour ce que j'ai compris, ton principe de websocket permet d'utiliser des fonctions (ou modules) pour échanger des informations entre l'arduino et le serveur web, c'est ce dont je vais avoir besoin. Je vais bientôt attaquer la partie programmation et notamment ce qui concerne la partie web. Pour le moment, je n'en suis pas encore là, j'avance doucement, pas à pas. Mais j'aurai besoin d'aide à ce moment là.

@+

Yep!

Pour ma part, je viens de finir la sérigraphie de mon premier proto double coeur à 20 Mhz.

J'ai quelques défauts de conception : petit manque de place au niveau de l'alimentation qui n'est pas définitive à l'heure actuelle. J'attends la livraison de régulateurs 5v/2A et 3.3v (le pion rouge) ainsi que des condo chimiques.
Je me suis planté sur l'empreinte des quartz.
C'est exploitable pour l'heure et je vais lancer les tests dés que j'aurais définitivement validé la partie alimentation (faudrait pas que çà chauffe de trop quand je vais tirer dessus).

J'attaque le shield ethernet + eeprom + ds1307 déssiné dans les grandes lignes.

@+

Zoroastre.

Brisebee:

osaka:
je suis en train de me faire une application java serveur de websocket qui permettra la communication websocket<->arduino via shield ethernet

Pour ce que j'ai compris, ton principe de websocket permet d'utiliser des fonctions (ou modules) pour échanger des informations entre l'arduino et le serveur web, c'est ce dont je vais avoir besoin.

En fait ça permettra surtout une communication full-duplex, dans le cas de serveur de contenu web (pages html, ...) la communication ne peux être initié que d'un seul côté, celui qui fais la requête (navigateur [requête]) ->arduino [réponse]-> navigateur).
Dans le cas du websocket chacun pourras initié la conversation (navigateur<->arduino).
Entre () contrairement à la solution ajax et socket php, ici le code html pourra ce trouver sur un hébergeur distant comme la beaucoup n'accepte pas les sockets.

Brisebee:
Mais j'aurai besoin d'aide à ce moment là.

Pas de problème, on t'aideras du mieux possible.

zoroastre:
je viens de finir la sérigraphie de mon premier proto double coeur à 20 Mhz.

Pourquoi un double coeur ? As-tu une application particulière en projet ?
Quels CI utilises-tu ?

Yep!

Brisebee:
Pourquoi un double coeur ? As-tu une application particulière en projet ?
Quels CI utilises-tu ?

Je vois que tu as raté un épisode...
EDIT1: Pourtant, tu étais là page 18 :stuck_out_tongue_closed_eyes:

Petit rappel : Je me suis inspiré des automates modernes qui possèdent une tache rapide et une tache normale. Ainsi, le premier uC (Atmega644), dans mon idée, s'occupera de la partie IHM (interface Homme/Machine : ethernet+Glcd) et le second de la communication avec les modules rs485 et sondes.
J'escompte faire dialoguer les 2 uC en I2c, avec une option multimaitre pour plus tard.

Outre l'expansion du nombre d'entrée/sortie et le partage des tâches, j'envisage dans les communications d'établir un système de priorisation des ordres.

Remarquons aussi que le débugage des programmes est facilité d'une certaine manière.

@+

Zoroastre.

PS : J'avouerais que je lorgne un peu vers la robotique en ce moment. Ce n'est pas encore ma priorité actuellement.

zoroastre:
Je vois que tu as raté un épisode...
EDIT1: Pourtant, tu étais là page 18 :stuck_out_tongue_closed_eyes:

Effectivement, j'étais là, mais ma mémoire a quelquefois besoin d'être raffraichie.

Et maintenant je comprends mieux ce dont tu parlais à ce moment là.

En fait, il y a différentes problématiques qui n'ont pas du tout besoin des mêmes temps de réponse.

Pour l'instant de la manière dont je conçois mon système de domotique les temps de réponse peuvent être lents, qu'une électrovanne, ou un chauffage se mette en ou hors circuit avec une seconde de retard n'a que très peu d'importance.

Probablement que lorsque je travaillerai sur l'interface web, les choses seront différentes, car s'il faut attendre trop longtemps pour que l'ensemble des données soient collectées puis affichées, ce sera une autre histoire !
Mais bon je n’y ai pas encore vraiment réfléchi, chaque chose en son temps.

Et évidemment pour la robotique c’est encore une toute autre chose !

@+

Yep!

Brisebee:
Probablement que lorsque je travaillerai sur l'interface web, les choses seront différentes

Je suis effectivement face à cette problématique. Mon système actuel est plutôt réactif et je n'ai pas trop à m'en plaindre. Le seul hic se situe au niveau de mon afficheur tactile, outre une latence toute naturelle due à la dalle résistive, dans mon projet initial, j'avais envisagé de positionner à deux endroits différents 2 afficheurs.
La connectique fût déjà mon premier problème et je me suis vite rendu compte également que j'allais démultiplier d'autant le nombre de cycle réquisitionné par l'arduino.

Pour l'instant, je palie au problème en désactivant soit la connection internet soit la dalle tactile en fonction d'où provient les ordres. Solution simple et efficace, mais qui limite outrageusement l'utilisation globale sans pour autant la pénaliser certes.
L'autre solution est de déporter tous les modules dans une résolution indépendante et communicative. Cependant, le protocole de com a plutôt interêt d'être costaud et de subordonner tout autre module pouvant ralentir le système global, la déléguation, le rebond, la redondance sont la clé.
La dernière solution est de disposer d'un pc serveur centralisant toutes les informations et pilotant les modules.

Mon experience a débuté sur des choses simples, celle qui sont réactives et demandent peu de travail à l'arduino. Mais plus le système évolue, plus les ressources sont sollicitées et selon les organes embarqués, la consommation devient rapidement exponentielle.

Aujourd'hui, je choisis de conserver une approche centralisée des choses et de disposer de plusieurs connectiques rs485, afficheurs, rs232, i2c, 1wire, sur une seule carte + shield. L'idée de modules déportés a fait son chemin et je l'ai aujourd'hui consideré, cependant, j'aimerais que mes modules déportés soient le plus discrets possible.

Il y a plusieurs avantages d'avoir deux cerveaux à sa disposition. Le nombre de sortie est démultiplié, les programmes sont précis et dédiés à chaque puce, les temps de cycle sont mieux maitrisés, le fonctionnement minimal est garantie si l'un des uC lache...

@+

Zoroastre.

zoroastre:
Aujourd'hui, je choisis de conserver une approche centralisée des choses

C'est aussi mon idée.

Je trouve, que globalement ta réflexion est très intéressante, mais, en fait, il faut considérer les moyens mis en œuvre par rapport à l’objectif (ou les objectifs) recherché(s).
Et les solutions retenues pour certaines situations ne sont pas forcément les meilleures pour d’autres.
C’est pour cela qu’il est important de fixer le champ des contraintes, et de rédiger un cahier des charges le plus précis possible pour chaque projet (c’est vari qu’on ne sait pas toujours jusqu’où on va aller lorsqu’on se lance dans un projet).
Ce qui ne devrait pas empêcher de mettre en œuvre des systèmes modulaires, tu as raison de dire que c’set alors les protocoles de communications qui sont à peaufiner.
Il me semble que c’est ce qu’Osaka cherche à faire (ou a fait).
@+

Salut à tous,

Depuis les derniers posts, j'avais bien progressé dans mon "espionnage" de régulateur (sondes NI1000), et puis ... BOUM : cours-jus sur le 230V-3V3, donc MEGA grillé, shield (et p-ê LCD) grillé, et ... régulation de tout mon capharnaum grillé. S**T. :-((((( Plus de solaire, plus de chauffage. Si quelqu'un est intéressé par un sketch d'oscilloscope 13 voies avec LCD 2"4 touch, je peux le poster...

Conclusion : on reprend tout à zéro. Plus besoin de penser à conserver le SAUTER, mais plutôt .. de ne pas mélanger les fils.

Première étape, installation d'un Arduino Nano sur breadboard pour remettre en route ... les trois sondes principales : T° intérieure, extérieure, capteurs. Pas très convaincant.
La feuille de calculs et le sketch est en annexe : avec le Nano en 5V et les NI1000 alimentés par D13 via une 4k7 chacun (sinon ils chauffent), mais une connexion 3V3-Aref, je pensais obtenir une résolution de 1 step/°C et un offset de 272, pas très précis mais bon ... Loupé. Mon multimètre montre bien les entrée faire 0-5V à vide et 0-1V avec la NI1000, mais les données sur l'EEPROM soit foireuses.

Ce soir/demain si tout va bien, deuxième essai avec le Nano. Quand çà marchera, je remplace par un DINo acheté le mois passé, et le Pro mini comme extension pour les sondes et les relais, peut-être avec du Firmata entre les deux. Je vous tiendrai au courant.

Pour recentrer sur le thread, l'opposition centralisé/décentralisé est aussi au coeur de mes questions. De toute façon, aucun AVR 8 bits n'a assez d'I/Os pour mon système, sauf le MEGA (16 analog ins), mais il n'était pas aisé à mettre en boîte non plus. Si la communication DINo/Pro mini se passe bien ou mal, on verra.

A+

ADC Calculs.xls (44.5 KB)

regu_mar28a.cpp (12.6 KB)

Brisebee:
C’est pour cela qu’il est important de fixer le champ des contraintes, et de rédiger un cahier des charges le plus précis possible pour chaque projet (c’est vari qu’on ne sait pas toujours jusqu’où on va aller lorsqu’on se lance dans un projet).

Je vise toujours aux plus loin (cahier des charges), pour cela la seule réponse que j'ai trouvé c'est dépendance et modularité.

Brisebee:
Ce qui ne devrait pas empêcher de mettre en œuvre des systèmes modulaires, tu as raison de dire que c’set alors les protocoles de communications qui sont à peaufiner.
Il me semble que c’est ce qu’Osaka cherche à faire (ou a fait).

C'est exact la modularité étant la réponse à certains besoins et problèmes l'impératif devient la fiabilité de communication entre ses modules.

Bon en voyant les différents montages de tout le monde je me dis qu'il serait temps d'acheter un petit fer à souder, je suis juste un peux bloquer niveau finance (Va me falloir un sponsor). :grin: