(update 27/04/21)
Finalmente il mio sistema arduino per acquario è entrato in funzione, è stato necessario costruire i cavi ad-hoc e saldare su millefori, al momento Aquardino è in grado di mostrare l’ora, gestire con un timer le luci (relay su presa multipla), misurare la temperatura esterna ed interna dell’acquario, controllare il PH con la sonda dedicata (quando immersa) e comandare indipendentemente le luci e il filtro/riscaldatore attraverso un telecomando a IR.
https://create.arduino.cc/projecthub/wildbuzz/aquardino-v2-2e1556
Componenti:
- Arduino Uno
- DS18B20 Sonda di Temperatura Digitale (n°2)
- KY-019 relay 5v
- RTC (DS3231)
- AZOLED12864-1000 (SSD 1306) 0,96 pollici 128×64 Pixel I2C
- Sensore PH con scheda dedicata
- Ricevitore IR
- varie: cavi, millefori, presa multipla, case, guaina termoretraibile, connettori
/* * Aquardino v 2.2 * alessandrobuzzi.com * * IR (elegoo) -> https://github.com/Arduino-IRremote/Arduino-IRremote * RTC (DS3231) -> https://github.com/sleemanj/DS3231_Simple * PH sensor -> https://wiki.dfrobot.com/PH_meter_SKU__SEN0161_ * LCD (I2c 16x2) -> https://www.maffucci.it/2019/01/25/utilizzo-delllcd-16x2-hitachi-hd44780-1602-con-modulo-i2c-pcf8574t/ * Temp (DS18B20) -> https://randomnerdtutorials.com/esp8266-ds18b20-temperature-sensor-web-server-with-arduino-ide/ */ // ------------------------ IR -----------------------------// #define DECODE_NEC #include <Arduino.h> #define IR_RECEIVE_PIN 7 #include <IRremote.h> // ------------------------ LCD -----------------------------// #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // impostazione dell'indirizzo dell'LCD 0x27 di 16 caratteri e 2 linee // ------------------------ Temperature -----------------------------// #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 4 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); DeviceAddress sensor1 = { 0x28, 0x58, 0xA0, 0x96, 0x42, 0x20, 0x1, 0xAB }; DeviceAddress sensor2 = { 0x28, 0x62, 0x62, 0x9, 0x42, 0x20, 0x1, 0x53 }; // ------------------------ PH -----------------------------// #define SensorPin A0 //pH meter Analog output to Arduino Analog Input 0 #define Offset 0.27 //deviation compensate #define LED 13 #define samplingInterval 20 #define printInterval 800 #define ArrayLenth 40 //times of collection int pHArray[ArrayLenth]; //Store the average value of the sensor feedback int pHArrayIndex=0; // ------------------------ RTC -----------------------------// #include <DS3231_Simple.h> DS3231_Simple Clock; // costanti per timing loop int Period1, Period2; unsigned long Time1, Time2; // ------------------------ custom -----------------------------// const int SW1 = 8; // the Arduino pin, which connects to the IN pin of relay const int SW2 = 9; // the Arduino pin, which connects to the IN pin of relay const int SW3 = 10; // the Arduino pin, which connects to the IN pin of relay // time night lights const int OnHour = 18; //SET TIME TO ON RELAY (24 HOUR FORMAT) const int OnMin = 1; const int OffHour = 22; //SET TIME TO OFF RELAY const int OffMin = 1; // time sun lights const int OnHour1 = 9; //SET TIME TO ON RELAY2 (24 HOUR FORMAT) const int OnMin1 = 1; const int OffHour1 = 18; //SET TIME TO OFF RELAY (18) const int OffMin1 = 22; // ------------------------ end includes and libraries -----------------------------// void setup() { Serial.begin(115200); // ------------------------ IR -----------------------------// IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK, USE_DEFAULT_FEEDBACK_LED_PIN); Serial.print(F("Ready to receive IR signals at pin ")); Serial.println(IR_RECEIVE_PIN); // ------------------------ LCD -----------------------------// lcd.begin(); // inizializzazione dell'LCD lcd.backlight(); // attivazione della retroilluminazione // ------------------------ RTC -----------------------------// Clock.begin(); // ------------------------ Temperature -----------------------------// sensors.begin(); // ------------------------ custom -----------------------------// // relays on pinMode(SW1, OUTPUT); pinMode(SW2, OUTPUT); pinMode(SW3, OUTPUT); digitalWrite(SW1, HIGH); // Relay is active low, so HIGH will turn it off at startup digitalWrite(SW2, HIGH); digitalWrite(SW3, HIGH); // time define Time1 = Time2 = millis(); Period1 = 10000; // 10 sec Period2 = 2000; // 0,2 sec } void loop() { // ------------------------ IR -----------------------------// if (IrReceiver.decode()) { // Print a short summary of received data IrReceiver.printIRResultShort(&Serial); if (IrReceiver.decodedIRData.protocol == UNKNOWN) { // We have an unknown protocol here, print more info IrReceiver.printIRResultRawFormatted(&Serial, true); } Serial.println(); IrReceiver.resume(); // Enable receiving of the next value /* * Finally, check the received data and perform actions according to the received command */ if (IrReceiver.decodedIRData.command == 0xC) { // 1 digitalWrite(SW1, LOW); } else if (IrReceiver.decodedIRData.command == 0x18) { // 2 digitalWrite(SW1, HIGH); }else if (IrReceiver.decodedIRData.command == 0x8) { // 4 digitalWrite(SW2, LOW); }else if (IrReceiver.decodedIRData.command == 0x1C) { // 5 digitalWrite(SW2, HIGH); }else if (IrReceiver.decodedIRData.command == 0x42) { // 7 digitalWrite(SW3, LOW); }else if (IrReceiver.decodedIRData.command == 0x52) { // 8 digitalWrite(SW3, HIGH); // tasto 8 }else if (IrReceiver.decodedIRData.command == 0x9) { // DOWN digitalWrite(SW1, HIGH); // All off digitalWrite(SW2, HIGH); digitalWrite(SW3, HIGH); }else if (IrReceiver.decodedIRData.command == 0x7) { // UP digitalWrite(SW1, LOW); // All on digitalWrite(SW2, LOW); digitalWrite(SW3, LOW); } } // ------------------------ RTC -----------------------------// DateTime MyDateAndTime; // Ask the clock for the data. MyDateAndTime = Clock.read(); //timerl luci base if(MyDateAndTime.Hour == OnHour && MyDateAndTime.Minute == OnMin){ digitalWrite(SW1,HIGH); Serial.println("LIGHT ON"); } else if(MyDateAndTime.Hour == OffHour && MyDateAndTime.Minute == OffMin){ digitalWrite(SW1,LOW); Serial.println("LIGHT OFF"); } //timer luce notturna if(MyDateAndTime.Hour == OnHour1 && MyDateAndTime.Minute == OnMin1){ digitalWrite(SW2,HIGH); Serial.println("LIGHT ON"); } else if(MyDateAndTime.Hour == OffHour1 && MyDateAndTime.Minute == OffMin1){ digitalWrite(SW2,LOW); Serial.println("LIGHT OFF"); } lcd.setCursor(0,0); lcd.print(MyDateAndTime.Hour);lcd.print(":");lcd.print(MyDateAndTime.Minute); // ----------- loop time for sensor request if(millis()-Time1>=Period1){ // ------------------------ Temperature -----------------------------// Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); // Send the command to get temperatures Serial.println("DONE"); Serial.print("Sensor 1(*C): "); Serial.print(sensors.getTempC(sensor1)); Serial.print(" Sensor 1(*F): "); Serial.println(sensors.getTempF(sensor1)); Serial.print("Sensor 2(*C): "); Serial.print(sensors.getTempC(sensor2)); Serial.print(" Sensor 2(*F): "); Serial.println(sensors.getTempF(sensor2)); //-----// lcd.setCursor(0,1); lcd.print("T: "); lcd.print(sensors.getTempC(sensor1)); lcd.setCursor(10,1); lcd.print(""); lcd.print(sensors.getTempC(sensor2)); // ora Serial.print(MyDateAndTime.Hour); Serial.write(':'); Serial.print(MyDateAndTime.Minute); Serial.println(); // relay attivi Serial.write("R1="); Serial.print(digitalRead (SW1)); Serial.println(); Serial.write("R2="); Serial.print(digitalRead (SW2)); Serial.println(); Serial.write("R3="); Serial.print(digitalRead (SW3)); Serial.println(); // ------------------------ PH -----------------------------// static unsigned long samplingTime = millis(); static unsigned long printTime = millis(); static float pHValue,voltage; if(millis()-samplingTime > samplingInterval) { pHArray[pHArrayIndex++]=analogRead(SensorPin); if(pHArrayIndex==ArrayLenth)pHArrayIndex=0; voltage = avergearray(pHArray, ArrayLenth)*5.0/1024; pHValue = 3.5*voltage+Offset; samplingTime=millis(); } if(millis() - printTime > printInterval) //Every 800 milliseconds, print a numerical, convert the state of the LED indicator { Serial.print("Voltage:"); Serial.print(voltage,2); Serial.print(" pH value: "); Serial.println(pHValue,2); digitalWrite(LED,digitalRead(LED)^1); printTime=millis(); // LCD display lcd.setCursor(8,0); lcd.print("PH: "); lcd.print(pHValue,2); } Time1=millis(); } // end loop time for sensors } //end void loop // PH sensor function double avergearray(int* arr, int number){ int i; int max,min; double avg; long amount=0; if(number<=0){ Serial.println("Error number for the array to avraging!/n"); return 0; } if(number<5){ //less than 5, calculated directly statistics for(i=0;i<number;i++){ amount+=arr[i]; } avg = amount/number; return avg; }else{ if(arr[0]<arr[1]){ min = arr[0];max=arr[1]; } else{ min=arr[1];max=arr[0]; } for(i=2;i<number;i++){ if(arr[i]<min){ amount+=min; //arr<min min=arr[i]; }else { if(arr[i]>max){ amount+=max; //arr>max max=arr[i]; }else{ amount+=arr[i]; //min<=arr<=max } }//if }//for avg = (double)amount/(number-2); }//if return avg; }// end PH sensor function
Lascia un commento