Buongiorno a tutti,
Sto cercando di costruire una centralina per una serra per un progetto scolastico di una farm ad alta tecnologia e automazione.
Devo fare un paio di doverose premesse. La prima è ho provato prima a cercare sul forum se ci fosse qualcosa di simile ma ahimè, non sono stato in grado di trovarlo, la seconda è che non ci capisco un accidenti di programmazione, la terza invece, è che la parte hardware del progetto è stata affidata ad un amico che se ne intende parecchio trattando elettronica per lavoro (lavora con i plc e affini, programma qualsiasi cosa, ma al momento purtroppo non ha tempo di starci dietro), abbastanza da far funzionare correttamente il tutto. Non potendo allegare lo schema elettrico (perché non ho proprio idea di come fare, ma partiamo dal presupposto che il tutto sia cablato a dovere, mi scuso in anticipo per questa cosa, eventualmente se a qualcuno interessa proverò a domandare per vedere se si ricorda come l'ha costruita).
Inizierò elencando le componenti hardware utilizzate nel progetto:
- arduino mega 2560
- ethernet shield
- sdc30 collegato a SDA SLA
- ds18b20 (collegato a digital pin 46)
- 2x SRD-05VDC-SL-C (collegati ad arduino mega dal digital pin 22 al 25 e dal 26 29).
I relè che verranno impiegati saranno "22, 24 e 25", con il 22 collegato al primo e il 24 e 25 collegati dal 26 al 29). - 2 ventole da computer collegate ad alimentatore 12v, a sua volta collegato al relè 24.
- riscaldatore (una semplice lampadina nel mio caso, atta a dimostrare il funzionamento) collegato al relè 25 (che si accenderà, ad esempio, se la temperatura dovesse essere inferiore ai 25 gradi)
- una bombola di co2, che andrà ad attivarsi e disattivarsi tramite elettrovalvola nel caso in cui le ppm siano troppo basse rispetto quelle desiderate (essendo un progetto lascerò questa parte inutilizzata, non vi è niente di collegato serve solo al fine dimostrativo soffiando sopra al sensore).
Ora, quello che il controller deve sostanzialmente fare non è niente di più di accendere/spegnere delle ventole in base alla temperatura e umidità registrate; possibilmente dando la priorità alla temperatura rispetto l'umidità (questo semplicemente per evitare conflitti di accendi/spegni continui)
Faccio un esempio, se la temperatura massima è 29 gradi deve accendersi l'aspirazione finché non la riporta a 25, allo stesso tempo se la temperatura è di 25 ma l'umidità è superiore al 80% deve restare accesa finché non scende al 65 (questo in linea teorica, mi direte voi se è un'utopia perché come ho già detto mi dispiace, ma non me ne intendo).
I sensori vengono alimentati collegando la 220 a un alimentatore 5v per cellulari.
Ammetto di aver provato a sviluppare la cosa tramite l'utilizzo di chatgpt e devo dire che c'è molto vicina dal creare la cosa, fornirò ora il codice prodotto fino ad adesso, sapendo che (e dico così perché non leggendo i dati del sensore non ho modo di verificarne il corretto funzionamento) il programma in sé per sé funziona, l'unico problema riscontrato è che non mostra i dati dei sensori (indi per cui annulla la funzionalità del programma stesso).
Chiedo aiuto ai più navigati, se potete consigliarmi come muovermi.
Ringrazio anticipatamente per il tempo dedicatomi.
Ecco qui il programma in uso al momento:
#include <SPI.h>
#include <Ethernet.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "SparkFun_SCD30_Arduino_Library.h"
#define DHTPIN 2
#define DHTTYPE DHT22
#define ONE_WIRE_BUS 8
#define RELAY_PIN_22 24
#define RELAY_PIN_24 26
#define RELAY_PIN_25 27
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
EthernetServer server(80);
bool logicActive = true;
float temperature = 0;
float humidity = 0;
float co2 = 0;
float temperatureSetpointMin = 20;
float temperatureSetpointMax = 25;
int humiditySetpointMin = 60;
int humiditySetpointMax = 70;
int co2SetpointMin = 400;
int co2SetpointMax = 600;
void setup() {
// Inizializza i pin dei relè come OUTPUT
pinMode(RELAY_PIN_22, OUTPUT);
pinMode(RELAY_PIN_24, OUTPUT);
pinMode(RELAY_PIN_25, OUTPUT);
// Inizializza la comunicazione seriale
Serial.begin(9600);
// Inizializza il sensore DHT
dht.begin();
// Inizializza il sensore di temperatura DS18B20
sensors.begin();
// Imposta il relè 22 come spento
digitalWrite(RELAY_PIN_22, LOW);
// Avvia la connessione Ethernet con MAC address e indirizzo IP
uint8_t mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 178, 180);
Ethernet.begin(mac, ip);
server.begin();
}
void loop() {
// Gestisci la connessione client
EthernetClient client = server.available();
if (client) {
processClient(client);
client.stop();
}
// Esegui la logica solo se il programma è attivo
if (logicActive) {
updateSensorsData();
checkAndControlRelays();
}
}
void processClient(EthernetClient& client) {
String request = client.readStringUntil('\r');
client.flush();
if (request.indexOf("/run") != -1) {
logicActive = true;
} else if (request.indexOf("/stop") != -1) {
logicActive = false;
} else if (request.indexOf("/releon22") != -1) {
digitalWrite(RELAY_PIN_22, HIGH);
} else if (request.indexOf("/releoff22") != -1) {
digitalWrite(RELAY_PIN_22, LOW);
} else if (request.indexOf("/releon24") != -1) {
digitalWrite(RELAY_PIN_24, HIGH);
} else if (request.indexOf("/releoff24") != -1) {
digitalWrite(RELAY_PIN_24, LOW);
} else if (request.indexOf("/releon25") != -1) {
digitalWrite(RELAY_PIN_25, HIGH);
} else if (request.indexOf("/releoff25") != -1) {
digitalWrite(RELAY_PIN_25, LOW);
} else if (request.indexOf("/IncSetPointReleOn22") != -1) {
increaseCo2SetpointMin();
} else if (request.indexOf("/DecSetPointReleOn22") != -1) {
decreaseCo2SetpointMin();
} else if (request.indexOf("/IncSetPointReleOff22") != -1) {
increaseCo2SetpointMax();
} else if (request.indexOf("/DecSetPointReleOff22") != -1) {
decreaseCo2SetpointMax();
} else if (request.indexOf("/IncSetPointReleOn24") != -1) {
increaseTemperatureSetpointMin();
} else if (request.indexOf("/DecSetPointReleOn24") != -1) {
decreaseTemperatureSetpointMin();
} else if (request.indexOf("/IncSetPointReleOff24") != -1) {
increaseTemperatureSetpointMax();
} else if (request.indexOf("/DecSetPointReleOff24") != -1) {
decreaseTemperatureSetpointMax();
} else if (request.indexOf("/IncSetPointReleOn25") != -1) {
increaseHumiditySetpointMin();
} else if (request.indexOf("/DecSetPointReleOn25") != -1) {
decreaseHumiditySetpointMin();
} else if (request.indexOf("/IncSetPointReleOff25") != -1) {
increaseHumiditySetpointMax();
} else if (request.indexOf("/DecSetPointReleOff25") != -1) {
decreaseHumiditySetpointMax();
}
sendHttpResponse(client);
}
void sendHttpResponse(EthernetClient& client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html><meta http-equiv=\"refresh\" content=\"10;URL=/\">");
client.println("<a href=\"/run\">Attiva logica</a> <br><a href=\"/stop\">Ferma logica</a> <br>stato Logica=" + String(logicActive) + "<br>");
client.println("Temperatura= " + String(temperature) + "<br>");
client.println("Co2(ppm)= " + String(co2) + "<br>");
client.println("temp(C)= " + String(dht.readTemperature()) + "<br>");
client.println("humidity(%)= " + String(dht.readHumidity()) + "<br>");
client.println("PPM minima desiderata <a href=\"/IncSetPointReleOn22\">[+]</a> <a href=\"/DecSetPointReleOn22\">[-]</a> valore=" + String(co2SetpointMin) + "<br>");
client.println("PPM massima desiderata <a href=\"/IncSetPointReleOff22\">[+]</a> <a href=\"/DecSetPointReleOff22\">[-]</a> valore=" + String(co2SetpointMax) + "<br>");
client.println("Temperatura minima desiderata <a href=\"/IncSetPointReleOn24\">[+]</a> <a href=\"/DecSetPointReleOn24\">[-]</a> valore=" + String(temperatureSetpointMin) + "<br>");
client.println("Temperatura massima desiderata <a href=\"/IncSetPointReleOff24\">[+]</a> <a href=\"/DecSetPointReleOff24\">[-]</a> valore=" + String(temperatureSetpointMax) + "<br>");
client.println("Umidita' minima desiderata <a href=\"/IncSetPointReleOn25\">[+]</a> <a href=\"/DecSetPointReleOn25\">[-]</a> valore=" + String(humiditySetpointMin) + "<br>");
client.println("Umidita' massima desiderata <a href=\"/IncSetPointReleOff25\">[+]</a> <a href=\"/DecSetPointReleOff25\">[-]</a> valore=" + String(humiditySetpointMax) + "<br>");
client.println("<a href=\"/releon22\">Accendi rele22</a> <a href=\"/releoff22\">Spegni rele22</a> stato=" + String(digitalRead(RELAY_PIN_22)) + "<br>");
client.println("<a href=\"/releon24\">Accendi rele24</a> <a href=\"/releoff24\">Spegni rele24</a> stato=" + String(digitalRead(RELAY_PIN_24)) + "<br>");
client.println("<a href=\"/releon25\">Accendi rele25</a> <a href=\"/releoff25\">Spegni rele25</a> stato=" + String(digitalRead(RELAY_PIN_25)) + "<br>");
client.println("</html>");
}
void updateSensorsData() {
// Aggiorna i dati del sensore DHT
temperature = dht.readTemperature();
humidity = dht.readHumidity();
// Aggiorna i dati del sensore SDC30 (da implementare correttamente)
// co2 = ...;
}
void checkAndControlRelays() {
// Controllo e attivazione relè 24 e 25 in base all'umidità
if (humidity > humiditySetpointMax) {
digitalWrite(RELAY_PIN_24, HIGH);
digitalWrite(RELAY_PIN_25, HIGH);
} else if (humidity < humiditySetpointMin) {
digitalWrite(RELAY_PIN_24, LOW);
digitalWrite(RELAY_PIN_25, LOW);
}
// Controllo e attivazione relè 24 e 25 in base alla temperatura
if (temperature > temperatureSetpointMax) {
digitalWrite(RELAY_PIN_24, HIGH);
digitalWrite(RELAY_PIN_25, HIGH);
} else if (temperature < temperatureSetpointMin) {
digitalWrite(RELAY_PIN_24, LOW);
digitalWrite(RELAY_PIN_25, LOW);
}
}
void increaseTemperatureSetpointMin() {
temperatureSetpointMin++;
}
void decreaseTemperatureSetpointMin() {
temperatureSetpointMin--;
}
void increaseTemperatureSetpointMax() {
temperatureSetpointMax++;
}
void decreaseTemperatureSetpointMax() {
temperatureSetpointMax--;
}
void increaseHumiditySetpointMin() {
humiditySetpointMin += 5;
}
void decreaseHumiditySetpointMin() {
humiditySetpointMin -= 5;
}
void increaseHumiditySetpointMax() {
humiditySetpointMax += 5;
}
void decreaseHumiditySetpointMax() {
humiditySetpointMax -= 5;
}
void increaseCo2SetpointMin() {
co2SetpointMin += 100;
}
void decreaseCo2SetpointMin() {
co2SetpointMin -= 100;
}
void increaseCo2SetpointMax() {
co2SetpointMax += 100;
}
void decreaseCo2SetpointMax() {
co2SetpointMax -= 100;
}
Allego la sorgente che viene mostrata nella pagina
| Attiva logica Ferma logica stato Logica=1 |
|
| Temperatura= NAN |
|
| Co2(ppm)= 0.00 |
|
| temp(C)= NAN |
|
| humidity(%)= NAN |
|
| PPM minima desiderata [+] [-] valore=400 |
|
| PPM massima desiderata [+] [-] valore=600 |
|
| Temperatura minima desiderata [+] [-] valore=20.00 |
|
| Temperatura massima desiderata [+] [-] valore=25.00 |
|
| Umidita' minima desiderata [+] [-] valore=60 |
|
| Umidita' massima desiderata [+] [-] valore=70 |
|
| Accendi rele22 Spegni rele22 stato=0 |
|
| Accendi rele24 Spegni rele24 stato=0 |
|
| Accendi rele25 Spegni rele25 stato=0 |
|