Flutter ESP32配网插件esp_provisioning_softap的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter ESP32配网插件esp_provisioning_softap的使用

esp_provisioning_softap 是一个用于通过SoftAP配置ESP32模块的Flutter插件。

版本信息

示例应用

GIF 图由原始 pub 包 esp_softap_provisioning 提供

比较

esp_provisioning 的比较:

仓库 SoftAP 支持 BLE 支持 加密 Protobuf
esp_provisioning_softap ✔️ ✖️ ✔️ (2.0.1) ✔️ (2.0.0)
esp_provisioning ✖️ ✔️ ✔️ (1.4.1) ✔️ (1.0.1)

最后更新日期:2022 年 3 月 24 日

使用方法

1. 添加依赖

pubspec.yaml 文件中添加依赖:

dependencies:
  esp_provisioning_softap_null_safe: ^1.0.0

然后运行以下命令以获取依赖项:

flutter pub get
2. 配置权限
Android

<your_app>/android/app/src/main/AndroidManifest.xml 中添加以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:label="yourapp"
        android:icon="@mipmap/ic_launcher"
        android:usesCleartextTraffic="true">
        ...
    </application>
</manifest>
iOS

<your_app>/ios/Runner/Info.plist 中添加以下内容:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>wifi-prov.local</key>
        <dict>
           <key>NSIncludesSubdomains</key>
           <true/>
           <key>NSExceptionAllowsInsecureHTTPLoads</key>
           <true/>
           <key>NSExceptionMinimumTLSVersion</key>
           <string>1.0</string>
           <key>NSExceptionRequiresForwardSecrecy</key>
           <true/>
        </dict>
    </dict>
</dict>

确保在 Podfile 中设置平台版本 >= 9.0。可以编辑此变量:

platform :ios, '9.0'

完整示例代码

以下是完整的示例代码,展示了如何使用 esp_provisioning_softap 插件进行ESP32设备的配置。

import 'package:flutter/material.dart';
import 'package:esp_provisioning_softap_null_safe/esp_provisioning_softap_null_safe.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ESP SoftAp Provisioning'),
        backgroundColor: Colors.blue,
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // 启动软AP配网流程
            await EspProvisioningSoftap.startProvisioning();
          },
          child: Text(
            '开始配网',
            style: TextStyle(color: Colors.white),
          ),
          style: ElevatedButton.styleFrom(
            primary: Colors.blueAccent,
            padding: EdgeInsets.all(15.0),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(5.0),
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter ESP32配网插件esp_provisioning_softap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter ESP32配网插件esp_provisioning_softap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用ESP32配网插件esp_provisioning_softap的示例代码案例。这个示例将展示如何通过SoftAP(软件接入点)模式为ESP32设备配网。

前提条件

  1. Flutter开发环境:确保你的开发环境中已经安装了Flutter和Dart。
  2. ESP-IDF环境:ESP32设备端的代码需要使用ESP-IDF来编译和烧录。
  3. Flutter插件:确保已经添加了esp_provisioning_softap插件到你的Flutter项目中。你可以通过pubspec.yaml文件添加依赖:
dependencies:
  flutter:
    sdk: flutter
  esp_provisioning_softap: ^x.y.z  # 替换为实际版本号

Flutter端代码

以下是一个简单的Flutter应用示例,用于连接到ESP32的SoftAP并发送配网信息。

import 'package:flutter/material.dart';
import 'package:esp_provisioning_softap/esp_provisioning_softap.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _ssid = '';
  String _password = '';
  String _ipAddress = '';
  String _status = '';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ESP32 SoftAP Provisioning'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              TextField(
                decoration: InputDecoration(labelText: 'SSID'),
                onChanged: (value) => setState(() => _ssid = value),
              ),
              TextField(
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
                onChanged: (value) => setState(() => _password = value),
              ),
              TextField(
                decoration: InputDecoration(labelText: 'ESP32 IP Address'),
                keyboardType: TextInputType.ipv4,
                onChanged: (value) => setState(() => _ipAddress = value),
              ),
              ElevatedButton(
                onPressed: () async {
                  setState(() => _status = 'Provisioning...');
                  bool success = await provisionDevice(
                    ssid: _ssid,
                    password: _password,
                    ipAddress: _ipAddress,
                  );
                  setState(() => _status = success ? 'Provisioned Successfully!' : 'Provisioning Failed');
                },
                child: Text('Provision Device'),
              ),
              Text(_status, style: TextStyle(fontSize: 18, color: Colors.red)),
            ],
          ),
        ),
      ),
    );
  }

  Future<bool> provisionDevice({required String ssid, required String password, required String ipAddress}) async {
    try {
      // 初始化并连接到ESP32的SoftAP
      final provisioningClient = ESPProvisioningSoftAP(ipAddress: ipAddress);
      await provisioningClient.connect();

      // 发送配网信息
      await provisioningClient.provisionWifi(ssid: ssid, password: password);
      return true;
    } catch (e) {
      print('Error: $e');
      return false;
    }
  }
}

ESP32端代码

在ESP32端,你需要使用ESP-IDF来设置SoftAP并监听配网请求。以下是一个简单的示例代码:

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_prov.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"

static const char *TAG = "example";

// SoftAP配置
#define EXAMPLE_ESP_SOFTAP_SSID "ESP_SoftAP"
#define EXAMPLE_ESP_SOFTAP_PASS "esp32password"
#define EXAMPLE_ESP_SOFTAP_CHANNEL 6
#define EXAMPLE_ESP_SOFTAP_IP     IPSTR_TO_U32("192.168.4.1")
#define EXAMPLE_ESP_SOFTAP_MASK   IPSTR_TO_U32("255.255.255.0")

static void wifi_init_softap(void)
{
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    wifi_config_t softap_config = {
        .sta = {
            .ssid = 0,
            .password = 0,
            .threshold.authmode = WIFI_AUTH_OPEN,
        },
        .softap = {
            .ssid = EXAMPLE_ESP_SOFTAP_SSID,
            .password = EXAMPLE_ESP_SOFTAP_PASS,
            .channel = EXAMPLE_ESP_SOFTAP_CHANNEL,
            .authmode = WIFI_AUTH_WPA2_PSK,
            .ssid_len = strlen(EXAMPLE_ESP_SOFTAP_SSID),
            .max_connection = 4,
            .beacon_interval = 100
        },
    };

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_SOFTAP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &softap_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
             EXAMPLE_ESP_SOFTAP_SSID, EXAMPLE_ESP_SOFTAP_PASS, EXAMPLE_ESP_SOFTAP_CHANNEL);
}

void app_main(void)
{
    // 初始化NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_LOGI(TAG, "ESP_WIFI_MODE_SOFTAP");
    wifi_init_softap();

    // 初始化配网
    esp_prov_config_t config = {
        .scheme = ESP_PROV_SCHEME_SOFTAP,
        .app_id = "your_app_id",
        .app_key = "your_app_key",
        .vendor_ie_data = NULL,
        .vendor_ie_len = 0,
    };

    esp_prov_handle_t handle;
    esp_err_t ret = esp_prov_start(&config, &handle);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to start provisioning");
        return;
    }

    ESP_LOGI(TAG, "Waiting for device to be provisioned...");

    // 等待配网完成事件
    while (true) {
        esp_prov_session_status_t status = esp_prov_get_status(handle);
        if (status == ESP_PROV_SESSION_SUCCESS) {
            ESP_LOGI(TAG, "Provisioning success");
            break;
        } else if (status == ESP_PROV_SESSION_FAILED || status == ESP_PROV_SESSION_TIMEOUT) {
            ESP_LOGE(TAG, "Provisioning failed or timed out");
            break;
        }
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

    esp_prov_stop(handle);
}

注意事项

  1. 依赖项:确保Flutter插件esp_provisioning_softap已经正确集成,并且ESP-IDF环境已经设置好。
  2. 安全性:在实际应用中,请确保使用安全的SSID和密码,并且保护好你的app_idapp_key
  3. IP地址:在Flutter应用中,确保输入的ESP32 IP地址是正确的,并且设备已经启动SoftAP模式。

这个示例展示了基本的配网流程,你可能需要根据具体需求进行进一步的定制和扩展。

回到顶部