-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
questionFurther information is requestedFurther information is requested
Description
Hello, I'm trying to use your Adafruit nrf52 library to scan for CODED PHY advertisements on my nrf52840. Do you have any examples of this? The example that I see uses the nRF device to transmit, but I want to receive. I believe that I have replaced the Adafruit library successfully with your implementation. This is what I have for code so far. I'm pretty sure that I'm missing something simple. If you happen to have time to take a look at this, I'd appreciate the help. I only care about the CODED PHY, that's why the other two are commented out. I'm receiving those, just fine.
#include <bluefruit.h>
void setup()
{
Serial.begin(115200);
// Wait for serial connection (optional - remove for standalone operation)
while (!Serial && millis() < 5000)
{
delay(10);
}
// Initialize Bluefruit
Bluefruit.begin();
Bluefruit.setName("CSH3-BLE-Scanner");
// Set maximum power for better range
Bluefruit.setTxPower(4);
// Configure scanner
Bluefruit.Scanner.setRxCallback(scan_callback);
Bluefruit.Scanner.restartOnDisconnect(true);
Bluefruit.Scanner.setInterval(160, 80); // Interval and window in 0.625ms units
Bluefruit.Scanner.useActiveScan(false); // Passive scanning to capture all advertisements
// Start scanning
Bluefruit.Scanner.start();
}
void loop()
{
// Main loop - scanning happens in background via callbacks
delay(100);
}
void scan_callback(ble_gap_evt_adv_report_t *report)
{
// Get current timestamp
unsigned long timestamp = millis();
// Encode MAC address
char macStr[18];
snprintf(macStr, sizeof(macStr), "%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]);
// Determine address type
const char *addrType = (report->peer_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) ? "Public" : "Random";
// Determine PHY
const char *phyStr = "Unknown";
switch (report->primary_phy)
{
// case BLE_GAP_PHY_1MBPS:
// phyStr = "1M";
// break;
// case BLE_GAP_PHY_2MBPS:
// phyStr = "2M";
// break;
case BLE_GAP_PHY_CODED:
phyStr = "Coded";
break;
}
// Convert raw data to hex string
String hexData = "";
for (int i = 0; i < report->data.len; i++)
{
if (report->data.p_data[i] < 0x10)
hexData += "0";
hexData += String(report->data.p_data[i], HEX);
if (i < report->data.len - 1)
hexData += " ";
}
// Parse advertisement fields
String parsedFields = parseAdvertisementDataJSON(report->data.p_data, report->data.len);
// Output as JSON
Serial.print("{");
Serial.print("\"timestamp\":");
Serial.print(timestamp);
Serial.print(",\"rssi\":");
Serial.print(report->rssi);
Serial.print(",\"mac\":\"");
Serial.print(macStr);
Serial.print("\"");
Serial.print(",\"addr_type\":\"");
Serial.print(addrType);
Serial.print("\"");
Serial.print(",\"phy\":\"");
Serial.print(phyStr);
Serial.print("\"");
Serial.print(",\"len\":");
Serial.print(report->data.len);
Serial.print(",\"data\":\"");
Serial.print(hexData);
Serial.print("\"");
Serial.print(",\"fields\":");
Serial.print(parsedFields);
Serial.println("}");
Bluefruit.Scanner.resume();
}
// Parse advertisement data and return as JSON object string
String parseAdvertisementDataJSON(uint8_t *data, uint8_t len)
{
uint8_t pos = 0;
String json = "[";
bool first = true;
while (pos < len)
{
uint8_t fieldLen = data[pos];
if (fieldLen == 0 || pos + fieldLen >= len)
break;
uint8_t fieldType = data[pos + 1];
uint8_t *fieldData = &data[pos + 2];
uint8_t fieldDataLen = fieldLen - 1;
if (!first)
json += ",";
json += "{\"type\":\"";
switch (fieldType)
{
case 0x01:
json += "Flags";
break;
case 0x02:
json += "Incomplete16BitUUIDs";
break;
case 0x03:
json += "Complete16BitUUIDs";
break;
case 0x08:
json += "ShortName";
break;
case 0x09:
json += "CompleteName";
break;
case 0xFF:
json += "ManufacturerData";
break;
default:
json += "Type0x";
char buf[3];
snprintf(buf, sizeof(buf), "%02X", fieldType);
json += buf;
break;
}
json += "\",";
json += "\"value\":";
// Value formatting
if (fieldType == 0x08 || fieldType == 0x09)
{
// Name as string
json += "\"";
for (int i = 0; i < fieldDataLen; i++)
{
json += (char)fieldData[i];
}
json += "\"";
}
else if (fieldType == 0x02 || fieldType == 0x03)
{
// UUIDs as array
json += "[";
for (int i = 0; i < fieldDataLen; i += 2)
{
if (i > 0)
json += ",";
uint16_t uuid = (fieldData[i + 1] << 8) | fieldData[i];
json += String(uuid);
}
json += "]";
}
else
{
// Hex string
json += "\"";
for (int i = 0; i < fieldDataLen; i++)
{
if (fieldData[i] < 0x10)
json += "0";
json += String(fieldData[i], HEX);
}
json += "\"";
}
json += "}";
first = false;
pos += fieldLen + 1;
}
json += "]";
return json;
}
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested