ESP8266端和APP端均提供源码,包含在文章各部分结尾。
app端(可远程显示温湿度、控制继电器开关)
ESP8266端:(IO0口控制继电器,IO2口读取温湿度传感器数值)
一、需要的材料(网上都能买到)
二、OneNet平台相关操作
三、MQTT简述
MQTT是基于发布/订阅范式的消息协议。你发布了一个Topic,只要别人订阅了这个Topic,那么他就能收到信息。同样你要收到别人发布的消息,首先你要订阅别人。(就好比抖音你关注了某个人,当这个人发布视频的时候,系统就会通知你)。假如说好几个人都订阅了一个Topic,那么这几个人都将收到信息。
四、安装开发环境
在安装开发环境之前,要确保你已经安装了JDK
五、创建项目
PROTOCOL_NAMEv311
。/***********************************************************************************************************************/
#define CFG_HOLDER 0x00FF55A4 /* Change this value to load default configurations */
/*DEFAULT CONFIGURATIONS*/
#define MQTT_HOST "192.168.1.100" // the IP address or domain name of your MQTT server or MQTT broker ,such as "mqtt.yourdomain.com"
#define MQTT_PORT 1883 // the listening port of your MQTT server or MQTT broker
#define MQTT_CLIENT_ID "Device_ID" // the ID of yourself, any string is OK,client would use this ID register itself to MQTT server
#define MQTT_USER "Device_Name" // your MQTT login name, if MQTT server allow anonymous login,any string is OK, otherwise, please input valid login name which you had registered
#define MQTT_PASS "Device_Passwd" // you MQTT login password, same as above
#define STA_SSID "AP_SSID" // your AP/router SSID to config your device networking
#define STA_PASS "AP_Passwd" // your AP/router password
SPI_SIZE_MAP?=0
改为SPI_SIZE_MAP?=1,但是mqtt的这个项目要是2MB以上,Esp8266-01s只有1MB所以只能改为2.
(如果是32Mbit的Flash改为SPI_SIZE_MAP?=4`).void mqttConnectedCb(uint32_t *args)
{
MQTT_Client* client = (MQTT_Client*)args;
INFO("MQTT: Connected\r\n");
MQTT_Subscribe(client, "/mqtt/topic/0", 0);
/* MQTT_Subscribe(client, "/mqtt/topic/1", 1);
MQTT_Subscribe(client, "/mqtt/topic/2", 2);
MQTT_Publish(client, "/mqtt/topic/0", "hello0", 6, 0, 0);
MQTT_Publish(client, "/mqtt/topic/1", "hello1", 6, 1, 0);
MQTT_Publish(client, "/mqtt/topic/2", "hello2", 6, 2, 0);*/
}
void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
{
char *topicBuf = (char*)os_zalloc(topic_len+1),
*dataBuf = (char*)os_zalloc(data_len+1);
MQTT_Client* client = (MQTT_Client*)args;
os_memcpy(topicBuf, topic, topic_len);
topicBuf[topic_len] = 0;
os_memcpy(dataBuf, data, data_len);
dataBuf[data_len] = 0;
INFO("Receive topic: %s, data: %s \r\n", topicBuf, dataBuf);
os_free(topicBuf);
os_free(dataBuf);
}
if( os_strcmp(topicBuf,"/mqtt/topic/0") == 0 )
{
if( os_strcmp(dataBuf,"1") == 0 ) // 有效载荷是"LED_ON"
{
//这里开灯的操作
INFO("LED--ON");
GPIO_OUTPUT_SET(GPIO_ID_PIN(0),1);
MQTT_Publish(&mqttClient, "LED_STATUS","1",1, 0, 0);
}
else if( os_strcmp(dataBuf,"0") == 0 ) // 有效载荷 == "LED_OFF"
{
//这里灭灯的操作
INFO("LED--OFF");
GPIO_OUTPUT_SET(GPIO_ID_PIN(0),0);
MQTT_Publish(&mqttClient, "LED_STATUS","0",1, 0, 0);
}
}
#include "driver/dht11.h"
void ICACHE_FLASH_ATTR OS_Timer_1_Init_JX(u32 time_ms, u8 time_repetitive)
{
os_timer_disarm(&OS_Timer_1);
os_timer_setfn(&OS_Timer_1,(os_timer_func_t *)OS_Timer_1_cb, NULL);
os_timer_arm(&OS_Timer_1, time_ms, time_repetitive);
}
void ICACHE_FLASH_ATTR OS_Timer_1_cb(void)
{
DHT11_Data Data;
if(DHT11_Read_Data(&Data,PERIPHS_IO_MUX_GPIO2_U,2) == 0)
{
os_printf("\n read ok \n");
os_printf("\n Humi: %d\t Temp: %d\n",Data.Humi,Data.Temp);
}
else
os_printf("\n\n\t\t read failed \n\n");
}
OS_Timer_1_Init_JX(10000,1);
MQTT_Publish(client, "hellow", "hello1", 6, 1, 0);
MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain)
temp_humi[0]=Data.Temp/10+'0';//除以10获得温度高位,并转化为char型
temp_humi[1]=Data.Temp%10+'0';//对10取模获得个位,也转为char型
temp_humi[2]=Data.Humi/10+'0';
temp_humi[3]=Data.Humi%10+'0';
MQTT_Publish(&mqttClient, "temp_humi",temp_humi,4, 0, 0);
六、程序编译
七、为ESP8266烧写固件
七、串口调试
八、Esp8266端源代码,可以导入后改一下信息进行烧写。
一、开发环境(AndroidStudio3.6,可自行百度安装)
二、导入Jar包
三、AndroidManFest中添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
四、AndroidManFest的application标签下添加服务
<service android:name="com.chinamobile.iot.onenet.mqtt.MqttService"/>
五、在onCreate()方法中调用init_MQtt()方法连接OneNet
/**
* MQTT连接服务器
*/
private void init_MQtt(){
//初始化sdk
MqttClient.initialize(this,"183.230.40.39",6002,"设备ID","产品ID","Master APIkey");
//设置接受响应回调
MqttClient.getInstance().setCallBack(callBack);
//设置连接属性
MqttConnectOptions connectOptions = new MqttConnectOptions();
connectOptions.setCleanSession(true);
connectOptions.setKeepAlive(121);
connectOptions.setWill(false);
connectOptions.setWillQoS(QoS.AT_MOST_ONCE);
connectOptions.setWillRetain(false);
//建立TCP连接
MqttClient.getInstance().connect(connectOptions);
}
/**
* MQTT回调函数
*/
private MqttCallBack callBack =new MqttCallBack() {
@Override
public void messageArrived(MqttMessage mqttMessage) {
switch (mqttMessage.getMqttHeader().getType()){
case CONNACK:
MqttConnAck mqttConnAck = (MqttConnAck)
break;
case PUBLISH:
break;
case SUBSCRIBE:
MqttSubscribe mqttSubscribe=(MqttSubscribe)mqttMessage;
break;
case SUBACK:
MqttSubAck mqttSubAck = (MqttSubAck) mqttMessage;
break;
case PINGRESP:
break;
case PUBACK:
MqttPubAck mqttPubAck=(MqttPubAck) mqttMessage;
break;
case PUBCOMP:
break;
}
}
@Override
public void connectionLost(Exception e) {
}
@Override
public void disconnect() {
}
};
六、此时手机设备已经连接上OneNet,可以在平台上看到
七、订阅Topic
MqttSubscribe mqttSubscribe = new MqttSubscribe("你要发布的Topic名字", QoS.AT_LEAST_ONCE);
MqttClient.getInstance().subscribe(mqttSubscribe);
八、发布Topic
//data中写入你想要发送的数据
byte[] data = {'1'};
MqttPublish mqttPublish=new MqttPublish("你要发布的Topic名称",data,QoS.AT_LEAST_ONCE);
MqttClient.getInstance().sendMsg(mqttPublish);
九、接收已订阅Topic的信息,在回调函数的相应项下修改
case PUBLISH:
MqttPublish mqttPublish = (MqttPublish) mqttMessage;
byte[] data = mqttPublish.getData();
String topic= mqttPublish.getTopicName();
String s=new String(data);
textview.setText(topic+" "+new String(data));
break;
十、本项目是用两个按键来发布一个Topic,一个的内容为1,另一个为0,ESP8266订阅了这个Topic,接收到1/0表示开/关灯。
手机订阅一个ESP8266发布的温湿度Topic和一个判断灯开关是否成功的Topic(LED_STATUS),实现温湿度在手机端显示和开关灯。
十一、你可以使用MQtt实现多人聊天。
十二、Android源码地址
十三、小白菜一个,大神勿喷,感谢onenet大哥提供的jar包。