Arduino Nano 33 BLE as iBeacon

Hi,

I'd like to use a Nano 33 BLE as an iBeacon. I found the BeaconNano library: https://github.com/antoniopetruzzella/BeaconNano It did not work - I got some errors (I guess I didn't know how to use it) - but I had a look at the code, copied it into my sketch and I was able to create my iBeacon with the default values.

Now the question is: how can I change the beacon data? I'd like to connect the Nano to a button and advertise if the button is pushed or not.

Thanks!

Could you please share your code, so we can see what you already have and what might be missing?

The following post will show you how to post code and a few other tips.

How to use this section of the forum

Here is my code:

The setup() works fine and I can detect the beacon with a smartphone … but I’m not sure how to update the BLE data in the loop() function …

#include <ArduinoBLE.h>

std::string _uuid;
int _major;
int _minor;
int _tx;


void setup() {
  begin("c336aa38054bb0483b0ae75027061982",1,1,197);

  if (!BLE.begin()) {
      while (1);
  }

  startBeacon();
  BLE.advertise();

}

void loop(){
  
}

    
void begin(std::string uuid, int major, int minor, int tx){
  _uuid=uuid;
  _major=major;
  _minor=minor;
  _tx=tx;
  
}

void startBeacon(){

  byte uuidByte[16],majByte[2],minByte[2];
  convertStringToByte(_uuid,uuidByte);
  byte data[25]={
    0X4C,0x00, //setting for iBeacons
    0x02,0x15,
    uuidByte[0],
    uuidByte[1],
    uuidByte[2],
    uuidByte[3],
    uuidByte[4],
    uuidByte[5],
    uuidByte[6],
    uuidByte[7],
    uuidByte[8],
    uuidByte[9],
    uuidByte[10],
    uuidByte[11],
    uuidByte[12],
    uuidByte[13],
    uuidByte[14],
    uuidByte[15],
    0,
    _major,
    0,
    _minor,
    _tx
  };
  BLE.setManufacturerData(data, 25);// AGGIUNGE IL MANUFACT
}

void convertStringToByte(std::string uuid, byte bytes[]){
  char uuidChar[uuid.length()+1];
  strcpy(uuidChar,uuid.c_str());
  int pos=0;
  for (unsigned int i = 0; i<sizeof(uuidChar);i += 2){
    
    char hexValue[2]; 
    hexValue[0]=uuidChar[i];
    hexValue[1]=uuidChar[i+1];
    int intValue=strtol(hexValue,0, 16);
    bytes[pos]=(char)intValue;
    pos++;
  }
  
}

There are a few issues.

First, the iBeacon is intended to be a fixed message with a UUID and Major and a Minor value. These three values are used by a smartphone application to figure out what to do. All the intelligence is in the smartphone app. The beacons are not doing anything but sending these numbers.

According to the iBeacon information from Apple

The UUID is a unique number for your application and use case. Let’s say you are a company with stores. That UUID is used inside all beacons used in your stores. This will allow your application to identify the beacons that are used for this with only remembering one number. You can create more and more beacons over time e.g. when you open a new store with little changes to your app.

The Major and Minor value are intended to be used to tell your smartphone application where it is.
You could use Major for the store. Each store uses a different Major value.
You could use Minor for the sections in the store.

Because this is the intended behavior if you change the data dynamically, standard smartphone applications will assume your beacon is multiple beacons.

Of course, your smartphone application could interpret the data differently. After all iBeacon is a pseudo standard. It is not part of the Bluetooth specification. All you need to do is stop advertisement change major and minor and start advertisement again. But then you cannot call it iBeacon anymore.

The next issue is that the library has some bugs and is not well documented.

If you still like to create a iBeacon application we could have a look at them. If you rather spend time on creating an application that does what you intended in the first place, could you tell me a little bit about your application and I can give you some pointers.

Thanks a lot Klaus!! this helps a lot, it makes more sense now!

What I would like to do is to send a physical button push to two smartphones at the same time. I tried to use the ButtonLED example (for ArduinoBLE) - it works fine, but it's a one-on-one connection - I cannot get the push notification on two smartphones at the same time. So, I'm trying the beacon approach - this way I could detect the button push on multiple nearby phones.

I tried to use BLE.setManufacturerData to change the minor and tx values in the loop() function but it does not work.

I think there's an error thrown because the loop() function stops - I see it by printing messages in the Serial Monitor - it prints once then it stops.

So, is there a special technique to change the data using BLE.setManufacturerData?

Or is there some other way to create a Beacon with Arduino?

Thanks!!

You need to stop advertisement when you want to change the ManufacturerData. I guess this is just an issue of the library.

Here is a very short example. I removed the whole iBeacon stuff. The time needed to switch is about 50ms.

How do you read the advertisement data? I have a few iPhone apps, but none of them update the advertisement data automatically. I need to start scanning again.

#include <ArduinoBLE.h>

const int BUTTON_PIN = 2;

void setup()
{
  pinMode( BUTTON_PIN, INPUT );

  BLE.begin();
}

void loop()
{
  const int DATA_SIZE = 1;
  uint8_t data[DATA_SIZE];
  static int oldButtonState = LOW;

  int buttonState = digitalRead( BUTTON_PIN );

  if ( oldButtonState != buttonState )
  {
    oldButtonState = buttonState;

    data[0] = ( uint8_t ) buttonState;

    BLE.stopAdvertise();
    BLE.setManufacturerData( data, DATA_SIZE );
    BLE.advertise();
  }
}

Klaus, thank you so much for the code!! I did some tests and it seems to work perfect - I can detect the data change with an Android BLE scanner app. I guess I'm pretty much done on the Arduino side - I'll continue on the Android side - thanks!!!

Sir, I want to make beacons with several nano 33 BLE sense. I want to receive data with one 'nano 33 BLE Sense'...!!!!!!! Please tell me the beacon transmitter code and receiver code!!

@mr_drlee Please create a new post. New posts get more attention because people can see when nobody answered before.

Make sure you read the "How to post" (it at the beginning of each sub forum), to ensure your post contains all the information we might need to help you. e.g.

Your code you have written so far (use code tags).

What you would like to achieve and what is not working.

Did you read the post? There is a beacon example at the beginning. Did you search the forum? There are other posts about beacons.

Do you want to create a known beacon format e.g. iBeacon or do you want to create your own?

What the purpose of the beacon?

arduino nano 33 ble sense I want to make beacons using!!!
I want to receive data from multiple beacons through one master receiver!!!
Please tell me how to configure the code!!!
It’s just a beacon that has multiple data values.
I’d like to receive it by one receiver.
Beacon’s code,
Please tell me the code of the receiver…!!!

#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>#include <ArduinoBLE.h>

I made IBEACON with one peripheral.
Temperature and humidity values can be written for major and minor values, and the values can be advertised.
But I can’t figure out how to SCAN in CENTRAL… How to BLE.setManufacturerData( data, 25 ); Can you read it!!!

/*  TEST 이동렬  */




//-------------------------------------------------------------------------------
#include <ArduinoBLE.h>   
//나노33BLE 라이브러리
#include <Arduino_HTS221.h>
//온도,습도 라이브러리
//-------------------------------------------------------------------------------

//-------------------------------------------------------------------------------
std::string _uuid;
int _major;
int _minor;
int _tx;
BLEService asdasd(std::string uuid, int major, int minor, int tx); // BLE LED Service

const int ledPin = LED_BUILTIN; 
// 내장 LED핀을 정의한다.

// Peripheral 주변기기의 UUID, BLEService는 Respon라고 정의한다.
//-------------------------------------------------------------------------------




void setup() {




  
Serial.begin(9600); //시리얼 통신 시작


 pinMode(ledPin, OUTPUT); //내장LED OUTPUT 지정
  pinMode(D2, OUTPUT);  // D2 LED OUTPUT 지정
  pinMode(D3, OUTPUT);  // D3 LED OUTPUT 지정

  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
   

    while (1);
  }

if (!HTS.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }

BLE.setLocalName("이동렬TEST");  // 광고할 peripheral UUID의 로컬네임을 지정한다.



//------------------------------------------------------------------------------------------------------


/*
BLE.advertise();
// peripheral의 광고 시작을 셋업


*/

}




  //-------------------------------------------------------------------------------











//-------------------------------------------------------------------------------





//-------------------------------------------------------------------------------






void begin(std::string uuid, int major, int minor, int tx){
  _uuid=uuid;
  _major=major;
  _minor=minor;
  _tx=tx;

}


















void loop() {

BLE.poll();

float temperatureC = HTS.readTemperature();//32비트(4바이트) 정보를 저장한다
  float humidity    = HTS.readHumidity();//32비트(4바이트) 정보를 저장한다
    
digitalWrite(ledPin, HIGH);         
          digitalWrite(D2, HIGH);
        digitalWrite(D3, HIGH);
        
   delay(250);                               
          digitalWrite(ledPin, LOW);          
          digitalWrite(D2, LOW);
      digitalWrite(D3, LOW);

delay(250);




if (ledPin, HIGH)
  {
  
   
    Serial.println(" ★ 나와 특성을 광고했음 ★ ");




    
     Serial.print("온도 = ");
  Serial.print(temperatureC); 
  Serial.print(" °C, "); 
 
  Serial.print("습도 = "); 
  Serial.print(humidity); 
  Serial.println(" %"); 
  

  }














/*
BLEDevice central = BLE.central();
//주변 BLE 장치로부터 수신한다.
*/
/*

if(central){
 // 만약  Central에 연결되면
*/
 
  
  
  /*
   while (central.connected()) {
    // Central에 계속 연결중 이라면 반복문
    */
 
    

    /*
      tempCharacteristic.writeValue(temperatureC);      // advertise temperature (2A6E) 특성광고
  humidCharacteristic.writeValue(humidity);       // advertise humidity (2A6F) 특성광고 
*/
/*
if (humidCharacteristic.writeValue(humidity))
*/




 if (ledPin, HIGH)
  {


  begin("c336aa38054bb0483b0ae75027061982",HTS.readTemperature(),HTS.readHumidity(),197);

  byte uuidByte[16],majByte[2],minByte[2];

  convertStringToByte(_uuid,uuidByte);
  byte data[25]={

 0X4C,0x00, 
    0x02,0x15,
    uuidByte[0],
    uuidByte[1],
    uuidByte[2],
    uuidByte[3],
    uuidByte[4],
    uuidByte[5],
    uuidByte[6],
    uuidByte[7],
    uuidByte[8],
    uuidByte[9],
    uuidByte[10],
    uuidByte[11],
    uuidByte[12],
    uuidByte[13], 
    uuidByte[14],
    uuidByte[15],
    0,
    _major,
    0,
    _minor,
    _tx

    
  };
/*
  byte data[4]={  
temperatureC,
0,
humidity,
0
    };

*/
 
    BLE.stopAdvertise();
    BLE.setManufacturerData( data, 25 );



    
    BLE.advertise();

  }


    
    /*
    
  Serial.print("온도 = ");
  Serial.print(temperatureC); 
  Serial.print(" °C, "); 
 
  Serial.print("습도 = "); 
  Serial.print(humidity); 
  Serial.println(" %"); 
    
    
       if (ResponCharacteristic.written()) {
        if (ResponCharacteristic.value()) {   
          Serial.println(" ★ SIGNAL IN --- ");



          
          digitalWrite(ledPin, HIGH);         
          digitalWrite(D2, HIGH);
        digitalWrite(D3, HIGH);
        
        } else {                              
          Serial.println(F(" --- SIGNAL OUT ★ "));
          digitalWrite(ledPin, LOW);          
          digitalWrite(D2, LOW);
      digitalWrite(D3, LOW);


 Serial.println(" ★ 나의 특성 광고했음. ");



tempCharacteristic.writeValue(temperatureC);      // advertise temperature (2A6E) 특성광고
  humidCharacteristic.writeValue(humidity);       // advertise humidity (2A6F) 특성광고 
*/
}
      
  /*  }  */
/*  }*/

void convertStringToByte(std::string uuid, byte bytes[]){
  char uuidChar[uuid.length()+1];
  strcpy(uuidChar,uuid.c_str());
  int pos=0;
  for (unsigned int i = 0; i<sizeof(uuidChar);i += 2){
   
    char hexValue[2];
    hexValue[0]=uuidChar[i];
    hexValue[1]=uuidChar[i+1];
    int intValue=strtol(hexValue,0, 16);
    bytes[pos]=(char)intValue;
    pos++;
  }
 
}

@mr_drlee

Please STOP posting the same thing over and over.

Other post/duplicate DELETED Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum. It will help you get the best out of the forum in the future. Other general help and troubleshooting advice can be found here. It will help you get the best out of the forum in the future.

Language problem ? Try a language closer to your native language:

하나의 주변기기로 IBEACON을 만들었습니다. 온도 및 습도 값은 메이저 및 마이너 값에 대해 쓸 수 있으며 값을 광고 할 수 있습니다. 하지만 CENTRAL에서 스캔하는 방법을 알 수 없습니다 ... How to BLE.setManufacturerData (data, 25); 읽을 수 있습니까? ???? !!!! PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!PLZ..!!