主要内容

远程传感器控制使用安全MQTT发布和订阅

这个示例展示了如何在ThingSpeak中使用MQTT发布和订阅体系结构。MQTT协议是一种低开销的设备消息传递系统。使用MQTT订阅控制通道的第1字段。当您更新控制通道时,已传递的值将被发送到您的设备。伺服旋转到指定的角度。设备测量网络强度,更新存储通道。代码中的注释说明了如何将此示例应用于不安全的连接。

金宝app支持的硬件

  • ESP8266、NodeMCU WeMOS

  • Arduino MKR1000

  • Arduino Uno, Mega, Due或Leonardo无线网络连接

  • 粒子光子(稍微调整代码和原理图)

该示例旨在仅使用额外的额外部件,即单个伺服电机。您可以使用床上的Wi-Fi天线进行Wi-Fi强度测量。

这些图像显示从存储通道输出的样本通道。字段1存储从控制通道设置的伺服电机角度,字段2显示测量的Wi-Fi强度值。

数据分析表明,微操作系统硬件的方向对测量信号的强度有方向性影响。

先决条件

1)为订阅控件创建一个ThingSpeak频道,如图所示在新通道中收集数据.订阅通道保持伺服电机的角度。当更新伺服电机角度时,订阅设备将角度接收为MQTT消息。该设备设置伺服角度并以该角度测量新的无线网络强度。

2)为已发布的数据创建另一件事程序邮件。发布通道记录设定角度和信号强度数据。

3)在频道设置视图,为发布通道启用字段1和2。为了区分字段,为每个字段指定一个描述性名称。

4)注意读写API键API密钥选项卡中频道设置视图(在图像中圈出)。

5)单击创建MQTT设备设备>MQTT那就在这一页的上面添加设备.当您设置设备时,添加两个通道。有关详细信息,请参见创建ThingSpeak MQTT设备

6)添加新设备时,单击下载凭据>Arduino (mqtt_secrets.h).将此下载的秘密文件保留在下面的代码部分中的访问权限。

所需的硬件

  • WeMOS D1 Mini,或以下设备之一,更改库使用:NodeMCU, ESP8266-01, ESP8266-04, ESP8266-12, ESP8266-12E, Arduino®MKR1000,或其他Arduino以太网或无线网络连接

  • 伺服电机(例如,Futaba S3003)

  • 跨接线(至少3根)

  • USB电缆

示意图和联系

1)将D5连接在WEMOS D1 MINI上伺服信号线。

2)将伺服接地线与WeMOS板上的地面连接。

3)连接伺服电源至3.3 V。在某些情况下,直接使用5v会导致USB电源过载。

计划你的Arduino

使用Arduino IDE为您的设备编程。可以下载最新的Arduino IDE在这里

1)添加ESP8266板包:

下一个。文件>首选项, 进入https://arduino.esp8266.com/stable/package_esp8266com_index.json.进入其他板经理URL

b。选择工具>董事会>董事会的经理.输入ESP8266在搜索栏中并安装软件包。

2)修改允许的数据包大小。

一种。通常导航到包含PUB子库标题文件的文件夹文档\ Arduino \图书馆\ PubSubClient \ src

b。编辑PubSubClient.h c修改“Max packet size”为4096。当完成时,一行应该是:

#定义MQTT_MAX_PACKET_SIZE 4096

3)创建应用:

一种。在Arduino IDE中打开一个新窗口,并保存文件。

b。添加code provided in the Code section.

c.请务必在代码中编辑无线网络信息和信道id。

4)将库和秘密文件添加到草图:

a.如果还没有,请通过选择将以下库添加到库管理器中草图>包括图书馆>管理库.对于每个库,搜索它的名称和选择安装

  • PubSubClient

  • ESP8266Wifi

  • 伺服

b。添加mqtt_secrets.h文件。

测试你的设备

成功上传程序后,您可以使用串行监视器监控输出。将值上载到您的optionspeak控制信道的范围为0到175.您可以从中乘以从中恢复GET请求格式API密钥选项卡或使用Write API密钥修改此文本。将每个URL直接进入浏览器的地址栏中,将Write API键更改为频道的Write API密钥。

https://api.thingspeak.com/update?api_key=your_write_api_key& field1=angle_value.

只要您发布到订阅通道,设备会将角度和Wi-Fi信号强度发布到存储频道。确保您的角度值在0到175的范围内。

代码

1)包含必需的库并定义数据字段:

#include  #include  //只在使用安全连接时需要。#include  #include  #include "mqtt_secrets.h" #define ANGLE_FIELD 0 #define DATA_FIELD 1 //发送信号强度的数据字段。

2)定义和初始化变量。请确保编辑无线网络信息、通道ID和API密钥。在你的频道主页的顶部找到你的频道ID。

char ssid [] =“still_waters_nest”;//将其更改为您的网络SSID(名称)。char pass [] =“33turkeys511”;//将其更改为您的网络密码。const char * server =“mqtt3.thingspeak.com”;char mqttusername [] = secret_mqt_username;char mqttpass [] = secret_mqt_password;//从帐户> myprofile的MQTT API密钥更改为您的MQTT API密钥。char clientID [] = secret_mqt_client_id;长readchannelid = 85; long writeChannelID = 86; // Here's how to get ThingSpeak server fingerprint: https://www.a2hosting.com/kb/security/ssl/a2-hostings-ssl-certificate-fingerprints const char* thingspeak_server_fingerprint = "27 18 92 dd a4 26 c3 07 09 b9 7a e6 c5 21 b9 5b 48 f7 16 e1"; // WiFiClient client; // Initialize the Wi-Fi client library. Uncomment for nonsecure connection. WiFiClientSecure client; // Uncomment for secure connection. PubSubClient mqttClient( client ); // Initialize the PuBSubClient library. Servo myservo; // Create servo object to control a servo . int fieldsToPublish[8]={1,1,0,0,0,0,0,0}; // Change to allow multiple fields. float dataToPublish[8]; // Holds your field data. int changeFlag=0; // Let the main loop know there is new data to set. int servo_pos=0; // Servo position

3)在此代码中定义功能原型。

// //原型// //处理来自MQTT订阅的消息。void mqttSubscriptionCallback(char* topic, byte* payload, unsigned int length);//生成唯一的客户端ID并连接到MQTT代理。空白mqttConnect ();//从ThingSpeak频道订阅一个字段或feed。int mqttSubscribe(long subChannelID,int field, int不明名);//将消息发布到通道提要。//连接到指定的Wi-Fi SSID。int connectWifi ();//测量Wi-Fi信号强度。 void updateRSSIValue();

4)初始化引脚的输入和输出,启动串行监视器,并初始化MQTT客户端设置例行公事。

void setup(){serial.begin(115200);serial.println(“开始”);int status = wl_idle_status;//设置临时Wi-Fi状态。connectwifi();//连接到Wi-Fi网络。// mqttclient.setserver(服务器,1883);//设置MQTT Broker详细信息,不确定端口。非法连接的取消注释。mqttclient.setserver(服务器,8883); // Set the MQTT broker details, secure port. Uncomment for secure connection. mqttClient.setCallback( mqttSubscriptionCallback ); // Set the MQTT message handler function. myservo.attach(14); // Attach the servo on GIO2 to the servo object. myservo.write(90); // Start in the middle. }

5)每次主循环执行时,检查是否可用于处理来自MQTT订阅的数据。然后设置伺服位置以匹配数据。确保无线和MQTT客户端处于活动状态并与客户端服务器保持连接。

void循环(){if(wifi.status()!= wl_connected){connectwifi();}如果(!mqttclient.connected()){mqttconnect();// Connect如果未连接MQTT客户端。if(mqttsubscribe(readchannelid,1,0)== 1){serial.println(“订阅”);mqttclient.loop();//调用循环以维护与服务器的连接。if((servo_pos> 175)||(servo_pos <0)){servo_pos = 0;}如果(changeflag){chanceflag = 0;myservo.write(servo_pos);DataTopublish [Anight_Field] = servo_pos; delay(1100); // Wait for ThingSpeak to publish. Serial.println( "Servo value " + String( servo_pos ) ); mqttPublish( writeChannelID, dataToPublish, fieldsToPublish ); } delay(1); }

6)使用mqttSubscriptionCallback函数来处理传入的MQTT消息。如果主循环执行处理步骤而不是回调,则程序运行得更流畅。在这个函数中,使用标志在主循环中引起更改。

/** *处理通过MQTT代理从订阅通道接收的消息。* topic -消息的订阅主题。*有效载荷-要订阅的字段。值0表示订阅所有字段。* mesLength -消息长度。*/ void mqttSubscriptionCallback(char* topic, byte* payload, unsigned int mesLength) {char p[mesLength + 1];memcpy(p, payload, mesLength);p [mesLength] =零;系列。print("Answer: "); Serial.println( String(p) ); servo_pos=atoi( p ); changeFlag=1; }

7)使用MQTTConnect函数来设置和维护到MQTT的连接。

void mqttConnect(){//循环直到连接。while (!mqttClient.connected());println(String(mqttUserName)+ ", " + mqttPass + ", " + clientID);//连接到MQTT代理。系列。print("尝试MQTT连接…");如果(mqttClient。connect(clientID, mqttUserName, mqttPass);println("Connected with Client ID: "+String(clientID) + " User "+String(mqttUserName) + " Pwd "+String(mqttPass));} else {Serial。print( "failed, rc = " ); // See https://pubsubclient.knolleary.net/api.html#state for the failure code explanation. Serial.print( mqttClient.state() ); Serial.println( " Will try again in 5 seconds" ); delay( 5000 ); } } }

8)使用mqttSubscribe接收LED控制字段的更新。在本例中,您订阅一个字段,但您也可以使用此函数订阅整个频道提要。调用函数场= 0订阅整个提要。

/** *订阅频道字段。* subChannelID -订阅的频道。* field -要订阅的字段。值0表示订阅所有字段。* readKey -读取订阅通道的API密钥。*不明嫌犯-设置为1取消订阅。*/ int mqttSubscribe(long subChannelID, int field, int unsubSub){String myTopic;//没有字段0,所以如果字段0被发送到订阅,那么就订阅整个频道提要。if (field==0){myTopic="频道/"+String(subChannelID)+"/subscribe";} else{myTopic="channels/"+String(subChannelID)+"/subscribe/fields/field"+String(field); } Serial.println( "Subscribing to " +myTopic ); Serial.println( "State= " + String( mqttClient.state() ) ); if ( unsubSub==1 ){ return mqttClient.unsubscribe(myTopic.c_str()); } return mqttClient.subscribe( myTopic.c_str() ,0 ); }

9)mqttunsubscribe.函数未在代码中使用,但您可以使用它来结束订阅。

/** * Unsubscribe channel * subChannelID -取消订阅的频道。*字段-取消订阅的字段。值0表示订阅所有字段。* readKey -读取订阅通道的API密钥。*/ int mqttUnSubscribe(long subChannelID,int field,char* readKey){String myTopic;if (field==0){myTopic="频道/"+String(subChannelID)+"/subscribe";} else{myTopic="channels/"+String(subChannelID)+"/subscribe/fields/field"+String(field);} mqttClient返回。退订(myTopic.c_str ());}

10)使用mqttPublish功能发送您的角度和Wi-Fi RSSI数据到ThingSpeak频道。

/ ** *发布到频道* pubchannelid  - 频道发布到。* pubwriteakikey  - 写通道的API键发布到。* dataArray  - 二进制数组,指示要发布的字段,以字段1. * fialeArray  - 要发布的值数组,以字段1. * / void mqttpublish(long pubchannelid,float dataArray [],int fieldarray []){int index = 0;string datastring =“”;updaterssiveue();//确保更新了存储的值。//虽然(索引<8){//查看字段数组以构建发布字符串以发送到thingspeak。if(FieldArray [index]> 0){dataString + =“&字段”+字符串(索引+ 1)+“=”+字符串(dataArray [index]);}索引++; } Serial.println( dataString ); // Create a topic string and publish data to ThingSpeak channel feed. String topicString ="channels/" + String( pubChannelID ) + "/publish"; mqttClient.publish( topicString.c_str(), dataString.c_str() ); Serial.println( "Published to channel " + String( pubChannelID ) ); }

将您的设备连接到无线网络connectwifi.函数。

int connectwifi(){whifi.status()!= wl_connected){wifi.begin(ssid,pass);延迟(8500);serial.println(“连接到Wi-Fi”);serial.println(“连接”);client.setfingerprint(thingspeak_server_fingerrint);//如果使用非线性连接,则评论此行。}

12)使用updateRSSIValue函数读取当前连接的网络的信号强度。

void updateRSSIValue(){long rssi = WiFi.RSSI();系列。打印(“RSSI:”);以(rssi);datatoppublish [DATA_FIELD]=float(rssi);}

另请参阅

|

相关话题

外部网站