GUI-O Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login
    Get help from AI-powered GUI-O Assistant! Open Assistant

    Looking for BLE example for UNO R4 WFi

    Scheduled Pinned Locked Moved Wishlist
    2 Posts 2 Posters 13 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      al1fch
      last edited by

      Hi

      I'm looking for a BLE exemple for an UNO R4 WiFi board (ArduinoBLE library used)
      Best Regards,
      Alain

      K 1 Reply Last reply Reply Quote 0
      • K
        kl3m3n @al1fch
        last edited by kl3m3n

        @al1fch Hi,

        try the code below (install the latest ArduinoBLE library through Library Manager).

        /*
         * GUI-O Basic BLE example for Arduino UNO R4 WiFi
         *
         * Uses the ArduinoBLE library and Nordic UART Service (NUS) UUIDs.
         *
         * Connect an LED (with a suitable series resistor) to PWM pin D9.
         * The onboard LED is not used because brightness control requires PWM.
         *
         * SPDX-License-Identifier: BSD-3-Clause
         */
        
        #include <ArduinoBLE.h>
        
        namespace led {
          constexpr uint8_t PIN = 9;  // UNO R4 WiFi PWM-capable pin
        }
        
        namespace uuid {
          constexpr char SERVICE[] = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
          constexpr char RX[]      = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
          constexpr char TX[]      = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
        }
        
        namespace ble {
          // A 20-byte payload works without depending on a larger negotiated MTU.
          constexpr size_t NOTIFY_CHUNK_SIZE = 20;
          constexpr int RX_BUFFER_SIZE = 512;
        }
        
        void parseGuioMsg(const String &msg);
        void sendMsg(const String &msg);
        
        BLEService nusService(uuid::SERVICE);
        
        // GUI-O writes commands to RX.
        BLECharacteristic rxCharacteristic(
          uuid::RX,
          BLEWrite | BLEWriteWithoutResponse,
          ble::RX_BUFFER_SIZE
        );
        
        // UNO R4 sends GUI commands through TX notifications.
        BLECharacteristic txCharacteristic(
          uuid::TX,
          BLENotify,
          ble::NOTIFY_CHUNK_SIZE
        );
        
        bool wasConnected = false;
        
        void setup() {
          Serial.begin(115200);
        
          pinMode(led::PIN, OUTPUT);
          analogWrite(led::PIN, 0);
        
          if (!BLE.begin()) {
            Serial.println("Failed to initialize BLE!");
            while (true) {
              delay(1000);
            }
          }
        
          BLE.setLocalName("BasicBLE_NUS");
          BLE.setDeviceName("BasicBLE_NUS");
          BLE.setAdvertisedService(nusService);
        
          nusService.addCharacteristic(rxCharacteristic);
          nusService.addCharacteristic(txCharacteristic);
          BLE.addService(nusService);
        
          BLE.advertise();
          Serial.println("BLE advertising started.");
        }
        
        void loop() {
          BLE.poll();
        
          BLEDevice central = BLE.central();
          const bool connected = central && central.connected();
        
          if (connected && !wasConnected) {
            Serial.print("Connected to: ");
            Serial.println(central.address());
            wasConnected = true;
          }
        
          if (!connected && wasConnected) {
            Serial.println("Disconnected!");
            wasConnected = false;
        
            // Explicitly resume advertising for reliable reconnection.
            BLE.advertise();
          }
        
          if (connected && rxCharacteristic.written()) {
            const int length = rxCharacteristic.valueLength();
        
            if (length > 0) {
              String msg;
              msg.reserve(length);
        
              const uint8_t *value = rxCharacteristic.value();
              for (int i = 0; i < length; ++i) {
                msg += static_cast<char>(value[i]);
              }
        
              parseGuioMsg(msg);
            }
          }
        }
        
        /***************************/
        /* IMPLEMENT YOUR GUI HERE */
        /***************************/
        void sendMsg(const String &msg) {
          if (!wasConnected) {
            return;
          }
        
          const uint8_t *data = reinterpret_cast<const uint8_t *>(msg.c_str());
          size_t remaining = msg.length();
        
          while (remaining > 0) {
            const size_t chunkLength =
              remaining > ble::NOTIFY_CHUNK_SIZE
                ? ble::NOTIFY_CHUNK_SIZE
                : remaining;
        
            if (!txCharacteristic.writeValue(data, chunkLength)) {
              Serial.println("Failed to send BLE notification.");
              return;
            }
        
            data += chunkLength;
            remaining -= chunkLength;
        
            BLE.poll();
            delay(10);
          }
        }
        
        void parseGuioMsg(const String &msg) {
          if (msg.startsWith("@init")) {
            Serial.println("GUI-O app is requesting INITIALIZATION!");
        
            // Clear screen and set background.
            sendMsg("@cls\r\n");
            sendMsg("@guis BGC:#FFFFFF\r\n");
            delay(100);
        
            // Initialize simple example GUI.
            sendMsg("|LB UID:title X:50 Y:15 TXT:\"Simple light switch\" FFA:\"font8\" FSZ:3.5\r\n");
            sendMsg("|LB UID:tap_me X:50 Y:70 TXT:\"TAP ME!\" FFA:\"font8\" FSZ:3 FFA:\"font5\"\r\n");
            sendMsg("|CB UID:brightness X:50 Y:50 W:90 BTH:5 HAH:8 HAW:8 VIS:0 STA:135 ENA:45 FGC:#000000 SFGC:#FFFF00 BGC:#CBCBCB\r\n");
            sendMsg("|IM UID:light_off X:50 Y:50 IP:\"https://i.imgur.com/3VbsS0Z.png\" VIS:1\r\n");
            sendMsg("|IM UID:light_on X:50 Y:50 IP:\"https://i.imgur.com/gNdck9A.png\" VIS:0\r\n");
          }
          else if (msg.startsWith("@light_off")) {
            Serial.println("GUI-O app is requesting LIGHT ON!");
        
            sendMsg("@light_off VIS:0\r\n");
            sendMsg("@light_on VIS:1\r\n");
            sendMsg("@brightness VIS:1 VAL:100\r\n");
        
            analogWrite(led::PIN, 255);
          }
          else if (msg.startsWith("@light_on")) {
            Serial.println("GUI-O app is requesting LIGHT OFF!");
        
            sendMsg("@light_off VIS:1\r\n");
            sendMsg("@light_on VIS:0\r\n");
            sendMsg("@brightness VIS:0 VAL:0\r\n");
        
            analogWrite(led::PIN, 0);
          }
          else if (msg.startsWith("@brightness")) {
            const int idx = msg.indexOf(' ');
        
            if (idx > 0) {
              const int val = msg.substring(idx + 1).toInt();
        
              if (val >= 0 && val <= 100) {
                Serial.print("GUI-O app is requesting LIGHT BRIGHTNESS: ");
                Serial.println(val);
        
                const int pwmValue = map(val, 0, 100, 0, 255);
                analogWrite(led::PIN, pwmValue);
              }
            }
          }
        }
        

        I just used Chat to port the code from ESP32 on the GUI-O website. Should work...

        Best regards,
        Kl3m3n

        1 Reply Last reply Reply Quote 0
        • First post
          Last post