solved - using interupt via LDR when a LCD screen is used

Hi all,

I have a project which is effectively a co2 dosing system in the first instance for tropical plants, I intend on adding humidity controls aswell.

what Im tryig to do is:

if the light is on then run the main program which monitors temp, humidity (dht11) and co2 (NDIR sensor) - currently the co2 sensor activates a relay and this is working ok.

I have been doing the research so that I can automatically shut off the above functions if it's dark but running into problems and not sure how to move forward, I've looked into interrupts but I am using a standard LCD which uses pins 2 and 3 so my LDR would have to be an analogue input.

Hope this makes sense.

heres the code so far:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 7

// Define pins for CO2 Sensor
int CO2_ReadPin = A0;                   
int CO2control = 13;                   
int CO2_Value;
int ppm;


void setup() {
  // Setup for co2 controller 
  pinMode(CO2control, OUTPUT); 
digitalWrite(CO2control, LOW);
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
 // Serial.begin(9600);
  //DISPLAY TEMPERATURE
 lcd.setCursor(0, 0);  
  // print the Temperature title
  lcd.print("Temperature");
  lcd.setCursor(17, 0);  
  lcd.print(char (0xdf)) + lcd.print("C");
  //DISPLAY RELATIVE HUMIDITY
  lcd.setCursor(0, 1);  
  // print the Relative Humidity title
  lcd.print("Humidity");
   lcd.setCursor(17, 1);  
  lcd.print("%");
   //DISPLAY CO2 READINGS
  lcd.setCursor(0, 2);  
  // print the CO2 title
  lcd.print("CO2 > ");
   lcd.setCursor(17, 2);  
  // print the CO2 'ppm'
  lcd.print("PPM");
//SQUIRREL-LABS
  lcd.setCursor(3,3);
  lcd.print("Squirrel-Labs");
  
  
  // Setup for CO2 Sensor

 int CO2_Value = 0;                     // variable set to zero
  int ppm = 0;                           // variable set to zero 
  
}

void loop() 
{
  int chk = DHT11.read(DHT11PIN);
    // CO2 Sensor
    CO2_Value = analogRead(CO2_ReadPin);   
    unsigned int ppm = ((unsigned long)analogRead(CO2_ReadPin) * 2500)/1024;  // calc ppm
 // co2 relay control
if (ppm < 1300)
  digitalWrite(CO2control, HIGH);
  lcd.setCursor(6,2);
  if (ppm < 1300)
  lcd.print("On ");
     if (ppm > 1500) 
  digitalWrite(CO2control, LOW);
  lcd.setCursor(6,2);
     if (ppm > 1500)
  lcd.print("Off");
//TEMP
  lcd.setCursor(14, 0);  
  // print the Temperature value
  lcd.print((float)DHT11.temperature, 0);
 //HUMIDITY
  lcd.setCursor(14, 1);  
  // print the Relative Humidity value
  lcd.print((float)DHT11.humidity, 0);
  //CO2
  lcd.setCursor(11, 2);  
  // print the CO2 value
  if(ppm < 1000)
  lcd.print(" ");
if(ppm < 100)
 lcd.print(" ");
if(ppm < 10)
 lcd.print(" ");
 lcd.print(ppm);
    
  delay(2000);
}

apologies: my comments could be better.

Any Help pointers greatly appreciated
T

I've looked into interrupts

Why? Interrupts are for events that must be handled NOW. Getting dark is not such an event.

but I am using a standard LCD which uses pins 2 and 3

Unless it is a shield, it uses no specific pins. You can move the wires that are currently connected to pins 2 and 3 to other pins (as long as you change the constructor call, too).

so my LDR would have to be an analogue input.

Pins 2 and 3, for external interrupts, are digital pins. Forget using interrupts, and those pins, for analog devices.

What is the problem with the code you posted? I'm happy to look at it, if I know what I am looking for.

No need for interrupts

Read the value from the LDR. If it above the threshold run the functions
What's the problem ?

You need to incorporate some hysteresis around the on/off light level to avoid constant on/off switching at that level and maybe only switch on/off if the level has been above/below the threshold for some time, but get the simple on/off based on the value from the LDR working first.

Hi,
Thanks for the quick response,

The code as it stands works ok (so far)

I would like to add the functionality that when it's dark (using and LDR) it over rides the co2 relay control and swithches it off until it gets light again so the main co2 dosing can take place via the relay...

hope that makes sense.. I looked into functionality that would do it and interrupts came out of googles searches every time so thought that was the direction I had to take.

T

So Here is one way I experimented with before looking into interrupts:

am I on the right path??

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 7

// Define pins for CO2 Sensor
int CO2_ReadPin = A0;                   
int CO2control = 13;                   
int CO2_Value;
int ppm;
int ldr = A5;
unsigned int ldrvalue = 0;


void setup() {
  // Setup for co2 controller 
  pinMode(CO2control, OUTPUT); 
digitalWrite(CO2control, LOW);
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
 // Serial.begin(9600);
  //DISPLAY TEMPERATURE
 lcd.setCursor(0, 0);  
  // print the Temperature title
  lcd.print("Temperature");
  lcd.setCursor(17, 0);  
  lcd.print(char (0xdf)) + lcd.print("C");
  //DISPLAY RELATIVE HUMIDITY
  lcd.setCursor(0, 1);  
  // print the Relative Humidity title
  lcd.print("Humidity");
   lcd.setCursor(17, 1);  
  lcd.print("%");
   //DISPLAY CO2 READINGS
  lcd.setCursor(0, 2);  
  // print the CO2 title
  lcd.print("CO2 > ");
   lcd.setCursor(17, 2);  
  // print the CO2 'ppm'
  lcd.print("PPM");
//CO2control Display Status 
//SQUIRREL-LABS
  lcd.setCursor(3,3);
  lcd.print("Squirrel-Labs");
  
  
  // Setup for CO2 Sensor

 int CO2_Value = 0;                     // variable set to zero
  int ppm = 0;                           // variable set to zero 
  
}

void loop() 
{
 
  ldrvalue = analogRead(ldr);
 if (ldrvalue <????) digitalWrite(13, LOW);  //not sure as yet to the correct value to use
 else digitalWrite(13, HIGH);
 
 if (ldrvalue <???); //not sure as yet to the correct value to use
 lcd.setCursor(6,2); 
 lcd.print("Off");
 
  int chk = DHT11.read(DHT11PIN);
    // Loop for CO2 Sensor
    CO2_Value = analogRead(CO2_ReadPin);   // read Teensy input pin 38
    unsigned int ppm = ((unsigned long)analogRead(CO2_ReadPin) * 2500)/1024;  // calc ppm
    
if (ppm < 1300)
  digitalWrite(CO2control, HIGH);
  lcd.setCursor(6,2);
  if (ppm < 1300)
  lcd.print("On ");
     if (ppm > 1500) 
  digitalWrite(CO2control, LOW);
  lcd.setCursor(6,2);
     if (ppm > 1500)
  lcd.print("Off");
  delay (2000);
//TEMP
  lcd.setCursor(14, 0);  
  // print the Temperature valie
  lcd.print((float)DHT11.temperature, 0);
 //HUMIDITY
  lcd.setCursor(14, 1);  
  // print the Relative Humidity value
  lcd.print((float)DHT11.humidity, 0);
  delay (1000);
  //CO2
  lcd.setCursor(11, 2);  
  // print the CO2 value
  if(ppm < 1000)
  lcd.print(" ");
if(ppm < 100)
 lcd.print(" ");
if(ppm < 10)
 lcd.print(" ");
 lcd.print(ppm);
    
  delay(2000);
}

I would like to add the functionality that when it's dark (using and LDR) it over rides the co2 relay control and swithches it off until it gets light again so the main co2 dosing can take place via the relay...

Each pass through loop, you read from the LDR. If the value is above a threshold, do one thing. Otherwise, do something else.

I don't see what the problem is.

You might need to use a flag. Set that flag to true when the value rises above the threshold. Set it to false only when it drops some amount below the threshold, so that there is not dithering around the transition from light to dark or dark to light.

Forget about using interrupts !

start of loop
  itsLight = LDR reading
    if (itsLight)
    {
      //your existing code goes here
    }
end of loop

I can't help feeling that I have missed something in your requirement. If only some of your code should be executed when it is light then put that inside the if test and the rest outside.

So Here is one way I experimented with before looking into interrupts:

You are going the right way with your code but need to put the statements to be executed if something is true in curly brackets so the program knows which commands to execute and which to ignore

if (something == true)
{
  //do these commands
}
else
{
  //otherwise do these commnads
}
//always do these commands

ok :slight_smile: I think its sorted it; with help from yourselves XD

thank you v much

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 7

// Define pins for CO2 Sensor
int CO2_ReadPin = A0;                   
int CO2control = 13;                   
int CO2_Value;
int ppm;
int ldr = A5;
unsigned int ldrvalue = 0;


void setup() {
  // Setup for co2 controller 
  pinMode(CO2control, OUTPUT); 
digitalWrite(CO2control, LOW);
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
 // Serial.begin(9600);
  //DISPLAY TEMPERATURE
 lcd.setCursor(0, 0);  
  // print the Temperature title
  lcd.print("Temperature");
  lcd.setCursor(17, 0);  
  lcd.print(char (0xdf)) + lcd.print("C");
  //DISPLAY RELATIVE HUMIDITY
  lcd.setCursor(0, 1);  
  // print the Relative Humidity title
  lcd.print("Humidity");
   lcd.setCursor(17, 1);  
  lcd.print("%");
   //DISPLAY CO2 READINGS
  lcd.setCursor(0, 2);  
  // print the CO2 title
  lcd.print("CO2 > ");
   lcd.setCursor(17, 2);  
  // print the CO2 'ppm'
  lcd.print("PPM");
//SQUIRREL-LABS
  lcd.setCursor(3,3);
  lcd.print("Squirrel-Labs");
  
  
  // Setup for CO2 Sensor

 int CO2_Value = 0;                     // variable set to zero
  int ppm = 0;                           // variable set to zero 
  
}

void loop() 
{
 
  
  int chk = DHT11.read(DHT11PIN);
    // Loop for CO2 Sensor
    CO2_Value = analogRead(CO2_ReadPin);   // read Teensy input pin 38
    unsigned int ppm = ((unsigned long)analogRead(CO2_ReadPin) * 2500)/1024;  // calc ppm
    
   ldrvalue = analogRead(ldr);
 if (ldrvalue < 700)
 {
   digitalWrite(13, LOW);
   lcd.setCursor(6,2);
 lcd.print("Off ");
  lcd.setCursor(3,3);
  lcd.print("Night Mode   ");
 } 
else 
{ 
if  (ppm < 1300)
  digitalWrite(CO2control, HIGH);
  lcd.setCursor(6,2);
  if (ppm < 1300)
  lcd.print("On  ");
     if (ppm > 1500) 
  digitalWrite(CO2control, LOW);
  lcd.setCursor(6,2);
     if (ppm > 1500)
  lcd.print("Off ");
  //SQUIRREL-LABS
  lcd.setCursor(3,3);
  lcd.print("Squirrel-Labs");
}
  delay (2000);
//TEMP
  lcd.setCursor(14, 0);  
  // print the Temperature valie
  lcd.print((float)DHT11.temperature, 0);
 //HUMIDITY
  lcd.setCursor(14, 1);  
  // print the Relative Humidity value
  lcd.print((float)DHT11.humidity, 0);
  delay (1000);
  //CO2
  lcd.setCursor(11, 2);  
  // print the CO2 value
  if(ppm < 1000)
  lcd.print(" ");
if(ppm < 100)
 lcd.print(" ");
if(ppm < 10)
 lcd.print(" ");
 lcd.print(ppm);
 
    
  delay(2000);
}

Using Tools + Auto Format would be a good thing.

Then, ask yourself this. If it's dark, does it matter what the temperature or CO2 level is?

If not, and I can't see that it does, move the code to get the temperature and CO2 level into the "it's light out" block.

Thanks for the tip :slight_smile: