├── .gitignore ├── BLE_everything_to_string └── BLE_to_string.ino ├── BLE_potentiometer └── BLE_potentiometer.ino ├── BLE_switch └── BLE_Switch.ino ├── BLE_temperature_sensor └── BLE_temperature_sensor.ino ├── BLE_write └── BLE_write.ino └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /BLE_everything_to_string/BLE_to_string.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* four data types being converted to char array */ 7 | char charArr[]="char array"; 8 | String str = "this is a string"; 9 | int integer = 7683; 10 | float decimalNumber = 768.30000; 11 | 12 | /* define the characteristic and it's propeties */ 13 | BLECharacteristic customCharacteristic( 14 | BLEUUID((uint16_t)0x1A00), 15 | BLECharacteristic::PROPERTY_READ | 16 | BLECharacteristic::PROPERTY_NOTIFY 17 | ); 18 | 19 | /* define the UUID that our custom service will use */ 20 | #define serviceID BLEUUID((uint16_t)0x1700) 21 | 22 | /* This function handles server callbacks */ 23 | bool deviceConnected = false; 24 | class ServerCallbacks: public BLEServerCallbacks { 25 | void onConnect(BLEServer* MyServer) { 26 | deviceConnected = true; 27 | }; 28 | void onDisconnect(BLEServer* MyServer) { 29 | deviceConnected = false; 30 | } 31 | }; 32 | 33 | void setup() { 34 | Serial.begin(115200); 35 | 36 | BLEDevice::init("MyESP32"); // Name your BLE Device 37 | BLEServer *MyServer = BLEDevice::createServer(); //Create the BLE Server 38 | MyServer->setCallbacks(new ServerCallbacks()); // Set the function that handles server callbacks 39 | BLEService *customService = MyServer->createService(serviceID); // Create the BLE Service 40 | customService->addCharacteristic(&customCharacteristic); // Create a BLE Characteristic 41 | customCharacteristic.addDescriptor(new BLE2902()); // Create a BLE Descriptor 42 | MyServer->getAdvertising()->addServiceUUID(serviceID); // Configure Advertising 43 | customService->start(); // Start the service 44 | MyServer->getAdvertising()->start(); // Start the server/advertising 45 | 46 | Serial.println("Waiting for a client to connect...."); 47 | } 48 | void loop() { 49 | for (int i = 0; i < 4; ++i) 50 | { 51 | switch(i){ 52 | case 0:{ //send char array 53 | customCharacteristic.setValue((char*)&charArr); 54 | customCharacteristic.notify(); 55 | break; 56 | } 57 | case 1:{ //send string 58 | char buffer[str.length()+1]; 59 | str.toCharArray(buffer,str.length()+1); 60 | customCharacteristic.setValue((char*)&buffer); 61 | customCharacteristic.notify(); 62 | break; 63 | } 64 | case 2:{ //send integer 65 | char buffer[20]; 66 | dtostrf(integer,1,0,buffer); 67 | customCharacteristic.setValue((char*)&buffer); 68 | customCharacteristic.notify(); 69 | break; 70 | } 71 | case 3:{ //send float 72 | char buffer[20]; 73 | dtostrf(decimalNumber,1,5,buffer); //change 5 to whatever decimal precision you want 74 | customCharacteristic.setValue((char*)&buffer); 75 | customCharacteristic.notify(); 76 | break; 77 | } 78 | } 79 | delay(1000); 80 | } 81 | } -------------------------------------------------------------------------------- /BLE_potentiometer/BLE_potentiometer.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define potPin 36 //connect the potentiometer to gpio36 7 | 8 | int sensorRead = 0; 9 | uint8_t value = 0; //the set value function only accepts unsigned 8 bit integers 10 | 11 | /* Define the UUID for our Custom Service */ 12 | #define serviceID BLEUUID((uint16_t)0x1700) 13 | 14 | /* Define our custom characteristic along with it's properties */ 15 | BLECharacteristic customCharacteristic( 16 | BLEUUID((uint16_t)0x1A00), 17 | BLECharacteristic::PROPERTY_READ | 18 | BLECharacteristic::PROPERTY_NOTIFY 19 | ); 20 | 21 | /* This function handles the server callbacks */ 22 | bool deviceConnected = false; 23 | class ServerCallbacks: public BLEServerCallbacks { 24 | void onConnect(BLEServer* MyServer) { 25 | deviceConnected = true; 26 | }; 27 | 28 | void onDisconnect(BLEServer* MyServer) { 29 | deviceConnected = false; 30 | } 31 | }; 32 | 33 | void setup() { 34 | Serial.begin(9600); 35 | 36 | // Create and name the BLE Device 37 | BLEDevice::init("MyESP32"); 38 | 39 | /* Create the BLE Server */ 40 | BLEServer *MyServer = BLEDevice::createServer(); 41 | MyServer->setCallbacks(new ServerCallbacks()); // Set the function that handles Server Callbacks 42 | 43 | /* Add a service to our server */ 44 | BLEService *customService = MyServer->createService(BLEUUID((uint16_t)0x1700)); // A random ID has been selected 45 | 46 | /* Add a characteristic to the service */ 47 | customService->addCharacteristic(&customCharacteristic); //customCharacteristic was defined above 48 | 49 | /* Add Descriptors to the Characteristic*/ 50 | customCharacteristic.addDescriptor(new BLE2902()); //Add this line only if the characteristic has the Notify property 51 | 52 | BLEDescriptor VariableDescriptor(BLEUUID((uint16_t)0x2901)); /*```````````````````````````````````````````````````````````````*/ 53 | VariableDescriptor.setValue("Temperature -40-60°C"); /* Use this format to add a hint for the user. This is optional. */ 54 | customCharacteristic.addDescriptor(&VariableDescriptor); /*```````````````````````````````````````````````````````````````*/ 55 | 56 | /* Configure Advertising with the Services to be advertised */ 57 | MyServer->getAdvertising()->addServiceUUID(serviceID); 58 | 59 | // Start the service 60 | customService->start(); 61 | 62 | // Start the Server/Advertising 63 | MyServer->getAdvertising()->start(); 64 | 65 | Serial.println("Waiting for a Client to connect..."); 66 | } 67 | 68 | void loop() { 69 | sensorRead = analogRead(potPin); //read the value of the potentiometer 70 | value = map(sensorRead,0,4095,0,255); //change the value to a range of 0-255 so that it can fit in a single byte 71 | Serial.println(value); 72 | if (deviceConnected) { 73 | /* Set the value */ 74 | customCharacteristic.setValue(&value,1); // This is a value of a single byte 75 | customCharacteristic.notify(); // Notify the client of a change 76 | } 77 | delay(50); 78 | } 79 | -------------------------------------------------------------------------------- /BLE_switch/BLE_Switch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define switchPin 15 7 | char value[]="OFF"; 8 | 9 | #define serviceID BLEUUID((uint16_t)0x1700) 10 | 11 | BLECharacteristic customCharacteristic( 12 | BLEUUID((uint16_t)0x1A00), 13 | BLECharacteristic::PROPERTY_READ | 14 | BLECharacteristic::PROPERTY_NOTIFY 15 | ); 16 | 17 | bool deviceConnected = false; 18 | class ServerCallbacks: public BLEServerCallbacks { 19 | void onConnect(BLEServer* MyServer) { 20 | deviceConnected = true; 21 | }; 22 | 23 | void onDisconnect(BLEServer* MyServer) { 24 | deviceConnected = false; 25 | } 26 | }; 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | pinMode(switchPin,INPUT_PULLUP); 31 | 32 | // Create the BLE Device 33 | BLEDevice::init("MyESP32"); 34 | 35 | // Create the BLE Server 36 | BLEServer *MyServer = BLEDevice::createServer(); 37 | MyServer->setCallbacks(new ServerCallbacks()); 38 | 39 | // Create the BLE Service 40 | BLEService *customService = MyServer->createService(serviceID); 41 | 42 | // Create a BLE Characteristic 43 | customService->addCharacteristic(&customCharacteristic); 44 | 45 | // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml 46 | // Create a BLE Descriptor 47 | customCharacteristic.addDescriptor(new BLE2902()); 48 | 49 | MyServer->getAdvertising()->addServiceUUID(serviceID); 50 | 51 | // Start the service 52 | customService->start(); 53 | 54 | // Start advertising 55 | MyServer->getAdvertising()->start(); 56 | Serial.println("Waiting for a client to connect...."); 57 | } 58 | 59 | void loop() { 60 | if (deviceConnected) { 61 | if(digitalRead(switchPin)==0){ 62 | customCharacteristic.setValue("ON"); 63 | Serial.println("ON"); 64 | } 65 | else{ 66 | customCharacteristic.setValue((char*)&value); 67 | Serial.println("OFF"); 68 | } 69 | customCharacteristic.notify(); 70 | } 71 | delay(50); 72 | } 73 | -------------------------------------------------------------------------------- /BLE_temperature_sensor/BLE_temperature_sensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int sensorPin = 15; 8 | OneWire ds(sensorPin); 9 | 10 | // BLECharacteristic *pCharacteristic; 11 | 12 | bool deviceConnected = false; 13 | 14 | int rec=0; 15 | 16 | void getTemp(); 17 | void BLETransfer(int16_t); 18 | 19 | float temperature = -1000; 20 | 21 | #define enviornmentService BLEUUID((uint16_t)0x181A) 22 | 23 | BLECharacteristic temperatureCharacteristic( 24 | BLEUUID((uint16_t)0x2A6E), 25 | BLECharacteristic::PROPERTY_READ | 26 | BLECharacteristic::PROPERTY_NOTIFY 27 | ); 28 | //BLEDescriptor tempDescriptor(BLEUUID((uint16_t)0x2901)); 29 | 30 | class MyServerCallbacks: public BLEServerCallbacks { 31 | void onConnect(BLEServer* pServer) { 32 | deviceConnected = true; 33 | }; 34 | 35 | void onDisconnect(BLEServer* pServer) { 36 | deviceConnected = false; 37 | } 38 | }; 39 | 40 | 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | 45 | // Create the BLE Device 46 | BLEDevice::init("MyESP32"); 47 | 48 | // Create the BLE Server 49 | BLEServer *pServer = BLEDevice::createServer(); 50 | pServer->setCallbacks(new MyServerCallbacks()); 51 | 52 | // Create the BLE Service 53 | BLEService *pEnviornment = pServer->createService(enviornmentService); 54 | 55 | // Create a BLE Characteristic 56 | pEnviornment->addCharacteristic(&temperatureCharacteristic); 57 | 58 | // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml 59 | // Create a BLE Descriptor 60 | temperatureCharacteristic.addDescriptor(new BLE2902()); 61 | 62 | BLEDescriptor TemperatureDescriptor(BLEUUID((uint16_t)0x2901)); 63 | TemperatureDescriptor.setValue("Temperature -40-60°C"); 64 | temperatureCharacteristic.addDescriptor(&TemperatureDescriptor); 65 | 66 | pServer->getAdvertising()->addServiceUUID(enviornmentService); 67 | 68 | // Start the service 69 | pEnviornment->start(); 70 | 71 | // Start advertising 72 | pServer->getAdvertising()->start(); 73 | Serial.println("Waiting a client connection to notify..."); 74 | } 75 | 76 | void loop() { 77 | getTemp(); 78 | Serial.println(temperature); 79 | String beaconMsg; 80 | if(temperature==-1000) 81 | { 82 | if(rec>5) 83 | { 84 | beaconMsg = "ESPSNA"; 85 | Serial.println(beaconMsg); 86 | temperature = 100000; 87 | } 88 | return; 89 | } 90 | 91 | if (deviceConnected) { 92 | int16_t value; 93 | value = (temperature*100); 94 | Serial.println(value); 95 | // BLETransfer(value); 96 | temperatureCharacteristic.setValue((uint8_t*)&value, 2); 97 | temperatureCharacteristic.notify(); 98 | } 99 | delay(200); 100 | } 101 | 102 | void BLETransfer(int16_t val){ 103 | temperatureCharacteristic.setValue((uint8_t*)&val, 2); 104 | temperatureCharacteristic.notify(); 105 | } 106 | 107 | void getTemp(){ 108 | //returns the temperature from one DS18S20 in DEG Celsius 109 | byte data[12]; 110 | byte addr[8]; 111 | 112 | if ( !ds.search(addr)) { 113 | //no more sensors on chain, reset search 114 | ds.reset_search(); 115 | Serial.println("no addr found"); 116 | rec++; 117 | Serial.println("rec = "+ rec); 118 | temperature = -1000; 119 | return; 120 | } 121 | 122 | if ( OneWire::crc8( addr, 7) != addr[7]) { 123 | Serial.println("CRC is not valid!"); 124 | rec++; 125 | Serial.println("rec = "+ rec); 126 | temperature = -1000; 127 | return; 128 | } 129 | 130 | if ( addr[0] != 0x10 && addr[0] != 0x28) { 131 | Serial.print("Device is not recognized"); 132 | rec++; 133 | Serial.println("rec = "+ rec); 134 | temperature = -1000; 135 | return; 136 | } 137 | 138 | ds.reset(); 139 | ds.select(addr); 140 | ds.write(0x44,1); // start conversion, with parasite power on at the end 141 | 142 | byte present = ds.reset(); 143 | ds.select(addr); 144 | ds.write(0xBE); // Read Scratchpad 145 | 146 | 147 | for (int i = 0; i < 9; i++) { // we need 9 bytes 148 | data[i] = ds.read(); 149 | } 150 | 151 | ds.reset_search(); 152 | 153 | byte MSB = data[1]; 154 | byte LSB = data[0]; 155 | 156 | float tempRead = ((MSB << 8) | LSB); //using two's compliment 157 | float TemperatureSum = tempRead / 16; 158 | Serial.println("rec = 0"); 159 | rec=0; 160 | temperature = TemperatureSum; 161 | } 162 | -------------------------------------------------------------------------------- /BLE_write/BLE_write.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | BLECharacteristic *pCharacteristic; 7 | 8 | bool deviceConnected = false; 9 | 10 | char value[50] = "Default"; 11 | 12 | #define customService BLEUUID((uint16_t)0x1700) 13 | BLECharacteristic customCharacteristic(BLEUUID((uint16_t)0x1A00), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE); 14 | 15 | class MyCharacteristicCallbacks: public BLECharacteristicCallbacks { 16 | void onWrite(BLECharacteristic *customCharacteristic){ 17 | std::string rcvString = customCharacteristic->getValue(); 18 | if(rcvString.length()>0){ 19 | Serial.println("Value Received from BLE: "); 20 | for (int i = 0; i < rcvString.length(); ++i) 21 | { 22 | Serial.print(rcvString[i]); 23 | value[i]=rcvString[i]; 24 | } 25 | for (int i = rcvString.length(); i < 50; ++i) 26 | { 27 | value[i]=NULL; 28 | } 29 | customCharacteristic->setValue((char*)&value); 30 | } 31 | else{ 32 | Serial.println("Empty Value Received!"); 33 | } 34 | } 35 | }; 36 | 37 | void setup() { 38 | Serial.begin(115200); 39 | 40 | // Create the BLE Device 41 | BLEDevice::init("MyESP32"); 42 | 43 | // Create the BLE Server 44 | BLEServer *pServer = BLEDevice::createServer(); 45 | 46 | // Create the BLE Service 47 | BLEService *pService = pServer->createService(customService); 48 | 49 | // Create a BLE Characteristic 50 | pService->addCharacteristic(&customCharacteristic); 51 | 52 | customCharacteristic.setCallbacks(new MyCharacteristicCallbacks()); 53 | 54 | pServer->getAdvertising()->addServiceUUID(customService); 55 | 56 | // Start the service 57 | pService->start(); 58 | 59 | // Start advertising 60 | pServer->getAdvertising()->start(); 61 | 62 | Serial.println(value); 63 | customCharacteristic.setValue((char*)&value); 64 | } 65 | 66 | void loop() { 67 | delay(100); 68 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32 BLE Examples for Arduino 2 | 3 | This repository contains example codes that can be used as templates for your BLE project with the ESP32 board. All these examples have been explained [this video](https://youtu.be/P0aqbD9umDE). 4 | 5 | ## Android Apps 6 | For the client app on your smartphone, I recommend using the [nRF connect app](https://www.nordicsemi.com/?sc_itemid={41FF7A0B-B565-420A-95B7-B32122B5D3AD}). 7 | The examples BLE_switch and BLE_everything_to_string look best on the custom app available [here](https://github.com/LiveSparks/BLE_Viewer_App). 8 | --------------------------------------------------------------------------------