Go Down

Topic: Homeduino : E/S pour la Domotique via Box (Read 3859 times) previous topic - next topic

Xiboard

Jan 21, 2014, 11:24 am Last Edit: Jan 27, 2014, 01:19 pm by Xiboard Reason: 1
Bonjour à tous,

Alors je vais vous présenter l'un de mes petit projet.
Il n'est pas très compliqué mais je suis sûr qu'il pourra servir à certain.

Préambule :
Je remercie avant tout, tous les personnes qui ont pu contribuer à l'avancement de mes projets.  :)
Je pense particulièrement à Skywodd pour son blog (http://skyduino.wordpress.com/author/skywodd/) très riche  :smiley-mr-green: . Mais aussi le site http://www.sonelec-musique.com/ qui regorge de montages élec super bien expliqués. Merci aussi à ceux qui publient leur réal ça aide bien au début. J'en oubli sûrement...

Description :
Donc mon projet est relativement simple. L'objectif est d'avoir des Entrées/Sorties pour la domotique le moins cher possible et le plus flexible possible. Si en plus c'est pas trop prise de tête et que ça demande pas un gros investissement (coût et temps) super ! Donc avec tout ça je me suis dirigé vers une solution Arduino.
Je ne veux pas tirer des câbles partout mais je ne suis pas fan non plus des radio fréquences.
Donc pour moi l'idéal est la communication via les prises ethernet.
Voilà donc pour faire simple : Arduino Uno(ou Mega) + Shield Ethernet !

J'ai donc une box domotique (Zibase) avec laquelle je commande ou lis mon arduino via des commandes http. L'arduino renvoie toujours un xml avec les infos importantes. L'arduino est aussi capable de commaner via pushingbox ou directement la zibase. (non utilisé encore dans ce programme)

Dans mon cas présent j'ai installé des spots sur tout le tour de la maison [en cours pas fini l'avant]. Je veux pouvoir commandé l'allumage de chaque spot indépendamment. J'utilise donc une carte Relais à 16 Relais. (sainsmart)
Avec une Uno ça condamne bcp de ports donc j'ai choisi d'utiliser 2 74HC595 pour les relais.

La commande indépendante des spots me permet de faire des chenillard extérieur !!! Un vrai sapin de noel la maison. ça permet aussi de faire un retour d'état de l'alarme en cas d'alerte.

Par rapport à la situation géographique de l'installation, j'en profite pour mesurer la température du ballon d'eau chaude de la chaudière fuel. Mais aussi pour détecter lorsque le brûleur de la chaudière est en fonctionnement. Pour cela je détecte la présence de 230V au brûleur.
L'objectif final est savoir par jour la conso en fuel et donc le coût. (Les infos brutes sont envoyé sur un MySQL ensuite c'est tout un site en php qui s'occupe de faire les calculs et qui affiche les graphiques via highcharts )

Je ne suis pas développeur. Je suis ingénieur, j'ai des bases un peu partout mais un peu quoi !
Donc mon code est très certainement à optimiser.

C'est d'ailleurs aussi ça qui est important dans le partage donnant/donnant.

Perspectives :
Etant sur un Arduino Uno ça limite quand même pas mal le prog. Je ferai une présentation d'un autre de mes projet identique : La gestion de mon portail/sonnette/Boite au Lettres/Autres. Sauf que j'ai mis un ici un Mega qui me laisse bcp plus de marge.

Pour celui ci, à court terme je doit rajouter un inter poussoir (déjà présent dans la maison) pour commander les spots sans passer par la box domotique. (Telephone, Telco ou Scénarios)

Sur le long terme, je prévoit chez moi de recâbler l'ensemble des éclairages. Tout câbler en étoile sur des relais (via des interrupteurs surement). Idem tout les inter en poussoir câblés sur l'arduino. Ensuite la programmation permettra de faire ce qu'on veux avec les inter. Une gestion multi-clic est aussi envisageable.

Détails techniques :
* Entrés :
 - Etat brûleur via un montage élec (je détaillerai plus tard) (redresseur, résistance, diode, optocoupleur)
 - Température avec DS18B20 moulé/câblé (http://dx.com/p/water-proof-ds18b20-temperature-probe-90cm-142889#.Ut5MRxBKFaQ)

* Sorties :
 - Led verte (Elle clignote en permanence via le code) pour savoir si le code est planté
 - 16 Relais via 3 fils avec les 74HC595

Xiboard

#1
Jan 21, 2014, 11:27 am Last Edit: Sep 29, 2014, 08:33 am by Xiboard Reason: 1
Le code :

Cette dernière version du code est en bêta car je teste une simplification pour les chenillard. Avant j'avais fait une fonction par chenillard en faisant des boucles for bien faites. La j'ai choisi de passer par des tableau avec l'etat direct des spots. C'est plus flexible et moins prise de tête.

Par contre j'ai bien gagné sur le poids du programe (74% de l'Uno) mais par contre j'ai perdu sur la RAM dispo. Je pense que je ne gère pas bien du tout les tableau chenillards (hisoitre de const et pointeurs ?)
Bref il y a une optimisation à faire.

Skywodd je sais qu'il faut pas utiliser des 'String' mais j'ai pas réussi à les remplacer par des char, ça compile pas. J'ai pas réussi a débuger.

Les commandes http :
http://192.168.0.01/?SpotsExAr/All/On
http://192.168.0.01/?SpotsExAr/All/Off
http://192.168.0.01/?SpotsExAr/All/ProgOn/DR
http://192.168.0.01/?SpotsExAr/All/ProgOn/DL
http://192.168.0.01/?SpotsExAr/All/ProgOn/GR
http://192.168.0.01/?SpotsExAr/All/ProgOn/GL
http://192.168.0.01/?SpotsExAr/All/ProgOff/DR
http://192.168.0.01/?SpotsExAr/All/ProgOff/DL
http://192.168.0.01/?SpotsExAr/All/ProgOff/GR
http://192.168.0.01/?SpotsExAr/All/ProgOff/GL
http://192.168.0.01/?SpotsExAr/All/C1
http://192.168.0.01/?SpotsExAr/All/C2
http://192.168.0.01/?SpotsExAr/All/C3
http://192.168.0.01/?SpotsExAr/All/C4
http://192.168.0.01/?SpotsExAr/All/C5
http://192.168.0.01/?SpotsExAr/All/C6
http://192.168.0.01/?SpotsExAr/PorteEntree/On
http://192.168.0.01/?SpotsExAr/PorteEntree/Off
http://192.168.0.01/?razEtat
http://192.168.0.01/?alerte=1
http://192.168.0.01/?alerte=0
http://192.168.0.01/?info
http://192.168.0.01/?freeMemory

Exemple de retour :
Code: [Select]

<doc ar="arduinoEclairageMaisonExterieur">
<temperatureEau>43.50</temperatureEau>
<tempEauforzibase>435.00</tempEauforzibase>
<SpotState1>0</SpotState1>
<SpotState2>0</SpotState2>
<SpotState3>0</SpotState3>
<SpotState4>0</SpotState4>
<SpotState5>0</SpotState5>
<SpotState6>0</SpotState6>
<SpotState7>0</SpotState7>
<SpotState8>0</SpotState8>
<SpotState9>0</SpotState9>
<SpotState10>0</SpotState10>
<SpotState11>0</SpotState11>
<SpotState12>0</SpotState12>
<SpotState13>0</SpotState13>
<SpotState14>0</SpotState14>
<SpotState15>0</SpotState15>
<SpotState16>0</SpotState16>
<etatBruleur>0</etatBruleur>
<freeMemory>1307</freeMemory>
<etat>OK</etat>
</doc>


Changelog
V2.2 22/01/32014
 -Finalisation Alerte
 -bugs dans Play corrigés
V2.3 22/01/2014
 -modif taille tableau Play
 -modif fonction Play avec pointeur (aucune amélioration mémoire :/)
 -chenillards en PROGMEM (là un bon gain de mémoire)
V2.4 27/01/2014
 -Rajout Chenillard
 -Fonction carnaval
 -Temperature interne
V2.5 01/02/2014
 -Rajout fction repetion sur MySQL echoué
 -Modif de la fction repetition sur Psuhingbox
 -Modif des tempos pour sauvegarder les relais et les ampoules.
V2.6 19/03/2014
 -Rajout timer pour envoie EtatBruleur (periode 5min)
 
V3 21/07/2014
 -Rajout fonction spots On/Off Forcé
 -Modif Off si déjà Off et On si déjà On !! ( CompareAllSpots(1) renvoie 1 si  un ou plus des spots est different de l'ancien état. )
 -Desactivation Pushingbox & Zibase Scenario
 -Alerte Corrigé
V3.1 26/09/2014
  -Rajout F() sur Etat
  -Modif PulseLed 'fonction'
  -BugFix : MySQL lastmillis

Bonjour,

Très intéressant. Je n'y connais rien en brûleur: si je comprends bien, à partir du moment où il fonctionne, le débit de carburant est toujours le même et donc il te suffit de mesurer le temps de fonctionnement pour connaître la consommation ?

Xiboard

#3
Jan 21, 2014, 11:36 am Last Edit: Jan 21, 2014, 11:42 am by Xiboard Reason: 1
Oui grosomodo le débit est le même temps qu'il fonctionne.
C'est une approx mais ça donne un bon ordre d'idée je pense.

Xiboard

Photos :

Mise en place de l'ensemble dans un boitier type tableau disjoncteur avec porte plexi :



Montages :

A Venir.

Xiboard

J'ai donc une question pour optimiser le code :

C'est sur la fonction play :

Code: [Select]
void Play(const boolean TableauSpot[][9], long delai, boolean onoff)
{
  int tailleBoucle = sizeof(TableauSpot)/sizeof(boolean);
  for(int i=0;i<=tailleBoucle;i++){
   for(int l=0;l<=15;l++){
     onoff ? SpotState[i]=TableauSpot[i][l] : SpotState[i]=!TableauSpot[i][l];
   }
   SpotsUpdate();
   delay(delai);
  }
}


Je déclare des tableau ensuite :
Code: [Select]
const boolean chenillard1[5][9]={
{1,0,0,0,0,0,0,0,1},
{1,1,0,0,0,0,0,1,1},
{1,1,1,0,0,0,1,1,1},
{1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1}};


Il ne vont pas changer pendant le code eux.

J'appel la fonction par :

Code: [Select]
Play(chenillard1,250,1)

Plus j'appel la fonction plus je perd de mémoire :

Actuellement j'ai :

Code: [Select]
Le croquis utilise 24 216 octets (75%) de l'espace de stockage de programmes. Le maximum est de 32 256 octets.
Les variables globales utilisent 1 168 octets (57%) de mémoire dynamique, ce qui laisse 880 octets pour les variables locales. Le maximum est de 2 048 octets.


Si j'enlève les appels de la fonction play (qui prend en paramètre un tableau) :

Code: [Select]
Le croquis utilise 23 452 octets (72%) de l'espace de stockage de programmes. Le maximum est de 32 256 octets.
Les variables globales utilisent 744 octets (36%) de mémoire dynamique, ce qui laisse 1 304 octets pour les variables locales. Le maximum est de 2 048 octets.


Quelqu'un  à une explication ? Comment améliorer le truc ?
Merci ;)

Xiboard

Bon j'avais quelques petites erreurs dans ma fonction play. Celle ci fonctionne :

Code: [Select]
void Play(const boolean TableauSpot[][9], long delai, boolean onoff, int tailleBoucle)
{
  //int tailleBoucle = sizeof(TableauSpot)/sizeof(boolean);
 
  for(int i=0;i<tailleBoucle;i++){
   for(int s=0;s<=8;s++){
     //onoff ? SpotState[l]=TableauSpot[i][l] : SpotState[l]=!TableauSpot[i][l];
     if(onoff){
       SpotState[s]=TableauSpot[i][s];
     }else{
       SpotState[s]=!TableauSpot[i][s];
     }
   }
   SpotsUpdate();
   delay(delai);
  }
}


Par contre j'ai du passer en paramètre la taille du tableau. A cause encore une fois d'une histoire de pointeur je pense.
Le int tailleBoucle = sizeof(TableauSpot)/sizeof(boolean); dans la fonction ne fonctionne pas.

Mon prog fonctionne bien mais actuellement il me laisse seulement 590 de Ram (freeMemory). J'aimerai trouver comment utiliser la méthode des tableau à deux dimension sans pourrir la mémoire.
Des pistes ?

PS: je met à jour les fichier du code

Xiboard

#7
Jan 22, 2014, 02:04 pm Last Edit: Jan 22, 2014, 02:09 pm by Xiboard Reason: 1
Ok, j'ai réussi avec les pointeurs mais ça ne libère pas ma mémoire dynamique pour autant  :smiley-yell: :

Voici un code 'type' qui marche  :
Code: [Select]
const boolean chenillard1[5][9]={ //chenillard1[][9] marche aussi
{1,0,0,0,0,0,0,0,1},
{1,1,0,0,0,0,0,1,1},
{1,1,1,0,0,0,1,1,1},
{1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1}};

#define sizeTab(array) (sizeof(array)/sizeof(*array))

boolean SpotState[16];

void setup() {
 // put your setup code here, to run once:
}

void loop() {
 // put your main code here, to run repeatedly:
Play(*chenillard1,sizeTab(chenillard1),0);
Play(*chenillard1,sizeTab(chenillard1),1);
}

void Play(const boolean *TableauSpot, int tailleBoucle, int state) //TableauSpot[][9]
{
 //int tailleBoucle = sizeof(TableauSpot)/sizeof(boolean);
 
 for(int i=0;i<tailleBoucle;i++){
  for(int j=0;j<=8;j++){
    SpotState[j]=*(TableauSpot+((i*8)+j));
  }
 }
}


Bon je vais m'atteler à passer par PROGMEM...

Xiboard

Bon j'attire pas les foules on dirait !  :smiley-roll-sweat:

Quoi qu'il en soit j'ai réussit à faire ce que je voulais avec PROGMEM.

ça doit être encore optimisable mais là j'occupe 36% de RAM du Uno, ça me va bien.

Je doit encore changer les String en char et peut-être passer les chenillards en 2 bytes plutôt que en 16 boolean qui occupent au final plus de place. Si je dit pas de conneries.

J'ai mi à jour le code.

Artouste


Bon j'attire pas les foules on dirait !  :smiley-roll-sweat:



bonjour
tu es dans la section realisations et projets finis avec une balise [en cours]  :smiley-mr-green:
c'est pas le meilleur endroit pour avoir de l'aide   8)

Xiboard

Bah oui, c'est une réalisation !  :P

Je vais virer le [en cours] je pense, maintenant elle est fonctionnelle et c'est seulement des évolutions qui vont suivre.

J'espère que mon partage peu servir à d'autres.

Xiboard

Voilà, c'est finalisé pour le moment.
Ca tourne nickel.

Je ferai un retour de mon montage de détection du 230V. (et aussi sur le topic dédié)

debrouille

Bonjour,

Très intéressé par votre projet..., aimerais realiser un mini projet domotique pour l
a gestion de l ouverture de store verticaux ou californiens dans une véranda
Avec suiveur solaire ( capteurs, moteurs, sonde de température,  etc...) via un bis sur
Reseaux électrique. .., voila en gros le projet peut être un complément a d'autre (s)...?
En espérant d'avoir des retour positif... bon courage a tous...
Gilbert.

B83s

Salut,
Ton chenillard et le tableau qu'il utilise semble poser soucis ... Je pense que tu peux te passer des tableaux (qui n'évoluent pas dans le programme) en codant les étapes du chenillard dans le play et en lui passant en argument un paramètre étape qui varie de 1 a 10
Ex
Si étape = 1  allumer 1 et 9
Si étape = 2 allumer 2 et 8 ( ou inverser l'état)
Si Étape 3=3 allumer 3 et 7
Si Étape =4 allumer 4 et 6
Si Étape = 5 allumer 5
Si Étape =6 éteindre 5 ... Et ainsi de suite
...
Si étape = 10, alors étape = 1  //pour recommencer
....


Xiboard

Salut à tous,

Après de nombreux mois d'utilisation, ça marche impec.

J'ai encore un souci mineur : Au bout de plusieurs jours d'utilisation la LED verte ne clignote plus !
Pourtant tout marche impec mais cette LED reste bloquée allumé ou éteinte. Des fois au bout d'une heure, elle a changée d'état.
Comme si la valeur fadeAmount était autre que 1 ou -1 ! Peut-être un dépassement de mémoire provoque ça ?

La détection du 220V ne marche pas super non plus, ça coïncide peut être avec ce problème.


A voir...

Go Up