Go Down

Topic: Unable to get the value from the function. (Read 156 times) previous topic - next topic

timontunes

Jan 12, 2019, 06:04 pm Last Edit: Jan 12, 2019, 06:15 pm by timontunes
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.


Code: [Select]

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

Code: [Select]

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.

gfvalvo

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

timontunes

#2
Jan 12, 2019, 06:14 pm Last Edit: Jan 12, 2019, 06:26 pm by timontunes
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?

timontunes

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.

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?

timontunes

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.

Delta_G

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:

Code: [Select]
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:

Code: [Select]
byte * const

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

Code: [Select]
const byte * const

or even

Code: [Select]
byte const * const

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

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

timontunes

#7
Jan 12, 2019, 06:48 pm Last Edit: Jan 12, 2019, 06:50 pm by timontunes
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:

Code: [Select]
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:

Code: [Select]
byte * const

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

Code: [Select]
const byte * const

or even

Code: [Select]
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.
Code: [Select]

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

gfvalvo

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:

Code: [Select]

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

If they are a non-terminated char array, then this:
Code: [Select]

  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.

timontunes

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

Code: [Select]

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

If they are a non-terminated char array, then this:
Code: [Select]

  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()
Code: [Select]

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*'

Code: [Select]

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


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

Delta_G

Quote
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.  
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Delta_G

#11
Jan 12, 2019, 07:13 pm Last Edit: Jan 12, 2019, 07:14 pm by Delta_G
Code: [Select]
const String* ptr = imu.stringValue();
      Serial.println((const String *) ptr);


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


Code: [Select]
[code] String ptr = imu.stringValue();
      Serial.println(ptr);
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

timontunes

#12
Jan 12, 2019, 07:25 pm Last Edit: Jan 12, 2019, 07:37 pm by timontunes
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.

Code: [Select]

#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();
 
  }
}





timontunes

Code: [Select]
const String* ptr = imu.stringValue();
      Serial.println((const String *) ptr);


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


Code: [Select]
[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++.

Go Up