16. Arduino 编程最佳实践
16.1 远程IO控制器
此项目通过阿里云 IoT Studio ,建立一个控制界面,用于控制IO扩展板的 8路继电器,读取每个输入通道的状态。
项目功能:
Edge101WE 主板叠加 IO扩展板,通过阿里云IoT上传输入通道数据。并接阿里云下发的继电器控制指令,控制继电器。
IoT Studio 建立Web操作界面,可控制每一路继电器。
具备阿里OTA功能。
1、创建云端产品以及设备
2、Web应用
接下来,我们根据此设备开发一个Web应用,访问网址:https://www.aliyun.com/product/iotstudio
浏览器访问此链接,到这里我们就搭建完成一个Web应用了
3、OTA 远程升级设置
接下来我们来搭建OTA功能,本系统采用的是自动升级,系统连接网络接上云端后,会自动上传固件版本号,若固件版本低于升级包的版本,将会进行空中升级。
4、例程代码
/*!
* @file relayOTA.ino
*
* @brief Simulate esp32 as a bedroom light and use Aliyun as a cloud platform.
* @n Subscribe to the relay control topic, which is the relay that can control the extension board in the cloud, and report the status of the 8-way input channel of the extension board
* @n Aliyun OTA
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @licence The MIT License (MIT)
* @author [Yangfeng](feng.yang@dfrobot.com)
* @version V1.0
* @date 2021-06-24
* @get from https://www.dfrobot.com
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "DFRobot_Iot.h"
#include "HttpsOTAUpdate.h"
#include "DFRobot_IOExpension.h"
/*Configure the WiFi name and password*/
const char * WIFI_SSID = "++++++++";
const char * WIFI_PASSWORD = "++++++++";
/*Configure the device certificate information*/
String ProductKey = "++++++";
String ClientId = "1234";/*The custom ID*/
String DeviceName = "++++++";
String DeviceSecret = "++++++";
/*Configure the domain name and port number*/
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;
/*Topics to be reported and subscribed to*/
const char * subTopic = "/sys/${ProductKey}/${DeviceName}/thing/service/property/set";
const char * subTopic1 = "/ota/device/upgrade/${ProductKey}/${DeviceName}";
const char * pubTopic1 = "/ota/device/inform/${ProductKey}/${DeviceName}";
const char * pubTopic = "/sys/${ProductKey}/${DeviceName}/thing/event/property/post";
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\r\n"
"MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\r\n" \
"A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\r\n" \
"b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\r\n" \
"MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\r\n" \
"YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\r\n" \
"aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\r\n" \
"jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\r\n" \
"xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\r\n" \
"1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\r\n" \
"snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\r\n" \
"U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\r\n" \
"9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\r\n" \
"BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\r\n" \
"AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\r\n" \
"yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\r\n" \
"38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\r\n" \
"AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\r\n" \
"DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\r\n" \
"HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\r\n" \
"-----END CERTIFICATE-----";
static HttpsOTAStatus_t otastatus;
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
DFRobot_Iot myIot;
WiFiClient espClient;
PubSubClient client(espClient);
bool interruptFlag = false;
static void inputGetStatus();
static void interEvent();
void HttpEvent(HttpEvent_t *event)
{
switch(event->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("Http Event Error");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("Http Event On Connected");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("Http Event Header Sent");
break;
case HTTP_EVENT_ON_HEADER:
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
break;
case HTTP_EVENT_ON_DATA:
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("Http Event On Finish");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("Http Event Disconnected");
break;
}
}
void connectWiFi(){
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID,WIFI_PASSWORD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP Adderss: ");
Serial.println(WiFi.localIP());
}
void callback(char * topic, byte * payload, unsigned int len){
Serial.print("Recevice [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < len; i++){
Serial.print((char)payload[i]);
}
Serial.println();
StaticJsonDocument<300> jsonBuffer;
auto error = deserializeJson(jsonBuffer, (char *)payload);
if (error){
Serial.println("parseObject() failed:");
Serial.println(error.f_str());
}
if( strcmp(topic,subTopic1)==0){
String str = jsonBuffer["data"]["url"];
if(str.compareTo("null")!=0){
String version0 =jsonBuffer["data"]["version"] ;
String a = "\"";
String version = a+version0+a;
Serial.println(version);
Serial.println(str);
HttpsOTA.onHttpEvent(HttpEvent);
Serial.println("Starting OTA");
HttpsOTA.begin(const_cast<char *>(str.c_str()) , server_certificate);
Serial.println("Please Wait it takes some time ...");
while(1){
otastatus = HttpsOTA.status();
if(otastatus == HTTPS_OTA_SUCCESS) {
client.publish(pubTopic1,("{\"id\":"+ClientId+",\"params\":{\"version\":"+version+",\"module\":\"esp32\"}}").c_str());
Serial.printf("Firmware written successfully. Current version information: %s . To reboot device, call API ESP.restart() or PUSH restart button on device",version0);
Serial.println("Auto restart after 3 seconds");
for(uint8_t i=0;i<2;i++){
delay(1000);
Serial.print(".");
}
delay(1000);
Serial.println(".");
ESP.restart();
} else if(otastatus == HTTPS_OTA_FAIL) {
Serial.println("Firmware Upgrade Fail");
break;
}
}
}
}else if( strcmp(topic,subTopic)==0){
String param = jsonBuffer["params"];
if(strstr(param.c_str(), "relay_1") != NULL){
const bool relay_1 = jsonBuffer["params"]["relay_1"];
IOExpension.setRelayStatus(/*channel= */1,/*mode=*/relay_1);
}
if(strstr(param.c_str(), "relay_2") != NULL){
const bool relay_2 = jsonBuffer["params"]["relay_2"];
IOExpension.setRelayStatus(/*channel= */2,/*mode=*/relay_2);
}
if(strstr(param.c_str(), "relay_3") != NULL){
const bool relay_3 = jsonBuffer["params"]["relay_3"];
IOExpension.setRelayStatus(/*channel= */3,/*mode=*/relay_3);
}
if(strstr(param.c_str(), "relay_4") != NULL){
const bool relay_4 = jsonBuffer["params"]["relay_4"];
IOExpension.setRelayStatus(/*channel= */4,/*mode=*/relay_4);
}
if(strstr(param.c_str(), "relay_5") != NULL){
const bool relay_5 = jsonBuffer["params"]["relay_5"];
IOExpension.setRelayStatus(/*channel= */5,/*mode=*/relay_5);
}
if(strstr(param.c_str(), "relay_6") != NULL){
const bool relay_6 = jsonBuffer["params"]["relay_6"];
IOExpension.setRelayStatus(/*channel= */6,/*mode=*/relay_6);
}
if(strstr(param.c_str(), "relay_7") != NULL){
const bool relay_7 = jsonBuffer["params"]["relay_7"];
IOExpension.setRelayStatus(/*channel= */7,/*mode=*/relay_7);
}
if(strstr(param.c_str(), "relay_8") != NULL){
const bool relay_8 = jsonBuffer["params"]["relay_8"];
IOExpension.setRelayStatus(/*channel= */8,/*mode=*/relay_8);
}
/*Publish the state of the relay*/
String tempMseg = "{\"id\":" + ClientId + ",\"params\":"+param+",\"method\":\"thing.event.property.post\"}";
char sendMseg[tempMseg.length()];
strcpy(sendMseg, tempMseg.c_str());
client.publish(pubTopic, sendMseg);
}
}
void ConnectAliyun(){
while (!client.connected()){
Serial.print("Attempting MQTT connection...");
/*A device connected to the cloud platform based on an automatically calculated username and password*/
if (client.connect(myIot._clientId, myIot._username, myIot._password)){
Serial.println("connected");
client.subscribe(subTopic);
client.subscribe(subTopic1);
} else{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup(){
Serial.begin(115200);
while(!Serial);
IOExpension.begin();
IOExpension.setRelayStatus(/*channel= */1,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */2,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */3,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */4,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */5,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */6,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */7,/*mode=*/0);
IOExpension.setRelayStatus(/*channel= */8,/*mode=*/0);
/* connect WIFI */
connectWiFi();
/*Initializes Alinyun's configuration to automatically calculate user name and password*/
myIot.init(ALIYUN,ALIYUN_SERVER,ProductKey,ClientId,DeviceName,DeviceSecret,PORT);
client.setServer(myIot._mqttServer,PORT);
/*Set the callback function that executes when a subscription is received*/
client.setCallback(callback);
/*Connect to the Aliyun*/
ConnectAliyun();
/*Report firmware version information*/
client.publish(pubTopic1,("{\"id\":"+ClientId+",\"params\":{\"version\":\"V1.0\",\"module\":\"esp32\"}}").c_str());
/*Reports the status of relays and input channels*/
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"relay_1\":0,\"relay_2\":0,\"relay_3\":0,\"relay_4\":0,\"relay_5\":0,\"relay_6\":0,\"relay_7\":0,\"relay_8\":0},\"method\":\"thing.event.property.post\"}").c_str());
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"INPUT_1\":0,\"INPUT_2\":0,\"INPUT_3\":0,\"INPUT_4\":0,\"INPUT_5\":0,\"INPUT_6\":0,\"INPUT_7\":0,\"INPUT_8\":0},\"method\":\"thing.event.property.post\"}").c_str());
}
uint8_t statusLast,statusNow;
void loop(){
if(!client.connected()){
ConnectAliyun();
}
client.loop();
statusNow = IOExpension.readInputStauts();
if(statusNow!=statusLast){
inputGetStatus(statusNow);
statusLast = statusNow;
}
delay(500);
}
static void inputGetStatus(uint8_t status)
{
bool switch_1,switch_2,switch_3,switch_4,switch_5,switch_6,switch_7,switch_8;
if(status & SWITCH_COUNTER_1){
switch_1 = 1;
} else{
switch_1 = 0;
}
if(status & SWITCH_COUNTER_2){
switch_2 = 1;
} else{
switch_2 = 0;
}
if(status & SWITCH_COUNTER_3){
switch_3 = 1;
} else{
switch_3 = 0;
}
if(status & SWITCH_COUNTER_4){
switch_4 = 1;
} else{
switch_4 = 0;
}
if(status & SWITCH_COUNTER_5){
switch_5 = 1;
} else{
switch_5 = 0;
}
if(status & SWITCH_COUNTER_6){
switch_6 = 1;
} else{
switch_6 = 0;
}
if(status & SWITCH_COUNTER_7){
switch_7 = 1;
} else{
switch_7 = 0;
}
if(status & SWITCH_COUNTER_8){
switch_8 = 1;
} else{
switch_8 = 0;
}
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"INPUT_1\":"+switch_1+",\"INPUT_2\":"+switch_2+",\"INPUT_3\":"+switch_3+",\"INPUT_4\":"+switch_4+",\"INPUT_5\":"+switch_5+",\"INPUT_6\":"+switch_6+",\"INPUT_7\":"+switch_7+",\"INPUT_8\":"+switch_8+"},\"method\":\"thing.event.property.post\"}").c_str());
}
16.2 工业脉冲计数器和OEE有效产能统计系统
工业场景中脉冲计数器通常连接接近开关、光电开关、霍尔开关等传感器用于对工业现场进行计数,也可以外接按钮进行人工按键计数。
可实现一次感应计一个数、一次感应计多个数、多次感应计一个数。实现自动复位和手动复位。可设定报警输出。意外断电可继续计数。
项目功能:
使用DFRobot的光电传感器和 I2C 数码管模块实现一个包装机工业计数器,当包装好的货物通过传送带时,光电传感器检测后记录数量,并通过数码管显示出来。
主板意外断电后可继续计数。
外接一个清零开关,当按下超过5秒后,计数值清零。
通过阿里云显示当天是否开机、开机的时间长度、包装数量。
可通过阿里云OTA进行程序升级。
Gravity: 8位数码管显示模块: https://www.dfrobot.com.cn/goods-2602.html
工业级背景抑制光电传感器: https://www.dfrobot.com.cn/goods-3111.html
一、搭建云平台
1、创建本次产品以及设备
首先访问阿里云首页(https://www.aliyun.com/)并登录自己的账号,进入自己的控制台。
接下来,我们就开始来创建一个产品和设备
创建好产品后我们先来为产定义物理模型
这里我们创建两个功能,一个用来记录系统开机时间,一个用来记录包装数量。
接下来我们为此产品创建一个设备
这里保存设备证书信息,并写入代码中
到这里,我们就可以将设备证书填写到代码中,并且修改配网信息,运行一次程序,使得云端设备激活。
2、创建一个Web应用
访问链接 https://www.aliyun.com/product/iotstudio
执行完上步骤后自动跳转到此界面
执行完上步骤后自动跳转到此界面
关联好产品和设备后,我们回到Web应用编辑界面
根据自己的喜好配置一些界面可以使其更加美观,当编辑好界面后,点击“发布“。
访问刚刚记录的链接,到这里我们就可以实时观察系统的包装数量和系统开机时间长度了。
3、OTA升级任务的创建
创建一次升级任务
到这里我们就创建好了一次升级任务,在升级任务作用的时间内,设备上线并且符合升级要求,将会进行自动升级。
升级完成样式如图。
二、例程
# include "DFRobot_LedDisplayModule.h"
#include "DFRobot_IOExpension.h"
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "DFRobot_Iot.h"
#include "HttpsOTAUpdate.h"
//#define CONNECT_ALIYUN
/*Configure the WiFi name and password*/
const char * WIFI_SSID = "++++++++";
const char * WIFI_PASSWORD = "++++++++";
/*Configure the device certificate information*/
String ProductKey = "++++++";
String ClientId = "1234";/*The custom ID*/
String DeviceName = "++++++";
String DeviceSecret = "++++++";
/*Configure the domain name and port number*/
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;
/*Topics to be reported and subscribed to*/
const char * subTopic = "/sys/${ProductKey}/${DeviceName}/thing/service/property/set";
const char * subTopic1 = "/ota/device/upgrade/${ProductKey}/${DeviceName}";
const char * pubTopic1 = "/ota/device/inform/${ProductKey}/${DeviceName}";
const char * pubTopic = "/sys/${ProductKey}/${DeviceName}/thing/event/property/post";
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\r\n"
"MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\r\n" \
"A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\r\n" \
"b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\r\n" \
"MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\r\n" \
"YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\r\n" \
"aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\r\n" \
"jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\r\n" \
"xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\r\n" \
"1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\r\n" \
"snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\r\n" \
"U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\r\n" \
"9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\r\n" \
"BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\r\n" \
"AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\r\n" \
"yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\r\n" \
"38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\r\n" \
"AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\r\n" \
"DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\r\n" \
"HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\r\n" \
"-----END CERTIFICATE-----";
static HttpsOTAStatus_t otastatus;
DFRobot_Iot myIot;
WiFiClient espClient;
uint32_t valLast = 0;
uint8_t userKey = 38;
volatile int keyUpTime,keyDownTime,keyTime;
static uint8_t errnum;
bool interruptFlag = false;
DFRobot_LedDisplayModule LED(Wire, 0xE0);
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
PubSubClient client(espClient);
#define MODE_A 0
#define MODE_B 1
#define MODE_C 2
int mode;
int counterValue = 0;
void ISR_FALLING()
{
keyDownTime = millis ();
attachInterrupt(digitalPinToInterrupt(38),ISR_RISING,RISING);
}
void ISR_RISING()
{
keyUpTime = millis ();
keyTime = keyUpTime - keyDownTime;
if(keyTime>= 5000){
interruptFlag = true;
keyTime = 0;
}else{
keyDownTime = keyUpTime;
}
attachInterrupt(digitalPinToInterrupt(38),ISR_FALLING,FALLING);
}
void HttpEvent(HttpEvent_t *event)
{
switch(event->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("Http Event Error");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("Http Event On Connected");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("Http Event Header Sent");
break;
case HTTP_EVENT_ON_HEADER:
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
break;
case HTTP_EVENT_ON_DATA:
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("Http Event On Finish");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("Http Event Disconnected");
break;
}
}
void connectWiFi(){
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID,WIFI_PASSWORD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP Adderss: ");
Serial.println(WiFi.localIP());
}
void callback(char * topic, byte * payload, unsigned int len){
Serial.print("Recevice [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < len; i++){
Serial.print((char)payload[i]);
}
Serial.println();
StaticJsonDocument<300> jsonBuffer;
auto error = deserializeJson(jsonBuffer, (char *)payload);
if (error){
Serial.println("parseObject() failed:");
Serial.println(error.f_str());
}
if( strcmp(topic,subTopic1)==0){
String str = jsonBuffer["data"]["url"];
if(str.compareTo("null")!=0){
String version0 =jsonBuffer["data"]["version"] ;
String a = "\"";
String version = a+version0+a;
Serial.println(version);
Serial.println(str);
HttpsOTA.onHttpEvent(HttpEvent);
Serial.println("Starting OTA");
HttpsOTA.begin(const_cast<char *>(str.c_str()) , server_certificate);
Serial.println("Please Wait it takes some time ...");
while(1){
otastatus = HttpsOTA.status();
if(otastatus == HTTPS_OTA_SUCCESS) {
client.publish(pubTopic1,("{\"id\":"+ClientId+",\"params\":{\"version\":"+version+",\"module\":\"esp32\"}}").c_str());
Serial.printf("Firmware written successfully. Current version information: %s . To reboot device, call API ESP.restart() or PUSH restart button on device",version0);
Serial.println("Auto restart after 3 seconds");
for(uint8_t i=0;i<2;i++){
delay(1000);
Serial.print(".");
}
delay(1000);
Serial.println(".");
ESP.restart();
break;
} else if(otastatus == HTTPS_OTA_FAIL) {
Serial.println("Firmware Upgrade Fail");
break;
}
}
}
}
}
void ConnectAliyun(){
while (!client.connected()){
Serial.print("Attempting MQTT connection...");
/*A device connected to the cloud platform based on an automatically calculated username and password*/
if (client.connect(myIot._clientId, myIot._username, myIot._password)){
Serial.println("connected");
client.subscribe(subTopic);
client.subscribe(subTopic1);
} else{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup()
{
Serial.begin(115200);
while(!Serial);
while(IOExpension.begin()!=0){
delay(1000);
}
/*Wait for the chip to be initialized completely, and then exit*/
while(LED.begin8() != 0)
{
Serial.println("");
delay(1000);
}
LED.setDisplayArea8(2,3,4,5,6,7);
LED.print8("H","E","L","L","O","!");
delay(2000);
Serial.println("Please select count mode:");
Serial.println(" Mode A: one number at a time;");
Serial.println(" Mode B: multiple numbers at a time;");
Serial.println(" Mode C: multiple induction meter a number;");
Serial.println("Enter 'A' for mode A; Enter 'B' for mode B; Enter 'C' for mode C.");
while(1){
if (Serial.available()){
counterValue = 0;
int inputchar = Serial.read();
if (char(inputchar) == 'A'){
Serial.read();
Serial.println("The system will operate in A mode");
mode = MODE_A;
break;
} else if (char(inputchar) == 'B'){
bool flag = true;
Serial.read();
Serial.read();
Serial.println("The system will operate in B mode");
Serial.println("Please input the corresponding count value of an induction");
while (1){
uint8_t a=Serial.available();
if(a>0){
flag = true;
for(uint8_t i=0;i<a;i++){
int value = Serial.read();
if(value>=48 && value<=57){
counterValue = counterValue * 10;
counterValue = counterValue + value - '0';
}else if (char(value) == '\r'|| char(value) == '\n'|| char(value) == '\0'){
}else{
Serial.println("Invalid value, please reselect");
flag = false;
for(;i<a;i++){
Serial.read();
}
counterValue = 0;
break;
}
}
if(flag == false){
continue;
}else{
break;
}
}
}
Serial.println(counterValue);
Serial.println("Set up the success");
mode = MODE_B;
break;
} else if (char(inputchar) == 'C'){
bool flag = true;
Serial.read();
Serial.read();
Serial.println("The system will operate in C mode");
Serial.println("Please input the corresponding induction value for induction");
while (1){
uint8_t a=Serial.available();
if(a>0){
flag = true;
for(uint8_t i=0;i<a;i++){
int value = Serial.read();
if(value>=48 && value<=57){
counterValue = counterValue * 10;
counterValue = counterValue + value - '0';
}else if (char(value) == '\r'|| char(value) == '\n'|| char(value) == '\0'){
}else{
Serial.println("Invalid value, please reselect");
flag = false;
for(;i<a;i++){
Serial.read();
}
counterValue = 0;
break;
}
}
if(flag == false){
continue;
}
break;
}
}
Serial.println(counterValue);
Serial.println("Set up the success");
mode = MODE_C;
break;
}else{
Serial.println("Invalid working mode, please reselect");
}
}
}
IOExpension.setFilterTimeOfInput(/*counter= */SWITCH_COUNTER_8,/*filtertime =*/100000);
pinMode(38,INPUT);
attachInterrupt(digitalPinToInterrupt(38),ISR_FALLING,FALLING);
delay(1000);
#if defined(CONNECT_ALIYUN)
/* connect WIFI */
connectWiFi();
/*Initializes Alinyun's configuration to automatically calculate user name and password*/
myIot.init(ALIYUN,ALIYUN_SERVER,ProductKey,ClientId,DeviceName,DeviceSecret,PORT);
client.setServer(myIot._mqttServer,PORT);
/*Set the callback function that executes when a subscription is received*/
client.setCallback(callback);
/*Connect to the Aliyun*/
ConnectAliyun();
/*Report firmware version information*/
client.publish(pubTopic1,("{\"id\":"+ClientId+",\"params\":{\"version\":\"V1.0\",\"module\":\"esp32\"}}").c_str());
/*Report light brightness information*/
unsigned long initTime = millis();
double pubTime = initTime/1000/3600.0;
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"countValue\":0,\"StartingTimeLength\":"+pubTime+"},\"method\":\"thing.event.property.post\"}").c_str());
#endif
}
void loop()
{
#if defined(CONNECT_ALIYUN)
if(!client.connected()){
ConnectAliyun();
}
client.loop();
#endif
if(interruptFlag){
interruptFlag = false;
IOExpension.setCountnerValue(/*counter=*/SWITCH_COUNTER_8,/*value=*/0);
Serial.println("Manual reset!");
LED.setDisplayArea8(1,2,3,4,5,6,7,8);
LED.print8(0.0);
}
uint32_t val = IOExpension.readCountnerValueOfInput(/*counter=*/SWITCH_COUNTER_8);
if(val>99999999 ){
LED.setDisplayArea8(1,2,3,4,5,6,7,8);
uint32_t err = 88888888;
LED.print8(err);
Serial.println(val,HEX);
errnum++;
if(errnum>10){
IOExpension.setCountnerValue(/*counter=*/SWITCH_COUNTER_8,/*value=*/0);
Serial.println("Number of times out of range :10. The counter has automatically reset to zero!");
LED.setDisplayArea8(1,2,3,4,5,6,7,8);
LED.print8(0.0);
errnum = 0;
}
} else{
if(mode == MODE_A){
} else if(mode == MODE_B){
val = val * counterValue;
} else if(mode == MODE_C){
val = val / counterValue;
}
//Serial.println(val);
LED.setDisplayArea8(1,2,3,4,5,6,7,8);
LED.print8(val);
#if defined(CONNECT_ALIYUN)
if(valLast!=val){
unsigned long nowTime = millis();
double pubTime = nowTime/1000/3600.0;
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"countValue\":"+val+",\"StartingTimeLength\":"+pubTime+"},\"method\":\"thing.event.property.post\"}").c_str());
}
valLast=val;
#endif
}
delay(500);
}
1、填写代码中的设备证书
2、添加WiFi信息
3、编译运行
4、按照串口信息,配置工作模式
配置成功后成功运行,此时观察数码管计数,或者上到云端观察数据即可。