Serial Problem with Arduino Mega 2560

Hi,

I’ve been trying to send data to the Arduino Mega board using Serial.available() and Serial.read(). However the data isn’t getting detected through a standard terminal program. However, when the data is sent out through the serial monitor tool of the IDE the data is getting received and displayed on the LCD.
I’ve also tested Serial.print to check the Rx, onto the terminal program. This works both on my terminal program as well as the serial monitor.serial ports i.e.: when Serial.available() is changed to Serial2.available() or Serial3.available() the data is getting received on the board so I’m sure nothing is wrong on my terminal program.

I wished to check if Serial.read() is disabled on the Arduino Mega board for terminal programs other than the Serial monitor in the Arduino IDE.
Code is as below.

#include <LiquidCrystal.h>

const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
int receivedChars1;
int receivedChars2,i,y;
int ledPin = 50;
int resetPin = 48;
boolean newData = false;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
 // digitalWrite(resetPin, HIGH);
  lcd.begin(16,2);
  pinMode(ledPin, OUTPUT);
 // pinMode(resetPin, OUTPUT);
  digitalWrite(ledPin, LOW);
 Serial.begin(9600);
 Serial.setTimeout(50);
 Serial2.begin(9600);
 Serial3.begin(9600);
 //Serial.println("<Arduino is ready>");
 
 
}

void loop() {

recvWithStartEndMarkers();
receivedChars1=  atoi(receivedChars);
//delay(100);

 recvWithStartEndMarkers();
 receivedChars2= atoi(receivedChars);
 i=receivedChars1-receivedChars2;
 y=receivedChars2-receivedChars1;
  if(i>10)
    {
    lcd.setCursor(0,0);
    lcd.print("Please Swipe ");
    lcd.setCursor(0,1);
    lcd.print("Card");
  //  digitalWrite(ledPin, HIGH);
    delay(3000);
    softReset();
    //delay(3000);
    
    }

    [b]while (Serial.available())
    {
      char received = Serial.read();
    [/b] // Serial.write(received);
      if(received == '@')
      {
         lcd.setCursor(0,0);
         lcd.print("Please collect ");
         lcd.setCursor(0,1);
         lcd.print("Goods");
         digitalWrite(ledPin, HIGH);
         delay(10000);
         softReset();
        }
        else
        {
          
         lcd.setCursor(0,0);
         lcd.print("Insufficient ");
         lcd.setCursor(0,1);
         lcd.print("Balance");
        // digitalWrite(ledPin, HIGH);
        delay(5000);
        softReset();
          }

    }
}


void recvWithStartEndMarkers() {
  delay(101);
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '.';
    char endMarker = 'S';
    char rc;
 
 
    while (Serial2.available() > 0 && newData == false) {
        rc = Serial2.read();

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

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
    newData = false;
    while(Serial2.available()>0)
{
  Serial2.read();
  }
}



   
void softReset(){
asm volatile ("  jmp 0");
}

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long to study quickly without copying to a text editor.

I think you have got things mixed up by incorrect copy-and-paste and if I can view it in a text editor I may be able to help.

…R

I don't have a Mega but when you say

when the data is sent out through the serial monitor tool of the IDE the data is getting received

is this via Serial2 ? I thought that the Serial monitor only worked with Serial. Have I misunderstood something ?

How is the terminal program connected to the Arduino ?

Robin2:
Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long to study quickly without copying to a text editor.

I think you have got things mixed up by incorrect copy-and-paste and if I can view it in a text editor I may be able to help.

…R

Thanks, I’ve modified the opening post to make it more legible

UKHeliBob:
I don't have a Mega but when you sayis this via Serial2 ? I thought that the Serial monitor only worked with Serial. Have I misunderstood something ?

How is the terminal program connected to the Arduino ?

No via Serial only. The PC is connected to the board through the USB cable(the same one thats used to upload the sketches)
What I'm seeing is that data is being sent only through Arduino Serial Monitor to Serial, my terminal program isn't able to transmit anything to the board. While the receive works both through serial monitor as well as my terminal program.( I tested this by putting Serial.print() on the board and monitoring the data both through the Arduino Serial Monitor and my terminal program)
This indicates( I think) that Tx to the arduino mega board using Serial works only through the Arduino Serial Monitor, is this right?

This indicates( I think) that Tx to the arduino mega board using Serial works only through the Arduino Serial Monitor, is this right?

That matches what I have always thought, but the Mega can also receive serial data using Serial1, Serial2 and Serial3 as long as the signal levels are correct (TTL not RS232) and that the correct pins are used.

This won't work. It is not how the function is intended to be used

recvWithStartEndMarkers();
receivedChars1=  atoi(receivedChars);
//delay(100);

 recvWithStartEndMarkers();
 receivedChars2= atoi(receivedChars);

Any single call to recvWithStartEndMarkers() is likely just to receive part of a message. It is only when newData is true that you know you have a message that can then be parsed.

...R

UKHeliBob:
That matches what I have always thought, but the Mega can also receive serial data using Serial1, Serial2 and Serial3 as long as the signal levels are correct (TTL not RS232) and that the correct pins are used.

Yeah, I’m already using Serial2 and have tested the code to receive data on Serial3. I particularly wanted to use Serial0 because I won’t have to use the DC jack to supply power to the board if use the usb jack for both power and data.
BTW, I’ve only ever used Arduino Mega, do you know how it works for other boards that want to use Serial0 to receive data from the PC?
Also, if I try to use the source code of the serial monitor would you know where that could be? Maybe I could modify my terminal program code to use the Arduino for doing the transfer. Ive already looked in HardwareSerial.cpp and didn’t find anything related to the serial monitor in there.

Robin2:
This won't work. It is not how the function is intended to be used

recvWithStartEndMarkers();

receivedChars1=  atoi(receivedChars);
//delay(100);

recvWithStartEndMarkers();
receivedChars2= atoi(receivedChars);




Any single call to recvWithStartEndMarkers() is likely just to receive part of a message. It is only when `newData` is true that you know you have a message that can then be parsed.

...R

I've actually referred to your tutorial for that function(thanks for that), but this code works for me because I'm continuously receiving data which is a 5 bytes long on Serial2 thus there always must be data stored on the buffer for me to parse and collect.
I've tried out the logic using Serial2 for input 1 and Serial3 for input 2(from terminal program on PC) and the code works as desired. I wanted to use Serial0 for input 2 because that'll save me a connection to the power jack. This is when I saw that I'm being able to transmit data from PC to board Serial0 only through the Arduino serial monitor program and not through my terminal program.
So I'm starting to think that the Serial0 receive on the arduino board is accessible only through the Serial terminal monitor on the arduino IDE. If this is correct, is there any way to invoke the arudino serial monitor through the code. I'm going through the source code, but am not able to find the code that refers to the serial monitor.

This is when I saw that I'm being able to transmit data from PC to board Serial0 only through the Arduino serial monitor program and not through my terminal program.

You can send data to the Arduino using a terminal program what you are calling Serial0 by selecting the appropriate COM port in the terminal program. Just don't try to have the Serial monitor open at the same time.

UKHeliBob:
You can send data to the Arduino using a terminal program what you are calling Serial0 by selecting the appropriate COM port in the terminal program. Just don't try to have the Serial monitor open at the same time.

I tried that, it doesn't transmit anything even when the serial monitor is closed. Ive shut the Arduino IDE and tried, still it didn't work.

rimas_tc:
I've actually referred to your tutorial for that function(thanks for that), but this code works for me

You are playing with fire. The time will come when it won't work and you will waste hours trying to find the cause.

Use the function the way it is intended to be used.

...R

Robin2:
You are playing with fire. The time will come when it won’t work and you will waste hours trying to find the cause.

Use the function the way it is intended to be used.

…R

I’ve changed the code to the below:

#include <LiquidCrystal.h>

const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
int receivedChars1;
int receivedChars2,i,y;
int ledPin = 50;
int resetPin = 48;
boolean newData = false;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
 // digitalWrite(resetPin, HIGH);
  lcd.begin(16,2);
  pinMode(ledPin, OUTPUT);
 // pinMode(resetPin, OUTPUT);
  digitalWrite(ledPin, LOW);
 Serial.begin(9600);
 //Serial.setTimeout(50);
 Serial2.begin(9600);
 Serial3.begin(9600);
 //Serial.println("<Arduino is ready>");
 
 
}

void loop() {

//while(newData){
 recvWithStartEndMarkers();
Serial.println(receivedChars);
 newData=false;
}
receivedChars1=  atoi(receivedChars);
//delay(100);

 while(newData){
  recvWithStartEndMarkers();
  Serial.println(receivedChars);
  newData=false;
 }
 
 receivedChars2= atoi(receivedChars);
 i=receivedChars1-receivedChars2;
 y=receivedChars2-receivedChars1;
  if(i>10)
    {
    lcd.setCursor(0,0);
    lcd.print("Please Swipe ");
    lcd.setCursor(0,1);
    lcd.print("Card");
  //  digitalWrite(ledPin, HIGH);
    delay(3000);
    softReset();
    //delay(3000);
    
    }

    while (Serial.available())
    {
      char received = Serial.read();
     // Serial.write(received);
      if(received == '@')
      {
         lcd.setCursor(0,0);
         lcd.print("Please collect ");
         lcd.setCursor(0,1);
         lcd.print("Goods");
         digitalWrite(ledPin, HIGH);
         delay(10000);
         softReset();
        }
        else
        {
          
         lcd.setCursor(0,0);
         lcd.print("Insufficient ");
         lcd.setCursor(0,1);
         lcd.print("Balance");
        // digitalWrite(ledPin, HIGH);
        delay(5000);
        softReset();
          }

    }
}


void recvWithStartEndMarkers() {
  delay(101);
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '.';
    char endMarker = 'S';
    char rc;
 
 // if (Serial.available() > 0) {
 
    while (Serial2.available() > 0 && newData == false) {
        rc = Serial2.read();

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

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
    newData = false;
    while(Serial2.available()>0)
{
  Serial2.read();
  }
}



   
void softReset(){
asm volatile ("  jmp 0");
}

I’m still facing the same issue viz. Serial0 not working outside of Arduino Serial Monitor for transmit

That code won't even compile. Your loop() function is:

void loop() {

//while(newData){
 recvWithStartEndMarkers();
Serial.println(receivedChars);
 newData=false;
}

The rest of the code is not in a function.

As well as what @PaulS has said, this is completely wrong

void loop() {

//while(newData){
 recvWithStartEndMarkers();
Serial.println(receivedChars);
 newData=false;
}

I wonder if you mistakenly think that recvWithStartEndMarkers() waits until it gets all the data - it does NOT. It is especially designed NOT to do that so that it does not block other Arduino activities.

Its purpose is to see if there is anything in the serial input buffer and transfer it to the array receivedChars. However in any one call to the function it may find no relevant data, or only one or 2 bytes. It is ONLY when the variable newData == true that there is any purpose in checking what is in receivedChars.

Look again carefully at the entire program example in Serial Input Basics

…R

Robin2:
As well as what @PaulS has said, this is completely wrong

void loop() {

while(newData){
recvWithStartEndMarkers();
Serial.println(receivedChars);
newData=false;
}



I wonder if you mistakenly think that `recvWithStartEndMarkers()` waits until it gets all the data - it does NOT. It is especially designed NOT to do that so that it does not block other Arduino activities.

Its purpose is to see if there is anything in the serial input buffer and transfer it to the array receivedChars[]. However in any one call to the function it may find no relevant data, or only one or 2 bytes. It is ONLY when the variable newData == true that there is any purpose in checking what is in receivedChars.

Look again carefully at the entire program example in [Serial Input Basics](http://forum.arduino.cc/index.php?topic=396450.0)

...R

OK, I’ve tried it in the below ways using examples given in the library:

/*
  Serial Event example

 When new serial data arrives, this sketch adds it to a String.
 When a newline is received, the loop prints the string and
 clears it.

 A good test for this is to try it with a GPS receiver
 that sends out NMEA 0183 sentences.

 Created 9 May 2011
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialEvent

 */
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  lcd.begin(16, 2);

  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {

      lcd.setCursor(0,0);
      lcd.print(inputString);    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == 's') {
      stringComplete = true;
    }
  }
}
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

String inData1;
void setup() {
    Serial.begin(9600);

    lcd.begin(16, 2);
    Serial.println("Serial conection started, waiting for instructions...");
   
}

void loop() {
    if (Serial.available())
    {
        char recieved = Serial.read();
        inData1 += recieved; 

        // Process message when new line character is recieved
        if (recieved == 'S')
        {
            lcd.setCursor(0,0);
            lcd.print(inData1);

            // You can put some if and else here to process the message juste like that:


            inData1 = ""; // Clear recieved buffer
        }


    
    }
   
}

In both these I’m able to display data on the LCD when I send the data through Arduino Serial Monitor and cant display the data when I used my terminal program to send the data. So, back to my original doubt, does the Serial0 receive work only for data sent through the Arduino Serial Monitor?

does the Serial0 receive work only for data sent through the Arduino Serial Monitor?

No, it also works for a serial device using the COM port that the Arduino uses or connected to pins 0/1
This works for me with a Uno using Teraterm as the emulator

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

void loop()
{
  if (Serial.available())
  {
    Serial.print(Serial.read());
  }
}

rimas_tc:
OK, I’ve tried it in the below ways using examples given in the library:

Sorry. I’m lost now. Neither of the examples in your Reply #15 use the code in my Serial Input Basics. Of course you are perfectly free not to use my examples but I assume you are interested in them because you quoted me.

Sorting out programming problems requires a methodical step-by-step approach - not the scatter-gun approach of trying something completely different for every test.

…R