Pages: [1] 2   Go Down
Author Topic: YATC - Yet Another Terrarium Controller  (Read 6124 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I would like to start a small Terrarium Controll Project. I have two Terrariums so i need a Modular Controller to inependently Controll both.
I need to switch several lamps, two heatlamps and one pump.
The two heatlamps needs to be temperature controlled.

In future i wanted to report the Temperature over Serial or Wifi to an Linux Device to create a Temperature Graph and simulate Sun Rising/ Falling by LED Lights and PWM.

So lets start with the required Hardware i ordered so far smiley


Microcontroller:
SparkFun Mega Pro 5V 41€
Relays:
Two Sainsmart 4-Channel 5V Relay Boards 8€ x 2 = 16€
LCD:
4 Line Normal LCD with I2C Adapter 21€
Temperature Sensors
Several DS1820 around 20€
PowerSupply:
At the Moment a Apple IPhone Power Adapter....
Bits and pieces:
Several Buttons and Resistors...
MicroSD Card 7€
SD/MICRO-SD Card Breakout Module 5€
Two Seeedstudio Grove - Moisture Sensor 2x5€ = 10€
Seeedstudio Grove - Watersensor 3€
Adafruit Ultimate GPS 35€






I will update this Topic with Code, Hardware Plans and Pictures. I hope anybody will find the information helpfull and or can give me suggestion to build a reliable and working solution.

Kind Regards
Dafes


« Last Edit: February 06, 2013, 04:41:38 pm by dafes » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13486
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I have two Terrariums so i need a Modular Controller to inependently Controll both.

Why not two UNO's in stead of one MEGA?  Modular is modular smiley-wink

Quote
and simulate Sun Rising/ Falling
I discussed an algorithm here - http://arduino.cc/forum/index.php/topic,66426.0.html - might be useful

(you can also connect an LDR to the window and "read the local sunset/rise" smiley
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I have two Terrariums so i need a Modular Controller to inependently Controll both.

Why not two UNO's in stead of one MEGA?  Modular is modular smiley-wink

Quote
and simulate Sun Rising/ Falling
I discussed an algorithm here - http://arduino.cc/forum/index.php/topic,66426.0.html - might be useful

(you can also connect an LDR to the window and "read the local sunset/rise" smiley

Yes thats true but one othe requirement was cheap as possible smiley-razz

Thanks for the Feedback i will take a look into the sunrise algorithm smiley


The next Part is the Programming Part... I want to use an SD Card to save the Settings and also to specify the "Switch Times" for each channel.(I updated the first Post with the new Hardware)
Additional i want to implement the functionality to programm the Controller over a Serial Interface in Step 1 and in Step 2 i want to replace the Serial Interface with an Bluetooth mate to configure the Controller from an Device.

Kind Regards
dafes

Edit:
I think i will add two additional Sensors. One Soil Moisture Sensor to verify if enough water in the watertank and one for the plant in the rainforest Terrarium. Has anybody a better idea for checking the water level in a Plastic Tank to prevent the pump for running dry? It should be cheap as possible smiley-grin
The moisture sensor cost 5€.

Edit2: I ordered a Watersensor to apply into the Watertank.

« Last Edit: January 08, 2013, 07:53:27 am by dafes » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13486
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Yes thats true but one othe requirement was cheap as possible
cheap comes at a price ...

Why not one uno, just count the number of lines you need to control. Note that the analog ports can be used as digital so an UNO has 19 IO lines

You need
input:
- 1 line for all the DS18B20's
- 2 lines water sensor
- 2 lines moisture sensor
- 2 I2C RTC

output:
- 4 SD card
- 2 Serial
- 3 lines for the relays (use a shift register!)
-------
16 lines so one UNO could do the job
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Yes thats true but one othe requirement was cheap as possible
cheap comes at a price ...

Why not one uno, just count the number of lines you need to control. Note that the analog ports can be used as digital so an UNO has 19 IO lines

You need
input:
- 1 line for all the DS18B20's
- 2 lines water sensor
- 2 lines moisture sensor
- 2 I2C RTC

output:
- 4 SD card
- 2 Serial
- 3 lines for the relays (use a shift register!)
-------
16 lines so one UNO could do the job

Yes thats right, but  smiley i want a litle more space to expand.
I have an 433MHZ Sender and some 433MHZ switches so maybe i expand the Board to controll Lights over this or i want to add some Wirelesse Solution to connect it to my Network.
And just saw you forget the 5 Button pins smiley-wink Right, Left, Up, Down and my lovely select smiley So i have to use 21 Lines and i beleive uno
has only 17 ports because d0 and d1 are used for Serial Connection or do i miss something?

 
Regard
dafes
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have finished the button Pad to controll some basic settings... I´ve made it as small as possible so the bottom layer is a litle bit dirty soldered.


* top 1.jpg (479.16 KB, 600x800 - viewed 55 times.)

* buttom 1.jpg (574.08 KB, 800x600 - viewed 55 times.)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
today everything arrives and now i can start programming and soldering smiley

My Plan was to build up two additional Boards:
- One Power Board to power the arduino and additional boards
- One Sensor/LCD Board to connect everything with the Arduino

I will post Pictures when i´m finished. A big question at the moment is how to handle the 1Wire Sensor Adresses and assign them to the right Terrarium.
My idea was to create an Terrarium Object(struct) and have a List of Byte[8] Sensors but i´ve got some problems with it...

Has anybody another Idea?

At the first start the Controller should ask how many Terrariums do you have and maybe then quide the user through the configuration process. All Settings will be saved on a SD Card since i´m a litle bit worry about the read/write cycle limits in eeprom.
Feedback is desired...

Kind Regards
dafes
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13486
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A big question at the moment is how to handle the 1Wire Sensor Adresses and assign them to the right Terrarium.

your idea looks good but I see no code you have tried sofar ...
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A big question at the moment is how to handle the 1Wire Sensor Adresses and assign them to the right Terrarium.

your idea looks good but I see no code you have tried sofar ...

Yes it is still pre Alpha smiley-grin
But here is something:
I created the following Object
Code:
/*
Represents a Terrarium Object

*/


typedef struct
{
    String Name;
    byte* Sensor;

}Terrarium;

Created an Array of it
Code:
const int NumTerrariums = 2;

byte sensor1[8] = { 0x10, 0xB2, 0xA0, 0x54, 0x2, 0x8, 0x0, 0x4E };
byte sensor2[8] = { 0x10, 0x3F, 0x7D, 0x54, 0x2, 0x8, 0x0, 0x5C };

Terrarium Terrariums[NumTerrariums];

Add initialize it with the following Data:
Code:

void updateTerrariums {
  Terrariums[0].Name = "Terrarium1";
  Terrariums[0].Sensor =&sensor1[0];
  Terrariums[1].Name = "Terrarium2";
  Terrariums[1].Sensor = &sensor2[0];
}
I use the sensor first in the following DS1820 libfunction:
Code:
float GetTemperature(byte sensor[8])
{
  //CRC Check
  if (OneWire::crc8(sensor, 7) != sensor[7]) {
      Serial.println("CRC is not valid!");
      return 0;
  }
  // the first ROM byte indicates which chip
  switch (sensor[0]) {
    case 0x10:
      //Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      //Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return 0;
  }

  ds.reset();
  ds.select(sensor);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(sensor);    
  ds.write(0xBE);         // Read Scratchpad

  //Serial.print("  Data = ");
  //Serial.print(present,HEX);
  //Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    //Serial.print(data[i], HEX);
    //Serial.print(" ");
  }
  // convert the data to actual temperature
  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  return celsius;
}
But i think i missed something with the pointers... I come from the c# world so i dont know the point(er)...smiley

BTW: Look what i received from China smiley And so nicely wrapped


* 20130110_181409_resized.jpg (458.23 KB, 1632x1224 - viewed 50 times.)

* 20130110_181829_resized.jpg (443.06 KB, 1632x1224 - viewed 58 times.)

* 20130110_181918_resized.jpg (544.63 KB, 1632x1224 - viewed 73 times.)
« Last Edit: January 10, 2013, 01:06:11 pm by dafes » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,
i rebuilded some Boards to be a litle more modular.
I have created a new power board out of two pin connectors and changed the "normal" pin header to Connectors.
I will post some pictures tonight.
On Programming side there is not much progress. I have defined all Pins and at the moment i work on a small menu. I also try to find a good solution to switch the Lights timebased on and off.... I think i will create delay loop of 5 minutes in the main loop and call a function to verify if something to do on timer or temperature basis.

Code:
void loop
{
switch(Time)
{
case "12:00":
 Light.On(T1.S2);
break;
}
deleay(300000);
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
On Hardware Side:
i have rebuilded some Boards to replace Pin Headers with Connectors. I also ordered many Connectors to connect the additional Sensos to sthe Systems.
I ordered some 3,5mm Audio Jacks to connect the sensors and 25m Shielded 4 lines Wire.
On Software Side:
 I defined all IO Pins to match the Sensors and everything. At the moment i have only a small test setup to test all Boards and Sensors.
In the next weeks i will write a small menu and the "scheduler". I think i will use 5m delay loop like:
Code:
void loop()
{
time = GetTime();
switch(time)
{
 case(12):
  if(!Switch.Status(Terrarium1,Switch1)) {
   Switch.On(Terrarium1,Switch1); }
 break;
}
delay(30000);
}
Or is it better to use a Timer based Interrupt?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13486
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
String Name;

Strong advice to remove the String usage form your sketch and replace it with a char array as the String class has "destructor" problems ..

Quote
Or is it better to use a Timer based Interrupt?
Don't use delay either => check the Blink without delay example how to schedule functionality in your code

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
String Name;

Strong advice to remove the String usage form your sketch and replace it with a char array as the String class has "destructor" problems ..

Quote
Or is it better to use a Timer based Interrupt?
Don't use delay either => check the Blink without delay example how to schedule functionality in your code


Thank you for the feedback. I wil avoid using String and try the millis thing.
I have just finished the build up and everything is now connected.
Now i can concentrate my time to programming a running beta.


* 20130128_222041.jpg (1862.88 KB, 3264x2448 - viewed 99 times.)
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13486
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Keep us informed of your progress!
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Keep us informed of your progress!
Sure smiley

Here is the loop Code:
Code:
void loop() {
//Display
 if(SettingsScreen) { DisplaySettings(); }
 else { NormalView(); }
 
 //Timing
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval)
  {
    // save the last time you run the function
    previousMillis = currentMillis;
    CheckForSomethingtoDo();   
  }
}

and here is the "CheckForSomethingtoDo" function:

Code:
void CheckForSomethingtoDo()
{
  //DBEUG To Verify if Function runs
  if(DEBUG) {Serial.println("DEBUG: CheckForSomethingtoDo"); }
  _CheckForSomethingtoDoTerrarium1();
  _CheckForSomethingtoDoTerrarium2();
}

void _CheckForSomethingtoDoTerrarium1()
{
  //Temperature
  TemperatureControlT1();
}
void _CheckForSomethingtoDoTerrarium2()
{
  //Temperature
  TemperatureControlT2();
}

//Snakes
void TemperatureControlT1()
{
  DateTime now = RTC.now();
  //Sommer
  if(now.month() >= T1_SommerStart && now.month() <  T1_WinterStart)
  {
   if(DEBUG) { Serial.println("Debug: Sommer"); }
   if(GetTemperature(sensor1) >= T1_TTS)
   { 
     if(DEBUG) {Serial.print("Debug:T1 "); Serial.print(GetTemperature(sensor1)); Serial.println(" SwitchOff");}
     SwitchOff(1, 1);
   }
   else
   {
     SwitchOn(1,1);
   }   
  }
  //Winter
  else
  {
    if(DEBUG) { Serial.println("Debug: Winter"); }
   
    if(GetTemperature(sensor1) >= T1_TTW)
    {
     
      if(DEBUG) {Serial.print("Debug:T1 "); Serial.print(GetTemperature(sensor1)); Serial.println(" SwitchOff");}
      SwitchOff(1, 1);
    }
    else
    {
      SwitchOn(1,1);
    }
  } 
}


void TemperatureControlT2()
{

}
In the main class i have the following "Configuration Section":
Code:
//---------------------------------Configuration-------------------------------------------------
const boolean DEBUG = true;

//Terrarium 1
//Target Temperature Sommer
const int T1_TTS = 26;
//Target Temperature Winter
const int T1_TTW = 26;
//Sommer
const int T1_SommerStart = 5;
//Winter
const int T1_WinterStart = 10;
//Terrarium 2

//---------------------------------End-Configuration---------------------------------------------
In future i will configure this variables over a lcd and buttons and a config file on a sd card.
Logged

Pages: [1] 2   Go Up
Jump to: