Print data from Serial port to LCD

Hi all,

I'm haivng some problems displaying some information on a LCD. I'm reading data from a serial port which which has a 3 digit value with several decimal places.

e.g. 256.446876428476

When i use the Arduino Serial monitor is see the data coming through perfectly, but when i try and send it the lcd is just shows as -1 -1 -1 -1

This is the basic code i tried. where am i going wrong ? Also if i wanted to convert the data to 2 decimal places, how owuld i go about doing that ?

e.g 256.44

void Loop {
float TestData = Serial.read();
lcd.print (TestData);
}

Thanks,
Rich.

I'm no expert, But i am not sure using float is a good idea, just my opinion...
What happens when you try to send it back to the computer?

Float was just an example of what i'm going. I'm happy to change it to something that handles 2 decimal places.

I'm also not sending anything back to the computer, merely trying to display the values.

You need to read the interface specs for the Serial library: Serial - Arduino Reference. And look at some of the example programs referenced on that page.

Serial.read returns one byte of character data; it doesn't return integer or floating point numbers.

You are sending it back to the computer. You are first reading from the host computer over the serial (USB) connection to the Arduino. And then when you call print, you are sending data back to the host over the same USB cable.

At least that is what you are intending to do; but you haven't programmed that yet :-)!

The serial library implements a bi-directional (to/from the Arduino) communication protocol over a serial connection (the USB port on the Arduino).

You need to follow the protocol to successfully read/write data over this connection. The examples should give you a better idea of how that protocol works.

So i'm guessing becuase the serial.read only reads one byte at a time, i'll have to create an array to caputre all the bytes i need, then send the array information to the lcd ??

i'll have to create an array to caputre all the bytes i need

Not necessarily - if you know in advance what format the numbers will be in (I'm assuming they come in as ASCII), you can convert on-the-fly.

Hi Ribuck, take a look at this page:
http://itp.nyu.edu/physcomp/Labs/SerialDuplex#toc7

It does a lot of explaining about how to do what you are asking, you might want to take a look at section 7, call and response.

-1 is what Serial.read returns when there is no data.

Try:

void loop() {
  char TestData;
  if(Serial.available() )
  {
    TestData = Serial.read();
    lcd.print (TestData);  // echo the incoming character to the LCD
  }
}

Hi Mem,

That code worked thanks. the only problem i have now is that i want to limit the number e.g. 356.6668769876968769 to 2 decimal places (356.66) and print it to a certain part of the screen.

At the moment it's printing the full 356.6668769876968769 value and repeating it, filling the lcd screen when i just want it to update the value in a set position on the lcd.

I dont know how to limit the number of characters, and when i try and tell to to print to screen 0,0 i just diplays a ? symbol

i tried lcd.print (0,0);

Thanks,
Rich

if you want to move the cursor to 0,0 (Char1, Line 1) then use the setCursor command:

lcd.setCursor(0,0);
lcd.print (TestData);
lcd.print(" "); // just to clear any data left on screen from previous reading.

make sure that somewhere in setup after you have declared the lcd that you do a lcd.begin(16,2); or however many chars/lines your LCD is.

I'm guessing that you want to use the float value once you've displayed it to the LCD? If so then you will really need to buffer the data to a string then convert the string to a float.

I tried the command for the lcd.setCursor(0,0);

When i use the set cursor the lcd just displays a single ? charater now.

Using the serial monitor the last characher of the data is a ?, so it looks like it's just looping all the character at a single point instead of displaying them from 0,0 onwards.

The setCursor function should be called outside the serial buffering loop, otherwise it will just display all of the characters at position 0,0 so they will all have been printed to the screen, but you only see the last one, the ? . My bad, I should've said.

Hi Reggie,

No joy on that front, when I put the lcd.setCursor(0,0); outside of the loop it does the exactly the same thing just constantly prints the data one after another across the entire lcd.

Anyone else got any more idea's as it's driving me nuts......it's probably something quite simple or trivial in the syntax

Desperate to solve this....... :cry:

Its difficult to see what you need to change without seeing your code, can you post your sketch?

// 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);
int i = 0;

void setup()
{
lcd.begin(20, 4);
Serial.begin(9600);

}

void loop() {
char TestData;
if(Serial.available() )
{
TestData = Serial.read();
Serial.write (TestData);;
lcd.print (TestData);

}
}

so far i've managed to get it looping the data in 1 character space or repeatedly filling the entire lcd.

The test date is a number from the serial port 356.4553545345 i just want to limit the number to 356.45 and display it at a set place on the lcd.

Rich.

Your code needs a way to determine where the number ends so it knows when to stop ignoring characters after the decimal place and reset the cursor ready for the start of the next number.

What sends the number strings? Does the number string have any terminating characters – for example a carriage return? Are there always a fixed number of characters after the decimal point?

Is anything other than the number you want to print being sent (is there any data coming in that you need to ignore)?

Hi mem,

For the purposes of testing the data is being generated by a vbscript, but the real data that comes from the serial port (Com6) of the machine.

ok let me ask this another way, if i was some how able to get coming through the serial port to be only 2 decialmal places e.g. 356.55 and terminate with a carrige return, then how would we display that on an lcd at a set point ?

Ribuck, are you reading the data from EQMod or from the skywatcher(celestron) firmware? If its EQMod ask them what they use as a terminatiing character when they send out the mount position data.

Does the data always come through in that format? 123.4567891? for instance, I believe you are reading 0-360? would 0.1234567 come through as 000.1234567? this would make things easier cos you just buffer the first 6chars :slight_smile: or you could look for the .(decimal point) and buffer 2 further characters. Trouble is, I don't see anywhere in your code that you are looking for a byte that tells you what type of data is coming, from the actual serial device is there anything that is displayed before the numbers?

Once you have the data are you just displaying it to the LCD or do you need to do some stuff to the value once its on the arduino? I think you are taking position data and then using it to match the position on something else? if thats the case then it would seem that you really need to buffer the data, convert it to a real float then you can do what you like with it.

Here is some code that may help you convert an incoming string into a floating point number. It uses a function called atof to do the conversion.

You can use the converted value as a floating variable in your sketch and the print routine (in serial or lcd) will truncate the displayed output to two places after the decimal point.

You will need to replace the serial code with lcd code and set the curser position just before you print the number to the lcd.

Note that this code assumes that each number will be terminated by carriage return (ascii 13). You will have to modify the code as required to detect the end of the string if your incoming numbers are not terminated with a carriage return

void setup()
{
  Serial.begin(9600);
}

const int MAX_LEN = 12; // the max digits in the number plus decimal point 
char  strValue[MAX_LEN + 1]; // add one for the terminating null

int index = 0; 

void loop()
{
  if( Serial.available())
  {
    char ch = Serial.read();
    if(index < MAX_LEN && ch != 13) // 13 is ascii value of carriage return
    {
      strValue[index++] = ch; // add the ASCII character to the string;
    }
    else
    {
      // here when buffer full or on the first non digit      
      strValue[index] = 0;        // terminate the string with a 0
      float value = atof(strValue);  // use atof to convert the string to a float
      index = 0;                  // reset the index for the next string
      Serial.println(value);
    }  
  }
}