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

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

在app中添加设备,获取Secret Key
Blinker 手机APP安卓下载
安卓手机下载apk后安装,IOS直接在APP Store中搜索Blinker下载

- 进入App,点击右上角的“+”号,然后选择 添加设备
- 点击选择Arduino > WiFi接入
- 复制申请到的Secret Key
编译并上传示例程序
打开Arduino IDE,通过 文件>示例>Blinker>Blinker_Hello/Hello_WiFi 打开例程或者复制下面的完整例程
在程序中找到保存Secret Key、WiFi名称和密码的变量,填入您要连接的WiFi名和密码,如:
1 2 3
| char auth[] = "abcdefghijkl"; char ssid[] = "abcdefg"; char pswd[] = "123456789";
|
- 例程中宏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;
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 pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); Blinker.begin(auth, ssid, pswd); Blinker.attachData(dataRead); Button1.attach(button1_callback); }
void loop() { Blinker.run(); }
|
例程分析
用于指定设备接入方式,你还可以使用 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 DHT22
DHT dht(DHTPIN, DHTTYPE);
float humi_read = 0, temp_read = 0;
void heartbeat() { 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) {
}
Slider1.attach(Slider1_callback)
|
摇杆组件
1 2 3 4 5 6 7 8
| BlinkerJoystick JoyStick1("joy-123");
void JoyStick1_callback(int val*) {
}
JoyStick1.attach(Slider1_callback)
|
图片组件
1 2 3 4 5 6 7 8
| BlinkerImage Image1("img-123");
Image1_callback(String url) { Image1.set(url) }
Image1.attach(Slider1_callback)
|
图表组件
待补完
地图组件
视频组件