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 ?
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 ??
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
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.
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.
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.
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)?
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 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);
}
}
}