关于ESP8266-NodeMCU和onenet通信传输学习总结(三)

关于ESP8266-NodeMCU和onenet通信传输学习总结(三)

2023年7月13日发(作者:)

关于ESP8266-NodeMCU和onenet通信传输学习总结(三)关于ESP8266-NodeMCU和onenet通信传输学习总结(三)⼀、前篇概述 很久没更新了,原因在于物流快递太慢和重温Android开发知识去了,想着脱离onenet平台 写⾃⼰的app使⽤,这⾥要先感谢下各位⼤佬的开发经验和教学分享。前⾯两节,我⽤esp8266nodemcu实现了onenet平台的连接和数据点上传下发指令,然后还接⼊了byj-48电机的操作,实现了⼀些基础通信控制。整体构建: 时隔多⽇,到今天终于实现了Android app的开发使⽤和天猫精灵的语⾳接⼊控制,其中有很多槽点和想法,⽂末再提,下⾯开始正⽂:⼆、基于之前的设计开发Android appapp我采⽤android studio 进⾏开发,这⾥要感谢⼀下b站博主阿正的教学分享!这⾥⽤多线程分别处理界⾯显⽰和数据处理,⼤致过程如下:Android数据处理:1、xml布局⽂件 显⽰效果:2、 3、ckage ;import ssLint;import r;import e;import patActivity;import ;import ;import ;import ;import iew;import ew;import ;import eliveryToken;import llback;import ient;import nnectOptions;import ception;import ssage;import Persistence;import ray;import ject;import ors;import ledExecutorService;import it;public class MainActivity extends AppCompatActivity { protected String host = "tcp://183.230.40.39:6002"; protected String userName = "396066"; protected String passWord = "tx6WM==zmW21Z2pt4susBRlHMuY="; protected String mqtt_id = "671460025"; // protected String mqtt_sub_topic = "getMessage"; // protected String mqtt_pub_topic = "sendMessage"; // protected int led_flag =1; protected int door_flag =1; protected ScheduledExecutorService scheduler; protected ScheduledExecutorService scheduler; private ImageView light_control; private ImageView door_control; private ImageView air_control; private ImageView curtain_control; private ImageView tv_control; private ImageView water_control; private TextView text_temperature; private TextView text_light; private TextView text_door_lock; protected MqttClient client; protected MqttConnectOptions options; protected Handler handler; @SuppressLint("HandlerLeak") @Override protected void onCreate(Bundle savedInstanceState) { te(savedInstanceState); setContentView(ty_main); curtain_control =findViewById(n_control); curtain_lickListener(new kListener() { @Override public void onClick(View v) { if(door_flag == 0) { publishmessageplus(mqtt_pub_topic,"{"doorLock":"open","led":""}"); xt(,"开门" ,_SHORT).show(); door_flag =1; }else{ publishmessageplus(mqtt_pub_topic,"{"doorLock":"close","led":""}"); xt(,"关门" ,_SHORT).show(); door_flag =0; } } }); light_control=findViewById(_control); light_lickListener(new kListener() { @Override public void onClick(View v) { if(led_flag == 0) { publishmessageplus(mqtt_pub_topic,"{"led":"open","doorLock":""}"); xt(,"开灯" ,_SHORT).show(); led_flag =1; }else{ publishmessageplus(mqtt_pub_topic,"{"led":"close","doorLock":""}"); xt(,"关灯" ,_SHORT).show(); led_flag =0; } } }); //

两个控件联动

按钮单机

更改 textview

的内容 text_temperature =findViewById(_temperture); text_door_lock=findViewById(_doorLock); text_light=findViewById(_bright);//**********************************************************// Mqtt_init(); startReconnect(); handler = new Handler() { @SuppressLint("SetTextI18n") public void handleMessage(Message msg) { Message(msg); switch (){ switch (){ case 1: //开机校验更新回传 break; case 2: //

反馈回传 break; case 3: //MQTT

主页消息处理

收到消息回传 UTF8Buffer msg=new UTF8Buffer(ng()); //处理message

传过来的 obj字段(⾥⾯包了数据)/* String T_val = ng().substring(ng().indexOf("temperature":")+13,ng().indexOf("}")); String text_val = T_val+"℃"; //在主进程 handler

⾥⾯更新UI

既保证了稳定性

⼜不影响⽹络传输 text_t(text_val); //xt(,T_val ,_SHORT).show();*/ try{ Log.v("1",ng()); JSONObject jsonObject=new JSONObject(ng()); GetMessage getMessage=new GetMessage(); perture(ing("temperature")); ht(ing("bright")); r_lock(ing("doorLock")); Log.v("3",r_lock()); if(perture()!=null){ String text_val = perture()+"℃"; text_t(text_val); } if(r_lock()!=null){ String text_val = r_lock(); text_door_t(text_val); } if(ht()!=null){ String text_val = ht(); text_t(text_val); } perture(null); ht(null); r_lock(null); }catch (Exception e){tackTrace();} break; case 30: //连接失败 xt(,"连接失败" ,_SHORT).show(); break; case 31: //连接成功 xt(,"连接成功" ,_SHORT).show(); try { ibe(mqtt_sub_topic,1); } catch (MqttException e) { tackTrace(); } break; default: break; } } }; } private void parseEasyJson(String json){ try{ JSONArray jsonArray = new JSONArray(json); for(int i = 0;i < ();i++){ JSONObject jsonObject = (JSONObject) (i); GetMessage getMessage=new GetMessage(); perture(ing("temperature")); ht(ing("bright")); r_lock(ing("doorLock")); r_lock(ing("doorLock")); } }catch (Exception e){tackTrace();} } protected void Mqtt_init() { try { //host为主机名,test为clientid即连接MQTT的客户端ID,⼀般以客户端唯⼀标识符表⽰,MemoryPersistence设置clientid的保存形式,默认为以内存保存 client = new MqttClient(host, mqtt_id, new MemoryPersistence()); //MQTT的连接设置 options = new MqttConnectOptions(); //设置是否清空session,这⾥如果设置为false表⽰服务器会保留客户端的连接记录,这⾥设置为true表⽰每次连接到服务器都以新的⾝份连接 anSession(false); //设置连接的⽤户名 rName(userName); //设置连接的密码 sword(Array()); //

设置超时时间

单位为秒 nectionTimeout(10); //

设置会话⼼跳时间

单位为秒

服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个⽅法并没有重连的机制 pAliveInterval(20); //设置回调 lback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { //连接丢失后,⼀般在这⾥⾯进⾏重连 n("connectionLost----------"); startReconnect(); } @Override public void deliveryComplete(IMqttDeliveryToken token) { //publish后会执⾏到这⾥ n("deliveryComplete---------" + lete()); } @Override public void messageArrived(String topicName, MqttMessage message) throws Exception { //subscribe后得到的消息会执⾏到这⾥⾯ n("messageArrived----------"); Message msg = new Message(); //封装message包 = 3; //收到消息标志位 =ng(); //发送messge到handler ssage(msg); // hander

回传 } }); } catch (Exception e) { tackTrace(); } } protected void Mqtt_connect() { new Thread(new Runnable() { @Override public void run() { try { if(!(ected()) ) //如果还未连接 { t(options); Message msg = new Message(); Message msg = new Message(); = 31; //

没有⽤到obj字段 ssage(msg); } } catch (Exception e) { tackTrace(); Message msg = new Message(); = 30; //

没有⽤到obj字段 ssage(msg); } } }).start(); } protected void startReconnect() { scheduler = gleThreadScheduledExecutor(); leAtFixedRate(new Runnable() { @Override public void run() { if (!ected()) { Mqtt_connect(); } } }, 0 * 1000, 10 * 1000, ECONDS); } protected void publishmessageplus(String topic,String message2) { if (client == null || !ected()) { return; } MqttMessage message = new MqttMessage(); load(es()); try { h(topic,message); } catch (MqttException e) { tackTrace(); } }}三、esp8266客户端这⾥由于准备不⽤onenet的功能了,因此只是把他当成⼀个服务器中转使⽤,代码建⽴在前两篇成果之上。#define BLINKER_WIFI#define BLINKER_ALIGENIE_OUTLET#define BLINKER_PRINT Serial#include #include #include #include "AccelStepper.h"#include #define PRODUCT_ID "396066" //产品名#define API_KEY "tx6WM==zmW21Z2pt4susBRlHMuY="//产品密钥#define DEVICE_ID "666259032"//设备名#define TOPIC "sendMessage"//订阅主题char auth[] = "0c39eb647f6d";char ssid[] = "CMCC-Q4QF";char pswd[] = "jcv53rvq";WiFiClient wifiClient;Ticker ticker;Ticker ticker2;int count = 0; //ticker1控制 数据上传下发的间隔时间(s)int count2 = 0; //ticker2控制 电机转动的时间(s)int count2 = 0; //ticker2控制 电机转动的时间(s)AccelStepper stepper1(4, D0, D2, D1, D3);//电机引脚String door = "close"; //默认检测门关闭PubSubClient mqttClient(wifiClient);const char* mqttServer = "183.230.40.39";//onenet地址const uint16_t mqttPort = 6002;//mqtt接⼝端⼝String doorLock = "close"; //默认门锁指令关闭char msgJson[75];//存json下发信息数据char msg_buf[200];//存json上传数据及标识位// 新建组件对象BlinkerButton Button1("btn-door");bool oState = false;void aligeniePowerState(const String & state){ BLINKER_LOG("need set power state: ", state); if (state == BLINKER_CMD_ON) { digitalWrite(LED_BUILTIN, LOW); tate("on"); (); oState = true; } else if (state == BLINKER_CMD_OFF) { digitalWrite(LED_BUILTIN, HIGH); tate("off"); (); oState = false; }}void aligenieQuery(int32_t queryCode){ BLINKER_LOG("AliGenie Query codes: ", queryCode); switch (queryCode) { case BLINKER_CMD_QUERY_ALL_NUMBER : BLINKER_LOG("AliGenie Query All"); tate(oState ? "on" : "off"); (); break; case BLINKER_CMD_QUERY_POWERSTATE_NUMBER : BLINKER_LOG("AliGenie Query Power State"); tate(oState ? "on" : "off"); (); break; default : tate(oState ? "on" : "off"); (); break; }}// 按下按键即会执⾏该函数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);}void setup() { // 初始化串⼝ (9600); Speed(500); // 设置电机最⼤速度为500 ed(0); // 初始化电机速度为300#if defined(BLINKER_PRINT) BLINKER_(BLINKER_PRINT);#endif pinMode(A0, INPUT); pinMode(D6, INPUT); pinMode(D8, INPUT); // 初始化有LED的IO pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); (WIFI_STA); ver(mqttServer, mqttPort); // 设置MQTT订阅回调函数 lback(receiveCallback); connectMQTTServer(); (1, addCount); // 初始化blinker (auth, ssid, pswd); Data(dataRead); (button1_callback); PowerState(aligeniePowerState); Query(aligenieQuery);}void loop() { (); if (ted()) { // 如果开发板成功连接服务器 // 每隔2秒钟发布⼀次信息 // 保持⼼跳 若电机正在运转,暂时不发信息(由于mcu没有多线程,不能同时运转电机和上传下发数据) if (count >= 2) { if (count2 == 0) { pubMsgAndroid(); //pubMQTTmsg(); (); count = 0; } } } else { // 如果开发板未能成功连接服务器 connectMQTTServer(); // 则尝试连接服务器 } //电机控制 if (doorLock == "close" && door == "open") { ed(-500); (1, controlDoor); n("door closed"); door = "close"; } else if (doorLock == "open" && door == "close") { ed(500); { ed(500); (1, controlDoor); door = "open"; n("door opened"); } ed();}//ticker2控制 电机运转时间void controlDoor() { count2++; ("ticker调⽤"); if (count2 >= 6) { ed(0); count2 = 0; (); // 使⽤detach来停⽌ticker对象定时调⽤函数 ("()"); }}//连接mqtt服务器void connectMQTTServer() { String clientId = DEVICE_ID; String productId = PRODUCT_ID; String apiKey = API_KEY; // 连接MQTT服务器 if (t(clientId.c_str(), productId.c_str(), apiKey.c_str())) { n("MQTT Server Connected."); n("Server Address: "); n(mqttServer); n("ClientId:"); n(clientId); subscribeTopic(); // 订阅指定主题 } else { ("MQTT Server Connect Failed. Client State:"); n(()); delay(3000); }}// 订阅指定主题void subscribeTopic() { // 这么做是为确保不同设备使⽤同⼀个MQTT服务器测试消息订阅时,所订阅的主题名称不同 String topicString = TOPIC; char subTopic[() + 1]; strcpy(subTopic, topicString.c_str()); // 通过串⼝监视器输出是否成功订阅主题以及订阅的主题名称 if (ibe(subTopic)) { n("Subscrib Topic:"); n(subTopic); } else { (""); }}//获取下发指令topic 指定主题 payload 下发信息,以字节存储 length 下发信息长度void receiveCallback(char* topic, byte* payload, unsigned int length) { ("Message Received ["); (topic); ("] "); String receivePassage; for (int i = 0; i < length; i++) { ((char)payload[i]); receivePassage += (char)payload[i]; } n("----" + receivePassage + "----"); n("----" + receivePassage + "----"); ("Message Length(Bytes) "); n(length); /// StaticJsonDocument<96> doc; deserializeJson(doc, receivePassage); const char* doorLock = doc["doorLock"]; // "close" const char* led = doc["led"]; // "close" receivePassage = ""; if (doc["doorLock"].as() == "open") { doorLock = "open"; } else if (doc["doorLock"].as() == "close") { doorLock = "close"; n("door closed"); } if (doc["led"].as() == "open") { digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。 n("LED ON"); } else if (doc["led"].as() == "close") { digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。 n("LED OFF"); } /* const char* json = (char *)payload; DynamicJsonDocument doc(64); deserializeJson(doc, json); const char* led = doc["led"]; // 灯控 const char* door = doc["door"]; // 门控 /// if(doc["door"].as()=="open") { doorLock='1'; n("door open"); } else if(doc["door"].as()=="close") { doorLock='2'; n("door off"); } if(doc["led"].as()=="open") { digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。 n("LED ON"); } else if(doc["led"].as()=="close") { digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。 n("LED OFF"); }*/ /* //onenet测试下发数据 if ((char)payload[0] == 'L') { // 如果收到的信息以“1”为开始 if((char)payload[1] == '0') { digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。 n("LED ON"); n("LED ON"); } else if((char)payload[1] == '1') { digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。 n("LED OFF"); } }else if((char)payload[0] == 'D') { // 如果收到的信息以“1”为开始 if((char)payload[1] == '1') doorLock="open"; else if((char)payload[1] == '2') doorLock="close"; } // */}/* void doorControl(char doorLock) { //开门 if(doorLock=='1') { digitalWrite(D5, HIGH); } //关门 else if(doorLock=='2') { digitalWrite(D5, LOW); } doorLock='0'; }*///对指定主题上传信息void pubMsgAndroid() { String topicString = "getMessage"; char publishTopic[() + 1]; strcpy(publishTopic, topicString.c_str()); //json数据转换为数组 DynamicJsonDocument doc(64); doc["temperature"] = analogRead(A0); doc["doorLock"] = digitalRead(D8); doc["bright"] = digitalRead(D5); serializeJson(doc, Serial); String jsonCode; serializeJson(doc, jsonCode); ("json Code: "); n(jsonCode); String messageString = jsonCode; char publishMsg[() + 1]; strcpy(publishMsg, messageString.c_str()); int json_len = strlen(publishMsg); h(publishTopic, publishMsg, json_len);}/*void pubMQTTmsg(){ //onenet数据点上传系统主题 String topicString = "$dp"; char publishTopic[() + 1]; strcpy(publishTopic, topicString.c_str()); //json数据转换为数组 DynamicJsonDocument doc(64); DynamicJsonDocument doc(64); bool pinState = !digitalRead(BUILTIN_LED); bool doorState = !digitalRead(D6); doc["led"] = pinState; doc["door"] = doorState; serializeJson(doc, Serial); // 建⽴发布信息。温度 String jsonCode; serializeJson(doc, jsonCode); ("json Code: ");n(jsonCode); String messageString = jsonCode; char publishMsg[() + 1]; strcpy(publishMsg, messageString.c_str()); int json_len=strlen(publishMsg); memset(msg_buf,0,200); msg_buf[0]=char(0x03); msg_buf[1]=char(json_len>>8); msg_buf[2]=char(json_len &0xff); memcpy(msg_buf+3,publishMsg,json_len); // 实现ESP8266向主题发布信息 if(h(publishTopic, (uint8_t*)msg_buf,3+json_len)){ n("Publish Topic:");n(publishTopic); String msg_bufTotal; for(int i=0;i

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689215869a222255.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信