How can I get Xiao nRF52840 Sense board info by code?

Forgive me if it’s been asked and answered I wasn’t able to find any solid answers, from Alphabet guy.

I want to gain the boards Serial number (See attached) or even the Mac address would do for unique ID. Here’s two boards for example.
BN: Seeed XIAO BLE - nRF52840
VID: 2886
PID: 8045
SN: 53BB210E6378CF67 (soldered battery)
BN: Seeed XIAO BLE - nRF52840
VID: 2886
PID: 8045
SN: F529BC40B1F8B34E
Programatically of course, I want to be able to send it via BLE to the phone App.

My situation is 10 BLE peripheries and I want to discern one from the other.
any HELP, Clue’s or Advice is most appreciated.
ALso When I scan I do see the different MAC’s and RSSI on the BLE app.
maybe the SEEED Hive has the info?
TIA
GL :slight_smile:



Hi, we haven’t really done any research on this. But we have found relevant information that you can refer to.

Ok well thank you, seems like a basic question. I looked further and turns out the Arduino Nano 33 BLE uses the Nordic nRF52840 chip. they are called Factory information configuration registers. There are a couple you can use to identify the chip. e.g. Device Identifier, Device Address.
this code from Klaus_K works perfectly.

#include <ArduinoBLE.h>

void setup()
{
  Serial.begin( 9600 );
  while ( !Serial );
}

void loop()
{
  Serial.print( "Device ID 0: " );
  Serial.println( NRF_FICR->DEVICEID[0], HEX );
  Serial.print( "Device ID 1: " );
  Serial.println( NRF_FICR->DEVICEID[1], HEX );

  Serial.print( "Device Address 0: " );
  Serial.println( NRF_FICR->DEVICEADDR[0], HEX );
  Serial.print( "Device Address 1: " );
  Serial.println( NRF_FICR->DEVICEADDR[1], HEX );

  delay ( 5000 );
}
I got this out put and it matches the Dev board's "get board info"
SWEET!

Device ID 0: A2041DAA
Device ID 1: 97B5492C
Device Address 0: B1F8B34E
Device Address 1: F529BC40

now on to how to embed it in the BLE advertised name. :slight_smile:
thanks for the Push.
GL :wink:

1 Like

Here is part of it, if you want to pull a fast serial number or unit number that will be “somewhat” Unique.
HTH
GL :-p



Serial output was perfect on both units.

#1
Processor came out of reset.
Xiao Unit: F529
Xiao MAC: BC:40:B1:F8:B3:4E
Battery Level 4.084

#2
Processor came out of reset.
Xiao Unit: 53BB
Xiao MAC: 21:0E:63:78:CF:67
Battery Level 4.065

#include <Arduino.h>
#include <Wire.h>
#include <U8x8lib.h>

//Create a instance of class
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ PIN_WIRE_SCL, /* data=*/ PIN_WIRE_SDA, /* reset=*/ U8X8_PIN_NONE);
// OLEDs without Reset of the Display
const int ledPin = LED_BUILTIN;
int BuzzerPin = A3;                 //A3 , P0.29 PIN 4
int buzzer = BuzzerPin;
int Vadc = analogRead(P0_31);
uint8_t mac_address[6];

void setup(){
 Serial.begin( 9600 );
 delay(2000);                       //relax...Get Ready for serial port
 Serial.println("Processor came out of reset.\n");
 startsound();
 setBatt();
 initdisplay();
 setupblink();  
 }
//
void loop(){
char buff[6];
get_id_address(mac_address);
sprintf(buff, "\nXiao Unit: %02lX%02lX\n",
          mac_address[0],mac_address[1]);
  Serial.print(buff);
  u8x8.clearDisplay();
  u8x8.setCursor(0,-1);
  u8x8.print(buff);
  u8x8.setCursor(6,6);
delay(2000);

char buffer[80];
char bufferu8[80];
get_mac_address(mac_address);
sprintf(buffer, "Xiao MAC: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  Serial.print(buffer);
  sprintf(bufferu8, "Xiao MAC: \n%02lX%02lX%02lX%02lX%02lX%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  u8x8.setCursor(0,3);
  u8x8.print(bufferu8);
delay (2000);
getBattery();
delay (2000);

}

// 
//************************functions **********************
//
void get_id_address(uint8_t mac_address[6]) {
	unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
	unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
	const uint8_t* part_0 = reinterpret_cast<const uint8_t*>(&device_addr_0);
	const uint8_t* part_1 = reinterpret_cast<const uint8_t*>(&device_addr_1);
	mac_address[0] = part_1[3];   //changed from get_mac_address elements 0,1
	mac_address[1] = part_1[2];   //
}

void setBatt(){
  pinMode(P0_31, INPUT);    //Battery Voltage monitoring pin
  pinMode(P0_13, OUTPUT);   //Charge Current setting pin
  pinMode(P0_14, OUTPUT);   //Enable Battery Voltage monitoring pin
  digitalWrite(P0_13, LOW); //Charge Current 100mA   
  digitalWrite(P0_14, LOW); //Enable
  analogReference(AR_INTERNAL2V4);  //Vref=2.4V
  analogReadResolution(12);
}

void getBattery(){
  int Vadc = analogRead(P0_31);
  float Vbatt = ((510e3 + 1000e3) / 510e3) * 2.4 * Vadc / 4096;
  Serial.print("Battery Level "); 
  Serial.println( Vbatt, 3); 
  digitalWrite(LED_GREEN, HIGH);
  u8x8.clearDisplay();
  u8x8.setCursor(0,2);
  u8x8.print("Battery Monitor");
  u8x8.setCursor(6,6);
  u8x8.print(Vbatt, 3);
}

void get_mac_address(uint8_t mac_address[6]) {
	unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
	unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
	const uint8_t* part_0 = reinterpret_cast<const uint8_t*>(&device_addr_0);
	const uint8_t* part_1 = reinterpret_cast<const uint8_t*>(&device_addr_1);
	mac_address[0] = part_1[1];
	mac_address[1] = part_1[0];
	mac_address[2] = part_0[3];
	mac_address[3] = part_0[2];
	mac_address[4] = part_0[1];
	mac_address[5] = part_0[0];
}

void setupblink(){
  setLedRGB(false, false, true);  // set Blue LED 
    delay(1000);
    setLedRGB(false, true, false);  // Red
    delay(1000);
    setLedRGB(true, false, false);  // Green
    delay(1000);
    setLedRGB(false, false, false);  // OFF
}   

void initdisplay() {
 pinMode(LEDR, OUTPUT);         // initialize the LED pin as an output:
 pinMode(LEDG, OUTPUT);         // initialize the LED pin as an output:
 pinMode(LEDB, OUTPUT);
 pinMode(LED_BUILTIN, OUTPUT);      // initialize the LED pin as an output:
  u8x8.begin();
    u8x8.setFlipMode(1);   // set number from 1 to 3, the screen word will rotary 180
    u8x8.setFont(u8x8_font_8x13B_1x2_r);
    u8x8.clearDisplay();
    u8x8.setCursor(0, 0);
    u8x8.print("Power ON ");
}

void startsound() {
  tone (buzzer, 890);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 800);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 800);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 990);
    delay (420);
    noTone(buzzer);
    delay (20);
}

void setLedRGB(bool red, bool green, bool blue) {
   if (!red) { digitalWrite(LEDR, HIGH); } else { digitalWrite(LEDR, LOW); }
   if (!green) { digitalWrite(LEDG, HIGH); } else { digitalWrite(LEDG, LOW); }
   if (!blue) { digitalWrite(LEDB, HIGH); } else { digitalWrite(LEDB, LOW); }
}

Hi PJ

I was borrowing your code and noticed that it didn’t always produce the correct MAC Address value.

You need to add the last line to the function.

void get_mac_address(uint8_t mac_address[6])
{
unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
const uint8_t *part_0 = reinterpret_cast<const uint8_t *>(&device_addr_0);
const uint8_t *part_1 = reinterpret_cast<const uint8_t *>(&device_addr_1);
mac_address[0] = part_1[1];
mac_address[1] = part_1[0];
mac_address[2] = part_0[3];
mac_address[3] = part_0[2];
mac_address[4] = part_0[1];
mac_address[5] = part_0[0];

// To ensure compliance with the Bluetooth Core Specification v4.0,
// which states that the two most significant bits (MSB) of the address
// must be set to '11' for random static addresses, you need to modify
// the first byte of the MAC address after retrieving it from the hardware.
//  ( see Bluetooth Core v4.0, Vol 3, Part C, chapter 10.8.1.)

mac_address[0] |= 0xC0; // 0xC0 is binary 11000000

}

Regards
Dave

2 Likes

Hi thanks
Thanks Dave… :+1:

This is unrelated to the comments above, but I’m having a problem with my Seeed XIAO nRF52840. After I finish uploading Arduino code, I suddenly lose the connection between the programming cable (USB cable) and this module. Can you please help me?

Hi there,

And Welcome Here…

Have you looked at the Wiki for the Xiao device you are using?
Ii you hold down the reset button and plug it into the USB does it make the windows “new Device Found” sound?

Does the double press reset button fast work to get into BL (bootloader) mode? Try some of the things in the WiKi and report back. After a few posted reply’s you’ll gain enough forum Cred to start a new thread with your exact issue.

HTH
GL :slight_smile: PJ :v:

1 Like