Go Down

Topic: Can someone go over my code please? 16ch chicken incubator (Read 2376 times) previous topic - next topic

rvannly

Hi everyone,

I'm fairly new to programming, and have this project I'm doing for my father. He asked me to control a chicken Incubator, but 16 of them. I decided to use the dht22 sensors being it reads temp. and humidity. To keep the internal temperature at a constant 100 Deg F, I will be using a 100w 120/220v light bulb in each of the 16 incubators. All 16 relays are controlled by a SainSmart 16ch relay board. Along with the climate control I also have a 24v Linear actuator in each incubator to tilt the egg trays at a 45 deg each way. This actuator tilts the tray to 45 deg every 1hour. This is where I need help, so far I can log temp and humidity from two sensors (the rest or in the mail) and the light bulbs are turning on and off according to set temps. The millis function is still a little hard to grasp, I've just saw my first arduino code or any type of code, just 3 weeks ago. Anyhow, here's my code so far. OH, thanks in advance

PS. Saintsmart lcd display is also going to be integrated, but later.




Code: [Select]
/* 16 channel Incubator
created/ modified apr 20 2012
by Roth Ly
Also bits of code has been used from "frostin" of Arduino forum:
http://arduino.cc/forum/index.php?topic=70742.0

This code is for a 16 channel chicken incubator, where a total of
16 seperate incubator will be controlled via one Arduino Mega.
16 Dht22 senor inputs will run in to digital I/O 23,25,27...37.
A 16 channel relay board from sain smart takes care of switching
the heating element(100watt bulb) needed in each of the 16 incubators to keep an
internal temp of 100F. Along side the sensor data and relay switching
there is also a code for turning a separate DPDT relay on and off to activate
a linear actuator every hour.

Modified Blink without Delay
Turns on and off a DPDT relay connected to a digital pin (off for 1hr, on for 1hr)
without using the delay() function.  This means that other code
can run at the same time without being interrupted by the LED code.

The Blink without Delay circuit:
* Relay pin connected at pin A15 and Ground, with a TIP102 tran and 1n4004 diode.
* This relay acts as a H-bridge to on/off a linear actuator every hour.

Blink without Delay
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/
//***************************************************************************

// constants won't change. Used here to
// set pin numbers:
const int relayPin =  A15;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 19000;           // interval at which to blink (milliseconds)


#include <DHT.h>

#define DHTPIN1 23 // sets Dht22 sensor #1 at pin digital 23
#define DHTPIN2 25 // sets Dht22 sensor #2 at pin digital 25

#define DHTTYPE DHT22

DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);

#define bulbPIN1 22 // pin number for relay/heater #1
#define bulbPIN2 24 // pin number for relay/heater #2

#define TEMP_HIGH  29 //at what temp (C*) to turn off relay/heater
#define TEMP_LOW 28 //at what temp to turn on relay/heater

//#define HUMID_HIGH 60
//#define HUMID_LOW 20

float minTemp = 100;
float maxTemp = 0;

//float minHumid = 100;
//float maxHumid = 0;

int bulbValue = 0;


void setup() {
  // set the digital pin as output:
  pinMode(relayPin, OUTPUT); 
  Serial.begin(9600);
  Serial.println("Program Start");
dht1.begin();// starts sensor 1
dht2.begin(); // starts sensor 2

  pinMode(bulbPIN1, OUTPUT);  //sets bulbPin as OUTPUT
  pinMode(bulbPIN2, OUTPUT);
 
}

void loop()
{
 
  // READ DATA
float t1 = dht1.readTemperature();
float h1 = dht1.readHumidity();
//int temperatureF = (t1 * 9 / 5) +32.5; // converts to Farenhiet, not sure how to use properly yet

  // DO THE MIN/MAX
  minTemp = min(minTemp, t1);
  maxTemp = max(maxTemp , t1);

  // DISPLAT DATA
  if (isnan(t1) || isnan(h1)){ // sensor reading check
    Serial.println("sensor 1");
  } else {
  Serial.print("#1 Temp:");
  Serial.print(t1);
  Serial.println("*C");
  Serial.print("#1 Humid:");
  Serial.print(h1);
  Serial.println("%\t");
    // relay/heater
  if (t1 > TEMP_HIGH) bulbValue = 1;
  else if (t1 < TEMP_LOW) bulbValue = 0;
  digitalWrite(bulbPIN1, bulbValue);
  delay(2000);  // DHT's need a delay between readings ...
  }
  //****************************************************
{
  // READ DATA
// READ DATA
float t2 = dht2.readTemperature();
float h2 = dht2.readHumidity();
//int temperatureF = (t2 * 9 / 5) +32.5;

  // DO THE MIN/MAX
  minTemp = min(minTemp, t2);
  maxTemp = max(maxTemp , t2);

  // DISPLAT DATA
  if (isnan(t2) || isnan(h2)){
    Serial.println("sensor 2");
  } else {
   
  Serial.print("#2 Temp:");
  Serial.print(t2);
  Serial.println("*c");
  Serial.print("#2 Humid:");
  Serial.print(h2);
  Serial.println("%\t");
    // CROCKPOT
  if (t2 > TEMP_HIGH) bulbValue = 1;
  else if (t2 < TEMP_LOW) bulbValue = 0;
  digitalWrite(bulbPIN2, bulbValue);
  delay(2000);  // DHT's need a delay between readings ...
  }
//*****************************************************************
}
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
previousMillis = currentMillis; 

    // if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
   else
     ledState = LOW;

    // set the LED with the ledState of the variable:
  digitalWrite(relayPin, ledState);
   }
}



strykeroz

Hi

I've not gone through it in detail, since you say it does log the temperature and humidity correctly for you now.  Just a couple of comments.

Rather than replicating your variables 16x times for the full scale version, consider using an array for each of them.
http://arduino.cc/en/Reference/Array
Then you can use a loop to address each in turn, which will keep your sketch organised and easier to read.  And will allow you to expand further when the time comes by only changing a few lines.

And, in this line you have a delay which will block your code from doing anything else for 2sec.  Not that this is a long time, but if you're using the non-blocking method (with millis) for turning the relays off and on, you may consider that here too.
Code: [Select]
  delay(2000);  // DHT's need a delay between readings ...

Love the build - looks impressive  !
Geoff
"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

wildbill

You're not doing anything with minTemp and maxTemp. If you intend to, you'll probably need to keep separate readings for each incubator - another array. Do you plan to use the humidity data to control anything or is it just a display item?

Consider using an SD shield so you can log your data. If you have a bug in your code, it may help to detect what's happening. Also, some kind of alarm functionality would be nice. When the bulb fails, you likely don't have much time to replace it before a batch of eggs is lost.

PaulS

Code: [Select]
    // if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
   else
     ledState = LOW;

Can be written much more compactly:
Code: [Select]
  ledState = !ledState;

You probably do not want to be banging the relay on and off as the temperature gets above/below the set-point, when you get to that point. Let the temperature vary a little before toggling the relay. If the set point is 25C, for instance, turn the relay on when the temp gets down to 24.75 and off when the temp gets to 25.25, rather than on and off exactly at 25.00. The amount of variation is something you can control, but keep in mind the accuracy of the sensor you are using, and the speed at which the temperature is changed by the heat source.

kf2qd

Also - Is your heat sensor where the light shines on it? if so you may get higher than actual air temperature readings. Make sure your sensor is warmed by the air and not the lamp.

Nikarus

That is one of the most organized homebrew circuit boards I have ever seen. Props to you man.

Though using arrays definitely will make your life and following your code a bit easier. A for loop would probably help too.
Reads sensor, calculates temp. Switches relay if needed. Moves on to next pin. And then just does this repeatedly.

For getting the actuator to tilt the egg trays a little though. One thing, is it supposed to be like a sudden, over a minute it does the 45 degree shift, or does it gently go back and forth over the course of the hour? And what kind of signal does it take to operate the actuator?

As for the millis command.
Since you're already using the basic blink without delay to turn on and off the incubator lights I think. Its probably good to mention that you can have other intervals to do sections of code at. Each one will need its own previous millis (so like prevmillisincubator, prevmillistilt) and then jsut have the different while loops activate as needed at different times.

One thing though. I don't think you can have a Millis based timer with a 2000ms delay within your code. I'm pretty sure thatd cause a problem. You could, for example, make it so that that delay is a millis one. If you've noticed, does you LED on your arduino only blink every 5 seconds or is it off and on every sec? (haven't tried putting both a delay and a timer in the loop at the same time, always figured it'd cause problems. If it doesn't, well then I learned something coming here today).

PaulS

Quote
One thing though. I don't think you can have a Millis based timer with a 2000ms delay within your code. I'm pretty sure thatd cause a problem. You could, for example, make it so that that delay is a millis one.

Sure you can. millis() is a clock. delay() uses the clock to know when it is done wasting time.

Nikarus


Quote
One thing though. I don't think you can have a Millis based timer with a 2000ms delay within your code. I'm pretty sure thatd cause a problem. You could, for example, make it so that that delay is a millis one.

Sure you can. millis() is a clock. delay() uses the clock to know when it is done wasting time.


Hmm I always figured that a delay stopped the loop from operating for that time though. So, if he were to have something with the 2 sec delay, but then something that should happen every second because of a millis timer, then the millis timer would also end up working at the 2 second mark (since itd be past the 1000ms interval anyways). Meh i guess ill try something out when i get to my dorm later.

wildbill

Quote
Hmm I always figured that a delay stopped the loop from operating for that time though.


That is true. The point is, you can mix and match delay and millis if you want to, but as you correctly observe in this case, the delays may interfere with the timing you're trying to control with millis. There is no reason to avoid delay altogther - it can be useful for debouncing for example, but in this case, of course it would be better to control the timing of the thermometer reads using millis too.

Go Up