導(dǎo)讀
本文介紹了如何使用微信公眾號前臺控制arduino,包括讀取傳感器數(shù)據(jù)或者如何控制馬達(dá),舵機(jī)等設(shè)備
目錄
- 總體架構(gòu)
- arduino 設(shè)備側(cè)實(shí)現(xiàn)
- OneNets設(shè)備云配置
- 自有云服務(wù)器后臺
- 微信公眾號前臺網(wǎng)頁 -- 實(shí)現(xiàn)對arduino的控制和信息讀取
一. 總體架構(gòu)
二. arduino 設(shè)備側(cè)實(shí)現(xiàn)
Word is cheap, Let me show you code first:
Device code on Github
設(shè)備端代碼基于AdminIOT修改奴艾,感謝原作者的無私分享,原作者網(wǎng)站:https://adminiot.com.cn/
先上一張圖說明下arduino板子連線
我用的是WeMos D1板子,接口和arduino uno等原裝板子類似的,不了解的同學(xué)百度下即可,包括Arduino IDE的配置,這里就不詳細(xì)說明了
額,線有點(diǎn)亂,看不清楚,我列個接線表說明下
連接的傳感器
DHT -- 濕度溫度傳感器
Servo -- 舵機(jī)
WeMos | DHT | Servo |
---|---|---|
D4 | out | / |
3.3V | + | / |
GND | - | / |
D5 | / | control(PWM) |
5V | / | + |
GND | / | GND |
代碼中一些重要文件和重要函數(shù)說明
iotweb.ino
void setup()
{
Serial.begin(9600);
delay(10);
Serial.println("board boot up , hello iot!\n");
//wifi setup
if(!setupWIFI()) die("setup WIFI fail\n");
//All sensor init
sensorInit();
//Mqtt init
MqttProtocolInit();
//Delay enough time for mqtt init done
delay(5000);
}
WeMos使用Mqtt協(xié)議和OneNet云平臺通訊,使用到的
Mqtt OneNet官方SDK
Mqtt OneNet協(xié)議
void loop()
{
// Wait a few seconds between measurements.
delay(1000);
MqttDataRecvLoop();//Board receive cmd or publish from server then reply and excute
MqttDataPublish(cnt);//Board publish data to server every few seconds.
cnt++;
if( cnt > 1000 )
{
cnt = 0;
}
}
MqttDataRecvLoop():輪詢讀取OneNet Server發(fā)過來的數(shù)據(jù)包(例如publish,command等)狼讨,然后進(jìn)行對應(yīng)處理。
MqttDataPublish():主動循環(huán)上報傳感器數(shù)值,可以設(shè)定定時發(fā)送弹砚。
mqtt_sample_layer.cpp 封裝mqtt sdk,處理協(xié)議流程救湖,提供對外接口
在解釋該文件前涎拉,先說下WifiClient這個類途茫,本案例使用它來連接WIFI和收發(fā)TCP數(shù)據(jù)包碟嘴,具體可以參考
MqttSample_RecvPkt 和MqttSample_SendPkt 使用了client.read 和 client.write來收發(fā),我們可以直接得到tcp segment數(shù)據(jù)
static int MqttSample_RecvPkt(void *arg, void *buf, uint32_t count)
{
uint32_t previousMillis = millis();
while(!client.available())
{
//yield();
uint32_t currentMillis = millis();
if(currentMillis - previousMillis >= ((int32_t) 2 * 1000))
{
printf("Recv time out.\n");
return false;
}
}
int read_size = 0;
if(client.available())
{
read_size = client.read((uint8_t *)buf, count);
}
return read_size;
}
static int MqttSample_SendPkt(void *arg, const struct iovec *iov, int iovcnt)
{
int bytes;
int i=0,j=0;
//get length to send
int length = 0;
//printf("Send count = %d\n", iovcnt);
for(i=0; i<iovcnt; ++i)
{
length += iov[i].iov_len;
}
for(i=0; i<iovcnt; ++i)
{
int send_size = client.write((char*)iov[i].iov_base, iov[i].iov_len);
//printf("The %d time size is : %d\n", i, send_size);
}
return length;
}
下面這個函數(shù)就是直接處理OneNet平臺Command的地方,注意發(fā)送給板子的命令字符串必須以“:”作為結(jié)束符
void MqttSample_pollingCmd()
{
if(bitRead(ctx->eventType,MQTT_EVENT_TYPE_GETCMD))
{
bitClear(ctx->eventType,MQTT_EVENT_TYPE_GETCMD);
char rsp[]="ok";
if(!MqttSample_respcommand(rsp))
{
LOG(ERROR,"CMD response error, resend it!\n");
}
else
{
if(strstr(ctx->cmd,CMD_GET_ALL_DATA))//OneNet request to get all data from Arduino
{
MqttSample_sendDHTdata();
MqttSample_sendServoPos();
//Send other sensor data following
}
else if(strstr(ctx->cmd, CMD_GET_DTH_DATA))
{
MqttSample_sendDHTdata();
}
/* You can handle other command following */
else if(strstr(ctx->cmd, CMD_GET_SERVO_POSTION))
{
MqttSample_sendServoPos();
}
else if(strstr(ctx->cmd, CMD_SET_SERVO_POSITION))
{
int pos_value = MqttSample_readCmdPos(ctx->cmd);
MqttSample_setServoPos(pos_value);
}
/* Command handle end */
else
{
LOG(ERROR,"CMD string error, resend it!\n");
}
}
}
}
下面這部分是讀取傳感器并主動上報的函數(shù)部分,DHT的library已經(jīng)在github上分享:DHT library
void MqttSample_sendServoPos()
{
//capture sensor data ...
printf("<%s>: come in\r\n", __FUNCTION__);
int pos = -1;
pos = myservo.read();
// Check if any reads failed and exit early (to try again).
if (pos < 0 || pos > 180)
{
LOG(ERROR,"Posistion data error!");
return;
}
//report data to oneNet
// LOG(DEBUG,"publish sensor data:\n");
if(!MqttSample_pulish_ServoData(pos))
{
LOG(ERROR,"publish servor data fail\n");
}
}
void MqttSample_sendDHTdata()
{
//capture sensor data ...
printf("<%s>: come in\r\n", __FUNCTION__);
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t))
{
LOG(ERROR,"Failed to read from DHT sensor!");
return;
}
//report data to oneNet
// LOG(DEBUG,"publish sensor data:\n");
![device.PNG](https://upload-images.jianshu.io/upload_images/16642078-dd8d2256a5a31773.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
if(!MqttSample_pulish_SensorData(h,t))
{
LOG(ERROR,"publish sensor data fail\n");
}
}
Arduino設(shè)備代碼的分享就到這了慈省,下面介紹OneNet設(shè)備云部分臀防。
IOT平臺操作基本類似
三.OneNet云平臺配置
1.新建產(chǎn)品
2.新建設(shè)備
添加完產(chǎn)品后眠菇,就可以添加設(shè)備边败,鑒權(quán)信息填寫后要記錄。
好了捎废,現(xiàn)在產(chǎn)品和設(shè)備都添加完了笑窜,我們整理下代碼中用到的OneNet平臺上顯示的一些SN,KEY之類的一一對應(yīng):
代碼中 | OneNet |
---|---|
devid_temp | 設(shè)備ID |
API_KEY | 產(chǎn)品--Master-APIkey |
PROD_ID | 產(chǎn)品ID |
SN | 鑒權(quán)信息 |
根據(jù)現(xiàn)在arduino板子連接的傳感器登疗,我們設(shè)定了如下三個數(shù)據(jù)流來顯示傳感器數(shù)據(jù)排截。
OneNet還有個功能就是創(chuàng)建應(yīng)用來顯示設(shè)備數(shù)據(jù)或控制設(shè)備
OneNet配置就是以上這么多了嫌蚤,如果有其他相關(guān)想了解的,可以自行查閱開發(fā)文檔
四.自有云服務(wù)器后臺的實(shí)現(xiàn)
代碼采用Express架構(gòu)實(shí)現(xiàn)断傲,鏈接:https://github.com/zguogang/api4onenet
api.js提供前臺http get route, 包括獲取設(shè)備列表脱吱,接收command命令等的處理與反饋數(shù)據(jù)
onenetApi.js 提供了對onenet 平臺api調(diào)用的接口,* iotApi.js* 未使用
oneNet api開發(fā)文檔鏈接:https://open.iot.10086.cn/doc/art528.html#108
五.微信公眾號前臺網(wǎng)頁
一個H5網(wǎng)頁,使用公眾號菜單跳轉(zhuǎn)认罩。
H5網(wǎng)頁代碼鏈接:https://github.com/zguogang/web2onenet
首先來看下前臺頁面UI箱蝠,比較簡單,只是提供一個實(shí)時顯示數(shù)據(jù)和發(fā)送控制命令的功能
命令是以字符串形式發(fā)送的
架構(gòu):VUE
具體這邊就不多解釋了垦垂,對照著后臺代碼一看就懂宦搬。
六.總結(jié)
成文草草,難免有錯漏劫拗,歡迎各位大牛间校,同道一起討論,指正页慷。