Pages: [1]   Go Down
Author Topic: Determine size of uint8_t* and convert to ASCII?  (Read 4594 times)
0 Members and 1 Guest are viewing this topic.
Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

I have searched the forum for a way to get the length of a uint8_t*, but to no avail. Many posts using this datatype have a specified length, but I do not know what the length will be. I guess there is a way to do it, and I have played with/searched for length, len(), size, etc But no luck yet, hope someone here can help.

I have an Arduino with Xbee in API mode receiving data. I am trying to get the data into a string eventually. To get the data from the package I received, I do:

Code:
uint8_t* rxData = rx.getData();

Then I want to go through all the elements in rxData and convert them to byte. With a testprogramm I send "Hello World!" and I am able to convert that into readable format using:
Code:
Serial.print(rx.getData(0), BYTE);
Serial.print(rx.getData(1), BYTE);
Serial.print(rx.getData(2), BYTE);
Serial.print(rx.getData(3), BYTE);
Serial.print(rx.getData(4), BYTE);
Serial.print(rx.getData(5), BYTE);
Serial.print(rx.getData(6), BYTE);
Serial.print(rx.getData(7), BYTE);
Serial.print(rx.getData(8), BYTE);
Serial.print(rx.getData(9), BYTE);
Serial.print(rx.getData(10), BYTE);
Serial.println(rx.getData(11), BYTE);

But that is only useful if I know up front how much data is coming. How could I get from an unknown length to a String on which I can do the various manipulations I want to do? (concat another string, split up, etc)

Regards,
Arno

p.s. I am currently using a fixed length but that is set way higher than what is needed, just in case. I would like to know so the code uses the minimum amount of memory.

« Last Edit: October 22, 2010, 09:01:16 am by aetjansen » Logged

Central Europe
Offline Offline
Edison Member
*
Karma: 7
Posts: 1220
Use the Source, Luke.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

An uint8_t * is just a pointer to a character (8 bit integer). No size information there for you, you have to know that on your own how many characters you can fit into it or available. This is probably the #1 security vulnerability and reason for bug in C code today, which is an awful damn lot.

For text-strings, in C the convention is it goes on until you encounter a character with ascii value 0. Most C string functions like strlen, strcat etc expect this. For functions filling that kind of buffer, safe coding and intercourse guides advice to pass a buffer length to the function and use a rubber. Depending on the circumstances, you might get away without this, but you'll have to live the consequences.

Korman
« Last Edit: October 22, 2010, 09:17:06 am by Korman » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am trying to get the data into a string eventually.
Put it into a String as you read it, using the += operator:

Code:
String inData;

inData += rx.getData();
The String object allocates space for some number of characters. When that space is full, a larger space is allocated, the existing string is copied there, and the original space is freed.

You should be sending some end of packet marker, so that you know when all the data has been received.
Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hm, I tried that method to get it into a String, but I get an error message while doing so:
"conversion from 'uint8_t*' to 'const String' is ambiguous"

Still trying to wrap my head around the uint8_t pointer... :-) Will get there eventually :-)
Logged

Portugal
Offline Offline
God Member
*****
Karma: 6
Posts: 962
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

An uint8_t is the same as a unsigned short, or an unsigned char and takes 8bits in the memory.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25735
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
An uint8_t is the same as a unsigned short, or an unsigned char

Only one of those statements is true.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have an Arduino with Xbee in API mode receiving data. I am trying to get the data into a string eventually. To get the data from the package I received, I do:

Code:
uint8_t* rxData = rx.getData();
I think it's time you tell us what rx is, so that we can confirm that you are using it correctly.

If rx.getData() is really returning a pointer to a uint8_t sized block of memory, there WILL be some what to cast that to a character pointer that String can use.
Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

On the sending Arduino, I have this piece of code loading the payload for the Xbee:
Code:
String testString = "21.45,999,999";
    Serial.println(testString);
    for (int i = 0; i < testString.length(); i++) {
      payload[i] = testString.charAt(i);
      //Serial.print(payload[i]);
    }
    //payload[0] = pin5 >> 8 & 0xff;
    //payload[1] = pin5 & 0xff;
    
    xbee.send(zbTx);

On the receiver Arduino, this is the part where the payload is handled:
Code:
// set dataLed PWM to value of the first byte in the data
        analogWrite(dataLed, rx.getData(0));
        // process the data from here on
        uint8_t* rxData = rx.getData();
        //int rxDataSize = strlen(rxData);
        Serial.println("Received data:");
        Serial.println("<START DATA>");
        String dataString;
        for (int i = 0; i < 13; i++) {
          
          dataString +=  rx.getData(i);
          Serial.print(rx.getData(i), BYTE);
        }
        Serial.println("<END DATA>");

The first 2 lines in the receiver code are the lines that are present in the example code. I must be missing something, or I have my math wrong somehow I think..

Although this "limitation due to ignorance" caused me to try and get the data I want into smaller package size and that means I am learning about bit math so I can get 8 true/false statuses into one byte... :-)

Thanks for all the help!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are sending 13 characters, and reading 15 bytes.

1)         analogWrite(dataLed, rx.getData(0));
2)        uint8_t* rxData = rx.getData();
3-15)          dataString +=  rx.getData(i);

Quote
I am learning about bit math so I can get 8 true/false statuses into one byte...
There are functions, bitSet, bitClear, bitRead, and bitWrite, that hide all the complexity.

Of course, we still don't know what an rx object is, so we can't tell that rx.getData() actually returns a uint8_t pointer. It's also not clear where/how you use rxData, and it's no longer clear specifically what your problem is, and what works, or doesn't.
Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the reply.

The rx is obtained from the xbee library (http://code.google.com/p/xbee-api/):

Code:
ZBRxResponse rx = ZBRxResponse();

The getData() and getData(i) functions from the library:
Code:
uint8_t RxDataResponse::getData(int index) {
      return getFrameData()[getDataOffset() + index];
}

uint8_t* RxDataResponse::getData() {
      return getFrameData() + getDataOffset();
}

And getFrameData() and getDataOffset():
Code:
uint8_t* XBeeResponse::getFrameData() {
      return _frameDataPtr;
}

// markers to read data from packet array.  this is the index, so the 12th item in the array
uint8_t ZBRxResponse::getDataOffset() {
      return 11;
}

About the code snippets I pasted in the previous post:

I get that this line does not do much since I never use/reference rxData again:
Code:
uint8_t* rxData = rx.getData();

But, I don't follow you where you say I read 15 characters  :-? In this line I specifically index the first element:
Code:
analogWrite(dataLed, rx.getData(0));

Then, I created another pointer to the same data (the line above where rxData points to the same as rx.getData();

Then, I cycle from 0 to 13 through the data, indexing each character. I thought that means that I start form the beginning again? But, form your comment I take it I made a mistake there? In other words:
Index 0 in this line:
Code:
analogWrite(dataLed, rx.getData(0));

Is not the same as index 0 in (when i has value 0):
Code:
dataString +=  rx.getData(i);




« Last Edit: October 28, 2010, 04:04:48 pm by aetjansen » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The rx is obtained from the xbee library (http://code.google.com/p/xbee-api/):
OK. That's helpful.

Quote
I get that this line does not do much since I never use/reference rxData again:
That's actually the only call you need. More on that later.

Quote
But, I don't follow you where you say I read 15 characters. In this line I specifically index the first element:
You are right. I was wrong. You are only reading 13 characters.

The first call returns a pointer to the data. The other calls are specifically returning one character from the array that rxData also points to. The elements in the array being pointed to are the same size as a char. It would have been possible for the function to simply return a char *, but the uint8_t pointer offers more flexibility.

You should be able to simply cast that pointer to a char pointer, and pass the cast pointer to strlen, to get the length of data.
Logged

Pages: [1]   Go Up
Jump to: