Go Down

Topic: General Serial Port usage confusion (Read 1 time) previous topic - next topic

jim-yang

Sep 06, 2018, 11:09 pm Last Edit: Sep 06, 2018, 11:12 pm by jim-yang
I'm having some difficulty understanding serial communication and am getting pretty confused. Can you be using different serial ports on the same COM?

I was looking at Robin2's demo of PC-Arduino communication and I noticed that the reading and writing are  in different functions to be executed at different times. Now I'm a little confused. If I want multiple independent communications to occur between the PC-Arduino, do I need to use different ports?

For example, in the code found in the first link, a check for serial.available is done, and then the byte x is read. Would I need two independent serial.read commands if I were to be receiving two independent data at the same time? Would it be possible to use byte instead of int? Given that every instance of byte be changed to an int value?


Code: [Select]
// 12 Mar 2014
// this works with ComArduino.py and ComArduinoA4e.rb
// this version uses a start marker 254 and an end marker of 255
//  it uses 253 as a special byte to be able to reproduce 253, 254 and 255
// it also sends data to the PC using the same system
//   if the number of bytes is 0 the PC will assume a debug string and just print it to the screen

//================

#define startMarker 254
#define endMarker 255
#define specialByte 253
#define maxMessage 16

// the program could be rewritten to use local variables instead of some of these globals
//  however globals make the code simpler
//  and simplify memory management

byte bytesRecvd = 0;
byte dataSentNum = 0; // the transmitted value of the number of bytes in the package i.e. the 2nd byte received
byte dataRecvCount = 0;


byte dataRecvd[maxMessage];
byte dataSend[maxMessage]; 
byte tempBuffer[maxMessage];

byte dataSendCount = 0; // the number of 'real' bytes to be sent to the PC
byte dataTotalSend = 0; // the number of bytes to send to PC taking account of encoded bytes

boolean inProgress = false;
boolean startFound = false;
boolean allReceived = false;

//================

void setup() {
  pinMode(13, OUTPUT); // the onboard LED
  Serial.begin(57600);
  debugToPC("Arduino Ready from ArduinoPC.ino");
 
  delay(500);
  blinkLED(5); // just so we know it's alive
}

//================

void loop() {

  getSerialData();
 
  processData();

}

//================

void getSerialData() {

     // Receives data into tempBuffer[]
     //   saves the number of bytes that the PC said it sent - which will be in tempBuffer[1]
     //   uses decodeHighBytes() to copy data from tempBuffer to dataRecvd[]
     
     // the Arduino program will use the data it finds in dataRecvd[]

  if(Serial.available() > 0) {

    byte x = Serial.read();
    if (x == startMarker) {
      bytesRecvd = 0;
      inProgress = true;
      // blinkLED(2);
      // debugToPC("start received");
    }
     
    if(inProgress) {
      tempBuffer[bytesRecvd] = x;
      bytesRecvd ++;
    }

    if (x == endMarker) {
      inProgress = false;
      allReceived = true;
     
        // save the number of bytes that were sent
      dataSentNum = tempBuffer[1];
 
      decodeHighBytes();
    }
  }
}

//============================

void processData() {

    // processes the data that is in dataRecvd[]

  if (allReceived) {
 
      // for demonstration just copy dataRecvd to dataSend
    dataSendCount = dataRecvCount;
    for (byte n = 0; n < dataRecvCount; n++) {
       dataSend[n] = dataRecvd[n];
    }

    dataToPC();

    delay(100);
    allReceived = false;
  }
}

//============================

void decodeHighBytes() {

  //  copies to dataRecvd[] only the data bytes i.e. excluding the marker bytes and the count byte
  //  and converts any bytes of 253 etc into the intended numbers
  //  Note that bytesRecvd is the total of all the bytes including the markers
  dataRecvCount = 0;
  for (byte n = 2; n < bytesRecvd - 1 ; n++) { // 2 skips the start marker and the count byte, -1 omits the end marker
    byte x = tempBuffer[n];
    if (x == specialByte) {
       // debugToPC("FoundSpecialByte");
       n++;
       x = x + tempBuffer[n];
    }
    dataRecvd[dataRecvCount] = x;
    dataRecvCount ++;
  }
}

//====================

void dataToPC() {

      // expects to find data in dataSend[]
      //   uses encodeHighBytes() to copy data to tempBuffer
      //   sends data to PC from tempBuffer
    encodeHighBytes();

    Serial.write(startMarker);
    Serial.write(dataSendCount);
    Serial.write(tempBuffer, dataTotalSend);
    Serial.write(endMarker);
}

//============================

void encodeHighBytes() {
  // Copies to temBuffer[] all of the data in dataSend[]
  //  and converts any bytes of 253 or more into a pair of bytes, 253 0, 253 1 or 253 2 as appropriate
  dataTotalSend = 0;
  for (byte n = 0; n < dataSendCount; n++) {
    if (dataSend[n] >= specialByte) {
      tempBuffer[dataTotalSend] = specialByte;
      dataTotalSend++;
      tempBuffer[dataTotalSend] = dataSend[n] - specialByte;
    }
    else {
      tempBuffer[dataTotalSend] = dataSend[n];
    }
    dataTotalSend++;
  }
}

//=========================

void debugToPC( char arr[]) {
    byte nb = 0;
    Serial.write(startMarker);
    Serial.write(nb);
    Serial.print(arr);
    Serial.write(endMarker);
}

//=========================

void debugToPC( byte num) {
    byte nb = 0;
    Serial.write(startMarker);
    Serial.write(nb);
    Serial.print(num);
    Serial.write(endMarker);
}

//=========================

void blinkLED(byte numBlinks) {
    for (byte n = 0; n < numBlinks; n ++) {
      digitalWrite(13, HIGH);
      delay(200);
      digitalWrite(13, LOW);
      delay(200);
    }
}



http://forum.arduino.cc/index.php?topic=225329.0 Robin2 PC-Arduino communication link

https://www.arduino.cc/en/Tutorial/TwoPortReceive

sterretje

Your question does not quite make sense to me. COMX is the serial port on a PC. It can only be used by one application at a time.

If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

GolamMostafa

#2
Sep 07, 2018, 08:28 am Last Edit: Sep 07, 2018, 10:12 am by GolamMostafa
If I want multiple independent communications to occur between the PC-Arduino, do I need to use different ports?
Let us take the case of Arduino UNO.

UNO has only one UART Port which is permanently engaged with PC via USB/Virtual COMX Port to operate the Serial Monitor and the IDE.

The PC has many more USB Ports; but, the UNO has no more UART Ports.

Now please, clarify the meaning of what you have wanted to mean by saying -- multiple independent communications to occur between the PC-Arduino. Have you wanted to mean --

You want to open a 2nd IDE (which you can) in the PC and link it with UNO using a 2nd USB/VCOMX Port of the PC?

You can do the above job; but, this is a complicated task -- you need a USB<--->RS232) conversion cable; you need to know the signal signatures of the 9-Pin DB connector of the conversion cable; you need a RS232<--->TTL conversion chip (MAX232); you need to create a software UART Port for the UNO.

Robin2

Would I need two independent serial.read commands if I were to be receiving two independent data at the same time?
As others have said on the PC only one program can "own" a COM port at any one time and that COM port appears as a single source of data as far as the Arduino is concerned. If the PC changes to using a different program the Arduino won'r know.

If you need two PC programs to be able to talk to the Arduino at the same time (which would be unusual) you need to use a second COM port probably with a USB-TTL cable to connect to a second serial port on the Arduino. In that case the Arduino program would need a completely separate receive and send functions for the second serial port.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jim-yang

I think I understand what you mean.

For example, I was wondering if I wanted to send a int and a string from the PC to the Arduino, if I would need to leave 1 COMX for a int and 1 for a string. This meaning I would need 2 COMX to send the data.

But if I understand correctly, it will still all be over 1 COMX regardless of the type of data being sent. If I had a PC send data to the Arduino, and then have the Arduino send the data to another PC, I would then need 2 COMX ports.

Robin2

If I had a PC send data to the Arduino, and then have the Arduino send the data to another PC, I would then need 2 COMX ports.
No you don't need two COM ports. Serial communication is bi-directional.

Have a look at this Python - Arduino demo

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

No you don't need two COM ports. Serial communication is bi-directional.

Have a look at this Python - Arduino demo

...R
He is communicating with two PCs --- at least that is what his post says --- so he will need two COM ports.

Robin2

He is communicating with two PCs --- at least that is what his post says --- so he will need two COM ports.
I don't see that anywhere?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

#8
Sep 08, 2018, 11:02 pm Last Edit: Sep 08, 2018, 11:03 pm by ieee488
I don't see that anywhere?

...R
It is in what you quoted!

OP wrote --->  If I had a PC send data to the Arduino, and then have the Arduino send the data to another PC, I would then need 2 COMX ports.

CrossRoads

You can have one Arduino (Uno) talking to two PCs - one will use Serial thru D0/D1 and the onboard USB interface chip (atmega16U2 (Uno/Mega), FT232 (Nano), or onchip (Leonardo/Micro ath atmega32U4); the second will use soft version of software serial thru a different pair of port and using an offboard FTDI Basic to have a 2nd USB port.

Atmega1284P has two hwardware serial ports, Serial and Serial1, many  boards (like mine) have FTBasic function onboard for Serial, and 2nd FTDI Basic can be connected for Serial 1.

Megas have 4 hardware serial ports, with Serial thru the onboard Atmega16U2, and offboard FTDI Basics connected to Serial1, Serial2, Serial3 for 3 more hardware serial ports.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Robin2

It is in what you quoted!
Thanks. I had not spotted that. I had assumed the conversation was a continuation of the OP's first Post in which seemed fairly clearly about two communications with the same PC. I guess it was further confusing by the OP's use of the term COM ports because they only exist in a PC.

Anyway ...


@jim-yang, if you want to connect your Arduino to two separate PCs then you will need to use two Serial ports on the Arduino. That can be achieved using SofwareSerial on an Uno or Nano or by using the extra HardwareSerial ports on a Mega or Leonardo or Micro.

You can connect one of the PCs to the Arduino using the regular USB connection but you will need a USB-TTL cable to connect the second PC to the Rx Tx and GND pins for the second Arduino serial port.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ieee488

Thanks. I had not spotted that. I had assumed the conversation was a continuation of the OP's first Post in which seemed fairly clearly about two communications with the same PC. I guess it was further confusing by the OP's use of the term COM ports because they only exist in a PC.

Anyway ...


His post was confusing.
And he hasn't returned.  LOL.

.

jim-yang

I thought I understood from your earlier explanation and wanted to present a scenario and the solution to see if my understanding was correct or not.

I asked a follow up question to see if my understanding is the same, and presented a scenario and what I thought would need to do after, rather than trying to start a new post on this topic.

I'm just trying to communicate between a Windows Form GUI and a Arduino, but I have never worked with UART/serial communication and had trouble understanding how exactly it works with Arduino. Since I am only going between a PC and Arduino, I only need 1 COM established in order to communicate back and forth,

In the scenario in which I use two PC and an Arduino to send, I think I would need I would need multiple Serial ports not COM Ports.

I was putting out a scenario and then saying what the solution would be to see if I were right. I didn't think I worded it confusingly. Apologies if you got confused. Thanks for the help.

ron_sutherland

#13
Sep 10, 2018, 06:00 am Last Edit: Sep 10, 2018, 06:04 am by ron_sutherland
Sadly on Windows, the letters COM can mean a serial communication port or the Component Object Modle for inter-process communication. I recall using a National Instruments COM device for communication with GPIB instruments. The COM has died more or less thankfully, but I have a feeling its confusion lives on.
my projects: https://github.com/epccs

Go Up