Serial Communication with the Arduino

Hello,

I've been following this tutorial to interface between a C# program and my Arduino. The C# program isn't even my problem at the moment.

I came up with the following:

#include <arduino.h>

/* CONSTANTS */
#define STX "\x02"    //ASCII-Code 02, text representation of the STX code
#define ETX "\x03"    //ASCII-Code 03, text representation of the ETX code
#define RS  "$"       //Used as RS code

/* WARNING, ERROR AND STATUS CODES */
//STATUS
#define MSG_METHOD_SUCCESS 0
//WARNINGS
#define WRG_NO_SERIAL_DATA_AVAILABLE 250
//ERRORS
#define ERR_SERIAL_IN_COMMAND_NOT_TERMINATED -1

int readSerialInputString(String *command);
void WriteDummyWeatherData();

int main() {
  init();

  Serial.begin(9600);

  while(true) {
    String command = ""; // Storing the latest command received
    int serialResult = 0; // The answer code of the command received
    
    serialResult = readSerialInputCommand(&command);

    if(serialResult == MSG_METHOD_SUCCESS) {
      if(command == "connection#") {
        returnPing();
      }
    }
  }
}

void returnPing() {
  Serial.print(STX);
  Serial.print("success");
  Serial.print(ETX);
}

int readSerialInputCommand(String *command) {
  int operationStatus = MSG_METHOD_SUCCESS;
  if (Serial.available()) {
      char serialInByte;//temporary variable to hold the last serial input buffer character

      // Run the following until the terminating character comes up or no data is available.
      do{
        serialInByte = Serial.read();
        *command = *command + serialInByte; //Add last read serial input buffer byte to received command
      } while (serialInByte != '#' && Serial.available());

      // If command is not terminated by '#', return an error.
      if(serialInByte != '#') {
        operationStatus = ERR_SERIAL_IN_COMMAND_NOT_TERMINATED;
      }
    }
    else{
      // If no serial input buffer data is available, operationStatus becomes WRG_NO_SERIAL_DATA_AVAIBLE
      operationStatus = WRG_NO_SERIAL_DATA_AVAILABLE;
    }
    
  return operationStatus;
}

To test the code, I want to write "connection#" to the Serial Port (while the '#' is the character to indicate a command's end) using the Arduino Serial Monitor. Later on, the C# part is supposed to take over this task.

But for now, nothing happens when I write anything to the Serial Monitor. While "connection#" should return "succcess", nothing happens. I placed a test-write into the if(command == "connection#") to see if this is even triggered, which is not the case. However, the correct status codes are generated for what I typed in.

My guess is the command is not read correctly but I actually don't know why.
Any experts here who could help? :slight_smile:

Thanks,
Daniel

This is not arduino code. Why not use setup() and loop() like the arduino Gods intended?

Do you have a particular reason for writing your own main() function instead of using the more normal Arduino setup() and loop() functions ?

That's something our teacher at university came up with as

int main() {
	while(true) {
		
	}
}

is supposed to be more "C like" and works just the same as the setup() and loop() functions.

Never was a problem up to now, does it have something to do with my current issue?

Could, since it does not do the regular startup.

The obvious first thing to do is to echo all the characters received.

KeithRB:
Could, since it does not do the regular startup.

Changed it, just to be save, didn't solve the problem though.

KeithRB:
The obvious first thing to do is to echo all the characters received.

I put a Serial.print(serialInByte); in front of the *command = *command + serialInByte; and this prints out the correct input. So what's read seems not to be the problem. After the line I put Serial.print(&command); but the compiler gives me the error "call of overloaded 'print(String**)' is ambiguous" here. I think there is something wrong with the command variable?

Since I never use Strings on the arduino I could not say. try with a standard C character buffer.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

you probably have two problems - remember the arduino executes a lot faster than serial data arrives

  1. what happens if Serial.read() fails to read a byte and returns -1 ? you add it to your string anyway
  2. your while terminates if Serial.available() returns false even if you are in the middle of reading your string
    try
    do{
        while((serialInByte = Serial.read()) == -1);
        *command = (*command) +  serialInByte; //Add last read serial input buffer byte to received command
        Serial.println(*command);
      } while (serialInByte != '#');// && Serial.available());

having a print in the loop gives you some feedback as to what is going on

horace:
you probably have two problems - remember the arduino executes a lot faster than serial data arrives

  1. what happens if Serial.read() fails to read a byte and returns -1 ? you add it to your string anyway
  2. your while terminates if Serial.available() returns false even if you are in the middle of reading your string

All covered in Serial Input Basics

...R

horace:

  1. what happens if Serial.read() fails to read a byte and returns -1 ? you add it to your string anyway
  2. your while terminates if Serial.available() returns false even if you are in the middle of reading your string

Thank you! It seems that this was the problem. Thank you very much for explaining. It's working now! -

Robin2:
All covered in Serial Input Basics

Point taken, thanks. I'll give it a read.

Haha thanks, but I want to take some of his future courses so I don't want to mess with him too much :stuck_out_tongue:

But I get what you mean.

True that. I will bringt this up to him. Maybe he has an explanation. Can't believe he is doing this out of stupidity. He is a good teacher normally.