1

I have an Arduino that send on serial port some information revealed by analogical pin. Anyway, in the Arduino code (that I can not modify) is used Serial.write() instead of Serial.print() in order to print a buffer of char. As a consequence, if in my C# software I read the information with a "simple" ReadLine(), the data are incomprehensible. How can I read these type of data with C#?

It is the Arduino code:

#include <compat/deprecated.h>
#include <FlexiTimer2.h>

#define TIMER2VAL (1024/256)       // 256Hz - frequency                    
volatile unsigned char myBuff[8];
volatile unsigned char c=0;
volatile unsigned int myRead=0;
volatile unsigned char mych=0;
volatile unsigned char i;

void setup() {
 pinMode(9, OUTPUT);

noInterrupts();

 myBuff[0] = 0xa5;    //START 0
 myBuff[1] = 0x5a;    //START 1
 myBuff[2] = 2;       //myInformation
 myBuff[3] = 0;       //COUNTER
 myBuff[4] = 0x02;    //CH1 HB
 myBuff[5] = 0x00;    //CH1 LB
 myBuff[6] = 0x02;    //CH2 HB
 myBuff[7] = 0x00;    //CH2 LB
 myBuff[8] = 0x01;    //END


  FlexiTimer2::set(TIMER2VAL, Timer2);
 FlexiTimer2::start();

  Serial.begin(57600);
 interrupts(); 
}

void Timer2()
{
  for(mych=0;mych<2;mych++){
    myRead= analogRead(mych);
    myBuff[4+mych] = ((unsigned char)((myRead & 0xFF00) >> 8));  // Write HB
    myBuff[5+mych] = ((unsigned char)(myRead & 0x00FF)); // Write LB
  }

  // SEND
  for(i=0;i<8;i++){
    Serial.write(myBuff[i]);
  }

  myBuff[3]++;

}

void loop() {

 __asm__ __volatile__ ("sleep");

}

And this is the C# method that read from serial port

public void StartRead()
    {
        msp.Open(); //Open the serial port

        while (!t_suspend)
        {
            i++;
            String r = msp.ReadLine();
            Console.WriteLine(i + ": " + r);
        }
    }

EDIT: I would as output an array of string that correspond to the data of Arduino output. If I record everything as an array of byte, I have not the information about start and the end of the array. I can edit the code as:

public void StartRead()
    {
        msp.Open(); //Open the serial port
        ASCIIEncoding ascii = new ASCIIEncoding();
        while (!t_suspend)
        {
            i++;
            int r = msp.ReadByte();
            String s = ascii.getString((byte)r); // here there is an error, it require an array byte[] and not a single byte
            Console.WriteLine(i + ": " + r);
        }
    }

How I can have the same Arduino array value (but as a String) in my C# software, considering that the starting value is every time 0xa5 and the end is 0x01.

youngz
  • 179
  • 2
  • 16
  • Because Arduino send sigle bytes, you have to read single bytes `ReadByte()`. – H.G. Sandhagen Dec 22 '16 at 15:31
  • Ok, but the output is a `char`. If I use `ReadByte()` it return an integer, and I do not know how to cast this integer into a char. – youngz Dec 22 '16 at 15:40
  • `ReadLine()` reads a line that ends with a newline character. You are just sending 8 bytes that aren't necessarily all printable characters, so I don't know why are you expecting it to be comprehensible. – gre_gor Dec 22 '16 at 16:23
  • Also both your analog channels are writing to `myBuff[5]` and none to `myBuff[7]`. – gre_gor Dec 22 '16 at 16:24
  • And you are initialising your buffer with 9 values. – gre_gor Dec 22 '16 at 16:30
  • @gre_gor: I didn't check the arduio code, because youngz wrote:" in the Arduino code (that I can not modify)". You are write. This code wiill not work. – H.G. Sandhagen Dec 22 '16 at 16:39
  • I am sorry, i see that the arduino code is worng just now. It is only a simplification (in order to understand) about how it send the information. The real arduino code works, but post all Arduino code is pretty longer, with many more channels and much more interaction between the data – youngz Dec 22 '16 at 16:49
  • @gre_gor I know that I can not read with a ReadLine, I edit the main post in order to explain better what I am looking for. Thanks – youngz Dec 22 '16 at 16:52
  • You still won't get anything comprehensible with that code, since that data isn't for printable ASCII codes. If you want to print out data for debugging, use H.G. Sandhagen's answer and [convert the byte array to a hexstring](http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa). – gre_gor Dec 22 '16 at 16:59

1 Answers1

1

Arduino sends a telegram of several bytes. You can read it into a byte array:

byte[] telegram = byte[msp.BytesToRead];
msp.Read(telegram, 0, msp.BytesToRead);

To get the data from the byte array you have to interpret the bytes (See example below). Of course you could create a string from the properties of the Telegram class:

    class Telegram {
    public Telegram(byte[] tel) {
        // Check start bytes ( 0xa5, 0x5a );
        Info = tel[2];
        Counter = tel[3];
        Channel1 = BitConverter.ToInt16(new byte[] { tel[5], tel[4] }, 0); // Switch lo/hi byte
        Channel2 = BitConverter.ToInt16(new byte[] { tel[7], tel[6] }, 0);// Switch lo/hi byte
        // check tel[8] == 1 for end of telegram
     }    
     public int Info { get; private set; }
     public int Counter { get; private set; }
     public int Channel1 { get; private set; }
     public int Channel2 { get; private set; }
}
H.G. Sandhagen
  • 772
  • 6
  • 13