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


Messages recommandés

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

 

Modifié par Gen
  • Like 1
Lien à poster
Partager sur d’autres sites

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 !

Modifié par Omgprod
  • Like 1
Lien à poster
Partager sur d’autres sites

Pas de problème..

Mais je vais quand même ré-écrire le code. Car j'aime me faire mal :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.JPG

 

 

++

GEN

 

Modifié par Gen
  • Thanks 1
Lien à poster
Partager sur d’autres sites

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é ^_^  

Lien à poster
Partager sur d’autres sites

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

 

 

  • Like 1
Lien à poster
Partager sur d’autres sites

Re @Gen 

 

Laisse tombé pour la lib j'ai dis des conne***s comme d'hab ^^ j'ai melangé mon plus est mon moins -_-  ( 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 ? :) 

PS : What the F... , tu connectes l'I2C de l’écran sur les ports de l'horloge ...  ( pourquoi je trouve pas ça moi !!! :rolleyes: )

 

Spoiler

Screenshot_1.png.2939a1472b7b03bdf45fe5497af1fb0f.png

 

ce genre de partage aussi est très appréciable !! :wub: Thanks ! 

 

Lien à poster
Partager sur d’autres sites

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

 

Modifié par Gen
  • Thanks 1
Lien à poster
Partager sur d’autres sites

salut les gars !

Pas de soucis Omgprod

 

 

Citation

  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)

  • Thanks 1
Lien à poster
Partager sur d’autres sites

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++

Modifié par tizi59
  • Thanks 1
Lien à poster
Partager sur d’autres sites

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: 

Lien à poster
Partager sur d’autres sites
il y a 7 minutes, Omgprod a dit:

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 

 

 

 

Modifié par tizi59
Lien à poster
Partager sur d’autres sites
il y a 13 minutes, Omgprod a dit:

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.

Lien à poster
Partager sur d’autres sites
Spoiler
il y a 33 minutes, tizi59 a dit:

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.

 

 

ça va le plus dur est fait alors ;) 

 

bonne journée @tizi59

Lien à poster
Partager sur d’autres sites

Salut les loulous 

 

Vu que @Gen m'as provisoirement mis au chômage technique ^_^ 

 

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 :) 

 

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 : 

 

Spoiler

Screenshot_6.png.9ddfc0c6f5b94134157090a8c3def94f.png

pour le moment rien de très dur 

Screenshot_7.png.5ce559738024dc66b5f98954020d717b.png

un montage prototype ^_^ 

 

 

et le résultat :

Screenshot_8.png.da00bb7f74cf8490e8906d231b6f9d54.png

 

Screenshot_2.thumb.png.7faa36a3f44e96369fbd408ea72140c6.pngScreenshot_3.thumb.png.2e1956b1ed93f537be5343835fac410c.png

 

Les GPIOS ne sont pas fonctionnel pas grand chose ne l’était , peut être que sa viendras ;) 

 

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

 

Bonne Aprem ! 

 

Modifié par Omgprod
Lien à poster
Partager sur d’autres sites
Il y a 2 heures, Omgprod a dit:

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
 

Spoiler

 


//#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 : 180228-192511-uno.pdf

 

edit :

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

elle sert uniquement pour faire des tests

 

++

GEN

 

 

 

 

Modifié par Gen
  • Thanks 1
Lien à poster
Partager sur d’autres sites