Pages: [1]   Go Down
Author Topic: Sending arrays serially  (Read 909 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 81
everywhen
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This one has me stumped.

What I'm trying to do is store an array in my Arduino, that gets updated with sensor values. These values are unsigned integers.

When the computer requests, I want to send back the array. I am trying to cut back on how much code is used. When sending back data to the computer, I "encapsulate" it by first sending each "packet" with a byte indicating the size of the data to follow.

This isn't working, and I think that it might be more simple if I were to just send the whole array as one string.

Before, I had something like this: (excerpts)
const int logSize = 127;
int localLog[logSize];          // Data while pc is off
..
        for (int adcCount=0; adcCount <= logSize; adcCount++) {
          sendData(localLog[adcCount]);
        }

where that sendData is a function to encapsulate the data. that in itself takes up a lot of resources, so I was thinking if I could send the whole array back to the computer without all these loops, that'd be great.

problems with storing data comes in unsigned integers led to the change to that data type.

A separate program, created solely for the purposes of figuring out this challenge, goes like this:
int unsigned fubar[5];

After asking around on IRC for some syntax help, someone brought me to this:
Serial.print(reinterpret_cast<char*>(fubar));

with my array filled with numbers greater than 255, this works great, and sends back 14 bytes representing the values inside this array.

Problems were encountered, however, when a value of 255 or less was in one of these array elements. This is, because if an integer is less than 255, stored in memory it's "most significant byte" would be zero, indicating end of the string I am sending.

So, I want to send this whole array over, expecting some of the values to contain and translate to character zero, which causes the transmission to cease. Of course I know how much data in the end I will be transmitting, but I could not find any routines that let me tell the serial print function that I am passing it a string/char array, and specify the length.

Therefore, if at any where in my array something less than 256 exists, it interrupts the serial communication and my array is not received on the other end, in full.

So my question is, when sending a string (for example) that contains character 0, but is not intended to mark the end of the string, how would I send to the PC the whole entire string?

I did not see in HardwareSerial.h a definition of the print function also accepting the length of the data to be transmitted. How do you go about sending a full string, even if it has these characters in it?

My reason for this packetization is so that my PC software end of the contraption can discriminate between discrete responses to its requests.

TIA
Logged

Chicago IL USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
int myMind = 0;
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to solve this exact same problem in reverse... trying to send an entire array through serial to arduino.... If anyone has any insight on this it would be highly appreciated
Logged

there are 10 types of people in this world, those who can read binary and those who can't.

0
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
After asking around on IRC for some syntax help, someone brought me to this:
Serial.print(reinterpret_cast<char*>(fubar));
someone didn't understand your problem, or was plain wrong.

Your problem is becuase you're sending a chunk of binary data to a function the expects a null-terminated string.
the string version of serial.print will not work for what you're trying to do.  Write a loop to send the data one byte at a time until the whole array is sent.

-j

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 81
everywhen
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

See, that's a little more code-intensive than I wanted. But, I suppose I'll have to do it that way.

Even so, if I have an integer, and call Serial.print(var, BYTE), then if the var is > 255, it won't work.

How would I send an unsigned integer as two bytes? I suppose I could put the LS byte in one var and the ms portion ( that above 0x100 ) in another byte, and send em seperately. Again, it seems to me there should be a way to just send it all in one string by specifying the string (or char array), and length of it. Sort of like how many serial / socket libraries work when receiving data.
Logged

0
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The problem is you don't have space for many libraries on a microcontroller, so just the basics are offered.  If you can send one byte you can loop it and send a block of bytes, so code space isn't wasted on a function to send a block.

One way to solve your problem is:

Code:
#define MAX 127
int i, data[MAX];

...

for (i=0; i<MAX; i++)
{
  Serial.print(data[i] >> 8, BYTE);
  Serial.print(data[i] & 0xFF, BYTE);
}

Another way would be to use a pointer to a byte, copy the starting address of the array to the pointer and loop through it byte-by-byte.  That would be a bit more complex.

-j
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 81
everywhen
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot! I'm not keen on the syntax, so I wouldn't have figured out how to derive the lsbyte/msbyte from an integer, to be sent as a byte.

Hopefully this will work for my application.
Logged

Pages: [1]   Go Up
Jump to: