Serial comunication with pc. send and receive over single port.

Hi all,

I read a couple of examples online and wrote a very simple visual studio program to send values through the serial port when a "slider" is moved. These values are picked up by the arduino using the basic serial event and an LED's brightness is controlled by these values. All works well at this point.

I plan on expanding on this and adding more sliders which would send values to control other things and for this I would be sending data something like "F255\n" (for fan - 255). Also, later I plan on sending sensor information back through the port to the computer to be displayed.

I have tried this in the past and had trouble when sending info both ways as I was never sure if the arduino or the computer would pick up data so this time I plan on adding a "C" (computer) or an "A"(arduino) infront of the serial data to tell me where it has been sent from. Giving something like, "CF255\n", a command sent from the computer to set the fan to 255.

I was wondering if:

  1. The above is a good approach or if there is a more standard way that people would usually use for handeling two way communication over one serial port?

  2. I have no way to debug at the moment accept by visually seeing if the component is turned on or not. I have tried to get the serial monitor to send serial data using the send button but it doesn't seem to get picked up by the serial event... Is that approach do-able? if so could you point me in the right direction on how?

Thanks for reading :slight_smile:
Scott

I see no need for serial event. Polling Serial.available() should be sufficient, and when enough characters have arrived, you can decode the message. Serial transmission requires that both stations use the same baudrate, of course.

Have a look at this Python - Arduino demo
and at Serial Input Basics

The business of 2-way communication requires a plan. It is easiest if you put one of the devices in control.

I suggest it should be the Arduino because the PC is much faster and more flexible. For example the PC could send a message after every message it receives from the Arduino. And the Arduino could ask for data every (say) 100 millisecs. Asking for data could be as simple as sending ‘M’ for more. Or it could be a message with useful data in it. No doubt 10 minutes of thought will come up with 50 alternatives.

If you have several pieces of data that the PC needs to send (from several sliders, say) I recommend sending all the items every time even though they have not changed. Then you don’t need to identify the item. Its place in the message will identify it. For example send <123, 765, 23, 0, 98>

…R

I don't see a need for synchronisation of both stations, because the Serial connection is hardware full duplex by design. Synchronization is required for SoftwareSerial or wireless transmission, which only implement half duplex operation.

Ah... I never considered "Asking for data", that sounds good and I can definitely see the benifit in sending all the data in order at once as well.

Thanks for the tips and links I will give them a read. But I think I have a better idea on a direction to take just from those two ideas.

Thanks
Scott

DrDiettrich:
I don't see a need for synchronisation of both stations, because the Serial connection is hardware full duplex by design. Synchronization is required for SoftwareSerial or wireless transmission, which only implement half duplex operation.

I was not thinking of what you describe which I might call "technical" synchronization but rather with "process" synchronization.

...R

@Robin2

So I have been looking through the links you left - good stuff!

I thought in return I would give you a bit of a laugh!

I got side tracked by your parseData method as it used a few functions I had not seen before and used a pointer (i think) and as I had little idea on how they worked, I thought I would just try and write it out long hand…

Your five lines of:

  char * strtokIndx; // this is used by strtok() as an index
  
  strtokIndx = strtok(inputBuffer,",");      // get the first part - the string
  strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  newFlashInterval = atoi(strtokIndx);     // convert this part to an integer
  
  strtokIndx = strtok(NULL, ",");

Turned into:

 void myTestParseDataAttempt()
{
  int commaCount = 0;
  for (int i=0; i<strlen(inputBuffer);i++)
  {     
    if(inputBuffer[i] == ',')
    {
      commaCount++;
    }
  }  
  
  String parsedArray[commaCount + 1]; 
  String currentString = "";
  int currentIndex = 0;
  for (int i=0; i<strlen(inputBuffer); i++)
  {     
    char currentChar = inputBuffer[i];
    if(currentChar == ',')
    {
      parsedArray[currentIndex] = currentString;      
      currentIndex++;
      currentString = ""; // reset the string
    }
    else
    {
      currentString += currentChar;
      
      if (i+1 == strlen(inputBuffer))
      {
        parsedArray[currentIndex] = currentString; // final item
      }
    }
  }

  
  // test
  for (int i=0;i<currentIndex+1;i++)
  {
    Serial.println(parsedArray[i]);
  }
  

  printData = false;
}

Where is: str.Split(’,’) when you need it ha.

scottbnoob:
Where is: str.Split(',') when you need it ha.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

Which is what my demo uses.

...R

Noted.