ESP32使用Blinker进行物联网开发


Blinker点灯科技

官方文档
Arduino社区教程

前言

使用带有网络模块的MCU,绕不开的就是物联网开发,虽然ESP32系列支持http协议,可以使用post、get请求和服务器通信,向服务端上传数据,接收服务器的指令。但是自行开发需要构建可靠的网络通信服务器,绘制网页UI,编写APP,过于麻烦。
因此可以使用Blinker,这是国内目前做的比较好的一个物联网解决方案。主要由Arduino的库和手机APP组成,库风格清晰,容易开发,手机APP支持组件拖动搭建,界面美观

硬件准备

esp8266 / esp32开发板
LED、WS28b20、DHT11/22温湿度传感器、电阻等
20220201120654

手机APP与Arduino库

Blinker Arduino库下载
通过Arduino IDE 菜单>项目>加载库>添加.ZIP库 导入到库,如图:
加载库文件

在app中添加设备,获取Secret Key

Blinker 手机APP安卓下载
安卓手机下载apk后安装,IOS直接在APP Store中搜索Blinker下载
20220201122412

  1. 进入App,点击右上角的“+”号,然后选择 添加设备
  2. 点击选择Arduino > WiFi接入
  3. 复制申请到的Secret Key

编译并上传示例程序

打开Arduino IDE,通过 文件>示例>Blinker>Blinker_Hello/Hello_WiFi 打开例程或者复制下面的完整例程
在程序中找到保存Secret Key、WiFi名称和密码的变量,填入您要连接的WiFi名和密码,如:

1
2
3
char auth[] = "abcdefghijkl"; //上一步中在app中获取到的Secret Key
char ssid[] = "abcdefg"; //您的WiFi热点名称
char pswd[] = "123456789"; //您的WiFi密码
  • 例程中宏LED_BUILTIN为开发板厂家定义的连接板载LED的引脚,如果您选择的开发板没有定义LED_BUILTIN,可以自行修改为您要使用的引脚
  • 编译并上传程序到esp32开发板,打开串口调试器
  • 当看到提示“MQTT Connected!”,说明设备已经成功连接到MQTT服务器
    *注意:esp系列芯片只能连接2.4G WiFi热点

在APP中点击刚才您添加的设备,即可进入控制界面,点点按钮就可以控制Arduino上的LED灯开关

完整例程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#define BLINKER_PRINT Serial
#define BLINKER_WIFI

#include <Blinker.h>

char auth[] = "Your Device Secret Key";
char ssid[] = "Your WiFi network SSID or name";
char pswd[] = "Your WiFi network WPA password or WEP key";

// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");

int counter = 0;

// 手机APP按下按键即会执行该函数
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}

void setup() {
// 初始化串口
Serial.begin(115200);

#if defined(BLINKER_PRINT)
BLINKER_DEBUG.stream(BLINKER_PRINT);
#endif

// 初始化有LED的IO
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback); // 绑定按键回调函数
}

void loop()
{
Blinker.run();
}

例程分析

1
#define BLINKER_WIFI

用于指定设备接入方式,你还可以使用 BLINKER_BLE,不同的接入方式对应的Blinker初始化函数也不同:

蓝牙接入

1
2
3
4
5
6
#define BLINKER_BLE  
#include <Blinker.h>

void setup() {
Blinker.begin();
}

WiFi接入

1
2
3
4
5
6
#define BLINKER_WIFI  
#include <Blinker.h>

void setup() {
Blinker.begin(auth, ssid, pswd);
}

新建组件并绑定回调函数

新建组件

blinker app上每个UI组件在设备端都可以创建一个对应的对象。创建方式如下:

组件类型 对象名(键名)

app中组件对应的键名可以在界面编辑模式下看到。
使用组件的数据键名创建对应的对象,这个对象就与blinker app界面上的UI组件进行了绑定。
blinker库定义了多种组件类型,对应app上UI组件类型,如
BlinkerSlider 滑块组件
BlinkerRGB 颜色拾取组件
BlinkerNumber 数值组件
BlinkerText 文本组件
如下,创建了按键组件和数值组件对应的对象:

1
2
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");
回调函数
1
2
3
4
5
>void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
绑定回调函数
1
Button1.attach(button1_callback);

当app中组件触发并发送到设备端时将触发该组件注册的回调函数

Blinker运行时
1
2
3
4
>void loop()
{
Blinker.run();
}

Blinker.run()语句负责处理Blinker收到的数据,每次运行都会将设备收到的数据进行一次解析。
在使用WiFi接入时,该语句也负责保持网络连接

开启调试信息

你可以在setup中添加以下语句,以查看调试信息
BLINKER_DEBUG.stream(Serial);

用于指定调试信息输出的串口,设备开发时调试使用,项目或产品成型后,可以删除。
如果需要查看更多内部信息,可以添加
BLINKER_DEBUG.debugAll();

数据同步

Blinker可以将设备端采集的温湿度数据,通过心跳包同步数据的方式,显示到APP上。

  • 通过界面编辑功能,添加两个数据组件
  • 将数据键值分别设为humi和temp,两个组件分别对应温湿度数据。如图:
  • 还可以添加一个调试组件,用以观察APP收到的数据,方便调试程序。
    添加组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#define BLINKER_WIFI

#include <Blinker.h>
#include <DHT.h>

char auth[] = "Your Device Secret Key";
char ssid[] = "Your WiFi network SSID or name";
char pswd[] = "Your WiFi network WPA password or WEP key";

BlinkerNumber HUMI("humi"); // 数据组件
BlinkerNumber TEMP("temp");

#define DHTPIN D7

//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

float humi_read = 0, temp_read = 0;

void heartbeat() // 心跳组件,每60s触发一次,将数据上传
{
HUMI.print(humi_read);
TEMP.print(temp_read);
}

void setup()
{
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);

Blinker.begin(auth, ssid, pswd);
Blinker.attachHeartbeat(heartbeat); // 注册数据组件
dht.begin();
}

void loop()
{
Blinker.run();

float h = dht.readHumidity();
float t = dht.readTemperature();

if (isnan(h) || isnan(t))
{
BLINKER_LOG("Failed to read from DHT sensor!");
}
else
{
BLINKER_LOG("Humidity: ", h, " %");
BLINKER_LOG("Temperature: ", t, " *C");
humi_read = h;
temp_read = t;
}

Blinker.delay(2000);
}

需要注意的是:blinker下的所有延时操作,都需要使用Blinker.delay(ms);替代,否则会导致设备断开连接。

组件介绍

文字组件

1
2
3
BlinkerText Text1("tex-123");
Text1.text = "Test";
Text1.print()

按键组件

1
2
3
4
5
6
7
8
9
BlinkerNumber button1("btn-123");

void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

button1.attach(button1_callback);

数据组件

1
2
3
BlinkerNumber TEMP("temp")

TEMP.print(temp_read);

滑块组件

1
2
3
4
5
6
7
8
BlinkerSlider Slider1("sli-123");  // 创建实例

void Slider1_callback(int val) // 回调函数 参数val是APP的滑动条长度,在0~100之间
{

}

Slider1.attach(Slider1_callback) // 绑定回调函数

摇杆组件

1
2
3
4
5
6
7
8
BlinkerJoystick JoyStick1("joy-123");  // 创建实例

void JoyStick1_callback(int val*) // 回调函数 参数val是摇杆的左边(X,Y),在0~255之间
{

}

JoyStick1.attach(Slider1_callback) // 绑定回调函数

图片组件

1
2
3
4
5
6
7
8
BlinkerImage Image1("img-123");  // 创建实例

Image1_callback(String url) // 回调函数 参数val是摇杆的左边(X,Y),在0~255之间
{
Image1.set(url)
}

Image1.attach(Slider1_callback) // 绑定回调函数

图表组件

待补完

地图组件

视频组件


文章作者: Allen Hong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Allen Hong !
  目录