Go Down

Topic: Send byte array (Read 4721 times) previous topic - next topic

joshwl2003

I am trying to read all of the sensor values that I need and send one byte array over the serial port to be read by some client code. When I send the byte array I get garbage data in my client code. Here is my sketch
Code: [Select]

int sensor1pin = A0;
int sensor2pin = A1;
int sensor3pin = A2;
int sensor4pin = A3;

int sensor1Value=0;
int sensor2Value=0;
int sensor3Value=0;
int sensor4Value=0;

byte dataToSend[65];
byte conversionByte[2];

//Changes int LSB
void integerToBytes(int val, byte b[2]) {
b[0] = (byte)(val & 0xff);
b[1] = (byte)((val >> 8) & 0xff);
//Serial.println(b[0]);
//Serial.println(b[1]);
}

void setup()
{
/* add setup code here */
int i=0;
for (i=0; i<65; i++)
{
dataToSend[i]=0x00;
}

Serial.begin(115200);
}

void loop()
{
/* add main program code here */
sensor1Value = analogRead(sensor1pin);
sensor2Value = analogRead(sensor2pin);
sensor3Value = analogRead(sensor3pin);
sensor4Value = analogRead(sensor4pin);

//Serial.println("Parsing sensor 1");
integerToBytes(sensor1Value,conversionByte);
dataToSend[0] = 0x00;
dataToSend[1] = conversionByte[0];
dataToSend[2] = conversionByte[1];
//Serial.println(sensor1Value);

//Serial.println("Parsing sensor 2");
integerToBytes(sensor2Value,conversionByte);
dataToSend[3] = 0x01;
dataToSend[4] = conversionByte[0];
dataToSend[5] = conversionByte[1];
//Serial.println(sensor2Value);

//Serial.println("Parsing sensor 3");
integerToBytes(sensor3Value,conversionByte);
dataToSend[6] = 0x02;
dataToSend[7] = conversionByte[0];
dataToSend[8] = conversionByte[1];
//Serial.println(sensor3Value);

//Serial.println("Parsing sensor 4");
integerToBytes(sensor4Value,conversionByte);
dataToSend[9] = 0x03;
dataToSend[10] = conversionByte[0];
dataToSend[11] = conversionByte[1];
//Serial.println(sensor4Value);

dataToSend[12] = 0x0A;

//int i;
////Serial.println("Printing byte array values");
//for (int i = 0; i < 12; i+=3)
//{
// Serial.print(dataToSend[i]);
// Serial.print(" ");
// Serial.print(dataToSend[i+1]);
// Serial.print("|");
// Serial.println(dataToSend[i+2]);
//}

//Serial.println("Sending data over serial write")
Serial.write(dataToSend,65);
//Serial.flush();
}


When I uncomment the print statements I get the data I expect to receive but when I use serial write I do not get the packet in the format I desire.

I have also tried to have the buffer as pointer but that causes memory issues with in the program.

Any help would be great.

holmes4

Serial.write(dataToSend,65);

The second parameter is the number of bytes you want sent and not the length of the array.

Mark

joshwl2003

Even with changing that number I still get bad data on the other side. The C# code parsing the data looks like this
Code: [Select]

            port.Read(buffer, 0, 65);
           
            for (int i = 0; i < 12; i+=3)
            {
               portChanged = int.Parse(buffer[i].ToString());
               value = Convert.ToInt32(BitConverter.ToUInt16(buffer, i+1));
               Console.WriteLine("Port {0} Bytes {1}|{2} Value {3}", buffer[0],buffer[i+1],buffer[i+2],value);
            }
           
            System.Threading.Thread.Sleep(50);


If I look at the buffer the values in it are not what should be getting sent over.

holmes4

What is being sent? What do you expect to see?

Mark

joshwl2003

I would expect to see the values on the sensors so I should get 2 bytes for each number between 0 and 255 and get the port numbers. I get random data sometimes it is all 0's sometimes it has random numbers inside of the data. I know that the values on each port should be 0,1023, and around 600. This is because I jumped the arduino voltage outputs and grounds to the pins.

holmes4

Print converts the number to a string of chars. Write just sends the value of the byte "as is".

Mark

PeterH

On the receiving side you are parsing the received data as though it was a decimal ascii string. For that to work, you need to send it as a decimal ascii string. That's what print() does - it converts the value you give it to ascii, and sends the ascii characters over the serial port. If you send it using write(), the byte values you provide go over the wire directly.

joshwl2003

Can print has no option to send a byte array. Are there any methods of doing this?

PaulS

First, you need to decide whether you want to send binary data, as the Arduino is doing, or ASCII data, as the C# code is expecting. Once you determine that, we can help.
The art of getting good answers lies in asking good questions.

joshwl2003

I do not care how the data is sent. The biggest things that I care about are being able to send all of my sensor data in 1 packet and not having to send the data as a string that requires string parsing when I receive it. Is there a standard way that this is typically done in the arduino? Embedded systems a new area to me.

Thanks for all of the help! 

PaulS

Quote
and not having to send the data as a string that requires string parsing when I receive it.

So, why have you written all the code to do parsing?
The art of getting good answers lies in asking good questions.

joshwl2003

What I mean by that is I do not want to send the data as string an example would be "0|1024|1|150" then have to convert this into a string array and then have to convert these values into what I really need.

PeterH

I wish you'd just make up your mind whether you're going to send the data as an ASCII string or not. Whatever encoding scheme you decide, implement BOTH SIDES to use the same encoding scheme.

Currently, the receiver expects it as an ASCII decimal string. Parsing and decoding that is no big deal and I don't understand your objection to doing that.

If you want to send the data in a binary format then you will need to do some work to make it work at all, and some more work to make it work reliably. Your integer values are too big to fit into a byte so you will need to send multiple bytes per value. So you will need to have some scheme to decide which pair of bytes out of this byte stream represents a single integer value, and then which set of numbers out of the resulting sequence represents a result set. It's all doable, but writing a robust binary encoding scheme is much harder than writing an ASCII coding scheme. Unless you have a compelling reason for avoiding ASCII, such as running out of bandwidth, I think your attempts to move away from ASCII (despite the fact that you have already implemented it on both sides) is misguided.

joshwl2003

I'm sorry for being confusing about this topic. This is a very new area in programming for me. Again my question remains how can I send an array of data from an arduinio. As for parsing I can handle binary or ascii with out a problem but I need help getting all of my data from the arduino into C# in 1 data packet. I figured that using write would be best because it can take in a byte array which I had set up and it has the correct data in it. If print is the way to go I am okay with that and I understand what type of data I will get on the other side. My question still remains how do I read in multiple sensors put their values into an array of data and then send the data using a print or write statement? If you could provide some example code I would greatly appreciate it.

holmes4

You don't need any example code. The code you first posted does both. The commented you prints do it in ascii and the writes do it as binary values.

Mark

Go Up