I know it is seriously big noob question but i can't figured it out where my problem is.
My target is to get a string with serial communication an use it as a simple string. In some projects this works but now i want build a new one and this dosen't work well.
So i started with a easy code an now i am very confuesed
String input = "";
char current ;
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
}
void loop() {
while(Serial.available()){
current = Serial.read();
input = input + current;
}
if(input != ""){
Serial.println(input);
input == "";
}
}
So thats the code not very impressive but impresive enough to confuse me
I think if there is a serial communication the Arduino will stuck in the while loop until the transmission ends and put every received char at the end of the input char. After communication ends my if will check it and if there is a value in input it will send it back and clear it.
But the Arduino didn't stuck in the while loop and repeat the main loop everytime so input only hold one char at the time.
You need to understand that serial is slow - at 9600 that's only 960 characters per second.
That is an age to a 16MHz processor, so as soon as there are no characters that read, it exits the while loop.
Which is most of the time.
My target is to get a string with serial communication an use it as a simple string.
So, you start by creating a String. A String and a string are not the same thing. Not even close.
I think if there is a serial communication the Arduino will stuck in the while loop until the transmission ends and put every received char at the end of the input char.
True, but since serial data arrives slowly, but is read quickly, it won't be "stuck" in that while loop long.
After communication ends my if will check it and if there is a value in input it will send it back and clear it.
Yes.
But the Arduino didn't stuck in the while loop and repeat the main loop everytime so input only hold one char at the time.
Serial data arrives slowly. It is read quickly. There is nothing wrong with the code. There IS something wrong with your expectations.
If you want to read and store the data until some terminating marker arrives, you must change the code to NOT clear the String unless if contains the terminating marker. And, don't print it until then, either.
Shouldn't be necessary with delimiters and only makes things a whole lot more complex than they need to be, here, try this:
String input = "";
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
}
void loop() {
while(Serial.available() > 0){ // While there is more to be read, keep reading
input += (char)Serial.read();
delay(1); // This is needed to prevent ... weirdness :)
}
// TADA! Now, if there was a burst of characters on the port they are all
// contained in your input string so you can now use that string in your code :)
// Your code can go here
if(input != ""){
Serial.println(input);
input == "";
}
}
Now in that code where I have put the comment // Your code can go here
you can put some conditional statements to do stuff with your string before the last part of your code sets the input string back to "" (deletes it) so an example of doing stuff might be...
// Your code can go here
if(input == "hello") {
Serial.println("Hey, you said hello! so I'm saying hello back :)");
}
If you mean that a terminal emulator sends one character at a time while you write then you are correct, this will just receive one character at a time, you could build up a string and do conditional testing on it but this code is designed to receive a complete string of text all at once.
I have a terminal emulation program for the PC that can send a complete string of text, you need to click on the 'Send' tab and then write something in one of the boxes then click on the Send ASCII button to send that string of text all at once.
Not on this occasion, no, though I have in the past.
My recollection was that it produced less object code than the "equivalent" String-based solution, and didn't have any delays.
Next time I'm in front of a PC, I'll see if I can find it again.
Cool, my reference to setting the baud rate (to 9600) was for the terminal emulator program, there is a 'port' tab where you choose the port (which can incidentally be a bluetooth virtual serial port) and in my experience if you have the PC's port set to one baudrate and the Arduino's serial port set to another you get:
Very simple serial code that will echo what is sent from the serial monitor back to the serial monitor.
//zoomkat serial echo test 7-31-2011
char input; // incoming serial data
void setup() {
Serial.begin(9600); // set serial port at desired value
Serial.println("serial echo test 0021"); // echo test
Serial.println();
}
void loop() {
if (Serial.available() > 0) { // check for serial buffer input
input = Serial.read(); // read the incoming byte:
Serial.print(input); // print the input
//Serial.println(); // print new line for better reading
}
}
Cool code zoomcat.
I find that it's always good to take it down to as simple as possible so that the user can understand it and get on and do something that works before they lose interest. They can always change it later if they need to.
In this case LordN1kon states that his objective is:
My target is to get a string with serial communication an use it as a simple string.
So he needs an array of chars, that'll be a String then
Your nice'n easy code demonstrates how to receive each char as it comes through the serial port and from there it should be easy to build up a string which can then be used as he needs.
I think a String is an expensive proposition as far as memory goes though so it will be interesting to see AWOL's technique.
I took this String-based code from earlier in the thread and compiled it for a 2009
String input = "";
void setup() {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
}
void loop() {
while(Serial.available() > 0){ // While there is more to be read, keep reading
input += (char)Serial.read();
delay(1); // This is needed to prevent ... weirdness :)
}
// TADA! Now, if there was a burst of characters on the port they are all
// contained in your input string so you can now use that string in your code :)
// Your code can go here
if(input != ""){
Serial.println(input);
input == "";
}
}
, and got a code size of 3962 bytes (IDE 1.0.5)
I took this
const byte MAX_LEN = 40;
char inputSentence [MAX_LEN + 1];
byte inputIndex = 0;
bool newInput;
void setup ()
{
Serial.begin (9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
}
void loop ()
{
if (newInput && strlen (inputSentence)) {
Serial.println (inputSentence);
newInput = false;
inputIndex = 0;
inputSentence [0] = '\0';
}
}
void serialEvent ()
{
while (Serial.available() ) {
char readChar = Serial.read ();
if (readChar == '\n') {
newInput = true;
} else {
if (inputIndex < MAX_LEN) {
inputSentence [inputIndex++] = readChar;
inputSentence [inputIndex] = '\0';
}
}
}
}
non-String, non-delaying, non-memory fragmenting, line-speed agnostic code and compiled it, and got a code size of 2030 bytes - very close to half the size.