Unable to get the value from the function.

Hi!

Sorry I am a new to c++. Been trying this all day.
I couldn't figure the right way to get the value from this function.

I am using Arduino Genuino 101, trying to get the data via BLE in Central mode.

This code basically gets the data from the function imu.value().
I am trying to get the address of imu.value and trying to get the data its pointing to.

while (peripheral.connected()) 
  {  
      const unsigned char *data = imu.value();
      size_t len = imu.valueLength();
      addReceiveBytes((const uint8_t*)data, len);  
  }
void addReceiveBytes(const uint8_t* bytes, size_t len) 
{
  for (size_t i = 0; i < len; i++) 
  {
        char value_ = *reinterpret_cast<char *>(bytes[i]);   // Gets the value of the pointer
        Serial.println(value_);
  }
}

Here is the imu.value() Function: from Github

const byte* BLECharacteristic::value() const
{
    const byte* value_temp = NULL;
    BLECharacteristicImp *characteristicImp = getImplementation();
    if (NULL != characteristicImp)
    {
        value_temp = characteristicImp->value();
    }
    return value_temp;
}

Any suggestion is much appreciated.

timontunes:
This function returns a const.

No, it returns a pointer to a const byte. It's unclear what you are trying to do.

gfvalvo:
No, it returns a pointer to a const byte. It's unclear what you are trying to do.

The received BLE data values are accessed by imu.value() function.
I am trying to read the values.
I am not sure how the const byte pointer works to do so.

I removed the statement as it's wrong. " This function returns a const"

The function indeed returns a pointer to a const byte.
How do I access the value of the const byte pointer?

Delta_G:
What does "const" mean to you?

I perceive it as a constant that doesn't change value.
What I thought was, the constant is having the address.
Which is a const, but the value pointed by that address varies.

What does "read the values" mean? Do you want to put them in array? Print them to Serial monitor? Are the values ASCII characters or binary numbers?

gfvalvo:
What does "read the values" mean? Do you want to put them in array? Print them to Serial monitor? Are the values ASCII characters or binary numbers?

For now just to Print them in a Serial monitor. The values are char array I suppose.

timontunes:
I perceive it as a constant that doesn't change value.
What I thought was, the constant is having the address.
Which is a const, but the value pointed by that address varies.

I believe it is left associative or if it starts the line then it goes to the first thing on its right. So in this case the byte is what gets the const. So you can change what address it points to, but not the value in that location. It would be the same if you had written:

byte const *

If you want a pointer where you can change the value pointed to but not the location pointed to then I think you use:

byte * const

Or if you want neither to be able to change then you use:

const byte * const

or even

byte const * const

Sorry for removing that post. I was going to edit and for some reason just hit delete.

Delta_G:
I believe it is left associative or if it starts the line then it goes to the first thing on its right. So in this case the byte is what gets the const. So you can change what address it points to, but not the value in that location. It would be the same if you had written:

byte const *

If you want a pointer where you can change the value pointed to but not the location pointed to then I think you use:

byte * const

Or if you want neither to be able to change then you use:

const byte * const

or even

byte const * const

Sorry for removing that post. I was going to edit and for some reason just hit delete.

Thanks a lot! That was insightful.
So I can point it to another address and access the value ?
How to do that, since this is an array of bytes I suppose ?
I know the length of the array.

const byte* BLECharacteristic::value() const
{
    const byte* value_temp = NULL;
    BLECharacteristicImp *characteristicImp = getImplementation();
    if (NULL != characteristicImp)
    {
        value_temp = characteristicImp->value();
    }
    return value_temp;
}

timontunes:
The values are char array I suppose.

Well, it's pretty important to know. If they are a c-string (aka null-terminated char array), then this will work:

  const byte* ptr = imu.value();
  Serial.println((const char *) ptr);

If they are a non-terminated char array, then this:

  const byte* ptr = imu.value();
  size_t len = imu.valueLength();  
  for (uint16_t i = 0; i < len; i++) {
    char c = (char)(*(ptr + i));
    Serial.print(c);
  }
  Serial.println();

Of course, either of the above will print garbage if they aren't ASCII characters.

gfvalvo:
Well, it's pretty important to know. If they are a c-string (aka null-terminated char array), then this will work:

  const byte* ptr = imu.value();

Serial.println((const char *) ptr);



If they are a non-terminated char array, then this:


const byte* ptr = imu.value();
  size_t len = imu.valueLength(); 
  for (uint16_t i = 0; i < len; i++) {
    char c = (char)(*(ptr + i));
    Serial.print(c);
  }
  Serial.println();



Of course, either of the above will print garbage if they aren't ASCII characters.

The first one printed a const value. The second one didn't print anything.
Thanks a lot!
Trying to print the string
I was also trying with this function from Github
imu.stringValue()

String BLEAttributeWithValue::stringValue() const
{
    const char *retTemp = (const char *)this->value();
    return retTemp;
}

I did similar to the first code, it threw error saying cannot convert string to 'const String*'

      const String* ptr = imu.stringValue();
      Serial.println((const String *) ptr);

I am not sure how to do similarly.
Thank you for your time!

How to do that, since this is an array of bytes I suppose ?

You're going to have to do better than suppose. If you don't know then show us where it comes from.

 const String* ptr = imu.stringValue();
      Serial.println((const String *) ptr);

But that function returns just a String, not a String pointer.

[code] String ptr = imu.stringValue();
      Serial.println(ptr);

Delta_G:
You're going to have to do better than suppose. If you don't know then show us where it comes from.

Yes, I should. I will try to show where it comes from.

A Intel curie tiny tile board send char array via BLE.
In my phone BLE app NRF connect receive it as a hexadecimal array,
something like F0-FA-06-37-BD-5D-FF-60-FF-4C-00.

I am trying to read this in an arduino 101 instead of the phone.

This is the whole code below.
I am using this library from Github ArduinoCore-arc32/libraries/CurieBLE.

I was modifying this sample code.

#include <CurieBLE.h>

int a[6];
static volatile size_t rxHead;
volatile uint8_t rxBuffer[12];
String bb;
String cc;
void setup() 
{
  Serial.begin(115200);
  BLE.begin();
  Serial.println("Ble begins");
  BLE.scanForUuid("F7580003-153E-D4F6-F26D-43D8D98EEB10");
}
      //BLECharacteristic imu = peripheral.characteristic("F7580003-153E-D4F6-F26D-43D8D98EEB13");

void loop() 
{
  BLEDevice peripheral = BLE.available();
 if (peripheral) 
 {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    /* see if peripheral is a SensorTag
     * The localName, CC2650 SensorTag, is in the Scan Response Data packet.
     * If this is not the expected name, please change the following
     * if-statement accordingly.
     */
    if (peripheral.localName() == "Imu") 
    {
      // stop scanning
      BLE.stopScan();
      Serial.println("found IMU ");
      //monitorSensorTagButtons(peripheral);
      readData(peripheral);
      // peripheral disconnected, start scanning again
      BLE.scan();
      
    }
}
}

void readData(BLEDevice peripheral)
{
   Serial.println("Connecting ...");
  if (peripheral.connect()) 
  {
    Serial.println("Connected");
  } 
  else 
  {
    Serial.println("Failed to connect!");
    return;
  }
  
Serial.println("Discovering attributes of service F7580003-153E-D4F6-F26D-43D8D98EEB10 ...");
  if (peripheral.discoverAttributesByService("F7580003-153E-D4F6-F26D-43D8D98EEB10")) 
  {
    Serial.println("Attributes discovered");
  } 
  else 
  {
    Serial.println("Attribute discovery failed.");
    peripheral.disconnect();
    return;
  }

BLECharacteristic imu = peripheral.characteristic("F7580003-153E-D4F6-F26D-43D8D98EEB13");

Serial.println("Subscribing to characteristic ...");
  if (!imu) 
  {
    Serial.println("no characteristic found!");
    peripheral.disconnect();
    return;
  } 
  else if (!imu.canSubscribe()) 
  {
    Serial.println("characteristic is not subscribable!");
    peripheral.disconnect();
    return;
  } 
  else if (!imu.subscribe()) 
  {
    Serial.println("subscription failed!");
    peripheral.disconnect();
    return;
  } 
  else 
  {
    Serial.println("Subscribed");
  }

  while (peripheral.connected()) 
  {  

//      const String* ptr = imu.stringValue();
//      Serial.println((String) imu.stringValue());
//      const byte* ptr = imu.value();
//      size_t len = imu.valueLength();  
//      for (uint16_t i = 0; i < len; i++) 
//      {
//        char c = (char)(*(ptr + i));
//        Serial.print(c);
//      }
//      Serial.println();
  
  }
}

Delta_G:

 const String* ptr = imu.stringValue();

Serial.println((const String *) ptr);




But that function returns just a String, not a String pointer. 




[code] String ptr = imu.stringValue();
      Serial.println(ptr);

Sorry, it's stupid of me.
Sorry for the trouble.
I have to check my code on other things I suppose.

Thanks a lot for your time.
I think I will go and read some c++.