What's new
  • ICMag with help from Landrace Warden and The Vault is running a NEW contest in November! You can check it here. Prizes are seeds & forum premium access. Come join in!

[Working In Progress] Progetto GrowStation - Arduino

Selvaticus

Member
Con Arduino (o un altro microcontroller) potresti regolare tutto, servono dei sensori che rilevino temperatura ed umidità e delle schede con relé per pilotare (accendere/spegnere) umidificatore/deumidificatore, ventole/estrattori, luci, eventuali pompe per l'irrigazione, ecc...
Il tutto verrebbe regolato da un software che legge le condizioni ambientali e superate certe soglie dà i comandi per accendere o spegnere i vari dispositivi.
 
Ciao Bluedeep. ieri mi è arrivato il tutto anche a me:biggrin::biggrin:.. puoi dagli un occhiata se mi manca qualcosa?…è un po’ diverso del tuo ma la programmazione sarà la stessa no?…spero che questo inverno mi dai una mano sulla programmazione cercherò di essere un po’ preparato sul argomento…buon coltivo:tiphat:

picture.php
 

Corrente

Member
Lo scopo è praticamente quello.

Basta programmare arduino dicendo che se dal sensore di temperatura legge più di 28°C, allora accende l'aspirazione (attraverso un rele'), quando questa scende sotto i 25°C spegne l'aspirazione sganciando il relativo rele'

Con Arduino (o un altro microcontroller) potresti regolare tutto, servono dei sensori che rilevino temperatura ed umidità e delle schede con relé per pilotare (accendere/spegnere) umidificatore/deumidificatore, ventole/estrattori, luci, eventuali pompe per l'irrigazione, ecc...
Il tutto verrebbe regolato da un software che legge le condizioni ambientali e superate certe soglie dà i comandi per accendere o spegnere i vari dispositivi.

A saperlo fare... Dove lo trovo dalle mie parti un elettricista che sia anche programmatore, come voi? Io purtroppo di queste cose, ripeto, ne capisco pochissimo... Se mi chiamano Corrente è per un altro motivo!

Comunque continuo a seguire; ripeto: davvero ottimo progetto signori! :tiphat:
 
Beh se sei di zona perché no :D

Comunque sono a circa 300 linee di codice:

-Sync NTP Completato
-Interfacciamento con PHP/MYSQL per la registrazione dei dati completato.

Presto comincio a guardare i rele' :)
 
Ciao Ragazzi,

ho bisogno di una mano con le soglie di umidità/temperatura per abilitare ventilazione e umidificatore/deumidificatore



#define LUCE_START 8 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 20 //Imposta lo spegnimento della lampada

#define TEMP_MAX 30.00 //Temperatura Massima
#define TEMP_MIN 22.00 //Temperatura Minima

#define HUM_MAX 70.00 //Umidità Massima
#define HUM_MIN 30.00 //Umidità Minima
 

Edhorin

Member
Certo che serve :)

Ma è una cosa veramente stupida! Arduino è in grado di inviare un URL con una serie di variabili

Es

Code:
input.php?temp1=$var1&umd1=$var2&temp2=$var3...
input.php prenderà queste variabili e le butterà dentro sql. Quindi connect col db e INSERT.

La parte più complicata è fare un php force con fusioncharts (meglio qualcosa di open però)



Dai stessa idea :) Bene! Per scuola qualche anno fa ho studiato il c. Arduino si programma in c++ (molto simile). Sono un po' arrugginito ma credo di poter tirare fuori gli zampini... basta basterci un po' la testa. Diciamo che è molto più semplice che programmare a basso livello :D



Puoi metterlo sotto UPS ma in realtà non serve. Se ti manca la luce non ce l'hai nemmeno per comandare le luci e altro (sempre se non hai un signor UPS). Arduino fa un boot in un s
econdo e la programmazione resiste ovviamente in mancanza di corrente



D'accordo ma così poi non monitorizzi un parametro. L'umidità del terreno :(
Permettono di dissentire se manca la corrente in salta la programmazione ma saltano i registri cioè lo stack la heap e le flag dovresti pensare ad un real time clock x la temporizzazione. Seguo poiché lavoriamo sulla stessa idea solo che io prferisco il processore armi CN programmazione nuda e cruda mi fido ancora poco delle librerie
 

Edhorin

Member
D'accordo ma così poi non monitorizzi un parametro. L'umidità del terreno :(

Per l umidita del terreno si può sempre controllare cosi capisco se i blumat fanno veramente il suo dovere…



Corrosione? Secondo me lo sanno che vanno nel terreno avrà una sua protezione una specie di vernicetta almeno spero…. scorrerà elettricità ma penso che alla piante non faccia nulla se no lo vendono a fare.. oramai è qua a casa…la seconda domanda è inutile è come se parleresti in cinese per me …dammi un po’ di tempo perché adesso ho altro da fare e non posso buttarmi su questo arduino perché lo so come sono fatto non dormo più di notte se mi ci metto..cmq seguo con molto interesse il tuo Thread..ciao e buon proseguimento…:tiphat::tiphat:

p.s. chiedi ai moderatori di postare il Thread mi sa che non è la sezione giusta…[/QUOTE]

Si fa la elettrolisi delle particelle di acqua vicino al sensore un va sempre alimentato ma attivato a step di 2-3 ore
 
Intanto vi posto un po' di codice che sto sviluppando, ovviamente è ancora allo stato grezzo :)

/*
* GrowStation.pde
* Alpha Stage - by Bluedeep85
* https://www.icmag.com/ic/showthread.php?t=285405
* Credits:
* Codice NTP basato su Time_NTP.pde by pklaus
*
*/

#include <Time.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Dns.h>
#include "DHT.h"
#include <Wire.h>
#include <Digital_Light_TSL2561.h>
#include <LiquidCrystal.h>

#define LUCE_START 1 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 2 //Imposta lo spegnimento della lampada

#define TEMP_MAX 30.00 //Temperatura Massima
#define TEMP_MIN 22.00 //Temperatura Minima

#define HUM_MAX 70.00
#define HUM_MIN 30.00

LiquidCrystal lcd(22, 23, 24, 25, 26, 27); //Inizializzo la librearia con i numeri dei pin collegati

// Imposta un MAC address per il tuo controller
// Nessuna Ethernet shields ha un MAC address stampato sul modulo
byte mac[] = { 0xDE, 0xAD, 0xBC, 0xEF, 0xFE, 0xE0 };
byte ip[] = {192, 168, 1, 100 }; //IP dell'interfaccia
byte gateway[] = {192, 168, 1, 1 }; //Gateway
byte mask [] = {255, 255, 255, 0 }; //NetMask

//IPAddress timeServer(132, 163, 4, 101); // time.nist.gov NTP server
IPAddress timeServer(192, 168, 1, 7); // time.nist.gov NTP server
#define BAUD 9600 // Baud rate of serial port

#define DHTPIN1 A10 //a quale pin è collegato il sensore
#define DHTPIN2 A12 //a quale pin è collegato il sensore
#define DHTPIN3 A14 //a quale pin è collegato il sensore
#define RELAY1 14 //a quale pin è collegato il relay

#define LOG_INTERVAL 500 // mills between entries

#define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero
#define WAIT_TO_START 0 // Wait for serial input in setup()
#define ADC_DELAY 10 // ADC delay for high impedence sensors

#define TZ_OFFSET -7200L // time zone offset - set this to the offset in seconds to your local time;
#define TIME_SYNC_INTERVAL 86400 // = 60*60*24 seconds = 1 day until time is synced again

#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
DHT dht3(DHTPIN3, DHTTYPE);

#define LOCAL_UDP_PORT 8888 // local port to listen for UDP packets
// Can connect via Netcat (`nc 193.149.10.108 23`)
// or via Telnet (`telnet 193.149.10.108`)

#define LED1 4
#define LED2 2

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

const char* host = "nsath.forthnet.gra"; // Use random servers through DNS

EthernetClient client; //Costruttore per la sessione client
//indirizzo server web (locale)
IPAddress server(192, 168, 1, 7);

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Istanza DNS per risolvere i nomi a dominio
DNSClient Dns;
IPAddress rem_add;

time_t prevDisplay = 0; // when the digital clock was displayed
time_t cur_time = 0;

char isodate[25]; // The current time in ISO format is being stored here


// buffer to format data - makes it eaiser to echo to Serial
char buf[80];

String strURL =""; //Stringa per la costruzione dell'URL PHP

//float temperature umidità
float temp1 = 0;
float hum1 = 0;

float temp2 = 0;
float hum2 = 0;

float temp3 = 0;
float hum3 = 0;
//------------------------------------------------------------------------------
void setup()
{

Serial.begin(BAUD);
Serial.println("Avvio Arduino.");
lcd.begin(20, 4);
lcd.print("Avvio Arduino...");

Serial.println("Imposto parametri di rete.");
lcd.setCursor(0, 1);
lcd.print("Avvio Rete... ");
// start Ethernet and UDP
Ethernet.begin(mac, ip, gateway, gateway, mask );
// no point in carrying on, so do nothing forevermore:
lcd.setCursor(0, 0);
lcd.print("IP: ");
lcd.print(Ethernet.localIP());
lcd.setCursor(0, 1);
lcd.print("GW: ");
lcd.print(Ethernet.gatewayIP());
lcd.setCursor(0, 2);
lcd.print("DNS: ");
lcd.print(Ethernet.dnsServerIP());
lcd.setCursor(0 ,3);
lcd.print("MSK: ");
lcd.print(Ethernet.subnetMask());
delay(5000);



Udp.begin(LOCAL_UDP_PORT);
Dns.begin(Ethernet.dnsServerIP() );

Serial.println("Starting to sync the time via NTP.");
lcd.clear();
lcd.print("Avvio sync NTP...");

setSyncProvider(getNtpTime);
while(timeStatus() == timeNotSet); // wait until the time is set by the sync provider
setSyncInterval(TIME_SYNC_INTERVAL);

cur_time = now();
makeISOdate();
Serial.print("OK. It's now ");
Serial.println(isodate);
lcd.setCursor(0, 1);
lcd.print(isodate);

pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(RELAY1, OUTPUT);

//Begin Sensore Luce
Wire.begin();
TSL2561.init();

//Begin DHT22
dht1.begin();
dht2.begin();
dht3.begin();


}

void loop()
{
uint32_t m;

LampadaOnOff();

AspirazioneOnOff();

DeumidificatoreOnOff();

UpdateTemp();




digitalWrite(RELAY1, HIGH); //prova RELAY

unsigned long Lux;
TSL2561.getLux();
Serial.print("The Light value is: ");
Serial.println(TSL2561.calculateLux(0,0,1));

while(client.available())
{
char c = client.read();
Serial.print(c);
}

if (!client.connected())
{
Serial.println();
Serial.println("Disconnesso.");
client.stop();
}
cur_time = now();
if( cur_time != prevDisplay) //update the display only if the time has changed
{
prevDisplay = cur_time;
digitalClockDisplay();
makeISOdate();
//Serial.println(isodate);
}

// wait for time to be a multiple of interval
do {
m = millis();
} while (m % LOG_INTERVAL);

delay(5000);
}

void LampadaOnOff() {
if ((hour() >= LUCE_START) && (hour() < LUCE_STOP)) //Controllo se accendere o spegnere la luce
{
digitalWrite(LED1, HIGH);
Serial.println(hour()); //debug
Serial.println("Luce accesa"); //debug
}
else
{
digitalWrite(LED1, LOW);
Serial.println(hour()); //debug
Serial.println("Luce spenta"); //debug
}
}

void AspirazioneOnOff() {
if (temp1 > TEMP_MAX) //Controllo se accendere o spegnere l'aspirazione
{
digitalWrite(LED2, HIGH);
Serial.print("Debug :");
Serial.print(temp1);
}
else
{
digitalWrite(LED2, LOW);
}
}

void DeumidificatoreOnOff() {
if (hum1 > HUM_MAX)
{
digitalWrite(LED2, HIGH);
}
else
{
digitalWrite(LED2, LOW);
}
}

void UpdateTemp() {

char _temp1[10];
char _hum1[10];

char _temp2[10];
char _hum2[10];

char _temp3[10];
char _hum3[10];

lcd.clear();

Serial.println("Connessione...");

if (client.connect(server, 80)) {
Serial.println("Connesso");
temp1 = dht1.readTemperature();
hum1 = dht1.readHumidity();
dtostrf(temp1, 2, 2, _temp1);
dtostrf(hum1, 2, 2, _hum1);

temp2 = dht2.readTemperature();
hum2 = dht2.readHumidity();
dtostrf(temp2, 2, 2, _temp2);
dtostrf(hum2, 2, 2, _hum2);

temp3 = dht3.readTemperature();
hum3 = dht3.readHumidity();
dtostrf(temp3, 2, 2, _temp3);
dtostrf(hum3, 2, 2, _hum3);

lcd.print("T1:");
lcd.print(_temp1);
lcd.print(" H1:");
lcd.print(_hum1);

lcd.setCursor(0, 1);
lcd.print("T2:");
lcd.print(_temp2);
lcd.print(" H2:");
lcd.print(_hum2);

lcd.setCursor(0, 2);
lcd.print("T3:");
lcd.print(_temp3);
lcd.print(" H3:");
lcd.print(_hum3);

lcd.setCursor(0, 3);
digitalClockDisplayLCD();


//creo l'url utilizzanzo una stringa
strURL = "GET /arduino/index.php?temp1=";
strURL += _temp1;
strURL += "&hum1=";
strURL += _hum1;
strURL += "&temp2=";
strURL += _temp2;
strURL += "&hum2=";
strURL += _hum2;
strURL += "&temp3=";
strURL += _temp3;
strURL += "&hum3=";
strURL += _hum3;
strURL += " HTTP/1.1";

//invio la richiesta al server
client.println(strURL);
client.println("Host: localhost");
client.println("Connection: close");
client.println();
//chiudo la connessione
client.stop();
}
else
{
Serial.println("Errore Connessione");
}
}

void digitalClockDisplay(){
// Ask only once for date and time:
time_t t = cur_time;
// digital clock display of the time
Serial.print(hour(t));
printDigits(minute(t));
printDigits(second(t));
Serial.print(" ");
Serial.print(day(t));
Serial.print(" ");
Serial.print(month(t));
Serial.print(" ");
Serial.print(year(t));
Serial.println();
}

void digitalClockDisplayLCD(){
// Ask only once for date and time:
time_t t = cur_time;
// digital clock display of the time
lcd.print(hour(t));
lcd.print(":");
lcd.print(minute(t));
lcd.print(";");
lcd.print(second(t));
lcd.print(" ");
lcd.print(day(t));
lcd.print(" ");
lcd.print(month(t));
lcd.print(" ");
lcd.print(year(t));
}

void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}

void makeISOdate(){
// Uses the global time variable cur_time (user's responsibility to call before this func).
time_t t = cur_time;
sprintf(isodate, "%4d-%02d-%02dT%02d:%02d:%02d%+05d",
year(t), month(t), day(t), hour(t), minute(t), second(t), TZ_OFFSET/36 );
}

/*-------- NTP code ----------*/

unsigned long getNtpTime()
{
if(Dns.getHostByName(host, rem_add) == 1 ){
Serial.println("DNS resolve...");
Serial.print(host);
Serial.print(" = ");
Serial.println(rem_add);
sendNTPpacket(rem_add);
} else {
Serial.print("DNS fail...");
Serial.print("time.nist.gov = ");
Serial.println(timeServer); // fallback
sendNTPpacket(timeServer); // send an NTP packet to a time server
}

// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer

//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:

unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;

// now convert NTP time into Unix time
// starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;
return epoch - TZ_OFFSET;
}
return 0; // return 0 if u````` qqnable to get the time
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;

// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
 

Edward85

Member
ciao Bluedeep e ciao a tutti

vedo solo adesso questo thread troppo interessante

complimenti Bluedeep per il progetto che hai intrapreso

---

circa 2 mesi fa ho iniziato a sentire l'estrema necessità di capire il livello di umidità del terreno e navigando in rete, oltre ai vari strumenti made in china con l'astina analogica, ho scoperto Arduino e il "moisture soil sensor". contentissimo di aver trovato questa apparecchiatura, ho iniziato ad informarmi. più mi informavo e più capivo che le mie conoscenze a livello informatico erano insufficienti per non parlare di quelle elettroniche
i progetti di "serra completamente automatizzata" mi sono rimasti in testa, ma le informazioni che trovavo in internet (praticamente solo in inglese. infatti questa cosa un po mi frena) ed il poco tempo per seguire il progetto mi hanno fatto abbandonare l'idea. confesso che il sogno di realizzare qualcosa di fatto bene rimane

per monitorare il valore dell'umidità del terreno mi sono arrangiato costruendo per conto mio un "moisture soil sensor" senza Arduino
praticamente ho usato un mult1metro e due barre di ferro a mò di "sonde" impiantate nel terreno
misuro la resistenza appoggiando i punt4li uno su una sonda e l'altro sull'altra. più resistenza c'è meno acqua c'è e quindi più il terreno è asciutto

---

Edhorin in parte mi ha anticipato, comunque mentre leggevo pensavo:
per quanto riguarda il problema dell'elettrolisi sul sensore con Arduino non è possibile interrompere il passaggio di corrente?
ho capito che vuoi tenere traccia del monitoraggio dei vari parametri ma il livello di umidità del terreno non ha cambiamenti sostanziali ogni secondo
cioè dare l'impulso per la lettura ad intervalli tipo di 8 ore
tanto per l'irrigazione automatica l'ideale sarebbe farglielo leggere anche solo una volta al giorno, poco prima che si accendano le luci e in base al valore Arduino decide se far partire la pompa o no
se si riuscisse ad azionare il sensore ogni tanto si eviterebbe anche di porsi troppo il problema se la corrente che passa tra le sonde fa male alle radici (male non so ma sicuramente qualcosa fa. consiglio la visione del video di quark che trovate su questo thread https://www.icmag.com/ic/showthread.php?t=285590 )

---

poi, una cosa non mi è chiara
non capisco bene a cosa possa servire in indoor il sensore di lumens e come possa essere integrato in un processo automatizzato
o serve solo capire quando sostituire il bulbo?

---

per quanto riguarda le soglie secondo me vanno divise in 3 (minimo)
preciso anche che non è ottimizzata per aut0fior3nti

germinazione:

#define LUCE_START 5 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 23 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 18.00 //Temperatura Minima

#define HUM_MAX 85.00 //Umidità Massima
#define HUM_MIN 75.00 //Umidità Minima

vegetativa:

#define LUCE_START 5 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 23 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 18.00 //Temperatura Minima

#define HUM_MAX 65.00 //Umidità Massima
#define HUM_MIN 55.00 //Umidità Minima

fioritura:

#define LUCE_START 8 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 20 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 17.00 //Temperatura Minima

#define HUM_MAX 45.00 //Umidità Massima
#define HUM_MIN 35.00 //Umidità Minima

---

l'automazione sarebbe bello farla in idroponica con sensori ph ed ec (quello ec non so se esista per Arduino) che interagiscono con dei dosatori a goccia che regolano costantemente i valori ottimali del serbatoio per l'irrigazione
ma qui mi sa che sfioriamo quasi la fantascienza :) (in più ci sarebbe il grosso problema della calibrazione dei sensori)

---

troppe riflessioni in un solo post
spero non vadano perse
 
Last edited:
circa 2 mesi fa ho iniziato a sentire l'estrema necessità di capire il livello di umidità del terreno e navigando in rete, oltre ai vari strumenti made in china con l'astina analogica, ho scoperto Arduino e il "moisture soil sensor". contentissimo di aver trovato questa apparecchiatura, ho iniziato ad informarmi. più mi informavo e più capivo che le mie conoscenze a livello informatico erano insufficienti per non parlare di quelle elettroniche
i progetti di "serra completamente automatizzata" mi sono rimasti in testa, ma le informazioni che trovavo in internet (praticamente solo in inglese. infatti questa cosa un po mi frena) ed il poco tempo per seguire il progetto mi hanno fatto abbandonare l'idea. confesso che il sogno di realizzare qualcosa di fatto bene rimane

per monitorare il valore dell'umidità del terreno mi sono arrangiato costruendo per conto mio un "moisture soil sensor" senza Arduino
praticamente ho usato un mult1metro e due barre di ferro a mò di "sonde" impiantate nel terreno
misuro la resistenza appoggiando i punt4li uno su una sonda e l'altro sull'altra. più resistenza c'è meno acqua c'è e quindi più il terreno è asciutto

---

Edhorin in parte mi ha anticipato, comunque mentre leggevo pensavo:
per quanto riguarda il problema dell'elettrolisi sul sensore con Arduino non è possibile interrompere il passaggio di corrente?
ho capito che vuoi tenere traccia del monitoraggio dei vari parametri ma il livello di umidità del terreno non ha cambiamenti sostanziali ogni secondo
cioè dare l'impulso per la lettura ad intervalli tipo di 8 ore
tanto per l'irrigazione automatica l'ideale sarebbe farglielo leggere anche solo una volta al giorno, poco prima che si accendano le luci e in base al valore Arduino decide se far partire la pompa o no
se si riuscisse ad azionare il sensore ogni tanto si eviterebbe anche di porsi troppo il problema se la corrente che passa tra le sonde fa male alle radici (male non so ma sicuramente qualcosa fa. consiglio la visione del video di quark che trovate su questo thread https://www.icmag.com/ic/showthread.php?t=285590 )

Beh quello che hai fatto semplicemente è quello che fa il sensore per arduino :)

Il problema della corrosione in realtà è sempre presente, ovviamente amplificato dal fatto che passa corrente (quando passa), ma ad ogni modo una differenza di potenziale si genera anche senza corrente in quanto il sensore/barre sono sempre immerse in un terreno pieno di sali o elementi carichi.

Posso quasi garantire che non c'è nessun trattamento sugli elettrodi... Se è isolato il sensore ovviamente non funziona!

poi, una cosa non mi è chiara
non capisco bene a cosa possa servire in indoor il sensore di lumens e come possa essere integrato in un processo automatizzato
o serve solo capire quando sostituire il bulbo?

L'idea era di sapere:
1. Quanta luce genera la lampada. Purtroppo credo che 40000 lux non siano sufficienti, ovvero il sensore non è così sensibile ai lux generati dalla lampada
2. Quando la lampada è accesa/spenta. I rele' sono soggetti ad usura e rottura quindi è una ulteriore informazioni che posso avere.
Poi se plottiamo i risultati del sensore con quello della temperatura, umidità posso subito a occhi a capire le variazione di questi parametri!

per quanto riguarda le soglie secondo me vanno divise in 3 (minimo)
preciso anche che non è ottimizzata per aut0fior3nti

germinazione:

#define LUCE_START 5 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 23 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 18.00 //Temperatura Minima

#define HUM_MAX 85.00 //Umidità Massima
#define HUM_MIN 75.00 //Umidità Minima

vegetativa:

#define LUCE_START 5 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 23 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 18.00 //Temperatura Minima

#define HUM_MAX 65.00 //Umidità Massima
#define HUM_MIN 55.00 //Umidità Minima

fioritura:

#define LUCE_START 8 //Imposta l'inizio dell'accensione della lampada
#define LUCE_STOP 20 //Imposta lo spegnimento della lampada

#define TEMP_MAX 25.00 //Temperatura Massima
#define TEMP_MIN 17.00 //Temperatura Minima

#define HUM_MAX 45.00 //Umidità Massima
#define HUM_MIN 35.00 //Umidità Minima

Grazie! implemento subito le soglie.
Prevedo anche un ciclo IF per definire quali costanti usare :)

l'automazione sarebbe bello farla in idroponica con sensori ph ed ec (quello ec non so se esista per Arduino) che interagiscono con dei dosatori a goccia che regolano costantemente i valori ottimali del serbatoio per l'irrigazione
ma qui mi sa che sfioriamo quasi la fantascienza
smile.gif
(in più ci sarebbe il grosso problema della calibrazione dei sensori)

In realtà non vedo nulla di complicato :)
Googlando si trova qualcosa come sensore EC.

L'idea è:

Sensori pH ed EC
n x Rele'
n x Pompe
n x serbatoi con acqua + nutrienti

Leggo dai sensori il pH ed EC della soluzione e avvio/spengo le relativa pompe attraverso i rele'

troppe riflessioni in un solo post
spero non vadano perse

No, anzi! Benvengano!!!
 
Sono diciamo a buon punto :)

Il data logger funziona molto bene i grafici li sto facendo con pchart e la base dati sql, sono un po' fermo perché dovrei passare alla costruzione della grow-box in modo da procedere pure con l'arduino xD.

Allora ho già creato la ciabatta con i relé che saranno pilotati dall'arduino (luci, aspirazione, estrazione, umidificatore ecc...)...

Qualche domanda? :)
 

mambo

Member
Veteran
Il progetto è molto interessante Bluedeep ma dove sei finito??

Per renderlo veramente opensource però secondo me dovresti tenere a mente alcuni dettagli:

  1. alcune persone (io per esempio :biggrin:) non capiscono una mazza di programmazione
  2. più aumenti la complessità del progetto più aumentano le probabilità di malfunzionamenti (più pezzi che si possono rompere)
  3. non tutti gli strain sono uguali e quindi hanno necessità diverse, quindi come per la cucina il controllo umano è insostituibile (alcuni pomodori hanno più sugo di altri ed a parità di dosi e di cottura si bruciano o no; per fare un uovo a la coque sono necessari 3 min di cottura ma le uova sono piccole, medie o grandi quindi valgono 3 min per tutte?)
  4. visto che internet non è una certezza (spesso può mancare il collegamento per i motivi più disparati) preferirei il clock almeno per le luci che sono la cosa fondamentale (se per 2 gg la T° o l'UR sballano un pò è meno dannoso)
  5. visto che ancora non è una cosa legale eviterei il controllo via internet o via cellulare...perchè le fdo possono controllare anche loro a che punto del coltivo sei
Questi sono i primi che mi vengono in mente, ma sono molto interessato ad un progetto che riesca a controllare luce, T° ed UR ad un costo molto basso come tu descrivi...per il resto preferisco innaffiare a mano quando lo ritengo necessario evitando...l'eventuale allagamento di casa :biggrin:...ricordi il film Brazil?


Spero comunque che continui il 3d :tiphat:
 

..db..

New member
vorrei portare allatenzione questo sketch ottimo direi questo il link del sito => http://decoy81.blogspot.com.ar

// DeCoY Grow Lite - Ignacio Adrián López
// Código para debug, pero incluye todas las cosas que puedas necesitar para realizar el tuyo. Si te resulta útil pasá por el blog a decir gracias.
// This code is for debug use, you can use it to generate your own. If you find it usefull leave a comment in the blog.
// http://decoy81.blogspot.com.ar


// include the library code:
#include <Wire.h>
#include <math.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>
#include "DHT.h"
#include "RTClib.h"
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

//Temp&Hum Sensor pin and type
#define DHTPIN 27
#define DHTTYPE DHT22

//Pins relays
int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;

//Soil Moisture Pins (I ended up using only 2) - Sensores de humedad de tierra (solo usé 2)
int analogPin1 = A0; // Sensor 1 Humedad soil
float SoilH1 = 0; // variable to store the value coming from the sensor
int analogPin2 = A1; // Sensor 2 Humedad soil
float SoilH2 = 0; // variable to store the value coming from the sensor
int analogPin3 = A2; // Sensor 3 Humedad soil
float SoilH3 = 0; // variable to store the value coming from the sensor
int analogPin4 = A3; // Sensor 4 Humedad soil
float SoilH4 = 0; // variable to store the value coming from the sensor
float SoilH = 0; // This one is for calc - Para sacar promedios

//TEMPS & HR POTS
int temppot = A10; //
int humpot = A9; //
int tempval = 0; // variable to store the value coming from the sensor
int humval = 0; // variable to store the value coming from the sensor

//CO2
int CO2 = 9999;
int analogPin = A8; // voltage input from sensor
//CO2 Setting Sensor Calibration Constants
float v400ppm = 2.82; //MUST BE SET ACCORDING TO CALIBRATION
float v40000ppm = 1.55; //MUST BE SET ACCORDING TO CALIBRATION````````````````````````
float deltavs = v400ppm - v40000ppm;
float A = deltavs/(log10(400) - log10(40000));
float B = log10(400);

// MAC&IP
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC ADDRESS
IPAddress ip(192,168,0,22);
EthernetClient client;

//RTC Object - Crea Objeto RTC
RTC_DS1307 RTC;

//Temp & HR Sensor Define - Define tipo de Sensor DHT
DHT dht(DHTPIN, DHTTYPE);

// Set the LCD I2C address - Asigna direccion serial al LCD
LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Xively
// Sending data to the cloud - Manda los datos a internet para su guardado y observacion.
// https://xively.com/develop/xu3ukJOdlcfc3BMhHGBH so u can see, how it is...
char xivelyKey[] = "cbNAefNR20wzEB4qoahwJ8OUYsRl1dtZQbRND0izVfP8Oigq";
char sensorId1[] = "Temp";
char sensorId2[] = "HR";
char sensorId3[] = "CO2";
char sensorId4[] = "SOILH1";
char sensorId5[] = "SOILH2";
char sensorId6[] = "SOILH3";
char sensorId7[] = "SOILH4";
char sensorId8[] = "SOILHPROM";
#define xivelyFeed 869734635
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorId1, strlen(sensorId1), DATASTREAM_FLOAT),
XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
XivelyDatastream(sensorId3, strlen(sensorId3), DATASTREAM_FLOAT),
XivelyDatastream(sensorId4, strlen(sensorId4), DATASTREAM_FLOAT),
XivelyDatastream(sensorId5, strlen(sensorId5), DATASTREAM_FLOAT),
XivelyDatastream(sensorId6, strlen(sensorId6), DATASTREAM_FLOAT),
XivelyDatastream(sensorId7, strlen(sensorId7), DATASTREAM_FLOAT),
XivelyDatastream(sensorId8, strlen(sensorId8), DATASTREAM_FLOAT),
};
XivelyFeed feed(xivelyFeed, datastreams, 8);
XivelyClient xivelyclient(client);

// Misc Var - Variables usos varios
int ret = 0; //Shows Xively return code - Muestra el codigo de retorno de Xively
int ret2 = 0;
int counter = 0; //for a 60 Cicle Counter
int counter2 = 0; // a counters counter for debug
int state = 0; // for relay display on LCD


//////////////////
void setup() {

lcd.begin(20, 4); // LCD's number of columns and rows
dht.begin(); // start DHT sensor
Serial.begin(9600); //
Wire.begin(); //
RTC.begin(); //

//relays
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);

//Co2 pin
pinMode(analogPin, INPUT);

// Setting up Ethernet static IP address
Ethernet.begin(mac, ip);

int counter = 30;
int counter2 = 1;
digitalWrite(relay1, HIGH); // HIGH means OFF
digitalWrite(relay2, HIGH);
digitalWrite(relay3, HIGH);
digitalWrite(relay4, HIGH);

}
///////////////////
void loop() {

// Soil Moisture Sensors - I calibrated the sensor and created this formula by myself so dont expect lab accuracy.
if (analogRead(analogPin1) > 224) {
SoilH1 = 100-(((analogRead(analogPin1))-224)*0.125);
} else {
SoilH1 = 100;
}
if (analogRead(analogPin2) > 224) {
SoilH2 = 100-(((analogRead(analogPin2))-224)*0.125);
} else {
SoilH2 = 100;
}
// Decided to use only 2 soil moisture sensors
// if (analogRead(analogPin3) > 224) {
// SoilH3 = 100-(((analogRead(analogPin3))-224)*0.125);
// } else {
// SoilH3 = 100;
// }
// if (analogRead(analogPin4) > 224) {
// SoilH4 = 100-(((analogRead(analogPin4))-224)*0.125);
// } else {
// SoilH4 = 100;
// }

// Copy results from previous sensor to sensors 3&4;
SoilH3 = (SoilH1);
SoilH4 = (SoilH2);

//Soil H Average
SoilH = ((SoilH1+SoilH2+SoilH3+SoilH4)/4);

//Sensor Co2, every 30 cicles.
if (counter = 30) {
// Read co2 data from sensor
int data = analogRead(analogPin); //digitise output from c02 sensor
float voltage = data/204.6; //convert output to voltage
// Calculate co2 from log10 formula (see sensor datasheet)
float power = ((voltage - v400ppm)/A) + B;
float co2ppm = pow(10,power);
CO2 = co2ppm;
}

// TEMP & HUM POTS
tempval = analogRead(temppot)/25; // read the value from the pot
humval = analogRead(humpot)/11; // read the value from the pot

// DHT Sensor Reading - temp & hum
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT");}

//TIME - hora
DateTime now = RTC.now(); // Obtains RTC time - Obtiene la fecha y hora del RTC
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C");
Serial.print("Humedad Soil Promedio %: ");
Serial.println(SoilH);
counter = counter + 1 ;
Serial.print("Sensores Soil HR%: ");
Serial.print(SoilH1);
Serial.print(" ");
Serial.println(SoilH2);
Serial.println(counter);


//Relay operation
//You have to make sth for your own here, for example if temperature goes above your selected temp: relay1 goes LOW (that is ON)...
//Right now the code only lights up the relay strip.
//Acá manejas los relays como quieras, dependiendo de las condiciones y lo que desees. si la temperatura es mayor que la que seleccionaste con el potenciometro se prende el relay1
//seteandolo en LOW. (LOW prende).
if (t > tempval) {
digitalWrite(relay1, LOW);}
if (t < tempval) {
digitalWrite(relay1, HIGH);}
if (h > humval) {
digitalWrite(relay2, LOW);}
if (h < humval) {
digitalWrite(relay2, HIGH);}
//For example, if Soil Humidity goes down to 60% it will turn on a water pump (relay3) for 8 seconds and then turn it off.
// Por ejemplo, si la huymnedad promedio de la tierra baja a menos de 60, prende una bomba de agua (relay3) por 8 segundos y lo apaga.
// if (SoilH < 60) {
// digitalWrite(relay3, LOW);
// delay(8000);
// digitalWrite(relay3, HIGH);}


// Xively Cloud Hosting, every 60 cicles
// Manda a la nube los datos cada 60 vueltas
if (counter > 60) {
datastreams[0].setFloat(t);
datastreams[1].setFloat(h);
datastreams[2].setFloat(CO2);
datastreams[3].setFloat(SoilH1);
datastreams[4].setFloat(SoilH2);
datastreams[5].setFloat(SoilH3);
datastreams[6].setFloat(SoilH4);
datastreams[7].setFloat(SoilH);

//send value to xively
Serial.println("Uploading it to Xively");
int ret = xivelyclient.put(feed, xivelyKey);
ret2 = (ret);
//return message
Serial.print("xivelyclient.put returned ");
Serial.println(ret);
Serial.println("");
ret2 = (ret);
counter = 0;
counter2 = counter2+1;

}


// Print to the LCD.
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TEST ");
state = digitalRead(relay1);
lcd.print(state);
state = digitalRead(relay2);
lcd.print(state);
state = digitalRead(relay3);
lcd.print(state);
state = digitalRead(relay4);
lcd.print(state);
lcd.print(" ");
lcd.print(counter);
lcd.print(" ");
lcd.print(counter2);
lcd.print(" ");
lcd.print(ret2);
lcd.setCursor(0, 1);
lcd.print("HR: ");
Serial.print("h");
//lcd.setCursor(4, 2);
lcd.print(h);
//lcd.setCursor(7, 1);
lcd.print("% ");
lcd.print(humval);
lcd.setCursor(0, 2);
lcd.print("Temp: ");
// lcd.setCursor(7, 2);
// lcd.setCursor(13, 3);
lcd.print(t);
lcd.print("C ");
lcd.print(tempval);
lcd.setCursor(0, 3);
lcd.print(round(SoilH1));
lcd.print(" ");
lcd.print(round(SoilH2));
lcd.print(" CO2: ");
lcd.print(CO2);
lcd.print(" ppm");
ret2 = 0;

}
:woohoo:
 
G

GrowInTheShadow

non molto tempo fa feci costruire ad un ragazzo conosciuto su un forum, un igrostato/termometro basato su arduino.
Funziona molto bene, anche se il display perde qualche colpo per via dell'umidità a cui è sottoposto.
Mio consiglio...sonda esterna con cavo!(il mio è un blocco unico)
 
Top