Search code examples
javascriptc++arduinobluetooth-lowenergystd

C++ convert std::string to byte array


Bear with me as I'm new to C++, pointers, etc..

I'm sending over raw image data to a microcontroller using Arduino via BLE.

Currently, I'm using JS to send the raw data over as an ArrayBuffer. However (surprisingly), it looks like I can only receive the data on the Arduino side as a String and not raw Bytes.

I verified this by looking at the param the onWrite cb takes. It takes a BLECharacteristic Object. Doc here BLECharacteristic doesn't show any instance methods or anything to receive data...just the getValue fn which returns a String. Printing this String out on Serial shows weird symbols..guessing just something similar to ArrayBuffer.toString()...?

I'd then like to convert this String data to a Byte array so that I can display it on an epaper display.

Here is my BLE onWrite cb.

class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
    std::string value = pCharacteristic->getValue();

    int n = value.length();

    char const *cstr = new char [value.length()+1];
    std::strcpy (cstr, value.c_str());

    display.drawBitmap(0,0,*c,296,128,EPD_BLACK);
  }
}};

This doesn't work and I get invalid conversion from 'const char*' to 'char*'

Note: The format the drawBitmap function is expecting is const uint8_t (byte array). drawBitmap docs

However, I've gotten this to work by using a hardcoded array in the format of

const unsigned char foo [] = {
    0xff, 0xff, 0xff, 0xff, 0xff
};

So I'm confused on the difference between const char [], const uint8_t, and byte array. May someone please explain the differences? Then - how can I convert my String of raw data into that the drawBitmap fn is expecting?


Solution

  • Seems to be quite simple, std::strcpy() needs a pointer to writable (not const) memory, therefor the pointer cstr may not point to const char, leave out const and the following should work:

    char *cstr = new char [value.length()+1];
    std::strcpy (cstr, value.c_str());
    

    If you feel fancy, I believe you could use a const pointer to char, meaning the content can be changed but not the pointer itself, this however seems unnecessary:

    char * const cstr = new char [value.length()+1];
    std::strcpy (cstr, value.c_str());