1

A few hours since I started messing with my first Arduino and I was trying to understand a small program and need some help. The program sends out the MAC address to the serial port. As it's little endian, the "printBufferReverse" reverses the buffer as shown below. But instead of sending this data to the serial port, how do I store the same data into a string variable? Thanks so much

#include <bluefruit.h>
void scan_callback(ble_gap_evt_adv_report_t* report)
{
  uint8_t len = 0;
  uint8_t buffer[32];
  memset(buffer, 0, sizeof(buffer));

  // MAC is in little endian --> print reverse
  // NOTE: I want to store this into a string variable
  // NOTE: the reversing
  Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
  Serial.print("\n");

  /* TX Power Level */
  if (Bluefruit.Scanner.parseReportByType(report, 
    BLE_GAP_AD_TYPE_TX_POWER_LEVEL, buffer, sizeof(buffer)))
    {
      Serial.printf("%14s %i\n", "TX PWR LEVEL", buffer[0]);
      memset(buffer, 0, sizeof(buffer));
    }
}

And the below line how do I store the data to a string instead of sending to serial port? It's adding a hypen to make the end result look like this:12-09-69-57-45-45-43-41-52-45-20

Serial.printBuffer(report->data, report->dlen, '-');

I don't want to send this to serial port but to store in a string variable.

This is the board that I am using: https://www.adafruit.com/product/3406

Complete code

/*********************************************************************
 This is an example for our nRF52 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

#include <bluefruit.h>

/* For a list of EIR data types see:
 *    https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
 *    Matching enum: cores/nRF5/SDK/components/softdevice/s132/headers/ble_gap.h */

void setup() 
{
  Serial.begin(115200);

  Serial.println("Scanning for beacons");
  Serial.println("------------------------------------\n");

  // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
  // SRAM usage required by SoftDevice will increase dramatically with number of connections
  Bluefruit.begin(0, 1);

  // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
  Bluefruit.setTxPower(4);

  /* Set the device name */
  Bluefruit.setName("Bluefruit52");

  /* Set the LED interval for blinky pattern on BLUE LED */
  Bluefruit.setConnLedInterval(250);

  /* Start Central Scanning
   * - Enable auto scan if disconnected
   * - Filter out packet with a min rssi
   * - Interval = 100 ms, window = 50 ms
   * - Use active scan (used to retrieve the optional scan response adv packet)
   * - Start(0) = will scan forever since no timeout is given
   */
  Bluefruit.Scanner.setRxCallback(scan_callback);
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.filterRssi(-80);
  //Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE); // only invoke callback if detect bleuart service
  Bluefruit.Scanner.setInterval(160, 80);       // in units of 0.625 ms
  Bluefruit.Scanner.useActiveScan(true);        // Request scan response data
  Bluefruit.Scanner.start(0);                   // 0 = Don't stop scanning after n seconds

  Serial.println("Started ...");
}

void scan_callback(ble_gap_evt_adv_report_t* report)
{
  uint8_t len = 0;
  uint8_t buffer[32];
  memset(buffer, 0, sizeof(buffer));
  boolean hasPayload;
  String bleDvcID;
  String advPayload;

  hasPayload = false;
  bleDvcID = "";
  advPayload = "";

  /* Display the timestamp and device address */
  /*
  if (report->scan_rsp)
  {
    Serial.printf("[SR%10d] Packet received from ", millis());
  }
  else
  {
    Serial.printf("[ADV%9d] Packet received from ", millis());
  }
  */
  // MAC is in little endian --> print reverse
  // bleDvcID = printBufferReverse(report->peer_addr.addr, 6, ':');
  // char buffer[18] = "";
  /*
    snprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X", 18, 
        report->peer_addr.addr[5],
        report->peer_addr.addr[4],
        report->peer_addr.addr[3],
        report->peer_addr.addr[2],
        report->peer_addr.addr[1],
        report->peer_addr.addr[0]
    );
   */
  Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
  Serial.print("\n");

  /* Raw buffer contents */
  Serial.printf("%14s %d bytes\n", "PAYLOAD", report->dlen);
  if (report->dlen)
  {
    hasPayload = true;
    Serial.printf("%15s", " ");
    Serial.printBuffer(report->data, report->dlen, '-');
    Serial.println();
  }

  /* RSSI value */
  Serial.printf("%14s %d dBm\n", "RSSI", report->rssi);

  /* Complete Local Name */
  if(Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, buffer, sizeof(buffer)))
  {
    Serial.printf("%14s %s\n", "COMPLETE NAME", buffer);
    if (strcmp((const char*)buffer, "Temperature Fren")==0)
    {
        Serial.println("Found beacon!");
    }
    memset(buffer, 0, sizeof(buffer));
  }

  /* TX Power Level */
  if (Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_TX_POWER_LEVEL, buffer, sizeof(buffer)))
  {
    Serial.printf("%14s %i\n", "TX PWR LEVEL", buffer[0]);
    memset(buffer, 0, sizeof(buffer));
  }

  /* Check for UUID16 Complete List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid16List(buffer, len);
  }

  /* Check for UUID16 More Available List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid16List(buffer, len);
  }

  /* Check for UUID128 Complete List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid128List(buffer, len);
  }

  /* Check for UUID128 More Available List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid128List(buffer, len);
  }  

  /* Check for BLE UART UUID */
  /*
  if ( Bluefruit.Scanner.checkReportForUuid(report, BLEUART_UUID_SERVICE) )
  {
    Serial.printf("%14s %s\n", "BLE UART", "UUID Found!");
  }
  */
  /* Check for DIS UUID */
  /*
  if ( Bluefruit.Scanner.checkReportForUuid(report, UUID16_SVC_DEVICE_INFORMATION) )
  {
    Serial.printf("%14s %s\n", "DIS", "UUID Found!");
  }
  */
  /* Check for Manufacturer Specific Data */
  /*
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, buffer, sizeof(buffer));
  if (len)
  {
    Serial.printf("%14s ", "MAN SPEC DATA");
    Serial.printBuffer(buffer, len, '-');
    Serial.println();
    memset(buffer, 0, sizeof(buffer));
  }  
  */
  Serial.println();
}

void printUuid16List(uint8_t* buffer, uint8_t len)
{
  /* Serial.printf("%14s %s", "16-Bit UUID"); */
  for(int i=0; i<len; i+=2)
  {
    uint16_t uuid16;
    memcpy(&uuid16, buffer+i, 2);
    /* Serial.printf("%04X ", uuid16); */
  }
  /* Serial.println(); */
}

void printUuid128List(uint8_t* buffer, uint8_t len)
{
  (void) len;
  /* Serial.printf("%14s %s", "128-Bit UUID"); */

  // Print reversed order
  for(int i=0; i<16; i++)
  {
    const char* fm = (i==4 || i==6 || i==8 || i==10) ? "-%02X" : "%02X";
    /* Serial.printf(fm, buffer[15-i]); */
  }

  /* Serial.println(); */
}

void loop() 
{
  // Toggle both LEDs every 1 second
  digitalToggle(LED_RED);

  delay(1000);
}
2
  • 1
    Please edit your question to state which Arduino board you're compiling for. I believe Serial.printBufferReverse() is only part of the Adafruit nRF52 core, and even that only added recently so many people here may not be familiar with it.
    – per1234
    Jan 20 '18 at 19:34
  • Sorry I was supposed to mention that I am using Arduino IDE to program Adafruit nRF52 board. But the question itself isn't tied strictly to a particular board.
    – R.W
    Jan 20 '18 at 19:37
2

You can do it with snprintf_P:

char mac[18];

snprintf_P(mac, 18, (PGM_P)F("%02X-%02X-%02X-%02X-%02X-%02X"),  
    report->peer_addr.addr[5],
    report->peer_addr.addr[4],
    report->peer_addr.addr[3],
    report->peer_addr.addr[2],
    report->peer_addr.addr[1],
    report->peer_addr.addr[0]
);

That is, assuming that report->peer_addr.addr is an array of 6 bytes.

If your strange board doesn't support the _P variants of string manipulation functions then you can drop that part along with the (PGM_P)F(...) bit:

char mac[18];

snprintf(mac, 18, "%02X-%02X-%02X-%02X-%02X-%02X",  
    report->peer_addr.addr[5],
    report->peer_addr.addr[4],
    report->peer_addr.addr[3],
    report->peer_addr.addr[2],
    report->peer_addr.addr[1],
    report->peer_addr.addr[0]
);

Doing so on an Ardunio, though, would waste RAM.

16
  • Thanks. The first one with _P does not exist. And the 2nd one snprintf throws the following error; invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]. Btw this is the board: adafruit.com/product/3406
    – R.W
    Jan 20 '18 at 19:52
  • @M.M, please add the reference about the board to your question
    – jsotola
    Jan 20 '18 at 20:05
  • @jsotola sure, done.
    – R.W
    Jan 20 '18 at 20:07
  • @Majenko, the 2nd function seems to help but I get this error; conflicting declaration 'char buffer [18]'
    – R.W
    Jan 20 '18 at 20:19
  • So choose another name that doesn't conflict with whatever is in the rest of your sketch.
    – Majenko
    Jan 20 '18 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.