Hello. I am building an automated terrarium. So far I have it set up how I want, such that certain actions happen when certain conditions are met. As part of my projects I have an LCD display running continuously with screens switching every 3-seconds while the program updates every n-minutes (5s in the posted code).
I am running into issues when the LCD has to display the light sensor reading. All my other variables update real time as the code runs, but the light variable does not change at all on the LCD. However, it updates on the Serial Monitor, so I know the connection is correct and the sensor works.
I suspect the issue lies in how/where I am initializing the rangeLight variable, however, I don't know how to fix it.
Does anyone have any insight?
Thank you in advance.
Code:
//Terrarium Sketch
// Updated: 15/sept/2018
// Include Libraries
#include <dht.h> //humidity and temperature sensor
#include <virtuabotixRTC.h> //real clock
#include <LiquidCrystal.h> // lcd
//Initialize and Define Pins
virtuabotixRTC myRTC(7, 6, 5);
dht DHT;
#define DHT11_PIN 22
const int sensorMin = 120;
const int sensorMax = 800;
int lightsensorPin = A0;
int soilsensorPin = A1;
int soilsensorValue = 0;
int soilpercent = 0;
int fanPin = 24;
int relay1 = 31; //humidifier
int relay2 = 33; //grow lamp
int relay3 = 35; //heating pad
int redPin = 9;
int greenPin = 10;
int bluePin = 11;
LiquidCrystal lcd(51, 49, 47, 45, 43, 41);
int convertTosoilpercent(int value)
{
int soilpercentValue = 0;
soilpercentValue = map(value, 0, 582, 0, 100);
return soilpercentValue;
}
int rangeLight;
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000;
long previousLCDMillis = 0; // for LCD screen update
long lcdInterval = 3000;
// screen to show
int screen = 0;
int screenMax = 3;
bool screenChanged = true; // initially we have a new screen, by definition
// defines of the screens to show
#define DATE 0
#define HUMIDITY 1
#define TEMPERATURE 2
#define LIGHT 3
//////////////////////////////////////
//
// LCD display functions
//
void showDate()
{
lcd.clear();
lcd.print("Date: ");
lcd.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system
lcd.print("/");
lcd.print(myRTC.month);
lcd.print("/");
lcd.print(myRTC.year);
lcd.setCursor(0,1);
lcd.print("Time: ");
lcd.print(myRTC.hours);
lcd.print(":");
lcd.print(myRTC.minutes);
lcd.print(":");
lcd.print(myRTC.seconds);
}
void showHumidity()
{
lcd.clear();
lcd.print("Soil Hum: ");
lcd.print(soilpercent);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("Air Hum: ");
lcd.print(DHT.humidity);
}
void showTemperature()
{
lcd.clear();
lcd.print("Temp F = ");
lcd.print((DHT.temperature*1.8)+32);
lcd.setCursor(0,1);
lcd.print("Temp C = ");
lcd.print(DHT.temperature);
}
void showLight()
{
lcd.clear();
lcd.print("Light = ");
switch (rangeLight)
{
// your hand is on the sensor
case 0:
lcd.print("Dark");
break;
// your hand is close to the sensor
case 1:
lcd.print("Dim");
break;
// your hand is a few inches from the sensor
case 2:
lcd.print("Medium");
break;
// your hand is nowhere near the sensor
case 3:
lcd.print("Bright");
break;
}
}
void setup() {
Serial.begin(9600); // Initializes Serial Monitor
lcd.begin(16,2); // Initializes LCD
pinMode(fanPin,OUTPUT);
pinMode(relay1,OUTPUT);
pinMode(relay2,OUTPUT);
pinMode(relay3,OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
//Start with all relays off
digitalWrite(relay1,LOW);
digitalWrite(relay2,LOW);
digitalWrite(relay3,LOW);
}
void loop() {
// Read Values
currentMillis = millis();
if (currentMillis - startMillis >= period){
int chk = DHT.read11(DHT11_PIN);
myRTC.updateTime();
int analogLight;
int rangeLight;
analogLight = analogRead(lightsensorPin);
rangeLight = map(analogLight,sensorMin,sensorMax,0,3);
soilsensorValue = analogRead(soilsensorPin);
soilpercent = convertTosoilpercent(soilsensorValue);
// If Humidity is high OR Temp is high (>80F): turn fans on
if (DHT.humidity >= 80 || DHT.temperature > 30){
digitalWrite(fanPin,HIGH);
} else {
digitalWrite(fanPin,LOW);
}
// If Temp is low (<68F): turn on heating pad
if (DHT.temperature < 20) {
digitalWrite(relay3,HIGH);
} else {
digitalWrite(relay3,LOW);
}
// If Time of Day is between 8am and 3pm AND the light sensor detects dim or below: turn relay 2 (the lamp) on
while (myRTC.hours > 8 && myRTC.hours < 15){
if (rangeLight < 2){
//(myRTC.hours > 8 && myRTC.hours < 15 && rangeLight < 2)
digitalWrite(relay2,HIGH);
} else {
digitalWrite(relay2,LOW);
}
}
//If the humidity is low: turn on humidifier
if (DHT.humidity < 40) {
digitalWrite(relay1,HIGH);
} else {
digitalWrite(relay1,LOW);
}
//Reflect Soil Moisture with LED: if high = green, if med = blue, if low = red
if (soilsensorValue > 465){
digitalWrite(greenPin,HIGH); // green
} else {
digitalWrite(greenPin,LOW); }
if (soilsensorValue > 257 && soilsensorValue < 464){
digitalWrite(bluePin,HIGH); // blue
} else
{
digitalWrite(bluePin,LOW); }
if (soilsensorValue < 256){
digitalWrite(redPin,HIGH); // red
} else {digitalWrite(redPin,LOW); }
// Print to serial monitor
Serial.print("\nCurrent Date / Time: ");
Serial.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
Serial.print("Soil Analog Value: ");
Serial.print(soilsensorValue);
Serial.print("\nSoil Humidity: ");
Serial.print(soilpercent);
Serial.print("%");
Serial.print("\nTemperature F = ");
Serial.println((DHT.temperature*1.8)+32);
Serial.print("Temperature C = ");
Serial.println(DHT.temperature);
Serial.print("Humidity = ");
Serial.println(DHT.humidity);
Serial.print("Light = ");
switch (rangeLight)
{
// your hand is on the sensor
case 0:
Serial.println("Dark");
break;
// your hand is close to the sensor
case 1:
Serial.println("Dim");
break;
// your hand is a few inches from the sensor
case 2:
Serial.println("Medium");
break;
// your hand is nowhere near the sensor
case 3:
Serial.println("Bright");
break;
}
startMillis = currentMillis;
}
unsigned long currentLCDMillis = millis();
if(currentLCDMillis - previousLCDMillis > lcdInterval) // save the last time you changed the display
{
previousLCDMillis = currentLCDMillis;
screen++;
if (screen > screenMax) screen = 0; // all screens done? => start over
screenChanged = true;
}
// DISPLAY CURRENT SCREEN
if (screenChanged) //-- only update the screen if the screen is changed.
{
screenChanged = false; // reset for next iteration
switch(screen)
{
case DATE:
showDate();
break;
case HUMIDITY:
showHumidity();
break;
case TEMPERATURE:
showTemperature();
break;
case LIGHT:
showLight();
break;
default:
break;
}
}
}