Go Down

Topic: LCD Display Random Characters 16x2 output variable data (data,DEC) (Read 5636 times) previous topic - next topic

nbowers

Mar 21, 2014, 07:34 am Last Edit: Mar 21, 2014, 05:49 pm by nbowers Reason: 1
Hello,
I have made a successful tachometer measuring an erector set motor's speed (rpm) using an ir led and ir detector diode. The original program is set to display the data i.e. rpm via the serial monitor.  I have been trying for hours to alter the code to also display on a 16x2 lcd display instead or better yet both.  All I get is the "LCD Ready..." displayed from the setup sequence then random jumbled numbers as the measurements.  These random characters change as the speed changes.  Serial Monitor still displays the correct information.  Can data not be displayed on both simultaneously?  I know its something simple.  Serial.println(rpm,DEC); print to the serial monitor and lcd.print(rpm,DEC); should print the exact data to the lcd Correct?  (with a delay then clear lcd and repeat).  I have used an lcd to display text in quotations like lcd.print("You're a Loony");  but never variable changing data.  Here is the edited tachometer Code I have so far:

Code: [Select]
/*
* Optical Tachometer
*

* The IR LED is connected to pin 13 and ran continually. A status LED is connected
* to pin 12. Pin 2 (interrupt 0) is connected across the IR detector.
*
*
*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 1);

int ledPin = 13;                // IR LED connected to digital pin 13
int statusPin = 8;             // LED connected to digital pin 12

volatile byte rpmcount;
volatile int status;

unsigned int rpm;

unsigned long timeold;

void rpm_fun()
{
  //Each rotation, this interrupt function is run twice, so take that into consideration for
  //calculating RPM
  //Update count
     rpmcount++;
     
  //Toggle status LED  
  if (status == LOW) {
    status = HIGH;
  } else {
    status = LOW;
  }
  digitalWrite(statusPin, status);
}

void setup()
{
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("LCD Ready...");
  delay(1000);
  lcd.clear();
 
  Serial.begin(9600);
  Serial.println("Serial Monitor Ready...");
  delay(1000);
  //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
  //Triggers on FALLING (change from HIGH to LOW)
  attachInterrupt(0, rpm_fun, FALLING);
 
  //Turn on IR LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
 
  //Use statusPin to flash along with interrupts
  pinMode(statusPin, OUTPUT);

  rpmcount = 0;
  rpm = 0;
  timeold = 0;
  status = LOW;
}

void loop()
{

  //Update RPM every second
  delay(1000);
  //Don't process interrupts during calculations
  detachInterrupt(0);
  //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
  //happened once per revolution instead of twice. Other multiples could be used
  //for multi-bladed propellers or fans
  rpm = 30*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
 
    //Write it out to serial port
  Serial.println(rpm,DEC);
       //write to lcd too
   lcd.clear();
    lcd.print(rpm,DEC);
    delay(10);
    lcd.clear();
   


 
  //Restart the interrupt processing
  attachInterrupt(0, rpm_fun, FALLING);

 }

bperrybap

look the code in loop and think about how it is updating the display.

You wait a long time (1 second)
you do some stuff and calculate some stuff,
clear the display
write to the display
wait 10 milliseconds
clear the display.

Then repeat.

So if you look at that, the majority of the time the display will
be cleared because you clear it almost immediately after you wrote to it,
then you delay for a long time (1 second) when the display is cleared.
You aren't going to see anything doing that.
The human eye needs close to 16ms to see things without flicker.
Also, the LCD panel needs 15 to 20ms to change the liquid molecules to darken
the pixels.

Think about all this for a moment, the solution is actually quite simple.
hint: the display should contain what you want to see when the long
delay is happening.

--- bill





nbowers

#2
Mar 21, 2014, 08:22 am Last Edit: Mar 21, 2014, 05:48 pm by nbowers Reason: 1
Right, I had this correct earlier then messed it up and couldn't tell what i did.  So I simply moved the lcd.clear below the delay(1000) and took out the random delay(10) I had tossed in there.  starts displaying "0" then still I get jumbled numbers once reading start to display (on serial monitor).  Oh and all connections are great and all solder points on the lcd display are great.

Code: [Select]
void loop()
{
  //Update RPM every second
  delay(1000);
  lcd.clear();
  //Don't process interrupts during calculations
  detachInterrupt(0);
  //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
  //happened once per revolution instead of twice. Other multiples could be used
  //for multi-bladed propellers or fans
  rpm = 30*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
 
    //Write it out to serial port
  Serial.println(rpm,DEC);
       //write to lcd too
    lcd.print(rpm,DEC);
 
  //Restart the interrupt processing
  attachInterrupt(0, rpm_fun, FALLING);
 }

Paul__B

OK, now go back to each of your previous posts, select "modify" and highlight the code section and click the [ # ] icon above the text window to mark up your code as such.

That will make it easier for all of us to look through it.

nbowers

Done, Yes that does help with reading everything thanks.  Any suggestions on solving the random character issue?

floresta

Try getting rid of the lcd.clear().

After writing to the serial monitor try this:

Code: [Select]

  lcd.setCursor(0,0);
  lcd.print("          ");
  lcd.setCursor(0,0);
  lcd.print(rpm,DEC);


Don

nbowers

Don, I tried your code edit and I still get scrambled characters.  With the code I have now I get a "0" displayed then 3 - 4 characters like those seen in the photo attached.  These characters change each time the serial monitor prints a new rpm.

bperrybap

I don't see anything wrong with your code.
I would like to know which AVR/ Arduino board variant you are using as there is some
really strange stuff that goes on down in the attach/detach interrupt Arduino core code
depending on which chip/variant you are using.
(I'm assuming you are not using a 32u4 based board like Leonardo)

In the mean time, I'd be curious if you see the issue if you change the LCD d6 pin
to use some other Arduino pin than 3 (and don't pick 2 either).


--- bill

MAS3


Code: [Select]

LiquidCrystal lcd(12, 11, 5, 4, 3, 1);

void setup()
{  
  Serial.begin(9600);
  Serial.println("Serial Monitor Ready...");
}



And:


These characters change each time the serial monitor prints a new rpm.


Did you actually connect the display the way you declared it ?
And you're sending to serial ?

Pin 1 is serial TX, and you are also using it as an LCD pin.
That's your conflict.
Use other pins for your display (perhaps you should shift them all one position).
Remember to only use pins 0 and 1 if you have no other options or exactly know what you're doing in the future.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

nbowers

Problem Solved! Thanks bill.  Either pin 3 and/or 1 on my arduino uno R3 is faulty.  Changed the lcd pin setup to LiquidCrystal lcd(12, 11, 7, 6, 5, 4);  and It works like a charm!

nbowers


bperrybap

MAS3 figured it out.
Pin 1 is your problem.
While the serial port  data is sent over USB, the serial pins are still being used
which are Arduino pins 0 and 1
So while pin 1 looks "free" since you didn't explicitly specify it,
it is actually in use by the HardwareSerial library.

--- bill

Go Up