Arduino sensor upgrade and project improvement - s l o w thread. . .

Hello,
I am new to Arduino and programming. After a few days of lurking into the libraries and examples, I tried to improve an arduino sketch for my home project, that is based on an exact idea of this instructable: http://www.instructables.com/id/Environmental-Mushroom-Control-Arduino-Powered/
The sketch was later improvised by the author himself using DHT22 sensor on my request.(I haven't tried physically yet)
I gave it a thought and decided to be future proof with a robust and reliable sensor SHT-75. So I tried to upgrade the sketch with Sensirion SHT1x library.
I tried it myself for the first time using Arduino IDE. After a few errors and re-corrections, I found my sketch was compiled error free. I couldn't believe that I did it right as a newbie. I still doubt it if the sketch works properly in the real world with zero issues. I don't know it might.
I don't want to screw up with the project. Especially SHT-75 (ouch!!! very expensive!). I need to be sure of it before trying.
So someone who's more knowledgeable than me and experienced could please check the 1st part of the code below and approve if okay.
Please feel free for comments, ideas, suggestions ..
Thank you.

#include <SHT1x.h>
#include <LiquidCrystal.h>
#include <stdlib.h>
#include <EEPROM.h>
#define ARRAY_SIZE 2
#define dataPin  2
#define clockPin 3

/**********************/
/*Hysterisis Intervals*/
#define TEMP_LO 1
#define TEMP_HI 1
#define HUM_LO 5
#define HUM_HI 0
/**********************/
/*Define output  Pins */
//Digital
#define RELAY1  11    
#define RELAY2  12     
#define RELAY3  13     
#define BACKLIGHT 10 

/***********************/
/* Interval Definitions*/
#define INTERVAL 30000
#define SENSOR_INTERVAL 100 
#define BACKLIGHT_TIME 180000 
#define EE_PROM_INTERVAL 600000
#define AIR_DIVISION 10

/******Define Size of storage array for values*/
#define ARRAY_STORE 200

SHT1x sht1x(dataPin, clockPin);

/*****************************/
/*set Triggers *************/
int heatTrigger1  = 20;  
int HumTrigger = 80;
int duty = 25; 

int thermValue1 = 0;  
int humValue = 0;      
int therm1[ARRAY_SIZE];  
int humval[ARRAY_SIZE];  

/*Set time check ms     */
long last_check = millis();
long backlight = millis();
long time_eeprom = millis();

/** LCD Shield            */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char buf[5]; 
int configure = 0;
int showReading = 0;
int adc_key_in = 1024;
int adc_key_val[5] = {100, 160, 360, 770, 800 };
int NUM_KEYS = 5;
int key= -1;
char trigger_names[3][15] = {"Temp Trigger ","Humid Trigger","Air Duty Cycle"};
/** Setup Booleans for LCD Relay indicator Persistance */
boolean Heat_on = false;
boolean Humid_on = false;
boolean Air_on = false;
/* Set up index value for storing values in eeprom*/
int k=0;
void setup(void)
{Serial.println("Starting up");
pinMode(RELAY1, OUTPUT); 
pinMode(RELAY2, OUTPUT); 
pinMode(RELAY3, OUTPUT); 
 int i;for(i=0; i< ARRAY_SIZE; i++)
 {therm1[i] = 20;humval[i] = 80;}
 lcd.begin(16, 2);
 pinMode(BACKLIGHT, OUTPUT);
 digitalWrite(BACKLIGHT,HIGH);
 Serial.begin(115200); 
 delay(100);}


void loop(void)

{ key = get_key(adc_key_in); //In case
  float therml;
  float humidity;
    
   
  {
     int i;for (i=0; i < ARRAY_SIZE -1 ; i++) 
      {therm1[i] = therm1[i+1];
      humval[i] = humval[i+1];}
    
   /*** Read in sensor values */
  therm1[ARRAY_SIZE -1] = sht1x.readTemperatureC();
  humval[ARRAY_SIZE -1] = sht1x.readHumidity();
    
  Serial.print(therm1[ARRAY_SIZE -1]);
  Serial.print(":");
  Serial.println(humval[ARRAY_SIZE -1]);
  /**Add first line of Display**/
    if (configure == 0)
    {lcd.setCursor(0,0); lcd.print("Tem:Hum:Duty");}
    thermValue1 = mov_avg(therm1);
    humValue = mov_avg(humval);
    /**** Add second line of the Display *****/
    if (configure == 0)
    {lcd.setCursor(0,1);
      itoa(thermValue1, buf, 10);
      lcd.print(buf);
      
      lcd.setCursor(4,1);
      itoa(humValue, buf, 10);
      lcd.print(buf);

      lcd.setCursor(8,1);
      itoa(duty, buf, 10);
      lcd.print(buf);} }
    
 
  /*EEPROM STORAGE ***/
  if(millis() < time_eeprom) { time_eeprom = millis(); }
  /**Put values into eeprom*/
  if(millis() - time_eeprom > EE_PROM_INTERVAL)
  {time_eeprom = millis();
    EEPROM.write((k*2),(thermValue1));
    EEPROM.write((k*2+1),(humValue));
    k=k+1;
    if(k>=ARRAY_STORE) { k=0;  }}

  if( millis() < last_check ) { last_check = millis(); }

  if (millis() - last_check > INTERVAL) 
  {last_check = millis(); 

 //Temperature check and Relay Change
    if (thermValue1 < (heatTrigger1 +TEMP_HI) ){digitalWrite(RELAY1, LOW);Heat_on =false ;  }
    if  (thermValue1 > (heatTrigger1 -TEMP_LO) ) { digitalWrite(RELAY1, HIGH); Heat_on = true; }
  
  //Humidity Check and Relay change   //
    if ( humValue > HumTrigger+ HUM_HI ) {digitalWrite(RELAY3, LOW);Humid_on = false; }
    if ( humValue <= HumTrigger - HUM_LO ){digitalWrite(RELAY3, HIGH);Humid_on = true;}

and continued in attachment:

arduino remaining code attachment.txt (4.09 KB)

I can't think of any good reason to spend $70 on a humidity sensor. Your program is very long and complicated. The sensor has a communication protocol which is different to other sensors and may take quite a bit of debugging to get it to work. It says it will work up to 5.5V but "prefers" 3.3V, interpret that how you will.

Hi michinyon,
Thanks for reply. Yes, the sketch is complicated for sure. The author of it seems like a skilled person in programming. :sweat_smile:
I didn't understand a few parts of it though..

A little story: In my previous attempt to build a simple PIC16f chip based temperature and humidity reader, I used the much cheaper DHT-11 sensor. It worked good for a few hours at 35-40% R.H. Later increasing the R.H value with my humidifier a little, it started to show a random jump in the values like 20,95,63,87,29,55 and so on. I switched off the PIC reader for an hour and gave some rest to sensor. Later I switched it on to find out the sensor was still malfunctioning. So I opened up the sensor case, used a pcb cleaner and dried it with a blower. Putting it back into the circuit, it showed real values for a few minutes and again started to malfunction. I tried every possible replacement of psu, wires, resistors, crystal, PIC16f itself but couldn't get it work properly. Finally I gave upon it.. and lost appetite for DHT's :frowning:

So that's the reason I would prefer to invest most of my budget on a reliable sensor.
For sensor psu, I thought to use the arduino on board 3.3v regulated power out.
Since there is no other good sensor option (availability and time) I am willing to try it.
For now, I just want to make sure that I didn't miss anything on the sketch relating to SHT 75.

Anyone and everyone, If there are any mistakes in the sketch that you could find, please point out and suggest what needs to be done.
If sketch seems to be okay, please reply with 'okay'
The orders take much time to ship.
So I am waiting for replies.
Thank you.

your most reliable humidty sensor is going to be a diy wet and dry bulb thermometer, google the concept. Make one using 2x ds18b20's, will cost you three dollars and will be more accurate than any digital sensor. Only downsides are size, and having to have a fan circulating the air. I've used different digital sensors, all told me my humidity was about 30-50%, turns out it is actually about 80-90%, which is what i expected.....

It is a good point about the humidity sensors, they don't seem to be very reliable. I've used a couple and encountered these problems myself. There doesn't seem to be a robust way of measuring humidity.

They seem to work best when the humidity is very low.

I have actual real "wet and dry" thermometers, you can certainly calculate the humidity from them, I guess you can do it with the DS120Bs as well, I don't see why not, the only issue is keeping the moisture up to the "wet" detector, and the readings are very sensitive to other conditions like wind, for the same reason that a wet Tshirt feels colder if it is windy than if it isn't windy.

Hello lazah and michinyon,

Thanks for replying. Your suggestions are simple and easier, which I really appreciate to consider :slight_smile: . Earlier in my research, I have read and thought about using a setup like you both said.
By using a wet and dry bulb thermometer setup (psychrometer) we can surely have accurate R.H. monitoring at higher levels, where most of the cheap and expensive digital sensors struggle/fail to keep up with.
And Ds18b20, LM35 will do great job for monitoring and controlling temperature, irrespective of R.H. Simple and easy enough, the desired temperature is maintained.
But the problem is, using Psychrometer's readings as reference for maintaining R.H value, I still have to manually trigger the humidifier :~ . If there is a way to get the readings from this meter for automatic triggering, it should end the biggest problem in the project.
I too like to keep it simple and at a reasonable expenditure. But out of options I have finally chose to go with sensirion..
I don't mind the space occupancy for the psychrometer though, and could run a small 12cm fan all day and night. Since it is relatively cheaper and best for true R.H monitoring, I will surely buy and hook up one in my grow space for reference :slight_smile: .
But still, I am stuck with R.H. automation.

Wait a minute. Are you suggesting me to use 2x Ds18b20 sensors along with psychrometer? like, one attached to dry bulb and another to the wet bulb, So the readings can be retrieved for automation? Wow! what was I thinking? XD
Okay... Is that possible? Does the same principle work with these sensors? How about the accuracy and response time at high R.H levels? :slight_smile:

Hello,

Happy New Year to all!

Thank you again lazah and michinyon for your suggestions. I have now learned about psychrometer and it's working. I also studied about DS18b20 sensor and 1 wire protocol which were totally new to me. I tried to learn as much possible in a little available time.
So now I have come up with the following simple sketch using 2xDs18b20, which replicates the working of wet bulb and dry bulb principle.
Of course, I modified it to work within the required temperatures. :slight_smile: and keeping up the humidity levels above 80 to 95% in closed environment with no sensor issues.. compared to dht's or sht's or any sensors. Because its based on simple science, It should be the robust humidity sensor for a long run I.M.O :grin: and best bang for buck :wink:
Well, it may be a little slow reading temperatures from DS18b20 steel probes.. but still it's totally acceptable for me :slight_smile:
The code has compiled with no errors after a few corrections. So for now, I am hoping it to work flawlessly with the hardware too.. :sweat_smile:
Any suggestions are welcome ..

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

// Data wire is plugged into pin 8 on the Arduino
#define ONE_WIRE_BUS 8

// Setup a oneWire instance to 
//communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress DryThermometer = { 0×28, 0xF0, 0xEA, 0×73, 0×03, 0×00, 0×00, 0xCF };
DeviceAddress WetThermometer = { 0x28, 0xDF, 0x21, 0x16, 0x03, 0x00, 0x00, 0x1E };

int Dry = 6; // configure pin A/C
int Wet = 7; // configure pin Humidifier

float Drytemp = 0;
float Wettemp = 0;


void setup(void)
{// Start up the library
  sensors.begin();// set the resolution to 10 bit (good enough?)
  sensors.setResolution(DryThermometer, 10);
  sensors.setResolution(WetThermometer, 10);
  
lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen

pinMode(Dry, OUTPUT); // for relay output
pinMode(Wet, OUTPUT);} 

void printTemperature(DeviceAddress deviceAddress)
{float tempC = sensors.getTempC(deviceAddress);
  float t1tempC = sensors.getTempC(DryThermometer);
  float t2tempC = sensors.getTempC(WetThermometer);
  
  if (tempC == -127.00) {
lcd.print("Error");} else 
{// lcd.print(tempC);
// lcd.print("/");
Drytemp = (DallasTemperature::toFahrenheit(t1tempC));
Wettemp = (DallasTemperature::toFahrenheit(t2tempC));
lcd.print(DallasTemperature::toFahrenheit(tempC));}}

void loop(void)
{ delay(2000);
sensors.requestTemperatures();
lcd.setCursor(0,0);
lcd.print("Dry: ");
printTemperature(DryThermometer);
lcd.setCursor(0,1);
lcd.print("Wet: ");
printTemperature(WetThermometer);

if (Drytemp >= 80)//26.6
{digitalWrite(Dry, HIGH);}

if (Drytemp <= 76)//24.4
{digitalWrite(Dry, LOW);}

if (Wettemp < Drytemp-2)//24.6-22.4
{digitalWrite(Wet, HIGH);}

if (Wettemp >= Drytemp-1 )//25.6-23.4
{digitalWrite(Wet, LOW);}}
  
//if (Drytemp >= 82 && Drytemp <= 72)
//{digitalWrite(tank1, HIGH);}}

On a slightly different vane but touching on the slow issue you mentioned, I noticed something very strange around the reading and when I made one small change the DS18B20 sped up considerably.

First I ran with the standard 5V, Gnd and input connected up as per normal with a 4.7k resistor between input and +5v. The 5v I used was just a standard board pin (Arduino Uno).

/* 
Modified DS18B20 temperature reading script
This version by  Tim Russell (http:.//www.russellweb.eu) and
is  based on the original work from Miles Burton. 
(https://github.com/milesburton/Arduino-Temperature-Control-Library)
*/
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 9 /*-(Connect to Pin 9 )-*/

OneWire ourWire(ONE_WIRE_BUS);

DallasTemperature sensors(&ourWire);

void setup(){
  delay(1000);
  Serial.begin(115200);
  Serial.println("Temperature Sensor DS18B20 Test Program");
  delay(1000);
  sensors.begin();
}


void loop(){
  Serial.print(millis());
  Serial.print(" ");  
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.print(millis());
  Serial.print(" ");  
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print(" ");  
  Serial.println(millis());
}

...The resulting serial print showing 750ms to request the temperature.

Temperature Sensor DS18B20 Test Program
2061 2813 7.63 2842
2842 3595 7.63 3623
3624 4376 7.63 4406
4406 5158 7.63 5187
5187 5940 7.56 5968
5968 6721 7.63 6750
6750 7502 7.63 7531

I then disconnected the power, made a few code changes and moved the power input to an Arduino digital pin, pin 2 in this case and ran it again.

/* 
Modified DS18B20 temperature reading script
This version by  Tim Russell (http:.//www.russellweb.eu) and
is  based on the original work from Miles Burton. 
(https://github.com/milesburton/Arduino-Temperature-Control-Library)
*/
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 9 /*-(Connect to Pin 9 )-*/
#define ONE_WIRE_PWR 2 /*-(Connect to Pin 2 )-*/
OneWire ourWire(ONE_WIRE_BUS);

DallasTemperature sensors(&ourWire);

void setup(){
  Serial.begin(115200);
  Serial.println("Temperature Sensor DS18B20 Test Program");
  delay(1000);
  pinMode(ONE_WIRE_PWR, OUTPUT);
  digitalWrite(ONE_WIRE_PWR, HIGH);
  sensors.begin();
  sensors.requestTemperatures(); // Send the command to get temperatures
  delay(1000);
}


void loop(){
  Serial.print(millis());
  Serial.print(" ");  
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.print(millis());
  Serial.print(" ");  
  Serial.print(sensors.getTempCByIndex(0));
  Serial.print(" ");  
  Serial.println(millis());
}

The serial result as you can see is quite different, with less than 100 msec read and I can't 'yet' explain it!!

Temperature Sensor DS18B20 Test Program
2097 2193 7.69 2222
2222 2319 7.69 2348
2348 2444 7.69 2472
2473 2570 7.69 2598
2598 2695 7.69 2723
2724 2821 7.69 2849
2849 2946 7.69 2974
2975 3072 7.69 3100
3100 3196 7.69 3225
3226 3322 7.69 3351
3351 3447 7.69 3476

With some playing it appears there is a mismatch between the libraries and power to the sensor starting at the same time as the board. By introducing a delay to the power for the sensor it all works a lot quicker.

I'm sure someone with more time on their hands will go through the libraries and find the reason :stuck_out_tongue: