Premier projet !

Bonjour, je me présente Raphael 29 ans, Menuisier Agenceur et passionné d'hardware et d'aquariophilie.

Voila je me suis inscrit car je m'aide presque tout les jours sur le forum Arduino pour mon premier projet.

Celui consiste a créer un petit automate pour mon aquarium.

Liste matériel:

Arduino Uno Rev3 LCD 16x2 Module RTC DS3231 Sonde étanche DS18B20 Sonde PH H-101 Relay Grove 10A-250V Capteur de niveau d'eau

Le but final du projet étant d'avoir un contrôle continue et affiché des informations suivantes.

Date/Heure Temp de l'eau PH de l'eau Niveau de l'eau

Activation chauffage si température trop basse.

Par la suite je veut grâce a un module GSM/GPRS pouvoir consulter via SMS mes paramètres d'eau quand je suis en vacances ou au boulot.

Une alerte en cas de baisse brut du niveau d'eau.

Voila pour le départ ca sera surement agrémenté par la suite.

Il est donc possible au vu de mes faibles compétences en C++ que je requiert votre aide pour mon projet.

Bonne journée :)

Sympa comme projet !

Pour bien commencer, tu peux lire le tutoriel d'eskimon qui t'apportera presque toutes les connaissances utiles pour ton projet, à compléter uniquement avec les spécifications/besoins particuliers de tes capteurs & actuateurs.

bonne chance !

Voila j’ai fais mon câblage et mon code mais je me heurt a un petit soucis.

J’arrive a afficher sur mon écran la date et le PH mais pas la température, par contre si je vire le PH du code la température apparaît. Tout ca me laisse un peu perplexe.

Voici mon code si vous avez une idée.

// LIBRAIRIES


#include <OneWire.h> // Sonde PH + Sonde Temperature
#include <LiquidCrystal.h> // Ecran LCD
#include <DS3231.h> // Module Horloge


// ECRAN


LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PINS de l'ecran


// HORLOGE ET DATE


DS3231 clock;
RTCDateTime dt;


// SONDE PH


#define SensorPin 0          //ENTREE ANALOGUE DE LA SONDE PH
unsigned long int avgValue;  //STOCKAGE VALEUR
float b;
int buf[10],temp;


// SONDE TEMPERATURE DS18B20


// Variables propres au DS18B20
const int DS18B20_PIN=3;
const int DS18B20_ID=0x28;
// Déclaration de l'objet ds
OneWire ds(DS18B20_PIN); // on pin DS18B20_PIN (a 4.7K resistor is necessary)

// Variables générales
float DS18B20_temperature;
const int SERIAL_PORT=9600;


// SEQUENCE UNIQUE DE DEMARRAGE


void setup() 

{
  Serial.begin(9600); // VITESSE EN BAUDS
  Serial.println("Initialisation du programme");
  lcd.begin(16,2); // DEMARRAGE ECRAN EN 16X2
  lcd.clear(); // NETTOYAGE ECRAN
  clock.begin(); // DEMARRAGE MODULE HORLOGE ET DATE
  clock.setDateTime(__DATE__,__TIME__); // RECTIFICATION HEURE ET DATE
}


// SEQUENCE REPETEE


void loop()
 

// CODE AFFICHAGE DS18B20


{
DS18B20_temperature = getTemperatureDS18b20(); // On lance la fonction d'acquisition de T°
// on affiche la T°
lcd.setCursor(11, 1);
lcd.print(DS18B20_temperature,1);
}
 
/* --------------- Acquisition de la température ----------------------------------- */
float getTemperatureDS18b20(){
byte i;
byte data[12];
byte addr[8];
float temp =0.0;
 
//Il n'y a qu'un seul capteur, donc on charge l'unique adresse.
ds.search(addr);
 
// Cette fonction sert à surveiller si la transmission s'est bien passée
if (OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("getTemperatureDS18b20 : <!> CRC is not valid! <!>");
return false;
}
 
// On vérifie que l'élément trouvé est bien un DS18B20
if (addr[0] != DS18B20_ID) {
Serial.println("L'équipement trouvé n'est pas un DS18B20");
return false;
}
 
// Demander au capteur de mémoriser la température et lui laisser 850ms pour le faire (voir datasheet)
ds.reset();
ds.select(addr);
ds.write(0x44);
delay(850);
// Demander au capteur de nous envoyer la température mémorisé
ds.reset();
ds.select(addr);
ds.write(0xBE);
 
// Le MOT reçu du capteur fait 9 octets, on les charge donc un par un dans le tableau data[]
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
// Puis on converti la température (*0.0625 car la température est stockée sur 12 bits)
temp = ( (data[1] << 8) + data[0] )*0.0625;
 
return temp;


// CODE SONDE PH

{
for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  { 
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue;                      //convert the millivolt into pH value
  lcd.setCursor(0,1);
  lcd.print("PH:");  
  lcd.print(phValue,2);


// CODE DATE ET HEURE


  dt = clock.getDateTime();
  lcd.setCursor(0, 0);
  lcd.print(dt.day);
  lcd.print("/");
  lcd.print(dt.month);
  lcd.print("/");
  lcd.print(dt.year);
  lcd.print(" ");
  lcd.print(dt.hour);
  lcd.print(":");
  lcd.print(dt.minute); 
  delay(1000);
}
}

Et avec ce code j’ai la date + heure + ph.

// LIBRAIRIES


#include <OneWire.h> // Sonde PH + Sonde Temperature
#include <LiquidCrystal.h> // Ecran LCD
#include <DS3231.h> // Module Horloge


// ECRAN


LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PINS de l'ecran


// HORLOGE ET DATE


DS3231 clock;
RTCDateTime dt;


// SONDE PH


#define SensorPin 0          //ENTREE ANALOGUE DE LA SONDE PH
unsigned long int avgValue;  //STOCKAGE VALEUR
float b;
int buf[10],temp;


// SEQUENCE UNIQUE DE DEMARRAGE


void setup() 

{
  Serial.begin(9600); // VITESSE EN BAUDS
  lcd.begin(16,2); // DEMARRAGE ECRAN EN 16X2
  lcd.clear(); // NETTOYAGE ECRAN
  clock.begin(); // DEMARRAGE MODULE HORLOGE ET DATE
  clock.setDateTime(__DATE__,__TIME__); // RECTIFICATION HEURE ET DATE
}


// SEQUENCE REPETEE


void loop()
 

// CODE SONDE PH

{
for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  { 
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
    avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue;                      //convert the millivolt into pH value
  lcd.setCursor(0,1);
  lcd.print("PH:");  
  lcd.print(phValue,2);


// CODE DATE ET HEURE


  dt = clock.getDateTime();
  lcd.setCursor(0, 0);
  lcd.print(dt.day);
  lcd.print("/");
  lcd.print(dt.month);
  lcd.print("/");
  lcd.print(dt.year);
  lcd.print(" ");
  lcd.print(dt.hour);
  lcd.print(":");
  lcd.print(dt.minute); 
  delay(1000);
}

Donc si je rajoute le code du DS18B20 la température s’affiche mais tout le reste disparaît.

Le premier code ne fait que ceci :

// LIBRAIRIES


#include <OneWire.h> // Sonde PH + Sonde Temperature
#include <LiquidCrystal.h> // Ecran LCD
#include <DS3231.h> // Module Horloge


// ECRAN


LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PINS de l'ecran


// HORLOGE ET DATE


DS3231 clock;
RTCDateTime dt;


// SONDE PH


#define SensorPin 0          //ENTREE ANALOGUE DE LA SONDE PH
unsigned long int avgValue;  //STOCKAGE VALEUR
float b;
int buf[10],temp;


// SONDE TEMPERATURE DS18B20


// Variables propres au DS18B20
const int DS18B20_PIN=3;
const int DS18B20_ID=0x28;
// Déclaration de l'objet ds
OneWire ds(DS18B20_PIN); // on pin DS18B20_PIN (a 4.7K resistor is necessary)

// Variables générales
float DS18B20_temperature;
const int SERIAL_PORT=9600;


// SEQUENCE UNIQUE DE DEMARRAGE


void setup() 

{
  Serial.begin(9600); // VITESSE EN BAUDS
  Serial.println("Initialisation du programme");
  lcd.begin(16,2); // DEMARRAGE ECRAN EN 16X2
  lcd.clear(); // NETTOYAGE ECRAN
  clock.begin(); // DEMARRAGE MODULE HORLOGE ET DATE
  clock.setDateTime(__DATE__,__TIME__); // RECTIFICATION HEURE ET DATE
}


// SEQUENCE REPETEE


void loop()
 

// CODE AFFICHAGE DS18B20


{
DS18B20_temperature = getTemperatureDS18b20(); // On lance la fonction d'acquisition de T°
// on affiche la T°
lcd.setCursor(11, 1);
lcd.print(DS18B20_temperature,1);
}

Donc c’est tout à fait normal qu’il n’affiche que la température vu qu’il ne fait que ca (!) D’ailleurs c’est même étonnant que ca compile (!?)

Le deuxième bout de code a un peu plus d’affichage dans sa fonction loop(), il y a bien le PH, la date et l’heure qui sont affichés.

Les accolades ne sont pas là pour décorer, aligner une accolade fermante à la même hauteur que l’ouvrante permet de voir plus clair dans son code pour savoir quel block correspond à quoi. (cela s’appelle “indenter” son code, il n’y a pas de honte à le faire, même les développeurs expérimentés le font).

d'acc mais la je comprend pas trop, j'ai essayé toute les formes possible et imaginable avec les accolades et tout mais soit j'ai un erreur m'indiquant:

Non utilisé : D:\Arduino\libraries\Wire exit status 1 'getTemperatureDS18b20' was not declared in this scope

soit j'ai rien sur l'écran, donc je vais essayer de farfouiller et de trouver la solution.

Merci

Un peu plus propre comme ca.

// LIBRAIRIES---------------------------------------------------------------------------------------------


#include <Wire.h>
#include <OneWire.h> // Sonde PH + Sonde Temperature
#include <LiquidCrystal.h> // Ecran LCD
#include <DS3231.h> // Module Horloge


// ECRAN----------------------------------------------------------------------------------------------------------


LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PINS de l'ecran


// HORLOGE ET DATE--------------------------------------------------------------------------------------------


DS3231 clock;
RTCDateTime dt;


// SONDE PH------------------------------------------------------------------------------------------------------


#define SensorPin 0          //ENTREE ANALOGUE DE LA SONDE PH
unsigned long int avgValue;  //STOCKAGE VALEUR
float b;
int buf[10],temp;


// SONDE TEMPERATURE DS18B20-----------------------------------------------------------------------------


const int DS18B20_PIN=3;
const int DS18B20_ID=0x28;
OneWire ds(DS18B20_PIN); 
float DS18B20_temperature;
const int SERIAL_PORT=9600;


// SEQUENCE UNIQUE DE DEMARRAGE-------------------------------------------------------------------------


void setup() 

{
  Serial.begin(9600); // VITESSE EN BAUDS
  lcd.begin(16,2); // DEMARRAGE ECRAN EN 16X2
  lcd.clear(); // NETTOYAGE ECRAN
  clock.begin(); // DEMARRAGE MODULE HORLOGE ET DATE
  clock.setDateTime(__DATE__,__TIME__); // RECTIFICATION HEURE ET DATE
}


// SEQUENCE REPETEE-------------------------------------------------------------------------------------------


void loop()


// CODE SONDE PH----------------------------------------------------------------------------------------------


{
  for(int i=0;i<10;i++)       
{ 
  buf[i]=analogRead(SensorPin);
  delay(10);
}
  for(int i=0;i<9;i++)        
{
    for(int j=i+1;j<10;j++)
{
      if(buf[i]>buf[j])
{
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
}
}
}

  avgValue=0;
  for(int i=2;i<8;i++)                     
    avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; 
  phValue=3.5*phValue;                      
  lcd.setCursor(0,1);
  lcd.print("PH:");  
  lcd.print(phValue,2);
  


// CODE DATE ET HEURE----------------------------------------------------------------------------------------

{
  dt = clock.getDateTime();
  lcd.setCursor(0, 0);
  lcd.print(dt.day);
  lcd.print("/");
  lcd.print(dt.month);
  lcd.print("/");
  lcd.print(dt.year);
  lcd.print(" ");
  lcd.print(dt.hour);
  lcd.print(":");
  lcd.print(dt.minute); 
  delay(1000);
}


// CODE AFFICHAGE DS18B20----------------------------------------------------------------------------------


{
DS18B20_temperature = getTemperatureDS18b20();
lcd.setCursor(9,1);
lcd.print("TP=");
lcd.print(DS18B20_temperature,1);
lcd.print((char)223);
}
}

Mais la ca veut pas compiler, j’ai le fameux getTemperatureDS18b20 was not declared in this scope.

quand on va rechercher des bouts de code à droite et à gauche…
ce n’est pas un reproche, je le pratique également
la fonction gettemperature fait partie de la bibliotheque dallastemperature, qui n’est pas inclue dans ton sketch
#include <OneWire.h>
#include <DallasTemperature.h>
sans garanties
parfois certaines biblios sont incompatibles entre elles, si include dans le meme sketch
bonne continuation

Prendre des bouts de code pour les assembler sans comprendre ce qu'on fait, ca ne marche pas : ce n'est pas un reproche non plus, c'est un constat et une réalité.

Tu devrais commencer par lire au moins le premier chapitre de ce tuto, tu comprendras au moins à quoi servent les accolades... Parce que sans cela, c'est difficile de pouvoir programmer tout court, quelque soit le langage.

Enfaîte c'est plus complexe.

Il existe des milliers de capteurs de température, analogique, digital, I2C, SPI et j'en passe.

Chaque capteur a sa particularité, l'objectif est de trouver celui qui conviens le mieux pour le projet.

Pour mesurer la température de l'eau je pense qu'une résolution de 0,1°C n'est pas vraiment nécessaire, avoir un capteur qui a numéro de série ou code ces trames avec du CRC non plus.

Il faut aller a l'essentiel, l'utilisation d'une thermistance ou d'un capteur analogique semble mieux approprié, une simple lecture analogique et une équation dans le code suffit pour avoir des degrés Celsius convenable.

En gros je veut dire que le capteur de température que tu utilise actuellement t’empêche de comprendre comment coder, il y a des alternatives beaucoup plus simple !

LM35 LM335 Thermistance

Merci pour vos réponses,

J'ai lu le tuto que Zorro ma link en entier ca ma bien aidé. Merci

J'ai réussi a coder l'ensemble et tout fonctionne.

Je suis passé sur la librairie DallasTemperature et ca marche impec.

|500x281

Me reste le calibrage de la sonde PH avec les solution 4.01 et 10.1 qui arrive demain.

Par contre j'ai remarqué un truc bizarre au niveau de l'horloge, sur l'image on voit clairement l'heure en entier mais des qu'on passe a l'heure suivante les 9 premières minutes j'ai 21:1 au lieu de 21:01, une fois a 21:10 tout redevient normal.

Et idem pour le passage de 23:59 a 00h01, ca m'affiche 0.1 au lieu de 00:01

Voici le bout de code pour l'heure.

{
  dt = clock.getDateTime();
  lcd.setCursor(0, 0);
  lcd.print(dt.day);
  lcd.print("/");
  lcd.print(dt.month);
  lcd.print("/");
  lcd.print(dt.year);
  lcd.print(" ");
  lcd.print(dt.hour);
  lcd.print(":");
  lcd.print(dt.minute);
  lcd.print("  "); 
  delay(1000);
}

Je me posé la question si il fallait pas travailler sur les setCursor pour régler le problème parce que toutes mes lectures jusqu'ici n'ont pu m'aider.

Pour un affichage un peu plus optimal sur ton écran LCD, tu peux lire ce tuto. Sinon tu peux aussi utiliser sprintf()

Bonjour, Que représente, d'un point de vue physique, l'affichage des données au 1/100ème ? IMHO on n'est déjà pas sur du 1/10. @+

Je comprend pas ta question Icare. Ce que ça représente en code ou en intérêt ?

Je pense qu'icare fait référence à l'utilité d'afficher une précision au 1/100e (deux chiffres après la virgule) pour les capteurs que t'utilises qui ne fournissent peut-être pas une telle précision... (?)

Ah non j’ai pris la photo dès que ca a fonctionné mais les 1/100eme servent a rien j’ai tout basculé en value,1 après.

Bonjour,

Zorro_X: Je pense qu'icare fait référence à l'utilité d'afficher une précision au 1/100e (deux chiffres après la virgule) pour les capteurs que t'utilises qui ne fournissent peut-être pas une telle précision... (?)

Exact ;)

Bonsoir, mon projet avance bien je commence a me familiariser avec le C et le monde d’Arduino mais pas encore assez bien puisque j’ai un petit soucis avec le DS3231.

Alors voila c’est assez simple, si je débranche la carte de son alimentation et que je la rebranche 10 minutes plus tard, elle redémarre avec l’heure qu’elle avait au dernier télé versement dans la carte.
grosso modo on dirait que le RTC ne garde que l’heure de base en mémoire mais ne continue pas de tourner entre temps.

Niveau câblage c’est:

GROUND → MASSE
VCC → 5V
SCL → Analog 5
SDA → Analog 4

J’ai déjà changé la pile ca y fait rien.

Mon deuxième problème, c’est que si je demande a la carte de m’afficher les secondes sur le 16x2, mes secondes font se rafraichir toutes les 2 voir 3 secondes.

Je vois donc a l’écran:
21:03:30 - 21:03:33 - 21:02:36 etc…

Voila mon petit code.

Si vous avez un idée je suis preneur j’ai pas encore déniché de solution :confused:

merci

// LIBRAIRIES------------------------------------------------------------------------------------------------------------------------------------------------


#include <OneWire.h> // Sonde PH 
#include <LiquidCrystal.h> // Ecran LCD
#include <DS3231.h> // Module Horloge
#include <DallasTemperature.h> // Sonde Temperature DS18B20


// CAPTEUR TEMPERATURE


#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


// ECRAN-----------------------------------------------------------------------------------------------------------------------------------------------------


LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PINS de l'ecran


// HORLOGE ET DATE--------------------------------------------------------------------------------------------------------------------------------------------


DS3231 clock;
RTCDateTime dt;


// SONDE PH---------------------------------------------------------------------------------------------------------------------------------------------------


#define SensorPin 0          //ENTREE ANALOGUE DE LA SONDE PH
unsigned long int avgValue;  //STOCKAGE VALEUR
float b;
int buf[10], temp;


// SEQUENCE UNIQUE DE DEMARRAGE-------------------------------------------------------------------------------------------------------------------------------


void setup()


{
  Serial.begin(9600); // VITESSE EN BAUDS
  lcd.begin(16, 2); // DEMARRAGE ECRAN EN 16X2
  lcd.clear(); // NETTOYAGE ECRAN
  clock.begin(); // DEMARRAGE MODULE HORLOGE ET DATE
  clock.setDateTime(__DATE__, __TIME__); // RECTIFICATION HEURE ET DATE
  sensors.begin(); // DEMARRAGE SONDE TEMPERATURE
}


// SEQUENCE REPETEE----------------------------------------------------------------------------------------------------------------------------------------


void loop()


// CODE SONDE PH-------------------------------------------------------------------------------------------------------------------------------------------


{
  for (int i = 0; i < 10; i++)
  {
    buf[i] = analogRead(SensorPin);
    delay(10);
  }
  for (int i = 0; i < 9; i++)
  {
    for (int j = i + 1; j < 10; j++)
    {
      if (buf[i] > buf[j])
      {
        temp = buf[i];
        buf[i] = buf[j];
        buf[j] = temp;
      }
    }
  }
  {
    avgValue = 0;
    for (int i = 2; i < 8; i++)
      avgValue += buf[i];
    float phValue = (float)avgValue * 5.0 / 1024 / 6;
    phValue = 3.5 * phValue;
    lcd.setCursor(10, 0);
    lcd.print("PH:");
    lcd.print(phValue, 1);
  }


  // CODE DATE ET HEURE--------------------------------------------------------------------------------------------------------------------------------------------


  {
    dt = clock.getDateTime();
    lcd.setCursor(0, 0);
    lcd.print(dt.day);
    lcd.print("/");
    lcd.print(dt.month);
    lcd.print("/");
    lcd.print(dt.year % 100);
  }
  {
    lcd.setCursor(0, 1);
    if (dt.hour < 10 )
      lcd.print ("0");
    lcd.print(dt.hour);
    lcd.print(":");
    if (dt.minute < 10 )
      lcd.print("0");
    lcd.print(dt.minute);
    lcd.print(":");
    if (dt.second < 10 )
      lcd.print("0");
    lcd.print(dt.second);
    delay(1000);
  }


  // CODE SONDE TEMPERATURE DS18B20---------------------------------------------------------------------------------------------------------------------------------


  {
    sensors.requestTemperatures(); // Send the command to get temperatures
    lcd.setCursor(10, 1);
    lcd.print("T=");
    lcd.println(sensors.getTempCByIndex(0), 1);
    lcd.setCursor(16, 1);
    delay(1000);
  }
}

malgré le fait que maintenant c'est mieux indenté (bravo ! c'est déjà plus lisible comme ca !), tu continues à avoir des accolades inutiles dans ton code. En lisant rapidement je constate qu'il y a deux delay(1000); qui sont exécutés à chaque cycle dans ta fonction loop(), c'est ce qui fait que tout est donc rythmé par des cycles de deux secondes (2000ms). Il ne faut pas chercher plus loin. Si t'as commencé à lire le tuto d'eskimon, continue à lire et va au moins jusqu'au chapitre où il parle de la gestion du temps. T'y découvriras pour quoi "c'est mal" d'utiliser delay() et surtout comment faire autrement. ;)

Etternell: Alors voila c'est assez simple, si je débranche la carte de son alimentation et que je la rebranche 10 minutes plus tard, elle redémarre avec l'heure qu'elle avait au dernier télé versement dans la carte. grosso modo on dirait que le RTC ne garde que l'heure de base en mémoire mais ne continue pas de tourner entre temps.

  clock.setDateTime(__DATE__, __TIME__); // RECTIFICATION HEURE ET DATE

ça semble normal avec cette ligne dans le setup