aboutsummaryrefslogtreecommitdiff
path: root/mussel2/mussel2.ino
blob: d7ad8165412a88a88849acd597ec8072ff1d391f (plain)
  1. /// mussel2 - mussel voter influenced by time
  2. ///
  3. /// SPDX-License-Identifier: GPL-3.0-or-later
  4. /// SPDX-FileCopyrightText: 2015-2023 Espressif Systems
  5. /// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
  6. ///
  7. /// Based on example `libraries/BLE/examples/iBeacon/iBeacon.ino`
  8. /// in project <https://github.com/espressif/arduino-esp32/>.
  9. /*
  10. Create a BLE server that will send periodic iBeacon frames.
  11. The design of creating the BLE server is:
  12. 1. Create a BLE Server
  13. 2. Create advertising data
  14. 3. Start advertising.
  15. 4. wait
  16. 5. Stop advertising.
  17. */
  18. #include <BLEDevice.h>
  19. #include <BLEServer.h>
  20. #include <BLEUtils.h>
  21. #include <BLE2902.h>
  22. #include <BLEBeacon.h>
  23. #define DEVICE_NAME "Cycles of five good then one bad"
  24. #define SERVICE_UUID "32eed4b3-e233-4808-a120-c4cee1a8e0c5"
  25. #define BEACON_UUID "84b7f168-a742-49b7-bd15-dc808dddb672"
  26. #define BEACON_UUID_REV "87a3c0f9-695f-4c04-8195-3a89d6cd44f0"
  27. #define CHARACTERISTIC_UUID "738e7085-9717-4288-ab21-c59ff7c5dd96"
  28. BLEServer *pServer;
  29. BLECharacteristic *pCharacteristic;
  30. bool deviceConnected = false;
  31. uint8_t value = 0;
  32. class MyServerCallbacks : public BLEServerCallbacks {
  33. void onConnect(BLEServer *pServer) {
  34. deviceConnected = true;
  35. Serial.println("deviceConnected = true");
  36. };
  37. void onDisconnect(BLEServer *pServer) {
  38. deviceConnected = false;
  39. Serial.println("deviceConnected = false");
  40. // Restart advertising to be visible and connectable again
  41. BLEAdvertising *pAdvertising;
  42. pAdvertising = pServer->getAdvertising();
  43. pAdvertising->start();
  44. Serial.println("iBeacon advertising restarted");
  45. }
  46. };
  47. class MyCallbacks : public BLECharacteristicCallbacks {
  48. void onWrite(BLECharacteristic *pCharacteristic) {
  49. String rxValue = pCharacteristic->getValue();
  50. if (rxValue.length() > 0) {
  51. Serial.println("*********");
  52. Serial.print("Received Value: ");
  53. for (int i = 0; i < rxValue.length(); i++) {
  54. Serial.print(rxValue[i]);
  55. }
  56. Serial.println();
  57. Serial.println("*********");
  58. }
  59. }
  60. };
  61. void init_service() {
  62. BLEAdvertising *pAdvertising;
  63. pAdvertising = pServer->getAdvertising();
  64. pAdvertising->stop();
  65. // Create the BLE Service
  66. BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID));
  67. // Create a BLE Characteristic
  68. pCharacteristic = pService->createCharacteristic(
  69. CHARACTERISTIC_UUID,
  70. BLECharacteristic::PROPERTY_READ
  71. | BLECharacteristic::PROPERTY_WRITE
  72. | BLECharacteristic::PROPERTY_NOTIFY
  73. );
  74. pCharacteristic->setCallbacks(new MyCallbacks());
  75. pCharacteristic->addDescriptor(new BLE2902());
  76. pAdvertising->addServiceUUID(BLEUUID(SERVICE_UUID));
  77. // Start the service
  78. pService->start();
  79. pAdvertising->start();
  80. }
  81. void init_beacon() {
  82. BLEAdvertising *pAdvertising;
  83. pAdvertising = pServer->getAdvertising();
  84. pAdvertising->stop();
  85. // iBeacon
  86. BLEBeacon myBeacon;
  87. myBeacon.setManufacturerId(0x4c00);
  88. myBeacon.setMajor(5);
  89. myBeacon.setMinor(88);
  90. myBeacon.setSignalPower(0xc5);
  91. myBeacon.setProximityUUID(BLEUUID(BEACON_UUID_REV));
  92. BLEAdvertisementData advertisementData;
  93. advertisementData.setFlags(0x1A);
  94. advertisementData.setManufacturerData(myBeacon.getData());
  95. pAdvertising->setAdvertisementData(advertisementData);
  96. pAdvertising->start();
  97. }
  98. void setup() {
  99. Serial.begin(115200);
  100. Serial.println();
  101. Serial.println("Initializing...");
  102. Serial.flush();
  103. BLEDevice::init(DEVICE_NAME);
  104. pServer = BLEDevice::createServer();
  105. pServer->setCallbacks(new MyServerCallbacks());
  106. init_service();
  107. init_beacon();
  108. Serial.printf("iBeacon + service defined and advertising: %s",
  109. DEVICE_NAME);
  110. }
  111. void loop() {
  112. if (deviceConnected) {
  113. // Get second-long cyclic counter 0-11
  114. unsigned long currentTime = millis();
  115. unsigned long totalSeconds = currentTime / 1000;
  116. unsigned long currentSecond = totalSeconds % 12;
  117. String msg = "good";
  118. if (currentSecond >= 9)
  119. msg = "bad";
  120. Serial.printf("*** NOTIFY: %s ***\n", msg);
  121. pCharacteristic->setValue(msg);
  122. pCharacteristic->notify();
  123. value++;
  124. }
  125. delay(2000);
  126. }