需要使用的模块有ESP32,DHT11,土壤湿度检测模块(电阻式)传感器模块。通过DHT11传感接收到温湿度以及土壤湿度检测模块接收到数据传入服务器。并对服务器数据进行提取以实现能够在微信小程序上远程接收到温湿度数据。
图片如下。
实验主要分为三大步骤:传感器接收数据,数据上传至onenet平台,通过微信小程序接受数据。
本次实验涉及到的方面较多,但由于无法精通各方面的知识,所以在实践过程中遇到了一系列的问题,并且读者如果有更好的建议可以提出并且会虚心采纳。
第一步:传感器接收数据
前篇文章提到了如何测土壤湿度,这里就不再过多赘述。测量温湿度通过使用DHT11模块,具体步骤可参考一下代码
#define SUCC 0 //成功编码
#define INITTOUT 1 //初始化超时错误编码
#define CHECKSUM 2 //校验和错误编码
#define IO_OUTMODE pinMode(DHT_PIN, OUTPUT);//初始化GPIO0为输出
#define IO_INMODE pinMode(DHT_PIN, INPUT); //设置IO位输入
#define IO_SET digitalWrite(DHT_PIN, HIGH);//IO输出高
#define IO_CLR digitalWrite(DHT_PIN, LOW);//IO输出低
#define READ_IO digitalRead(DHT_PIN) //读取IO输入
#define DELAY_MS delay //ms级延时函数
#define DELAY_US delayMicroseconds //us级延时函数
//DHT11初始化函数
uint8_t ICACHE_FLASH_ATTR dht11_init(void) {
uint8_t errcode = SUCC;
uint8_t i = 0;
IO_OUTMODE //设置IO输出
IO_SET //IO输出1
DELAY_MS(2); //延时2ms,为下降沿做准备
IO_CLR //IO输出0,产生下降沿
DELAY_MS(20); //延时20ms,主机下降沿并保持,18ms以上的低电平启动DHT11
IO_SET //再次拉高IO,等待DHT11拉低以作应答
IO_INMODE //设置IO输入
DELAY_US(40); //延时40us,等待DHT11输入的低电平应答信号
//等待DHT11拉低IO,最高持续MAXCOUNT个us
while(READ_IO==1 && i<MAXCOUNT) {
i++;
DELAY_US(1);
}
if(i>=MAXCOUNT) {
errcode = INITTOUT;
return errcode;
} else i = 0;
//DHT11拉低IO持续80us,后会在拉高IO持续80us作为完整的应答
while (READ_IO==0 && i<MAXCOUNT) {
i++;
DELAY_US(1);
}
if(i>=MAXCOUNT) {
errcode = INITTOUT;
return errcode;
}
return errcode;
}
//读取一个bit函数
uint8_t dht11_readBit(void) {
uint8_t i = 0;
//等待IO变低
while(READ_IO==1 && i<MAXCOUNT) {
i++;
DELAY_US(1);
}
i = 0;
//等待IO变高——先低再高表示开始传输一个bit
while (READ_IO==0 && i<MAXCOUNT) {
i++;
DELAY_US(1);
}
DELAY_US(40); //等待40us(0 bit)
if(READ_IO==1) return 1;
else return 0;
}
//读取一个Byte函数
uint8_t dht11_readByte(void) {
uint8_t i = 0;
uint8_t data = 0;
for(i=0; i<8; i++) {
data <<= 1;
data |= dht11_readBit();
}
return data;
}
//读取温湿度值
uint8_t dht11Read(uint8_t *temp, uint8_t *humi) {
uint8_t buf[5];
uint8_t i;
if(!dht11_init()) {
for(i=0; i<5; i++) {
buf[i] = dht11_readByte();
}
if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4]) {
*humi = buf[0];
*temp = buf[2];
} else {
return CHECKSUM;
}
} else {
return INITTOUT;
}
return SUCC;
}
其实arduino库里面有相应的案例可以直接调用,这里只是方便学习。
第二步:数据上传至onenet平台
首先应先在onenet平台创建个人用户,在多协议接入下创建设备,创建完成之后我们可以得到一些数据,如图
这里面的大部分数据信息我们以后都会用到,然后创建数据流模板,为了使一会接收到的数据具有格式化。
我这里已经创建好了,自己可以根据自己的实验情况进行创建。这次数据的传输使用过MQTT协议完成的。准备工作做好之后,我们就可以在arduino里面配置相关信息。
WIFI信息的配置
const char *ssid = "***"; //wifi名
const char *password = "***"; //wifi密码
const char *mqtt_server = "183.230.40.39"; //onenet 的 IP地址
MQTT协议的配置(所需信息可以在onenet里面找到填写自己的)
#define mqtt_devid "946318073" //设备ID
#define mqtt_pubid "519341" //产品ID
#define mqtt_password "test123" //鉴权信息
接下来就是调用函数连接WIFI,设置客户端连接onenet服务器并连接指定的产品设备,向主题发送数据,以及收到主题下发的回调。在向主题发送数据中
void sendTempAndHumi()
{
if (client.connected())
{
delay(3000);
//Serial.printf("The temp:%d,The humi:%d\r\n", temperature, humidity);
snprintf(msgJson,60, dataTemplate,temperature,humidity,counts2); //将模拟温湿度数据套入dataTemplate模板中, 生成的字符串传给msgJson
json_len = strlen(msgJson); //msgJson的长度
msg_buf[0] = char(0x03); //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
msg_buf[1] = char(json_len >> 8); //数据第二位是要发送的数据长度的高八位
msg_buf[2] = char(json_len & 0xff); //数据第三位是要发送数据的长度的低八位
memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
msg_buf[3 + strlen(msgJson)] = 0; //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
Serial.print("public message:");
Serial.println(msgJson);
client.publish("$dp", (uint8_t *)msg_buf, 3 + strlen(msgJson)); //发送数据到主题$dp
}
}
在进行传输数据的时候发送json数据的数组容量要足够大。否则最后传出的数据不完整。
最后烧录之后打开串口调试器等待WIFI连接成功即可连接到onenet上,打开onenet刷新一下打开数据流即可看到接收到的数据
第三步:通过微信小程序接收数据
微信小程序类似网页开发,要具备一定的web基础。在wxml里面定义一些格式,js则是通过接口获取数据,以及定义数据类型以及获取方法的事件处理函数。
timeout1: function() {
var that = this;
var timerName = setTimeout(function() {
wx.request({
url: 'http://api.heclouds.com/devices/946318073/datastreams/temp', //仅为示例,并非真实的接口地址(填写自己的)
data: {
},
header: {
'api-key': 'bpDuvk9kuR2lilNRgncfZwr0UrU=' // 填写自己的
},
method: 'get',
dataType: 'json',
success(res) {
console.log(res.data.data);
that.setData({
redata: res.data.data.current_value,
})
}
});
that.timeout()
}, 1000) //设定一个定时器,在指定的毫秒数后调用函数或计算表达式
},
在获取数据的过程中,由于是三种数据可以使用数组的形式进行获取。或者采用定义三个bindtap,来分别使用不同的接口。
<view class="usermotto">
<button bindtap="timeout1"> 获取温度 </button>
<button bindtap="timeout2"> 获取湿度 </button>
<button bindtap="timeout3"> 获取土壤湿度 </button>
</view>
展示结果:
至此,完整的实验过程以及做完。本次实验结合了之前文章提及到的一些相关内容并做了些整理。今后还会继续完善这个实验。涉及到的源码可以私信我,同时中间出现的问题和建议也请及时提出。