A simple and nice to use LCD voltmeter with resetable min max function.
/*
single channel voltmeter
range 0 to 5 Volts in 1023 steps
min max recorder resetable with pushbutton
LCD display driven in "4 bits" mode
R/W operation is not used; LCD pin 5 must be connected to ground
Reset button (optional) between Arduino's digital port 6 and ground
Analog signal shall be connected to Arduino's analog port 0
no need for additional libraries
no rights, no warranty, no claim just fun
didier longueville, december 2007
*/
// hardware related constants
#define analogPin 0
#define resetPin 6
#define ledPin 13
// lcd related constants
#define nbrCharPerLine 16 // update depending on LCD
// must be at least 16 characters per line
#define nbrLines 2 // must be 2 lines at least
#define left 0
#define right 1
#define invisible 0
#define visible 1
// declare variables
int RS = 7; // registry select LCD pin 4
int EN = 8; // enable LCD pin 6
int DB[] = {9,10,11,12}; // data bits LCD pins 11, 12, 13 and 14
char stringBuffer[nbrCharPerLine + 1]; // this is the working string buffer
int analogValueMax = 0;
int analogValueMin = 1023;
void setup (void) {
// Serial.begin(9600);
for (int i = 7;i <= 13;i++) {
pinMode(i,OUTPUT);
digitalWrite(i,LOW);
}
pinMode(resetPin,INPUT); // define reset pin
digitalWrite(resetPin, HIGH); // turn on pullup resistor
LcdInitialize(); // Initialize lcd
LcdUnderlineCursor(invisible); // hide underline cursor
}
void loop (void) {
// check if the reset button has been pushed (quick and dirty)
if(digitalRead(resetPin) == LOW) {
// reset variables
analogValueMin = 1023;
analogValueMax = 0;
// display status
BufferClear(); // clear buffer
// 1234567890123456
BufferInsertStringValue("min now max ",1);
LcdSendString(1);
BufferClear(); // clear buffer
// 1234567890123456
BufferInsertStringValue("-.-- -.-- -.--",1);
LcdSendString(2);
delay (1000); // time to read
}
int analogValue=analogRead(analogPin);
analogValueMin = min(analogValue,analogValueMin); // record min value
analogValueMax = max(analogValue,analogValueMax); // record max value
BufferClear(); // clear buffer
// 1234567890123456
BufferInsertStringValue("min now max ",1);
LcdSendString(1); // display converted value on line 1
BufferClear(); // clear buffer
// 1234567890123456
BufferInsertStringValue(" . . . ",1);
BufferInsertNumValue(analogValueMin,5,2,2);
BufferInsertNumValue(analogValue,5,2,8);
BufferInsertNumValue(analogValueMax,5,2,14);
LcdSendString(2); // display converted value on line 2
// blink status led
LedSendPulse(500);
}
/*
Lcd related functions:
LcdClearScreen
LcdCursorHome
LcdDisplay
LcdInitialize
LcdMoveCursor
LcdScrollDisplay
LcdSendBits
LcdSendByte
LcdSetLine
LcdUnderlineCursor
*/
void LcdClearScreen() {
LcdSendCommand(B00000001,8); // 0x01
}
void LcdCursorHome() {
LcdSendCommand(B00000010,8); // 0x02
}
void LcdDisplay(boolean status) {
if (status) {
LcdSendCommand(B00001100,8); // 0x0C Restore the display (with cursor hidden)
}
else {
LcdSendCommand(B00001000,8); // 0x08 Blank the display (without clearing)
}
}
void LcdInitialize() {
delay(40); // specification says > 30ms after power on
// function set
LcdSendCommand(B0010,4); // 0x2
LcdSendCommand(B00101000,8); // 0x28
delayMicroseconds(50); // specification says > 39�s
// display on/off control
LcdSendCommand(B00001110,8); // 0x0E
delayMicroseconds(50); // specification says > 39�s
// clear display
LcdSendCommand(B00000001,8); // 0x01
delay(2); // specification says > 1.53ms
// entry mode set
LcdSendCommand(B00000110,8); // 0x06
delay(2); //
}
void LcdMoveCursor(boolean dir, int steps) {
for (int j = 1;j <= steps;j++) {
if (dir) {
LcdSendCommand(B00010100,8); // 0x14
}
else {
LcdSendCommand(B00010000,8); // 0x10
}
}
}
void LcdScrollDisplay(boolean dir, int steps,int pause) {
for (int j = 1;j <= steps;j++) {
if (dir) {
LcdSendCommand(B00011110,8); // 0x1E
}
else {
LcdSendCommand(B00011000,8); // 0x18
}
delay(pause);
}
}
// set bits on Lcd and trigger enable pulse
void LcdSendBits(int value){
digitalWrite(EN,HIGH);
delayMicroseconds(5); // pause 1.4 �s according to datasheet
for (int i = 0;i <= 3;i++) {
digitalWrite(i + 9,value & 01); // set bit value
value >>= 1; // shift bits
}
digitalWrite(EN,LOW); // toggle enable line transfer bits
delayMicroseconds(5); // pause 1.4 �s according to datasheet
}
// send one byte onto LCD
void LcdSendByte(int value) {
constrain(value,32,126); // value shall be no less than 32 and no more than 126 (printable characters)
digitalWrite(RS,HIGH);
LcdSendBits(value >> 4); // msw
LcdSendBits(value); // lsw
}
// send command to LCD display
void LcdSendCommand(int value,int nbrBits) {
digitalWrite(RS,LOW);
if (nbrBits == 8) {
LcdSendBits(value >> 4); // msb
}
LcdSendBits(value); // lsb
}
void LcdSendString(int lineIndex){
constrain(lineIndex,1,nbrLines); //line index shall be no less than 1 and no more than nbrLines
if (lineIndex == 1) {
LcdSendCommand(B10000000,8); // 0x80
}
else if (lineIndex == 2) {
LcdSendCommand(B11000000,8); // 0xC0
}
// write working string buffer content onto LCD
for (int i = 0;i <= nbrCharPerLine;i++) {
LcdSendByte(stringBuffer[i]);
}
}
void LcdSetLine(int lineIndex){
constrain(lineIndex,1,nbrLines); //line index shall be no less than 1 and no more than nbrLines
if (lineIndex == 1) {
LcdSendCommand(B10000000,8); // 0x80
}
else if (lineIndex == 2) {
LcdSendCommand(B11000000,8); // 0xC0
}
}
void LcdUnderlineCursor(boolean status) {
if (status) {
LcdSendCommand(B00001110,8); // 0x0E
}
else {
LcdSendCommand(B00001100,8); // 0x0C
}
}
/*
led related functions:
LedSendPulse
*/
// pulseDelay value is equal to the total pulsing time
void LedSendPulse(int pulseDelay){
digitalWrite(ledPin,HIGH);
delay(pulseDelay/2);
digitalWrite(ledPin,LOW);
delay(pulseDelay/2);
}
/*
working string buffer functions:
BufferClear
BufferInsertNumValue
BufferInsertStringValue
*/
// clears the content of the working string buffer (global variable)
void BufferClear (){
for (int i = 1;i <= nbrCharPerLine;i++){
stringBuffer[i - 1] = 32; // blank buffer content with space characters
}
}
// insert converted float in the working string buffer (global variable)
void BufferInsertNumValue (int digitalValue,int fullScaleValue,int decimalPlaces,int decimalSeparatorPosition) {
unsigned long integerValue=((unsigned long)( digitalValue * fullScaleValue) * PowerInteger(10,decimalPlaces)) / 1023;
int remainder = 0;
stringBuffer[decimalSeparatorPosition - 1] = 46;
// decimals
for (int i = 1;i <= decimalPlaces;i++){
int asciiCode = (integerValue % 10) + 48;
stringBuffer[decimalSeparatorPosition + decimalPlaces - i] = asciiCode;
integerValue/=10;
}
// integers
int i = 0;
do {
i++;
int asciiCode = (integerValue % 10) + 48;
stringBuffer[decimalSeparatorPosition - 1 - i] = asciiCode;
integerValue /= 10;
} while (integerValue != 0);
}
// update the working string buffer (global variable)
// startingPosition is base 1
void BufferInsertStringValue(char * s,int startingPosition) {
int stringLength=strlen(s)-1;
for (int i = 0;i <= stringLength;i++) {
stringBuffer[startingPosition + i - 1] = s[i];
}
}
/*
general purpose functions:
PowerInteger
*/
int PowerInteger(int mantissa,int exponent){
int result; // declare result variable
if (exponent == 0) {
result = 1;
}
else {
result=mantissa;
for (int i = 2;i <= exponent;i++) {
result *= mantissa;
}
}
return result;
}