Advertisement
dckiller

Miscale init esp32

Jan 15th, 2021
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.50 KB | None | 0 0
  1. /**
  2. * An ESP32 BLE client to retrieve data from the Weight Measurement characteristic
  3. * of a Xiaomi Mi Smart weight scale
  4. * Author Pangodream
  5. * Date 2020.05.31
  6. */
  7. #include "esphome.h"
  8. #include "BLEDevice.h"
  9. //Base UUIDs
  10. //Weight Scale service
  11. static BLEUUID srvUUID("0000181d-0000-1000-8000-00805f9b34fb");
  12. //Weight Measurement characteristic
  13. static BLEUUID chrUUID("00002a9d-0000-1000-8000-00805f9b34fb");
  14.  
  15. static BLEAdvertisedDevice* scale;
  16. static BLERemoteCharacteristic* remoteChr;
  17. static boolean doConnect = false;
  18. static boolean connected = false;
  19. static int year = 0;
  20.  
  21. /**
  22. * Callback function for characteristic notify / indication
  23. */
  24. static void chrCB(BLERemoteCharacteristic* remoteChr, uint8_t* pData, size_t length, bool isNotify) {
  25. //Console debugging
  26. Serial.print("Received data. Length = ");
  27. Serial.print(length);
  28. Serial.print(". - Data bytes: ");
  29. for(int i =0; i< length; i++){
  30. Serial.print(pData[i]);
  31. Serial.print(" ");
  32. }
  33. Serial.println(" ");
  34. //End of console debugging
  35.  
  36. //Parsing the received data and calculate weight
  37. boolean temporary = true;
  38. int rcvdYear = pData[3];
  39. //If we received a year for the first time, store it in the year variable
  40. //The first year we receive indicates a temporary measurement
  41. if(year == 0){
  42. year = rcvdYear;
  43. }else{
  44. //If year has been previously defined and the year we have received is
  45. //greater than it, then the measurement is not temporary, is the final one
  46. if(rcvdYear > year){
  47. temporary = false;
  48. }
  49. }
  50. double weight = 0;
  51. weight = (pData[1] + pData[2] * 256) * 0.005;
  52.  
  53. Serial.print("Weight: ");
  54. Serial.print(weight);
  55. Serial.print(" Kg - ");
  56. if(temporary){
  57. Serial.println(" (Provisional)");
  58. }else{
  59. Serial.println(" (Definitive)");
  60. }
  61. }
  62.  
  63. /**
  64. * Callback class for each advertised device during scan
  65. */
  66. class deviceCB: public BLEAdvertisedDeviceCallbacks {
  67. //Called on each advertised device
  68. void onResult(BLEAdvertisedDevice advertisedDevice) {
  69. // We have found a device, let us now see if it contains the service we are looking for.
  70. if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(srvUUID)) {
  71. if(advertisedDevice.getName() != "MI_SCALE"){
  72. Serial.print(".");
  73. } else {
  74. Serial.println(" Found!");
  75. BLEDevice::getScan()->stop();
  76. Serial.println("Stopping scan and connecting to scale");
  77. scale = new BLEAdvertisedDevice(advertisedDevice);
  78. doConnect = true;
  79. }
  80. } else {
  81. Serial.print(".");
  82. }
  83. }
  84. };
  85. /**
  86. * Callback class for device events
  87. */
  88. class ClientCB : public BLEClientCallbacks {
  89. void onConnect(BLEClient* pclient) {
  90.  
  91. }
  92.  
  93. void onDisconnect(BLEClient* pclient) {
  94. Serial.println("Disconnected. Reconnecting...");
  95. connected = false;
  96. }
  97. };
  98.  
  99. bool connectToScale() {
  100. Serial.println("Stablishing communications with scale:");
  101. BLEClient* pClient = BLEDevice::createClient();
  102. Serial.println(" BLE client created");
  103.  
  104. pClient->setClientCallbacks(new ClientCB());
  105.  
  106. // Connect to the remove BLE Server.
  107. pClient->connect(scale);
  108. Serial.println(" Connected to scale");
  109.  
  110. // Obtain a reference to the service we are after in the remote BLE server.
  111. BLERemoteService* pRemoteService = pClient->getService(srvUUID);
  112. if (pRemoteService == nullptr) {
  113. Serial.println(" Error: Failed to find service");
  114. pClient->disconnect();
  115. return false;
  116. }
  117. Serial.println(" Service found");
  118.  
  119. remoteChr = pRemoteService->getCharacteristic(chrUUID);
  120. if (remoteChr == nullptr) {
  121. Serial.print(" Failed to find characteristic");
  122. pClient->disconnect();
  123. return false;
  124. }
  125. Serial.println(" Characteristic found");
  126. Serial.println(" Setting callback for notify / indicate");
  127. remoteChr->registerForNotify(chrCB);
  128. return true;
  129. }
  130.  
  131. void setup() {
  132. Serial.begin(115200);
  133. Serial.println("Searching for MI_SCALE device");
  134. BLEDevice::init("");
  135. BLEScan* pBLEScan = BLEDevice::getScan();
  136. pBLEScan->setAdvertisedDeviceCallbacks(new deviceCB());
  137. pBLEScan->setInterval(1349);
  138. pBLEScan->setWindow(449);
  139. //Set active scan
  140. pBLEScan->setActiveScan(true);
  141. //Scan during 5 seconds
  142. pBLEScan->start(5, false);
  143. }
  144.  
  145. void loop() {
  146. if(doConnect && !connected){
  147. connected = connectToScale();
  148. }
  149. delay(1000);
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement