Devices & Components
16x2 LCD display with I²C interface
Arduino Mega 2560 Rev3
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
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
Plastic box 30X20X12cm
Adafruit Waterproof DS18B20 Digital temperature sensor
Hardware & Tools
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