赞
踩
1. 第一步——ARDUINO引用软串口库
基本的只引用软串口
- #include <SoftwareSerial.h>
-
- SoftwareSerial mySerial(10, 11); // RX, TX 配置10、11为软串口
带有各种检测的
- #include <SoftwareSerial.h>
- // 软串口
- SoftwareSerial WIFISerial(6, 7); // RX, TX交叉接线
-
- #define OK "OK"
- #define SENDOK "SEND OK"
- #define WIFIPIN 4 //配网按键,按住2秒配网
- bool WIFIPINAvailable = true;// 配网按钮是否可用
- bool wifiLinked = false;// WIFI是否连接上AP
- bool serverLinked = false;// 服务器是否连接
- unsigned long lastTime;
2. 第二步——初始化
- void setup() {
- pinMode(WIFIPIN, INPUT);
-
- // 硬件串口 initialize serial for debugging
- Serial.begin(115200);
- while (!Serial) {}
- // 软串口 initialize serial for ESP module
- WIFISerial.begin(57600);
- // WIFISerial.println("AT+UART_DEF=57600,8,1,0,0");//解决乱码
- // delay(1000);
- while (!WIFISerial) {}
- WIFISerial.listen();// 开始监听
-
- Serial.println(F("---setup start---"));
-
- // 查询网络连接状态,等待wifi连网几秒
- bool _link = false;
- int _i = 0;
- bgnwifi:
- for (int i = 0; i < 3; i++) {
- // STATUS 2:获得 IP ,3:已连接,4:断开连接,5:未连接到 WiFi
- if (doCMD(F("AT+CIPSTATUS"), F("STATUS:2|STATUS:3"), 3000)) {
- _link = true;
- break;
- }
- delay(1000);
- }
- if (!_link && _i == 0) {
- doCMD(F("AT+RST"), F("ready"), 3000);// 重启wifi模块
- delay(4000);// 等待连接
- _i++;
- goto bgnwifi;
- }
- if (!_link) {
- smartConfig();// 启动一键配网
- }else {
- wifiLinked = true;
- }
-
- lastTime = millis();
- Serial.println(F("---setup end---"));
- }
3. 第三步——开始使用LOOP函数
-
- void loop() // run over and over
- {
- if (mySerial.available())
- Serial.write(mySerial.read());
- if (Serial.available())
- mySerial.write(Serial.read());
- }
-
- // 执行AT指令
- // cmd AT指令,返回值包含flag则true(2个以|分割),timeout超时时间ms(200的整数倍)
- bool doCMD(String cmd, String flag, long timeout) {
- String str = "";
- WIFISerial.println(cmd); //发送AT指令
- delay(300);
- flag.toLowerCase();// 小写
- // 限期时间
- long deadline = millis() + timeout;
- while (millis() < deadline)
- {
- str = "";
- while (WIFISerial.available()) {
- str += (char)WIFISerial.read();
- delay(2);
- }
- if (str != "") {
- Serial.println(str);// 打印输出
- str.toLowerCase();// 小写
- // 判断 flag 是否需要切割,以 | 切割,逻辑或关系
- String flag1 = "", flag2 = "";
- int commaPosition = flag.indexOf('|');
- if (commaPosition > -1)
- {
- flag1 = flag.substring(0, commaPosition);
- flag2 = flag.substring(commaPosition + 1, flag.length());
- }
- if (flag1 != "" && flag2 != "") {
- if (str.indexOf(flag1) > -1 || str.indexOf(flag2) > -1 ) {
- return true;
- }
- }
- if (str.indexOf(flag) > -1) {
- return true;
- }
- }
- delay(100);
- }
- return false;
- }
-
- // 一键配网 smartconfig
- void smartConfig() {
- // 启动smartconfig之前,先停止一下,以避免上次未复位
- doCMD(F("AT+CWSTOPSMART"), OK, 3000);
- // SmartConfig 仅支持在 ESP8266 单 station 模式下调用
- if (!doCMD(F("AT+CWMODE_DEF=1"), OK, 3000)) {}
- // 上电自动连接AP
- if (!doCMD(F("AT+CWAUTOCONN=1"), OK, 3000)) {}
- // 启动smartconfig,支持ESP-Touch和Airkiss智能配网
- // 在 SmartConfig 过程中请勿执行其他指令
- Serial.println(F("~~ Start SmartConfig ~~"));
- bool res = doCMD(F("AT+CWSTARTSMART=3"), F("WIFI GOT IP"), 60000);// 60秒超时
- if (res) {
- wifiLinked = true;
- Serial.println(F("SmartConfig OK"));
- } else {
- wifiLinked = false;
- Serial.println(F("SmartConfig Fail"));
- }
- doCMD(F("AT+CWSTOPSMART"), OK, 3000);// 无论配网是否成功,都释放快连所占的内存
- }
-
- // 连接TCP服务器
- bool connectTcp() {
- bool linkOk = true;
- //连接服务器
- String s(F("AT+CIPSTART=\"TCP\",\"tcp.x.com\",9960"));// 字符串存入FLASH
- if (!doCMD(s, F("OK|CONNECTED"), 3000)) {
- linkOk = false;
- }
- if (linkOk) {
- // 登录,也是心跳包,1分钟内必须上报一次,如有其他定时上报,则可不使用本心跳包
- s = F("{\"method\": \"update\",\"gatewayNo\": \"01\",\"userkey\": \"123\"}&^!");// 字符串存入FLASH
- doCMD("AT+CIPSEND=" + String(s.length()), ">", 3000);
- if (!doCMD(s, SENDOK, 3000)) {
- linkOk = false;
- }
- }
- if (!linkOk) {
- Serial.println(F("!!SERVER NOT CONNECTED!!"));
- } else {
- }
- serverLinked = linkOk;
- return linkOk;
- }
执行的业务逻辑是:每50秒为一个循环,在每个循环的第5秒上报传感器的温度和湿度值给云端。当用户按下wifi配网按钮时,wifi模组进入一键配网流程重新设置wifi的ssid和密码信息。
set up 函数参考上面的,这里直接给出loop函数
- void loop() {
- String info = "";
-
- // 定时上报给服务器 - TCP长连接
- if (millis() - lastTime == 5000) {
- // 判断wifi是否连接上
- if (!wifiLinked) {
- Serial.println(F("!!WIFI NOT CONNECTED!!"));
- } else {
- //连接TCP服务器
- if (!serverLinked) {
- connectTcp();//连接TCP服务器
- } else {
- // 上报传感器值 - 定时上报,可代替心跳包(1分钟内1次)
- String temp = String(random(10, 40));// 模拟温度
- String humi = String(random(40, 90));// 模拟湿度
- if (true) {
- String s1(F("{\"method\": \"upload\",\"data\":[{\"Name\":\"temp\",\"Value\":\""));// 字符串存入FLASH
- String s2(F("\"},{\"Name\":\"humi\",\"Value\":\""));// 字符串存入FLASH
- String s3(F("\"}]}&^!"));// 字符串存入FLASH
- info = s1 + temp + s2 + humi + s3;
- Serial.println(info);
- doCMD("AT+CIPSEND=" + String(info.length()), ">", 3000);
- if (!doCMD(info, SENDOK, 3000)) {
- serverLinked = false;
- } else {
- }
- }
- }
- }
- }
- // 恢复计时,云端限制提交频率不能低于20秒
- if (millis() - lastTime >= 50000) {
- lastTime = millis();
- }
-
- // 读取WIFI配网按钮是否接通
- boolean val = digitalRead(WIFIPIN);
- if (val && WIFIPINAvailable) {
- WIFIPINAvailable = false;
- Serial.println(F("WIFIPIN pressed"));
- smartConfig();// 启动一键配网
- WIFIPINAvailable = true;
- }
-
- // PC串口转发给wifi软串口
- while (Serial.available()) {
- WIFISerial.write(Serial.read());
- }
- // wifi软串口发送过来的信息
- String str = "";
- while (WIFISerial.available()) {
- str = str + (char)WIFISerial.read();
- }
- if (str != "") {
- Serial.println(str);
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。