Advertisement
dckiller

miscale test

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