Components and supplies
DHT22 Temperature Sensor
Module RTC 1302
Water pump 12v brushless
1mm silicon pipe 5meter
Dual H-Bridge motor drivers L298
8mm pvc pipe 5meter
MINI RELAY SPDT 5 PINS 12VDC 10A 120V CONTACT
I2C 16x2 Arduino LCD Display Module
Hw 125 MicroSD Reader
NodeMCU ESP8266 Breakout Board
Heatsink from PC watercooling
Peristaltic pump 12v 7w 11ml/min
Male/Female Jumper Wires
Module peltier 12706
Gravity: Analog LM35 Temperature Sensor For Arduino
Arduino Mega 2560
Plastic box 30X20X12cm
Adafruit Waterproof DS18B20 Digital temperature sensor
Tools and machines
Soldering iron (generic)
Hot glue gun (generic)
Multitool, Screwdriver
Drill / Driver, Cordless
Manual saw
Project description
Code
MEGA-ESP_v08_propre.ino
arduino
My first coding project
1int getMedianNum(int bArray[], int iFilterLen) 2{ 3 int bTab[iFilterLen]; 4 for (byte i = 0; i < iFilterLen; i++) 5 bTab[i] = bArray[i]; 6 int i, j, bTemp; 7 for (j = 0; j < iFilterLen - 1; j++) 8 { 9 for (i = 0; i < iFilterLen - j - 1; i++) 10 { 11 if (bTab[i] > bTab[i + 1]) 12 { 13 bTemp = bTab[i]; 14 bTab[i] = bTab[i + 1]; 15 bTab[i + 1] = bTemp; 16 } 17 } 18 } 19 if ((iFilterLen & 1) > 0) 20 bTemp = bTab[(iFilterLen - 1) / 2]; 21 else 22 bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2; 23 return bTemp; 24} 25 26byte Heart[8] = { 27 0b00000, 28 0b01010, 29 0b11111, 30 0b11111, 31 0b01110, 32 0b00100, 33 0b00000, 34 0b00000 35}; 36 37 38 39//=========================================debut Muoton"Black Sheep" Alexandros Pantelidis Avril 2020================================= 40byte tete1[8] = 41{ 42 0b00011, 43 0b00100, 44 0b01010, 45 0b10000, 46 0b11111, 47 0b00011, 48 0b00011, 49 0b00010 50}; 51 52byte tete2[8] = 53{ 54 0b11000, 55 0b11100, 56 0b10001, 57 0b11110, 58 0b10001, 59 0b11000, 60 0b11111, 61 0b10001 62}; 63 64byte tete3[8] = 65{ 66 0b00000, 67 0b00000, 68 0b10011, 69 0b01110, 70 0b10001, 71 0b00100, 72 0b10001, 73 0b01110 74}; 75 76byte tete4[8] = 77{ 78 0b00000, 79 0b00000, 80 0b00000, 81 0b10000, 82 0b01000, 83 0b01000, 84 0b11100, 85 0b10110 86}; 87 88byte bas1[8] = 89{ 90 0b00010, 91 0b00010, 92 0b00011, 93 0b00001, 94 0b00001, 95 0b00000, 96 0b00000, 97 0b00000 98}; 99 100byte bas2[8] = 101{ 102 0b01011, 103 0b01100, 104 0b00111, 105 0b01000, 106 0b11111, 107 0b01001, 108 0b01001, 109 0b01001 110}; 111 112byte bas3[8] = 113{ 114 0b00011, 115 0b11001, 116 0b00000, 117 0b10100, 118 0b11111, 119 0b00010, 120 0b00010, 121 0b00010 122}; 123 124byte bas4[8] = 125{ 126 0b10001, 127 0b01001, 128 0b00101, 129 0b10011, 130 0b11110, 131 0b00100, 132 0b00100, 133 0b00100 134}; 135//=========================================Fin mouton================================= 136//=========================================Librarie utilisées========================= 137#include <EEPROM.h> 138#include <DHT.h> 139#include <DallasTemperature.h> 140#include <SPI.h> 141#include <SD.h> 142#include <LiquidCrystal_I2C.h> 143#include <virtuabotixRTC.h> //Library used 144#include <ResponsiveAnalogRead.h> 145//=========================================Pin definie================================= 146#define RELAY1 24 147#define POMPES 22 148#define LAMPES 26 149#define moteurA_1 38 150#define moteurA_2 40 151#define moteurB_1 36 152#define moteurB_2 34 153#define DS1302_GND_PIN 33 154#define DS1302_VCC_PIN 31 155#define Tbox A2 156#define DHTPIN 32 // what pin we're connected to 157#define DHTTYPE DHT22 // DHT 22 (AM2302) 158#define TdsSensorPin A8 159#define VREF 5.0 // analog reference voltage(Volt) of the ADC 160#define SCOUNT 3 // sum of sample point 161#define ONE_WIRE_BUS 7 162//=========================================Constantes utiilisées============================ 163unsigned long currentMillis1 = 0; 164unsigned long currentMillis4 = 0; 165unsigned long previousMillis1 = 0; 166unsigned long previousMillis = 0; 167unsigned long previousMillis3 = 0; 168const long interval = 10000; 169unsigned long periodtds = 3600000; // 1h 170const long nettoyage = 10000; 171const int chipSelect = 49; 172unsigned long startMillis1; 173unsigned long startMillis; 174String message = ""; 175bool messageReady = false; 176String message1 = ""; 177bool messageReady1 = false; 178 179 180int analogBuffer1[SCOUNT]; // store the analog value in the array, read from ADC 181int analogBufferTemp1[SCOUNT]; 182int analogBufferIndex1 = 0, copyIndex1 = 0; 183 184int analogBuffer[SCOUNT]; 185int analogBufferTemp[SCOUNT]; 186int analogBufferIndex = 0, copyIndex = 0; 187float averageVoltage = 0 , tdsValue = 0; 188 189int analogBuffer2[SCOUNT]; 190int analogBufferTemp2[SCOUNT]; 191int analogBufferIndex2 = 0, copyIndex2 = 0; 192float averageVoltage2 = 0; 193 194int val; 195int addr = 0; 196 197const byte numChars = 64; 198char receivedChars[numChars]; 199char tempChars[numChars]; 200char messageFromPC[numChars] = {0}; 201int integerFromPC = 0; 202float floatFromPC = 0.0; 203boolean newData = false; 204 205int ledstate; 206int pompestate; 207 208int int1; 209int int2; 210int int3; 211int int4; 212int int5; 213int int6; 214int int7; 215 216int minteau ; 217int maxteau ; 218int timearro; 219 220float temperature; 221float humi; 222float temp; 223float tbox; 224int tdsval; 225 226int OnHour; 227int OnMin; //set hour and minutes for timer 228 229int OffHour; 230int OffMin; 231 232int valeur_brute; 233 234bool freshtds = false; 235bool cleanup = false; 236bool perioff = true; 237//=========================================Fonction declaré============================ 238 239LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display 240DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino 241OneWire oneWire(ONE_WIRE_BUS); 242DallasTemperature sensors(&oneWire); 243ResponsiveAnalogRead analog(Tbox, true); 244virtuabotixRTC myRTC(35, 37, 39); //If you change the wiring change the pins here also 245//=========================================Fonction demmarage ============================ 246void LedState() { 247 248 val = EEPROM.read(addr); 249 if (val == 1) 250 { 251 digitalWrite(LAMPES, HIGH); 252 253 } 254 if (val == 2) 255 { 256 digitalWrite(LAMPES, LOW); 257 } 258 maxteau = EEPROM.read(2); 259 minteau = EEPROM.read(3); 260 OnHour = EEPROM.read(4); 261 262 OnMin = EEPROM.read(5); 263 OffHour = EEPROM.read(6); 264 OffMin = EEPROM.read(7); 265 tdsval = 10 * EEPROM.read(8); 266 267 timearro = EEPROM.read(9); 268 269 Serial.println(maxteau); 270 Serial.println(minteau); 271 Serial.println(OnHour); 272 Serial.println(OnMin); 273 Serial.println(OffHour); 274 Serial.println(OffMin); 275 Serial.println(tdsval); 276 Serial.println(timearro); 277 278} 279 280//=========================================Executé au demmarage============================ 281void setup() { 282 Serial.begin(9600); 283 delay(1); 284 Serial1.begin(115200); 285 delay(1); 286 Serial.print("Initializing SD card..."); 287 delay(1); 288 289 if (!SD.begin(chipSelect)) { 290 Serial.println("Card failed, or not present"); 291 while (1); 292 } 293 Serial.println("card initialized."); 294 dht.begin(); 295 sensors.begin(); 296 pinMode(TdsSensorPin, INPUT); 297 pinMode(RELAY1, OUTPUT); 298 pinMode(POMPES, OUTPUT); 299 pinMode(LAMPES, OUTPUT); 300 pinMode(Tbox, INPUT); 301 pinMode(moteurA_1, OUTPUT); 302 pinMode(moteurB_1, OUTPUT); 303 pinMode(moteurA_2, OUTPUT); 304 pinMode(moteurB_2, OUTPUT); 305 digitalWrite(POMPES, HIGH); 306 digitalWrite(moteurA_1, LOW); 307 digitalWrite(moteurA_2, LOW); 308 digitalWrite(moteurB_1, LOW); 309 digitalWrite(moteurB_2, LOW); 310 digitalWrite(DS1302_GND_PIN, LOW); 311 pinMode(DS1302_GND_PIN, OUTPUT); 312 digitalWrite(DS1302_VCC_PIN, HIGH); 313 pinMode(DS1302_VCC_PIN, OUTPUT); 314 315 LedState(); 316 startMillis1 = millis(); 317 startMillis = millis(); 318 lcd.init(); 319 lcd.createChar(0, Heart); 320 lcd.createChar(1, tete1); 321 lcd.createChar(2, tete2); 322 lcd.createChar(3, tete3); 323 lcd.createChar(4, tete4); 324 lcd.createChar(5, bas1); 325 lcd.createChar(6, bas2); 326 lcd.createChar(7, bas3); 327 lcd.createChar(8, bas4); 328 lcd.backlight(); 329 lcd.setCursor(0, 0); 330 331 lcd.print("Alex's Hydro Box"); 332 lcd.setCursor(3, 1); 333 lcd.print("Bienvenue ^^"); 334 delay(5000); 335 lcd.clear(); 336 //myRTC.setDS1302Time(0, 8, 19, 2, 7, 4, 2020); 337 338} 339 340 341//=========================================Set cycle arrosage /on/off============================ 342 343 344void setpompe() { 345 timearro = EEPROM.read(9); 346 347 currentMillis1 = millis(); //get the current "time" (actually the number of milliseconds since the program started) 348 if (currentMillis1 - startMillis >= (1000 * 60 * timearro) ) { 349 digitalWrite(POMPES, !digitalRead(POMPES)); //if so, change the state of the LED. Uses a neat trick to change the state 350 startMillis = currentMillis1; //IMPORTANT to save the start time of the current LED state. 351 } 352} 353 354void recvWithStartEndMarkers() { 355 static boolean recvInProgress = false; 356 static byte ndx = 0; 357 char startMarker = '<'; 358 char endMarker = '>'; 359 char rc; 360 361 while (Serial1.available() > 0 && newData == false) { 362 rc = Serial1.read(); 363 364 if (recvInProgress == true) { 365 if (rc != endMarker) { 366 receivedChars[ndx] = rc; 367 ndx++; 368 if (ndx >= numChars) { 369 ndx = numChars - 1; 370 } 371 } 372 else { 373 receivedChars[ndx] = '\\0'; // terminate the string 374 recvInProgress = false; 375 ndx = 0; 376 newData = true; 377 } 378 } 379 380 else if (rc == startMarker) { 381 recvInProgress = true; 382 } 383 } 384} 385 386 387 388void parseData() { 389 390 char * strtokIndx; // this is used by strtok() as an index 391 392 //strtokIndx = strtok(tempChars,","); // get the first part - the string 393 //strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC 394 395 strtokIndx = strtok(tempChars, ","); // this continues where the previous call left off 396 integerFromPC = atoi(strtokIndx); 397 398 strtokIndx = strtok(NULL, ","); 399 int1 = atoi(strtokIndx); 400 401 strtokIndx = strtok(NULL, ","); 402 int2 = atoi(strtokIndx); 403 404 strtokIndx = strtok(NULL, ","); 405 int3 = atoi(strtokIndx); 406 407 strtokIndx = strtok(NULL, ","); 408 int4 = atoi(strtokIndx); 409 410 strtokIndx = strtok(NULL, ","); 411 int5 = atoi(strtokIndx); 412 413 strtokIndx = strtok(NULL, ","); 414 int6 = atoi(strtokIndx); 415 416 417} 418 419//=========================================fonction recu depuis nodemcu============================ 420 421void showParsedData() { 422 if (integerFromPC == 1) { 423 digitalWrite(LAMPES, HIGH); 424 EEPROM.update(addr, 1); 425 integerFromPC = 250; 426 } 427 if (integerFromPC == 0) { 428 digitalWrite(LAMPES, LOW); 429 EEPROM.update(addr, 2); 430 integerFromPC = 250; 431 } 432 433 if (integerFromPC == 4) { 434 digitalWrite(POMPES, HIGH); 435 integerFromPC = 250; 436 } 437 if (integerFromPC == 5) { 438 digitalWrite(POMPES, LOW); 439 integerFromPC = 250; 440 } 441 if (integerFromPC == 9 && int1 != 0 ) { 442 443 444 int timearro = int1; 445 446 EEPROM.update(9, timearro); 447 integerFromPC = 250; 448 int1 = 0; 449 } 450} 451 452void formulair () { 453 if (integerFromPC == 6 && int1 != 0 && int2 != 0) { 454 int maxteau = int1; 455 int minteau = int2; 456 EEPROM.update(2, maxteau); 457 EEPROM.update(3, minteau); 458 Serial.println(maxteau); 459 Serial.println(minteau); 460 integerFromPC = 250; 461 int1 = 0; 462 int2 = 0; 463 } 464} 465void formulair1 () { 466 if (integerFromPC == 7 && int3 != 0 ) { 467 int OnHour = int3; 468 int OnMin = int4; 469 int OffHour = int5; 470 int OffMin = int6; 471 EEPROM.update(4, OnHour); 472 EEPROM.update(5, OnMin); 473 EEPROM.update(6, OffHour); 474 EEPROM.update(7, OffMin); 475 Serial.println(OnHour); 476 Serial.println(OnMin); 477 Serial.println(OffHour); 478 Serial.println(OffMin); 479 integerFromPC = 250; 480 } 481} 482void tdsva () { 483 if (integerFromPC == 8 && int1 != 0 ) { 484 int tdsval = int1; 485 486 EEPROM.update(8, tdsval); 487 488 Serial.println(tdsval * 10); 489 490 integerFromPC = 250; 491 } 492} 493 494void settds() { 495 int tdsval = 10 * EEPROM.read(8); //10* valeur epprom car max 256 impossible de stocker 1000 comme valeur mais 100*10 c'est possible 496 497 unsigned long currentMillis3 = millis(); 498 if (tdsValue <= tdsval && tdsValue != 0 && freshtds == false && pompestate == 1 && tdsValue > 150) { 499 500 currentMillis4 = millis(); //get the current "time" (actually the number of milliseconds since the program started) 501 if (currentMillis4 - startMillis >= 8000 ) { 502 digitalWrite(moteurB_1, !digitalRead(moteurB_1)); //if so, change the state of the LED. Uses a neat trick to change the state 503 startMillis1 = currentMillis4; //IMPORTANT to save the start time of the current LED state. 504 505 } 506 previousMillis3 = currentMillis3; 507 cleanup = true; 508 } 509 if (tdsValue >= tdsval && cleanup == true ) { 510 511 digitalWrite(moteurB_1, LOW); 512 digitalWrite(moteurB_2, HIGH); 513 514 freshtds = true; 515 cleanup = false; 516 perioff = false; 517 518 } 519 if (currentMillis3 - previousMillis3 > nettoyage && perioff == false ) { 520 521 digitalWrite(moteurB_1, LOW); 522 digitalWrite(moteurB_2, LOW); 523 perioff = true; 524 } 525 526 if (currentMillis3 - previousMillis3 > periodtds && perioff == true) { 527 Serial.print("freshtds false"); 528 freshtds = false; 529 } 530} 531void loop() { 532 533 recvWithStartEndMarkers(); 534 if (newData == true) { 535 strcpy(tempChars, receivedChars); 536 // this temporary copy is necessary to protect the original data 537 // because strtok() used in parseData() replaces the commas with \\0 538 parseData(); 539 showParsedData(); 540 newData = false; 541 } 542 543 state(); 544 sensor(); 545 tdsva(); 546 setpompe(); 547 myRTC.updateTime(); 548 settds(); 549 formulair(); 550 formulair1(); 551 timmer(); 552 data(); 553 flcd(); 554 average(); 555 setwater(); 556} 557 558void state() { 559 maxteau = EEPROM.read(2); 560 minteau = EEPROM.read(3); 561 562 OnHour = EEPROM.read(4); 563 OnMin = EEPROM.read(5); 564 OffHour = EEPROM.read(6); 565 OffMin = EEPROM.read(7); 566 567 tdsval = 10 * EEPROM.read(8); 568 timearro = EEPROM.read(9); 569 analog.update(); 570 ledstate = digitalRead(LAMPES); 571 pompestate = digitalRead(POMPES); 572} 573 574void sensor() { 575 sensors.requestTemperatures(); 576 temperature = sensors.getTempCByIndex(0); 577 humi = dht.readHumidity(); 578 temp = dht.readTemperature(); 579 580 valeur_brute = analog.getValue(); 581 tbox = valeur_brute * (5.0 / 1023.0 * 100.0); 582} 583 584void setwater() { 585 if (temperature >= maxteau && temperature != -127 && temperature != 0) 586 { 587 digitalWrite(RELAY1, HIGH); 588 589 } 590 else if (temperature <= minteau && temperature != -127 && temperature != 0) 591 { 592 digitalWrite(RELAY1, LOW); 593 594 } 595 else { 596 ; 597 } 598} 599 600void average() { 601 static unsigned long analogSampleTimepoint = millis(); 602 if (millis() - analogSampleTimepoint > 40U) //every 40 milliseconds,read the analog value from the ADC 603 { 604 analogSampleTimepoint = millis(); 605 analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer 606 analogBufferIndex++; 607 if (analogBufferIndex == SCOUNT) 608 analogBufferIndex = 0; 609 } 610 static unsigned long printTimepoint = millis(); 611 if (millis() - printTimepoint > 800U) 612 { 613 printTimepoint = millis(); 614 for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++) 615 analogBufferTemp[copyIndex] = analogBuffer[copyIndex]; 616 averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value 617 float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); 618 float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation 619 tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value 620 } 621} 622 623 624 625void recorddata() { 626 627 unsigned long currentMillis = millis(); 628 if (currentMillis - previousMillis > 1000) { 629 previousMillis = currentMillis; 630 //Serial.print("Current Date / Time: "); 631 632 // Serial.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system && myRTC.minutes == OnMin 633 // Serial.print("/"); 634 // Serial.print(myRTC.month); 635 // Serial.print("/"); 636 // Serial.print(myRTC.year); 637 // Serial.print(" "); 638 // Serial.print(myRTC.hours); 639 // Serial.print(":"); 640 //Serial.print(myRTC.minutes); 641 // Serial.print(":"); 642 // Serial.println(myRTC.seconds); 643 // Serial.print("Humidity: "); 644 // Serial.print(humi); 645 // Serial.println(" %"); 646 // Serial.print("Temp air: "); 647 //Serial.print(temp); 648 // Serial.println(" Celsius"); 649 // Serial.print("Temp H2O ;"); 650 // Serial.print(temperature); 651 // Serial.println(" Celsius"); 652 // Serial.print("TDS Value:"); 653 // Serial.print(tdsValue, 0); 654 // Serial.println("ppm"); 655 //Serial.print("Temp box: "); 656 // Serial.println(tbox, 1); 657 // Serial.println(" Celsius"); 658 659 File dataFile = SD.open("datalog1.txt", FILE_WRITE); 660 delay(1); 661 dataFile.println(temperature); 662 delay(1); 663 dataFile.close(); 664 665 } 666} 667 668void timmer() { 669 if (myRTC.hours == OnHour && myRTC.minutes == OnMin ) { 670 EEPROM.update(addr, 1); 671 digitalWrite(LAMPES, HIGH); 672 delay(5); 673 } 674 else if (myRTC.hours == OffHour && myRTC.minutes == OffMin ) { // add && myRTC.minutes == OnMin ; (myRTC.hours == OffHour && myRTC.minutes == OffMin){ 675 EEPROM.update(addr, 2); 676 digitalWrite(LAMPES, LOW); 677 delay(5); 678 } 679} 680 681void data() { 682 if (integerFromPC == 3) { 683 684 Serial1.print("<"); 685 Serial1.print(ledstate); 686 Serial1.print(","); 687 Serial1.print(pompestate); 688 Serial1.print(","); 689 Serial1.print(tdsValue, 0); 690 Serial1.print(","); 691 Serial1.print(temp, 2); 692 Serial1.print(","); 693 Serial1.print(temperature, 2); 694 Serial1.print(","); 695 Serial1.print(humi, 2); 696 Serial1.print(","); 697 Serial1.print(tbox, 2); 698 Serial1.print(","); 699 Serial1.print(tdsval); 700 Serial1.print(","); 701 Serial1.print(OnHour); 702 Serial1.print(","); 703 Serial1.print(OnMin); 704 Serial1.print(","); 705 Serial1.print(OffHour); 706 Serial1.print(","); 707 Serial1.print(OffMin); 708 Serial1.print(","); 709 Serial1.print(maxteau); 710 Serial1.print(","); 711 Serial1.print(minteau); 712 Serial1.print(","); 713 Serial1.print(timearro); 714 Serial1.print(">"); 715 Serial1.println(""); 716 } 717} 718 719 720void flcd() { 721 lcd.setCursor(0, 0); 722 lcd.print("T Eau:"); 723 lcd.print(temperature, 1); 724 lcd.print((char)223); 725 lcd.setCursor(12, 0); 726 lcd.print("Hum:"); 727 lcd.print(humi, 0); 728 lcd.print(" % "); 729 lcd.print("AP Grow Box V1"); 730 lcd.print(" "); 731 lcd.write(byte(1)); 732 lcd.write(byte(2)); 733 lcd.write(byte(3)); 734 lcd.write(byte(4)); 735 736 lcd.setCursor(0, 1); 737 lcd.print("T Air:"); 738 lcd.print(temp, 1); 739 lcd.print((char)223); 740 lcd.setCursor(12, 1); 741 lcd.print("TDS:"); 742 lcd.print(tdsValue, 0); 743 lcd.print(" ppm "); 744 lcd.print("T Box:"); 745 lcd.print(tbox, 1); 746 lcd.print((char)223); 747 lcd.print(" "); 748 lcd.write(byte(5)); 749 lcd.write(byte(6)); 750 lcd.write(byte(7)); 751 lcd.write(byte(8)); 752 lcd.scrollDisplayLeft(); 753}
Aeroponic system
MEGA-ESP_v08_propre.ino
arduino
My first coding project
1int getMedianNum(int bArray[], int iFilterLen) 2{ 3 int bTab[iFilterLen]; 4 5 for (byte i = 0; i < iFilterLen; i++) 6 bTab[i] = bArray[i]; 7 int i, 8 j, bTemp; 9 for (j = 0; j < iFilterLen - 1; j++) 10 { 11 for (i = 0; i 12 < iFilterLen - j - 1; i++) 13 { 14 if (bTab[i] > bTab[i + 1]) 15 { 16 17 bTemp = bTab[i]; 18 bTab[i] = bTab[i + 1]; 19 bTab[i + 1] 20 = bTemp; 21 } 22 } 23 } 24 if ((iFilterLen & 1) > 0) 25 bTemp 26 = bTab[(iFilterLen - 1) / 2]; 27 else 28 bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen 29 / 2 - 1]) / 2; 30 return bTemp; 31} 32 33byte Heart[8] = { 34 0b00000, 35 36 0b01010, 37 0b11111, 38 0b11111, 39 0b01110, 40 0b00100, 41 0b00000, 42 43 0b00000 44}; 45 46 47 48//=========================================debut 49 Muoton"Black Sheep" Alexandros Pantelidis Avril 2020================================= 50byte 51 tete1[8] = 52{ 53 0b00011, 54 0b00100, 55 0b01010, 56 0b10000, 57 0b11111, 58 59 0b00011, 60 0b00011, 61 0b00010 62}; 63 64byte tete2[8] = 65{ 66 0b11000, 67 68 0b11100, 69 0b10001, 70 0b11110, 71 0b10001, 72 0b11000, 73 0b11111, 74 75 0b10001 76}; 77 78byte tete3[8] = 79{ 80 0b00000, 81 0b00000, 82 0b10011, 83 84 0b01110, 85 0b10001, 86 0b00100, 87 0b10001, 88 0b01110 89}; 90 91byte 92 tete4[8] = 93{ 94 0b00000, 95 0b00000, 96 0b00000, 97 0b10000, 98 0b01000, 99 100 0b01000, 101 0b11100, 102 0b10110 103}; 104 105byte bas1[8] = 106{ 107 0b00010, 108 109 0b00010, 110 0b00011, 111 0b00001, 112 0b00001, 113 0b00000, 114 0b00000, 115 116 0b00000 117}; 118 119byte bas2[8] = 120{ 121 0b01011, 122 0b01100, 123 0b00111, 124 125 0b01000, 126 0b11111, 127 0b01001, 128 0b01001, 129 0b01001 130}; 131 132byte 133 bas3[8] = 134{ 135 0b00011, 136 0b11001, 137 0b00000, 138 0b10100, 139 0b11111, 140 141 0b00010, 142 0b00010, 143 0b00010 144}; 145 146byte bas4[8] = 147{ 148 0b10001, 149 150 0b01001, 151 0b00101, 152 0b10011, 153 0b11110, 154 0b00100, 155 0b00100, 156 157 0b00100 158}; 159//=========================================Fin mouton================================= 160//=========================================Librarie 161 utilisées========================= 162#include <EEPROM.h> 163#include <DHT.h> 164#include 165 <DallasTemperature.h> 166#include <SPI.h> 167#include <SD.h> 168#include <LiquidCrystal_I2C.h> 169#include 170 <virtuabotixRTC.h> //Library used 171#include <ResponsiveAnalogRead.h> 172//=========================================Pin 173 definie================================= 174#define RELAY1 24 175#define POMPES 176 22 177#define LAMPES 26 178#define moteurA_1 38 179#define moteurA_2 40 180#define 181 moteurB_1 36 182#define moteurB_2 34 183#define DS1302_GND_PIN 33 184#define DS1302_VCC_PIN 185 31 186#define Tbox A2 187#define DHTPIN 32 // what pin we're connected to 188#define 189 DHTTYPE DHT22 // DHT 22 (AM2302) 190#define TdsSensorPin A8 191#define VREF 5.0 192 // analog reference voltage(Volt) of the ADC 193#define SCOUNT 3 // sum of sample 194 point 195#define ONE_WIRE_BUS 7 196//=========================================Constantes 197 utiilisées============================ 198unsigned long currentMillis1 = 0; 199unsigned 200 long currentMillis4 = 0; 201unsigned long previousMillis1 = 0; 202unsigned long 203 previousMillis = 0; 204unsigned long previousMillis3 = 0; 205const long interval 206 = 10000; 207unsigned long periodtds = 3600000; // 1h 208const long nettoyage = 10000; 209const 210 int chipSelect = 49; 211unsigned long startMillis1; 212unsigned long startMillis; 213String 214 message = ""; 215bool messageReady = false; 216String message1 = ""; 217bool 218 messageReady1 = false; 219 220 221int analogBuffer1[SCOUNT]; // store the analog 222 value in the array, read from ADC 223int analogBufferTemp1[SCOUNT]; 224int analogBufferIndex1 225 = 0, copyIndex1 = 0; 226 227int analogBuffer[SCOUNT]; 228int analogBufferTemp[SCOUNT]; 229int 230 analogBufferIndex = 0, copyIndex = 0; 231float averageVoltage = 0 , tdsValue = 0; 232 233int 234 analogBuffer2[SCOUNT]; 235int analogBufferTemp2[SCOUNT]; 236int analogBufferIndex2 237 = 0, copyIndex2 = 0; 238float averageVoltage2 = 0; 239 240int val; 241int addr = 242 0; 243 244const byte numChars = 64; 245char receivedChars[numChars]; 246char tempChars[numChars]; 247char 248 messageFromPC[numChars] = {0}; 249int integerFromPC = 0; 250float floatFromPC = 251 0.0; 252boolean newData = false; 253 254int ledstate; 255int pompestate; 256 257int 258 int1; 259int int2; 260int int3; 261int int4; 262int int5; 263int int6; 264int int7; 265 266int 267 minteau ; 268int maxteau ; 269int timearro; 270 271float temperature; 272float 273 humi; 274float temp; 275float tbox; 276int tdsval; 277 278int OnHour; 279int 280 OnMin; //set hour and minutes for timer 281 282int OffHour; 283int OffMin; 284 285int 286 valeur_brute; 287 288bool freshtds = false; 289bool cleanup = false; 290bool perioff 291 = true; 292//=========================================Fonction declaré============================ 293 294LiquidCrystal_I2C 295 lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display 296DHT 297 dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino 298OneWire 299 oneWire(ONE_WIRE_BUS); 300DallasTemperature sensors(&oneWire); 301ResponsiveAnalogRead 302 analog(Tbox, true); 303virtuabotixRTC myRTC(35, 37, 39); //If you change the wiring 304 change the pins here also 305//=========================================Fonction 306 demmarage ============================ 307void LedState() { 308 309 val = EEPROM.read(addr); 310 311 if (val == 1) 312 { 313 digitalWrite(LAMPES, HIGH); 314 315 } 316 if (val 317 == 2) 318 { 319 digitalWrite(LAMPES, LOW); 320 } 321 maxteau = EEPROM.read(2); 322 323 minteau = EEPROM.read(3); 324 OnHour = EEPROM.read(4); 325 326 OnMin = EEPROM.read(5); 327 328 OffHour = EEPROM.read(6); 329 OffMin = EEPROM.read(7); 330 tdsval = 10 * EEPROM.read(8); 331 332 333 timearro = EEPROM.read(9); 334 335 Serial.println(maxteau); 336 Serial.println(minteau); 337 338 Serial.println(OnHour); 339 Serial.println(OnMin); 340 Serial.println(OffHour); 341 342 Serial.println(OffMin); 343 Serial.println(tdsval); 344 Serial.println(timearro); 345 346} 347 348//=========================================Executé 349 au demmarage============================ 350void setup() { 351 Serial.begin(9600); 352 353 delay(1); 354 Serial1.begin(115200); 355 delay(1); 356 Serial.print("Initializing 357 SD card..."); 358 delay(1); 359 360 if (!SD.begin(chipSelect)) { 361 Serial.println("Card 362 failed, or not present"); 363 while (1); 364 } 365 Serial.println("card initialized."); 366 367 dht.begin(); 368 sensors.begin(); 369 pinMode(TdsSensorPin, INPUT); 370 pinMode(RELAY1, 371 OUTPUT); 372 pinMode(POMPES, OUTPUT); 373 pinMode(LAMPES, OUTPUT); 374 pinMode(Tbox, 375 INPUT); 376 pinMode(moteurA_1, OUTPUT); 377 pinMode(moteurB_1, OUTPUT); 378 pinMode(moteurA_2, 379 OUTPUT); 380 pinMode(moteurB_2, OUTPUT); 381 digitalWrite(POMPES, HIGH); 382 digitalWrite(moteurA_1, 383 LOW); 384 digitalWrite(moteurA_2, LOW); 385 digitalWrite(moteurB_1, LOW); 386 387 digitalWrite(moteurB_2, LOW); 388 digitalWrite(DS1302_GND_PIN, LOW); 389 pinMode(DS1302_GND_PIN, 390 OUTPUT); 391 digitalWrite(DS1302_VCC_PIN, HIGH); 392 pinMode(DS1302_VCC_PIN, OUTPUT); 393 394 395 LedState(); 396 startMillis1 = millis(); 397 startMillis = millis(); 398 lcd.init(); 399 400 lcd.createChar(0, Heart); 401 lcd.createChar(1, tete1); 402 lcd.createChar(2, 403 tete2); 404 lcd.createChar(3, tete3); 405 lcd.createChar(4, tete4); 406 lcd.createChar(5, 407 bas1); 408 lcd.createChar(6, bas2); 409 lcd.createChar(7, bas3); 410 lcd.createChar(8, 411 bas4); 412 lcd.backlight(); 413 lcd.setCursor(0, 0); 414 415 lcd.print("Alex's 416 Hydro Box"); 417 lcd.setCursor(3, 1); 418 lcd.print("Bienvenue ^^"); 419 delay(5000); 420 421 lcd.clear(); 422 //myRTC.setDS1302Time(0, 8, 19, 2, 7, 4, 2020); 423 424} 425 426 427//=========================================Set 428 cycle arrosage /on/off============================ 429 430 431void setpompe() { 432 433 timearro = EEPROM.read(9); 434 435 currentMillis1 = millis(); //get the current 436 "time" (actually the number of milliseconds since the program started) 437 if 438 (currentMillis1 - startMillis >= (1000 * 60 * timearro) ) { 439 digitalWrite(POMPES, 440 !digitalRead(POMPES)); //if so, change the state of the LED. Uses a neat trick 441 to change the state 442 startMillis = currentMillis1; //IMPORTANT to save the 443 start time of the current LED state. 444 } 445} 446 447void recvWithStartEndMarkers() 448 { 449 static boolean recvInProgress = false; 450 static byte ndx = 0; 451 char 452 startMarker = '<'; 453 char endMarker = '>'; 454 char rc; 455 456 while (Serial1.available() 457 > 0 && newData == false) { 458 rc = Serial1.read(); 459 460 if (recvInProgress 461 == true) { 462 if (rc != endMarker) { 463 receivedChars[ndx] = rc; 464 465 ndx++; 466 if (ndx >= numChars) { 467 ndx = numChars - 1; 468 469 } 470 } 471 else { 472 receivedChars[ndx] = '\\0'; // terminate 473 the string 474 recvInProgress = false; 475 ndx = 0; 476 newData 477 = true; 478 } 479 } 480 481 else if (rc == startMarker) { 482 recvInProgress 483 = true; 484 } 485 } 486} 487 488 489 490void parseData() { 491 492 char * strtokIndx; 493 // this is used by strtok() as an index 494 495 //strtokIndx = strtok(tempChars,","); 496 // get the first part - the string 497 //strcpy(messageFromPC, strtokIndx); 498 // copy it to messageFromPC 499 500 strtokIndx = strtok(tempChars, ","); // this 501 continues where the previous call left off 502 integerFromPC = atoi(strtokIndx); 503 504 505 strtokIndx = strtok(NULL, ","); 506 int1 = atoi(strtokIndx); 507 508 strtokIndx 509 = strtok(NULL, ","); 510 int2 = atoi(strtokIndx); 511 512 strtokIndx = strtok(NULL, 513 ","); 514 int3 = atoi(strtokIndx); 515 516 strtokIndx = strtok(NULL, ","); 517 518 int4 = atoi(strtokIndx); 519 520 strtokIndx = strtok(NULL, ","); 521 int5 522 = atoi(strtokIndx); 523 524 strtokIndx = strtok(NULL, ","); 525 int6 = atoi(strtokIndx); 526 527 528} 529 530//=========================================fonction 531 recu depuis nodemcu============================ 532 533void showParsedData() { 534 535 if (integerFromPC == 1) { 536 digitalWrite(LAMPES, HIGH); 537 EEPROM.update(addr, 538 1); 539 integerFromPC = 250; 540 } 541 if (integerFromPC == 0) { 542 digitalWrite(LAMPES, 543 LOW); 544 EEPROM.update(addr, 2); 545 integerFromPC = 250; 546 } 547 548 549 if (integerFromPC == 4) { 550 digitalWrite(POMPES, HIGH); 551 integerFromPC 552 = 250; 553 } 554 if (integerFromPC == 5) { 555 digitalWrite(POMPES, LOW); 556 557 integerFromPC = 250; 558 } 559 if (integerFromPC == 9 && int1 != 0 ) { 560 561 562 563 int timearro = int1; 564 565 EEPROM.update(9, timearro); 566 integerFromPC 567 = 250; 568 int1 = 0; 569 } 570} 571 572void formulair () { 573 if (integerFromPC 574 == 6 && int1 != 0 && int2 != 0) { 575 int maxteau = int1; 576 int minteau 577 = int2; 578 EEPROM.update(2, maxteau); 579 EEPROM.update(3, minteau); 580 581 Serial.println(maxteau); 582 Serial.println(minteau); 583 integerFromPC 584 = 250; 585 int1 = 0; 586 int2 = 0; 587 } 588} 589void formulair1 () { 590 591 if (integerFromPC == 7 && int3 != 0 ) { 592 int OnHour = int3; 593 int 594 OnMin = int4; 595 int OffHour = int5; 596 int OffMin = int6; 597 EEPROM.update(4, 598 OnHour); 599 EEPROM.update(5, OnMin); 600 EEPROM.update(6, OffHour); 601 EEPROM.update(7, 602 OffMin); 603 Serial.println(OnHour); 604 Serial.println(OnMin); 605 Serial.println(OffHour); 606 607 Serial.println(OffMin); 608 integerFromPC = 250; 609 } 610} 611void tdsva 612 () { 613 if (integerFromPC == 8 && int1 != 0 ) { 614 int tdsval = int1; 615 616 617 EEPROM.update(8, tdsval); 618 619 Serial.println(tdsval * 10); 620 621 integerFromPC 622 = 250; 623 } 624} 625 626void settds() { 627 int tdsval = 10 * EEPROM.read(8); 628 //10* valeur epprom car max 256 impossible de stocker 1000 comme valeur mais 629 100*10 c'est possible 630 631 unsigned long currentMillis3 = millis(); 632 if 633 (tdsValue <= tdsval && tdsValue != 0 && freshtds == false && pompestate == 1 && 634 tdsValue > 150) { 635 636 currentMillis4 = millis(); //get the current "time" 637 (actually the number of milliseconds since the program started) 638 if (currentMillis4 639 - startMillis >= 8000 ) { 640 digitalWrite(moteurB_1, !digitalRead(moteurB_1)); 641 //if so, change the state of the LED. Uses a neat trick to change the state 642 643 startMillis1 = currentMillis4; //IMPORTANT to save the start time of the current 644 LED state. 645 646 } 647 previousMillis3 = currentMillis3; 648 cleanup = 649 true; 650 } 651 if (tdsValue >= tdsval && cleanup == true ) { 652 653 digitalWrite(moteurB_1, 654 LOW); 655 digitalWrite(moteurB_2, HIGH); 656 657 freshtds = true; 658 cleanup 659 = false; 660 perioff = false; 661 662 } 663 if (currentMillis3 - previousMillis3 664 > nettoyage && perioff == false ) { 665 666 digitalWrite(moteurB_1, LOW); 667 668 digitalWrite(moteurB_2, LOW); 669 perioff = true; 670 } 671 672 if (currentMillis3 673 - previousMillis3 > periodtds && perioff == true) { 674 Serial.print("freshtds 675 false"); 676 freshtds = false; 677 } 678} 679void loop() { 680 681 recvWithStartEndMarkers(); 682 683 if (newData == true) { 684 strcpy(tempChars, receivedChars); 685 // this 686 temporary copy is necessary to protect the original data 687 // because strtok() 688 used in parseData() replaces the commas with \\0 689 parseData(); 690 showParsedData(); 691 692 newData = false; 693 } 694 695 state(); 696 sensor(); 697 tdsva(); 698 setpompe(); 699 700 myRTC.updateTime(); 701 settds(); 702 formulair(); 703 formulair1(); 704 timmer(); 705 706 data(); 707 flcd(); 708 average(); 709 setwater(); 710} 711 712void state() 713 { 714 maxteau = EEPROM.read(2); 715 minteau = EEPROM.read(3); 716 717 OnHour 718 = EEPROM.read(4); 719 OnMin = EEPROM.read(5); 720 OffHour = EEPROM.read(6); 721 722 OffMin = EEPROM.read(7); 723 724 tdsval = 10 * EEPROM.read(8); 725 timearro 726 = EEPROM.read(9); 727 analog.update(); 728 ledstate = digitalRead(LAMPES); 729 730 pompestate = digitalRead(POMPES); 731} 732 733void sensor() { 734 sensors.requestTemperatures(); 735 736 temperature = sensors.getTempCByIndex(0); 737 humi = dht.readHumidity(); 738 739 temp = dht.readTemperature(); 740 741 valeur_brute = analog.getValue(); 742 tbox 743 = valeur_brute * (5.0 / 1023.0 * 100.0); 744} 745 746void setwater() { 747 if (temperature 748 >= maxteau && temperature != -127 && temperature != 0) 749 { 750 digitalWrite(RELAY1, 751 HIGH); 752 753 } 754 else if (temperature <= minteau && temperature != -127 && 755 temperature != 0) 756 { 757 digitalWrite(RELAY1, LOW); 758 759 } 760 else 761 { 762 ; 763 } 764} 765 766void average() { 767 static unsigned long analogSampleTimepoint 768 = millis(); 769 if (millis() - analogSampleTimepoint > 40U) //every 40 milliseconds,read 770 the analog value from the ADC 771 { 772 analogSampleTimepoint = millis(); 773 774 analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog 775 value and store into the buffer 776 analogBufferIndex++; 777 if (analogBufferIndex 778 == SCOUNT) 779 analogBufferIndex = 0; 780 } 781 static unsigned long printTimepoint 782 = millis(); 783 if (millis() - printTimepoint > 800U) 784 { 785 printTimepoint 786 = millis(); 787 for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++) 788 analogBufferTemp[copyIndex] 789 = analogBuffer[copyIndex]; 790 averageVoltage = getMedianNum(analogBufferTemp, 791 SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median 792 filtering algorithm, and convert to voltage value 793 float compensationCoefficient 794 = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) 795 = fFinalResult(current)/(1.0+0.02*(fTP-25.0)); 796 float compensationVolatge 797 = averageVoltage / compensationCoefficient; //temperature compensation 798 tdsValue 799 = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 800 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; 801 //convert voltage value to tds value 802 } 803} 804 805 806 807void recorddata() 808 { 809 810 unsigned long currentMillis = millis(); 811 if (currentMillis - previousMillis 812 > 1000) { 813 previousMillis = currentMillis; 814 //Serial.print("Current 815 Date / Time: "); 816 817 // Serial.print(myRTC.dayofmonth); //You 818 can switch between day and month if you're using American system && myRTC.minutes 819 == OnMin 820 // Serial.print("/"); 821 // Serial.print(myRTC.month); 822 823 // Serial.print("/"); 824 // Serial.print(myRTC.year); 825 // Serial.print(" 826 "); 827 // Serial.print(myRTC.hours); 828 // Serial.print(":"); 829 //Serial.print(myRTC.minutes); 830 831 // Serial.print(":"); 832 // Serial.println(myRTC.seconds); 833 // 834 Serial.print("Humidity: "); 835 // Serial.print(humi); 836 // Serial.println(" 837 %"); 838 // Serial.print("Temp air: "); 839 //Serial.print(temp); 840 // 841 Serial.println(" Celsius"); 842 // Serial.print("Temp H2O ;"); 843 // 844 Serial.print(temperature); 845 // Serial.println(" Celsius"); 846 // Serial.print("TDS 847 Value:"); 848 // Serial.print(tdsValue, 0); 849 // Serial.println("ppm"); 850 851 //Serial.print("Temp box: "); 852 // Serial.println(tbox, 1); 853 // 854 Serial.println(" Celsius"); 855 856 File dataFile = SD.open("datalog1.txt", 857 FILE_WRITE); 858 delay(1); 859 dataFile.println(temperature); 860 delay(1); 861 862 dataFile.close(); 863 864 } 865} 866 867void timmer() { 868 if (myRTC.hours 869 == OnHour && myRTC.minutes == OnMin ) { 870 EEPROM.update(addr, 1); 871 digitalWrite(LAMPES, 872 HIGH); 873 delay(5); 874 } 875 else if (myRTC.hours == OffHour && myRTC.minutes 876 == OffMin ) { // add && myRTC.minutes == OnMin ; (myRTC.hours == OffHour && 877 myRTC.minutes == OffMin){ 878 EEPROM.update(addr, 2); 879 digitalWrite(LAMPES, 880 LOW); 881 delay(5); 882 } 883} 884 885void data() { 886 if (integerFromPC == 887 3) { 888 889 Serial1.print("<"); 890 Serial1.print(ledstate); 891 Serial1.print(","); 892 893 Serial1.print(pompestate); 894 Serial1.print(","); 895 Serial1.print(tdsValue, 896 0); 897 Serial1.print(","); 898 Serial1.print(temp, 2); 899 Serial1.print(","); 900 901 Serial1.print(temperature, 2); 902 Serial1.print(","); 903 Serial1.print(humi, 904 2); 905 Serial1.print(","); 906 Serial1.print(tbox, 2); 907 Serial1.print(","); 908 909 Serial1.print(tdsval); 910 Serial1.print(","); 911 Serial1.print(OnHour); 912 913 Serial1.print(","); 914 Serial1.print(OnMin); 915 Serial1.print(","); 916 917 Serial1.print(OffHour); 918 Serial1.print(","); 919 Serial1.print(OffMin); 920 921 Serial1.print(","); 922 Serial1.print(maxteau); 923 Serial1.print(","); 924 925 Serial1.print(minteau); 926 Serial1.print(","); 927 Serial1.print(timearro); 928 929 Serial1.print(">"); 930 Serial1.println(""); 931 } 932} 933 934 935void 936 flcd() { 937 lcd.setCursor(0, 0); 938 lcd.print("T Eau:"); 939 lcd.print(temperature, 940 1); 941 lcd.print((char)223); 942 lcd.setCursor(12, 0); 943 lcd.print("Hum:"); 944 945 lcd.print(humi, 0); 946 lcd.print(" % "); 947 lcd.print("AP Grow Box V1"); 948 949 lcd.print(" "); 950 lcd.write(byte(1)); 951 lcd.write(byte(2)); 952 lcd.write(byte(3)); 953 954 lcd.write(byte(4)); 955 956 lcd.setCursor(0, 1); 957 lcd.print("T Air:"); 958 959 lcd.print(temp, 1); 960 lcd.print((char)223); 961 lcd.setCursor(12, 1); 962 963 lcd.print("TDS:"); 964 lcd.print(tdsValue, 0); 965 lcd.print(" ppm "); 966 967 lcd.print("T Box:"); 968 lcd.print(tbox, 1); 969 lcd.print((char)223); 970 971 lcd.print(" "); 972 lcd.write(byte(5)); 973 lcd.write(byte(6)); 974 lcd.write(byte(7)); 975 976 lcd.write(byte(8)); 977 lcd.scrollDisplayLeft(); 978}
Aeroponic system
Downloadable files
Shemas Mega2560/nodemcu8266 Aeroponic System
Wiring shemas
Shemas Mega2560/nodemcu8266 Aeroponic System
Comments
Only logged in users can leave comments