Hello all you wonderful people!
So, I am hooked. The Arduino platform is by far the greatest thing since Lego or Scalextrics! I have had so much fun and learned so much about everything from coding to electronics since I first stumbled upon this little gem. I have the UNO R2 by the way, well, I have three. I fried the ATMEGA chip on one and... long story. I now have three boards and three spare chips.
Down to business though. I could really use some advice on my current project. It is a controller which reads the temperature and humidity and switches on either a fan or a heating pad to keep the environment within a certain range. It is for an incubator which houses plant cultures.
Firstly, I worry that my code, although it may appear to be correct and it runs fine, actually isn't. I don't know how well my sensor averaging works to be honest - the temperature sometimes hangs on a round figure for a good 10 loops.
As far as physical wiring goes, well, it is wired correctly-ish. I know I am being naughty for not using pull down resistors and simple stuff like that but everything seems to work so.... bleh!
Here is my code, and please, feel free to share it around!!!
// TEMP SENSOR IS 3.3V!!! Don't mess that up!
// Connect Temp Pins SDA and SCL to A4 and A5 respectively.
//Humidity is 5v.
// Connect Analogue Pin on TRH sensor to A0
//LCD uses PWM pin 2 as RX
//Relays are on Pins 4 and 7
#include <SoftwareSerial.h>
#include <Wire.h>
///////////////////////////////////////////////////////////////////////////////
///////////////////////// setup ///////////////////////////////////////////////
int relay1 = 4;
int relay2 = 7;
const int numReadings1 = 10;
int readings1[numReadings1]; // reading from analogue in
int index1 = 0; // index of current reading
float total1 = 0; // running total
float average1 = 0; // average
const int numReadings2 = 10;
int readings2[numReadings2];
int index2 = 0;
float total2 = 0;
float average2 = 0;
byte msb;
byte lsb;
int temperature;
float celcius;
float adcValue = 0;
float voltage = 0;
float percentRH = 0;
SoftwareSerial LCD2(3,2); // pin 2 = TX
int tmp102Address = 0x91 >> 1;
void setup()
{
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
LCD2.begin(9600); //serial connection baud
Wire.begin(); // for the I2C thingy
delay(500); // take a breath
LCD2.write(254); // Special Character
LCD2.write(128); // move cursor to beginning of first line
LCD2.write(" Auto ");
LCD2.write(" Enviro Control");
delay(2000);
LCD2.write(254);
LCD2.write(128);
LCD2.write(" ");
LCD2.write(" ");
LCD2.write(254);
LCD2.write(128);
LCD2.write(" Incubator V1 ");
LCD2.write("Make Life Easier");
delay(2000);
LCD2.write(254);
LCD2.write(128);
LCD2.write(" ");
LCD2.write(" ");
LCD2.write(254);
LCD2.write(128);
LCD2.write(" Sensor Values ");
LCD2.write(" Are Aggregated ");
delay(2000);
}
//-------------------------------------------------------------------------------------------
void loop(){
// Pulled this from the sparkfun example I think...
Wire.requestFrom(tmp102Address,2);
if (2 <= Wire.available()) // if two bytes were received
{
msb = Wire.read(); // receive high byte (full degrees)
lsb = Wire.read(); // receive low byte (fraction degrees)
temperature = ((msb) << 4); // MSB
temperature |= (lsb >> 4); // LSB
celcius = temperature*0.0625;
}
// this seems to be correct.
percentRH = (analogRead(0) / 675.84 * 100.0);
delay(100);
// This part here averages out the sensor readings. I found it on a tut online. No credit to me.
total1= total1 - readings1[index1];
// read from the sensor:
readings1[index1] = percentRH;
// add the reading to the total:
total1= total1 + readings1[index1];
// advance to the next position in the array:
index1 = index1 + 1;
// if we're at the end of the array...
if (index1 >= numReadings1)
// ...wrap around to the beginning:
index1 = 0;
// calculate the average:
average1 = total1 / numReadings1;
/////////////////^HUMIDITY///////////////////////////
/////////|TEMPERATURE//////////////////////
total2= total2 - readings2[index2];
readings2[index2] = celcius;
total2= total2 + readings2[index2];
index2 = index2 + 1;
if (index2 >= numReadings2)
index2 = 0;
average2 = total2 / numReadings2;
LCD2.write(254);
LCD2.write(128);
LCD2.write(" ");
LCD2.write(" ");
LCD2.write(254);
LCD2.write(128);
LCD2.write("Temp (c)= " );
LCD2.write("Humidity= " );
LCD2.write(254);
LCD2.write(138);
LCD2.print(average2);
LCD2.print((char)223); // Degrees symbol
LCD2.write(254);
LCD2.write(202);
LCD2.print(average1);
LCD2.print("%");
delay(1000);
////////////////////// RELAYS //////////////////////////
if(average1 > 90) // if it is more than 90% switch the fan on
{
digitalWrite(relay1, HIGH);
}
else
{
digitalWrite(relay1, LOW);
}
if(average2 < 25) // If it is cooler than 25 switch the heater on
{
digitalWrite(relay2, HIGH);
}
else
{
digitalWrite(relay2, LOW);
}
}
Alrighty, so it looks messy, granted, but how is it? Is it going to perform correctly -I sort of need it to, the cultures will die if things fail. As it is, it appears to do what it is meant to, so I guess it works... right? Right???
Any hints on making things smoother, more accurate or even corrections??? I would really appreciate a guiding hand on this! I'll do what I can to pay it forward to the community in the future. I know that using delay(xx); is a little naughty but I still trying to get my head around the millis(); option ![]()
Um, some details on the hardware: Humidity sensor is HMZ-333a. Temp sensor is TMP102. The LCD is the sparkfun 16x2 serial enabled LCD (easier to work with). The relays are NPA-AS3. The Fan is 12v, with its own power supply and the heating pad is 240v with its own power supply. I'm from South Africa, if that makes a difference ![]()
Thank You! Please grill me, shout at me, correct me and critique me - its how we learn right!
KD.