Writing unsigned long int to LCD1602 deviates from serial monitor

Okay, once more I am here to pester the gurus.

I am doing a mechanical RPM counter for a project. It's very simple, it just used millis() to see the time between two successive switch closures. I have it running nicely and on the Serial I get this output:

CurrentMillis: 8686 LastMillis: 8601 DeltaMillis: 85 Hits: 13

etc.

But when I get the output onto a LCD, I don't get that nice DeltaMillis, but something like in the picture. The D value should be around the same value as in the DeltaMillis in the text above.

So, my question is, how do I get the LCD to show the same number as the DeltaMillis on the serial monitor?

Many thanks!

This is the code (feel free to ignore all servo related stuff, it's not vital here:

#include <Servo.h>
#include <Math.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

Servo driverServo;
int backSwitchPin = 4;
int driverServoPin = 8;
int backSwitchDown = false;
int sensorValue;
int hits = 0;
float signalLength;
unsigned long lastMillis = 0;
unsigned long currentMillis = 0;
int deltaMillis = 0;

void setup() {
  lcd.init(); 
  lcd.backlight(); 
  Serial.begin(9600);
  pinMode(backSwitchPin, INPUT);
  pinMode (driverServoPin, OUTPUT);
  digitalWrite(backSwitchPin, HIGH);
  driverServo.attach(driverServoPin);
}

void loop() {
  driveForward();
  workLCD();
  if (BackSwitchDown()) {
    Serial.print("   CurrentMillis: ");
    Serial.print(currentMillis);
    Serial.print("   LastMillis: ");
    Serial.print(lastMillis);
    Serial.print("   DeltaMillis: ");
    Serial.print(deltaMillis);
    Serial.print("   Hits: ");
    Serial.println(hits);
    hits++;
  }
  else {
  }
}

void workLCD() {
  lcd.setCursor(0, 1);
  lcd.print("Hits: ");
  lcd.print(hits); 
  lcd.setCursor(0, 0);
  lcd.print("D: ");
  lcd.print(deltaMillis);
  lcd.setCursor(0, 2);
  lcd.print("Curr: "); 
  lcd.print(currentMillis); 
  lcd.setCursor(0, 3);
  lcd.print("Last: ");
  lcd.print(lastMillis); 
}


void driveForward() {
  sensorValue = analogRead(A0);
  signalLength = map(sensorValue, 20, 1023, 1495, 1800);
  driverServo.writeMicroseconds(signalLength);
  delay(20);
}


boolean BackSwitchDown() {

  backSwitchDown = digitalRead(backSwitchPin);
  if (LOW == backSwitchDown) {
    currentMillis = millis();
    deltaMillis = currentMillis - lastMillis;
    lastMillis = currentMillis;
    return true;

  }
  else {
    return false;
  }
}

20180112_150255[1].jpg

try changing this line

unsigned long deltaMillis = 0;

I did, no change.

THe BackSwitchDown() changes the values and then you print them to Serial
so Serial has the last values.

Hits is updated after serial prints so the next LCD print will definitely print another value for hits.
so that should be fixed.

backSwitchDown is both the name of an int (initialized as boolean) and a function.
Compiler should see that but it is not really good practice...

Try this version, I moved some functionality around to better see what happens..

#include <Servo.h>
#include <Math.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

Servo driverServo;

int backSwitchPin = 4;
int driverServoPin = 8;
bool backSwitchDown = false;

int sensorValue;
int hits = 0;

float signalLength;

unsigned long lastMillis = 0;
unsigned long currentMillis = 0;
unsigned long deltaMillis = 0;

void setup()
{
  lcd.init();
  lcd.backlight();

  Serial.begin(9600);

  pinMode(backSwitchPin, INPUT);
  digitalWrite(backSwitchPin, HIGH);

  pinMode (driverServoPin, OUTPUT);
  driverServo.attach(driverServoPin);
}

void loop() {
  driveForward();
  workLCD();
  if (BackSwitchDownPressed())
  {
    updateVars();
    workSerial();
  }
}

void updateVars()
{
  currentMillis = millis();
  deltaMillis = currentMillis - lastMillis;
  lastMillis = currentMillis;
  hits++;
}


void workSerial()
{
  Serial.print("   CurrentMillis: ");
  Serial.print(currentMillis);
  Serial.print("   LastMillis: ");
  Serial.print(lastMillis);
  Serial.print("   DeltaMillis: ");
  Serial.print(deltaMillis);
  Serial.print("   Hits: ");
  Serial.println(hits);
}


void workLCD()
{
  lcd.setCursor(0, 1);
  lcd.print("Hits: ");
  lcd.print(hits);
  lcd.setCursor(0, 0);
  lcd.print("D: ");
  lcd.print(deltaMillis);
  lcd.setCursor(0, 2);
  lcd.print("Curr: ");
  lcd.print(currentMillis);
  lcd.setCursor(0, 3);
  lcd.print("Last: ");
  lcd.print(lastMillis);
}


void driveForward()
{
  sensorValue = analogRead(A0);
  signalLength = map(sensorValue, 20, 1023, 1495, 1800);
  driverServo.writeMicroseconds(signalLength);
  delay(20);
}


boolean BackSwitchDownPressed()
{
  backSwitchDown = (digitalRead(backSwitchPin) == LOW);
  if (backSwitchDown)
  {
    return true;
  }
  return false;
}

Thanks muchly! I will be sure to try this when I go back to work on Wednesday.

void workLCD()
{
  lcd.setCursor(0, 1);
  lcd.print("Hits: ");
  lcd.print(hits);
  lcd.setCursor(0, 0);
  lcd.print("D: ");
  lcd.print(deltaMillis);
  lcd.setCursor(0, 2);
  lcd.print("Curr: ");
  lcd.print(currentMillis);
  lcd.setCursor(0, 3);
  lcd.print("Last: ");
  lcd.print(lastMillis);
}

For best display update speed, the unchanging test parts of this display routine should be placed in set up.

Is it just leaving old digits on the LCD ?

  lcd.setCursor(0, 0);
  lcd.print("D: ");
  lcd.print(deltaMillis);
  lcd.print("   ");   // wipe out any old digits

Yours,
TonyWilk

Tony Wilk solved it for me, many many thanks indeed!

It was really keeping old digits on the screen and I needed to write over whatever was remaining there.

The solution is now once more so obvious that I should not have bothered you at all, but as I have already, I remain grateful for all your help, folks.

+1 for Tony !