espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.78k stars 7.44k forks source link

BLE Provisioning not working on iOS #7657

Open Ankita-Dasgupta opened 1 year ago

Ankita-Dasgupta commented 1 year ago

Board

ESP32 Dev Module

Device Description

ESP32 attached to power source

Hardware Configuration

Only power source connected, LED used is on the board

Version

latest master (checkout manually)

IDE Name

Arduino IDE

Operating System

macOS 13.0.1

Flash frequency

80MHz

PSRAM enabled

yes

Upload speed

115200

Description

I ran the example code RMakerSwitch and I'm unable to do the BLE Provisioning. I have an iOS and when I tried again with an android it worked. I've also tried using the RainMaker BLE Provisioning app which does work but it doesn't add the device so I can't see it on the RainMaker app.

Sketch

//This example demonstrates the ESP RainMaker with a standard Switch device.
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"

#define DEFAULT_POWER_MODE true
const char *service_name = "PROV_1234";
const char *pop = "abcd1234";

//GPIO for push button
#if CONFIG_IDF_TARGET_ESP32C3
static int gpio_0 = 9;
static int gpio_switch = 7;
#else
//GPIO for virtual device
static int gpio_0 = 0;
static int gpio_switch = 16;
#endif

/* Variable for reading pin status*/
bool switch_state = true;

//The framework provides some standard device types like switch, lightbulb, fan, temperaturesensor.
static Switch my_switch;

void sysProvEvent(arduino_event_t *sys_event)
{
    switch (sys_event->event_id) {
        case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32S2
            Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
            printQR(service_name, pop, "softap");
#else
            Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
            printQR(service_name, pop, "ble");
#endif
            break;
        case ARDUINO_EVENT_PROV_INIT:
            wifi_prov_mgr_disable_auto_stop(10000);
            break;
        case ARDUINO_EVENT_PROV_CRED_SUCCESS:
            wifi_prov_mgr_stop_provisioning();
            break;
        default:;
    }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
    const char *device_name = device->getDeviceName();
    const char *param_name = param->getParamName();

    if(strcmp(param_name, "Power") == 0) {
        Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
        switch_state = val.val.b;
        (switch_state == false) ? digitalWrite(gpio_switch, LOW) : digitalWrite(gpio_switch, HIGH);
        param->updateAndReport(val);
    }
}

void setup()
{
    Serial.begin(115200);
    pinMode(gpio_0, INPUT);
    pinMode(gpio_switch, OUTPUT);
    digitalWrite(gpio_switch, DEFAULT_POWER_MODE);

    Node my_node;
    my_node = RMaker.initNode("ESP RainMaker Node");

    //Initialize switch device
    my_switch = Switch("Switch", &gpio_switch);

    //Standard switch device
    my_switch.addCb(write_callback);

    //Add switch device to the node
    my_node.addDevice(my_switch);

    //This is optional
    RMaker.enableOTA(OTA_USING_TOPICS);
    //If you want to enable scheduling, set time zone for your region using setTimeZone().
    //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
    // RMaker.setTimeZone("Asia/Shanghai");
    // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
    RMaker.enableTZService();

    RMaker.enableSchedule();

    RMaker.enableScenes();

    RMaker.start();

    WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32S2
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#else
    WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#endif
}

void loop()
{
    if(digitalRead(gpio_0) == LOW) { //Push button pressed

        // Key debounce handling
        delay(100);
        int startTime = millis();
        while(digitalRead(gpio_0) == LOW) delay(50);
        int endTime = millis();

        if ((endTime - startTime) > 10000) {
          // If key pressed for more than 10secs, reset all
          Serial.printf("Reset to factory.\n");
          RMakerFactoryReset(2);
        } else if ((endTime - startTime) > 3000) {
          Serial.printf("Reset Wi-Fi.\n");
          // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
          RMakerWiFiReset(2);
        } else {
          // Toggle device state
          switch_state = !switch_state;
          Serial.printf("Toggle State to %s.\n", switch_state ? "true" : "false");
          my_switch.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state);
          (switch_state == false) ? digitalWrite(gpio_switch, LOW) : digitalWrite(gpio_switch, HIGH);
      }
    }
    delay(100);
}

Debug Message

it is not able to connect to the wifi

Other Steps to Reproduce

It worked on Android.

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 year ago

@sanketwadekar - Could you please take a look? Thanks!

sanketwadekar commented 1 year ago

@Ankita-Dasgupta please specify the version of ESP32-Arduino and iOS version. Also, check if your Rainmaker app is updated. Thanks

JohnMacrae commented 7 months ago

I am not the OP but I can confirm this does not work with Arduino 2.0.16 but using 2.0.6 (Last version I know to work) does provision properly. I'm not sure its an iOS problem as I also saw it on Android - the problem is in Rainmaker itself. My module ESP32 Wroom, 4Mb, Arduino IDE 2.3.2, Win11. @sanketwadekar (I can test more versions but this will run me out of node space on the dashboard).