Send Arduino String to C # via Serial

0

I need to send Arduino Strings to C # in real time via Serial communication.

In the arduino code I'm using the following to send:

if (Serial.available()) //se byte pronto para leitura
{
   switch(Serial.read())      //verifica qual caracter recebido
   {
      case 'T':
          Serial.print("STATUS");
      break:
   }
}

And in C # to get the string:

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
   RxString = serialPort1.ReadExisting();
   Console.WriteLine(RxString);
}

OUTPUT:

ST

ATUS

ST

ATUS

STAT

US

ST

ATUS

ST

ATUS

STAT

US

S

However, I'm getting the broken String. What am I missing? Is there a better way to do this?

    
asked by anonymous 06.02.2015 / 12:40

1 answer

0

This is what is expected of serial communication.

There is no separation between the data sent and no guarantee that it will arrive all at once.

Following your example, there is no guarantee that a single call to Serial.print can not arrive in several parts of your C # program, as can a number of consecutive Serial.print calls made in a very short period come all together at once in your C # program.

So basically it's up to you to create a way to treat the data correctly, not only to know if the whole data arrived, but also to separate if data arrives from more than one message at a time.

I would say that the most basic thing you can do with a text-based protocol would be to use a delimiter, for example in arduino you would mark the end of the message with some character that you are sure will never be used, such as #

Serial.print("STATUS#");
So in C # you need to do two things, first of all you will need to create a buffer to save the data as it can get less data than necessary, so everything that you get adds to that buffer after you add the data to it. buffer you check if you have enough data to handle, if you have then you start to process the buffer and only when you see that the buffer is empty or that the data on it is not enough to process.
//buffer usado para guardar as mensagens, iniciado como uma string vazia
string buffer = "";

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    //sempre recebe os dados adicionando no final do buffer
    buffer += serialPort1.ReadExisting();
    //depois de receber os dados verifica se possui uma mensagem inteira nele
    //devemos fazer isso em um loop pois pode acontecer de chegar mais de uma
    //mensagem ao mesmo tempo
    int idx;
    while((idx = buffer.IndeOf('#')) >= 0)
    {
        //separamos a primeira mensagem do buffer sem o delimitador
        string mensagem = buffer.Substring(0, idx);
        //tratamos ela da forma que for necessário
        Console.WriteLine(mensagem);
        //por fim removemos ela do buffer
        buffer = buffer.Substring(idx + 1);
    }
}

Remembering that any unprocessed information because it is insufficient is in the buffer, if communication for some reason is interrupted and needs to be started again you may need to clear this buffer.

You have to always take into account also that serial communication may not be very reliable, I had a case where communication with a device from time to time lost a byte, was a limitation of the hardware of the device and did not have what I had to take this into account and ignore it when I detected a message that was incomplete.

This same logic applies to virtually any type of serial communication, whether it is a serial port, TCP / IP or Bluetooth using RFCOMM for example.

    
06.02.2015 / 13:48