i’m trying to set the LCD screen’s backlight to go off after a period of inactivity. I can get the screen to go off after the 5 seconds, but then when I change the state of one of the sensors, the screen flashes on,and almost immediately off again. I would like the backlight to come on again for the 5 seconds.
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
const long seconds_start_delay = 5; // Pause during startup to let PIRs settle down
#define STATE_SHORT 0
#define STATE_NORMAL 1
#define STATE_TAMPER 2
#define STATE_ALARM 3
#define STATE_ALARM_TAMPER 4
#define STATE_CUT 5
#define STATE_UNKNOWN 6
int pirOut = 3;
/* Display config */
#define ENABLE_LCD true // true/false. Enable if you have a Freetronics OLED128 connected
int lcd2_timeout = 20; // Seconds before screen blanks after last activity
unsigned long previousMillis = 0;
/* Analog readings corresponding to different sensor states */
struct input_ranges {
int sensor_state;
const String label;
int range_bottom;
int range_optimum;
int range_top;
};
const input_ranges ranges[] {
{ STATE_SHORT, "Shorted", 0, 0, 162 }, // 0
{ STATE_NORMAL, "Normal", 163, 326, 409 }, // 1
{ STATE_TAMPER, "Tamper", 410, 495, 551 }, // 2
{ STATE_ALARM, "Alarm", 552, 609, 641 }, // 3
{ STATE_ALARM_TAMPER, "Alarm+Tamper", 642, 675, 848 }, // 4
{ STATE_CUT, "Cut", 849, 1023, 1023 }, // 5
{ STATE_UNKNOWN, "Unknown", 1024, 1024, 1024 }, // 6. Range beyond analog in because this is never read
};
/* Connected sensors */
struct sensor {
const String label;
byte analog_input;
byte status_output;
byte last_state;
};
sensor sensors[] {
{ "A", 0, 4, STATE_UNKNOWN },
{ "B", 1, 5, STATE_UNKNOWN },
{ "C", 2, 6, STATE_UNKNOWN },
{ "D", 3, 7, STATE_UNKNOWN },
};
long lastActivityTime = 0;
char messageBuffer[100];
char topicBuffer[100];
char clientBuffer[20];
/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 16 chars 2 line display
// A FEW use address 0x3F
// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd2(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
void setup()
{
{
Serial.begin(9600);
if ( ENABLE_LCD == true )
{
lcd2.begin(20, 4);
// ------- Quick 3 blinks of backlight -------------
for (int i = 0; i < 3; i++)
{
lcd2.backlight();
delay(250);
lcd2.noBacklight();
delay(250);
}
lcd2.backlight();
//-------- Write characters on the display ------------------
// NOTE: Cursor Position: (CHAR, LINE) start at 0
lcd2.setCursor(0, 0); //Start at character 4 on line 0
lcd2.print("Alarm System");
delay(1000);
lcd2.setCursor(0, 1);
lcd2.print("C Brennan V1.0");
delay(8000);
lcd2.clear();
}
if (seconds_start_delay > 0)
{
Serial.print("Pausing ");
Serial.print( seconds_start_delay );
Serial.println(" seconds to let sensors settle");
if ( ENABLE_LCD == true )
{
lcd2.setCursor(0, 0);
lcd2.print(F("Pausing "));
lcd2.setCursor(0, 1);
lcd2.print(seconds_start_delay, DEC);
lcd2.print(" Secs to settle");
//
}
}
delay(seconds_start_delay * 1000);
lcd2.clear();
}
pinMode(pirOut, OUTPUT);
digitalWrite(pirOut, HIGH);
delay(100);
digitalWrite(pirOut, LOW);
delay(100);
digitalWrite(pirOut, HIGH);
delay(100);
digitalWrite(pirOut, LOW);
}
void loop()
{
if ( ENABLE_LCD == true )
{
// Get snapshot of time
unsigned long currentMillis = millis();
if ( millis() > (lastActivityTime + (1000 * lcd2_timeout)))
{
lcd2.noBacklight();
}
}
byte i;
for ( i = 0; i < 2; i++) {
processSensor( i );
}
}
void processSensor( byte sensorId )
{
int sensorReading = analogRead( sensors[sensorId].analog_input );
byte sensorState = STATE_UNKNOWN;
// This should check all entries in the states struct:
if ( (sensorReading >= ranges[STATE_SHORT].range_bottom) && (sensorReading <= ranges[STATE_SHORT].range_top) ) {
sensorState = STATE_SHORT;
digitalWrite (pirOut, HIGH);
} else if ( (sensorReading >= ranges[STATE_NORMAL].range_bottom) && (sensorReading <= ranges[STATE_NORMAL].range_top) ) {
sensorState = STATE_NORMAL;
digitalWrite (pirOut, LOW);
} else if ( (sensorReading >= ranges[STATE_TAMPER].range_bottom) && (sensorReading <= ranges[STATE_TAMPER].range_top) ) {
sensorState = STATE_TAMPER;
digitalWrite (pirOut, HIGH);
} else if ( (sensorReading >= ranges[STATE_ALARM].range_bottom) && (sensorReading <= ranges[STATE_ALARM].range_top) ) {
sensorState = STATE_ALARM ;
digitalWrite (pirOut, HIGH);
} else if ( (sensorReading >= ranges[STATE_ALARM_TAMPER].range_bottom) && (sensorReading <= ranges[STATE_ALARM_TAMPER].range_top) ) {
sensorState = STATE_ALARM_TAMPER;
digitalWrite (pirOut, HIGH);
} else if ( (sensorReading >= ranges[STATE_CUT].range_bottom) && (sensorReading <= ranges[STATE_CUT].range_top) ) {
sensorState = STATE_CUT;
digitalWrite (pirOut, HIGH);
} else {
sensorState = STATE_UNKNOWN;
}
// Compare to previous value
if ( sensorState != sensors[sensorId].last_state )
{
// It changed!
byte lastSensorState = sensors[sensorId].last_state;
Serial.print("Sensor ");
lcd2.backlight();
lcd2.clear();
lcd2.setCursor(0, 0);
Serial.print(sensorId);
lcd2.print("Sensor ");
lcd2.setCursor(7, 0);
lcd2.print(sensorId);
Serial.print(" changed from ");
lcd2.setCursor(0, 1);
lcd2.print("from ");
lcd2.setCursor(5, 1);
lcd2.print(ranges[lastSensorState].label);
Serial.print(ranges[lastSensorState].label);
Serial.print(" to ");
lcd2.setCursor(0, 2);
lcd2.print("to");
lcd2.setCursor(0, 3);
lcd2.print(ranges[sensorState].label);
Serial.println(ranges[sensorState].label);
sensors[sensorId].last_state = sensorState;
}
}
screensaver part where I think I’m going wrong
void loop()
{
if ( ENABLE_LCD == true )
{
// Get snapshot of time
unsigned long currentMillis = millis();
if ( millis() > (lastActivityTime + (1000 * lcd2_timeout)))
{
lcd2.noBacklight();
}
}