Go Down

Topic: Trouble reading 6 byte characteristic (Read 254 times) previous topic - next topic

DrGee

I am trying to read the 6 byte characteristic from the SensorTag barometric sensor.

Arduino IDE v1.81
101 v 2.02
Win 7 64 bit.

The 6 bytes represent two 24-bit unsigned int, one for die temperature and one for pressure.

I can't figure out how to get all 6 bytes unmolested. I may be missing something basic. To explain...

In the case of the humidity sensor, 4 bytes are returned. I can read that characteristic using either

1. unsigned long humval=HumValCharacteristic.unsignedLongValue();
 and then using

unsigned int rawhum=(unsigned int)( ( (humval >> 16) & 0x0000ffffL));
unsigned int rawtemp=(unsigned int)(humval & 0x0000ffffl);

or


2. String ValStr=HumValCharacteristic.stringValue();
and then using

ValStr.getBytes(charStr,ValStr.length()+1);
unsigned int rawtemp=(charStr[1]*256)+charStr[0];
unsigned int rawhum=(charStr[3]*256)+charStr[2];

charStr[] is an array of type byte

The problem I am having with the barometric pressure sensor is that a) it is 6 bytes and there is no arduino numeric data type of a length=6, so the method in 1 above comes up empty and b) the method of 2 above gives me trouble because the 3rd and 6th value are always '0' and the read string from Characteristic.stringValue() gets truncated at the first '0' in the string (as I guess you would expect).


How do I read the six bytes - I must be missing something basic, no?

sandeepmistry

Hi @DrGee,

Could you please share the entire sketch you are using?

Thanks.

DrGee

Hi. Thanks very much for taking the time to give a look and, hopefully, guide me toward a solution.

I have attached two sketches. The first, RH101.ino, reads the humidity sensor and prints out the data (Temperature and relative humidity). It works fine - the values are printed out as you would expect and they are very reasonable and consistent with the temperature and relative humidity from other sources here.

I am using the statement, String ValStr=HumValCharacteristic.stringValue(); to read the characteristic's value. In the code you can see the commented out method that I have also used with the statement unsigned long humval=HumValCharacteristic.unsignedLongValue(); I wrote about this in my initial post.

I am also attaching BP.ino. This sketch attempts to read the barometric pressure sensor with the statement, String ValStr=BPValCharacteristic.stringValue();

It does not work. It outputs a reasonable value for the Die temperature but only a zero for barometric pressure.

The SensorTag's output is in the form Temp[0:7], Temp[8:15], Temp[16:23], Press[0:7], Press[8:15], Press[16:23]  according to the User Guide ..."The data from the pressure sensor consists of two 24-bit unsigned integers: the temperature in bytes 0-2, the pressure in bytes 3-5. The conversion and adjustment calculations is done in firmware, so the application in effect only has to divide the incoming values by 100. Conversion to temperature and pressure is done as shown below. The temperature unit is degrees Celsius, the pressure in hectopascal (hPa). "

I have confirmed that the SensorTag is working without issue and has the latest update firmware v 1.32. This is from testing using the TI SensorTag android app.

I can also connect using nRF Master Control Panel. Using that on an android device, I can confirm that the BP sensor service UUID is F000AA40-0451-4000-B000-000000000000. Moreover, I can 'manually' write a '1' to the control service (at ...AA42) and read the values at ...AA41. I can see the 6 values, as expected. Also, as suspected, the 3rd value is always 0. Since this value (the first 3 bytes) is the die tem on the BMP chip, that is not surprising since if the MSB was not 0, it would indicate an incredibly high temperature. But, that 0 is read as a string terminator, so I miss out on bytes 4-6. In the case of humidity values, those are always non-zero, or at least usually non-zero. Again, for the humidity sensor, I can read the characteristic into a 4-byte long integer and am using the String read to illustrate.

 

I can't figure out how to read those six bytes into a byte array on the 101.

Thank you so much and I am anxious to read what you think.


DrGee

After several hours of head-banging, I am coming to believe that it is not possible to read a characteristic whose value is 6 bytes, beyond any byte value of '0'.

In BLEAttributeWithValue.h I see:

Code: [Select]
    // intepret the value of the attribute with the specified type
    String stringValue() const;
    char charValue() const;
    unsigned char unsignedCharValue() const;
    byte byteValue() const;
    short shortValue() const;
    unsigned short unsignedShortValue() const;
    int intValue() const;
    unsigned int unsignedIntValue() const;
    long longValue() const;
    unsigned long unsignedLongValue() const;
    float floatValue() const;
    double doubleValue() const;


which I think are all of the possibilities for XXX in the statement  Characteristic.XXXValue();

These choices mean that there is a size limitation based upon the Arduino numeric data types. Additionally, the String object type "String" will be '0' terminated, regardless of what the peripheral sends (i.e. any other bytes sent after '0').

Any set of values returned by a peripheral longer than 4 bytes (the greatest width of the data types) or containing a '0' (in the case of a String) can not be read accurately by the 101 in central mode.

So, for example, the SensorTag's BMP290 barometer (returns 6 bytes) and  MPU9250 movement sensor (returns 18 bytes).

Note that there is an example sketch using the SensorTag's key services making the limitation particularly notable since two of the sensors on the device can not be read (if I am understanding this correctly).

@sandeepmistry, or anyone - do you have an opinion on this and if you agree, do you think it should be brought up as an "issue" on GitHub?


sandeepmistry

Hi @DrGee,

Excellent progress!

You're correct about the String values containing "\0" values.

I've made a few minor modifications to the sketches to get them working.

BP

Replace:

Code: [Select]

    String ValStr=BPValCharacteristic.stringValue();
    ValStr.getBytes(charStr,ValStr.length()+1);
 
    unsigned long rawbptemp=(charStr[2]*65536) + (charStr[1]*256)+ charStr[0];
    unsigned int rawbp=(charStr[5]*65536)+ (charStr[4]*256)+ charStr[3];


with:

Code: [Select]

    unsigned long rawbptemp=(BPValCharacteristic[2]*65536) + (BPValCharacteristic[1]*256)+ BPValCharacteristic[0];
    unsigned int rawbp=(BPValCharacteristic[5]*65536)+ (BPValCharacteristic[4]*256)+ BPValCharacteristic[3];


RH101

(just for consistency)

Replace:

Code: [Select]

    String ValStr=HumValCharacteristic.stringValue();
    ValStr.getBytes(charStr,ValStr.length()+1);
    unsigned int rawtemp=(charStr[1]*256)+charStr[0];
    unsigned int rawhum=(charStr[3]*256)+charStr[2];


with

Code: [Select]

    unsigned int rawtemp=(HumValCharacteristic[1]*256)+HumValCharacteristic[0];
    unsigned int rawhum=(HumValCharacteristic[3]*256)+HumValCharacteristic[2];



Any plans to put these sketches up on Github or Project Hub? I think they would be super valuable to the Arduino community!

PS: I was hoping the SensorTag button example sketch would inspire someone to try to access the other SensorTag features.

DrGee

WOW!

Thanks so much for your help. I just was, conceptually hung up on the "must read into a variable" and you showed me that it is already done! I just tested the BP modifications and they seem to work very well. If I understand, I was actually creating the issue by reading it into a String when I didn't need to do that at all. I had all but given up on the barometric pressure and, again, thank you so much.


This is for a project article on the All About Circuits site....Using the 101 to make a data logger with an SD card. I anticipate that I am going to run into the number of characteristics vs. memory limitation that I have read about. My thinking about this is going to a procedure with subscribe to a service->->turn sensor on -> read sensor->unsubscribe and then move on to the next sensor. Since I am directly reading rather than using notifications, I am hoping that this will be a work around.

I really do appreciate your response and it has definitely changed the way I am thinking about this.

sandeepmistry

Hi @DrGee,

Please keep us posted here or by DM'ing me when you publish it online!

Regarding the memory limitations, the next release of the 101 core will make more RAM available to Arduino sketches.

Go Up