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.

9
  • Because Arduino send sigle bytes, you have to read single bytes ReadByte(). Commented Dec 22, 2016 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. Commented Dec 22, 2016 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. Commented Dec 22, 2016 at 16:23
  • Also both your analog channels are writing to myBuff[5] and none to myBuff[7]. Commented Dec 22, 2016 at 16:24
  • And you are initialising your buffer with 9 values. Commented Dec 22, 2016 at 16:30

1 Answer 1

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; }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.