Hi,
New guy here to the Arduino world and forum.
Using an Uno with a quadrature rotary encoder and a 2x8 LCD.
I have everything working great, counts up and down accurately with interrupts and pull ups installed. Only problem is the LCD will hold values "0" in the spaces where there is no longer a digit needed.
Example, if I turn the encoder to increment to 1055 then reverse the rotation to count down, when I hit 999, it will show 9990 and will not drop the last zero. It will continue to hold 0's all the way down to where the value "1" will show 1000.
Attached is my entire code feel free to pick it apart as needed, I'm pretty green to the language!
Thanks in advance for any advice.
Vince
/* Quadrature Encoder
* Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
int val;
int encoder0PinA = 2;
int encoder0PinB = 3;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;
int resetp = 8;
void setup() {
attachInterrupt(0, countPulse, CHANGE);
pinMode (encoder0PinA,INPUT);
pinMode (encoder0PinB,INPUT);
pinMode (resetp, INPUT);
//Serial.begin (9600);
lcd.begin(8, 2);
lcd.print("Pulses");
}
void loop() {
lcd.setCursor(0, 1);
lcd.print(encoder0Pos);
}
void countPulse(){
encoder0PinALast = n;
if (digitalRead(resetp) == HIGH){
encoder0Pos = 0;
}
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH)) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos--;
} else {
encoder0Pos++;
}
}
}
Yes it will do that. To cure it print a space after the number.
It does it because it only print the numbers you ask it to, so 999 is printed leaving the last digit you haven't printed over.
Thanks Mike, I'll give it a try tonight.
You could also change this:
void loop() {
lcd.setCursor(0, 1);
lcd.print(encoder0Pos);
}
to this:
void loop() {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(encoder0Pos);
}
Don
You could also add printf() support to the Print class which would allow better/easier formatting.
http://playground.arduino.cc/Main/Printf
(The latest Teensy code has this already built in)
It does come with a cost of a few k of flash, but if you are not tight on flash then it can be worth it.
This will allow you do things like:
lcd.printf("%4d", encoder0Pos); // print an integer in a fixed width 4 position field - left padded with spaces
lcd.printf("%04d", encoder0Pos); // print an integer in a fixed width 4 position field - left padded with zeros
You can also left justify, using other format specifiers.
--- bill
Another thing to consider is justification.
The other solutions above will solve the issue of not fully overwriting the previous characters,
however, they do left justification. This is not my preference for numbers that can be changing as
the base position of the 1's column is shifting location on the display.
For example, in your case, if you were to rotate the knob very quickly, the numbers
will potentially move left and right as the magnitude of the number changes.
i.e. when displaying 999 vs 1000 the 1 and 9 are landing in the same postion
but represent different magnitudes.
My preference is to right justify so that you have either leading spaces, or zeros
so that the magnitude digits remain in a fixed position.
If you don't want to use printf() you can also do this using the exiting Arduino Print class
functions, but it requires adding some code to check on the magnitude of the number and printing
extra spaces or zeros prior to printing the number to overwrite the positions that don't exist
for the about to be printed number.
example:
if(x < 1000)
lcd.print(" ");
if(x < 100)
lcd.print(" ");
if(x < 10)
lcd.print(" ");
lcd.print(x);
It is a bit clunky, which is why I prefer using printf() when code space allows.
--- bill
bperrybap:
It is a bit clunky, which is why I prefer using printf() when code space allows.
Because exactly the same "clunky" algorithm, is actually built into printf - that's why it takes so much program space. 
Thanks for all the options, I've tried all of them just so I can learn new and different methods!
@ Bill, I ended up using your suggestion just a little modified and it works great all the way up past 10k, not too much code for a great solution. Thanks for the tips!
if(encoder0Pos < 10000)
lcd.print(" ");
if(encoder0Pos < 1000)
lcd.print(" ");
if(encoder0Pos < 100)
lcd.print(" ");
if(encoder0Pos < 10)
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(encoder0Pos);