ESP32はWiFiに加えてBLEも使えるということで注目されています。Arduino IDEでは、2017年の10月頃からBLEがサポートされ始めました。
ボードも入手しやすくなってMH-ET LIVE D1 mini ESP32という小型のボードは$7.5ぐらいでAliExpressで購入できました。
今回はそのESP32を2個使って、サーバーとクライアントで動作させてみました。どちらもArduino IDEでプログラミングできるので楽なのではないかと思います。サーバーには照度センサーNJL7502Lがあり、クライアントが接続すると照度のデータを送ります。クライアントが接続している間はゆらゆら人形が揺れます。クライアントはデータをもらってシリアルでPCにデータを表示します。
電気回路:
3.3Vを照度センサの+側(長い足)、照度センサの-側(短い足)は10kΩでGNDに接続して、短い足の電圧をアナログ入力AI6(IO34)に接続します。データシートを見ると1000luxで3Vの出力になるようです。ゆらゆら人形はIO5とGNDに接続します。ゆらゆら人形はDaisoのソーラーゆらゆらを改造して、コイル両端を回路から外して外部に取り出します。
クライアント側はUSBでPCに接続します。
BLEライブラリの導入には以下のURLの情報を参考にしました。
「Arduino IDEでESP32 BLEライブラリを導入」
https://qiita.com/tomorrow56/items/afa06e206eec9fafcc7a


BLEライブラリはArduinoっぽくないので、「山勘で書いて、動いた」というレベルですのでもっと良いサンプルを誰かが書いてくれると思います。現状で分かっている問題点としては、サーバーが電源OFFで停止するとクライアントがハングアップして、クライアントの電源をOFF-ONしないと復帰しない点です。
サーバー側のスケッチ(ベースにしたのはBLE_notify)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
//https://dotstud.io/blog/nefrybt-ble-bluetooth-peripheral/ #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> BLECharacteristic *pCharacteristic; bool deviceConnected = false; int value = 0; const int analogInPin = A6; int sensorValue = 0; // See the following for generating UUIDs: // https://www.uuidgenerator.net/ #define SERVICE_UUID "81d78b05-4e0a-4644-b364-b79312e4c307" #define CHARACTERISTIC_UUID "0989bf07-e886-443e-82db-7108726bb650" #define SERVER_NAME "esp32devc" class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; void setup() { Serial.begin(115200); Serial.println("BLE_DataServer180130"); pinMode(5, OUTPUT); BLEDevice::init(SERVER_NAME); BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_INDICATE ); pCharacteristic->addDescriptor(new BLE2902()); pService->start(); pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify..."); } void loop() { if (deviceConnected) { Serial.printf("*** NOTIFY: %d ***\n", value); char buffer[10]; sensorValue = analogRead(analogInPin); value=map(sensorValue, 0, 4095, 0, 1100); //sprintf(buffer, "%d", sensorValue); sprintf(buffer, "%d", value); Serial.printf(buffer); pCharacteristic->setValue(buffer); pCharacteristic->notify(); digitalWrite(5, HIGH); // turn the LED on (HIGH is the voltage level) delay(30); // wait for a second digitalWrite(5, LOW); // turn the LED off by making the voltage LOW //value++; } delay(300); } |
クライアント側のスケッチ(ベースにしたのはBLE_client)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
//Based on BLE client example //サーバーが停止するとエラーで回復できない #include "BLEDevice.h" #define SERVICE_UUID "81d78b05-4e0a-4644-b364-b79312e4c307" #define CHARACTERISTIC_UUID "0989bf07-e886-443e-82db-7108726bb650" #define SERVER_NAME "esp32devc" static BLEUUID serviceUUID(SERVICE_UUID); static BLEUUID charUUID(CHARACTERISTIC_UUID); static BLEAddress *pServerAddress; static boolean doConnect = false; static boolean connected = false; static BLERemoteCharacteristic* pRemoteCharacteristic; static void notifyCallback( BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { Serial.print("Notify callback for characteristic "); Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str()); Serial.print(" of data length "); Serial.println(length); } bool connectToServer(BLEAddress pAddress) { Serial.print("Forming a connection to "); Serial.println(pAddress.toString().c_str()); BLEClient* pClient = BLEDevice::createClient(); pClient->connect(pAddress); BLERemoteService* pRemoteService = pClient->getService(serviceUUID); Serial.print(" - Connected to server :"); Serial.println(serviceUUID.toString().c_str()); if (pRemoteService == nullptr) { Serial.print("Failed to find our service UUID: "); Serial.println(serviceUUID.toString().c_str()); return false; } pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); Serial.print(" - Found our characteristic UUID: "); Serial.println(charUUID.toString().c_str()); if (pRemoteCharacteristic == nullptr) { Serial.print("Failed to find our characteristic UUID: "); return false; } Serial.println(" - Found our characteristic"); pRemoteCharacteristic->registerForNotify(notifyCallback); } class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str());//Name: esp32devc, Address: 30:ae:a4:02:a3:fe, txPower: -21 Serial.println(advertisedDevice.getName().c_str());//esp32devc if(advertisedDevice.getName()==SERVER_NAME){ // Serial.println(advertisedDevice.getAddress().toString().c_str()); advertisedDevice.getScan()->stop(); pServerAddress = new BLEAddress(advertisedDevice.getAddress()); doConnect = true; } } }; void setup() { pinMode(5, OUTPUT); Serial.begin(115200); Serial.println("BLE_DataClient180130"); BLEDevice::init(""); BLEScan* pBLEScan = BLEDevice::getScan(); Serial.println("getScan"); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); Serial.println("setAdvertisedDeviceCallbacks"); pBLEScan->setActiveScan(true); pBLEScan->start(10); Serial.println(""); Serial.println("End of setup"); } void loop() { if (doConnect == true) { if (connectToServer(*pServerAddress)) { Serial.println("We are now connected to the BLE Server."); connected = true; } else { Serial.println("We have failed to connect to the server; there is nothin more we will do."); connected = false; } doConnect = false; } if (connected) { digitalWrite(5, HIGH); std::string value = pRemoteCharacteristic->readValue(); String strVal=value.c_str(); int strNum=strVal.toInt(); Serial.println(strNum); } else{ Serial.println("Not connected"); doConnect = true; } delay(1000); digitalWrite(5, LOW); delay(1000); } |