Voltage reference with LCD

Hi

I have my lcd setup to display voltage referenced on A0 input, for using a battery monitoring with my project, the idea is for the lcd to not display anything while the voltage is above the threshold of 3volts and then display the voltage for 2 seconds and then clear the lcd. After the voltage drops below the threshold and after the delay (have tried using delay and mills) i can't get the lcd to clear.

See code

/*
 

// 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);

unsigned long time;
const int analogPin = A0;    // pin that the sensor is attached to
const int ledPin = 13;       // pin that the LED is attached to
const int threshold = 3;   // an arbitrary threshold level that's in the range of the analog input


void setup() {
  pinMode(ledPin, OUTPUT);
    // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // declare pin 9 to be an output:
  pinMode(6, OUTPUT);  
  analogWrite(6, 90);//contrast   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
 

}

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // if the analog value is high enough, turn on the LED:
  if (voltage < threshold) {
  lcd.setCursor(1, 0);
  // Print a message to the LCD.
  lcd.print("Battery Volts");
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(6, 1);
  // print the number of seconds since reset:
  lcd.print(voltage);
  digitalWrite(ledPin, LOW);
  delay(2500);
  lcd.clear();
  } 
  else {
  digitalWrite(ledPin, HIGH);
    //lcd.clear();
   
  }


}

The clear works fine, if the voltage goes back above 3

Any help would be appreciated.

You didn't add any code to prevent the 2.5 seconds of display from repeating immediately if the voltage was still low. You need to set a flag when you have displayed your voltage. Don't display the voltage if the flag is set. Clear the flag when the voltage is high again.

I have attempted to add the flags into the current code as well as change delay for millis, but still can't get the LCD to clear after the the count and now the display is now faint and missing characters

//Voltage reference code to display voltage on LCD it has fallen below the set threshold and for the time define by millis

// 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);

boolean lowbatt = false;
unsigned long Timer;   //ALWAYS use unsigned long for timers, not int
const int analogPin = A0;    // pin that the sensor is attached to
const int ledPin = 13;       // pin that the LED is attached to
const int threshold = 3;   // an arbitrary threshold level that's in the range of the analog input


void setup() {
  pinMode(ledPin, OUTPUT);
    // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // declare pin 9 to be an output:
  pinMode(6, OUTPUT);  
  analogWrite(6, 90);//contrast   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
 

}

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // if the analog value is low enough:
  if (voltage < threshold) {
  Timer = millis();   //set timer 
  lcd.setCursor(1, 0);
  // Print a message to the LCD.
  lcd.print("Battery Volts");
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(6, 1);
  // print voltage on A0:
  lcd.print(voltage);
  digitalWrite(ledPin, LOW);
  lowbatt = true;
  if (millis()-Timer >= 2500UL);  //timer expired
  if (lowbatt = true); lcd.clear();
   
 
  } 
  else {
  digitalWrite(ledPin, HIGH);
    lcd.clear();
    lowbatt = false;
  }


}

i can't work out if it the mills code or the setting of the flags thats wrong or am i missing something else

An LCD panel in of itself doesn't draw much current and a driver transistor to manage the backlight is a simple thing to do.
For that matter You Could just use a PNP transistor from a digital pin on the Arduino to turn off power to the whole LCD panel...
Rather than trying to control the contrast with the Arduino and save yourself a lot of code grief...
For that matter the Arduino Could be the VCC for the contrast pin... or you could simply "Gate" the contrast off with a transistor.
As I remember If you pull the pin about 2 - 3V high it will turn off the LCD contrast as that pin wants to be about .5 to 1V positive and any higher voltage will blank the display...
All are easy things to do and much easier than trying to PWM the contrast pin.
Although your idea is certainly do-able it is a whole lot more complication than is required... IMO
The methods I mentioned would be my first choice and PWM control of the device would be a method I would study real hard to avoid as it is too much code for too little a problem.
Occams Razor is a useful philosophy, I have found... mostly the hard way thus my tag line.
Here is a good reference from Wikihttp://en.wikipedia.org/wiki/Occam's_razor. Try reading it and see if you can't simplify things...
Fewer things to go wrong in the end, Most likely.

Doc

thanks for your input Doc, if i understand you correctly, your actually talking about turning off the lcd?

this wouldn't fit with the overall view of how i what this piece of code to fit into the overall project that i have in mind, for example i would like to have my main code with this code sat in the background and only appearing for a set amount of time when the batt volt is below the threshold and then returning to the main display, run by the main code

i have got the timer working, but lcd.clear() only half clears the display, unlike when the voltage returns above the threshold when the display clears completely

any ideas

code as it is now: -

#include <LiquidCrystal.h>
 
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
boolean lowbatt = false;
unsigned long Timer;   //ALWAYS use unsigned long for timers, not int
const int analogPin = A0;    // pin that the sensor is attached to
const int ledPin = 13;       // pin that the LED is attached to
const int threshold = 3;   // an arbitrary threshold level that's in the range of the analog input
 
 
void setup() {
  pinMode(ledPin, OUTPUT);
    // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // declare pin 9 to be an output:
  pinMode(6, OUTPUT); 
  analogWrite(6, 90);//contrast  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
 
}
 
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // if the analog value is low enough:
  if (voltage < threshold)
  {
      // If we currently have good battery, then make a note of when
      // we went bad!
      if ( lowbatt == false )
      {
            Timer = millis();   //set timer
      }
 
      lcd.setCursor(1, 0);
      // Print a message to the LCD.
      lcd.print("Battery Volts");
      // set the cursor to column 0, line 1
      // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(6, 1);
      // print voltage on A0:
      lcd.print(voltage);
      digitalWrite(ledPin, LOW);
      lowbatt = true;

       
  }
  else
  {
      // This will clear the display if the voltage is great. So that's okay.
      digitalWrite(ledPin, HIGH);
      lcd.clear();
      lowbatt = false;
  }
 
  // Now, let us clean the display if we are over the timer condition.
 
  if ( lowbatt == true )
  {
      // So we know that the battery is flagged as low.
      // Check the timer to see if we want to clear the screen
      if (millis()-Timer >= 4000UL)
      {
            // Just clear the display!
            lcd.clear();
      }
  }
}

Yes I did read the original post and I was referring to the contrast setting

analogWrite(6, 90);//contrast

I mistakenly thought you were blanking the display as part of your sleep mode and that was why I mentioned powering the LCD from a Proc. Pin and the noise about the back-light.
Look for a timing issue in the LCD library I read somewhere in this forum that there is a timing issue where you need a little more delay internal to the liquid crystal lib's and "Certain LCDs". I have some Lcd's left over from an old project that are a serial Pic backpack for the LCD and the guy packed a 4K7 resistor (Vcc to contrast and 330R from contrast to ground) PH Anderson's LCD117 Kit. I never saw anyone complain that their LCD wasn't working properly. My comments were based on the idea that any reason to control the contrast from the proc was just that and not a replacement for a pot. In reading your code I see now where you set the pin mode and analogwrite the contrast level???. Based on the assumption that your Vcc for the LCD is correct and stable then there is a possibility that you have an LCD panel with timing's that are on the edge of the Liquid Crystal Lib as I mentioned above. You could loop this code in a while loop and the battery voltage could be the while condition test... running "While the battery voltage is out of spec" and passing the while test when battery was good...

Doc

Try this version:

#include <LiquidCrystal.h>

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

boolean lowbatt = false;
unsigned long Timer;   //ALWAYS use unsigned long for timers, not int
const int analogPin = A0;    // pin that the sensor is attached to
const int ledPin = 13;       // pin that the LED is attached to
const float threshold = 3.0;   // an arbitrary threshold level that's in the range of the analog input


void setup() {
  pinMode(ledPin, OUTPUT);
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // declare pin 9 to be an output:
  pinMode(6, OUTPUT); 
  analogWrite(6, 90);//contrast  
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(analogPin);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // if the analog value is low enough:
  if (voltage < threshold)
  {
    if (!lowbatt)  // Just going low
    {
      Timer = millis();
      lowbatt = true;

      lcd.setCursor(1, 0);
      lcd.print("Battery Volts");

      lcd.setCursor(6, 1);
      lcd.print(voltage);

      digitalWrite(ledPin, LOW);
    }
    else  // lowbat flag is already set
    {
      // After 4 seconds with lowbatt set, clear the LCD
      if (millis()-Timer > 4000UL)
        lcd.clear();
    }
  }
  else  // Voltage greater than threshold
  {
    // This will clear the display if the voltage is great. So that's okay.
    digitalWrite(ledPin, HIGH);
    lowbatt = false;
  }
}