Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser ;)

En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.

Topic "Relevés aquaponique"

Flux RSS des posts récents dans ce topic ( Flux Atom)


Pas de photo de profil

aquabiofarm

Membre

#489 | Signaler ce message


Présentation de mon projet

J'ai installé un système aquaponique chez moi sur ma terrasse et afin de le faire évoluer, je voudrais faire les relevés automatiques.

Pour ceux qui ne savent pas ce qu'est l'aquaponie, dans les grandes lignes, c'est un système vertueux, mélangeant aquaculture et hydroponie, les excréments de poissons vont servir d'engrais pour les plantes et celles ci nettoient l'eau pour les poissons. Cette eau rempli d'excrément passe par deux filtres et du dernier l'eau va au bac de culture et aussi au bac à poissons.

Ce système entraîne des relevés de températures, pH, ammonium, nitrate, nitrite…. Certaines sondes sont hors de prix ou n'existent pas mais pour celle ci je verrais bien plus tard.

Dans un premier temps je veux récupérer la température et le pH sur le temps, les stocker, les envoyer sur un serveur afin de les consulter à distance et si les valeurs dépassent les minimums et maximums je voudrais une alerte par mail (ou sms). Voila un peu le résumé du projet.

Voici une photo de mon système

Equipements acquis:

  • Arduino uno pour tester chaque module séparé

  • Arduino mega pour le projet final

  • ESP8266-01

  • un LCD 20x4 pour le visuel sur le système

  • RTC DS1307

  • Adaptateur carte microSD

  • 3 sondes DS18D20 étanche

Equipements à acquérir :

  • sonde pH

  • Les autres sont trop cher

  • modules manquant selon l'évolution et aides sur le projet.

  • module GSM pour l'envoie d'alerte via sms

Les trois sondes DS18D20 seront placées chacune dans les filtres et bac poissons, par la suite toutes les sondes seront dans le bac poissons

En suivant le tutoriel sur le DS18D20, j'ai réussi à afficher la température sur le LCD, il ne me reste plus que l'affichage des deux autres, mais en suivant le super tuto fourni je pense que cela ne devrait pas poser de problème.

Je vais stocker les relevées des sondes en suivant le tuto du datalogger

La ou je tourne en rond, c'est comment faire pour envoyer les données des sondes via l'esp8266 pour y accéder à distance, site web, dynamique ou autre (je ne sais pas quel solution) et qu'une alerte par mail me parvienne en cas de dépassement des minimums et maximums.

Si une personne peut m'aider ou si quelqu'un a une autre solution plus logique à m'apporter, je suis preneur.

Derniére modification le par aquabiofarm


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#504 | Signaler ce message


La ou je tourne en rond, c'est comment faire pour envoyer les données des sondes via l'esp8266 pour y accéder à distance, site web, dynamique ou autre (je ne sais pas quel solution) et qu'une alerte par mail me parvienne en cas de dépassement des minimums et maximums.

par aquabiofarm

Ce que tu cherches à faire se rapproche énormément de l'internet des objets.

Il existe pas mal de services de stockage/visualisation de données, certains gratuit, certains payant. Quelques solutions open source existent mais globalement, c'est un joyeux merdier.

Personnellement, je te conseille de faire un site web maison avec une base de données. Envoi ensuite tes données depuis le ESP8266 en HTTP vers ton site. C'est la solution la plus simple.

PS Tu peux utiliser un Raspberry Pi en tant que serveur, un vieux PC ou un vrai serveur suivant ton budget.


Pas de photo de profil

aquabiofarm

Membre

#511 | Signaler ce message


Ce que tu cherches à faire se rapproche énormément de l'internet des objets.

Il existe pas mal de services de stockage/visualisation de données, certains gratuit, certains payant. Quelques solutions open source existent mais globalement, c'est un joyeux merdier.

par skywodd

C'est clair, j'ai découvert ce genre de site récemment et j'avoue que c'est le merdier quand on veut un truc perso et où on est maître de ce qu'on fait.

Personnellement, je te conseille de faire un site web maison avec une base de données. Envoi ensuite tes données depuis le ESP8266 en HTTP vers ton site. C'est la solution la plus simple.

PS Tu peux utiliser un Raspberry Pi en tant que serveur, un vieux PC ou un vrai serveur suivant ton budget.

Voilà c'est ça, j'aimerais envoyer les données de l'arduino via l'ESP, est ce qu'un site hébergé sur free peut faire l'affaire? Je viens de me mettre à l'arduino donc j'ai un peu peur de me lancer sur raspberry Pi et de m'éparpiller. Je pense que je vais finir le programme de mes relevés en premier temps, je viens de passer de la UNO à la Mega et je n'ai pas le même résultat sur le lcd. Les ennuis commencent quand on sort des sentiers battus des tutoriels.

Merci de ta réponse et du partage de tes connaissances.

Derniére modification le par aquabiofarm


Photo de profil de Cywill

Cywill

Membre

#514 | Signaler ce message


Salut aquabiofarm,

Sympa ton projet !

est ce qu'un site hébergé sur Free peut faire l'affaire?

Oui ça peut faire l'affaire, t'as du PHP et du MySQL (ou PostGreSQL) mais il y a quelques hics:
- C'est possible que les serveurs de base de données ne soient pas disponible à 100% (connexion simultané: 1)
- T'es limité en taille et création de base de données
- Tes données vont être transmise en clair (pas de connexion chiffré SSL/TLS)
- Je suis pas sure que d’après les conditions générale t'as le droit d'utiliser ce genre de service pour ton projet

Donc, le mieux c'est d'avoir son propre serveur…
Tu pourrais combiner l’ensemble, c'est à dire remplacer Arduino + ESP8266 par le Raspberry PI 3 ou un Raspberry PI avec dongle Wi-Fi

Avec un Raspberry PI pour ton projet:
- LCD 20x4 => OK
- RTC DS1307 (I2C) => OK ou tu peux remplacer le module par le protocole NTP
- Datalogger => clé USB ou disque dur externe
- DS18D20 (One-Wire) => géré
- Serveur service web (HTTP(S))
- Serveur base de données
- Envoie de mails (client SMTP)
- Envoyer des SMS via un API SMS par requête HTTP(S) (~7€ pour 100SMS)

Derniére modification le par Cywill


Pas de photo de profil

aquabiofarm

Membre

#516 | Signaler ce message


Merci Cywill Pour ce complément d'information, je vais rester avec la config actuelle Arduino + ESP, une fois que les capteurs, horodatage et affichage seront corrects, je passerai à la partie wifi, je enverrai les données en requête http à mon serveur.

Ordre d'exécution:

    1 - Les trois capteurs avec affichage sur LCD (en cours)
    2 - ajout de l'horodatage (prévu)
    3 - envoie en WIFI (prévu)

Derniére modification le par aquabiofarm


Pas de photo de profil

aquabiofarm

Membre

#517 | Signaler ce message


Salut voila un petit post pour l'avancé du projet

    1 - Les trois capteurs avec affichage sur LCD (Fait!!)

    2 - ajout de l'horodatage (En cours)

La partie sauvegarde sur carte mémoire fonctionne bien, il ne manque plus que le module DS1307 a intégré (il faut que je soude des pin dessus)

Petite question, avec le tuto sur le DS18d20, le relevé se fait avec un délai de 800 ce qui est bien pour l'affichage sur le lcd mais comment faire pour sauvegarder indépendamment sur la carte microSD à un temps plus long, genre 1 minute.

Je voudrais que le relevé des capteurs reste à 800 mais l'écriture sur la micro SD se fasse toutes les une minute. Voila mon code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*intégration des librairies */
#include <SD.h>
#include <SPI.h>
#include <OneWire.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>



/* Definition de la pin pour SD */
#define CS_PIN 53

/* Création des instances */
File monFichier;

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);


/* Broche du bus 1-Wire*/
const byte BROCHE_ONEWIRE = 8;

/*code de retour de la fonction getTemperature*/
enum DS18B20_RCODES 
{
  READ_OK, //Lecture ok
  NO_SENSOR_FOUND, //Pas de capteur
  INVALID_ADDRESS, //Adresse reçue invalide
  INVALID_SENSOR // Capteur invalide (pas un DS18B20)
};

/* Adresses des capteurs de température */
const byte SENSOR_ADDRESS_1[] = { 0x28, 0xFF, 0xB8, 0x41, 0xA1, 0x16, 0x05, 0x72 }; //bac poisson
const byte SENSOR_ADDRESS_2[] = { 0x28, 0xFF, 0xE3, 0x24, 0xA1, 0x16, 0x03, 0x5B }; //filtre sédiments
const byte SENSOR_ADDRESS_3[] = { 0x28, 0xFF, 0x38, 0x4A, 0xA1, 0x16, 0x03, 0xF0 }; //biofiltre

/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);



/**
 * Fonction de démarrage de la prise de mesure de la température via un capteur DS18B20.
 */
void startTemperatureMeasure(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté
  
  /* Reset le bus 1-Wire et sélectionne le capteur */
  ds.reset();
  ds.select(addr);
  
  /* Lance une prise de mesure de température et attend la fin de la mesure */
  ds.write(0x44, 1);
}

/**
 * Fonction de récupération de la prise de mesure de la température via un capteur DS18B20.
 */
float readTemperatureMeasure(const byte addr[]) {
  byte data[9];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté
 
  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
   
  /* Calcul de la température en degré Celsius */
  return ((data[1] << 8) | data[0]) * 0.0625; 
}

void setup() {
 
  // Initialisation du LCD
  lcd.begin();
  lcd.clear();


/* Affichage des 3 bacs pour les relevés */  
  //Bac poissons
  lcd.setCursor(0,0);
  lcd.print("Fish");
  lcd.setCursor(0,1);
  lcd.print("Tank");

  //filtre sédiments
  lcd.setCursor(7,0);
  lcd.print("Swirl");
  lcd.setCursor(7,1);
  lcd.print("Filter");

  //Biofiltre
  lcd.setCursor(14,0);
  lcd.print("Bio");
  lcd.setCursor(14,1);
  lcd.print("Filter");
  
  //pH sur 4ème ligne
  lcd.setCursor(0,3);
  lcd.print("Controleur pH");

  // initialisation du Serial
 Serial.begin(9600);


  /* Initilisation du microSD */

   Serial.print("Initialisation de la carte SD en cours...");
  if (SD.begin())
  {
    Serial.println(" Terminee.");
  } else
  {
    Serial.println(" Echec.");
    return;
  }  
  monFichier = SD.open("donnees.csv", FILE_WRITE);
  if (monFichier) 
  {   
    monFichier.println("Fish Tank,SwirlFilter,BioFilter");
    Serial.println("");
    Serial.println("Fish Tank | SwirlFilter | BioFilter");
    monFichier.close();    
  } 

}

void loop() {
  float temperature[3];
   
  /* Lit les températures des trois capteurs */
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3);


//Bac poissons
    lcd.setCursor(0,2);
    lcd.print(temperature[0], 1);
    lcd.print((char)223); // Caractère degré
    lcd.print("C");

//filtre sédiments
  lcd.setCursor(7,2);
  lcd.print(temperature[1], 1);
  lcd.print((char)223); // Caractère degré
  lcd.print("C");

//Biofiltre
  lcd.setCursor(14,2);
  lcd.print(temperature[2], 1);
  lcd.print((char)223); // Caractère degré
  lcd.print("C");

// On met en forme la donnée au formar csv, c'est-à dire chaque paramètre séparé par une virgule.
  String donnee = String (temperature[0],1) + "," + String (temperature[1],1) + "," + String (temperature[2],1);

  // On enregistre la donnée 
  monFichier = SD.open("donnees.csv", FILE_WRITE); //Maximum 8 caractères avant le .csv
  if (monFichier) 
  {   
    monFichier.println(donnee);
    Serial.println("   " + String (temperature[0],1) + "   |     " + String (temperature[1],1)+ "    |   " + String (temperature[2],1));
    monFichier.close();    
  } 
  else 
  {
    Serial.println("Impossible d'ouvrir le fichier");
  }  

    
}

Derniére modification le par aquabiofarm


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#526 | Signaler ce message


Oui ça peut faire l'affaire, t'as du PHP et du MySQL (ou PostGreSQL) mais il y a quelques hics:
- C'est possible que les serveurs de base de données ne soient pas disponible à 100% (connexion simultané: 1)
- T'es limité en taille et création de base de données
- Tes données vont être transmise en clair (pas de connexion chiffré SSL/TLS)
- Je suis pas sure que d’après les conditions générale t'as le droit d'utiliser ce genre de service pour ton projet

Donc, le mieux c'est d'avoir son propre serveur…

par Cywill
  • C'est même sûr que les serveurs de BDD ne seront pas disponibles à 100%. Sinon à quoi bon payer le prix fort chez Online pour avoir des garanties d'uptime ;)

  • Et limité en ressources (CPU/RAM), pour éviter que ton site n'impacte les sites des autres.

  • Pas de soucis pour les CGU, Free est très laxiste sur ce point. Tant que tu envois pas des emails à tour de bras, ça va.

Petite question, avec le tuto sur le DS18d20, le relevé se fait avec un délai de 800 ce qui est bien pour l'affichage sur le lcd mais comment faire pour sauvegarder indépendamment sur la carte microSD à un temps plus long, genre 1 minute.

Je voudrais que le relevé des capteurs reste à 800 mais l'écriture sur la micro SD se fasse toutes les une minute.

par aquabiofarm

Je te conseille de lire mon tutoriel sur le multi-tâche en Arduino ;)


Photo de profil de Cywill

Cywill

Membre

#527 | Signaler ce message


Tu peux jouer avec la fonction millis()

Par exemple:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
unsigned long previousMillis = 0;

const unsigned long delayLCD = 800;
const unsigned long delaySD = 60000;

void loop() {

  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= delayLCD) {
   
    previousMillis = currentMillis;
    
    // fonction affichage données LCD
    displayDataLCD();
  }

  if(currentMillis - previousMillis >= delaySD) {
   
    previousMillis = currentMillis;
    
    // fonction pour sauvegarder les données dans la carte SD (fichier CSV)
    saveDataSD();
  }
}

Par contre, si ton code tourne 24h 7j/7 et que tu emploies millis() tu dois gérer le rollover
Skywodd a écrit un article sur ça: La gestion du temps avec Arduino

Après relever une température toutes les minutes (faire une moyenne) c'est bien aussi, la température ne varie pas instantanément ;)

Derniére modification le par Cywill


Pas de photo de profil

aquabiofarm

Membre

#538 | Signaler ce message


Merci de ces retours, en fait j'ai reçu mon module DS1307 et je ferai un relevé toutes les 3 heures sur la carte microSD mais sur le lcd ce sera en temps réel. Mais la je m'oppose à un souci celui du DS1307, je n'arrive pas à le mettre à l'heure Je compile et téléverse ce code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//Mise à l'heure RTC
 
#include <Wire.h>
#include "RTClib.h"
 
RTC_DS1307 RTC; //Classe RTC_DS1307
 
void setup () {
  Serial.begin(57600); //Démarrage de la communication
  Wire.begin(); //Démarrage de la librairie wire.h
  RTC.begin(); //Démarrage de la librairie RTClib.h
  
  //Si RTC ne fonctionne pas
  if (! RTC.isrunning()) {
    Serial.println("RTC ne fonctionne pas !");
    
    //Met à l'heure à date à laquelle le sketch est compilé
    RTC.adjust(DateTime(__DATE__, __TIME__)); 
    //Cela fonctionne également :
    //RTC.adjust(DateTime("Avr  18 2017","12:50:00")); 
    //RTC.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }
  }
 
void loop() {
  //Affichage de l'heure
  DateTime now = RTC.now();
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);  
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  delay(3000);
}

Et sur le serial il m'apparait toujours 15/4/2017 et l'heure injuste forcément, même si je lui indique

1
RTC.adjust(DateTime(2014, 1, 21, 3, 0, 0));

Il met toujours la même date et l'heure fausse. D'ou vient l'erreur


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#540 | Signaler ce message


Il met toujours la même date et l'heure fausse. D'ou vient l'erreur

par aquabiofarm

L'horloge du DS1307 ne doit pas être activé. En utilisant mon code cela devrait fonctionner ;)


Pas de photo de profil

aquabiofarm

Membre

#541 | Signaler ce message


Il met toujours la même date et l'heure fausse. D'ou vient l'erreur

par aquabiofarm

L'horloge du DS1307 ne doit pas être activé. En utilisant mon code cela devrait fonctionner ;)

par skywodd

D'accord merci, une fois ton code mis, je pourrais récuperer la donnée d'heure avec "now" ? Il me faudra la bibliothèque et le fichier .h?

Derniére modification le par aquabiofarm


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#542 | Signaler ce message


D'accord merci, une fois ton code mis, je pourrais récuperer la donnée d'heure avec "now" ? Il me faudra la bibliothèque et le fichier .h?

par aquabiofarm

Tu peux utiliser mon code pour configurer le module puis utiliser le code que tu utilises actuellement. Sinon, tu peux utiliser mon code et oublier RTClib. Au choix.

Dans les deux cas, il te faudra le code de l'article en lien ci-dessus et le .h qui va avec.


Pas de photo de profil

aquabiofarm

Membre

#543 | Signaler ce message


Tu peux utiliser mon code pour configurer le module puis utiliser le code que tu utilises actuellement. Sinon, tu peux utiliser mon code et oublier RTClib. Au choix.

Dans les deux cas, il te faudra le code de l'article en lien ci-dessus et le .h qui va avec. [/quote]

Je viens d'essayer le code en téléchargeant directement, il y a deux lignes ou la fin de commentaire n'est pas signalée et il manque une accolade à la fin de la loop si tu peux corriger pour ceux ou celles qui vont le télécharger. Une fois ton code corrigé et mis, dans le serial il m'affiche toujours la même date 15/4/2017…. Que faire?


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#544 | Signaler ce message


Je viens d'essayer le code en téléchargeant directement, il y a deux lignes ou la fin de commentaire n'est pas signalée et il manque une accolade à la fin de la loop si tu peux corriger pour ceux ou celles qui vont le télécharger.

par aquabiofarm

Mince, c'est le grand retour du bug d'encodage. J'ai corrigé ce bug dans ma version de test. Elle sera mise en ligne d'ici la fin du mois.

En attendant, il est possible de sauvegarder le code en copier-collant le code depuis la version web (en couleur). Désolé pour le dérangement.

Une fois ton code corrigé et mis, dans le serial il m'affiche toujours la même date 15/4/2017…. Que faire?

par aquabiofarm

Changer de module et/ou vérifier les soudures du quartz. Si les secondes ne bougent pas c'est que le module est HS.


Pas de photo de profil

aquabiofarm

Membre

#549 | Signaler ce message


Changer de module et/ou vérifier les soudures du quartz. Si les secondes ne bougent pas c'est que le module est HS.

par skywodd

J'ai trouvé, sur mon module je pouvais souder les pin soit sur P1 ou P2 et j'avais soudé sur P2, en soudant sur P1 cela fonctionne. Encore un petit pas sur l'avancement du projet. Maintenant, il faut afficher en l'heure et la température temps réel sur le lcd et faire un relevé toutes les 3 heures sur la micro SD C'est parti!!!

Derniére modification le par aquabiofarm


Pas de photo de profil

aquabiofarm

Membre

#552 | Signaler ce message


Suite du projet

    1 - Les trois capteurs avec affichage sur LCD [FAIT]
    2 - ajout de l'horodatage [FAIT]
    3 - envoie en WIFI (en cours)

Voici le code pour l'affichage et le datalogger. Si vous avez des astuces pour soulager le code ou d'autre choses pour le simplifier, je suis preneur, je suis novice dans la matière donc je ne vois pas encore toute les subtilités.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
/********************************************************************************
 * Programme Arduino de relevé automatique des températures.
 * Sauvegarde des données sur carte microSD avec un horodatage
 * Visible sur écran lcd 20x4
********************************************************************************/
/***********************Déclaration des librairies*******************************/
#include <SPI.h>
#include <SD.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h> 
#include <Wire.h>
#include <RTClib.h>

/***********************Déclaration de la broche pour SD sur Mega****************/
const byte SDCARD_CS_PIN = 53;

/***********************Classe RTC_DS1307****************************************/
RTC_DS1307 RTC;

/***********************Création instance pour SD********************************/
File monFichier;

/**********Adresse du lcd 0x27 et 20 caractères sur 4 lignes*********************/
LiquidCrystal_I2C lcd(0x27, 20, 4);

/**********************Définition de la broche pour le ONEWIRE*******************/
const byte BROCHE_ONEWIRE = 8;

/**********************code de retour de la fonction getTemperature**************/
enum DS18B20_RCODES 
{
  READ_OK, //Lecture ok
  NO_SENSOR_FOUND, //Pas de capteur
  INVALID_ADDRESS, //Adresse reçue invalide
  INVALID_SENSOR // Capteur invalide (pas un DS18B20)
};

/***********************Adresses des capteurs de température**********************/
const byte SENSOR_ADDRESS_1[] = { 0x28, 0xFF, 0xB8, 0x41, 0xA1, 0x16, 0x05, 0x72 }; //bac poisson
const byte SENSOR_ADDRESS_2[] = { 0x28, 0xFF, 0xE3, 0x24, 0xA1, 0x16, 0x03, 0x5B }; //filtre sédiments
const byte SENSOR_ADDRESS_3[] = { 0x28, 0xFF, 0x38, 0x4A, 0xA1, 0x16, 0x03, 0xF0 }; //biofiltre

/*************Création de l'objet OneWire pour manipuler le bus 1-Wire*************/
OneWire ds(BROCHE_ONEWIRE);

/*Fonction de démarrage de la prise de mesure de la température via un capteur DS18B20.*/
void startTemperatureMeasure(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté
  
/************************Reset le bus 1-Wire et sélectionne le capteur**************/
  ds.reset();
  ds.select(addr);
  
/******Lance une prise de mesure de température et attend la fin de la mesure*******/
  ds.write(0x44, 1);
}

/*Fonction de récupération de la prise de mesure de la température via un capteur DS18B20.*/
float readTemperatureMeasure(const byte addr[]) {
  byte data[9];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté
 
 /*Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad*/
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);
 
 /**********************Lecture du scratchpad*************************************/
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
   
/***********************Calcul de la température en degré Celsius*****************/
  return ((data[1] << 8) | data[0]) * 0.0625; 
}

/*******Lit les températures des trois capteurs et les affiche sur le lcd*********/
 void readTemp() {
  float temperature[3];
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3);


//Bac poissons
    lcd.setCursor(0,2);
    lcd.print(temperature[0], 1);
    lcd.print((char)223); // Caractère degré
    lcd.print("C");

//filtre sédiments
  lcd.setCursor(7,2);
  lcd.print(temperature[1], 1);
  lcd.print((char)223); // Caractère degré
  lcd.print("C");

//Biofiltre
  lcd.setCursor(14,2);
  lcd.print(temperature[2], 1);
  lcd.print((char)223); // Caractère degré
  lcd.print("C");
 }
/***********************Affichage des bacs sur LCD**********************/
void affichageBac() {
  //Bac poissons
  lcd.setCursor(0,0);
  lcd.print("Fish");
  lcd.setCursor(0,1);
  lcd.print("Tank");

  //filtre sédiments
  lcd.setCursor(7,0);
  lcd.print("Swirl");
  lcd.setCursor(7,1);
  lcd.print("Filter");

  //Biofiltre
  lcd.setCursor(14,0);
  lcd.print("Bio");
  lcd.setCursor(14,1);
  lcd.print("Filter");
  
  //pH sur 4ème ligne
  lcd.setCursor(0,3);
  lcd.print("pH a venir");
}
  
/***********************Fonction si le RTC ne fonctionne pas**********************/
 void startRtc() {
 if (! RTC.isrunning()) {
    Serial.println("RTC ne fonctionne pas !");
    
    //Met à l'heure à date à laquelle le sketch est compilé
   
  RTC.adjust(DateTime(__DATE__, __TIME__)); 
    //Cela fonctionne également :
   // RTC.adjust(DateTime("Apr  18 2017","18:30:00")); 
   // RTC.adjust(DateTime(2017, 4, 18, 22, 25, 0));
    }
 }

/********************Fonction démarrage******************************************/
void start() {
  Wire.begin(); //Démarrage de la librairie wire.h
  RTC.begin(); //Démarrage de la librairie RTClib.h
  lcd.begin(); //Démarrage du lcd
  Serial.begin(115200); //Démarrage de la communication
}

/********************Fonction Clignotement des : **********************************/
/*Clignotement des : */
  char blinkPoint1s(){
  static unsigned char state = 0;
  static unsigned long prevMillis = 0;
  unsigned long curMillis = millis();
    if(curMillis - prevMillis > 1000){
      prevMillis = curMillis;
      state = !state;
    }
    return state ? ':' : ' ';
}

/*********************Fonction Montre********************************************/
void montre() {
  //Affichage de l'heure
  DateTime now = RTC.now();

  lcd.setCursor(15,3);
  if (now.hour() < 10)
  lcd.print("0");
  lcd.print(now.hour());
  lcd.print(blinkPoint1s());
  if (now.minute() < 10)
  lcd.print("0");
  lcd.print(now.minute()); 
}
/*********************Affichage dans le Série************************************/
void serieAffichage() {
  float temperature[3];
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3);

  
DateTime now = RTC.now();
  
  if (now.day() < 10)
  Serial.print("0");
  Serial.print(now.day(), DEC);
  Serial.print('/');
  if (now.month() < 10)
  Serial.print("0");
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);  
  Serial.print("  |   ");
  if (now.hour() < 10)
  Serial.print("0");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  if (now.minute() < 10)
  Serial.print("0");
  Serial.print(now.minute(), DEC);
  Serial.print("   |    ");
  //Bac poissons
  Serial.print(temperature[0], 1);
  Serial.print((char)176); // Caractère degré
  Serial.print("C");
  Serial.print("    |      ");
//filtre sédiments
  Serial.print(temperature[1], 1);
  Serial.print((char)176); // Caractère degré
  Serial.print("C");
  Serial.print("     |    ");
//Biofiltre
  Serial.print(temperature[2], 1);
  Serial.print((char)176); // Caractère degré
  Serial.print("C");
  Serial.println();
}

/**************************Fonction écriture dans le SD**************************/
void logToSD(){
     float temperature[3];
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3);

    DateTime now = RTC.now();
    File monFichier = SD.open("donnees.csv", FILE_WRITE);
      if (monFichier) {
       // monFichier.println("Date;Heure;Fishtank;Swirlfilter;Biofilter");
       //Enregistrement date et heure
        if (now.day() < 10)
        monFichier.print("0");
        monFichier.print(now.day(), DEC);
        monFichier.print('/');
        if (now.month() < 10)
        monFichier.print("0");
        monFichier.print(now.month(), DEC);
        monFichier.print('/');
        monFichier.print(now.year(), DEC);  
        monFichier.print(';');
        if (now.hour() < 10)
        monFichier.print("0");
        monFichier.print(now.hour(), DEC);
        monFichier.print(':');
        if (now.minute() < 10)
        monFichier.print("0");
        monFichier.print(now.minute(), DEC);
        monFichier.print(';');
       //Bac poissons
        monFichier.print(temperature[0], 1);
        monFichier.print((char)176); // Caractère degré
        monFichier.print("C");
        monFichier.print(';');
       //filtre sédiments
        monFichier.print(temperature[1], 1);
        monFichier.print((char)176); // Caractère degré
        monFichier.print("C");
        monFichier.print(';');
      //Biofiltre
        monFichier.print(temperature[2], 1);
        monFichier.print((char)176); // Caractère degré
        monFichier.print("C");
        monFichier.println();
        monFichier.close();
      }

    else {
        Serial.println("Impossible d'ouvrir le fichier");
        }  
  delay(1000);
}

/****************************Début du Setup**************************************/
void setup () {

  //Init des sorties
  start();
  //Démarrage du Rtc
  startRtc();
  
  /* Initialisation du port SPI */
  pinMode(53, OUTPUT); // Arduino Mega

  /* Initialisation de la carte SD */
  lcd.setCursor(0,0);
  lcd.print(F("Init SD card... "));
  delay(1000);
  if (!SD.begin(SDCARD_CS_PIN)) {
    lcd.println(F("FAIL"));
    lcd.setCursor(0,1);
    lcd.print("Verifier la carte...");
    lcd.setCursor(0,2);
    lcd.print("Puis reset");
    for(;;); //  appui sur bouton RESET
  }
  lcd.println(F("OK"));
  delay(1000);
  lcd.clear();
  Serial.println("    Date    |   Heure   |   Fishtank   |   Swirlfilter   |   Biofilter");
  File monFichier = SD.open("donnees.csv", FILE_WRITE);
      if (monFichier) {
        monFichier.println("Date;Heure;Fishtank;Swirlfilter;Biofilter");
        monFichier.close();
  affichageBac();
 }
}
/**********************Fin du Setup**********************************************/


/*********************Début Boucle Loop******************************************/
void loop() {
  /* Affichage de l'heure */
  montre();
  
  /*Lecture et affichage de la température */
  readTemp();
  
  /* Ecriture sur SD */
  DateTime now = RTC.now();
  int s = now.second();
  if (s == 0) {
  logToSD();
  serieAffichage();
  }
}
/***************************Fin du Loop****************************************/


/********************************************************************************/