[GMBB] Re-Edition de l'Automate de Windaube

re:

Pinpin.. il n'y a rien de personnel dans ce que j'ai écrit plus haut. Pas de jugement, pas de reproche.

Je suis dans le partage, je vois que ça merde, je viens vous aider.. rien de plus, rien de moins

C'est juste que ce code est mal foutu. Je vais te le réécrire et le documenter, ensuite tu pourras le modifier comme bon te semble.

Là tu apprendras plus vite ;-)

Pour le moment je me monte un Uno avec LCD 4x20 en I2c , DHT22 et boutons poussoirs histoire d'avoir le même matos que vous.

Je pense que le code sera bouclé pour fin de semaine en fonction de mon emploi du temps.

++

GEN

 
Dernière édition:
Re @Gen

Pinpin !! ^_^ Alors excuse moi de la véracité de ma réponse ! Ton message m'as un poil cassé le moral .. je code comme un fou ( avec mes pieds certes ) a trouver des bouts de code que je peux rajouter , quand je trouve , faut que je les rajoutes , un fois rajouté y'as toujours une c***lles quelque part que je passe 4 heures a corrigés ... :D
Je suis partis de ce code , car je n'ai aucun moyen de créer le miens par mes propres moyen et c'était le seul aussi lisible que facile a modifier pour une personne n'ayant jamais touché au langage C , et le matos requis est plus que minimaliste d'ou l’intérêt de partir de cette source pour un partage futur

Ne te prend pas la tête a ré-écrire le code avec tes projets en cours , j'imagine bien que tu n'as pas que ça as faire .. après si tu comme dis un de ces 4 tu le ponds .. je t'en remercie d'avance , car je pense qu'un bon code , bien fait et bien commenté ne pourras que être bénéfique a la compréhension du langage C ou même mieux aider a comprendre le code du MiniGrowDuino pour touts les novice du forum :)

Encore désolé du quiproquo @Gen, merci d'avoir rectifié ! ^_^

Passe une bonne journée !
 
Dernière édition par un modérateur:
Pas de problème..

Mais je vais quand même ré-écrire le code. Car j'aime me faire mal :fouet:/emoticons/default_fouet.gif" title=":fouet:">

PS : Je n'ai pas de boulot, car les circuits imprimés commandés n'arrivent que la semaine prochaine

Et en plus j'ai préparé le matos, et je me suis fait une 'cht'it' boîte à boutons

DSC_0290.webp

++

GEN
 
Dernière édition:
Ahhh ! bah je pense que tu vas faire des heureux y compris moi ! :) entre Papy qui est très libertin :P et toi qui fait dans Sado-masochisme je pense que je me suis peut être trompé dans le titre du site internet ou je me trouve .. :mdr:

je me permet de te poser une ou deux questions ? vue que je t'ai sous la main :D

Sur ce code que tu vas pondre y'aura t'il un exemple du fonctionnement RTC , car ce code fonctionne avec la lib DS1307 .. mais je n'ai que des horloges 3132 ( sa marche, mais la lib date et elle affiche la date et l'heure mais ne contient pas grand chose d'autre )

je voulais savoir aussi , si avec l'eeprom de l'horloge 3132 l'on pourrait automatiser une sauvegarde des datas de la DHT pour faire une page comme toi temp & humidité minimum, maximum suivis de la date a laquelle ces datas on était sauvegardés ??

Je sais pas si je me suis bien exprimé , je m'excuse d'avance pour le maux de tête occasionné ^_^
 
yop.

Sur ce code que tu vas pondre y'aura t'il un exemple du fonctionnement RTC , car ce code fonctionne avec la lib DS1307 .. mais je n'ai que des horloges 3132 ( sa marche, mais la lib date et elle affiche la date et l'heure mais ne contient pas grand chose d'autre )

?? bizarre ce que tu me racontes, lors des test de la 3132 pour mon GRCC, je n'ai rencontré aucun problème de ce coté là, car justement je voulais mettre un circuit RTC qui contient un oscillateur à l'inverse du DS1307

je voulais savoir aussi , si avec l'eeprom de l'horloge 3132 l'on pourrait automatiser une sauvegarde des datas de la DHT pour faire une page comme toi temp & humidité minimum, maximum suivis de la date a laquelle ces datas on était sauvegardés ??

Une EEPROM à une durée de vie limitée en terme de lectures et écriture, l'utiliser pour stocker autre chose que des parametres de setup est une mauvaise idée

Dans mon logiciel, les données sont stockées dans un array

Maintenant si tu veux que les données climatiques soient enregistrées de manière non volatile, 2 possibilités s'offrent à toi

1 - une sd card (perso je n'aime pas, on rencontre vite des problèmes)

2 - utiliser une ram avec maintient des données tel qu'un circuit 23LCV1024 (1Mb RAM) la solution que j'ai perso retenue pour mon shield DUE

Voila

++

GEN
 
Re @Gen

Laisse tombé pour la lib j'ai dis des conne***s comme d'hab ^^ j'ai melangé mon plus est mon moins -_-/emoticons/default_sleep.png" srcset="/emoticons/[email protected] 2x" title="-_-" width="20" /> ( pour changer )

oui j'ai lu ça a propos de sa durée de vie limité a force d'écrire dessus , c'est pour ça que je venais a toi ...sur cette question , une pichenette derrière les oreilles ... et ou est ce que tu stock ces données volatile ? :)/emoticons/default_basic-smile.png" srcset="/emoticons/[email protected] 2x" title=":)" width="18" />
PS : What the F... , tu connectes l'I2C de l’écran sur les ports de l'horloge ... ( pourquoi je trouve pas ça moi !!! :rolleyes:/emoticons/default_rolleyes.gif" title=":rolleyes:" /> )

Screenshot_1.webp

ce genre de partage aussi est très appréciable !! :wub:/emoticons/default_wub.png" title=":wub:" /> Thanks !
 
LOL

Je stocke les données volatile dans une table mémoire (Array)

ci dessous un exemple

les lignes 0 et 1 temperature Min Max

les lignes 2 et 3 humidité Min Max

Exemples d'utilisation

void resetMinMax()

{

int t = temperature;

int h = humidity;

for(int i = 0; i<=1 ; i++)

{

minMaxTable[0] = t;

minMaxTable[1] = now.day();

minMaxTable[2] = now.month();

minMaxTable[3] = now.hour();

minMaxTable[4] = now.minute();

}

for(int i = 2; i<=3 ; i++)

{

minMaxTable[0] = h;

minMaxTable[1] = now.day();

minMaxTable[2] = now.month();

minMaxTable[3] = now.hour();

minMaxTable[4] = now.minute();

}

}

void fillMinMaxTable(int indice, int newValue)

{

minMaxTable[indice][0] = newValue;

minMaxTable[indice][1] = now.day();

minMaxTable[indice][2] = now.month();

minMaxTable[indice][3] = now.hour();

minMaxTable[indice][4] = now.minute();

}

void recordMinMax()

{

int newt = temperature;

int newh = humidity;

if(newt < minMaxTable[0][0]){fillMinMaxTable(0,newt);}

if(newt > minMaxTable[1][0]){fillMinMaxTable(1,newt);}

if(newh < minMaxTable[2][0]){fillMinMaxTable(2,newh);}

if(newh > minMaxTable[3][0]){fillMinMaxTable(3,newh);}

}

++

GEN
 
Dernière édition:
salut les gars !

Pas de soucis Omgprod

heure = RTC.get(DS1307_HR, true);
minut = RTC.get(DS1307_MIN, false);
seconde = RTC.get(DS1307_SEC, false);
date = RTC.get(DS1307_DATE, false);
mois = RTC.get(DS1307_MTH, false);
annee = RTC.get(DS1307_YR, false);
temps_perso = (heure * 100) + minut; //creation temps_perso

l"erreur est ici non ? :culture:

minut = RTC.get(DS1307_MIN, false);

temps_perso = (heure * 100) + minut;

regarde bien ta oublié le "e" sur minute

peace B)
 
re:

Cette librairie c'est du concentré de daube en bouteille.

Faut trouver une librairie avec l'utilisation du DateTime now

++

GEN

 
re

perso j' ais fais ça pour la tmax/hmax et tmin/hmin et sa fonctionne

la tempMax et Min est "sauvegarder ?" pendant 24h

int tmin=100;
int tmax=0;
int hmin=100;
int hmax=0;

float t = dht.readTemperature(); //dht22

float h = dht.readHumidity();

int TabEvt [1][3] = {{9,6,00},}; // grow
int TabEvt1 [1][3] = {{11,00,00},}; // flow

if(t >= tmax)

{ tmax=t; }

if(t <= tmin)

{ tmin=t; }

if(h >= hmax)

{ hmax=h; }

if(h <= hmin)

{ hmin=h; }

/ je réinitialise la tmax/hmax et tmin/hmin a l'allumage à l'aide d'un tableau d' événement
if ((digitalRead(A2) == true) && now.hour() == TabEvt [0][0] && now.minute() == TabEvt [0][1] && now.second() == TabEvt [0][2] )

{tmax=0;tmin=100;hmax=0;hmin=100;}
if ((digitalRead(A2) == false) && now.hour() == TabEvt1 [0][0] && now.minute() == TabEvt1 [0][1] && now.second() == TabEvt1 [0][2] )

{tmax=0; tmin=100;hmax=0;hmin=100;}

a++
 
Dernière édition par un modérateur:
Yo @tizi59 & @Gen

Déjà je vous remercie pour les exemples et les bouts de code avec explications !

la table mémoire Array :plus: c'est vraiment sympa de votre part !

Et oui c'est ce que je voulais dire hier a propos de la lib je parlais pas de la 3132 mais de la DS1307 qui apars afficher l'heure ne fait pas grand chose -_-

T'es chaud coquin de @tizi59:mdr::mdr:
 
PTDRRR , par ce que tu codes et tu te débrouilles plus que bien a ce que je vois !! :)

donc oui t'es chaud , mon gars ! :D
 
PTDRRR , par ce que tu codes et tu te débrouilles plus que bien a ce que je vois !! :)

donc oui t'es chaud , mon gars ! :D

je suis dans le même cas que toi

j'ais commencer en bidouillant le code à windaub pour finalement le changer entièrement gràce aux infos de gen et de google mais je suis novice avec peut-etre quelque moi d'avance sur toi lol.

j 'ai "codé" un automate pour mon aqua au passage :D lol

peace
 
Dernière édition par un modérateur:
Ah bah sa fait plaisir a entendre , je comprend mieux les j’aimes sur des commentaires :D

GG a toi maggle ! Partit de rien , mais tu gères pas mal la fougère ;)

Peace Tizi :)
 
Ah bah sa fait plaisir a entendre , je comprend mieux les j’aimes sur des commentaires :D

GG a toi maggle ! Partit de rien , mais tu gères pas mal la fougère ;)

Peace Tizi :)

merci pour le moment mon code gère uniquement croissance et floraison donc la prochaine étape seras l'ajout de la gestion du séchage

peace.
 
Salut les loulous

Vu que @Gen m'as provisoirement mis au chômage technique ^_^/emoticons/default_happy.png" srcset="/emoticons/[email protected] 2x" title="^_^" width="20" />

Je suis tombé sur une source qui date un peu mais un truc vraiment sympa , qui m'intéresse assez vu le coté WIFI et le coût hardware ( wemos + dht = 7.50euro ) je le modifie pour ma box en ce moment même , j'aimerais avoir vos avis si cela pourrait vous intéressez :)/emoticons/default_basic-smile.png" srcset="/emoticons/[email protected] 2x" title=":)" width="18" />

tout n'est pas encore fonctionnel , et pour le moment c'est héberger sur le wifi ( réseau local ) je vais voir pour rediriger le port et d'avoir un accès a l’interface ou que l'on soit
Je vous montre :

Screenshot_6.webp

pour le moment rien de très dur

Screenshot_7.webp

un montage prototype ^_^/emoticons/default_happy.png" srcset="/emoticons/[email protected] 2x" title="^_^" width="20" />

et le résultat :

Screenshot_8.webp

Screenshot_2.webp

Screenshot_3.webp

Les GPIOS ne sont pas fonctionnel pas grand chose ne l’était , peut être que sa viendras ;)/emoticons/default_wink.png" srcset="/emoticons/[email protected] 2x" title=";)" width="20" />

J'attend vos avis et si intéressés je vous ferais un beau tuto avec tout les liens d’origines (y)

Bonne Aprem !
 
Dernière édition par un modérateur:
Vu que @Gen m'as provisoirement mis au chômage technique ^_^

Re : La récré est terminée, fini de te tourner les pouces !!

Le code est restructuré et les fioritures ont été supprimées

J'ai mis en remarque la création des Char car la définition n'en était pas correcte, on créé des array de 8 bytes et on n'en défini que 7 .. Cherchez l'erreur :-)

Vous trouverez dans l'archive, toutes les bonnes librairies pour faire tourner ce projet

Dorénavant, vous pouvez utiliser ce que vous voulez comme RTC, toutes les définitions se trouvent dans le code,

suffit de mettre en remarque ce que vous n'utilisez pas.

Je n'ai bien entendu pas fait le programme à ta place, j'ai assez de taf pour le moment, mais le squelette est complet et cohérent.

Il ne te reste plus qu'à arranger les écran à ta sauce et de faire un setup si nécessaire.

Certaines personnes n'ont pas besoin de setup et mettent les valeurs dans le code en 'dur', chacun fera comme il lui plaira.

Attention, l'assignation des pin a été modifiée !!

le programme fait 330 lignes au lieu de 700.. à l'origine, ce qui fait que vous avez encore plein de place pour faire ce que vous voulez

voici le récap de compil

Device: atmega328p

Program: 11706 bytes (35.7% Full)

(.text + .data + .bootloader)

Data: 741 bytes (36.2% Full)

(.data + .bss + .noinit)

J'ai codé de façon à ce que l'écran principal change toutes les 5 secondes sans utiliser la fonction millis()

Supprimez le si vous voulez, c'est juste fourni à titre d'exemple

A vous de gérer la manière de changer de mode (croissance, floraison, fin de floraison) via un setup et du code, ou à l'aide d'un interrupteur 3 positions, ou automatiquement en fonction des jours écoulés (c'est vous qui voyez)

Par défaut il est mis à croissance

voici le code

//#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Arduino.h>
#include <RTClib.h>
#include <DHT.h>
#include <DailyTimer.h>
#include <CyclicTimer.h>

#define DHTTYPE DHT22
#define CROISSANCE 0
#define FLORAISON 1
#define SECHAGE 2

#define DAY_DURATION_ON 0
#define DAY_DURATION_OFF 1
#define NIGHT_DURATION_ON 2
#define NIGHT_DURATION_OFF 3

#define PotPIN A0 // pas utilisé

#define cyclicPin 12
#define hygroPin 11
#define extractPin 10
#define chauffagePin 9
#define lampePin 8
#define dhtPin 6

#define MIN 0
#define MAX 1

// Activez la ligne correspondante à votre type de RTC
//DS1307 rtc;
//RTC_Millis rtc;
DS3231 rtc;
//PCF8563 rtc;
//PCF8583 rtc;
//DS1302 rtc(CE_PIN,SCK_PIN,IO_PIN);
//DS1302 rtc;// CE_PIN 4, SCK_PIN 5, IO_PIN 6 as default

DailyTimer lampe(lampePin);
CyclicTimer brasseur(cyclicPin);
LiquidCrystal_I2C lcd(0x3F, 20, 4);
DHT dht(dhtPin, DHTTYPE);

DateTime now;

const int UP = 1;
const int DOWN = 2;
const int ENTER = 3;

//------------- Reglage Temperature , Hygro , Extracteur ------------
bool hygroFlag = false;
bool chauffageFlag = false;
bool ventilFlag = false;

float t = 0.0;
float h = 0.0;

float chauffage_on = 23.00;
float chauffage_off = 24.00;
float extracteur_on = 70.00;
float extracteur_off = 15.00;

// MIN MAX
float hygro[3][2] = {{ 20.00, 80.00}, // CROISSANCE
{ 20.00, 60.00}, // FLORAISON
{ 20.00, 50.00}}; // FIN DE floraison

//les temps sont à définir en secondes (valeurs ci-dessous pour test)
int brasseur_duree_jour_ON = 2;
int brasseur_duree_jour_OFF = 2;
int brasseur_duree_nuit_ON = 1;
int brasseur_duree_nuit_OFF = 1;

bool firstScreen = true;
bool displayed = true;

int sol = 0;

int GROWMODE = 0 ; // CROISSANCE tu pourras modifier le status via un interrupteur 3 pos ou via le code ou menu etc..

void initializeLamp()
{
lampe.setValue(GROW_START,00,00); // 05:00
lampe.setValue(GROW_STOP ,18,00); // 23:00
lampe.setValue(FLO_START ,11,20); // 11:20
lampe.setValue(FLO_STOP ,23,20); // 23:20
}

void initializeIO()
{
pinMode(UP, INPUT);
pinMode(DOWN, INPUT);
pinMode(ENTER, INPUT);
for(int i = 9 ; i <= 11 ; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
}

void charCreation()
{
//lcd.createChar(coeur, COEUR);
//lcd.createChar(carre, CARRE);
//lcd.createChar(rond, ROND);
//lcd.createChar(cel, CEL);
//lcd.createChar(temp, TEMP);
//lcd.createChar(canna, CANNA);
//lcd.createChar(goutte, GOUTTE);
//lcd.createChar(ampoule, AMPOULE);
}

void initializeLCD()
{
lcd.init();
lcd.backlight();
}

void initializeBrasseur()
{
brasseur.initialise(DAY_DURATION_ON,brasseur_duree_jour_ON);
brasseur.initialise(DAY_DURATION_OFF,brasseur_duree_jour_OFF);
brasseur.initialise(NIGHT_DURATION_ON,brasseur_duree_nuit_ON);
brasseur.initialise(NIGHT_DURATION_OFF,brasseur_duree_nuit_OFF);
}

void intro()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" GrowMyBox Bitch's ");
lcd.setCursor(0, 1);
lcd.print(" Thank's to ");
lcd.setCursor(0, 2);
lcd.print(" Windaube & Gen ");
lcd.setCursor(2, 3);
lcd.print("OMGPROD Edition ");
delay(3000);
lcd.clear();
}

int convertTimeInMinute(int hour, int minute)
{
return (hour * 60) + minute;
}

void setup()
{
initializeLamp();
initializeIO();
initializeLCD();
initializeBrasseur();
//charCreation(); à activer quand la definition des bytes char sera correcte
Serial.begin(9600); // a utiliser pour debugger sur le terminal
dht.begin();
rtc.begin();
// rtc.adjust(DateTime(__DATE__, __TIME__));
intro();
}

void catchData()
{
now = rtc.now();
float temporaryVal;
delay(10);
// ce code permet de garder la dernière valeur correcte
temporaryVal = dht.readTemperature();
if(!isnan(temporaryVal)){t = temporaryVal;}
delay(10);
temporaryVal = dht.readHumidity();
if(!isnan(temporaryVal)){h = temporaryVal;}
delay(10);
//setMinMaxToMemory();
}

void hygroProcess()
{
if(h < hygro[GROWMODE][MIN] && !hygroFlag) {hygroFlag = true;}
if(h > hygro[GROWMODE][MAX] && hygroFlag){hygroFlag = false;}
digitalWrite(hygroPin, hygroFlag);
}

void heatProcess()
{
if(t >= chauffage_off){chauffageFlag = false;}
if(t >= chauffage_on){chauffageFlag = true;}
digitalWrite(chauffagePin,chauffageFlag);
}

void ventilProcess()
{
if(t >= extracteur_on){ventilFlag = true;}
if(t <= extracteur_off){ventilFlag = false;}
digitalWrite(extractPin,ventilFlag);
}

void executeProcess()
{
lampe.run(convertTimeInMinute(now.hour(),now.minute()),GROWMODE); // lampe
hygroProcess(); // hygro
brasseur.run(now.unixtime(),lampe.isWorking()); // brasseur
Serial.println(now.unixtime());
ventilProcess(); // extracteur
heatProcess(); // chauffage
}

String formatIntNumberInXdigits(int number, int nbDigit)
{
String stringNumber = String(number);
while(stringNumber.length() < nbDigit)
{
stringNumber = "0"+stringNumber;
}
return stringNumber;
}

String getTimeFormated()
{
return formatIntNumberInXdigits(now.hour() , 2) + ":" +
formatIntNumberInXdigits(now.minute(), 2) + ":" +
formatIntNumberInXdigits(now.second(), 2);
}

String getDateFormated()
{
return formatIntNumberInXdigits(now.day() , 2) + "/" +
formatIntNumberInXdigits(now.month(), 2) + "/" +
formatIntNumberInXdigits(now.year(), 2);
}

void displayMainScreen()
{
lcd.setCursor(0,0);
lcd.print(getTimeFormated() + " " + getDateFormated());
lcd.setCursor(0,1);
lcd.print("TEMP:");
lcd.print(t);
lcd.setCursor(11,1);
lcd.print("HR:");
lcd.print(h);
lcd.setCursor(0,2);
lcd.print("MODE: ");
switch (GROWMODE)
{
case 0: lcd.print("CROISSANCE ");break;
case 1: lcd.print("FLORAISON ");break;
case 2: lcd.print("FIN FLORAISON");break;
}
lcd.setCursor(0,3);
if(lampe.isWorking())
{
lcd.print("LAMPE : ALLUMEE ");
}
else
{
lcd.print("LAMPE : ETEINTE ");
}
}

String return_ON_OFF(bool value)
{
String label[2] = {"OFF","ON "};
return label[value];
}

void displaySecondaryScreen()
{
lcd.setCursor(0,0);
lcd.print("Chauffage :");
lcd.print(return_ON_OFF(chauffageFlag));
lcd.setCursor(0,1);
lcd.print("Ventilation:");
lcd.print(return_ON_OFF(ventilFlag));
lcd.setCursor(0,2);
lcd.print("Brumisateur:");
lcd.print(return_ON_OFF(hygroFlag));
lcd.setCursor(0,3);
lcd.print("Brasseur :");
lcd.print(return_ON_OFF(brasseur.isWorking()));
}

void loop()
{

catchData(); // a partir d'ici les variable sont assignées ( t h et now)

if(now.unixtime()%5 == 0 && displayed == false )
{
lcd.clear();
firstScreen = !firstScreen;
}

if(firstScreen) // changement d'écran toutes les 5 secondes (exemple)
{
displayMainScreen();

}
else
{
displaySecondaryScreen();
}
displayed = true;
if(now.unixtime()%5 !=0 && displayed == true) {displayed = false;}

executeProcess();

//************************************************************************
//** A partir d'ici on peut mettre le traitement d'appuis sur un bouton pour
//** rentrer dans un setup etc..
//************************************************************************

// buttonState1 = digitalRead(bp1);
// buttonState2 = digitalRead(bp2);
// buttonState3 = digitalRead(bp3);
}

l'archive complète en Zip et renommée en pdf pour pouvoir la télécharger :

edit :

vous pouvez supprimer la ligne 208 Serial.print(now.unixtime());

elle sert uniquement pour faire des tests

++

GEN
 
Dernière édition:
Retour
Haut