本文最后更新于:June 30, 2023 pm
本文作者:[wangwenhai] # 概要:本文主要展示一段之前实现的Arduino命令行模拟代码,包含了WIFI操作,MQTT,DHT11温湿度读取等等常见操作.
1.概述
我们在用串口操作Arduino的时候,会有一些输出提示,一般我们做一个封装,比如命令行输出一些提示信息给用户去查看,操作比较友好,于是我自己写了个非常简单的模拟固件,同时还有通过串口配置WIFI的一些操作.
2.代码展示
代码如下所示:
#include <ESP_EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Ethernet.h>
#include <ACROBOTIC_SSD1306.h>
#include <Arduino_JSON.h>
#include "DHTesp.h"
///
#define RED_LED_GPIO 12
#define GREEN_LED_GPIO 13
#define BLUE_LED_GPIO 15
#define DHT11_GPIO 5
#define BUZZER_GPIO 14
#define MQTT_MAX_TRANSFER_SIZE
const char* clientId = "85C05BE9296E49EBAACA1A4BF77AD0E2";
/*
联网不一定连MQTT服务器
不联网一定不连MQTT服务器
*/
DHTesp dht;
boolean isConnectToWifi ;
boolean isConnectToMqtt ;
typedef struct SysConfig
{
char ssid[32];
char password[32];
char mqttServer[64] = "192.168.1.100";
char mqttClientId[64] = "testEsp";
char mqttUsername[64] = "system";
char mqttPassword[64] = "password";
int mqttPort = 1883;
};
SysConfig sysConfig;
/**
连接Mqtt用的
*/
WiFiClient espClient;
PubSubClient mqttClient("192.168.1.100", 1883, espClient);
//PubSubClient mqttClient(espClient);
/**
OLED 显示屏
*/
void display(int line, int x, boolean isClear, char content[]) {
if (isClear) {
oled.clearDisplay();
oled.setTextXY(0, 0);
oled.putString(content);
} else {
oled.setTextXY(0, 0);
oled.putString(content);
}
}
/**
加载配置
*/
void loadSysConfig() {
EEPROM.begin(sizeof(SysConfig));
EEPROM.get(0, sysConfig);
Serial.println("--------Load wifi SysConfig from EPROM--------");
Serial.print("|SSID: ");
Serial.print(sysConfig.ssid);
Serial.print("\t Password: ");
Serial.println(sysConfig.password);
Serial.println("----------------------------------------------");
}
/**
写入配置到EPROM
*/
void writeSysConfig() {
EEPROM.begin(sizeof(SysConfig));
EEPROM.put(0, sysConfig);
EEPROM.commitReset();
}
/**
打印banner
*/
void welcome() {
Serial.println("");
Serial.println("**********************************************");
Serial.println("* Welcome use NodeMcu Cli Mode V0.0.1 *");
Serial.println("* Send 'help' for more information *");
Serial.println("**********************************************");
}
/**
Help
*/
void showHelp() {
Serial.println("");
Serial.println("**********************************************");
Serial.println("|SysConfig Wlan: wlanset -s {SSID} -p {Password}|");
Serial.println("|Print Wlan Info:wlan |");
Serial.println("|Test Buzzer {n} times: beep {n} |");
Serial.println("|Print tempature:temp |");
Serial.println("|Print tempature:hum |");
Serial.println("**********************************************");
}
void echoTemp() {
Serial.println("*------------------------------------------*");
Serial.print("| Current tempature is: ");
Serial.print(35); Serial.println("|");
Serial.println("*------------------------------------------*");
}
void echoHumidity() {
Serial.println("*------------------------------------------*");
Serial.print("| Current humidity: |");
Serial.print(35); Serial.println("|");
Serial.println("*------------------------------------------*");
}
void echoWlan() {
if (WiFi.status() == WL_CONNECTED) {
Serial.println("*------------------------------------------*");
Serial.print("|state:");
Serial.print("ON\t");
Serial.print(" \tIP:");
Serial.println(WiFi.localIP());
Serial.println("*------------------------------------------*");
} else {
Serial.println("|Network has disconnected.");
}
}
/**
配置网络
*/
void setupWifi() {
Serial.println("-----------------SetUp wifi-------------------");
Serial.println("|Try connect to network.");
Serial.print("|");
WiFi.begin(sysConfig.ssid, sysConfig.password);
for (int i = 0 ; i < 10; i++) {
Serial.print("=>");
delay(1000);
if (WiFi.status() == WL_CONNECTED) {
WiFi.hostname("ESP8266_NODE_1");
Serial.println("\n|Success connect to network.");
isConnectToWifi = true;
writeSysConfig();
break;
}
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\n|Connect to network failure.Please try again!");
}
}
/**
初始化MQTT
*/
void initMqtt() {
Serial.println("-----------------SetUp mqtt-------------------");
mqttClient.setCallback([](char* topic, byte * payload, unsigned int length)-> void{
String msg ;
for (int i = 0 ; i < length; i++) {
msg += (char )payload[i];
}
JSONVar dataJson = JSON.parse(msg);
if (JSON.typeof(dataJson) == "undefined") {
Serial.println("Parsing input failed!");
return;
} else{
Serial.println(dataJson);
}
});
for (int i = 0 ; i < 10; i++) {
mqttClient.connect("NodeMcu10010");
// mqttClient.connect(sysConfig.mqttClientId, sysConfig.mqttUsername, sysConfig.mqttPassword);
Serial.print("=>");
delay(1000);
if (mqttClient.connected()) {
//连接成功
//mqttClient.subscribe(String(String("/device/OUT/") + sysConfig.mqttClientId).c_str(), 2);
mqttClient.subscribe(String("mqttTestNodeMcu").c_str(),2);
isConnectToMqtt = true;
Serial.println("\n|Connect to mqtt success!");
break;
}
}
if (!mqttClient.connected() ) {
isConnectToMqtt = false;
Serial.println("\n|Connect to mqtt failure.Please try again!");
}
}
/**
Mqtt配置:
准备使用clientId作为Topic
mqttset|username|password|clientId
*/
void setupMqtt(String cmd) {
Serial.println("|Start setup mqtt");
}
/**
配置WIFI
*/
void setWlan( String cmd) {
// wlanset|206-public|665544332211
Serial.println("|Start SysConfig wifi");
String ssid = cmd.substring(cmd.indexOf("|") + 1, cmd.lastIndexOf("|"));
String password = cmd.substring( cmd.lastIndexOf("|") + 1, cmd.length());
ssid.trim();
password.trim();
if (ssid.length() > 0 && password.length() > 0 ) {
Serial.print("|Wifi SSID:"); Serial.println(ssid);
Serial.print("|Password:"); Serial.println(password);
SysConfig &tempCfg = sysConfig;
strcpy(tempCfg.ssid, ssid.c_str());
strcpy(tempCfg.password, password.c_str());
setupWifi();
} else {
Serial.println("SSID and password must not null,command is : wlanset|ssid|password!");
}
}
/**
初始化GPIO
*/
void initialGpio() {
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(15, OUTPUT);
pinMode(3, OUTPUT);
pinMode(14, OUTPUT);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
digitalWrite(15, LOW);
Wire.begin();
oled.init();
dht.setup(DHT11_GPIO, DHTesp::DHT11);
}
/**
指示灯:三色RGB指示灯,可以组合出6种颜色;
r g b 含义
0 000 断电
1 001 联网
2 010 联网但是MQTT没有连上
3 011 联网+MQTT连上
4 100 断网
5 101 待定
6 111 待定
*/
void blinkRGB(int pin) {
digitalWrite(pin, LOW);
delay(1000);
digitalWrite(pin, HIGH);
delay(1000);
}
/**
蜂鸣器 嘀嘀嘀
beep|n
*/
void buzzerBeep(int times) {
Serial.print("|Beep: ");
Serial.println(times);
for (int i = 0; i < times; i++) {
tone(BUZZER_GPIO, 1500); // Send 1MHz sound signal...
delay(1000); // ...for 1 sec
noTone(BUZZER_GPIO); // Stop sound...
delay(1000); // ...for 1sec
}
}
/**
初始化
*/
void setup() {
buzzerBeep(1);
delay(1000);
initialGpio();
display(0, 0, true, "Hello world!NodeMcu!");
delay(1000);
Serial.begin(115200);
delay(1000);
welcome();
delay(1000);
loadSysConfig();
delay(1000);
setupWifi();
delay(1000);
initMqtt();
}
/*
* 读取DHT11
*/
JSONVar getDHT11Data() {
JSONVar data;
delay(dht.getMinimumSamplingPeriod());
//湿度
float h = dht.getHumidity();
//摄氏度
float c = dht.getTemperature();
//华氏度
float f = dht.toFahrenheit(c);
//热指数
float cc = dht.computeHeatIndex(c, h, true);
float ff = dht.computeHeatIndex(f, h, true);
data["h"] = h;
data["c"] = c;
data["f"] = f;
data["cc"] = cc;
data["ff"] = ff;
return data;
}
JSONVar jsonDataPackage(JSONVar j2strData)
{
JSONVar jsonData;
jsonData["clientId"] = clientId;
jsonData["value"] = JSON.stringify(j2strData);
return jsonData;
}
//
int count = 0;
int flag=0;
String publishData = "";
void loop() {
count += 1;
if (isConnectToMqtt) {
mqttClient.loop();
if (count >= 100000) {
publishData = JSON.stringify(jsonDataPackage(getDHT11Data()));
// flag=mqttClient.publish("/device/IN/NodeMcuTest",publishData.c_str(),strlen(publishData.c_str()));
mqttClient.beginPublish("/device/IN/NodeMcuTest",strlen(publishData.c_str()),false);
mqttClient.print(publishData.c_str());
mqttClient.endPublish();
Serial.println(publishData+flag);
count = 0;
}
}
String cmd = "";
if (Serial.available() > 0) {
cmd = Serial.readStringUntil('\n');
delay(100);
}
if (cmd.length() > 0) {
if (cmd.equals(String("help"))) {
showHelp();
}
if (cmd.equals(String("wlaninfo"))) {
echoWlan();
}
if (cmd.equals(String("temp"))) {
echoTemp();
}
if (cmd.equals(String("hum"))) {
echoHumidity();
}
/**
led 闪烁
*/
if (cmd.equals(String("red"))) {
blinkRGB(12);
}
if (cmd.equals(String("green"))) {
blinkRGB(13);
}
if (cmd.equals(String("blue"))) {
blinkRGB(15);
}
if (cmd.startsWith(String("wlanset|"))) {
setWlan(cmd);
}
if (cmd.startsWith(String("mqttset|"))) {
setWlan(cmd);
}
if (cmd.startsWith(String("beep|"))) {
int times = cmd.substring( cmd.lastIndexOf("|") + 1, cmd.length()).toInt();
buzzerBeep(times);
}
}
// wlanset|206-public|665544332211
if ( isConnectToWifi) {
// blue
digitalWrite(12, LOW);
digitalWrite(13, LOW);
digitalWrite(15, HIGH);
//if connect to mqtt
if (isConnectToWifi && isConnectToMqtt) {
//Green
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
digitalWrite(15, LOW);
}
} else {
//Red
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
digitalWrite(15, LOW);
}
}
上述代码,注释加的比较完善,比较容易看懂,就不详细解释了,有个细节在这里提一下就行,位置在通过串口配置网络处:
/**
配置网络
*/
void setupWifi() {
Serial.println("-----------------SetUp wifi-------------------");
Serial.println("|Try connect to network.");
Serial.print("|");
WiFi.begin(sysConfig.ssid, sysConfig.password);
for (int i = 0 ; i < 10; i++) {
Serial.print("=>");
/**
*
*此处的delay1000很重要,为了防止抖动引起的误差.
**/
delay(1000);
if (WiFi.status() == WL_CONNECTED) {
WiFi.hostname("ESP8266_NODE_1");
Serial.println("\n|Success connect to network.");
isConnectToWifi = true;
writeSysConfig();
break;
}
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\n|Connect to network failure.Please try again!");
}
}
单独把 delay(1000);这行拿出来说,因为通过实际操作发现,串口数据抖动还是比较大,建议做延迟防抖.
3.总结
本文展示了一段简单的Arduino代码Demo.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!