Controllo terrario

Ciao a tutti,
mi chiamo Eugenio e sono nuovo di questo forum e sopratutto nuovo per quanto riguarda Arduino.

Mi piacerebbe costruire un dispositivo per controllare la temperatura e l'umidità di due terrari per l'allevamento di rettili e v orrei avesse queste caratteristiche:

  1. Controllo temperatura
  2. termostato proporzionale o ad impulsi
  3. Igrometro
  4. Igrostato tramite soglie (raggiunto la soglia del 50%, far partire un dispositivo a 220V per un tot secondi e così via)
  5. Gestione accensione/spegnimento luci a led con dimmerizzazione per effetto alba tramonto
  6. Display a led per la lettura dei valori di temp/umidità e magari per settare i valori giorno/notte

Pensavo di settare le soglie e le curve di intervento tramite pc (quanto impiegare per passare dalla temp. giorno alla notte)

Bene... come faccio? :slight_smile:
Per ora sono solo riuscito a far andare il sensore SHT15 per temp ed umidità, e mi son già incastrato con l'RTC.
e poi...che componenti mi servono?

Grazie a tutti per l'aiuto che vorrete darmi!

per usare dispositivi 220V dei relè a 220V e molta attenzione a quello che fai.

qualche transistor o mosfet per i led, un alimentatore a parte per arduino per reggere senza USB e per avere abbastanza potenza per alimentare i led (vedi te quanti ampere pensi di consumare)

per il collegamento PC l'arduino ha già tutto il necessario, no? manca solo una interfaccina grafica perevitare di dare i comandi direttamente da serial monitor, ma a quello ci puoi penare quando avrai finito il resto :slight_smile:

Grazie lesto,
il vero problema sarà la programmazione e capire come fare il termostato proporzionale e non on/off.

Idee?

dividi tutto in tanti piccoli sketch poi qualcuno qui te li sistemera' in uno unico, io credo d'essere al tuo livello e per fare un progetto simile procederei cosi'

che tipo di terrario e'? perche' di solito ci devono essere lampade infrarosse, ma tu parli di umidita' quindi son rettili che non necessitano di scaldarsi, quindi perche' non mettere un generatore di nebbia ad ultrasuoni per umidificare

Prima di tutto grazie per l'aiuto!

Questo è quello che ho fatto, visto che ho il sensore umidità/temperatura ed il clock

#include <Wire.h>
int gTempCmd  = 0b00000011;
int gHumidCmd = 0b00000101;
int theDataPin  = 9;
int theClockPin = 8;
int temperatureVal;
int currentTemperatureInC;
int humidityVal;
int currentHumidityInPercent;
int ack;
 
int shiftIn(int dataPin, int clockPin, int numBits)
{
   int ret = 0;
   int i;

   for (i=0; i<numBits; ++i)
   {
      digitalWrite(clockPin, HIGH);
      delay(10);  // I don't know why I need this, but without it I don't get my 8 lsb of temp
      ret = ret*2 + digitalRead(dataPin);
      digitalWrite(clockPin, LOW);
   }

   return(ret);
}

void sendCommandSHT(int command, int dataPin, int clockPin)
{
  // Transmission Start
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, LOW);
          
  // The command (3 msb are address and must be 000, and last 5 bits are command)
  shiftOut(dataPin, clockPin, MSBFIRST, command);

  // Verify we get the correct ack
  digitalWrite(clockPin, HIGH);
  pinMode(dataPin, INPUT);
  ack = digitalRead(dataPin);
  if (ack != LOW)
    Serial.println("Ack Error 0");
  digitalWrite(clockPin, LOW);
  ack = digitalRead(dataPin);
  if (ack != HIGH)
     Serial.println("Ack Error 1");
}

void waitForResultSHT(int dataPin)
{
  int i;
 
  pinMode(dataPin, INPUT);
 
  for(i= 0; i < 100; ++i)
  {
    delay(10);
    ack = digitalRead(dataPin);

    if (ack == LOW)
      break;
  }
 
  if (ack == HIGH)
    Serial.println("Ack Error 2");
}

int getData16SHT(int dataPin, int clockPin)
{
  int val;
 
  // Get the most significant bits
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  val = shiftIn(dataPin, clockPin, 8);
  val *= 256;

  // Send the required ack
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
          
  // Get the least significant bits
  pinMode(dataPin, INPUT);
  val |= shiftIn(dataPin, clockPin, 8);

  return val;
}

void skipCrcSHT(int dataPin, int clockPin)
{
  // Skip acknowledge to end trans (no CRC)
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
}

void setup()
{
   Serial.begin(9600); // open serial

  //inizializzo la seriale
  Serial.begin(9600);
 
  //inizializzo la libreria
  Wire.begin();
 
  //attivo la comunicazione con il DS1307
  //l'indirizzo dell'RTC è 0x68
  Wire.beginTransmission(0x68);
  //il primo byte stabilisce il registro
  //iniziale da scivere
  Wire.write((byte)0x00);
  //specifico il tempo e la data
  Wire.write((byte)0x00); //1° byte SECONDI da 0x00 a 0x59
  Wire.write((byte)0x55); //2° byte MINUTI da 0x00 a 0x59
  Wire.write((byte)0x80 | 0x20); //3° byte ORE da 0x00 a 0x24
  Wire.write((byte)0x01); //4° byte GIORNO della settimana da 0x01 a 0x07
  Wire.write((byte)0x11); //5° byte GIORNO del mese da 0x00 a 0x31
  Wire.write((byte)0x06); //6° byte MESE da 0x00 a 0x12
  Wire.write((byte)0x12); //7° byte ANNO 0x00 a 0x99
  Wire.endTransmission();
}

void loop()
{
  sendCommandSHT(gTempCmd, theDataPin, theClockPin);
  waitForResultSHT(theDataPin);
  temperatureVal = getData16SHT(theDataPin, theClockPin);
  skipCrcSHT(theDataPin, theClockPin);
  Serial.print("Temperature in C:");
  currentTemperatureInC = -40.1 + 0.01 * (float)temperatureVal;
  Serial.println(currentTemperatureInC, DEC); 
  delay(5000);
 
  sendCommandSHT(gHumidCmd, theDataPin, theClockPin);
  waitForResultSHT(theDataPin);
  humidityVal = getData16SHT(theDataPin, theClockPin);
  skipCrcSHT(theDataPin, theClockPin);
  Serial.print("Humidity in percent:");
  currentHumidityInPercent = -4.0 + 0.0405 * humidityVal + -0.0000028 * humidityVal * humidityVal;
  Serial.println(currentHumidityInPercent, DEC);
  Serial.println("");
  delay(5000);

  //inizzializza la trasmissione partendo
  //dall'indirizzo 0x00
  Wire.beginTransmission(0x68);
  Wire.write((byte)0x00);
  Wire.endTransmission();
 
  //richiedo 7 byte dal dispositivo con
  //indirizzo 0x68
  Wire.requestFrom(0x68, 7);
  //regupero i 7 byte relativi ai
  //corrispondenti registri
  byte secondi = Wire.read();
  byte minuti = Wire.read();
  byte ora = Wire.read();
  byte giorno_sett = Wire.read();
  byte giorno_mese = Wire.read();
  byte mese = Wire.read();
  byte anno = Wire.read();
 
  Serial.print("Orario corrente: ");
  Serial.print(ora, HEX);
  Serial.print(":");
  Serial.print(minuti, HEX);
  Serial.print(":");
  Serial.println(secondi, HEX);
 
  Serial.print("Giorno della settimana: ");
  Serial.println(giorno_sett, HEX);
 
  Serial.print("Data corrente: ");
  Serial.print(giorno_mese, HEX);
  Serial.print("/");
  Serial.print(mese, HEX);
  Serial.print("/");
  Serial.println(anno, HEX);
  Serial.println();
 
  delay(5000);
}

il fatto è che non capisco come far "partire" l'orologio indipendentemente dal monitor seriale aperto...nel senso che finchè il monitor seriale è aperto l'orario procede, se lo chiudo si resetta.
Come faccio ad impostare tutto per temp/umidità/ora e po interrogare e basta?

Sto impazzendo!

perchè ogni volta che apri e chiudi il serial monitor, viene resettato l'arduino, e quindi lanciata di nuovo la funzione setup. Questa funzione si chiama autoreset e la puoi disattivare con un condensatore, cerca sul forum.

e questo mi sembra anche giusto ma...Visto che ho una batteria tampone, non posso svincolare solo il clock dall'autoreset?
Imposto l'ora e me la scordo...

esatto, è pensato proprio per quello, in pratica tu fai uno sketch per settare l'ora, poi da lì in poi non dovresti più averne bisogno.