Serial input basics error

Hello,

I am just working on multiple serial inputs. i have came across a tutorial http://forum.arduino.cc/index.php?topic=396450 as the tutorial gives information regarding serial input basics i tried it's first example
but it doesn't give the result which i expect when i try to enter single character it displays the character but also displays the data in code twice which shouldn't happen
following is the code

// Example 1 - Receiving single characters

char receivedChar;
boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvOneChar();
    showNewData();
}

void recvOneChar() {
    if (Serial.available() > 0) {
        receivedChar = Serial.read();
        newData = true;
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChar);
        newData = false;
    }
}

when i enter 'A' it should display "This is just in ... A" but it is displaying
"This is just in ... A"
"This is just in ..."
"This is just in ..."

the output in serial monitor is

<Arduino is ready>
This just in ... A
This just in ... 

This just in ...

Carriage return , line feed.

Change the line ending setting in the serial monitor to "none"

Thanks, i changed it to No line ending and it worked but when i tried same with the multiple Character example it doesn't work i have to change it to Newline or both NL&CR any suggestion why does it happen.

JairajDange:
any suggestion why does it happen.

Because that is how the code is written ...

In the single character example the code is

void recvOneChar() {
    if (Serial.available() > 0) {
        receivedChar = Serial.read();
        newData = true;
    }
}

so every character received is treated separately.

In the other examples the equivalent functions are named
void recvWithEndMarker()
and
void recvWithStartEndMarkers()
CORRECTION
In both of those examples the NEWLINE character is used as the end-marker.
In the first of those examples the NEWLINE character is used as the end-marker. In the second example the characters '<' and '>' are used as the start- and end-markers.
Apologies for any confusion.

You could use void recvWithEndMarker() to receive a single character followed by a NEWLINE

...R

Ok got it thanks

Robin2:
In the other examples the equivalent functions are named
void recvWithEndMarker()
and
void recvWithStartEndMarkers()
In both of those examples the NEWLINE character is used as the end-marker.

You don't know your own code anymore or I missed it :wink: I don't see a '\n' test in recvWithStartEndMarkers()

sterretje:
You don't know your own code anymore or I missed it :wink: I don't see a '\n' test in recvWithStartEndMarkers()

You are 100% correct.

The function recvWithStartEndMarkers() uses the characters '<' and '>' as the start- and end-markers.

I have corrected my earlier reply. Apologies to all for my stupidity.

...R

Hello,

Robin2

I did go through all your examples all works perfect , as in your examples their are startMarker and endMarkers and the data is stored in array of size 32.

i wanted to know is their a way if data stored in array and we want to startMarker from a specific position and endMarker at specific position.

for example: If following is the data [12345abcd23sdg] this data will come in array and if i want to start the startMarker at 6th position of array and endMarker at 10 position what should be done and then the data will be parsed .

You can just copy N of the received bytes to another buffer (size N + 1) and parse that.

If it can be destructive, you can overwrite character at position 10 with '\0' and parse &receivedChars[6] (note the ampersand).

JairajDange:
for example: If following is the data [12345abcd23sdg] this data will come in array and if i want to start the startMarker at 6th position of array and endMarker at 10 position what should be done and then the data will be parsed .

You need to do the sort of thing @sterretje suggested.

In the example you have suggested the start-marker is '[' and the end-marker is ']' And an important point is that you need that start-marker in order to know where to start counting.

...R

A good set of functions to learn are in ctype.h.

iscntrl(c) will return true of c is a control character like '\n' or '\r'.

You can use it to simply ignore characters you are not interested in.

The example which i gave was just a basic idea what i was trying to do, i wanted to parse data
as given in this thread Getting data from serial monitor - Programming Questions - Arduino Forum

the Start - marker and end -marker cannot be defined as i want as there are similar start-marker or end - marker

following is the data i want to parse on serial monitor

+CRING: VOICE

+CLIP: "+919404789938",145,"",,"No1",0

+CRING: VOICE

+CLIP: "+919404789938",145,"",,"No1",0

i want to get the mobile number and store it in array, we cannot use the start marker as "+" as their are two + signs, if i assign the start marker to "9" which is followed after "+" then what will be end marker as i cannot know every time what will be the last digit of the number as the mobile number can change so i thought of taking whole string and storing it in an array and then at a specific position it should start the start marker and end marker, check me if i am wrong and give any suggestions what else can be done :slight_smile:

JairajDange:
following is the data i want to parse on serial monitor

+CRING: VOICE

+CLIP: "+919404789938",145,"",,"No1",0

+CRING: VOICE

+CLIP: "+919404789938",145,"",,"No1",0

If that is an accurate sample of the sort of data you want to parse then it seems to me you can use a COLON ':' as the start marker and NEWLINE '\n' as the end marker. Then you can search the received data for the '+' prior to the number - or maybe the number will always start in character position 3 (counting from 0).

...R

Robin2:
use a COLON ':' as the start marker and NEWLINE '\n' as the end marker.

I have tried this with your fifth example, it sortof gives mixed values of data, i know i have to format the program, at least i am getting close to result what i want.

Now i am facing a problem using this method of parsing, as i am using two serial terminals sometimes the data gets lost (i think so) as the above data was when i read from serial1 terminal and display it on serial terminal of mega.

so i used example 3 so that i shall know exactly what is happening and i tried to send data on serial monitor and was expecting result

when i used following code

// Example 3 - Receive with start- and end-markers

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
    Serial1.begin(9600);
}

void loop() {
    recvWithEndMarker();
    showNewData();

    // read from port 1, send to port 0:
  if (Serial1.available()) {
   int inByte = Serial1.read();
    Serial.write(inByte);

}
  // read from port 0, send to port 1:
  if (Serial.available()) {
   int inByte = Serial.read();
    Serial1.write(inByte);
  }
}


void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '>';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

i got following results:

when i tried to enter in serial monitor

first two responses i didn't got any reply (blank serial monitor)

in third entry i got following response

<Arduino is ready>
This just in ... ho
<l
hll

WTF do you have this code in your program?

   // read from port 1, send to port 0:
  if (Serial1.available()) {
   int inByte = Serial1.read();
    Serial.write(inByte);

}
  // read from port 0, send to port 1:
  if (Serial.available()) {
   int inByte = Serial.read();
    Serial1.write(inByte);

How can you expect my code to work when you screw it up?

...R

Robin2:
WTF do you have this code in your program?

As i said

How can you expect my code to work when you screw it up?

As i said, i am trying to read from two separate serial terminals so i have used the code

Robin2:
How can you expect my code to work when you screw it up?

I didn't say that problem is with your code, i am saying that why their is a data loss when i am trying to read and write on two serial terminals simultaneously, the above code as mentioned in the quotes (// read from port 0, send to port 1:) and(// read from port 1, send to port 2:) is to write and read data simultaneously

JairajDange:
I didn't say that problem is with your code, i am saying that why their is a data loss when i am trying to read and write

Because the code you have added interferes with my code. You are snatching characters from the serial input buffer that should be left for my function.

If you want to read from two serial ports just create another copy of my function (and its associated data structures) - for example

void recvWithEndMarkerSerial1() {

...R