I'm interfacing a LCD with a consumer, prompting to enter some text via serial.
I have some default text (easy enough), but I will like to limit input to 8 character strings. What should I do:
Define input as char text[8].
Define input as String.
In either case, how to limit Serial.read() to read only 8 chars? (If loop with string.lenght == 8 )? or is there a more efficient way?
Neither. 8 characters need a 9 element array, so there is room for the terminating NULL.
In either case, how to limit Serial.read() to read only 8 chars?
That depends on what you intend to do if there is more than 8 characters sent. I would read and store the first 8, and read and discard the rest until the end-of-packet marker arrived.
Neither. 8 characters need a 9 element array, so there is room for the terminating NULL.
Ok, got it... Forgot about the NULL.
Are you suggesting me to go char text[9] instead of string?
PaulS:
In either case, how to limit Serial.read() to read only 8 chars?
That depends on what you intend to do if there is more than 8 characters sent. I would read and store the first 8, and read and discard the rest until the end-of-packet marker arrived.
I really want users to think through and only input 8 characters. If there is more than 8 chars, warn user and ask again. Only 'save' (change variable) if the input is 3<=text>=8, then LCD print some info with the user input!
Are you suggesting me to go char text[9] instead of string?
A string is a NULL terminated array of chars. A String, on the other hand, is a horrid beast that has no place on the Arduino.
I really want users to think through and only input 8 characters. If there is more than 8 chars, warn user and ask again. Only 'save' (change variable) if the input is 3<=text>=8, then LCD print some info with the user input!
How will you know when they are done with input? Where is the input coming from? You can count the characters received, and store the first 8 in the array. If the end-of-packet marker arrives before you get to 9, then use the data. Otherwise, reject it. It ain't rocket surgery.
You could overload the function to add in another parameter, or put a null in the source at the position you want it to stop copying at.
If needed, store the 8th character in a temp, replace with null, when done just put the temp char back.
You could read and count the characters until you reach the terminator, while you store the characters in a character array.
The terminator could be Carriage return, or other special you choose
If the count is >8, warn the user, ans start over.
Erni:
You could read and count the characters until you reach the terminator, while you store the characters in a character array.
The terminator could be Carriage return, or other special you choose
If the count is >8, warn the user, ans start over.
This sounds great, though I'm not sure how to implement the If. I have this so far:
char Name[9]; // My Data array
char inChar; // Where to store the character read
byte index = 0; // Index into array; where to store the character
if(index < 8){
inChar = Serial.read();
Name[index] = inChar; // Store it
index++; // Increment where to write next
Name[index] = '\r'; // Carriage to terminate the string
}
else{
Serial.println("Invalid Input, please enter 3 to 8 characters");
}
That was something like that I was thinking, although I think that the below test Sketch is more likely what you want.
You need to clear the Name array in case of wrong number of entrys, and end the Array with the null terminator.
There might be some errors in the sketch, but it explains better than words what I meant.
char Name[9]; // My Data array
char inChar; // Where to store the character read
byte index = 0; // Index into array; where to store the character
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available()>0){
inChar = Serial.read();
Name[index] = inChar; // Store it
if (index>8){
Serial.println("Invalid Input, please enter 3 to 8 characters");
}
if (int(Name[index])==13){ //If Carriage return has been reached
Serial.println(Name);
index=0;
}
index++; // Increment where to write next
}
}
Keep in mind that you need to provide a large enough array to hold what the user typed, and that that may be more than 8 bytes.
jajaja I found out about this already the hard way, with this code if I enter 123456789 I receive back two lines, 1st: 12345678 and 2nd: 92345678 so it overwrites the array.
char Name[9]; // My Data array
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Please Enter your Name: ");
}
void loop() {
while (!Serial.available()); // Wait for characters
Serial.readBytes(Name, 8);
Serial.println(Name);
}
Is there a way to avoid overwriting? ... not sure if I should go back to the other suggestions.
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
So, you know how many bytes were received. You can NULL terminate the array after that number of characters. That would make the output you saw "12345678" and "9".
I think a better approach is to use readBytesUntil() and send an EXPLICIT end of packet marker (the Serial Monitor can do that automatically). Then, simply check the number of bytes received.
tavovalencia:
Is there a way to avoid overwriting? ... not sure if I should go back to the other suggestions.
Some code posted earlier showed how to read characters one by one and append them to the array, incrementing an index variable that held the length of the string received so far.
All you need to do is add a check that the array is not already full, before you append another character to the string.
if (Serial.available()>0)
{
inChar = Serial.read();
if(index < 7)
{
Name[index++] = inChar; // Store it
Name[index] = 0; // append null-terminator
// ... etc
}
else
{
// buffer is already full - discard the character
}
}