该雷达应用程序使用超声波和伺服电机创建了在Thingspeak IOT 平台上显示的雷达应用程序。
转发:Radar application with thingspeak
这是我基于 RUS-04 超声波传感器和 W5100S-EVB-PICO 的更新版本。
由于带有 CircuitPython 环境和库的 W5100S-EVB-PICO 为我提供了与不同类型的物联网平台进行通信的不同可能性。
我曾尝试利用我现有的资源开发具有物联网平台的雷达。
本项目使用的平台是Thingspeak
通过使用 Thingspeak 的 MATLAB Visualizations,我可以通过创建绘图图表轻松开发雷达显示。
详情请参阅以下信息。
以下是模块与Thingspeak通信的连接结构
从上图中可以看出,该应用的模块是超声波传感器模块 RUS-04 和伺服电机 SG90。 SG90 将与 RUS-04 物理连接,作为可移动超声波传感器
这就是我连接两个模块并使其成为一体的方式。
与W5100S-EVB-PICO连线后,只需要使用很少的库即可使其正常工作。
由于我对基于 HCSR-04 的 CircuitPython 库进行了一些修改,以便在 RUS-04 模块上工作。 我仍然会继续在这个项目中使用 CircuitPython。
关于我之前项目的开发,可以参考下面的链接。
W5100S-EVB-PICO + RUS04 + Adafruit IO in Circuitpython
为了使RUS-04和SG90能够正常工作,我根据以下代码进行了一些设置。
库:
import pwmio #PWM control for servo
from adafruit_motor import servo #Use servo.py
import adafruit_hcsr04 #Use my previous project's modified Hcsr04 library
IO设置:
# create a PWMOut object on the control pin.
pwm = pwmio.PWMOut(board.GP0, duty_cycle=0, frequency=50)
servo = servo.Servo(pwm)
#Sonar setup
sonar = adafruit_hcsr04.HCSR04(trigger_pin=board.GP2)
RUS-04 + SG90:
#variables to save data
result = [None] * 32
#variables to set the correct format to upload thingspeak
pub = [None] * 4
#collect ultrasonic data from each 5 degree angle
for i in range(32): # Collect 32 data (limitation by thingspeak)
servo.angle = i*5
result[i] = sonar.distance
print(result[i])
time.sleep(0.08)
for i in range(180): #back to zero point
servo.angle = 180 - i
time.sleep(0.01)
设置好代码后,我们就可以轻松采集到每5度角的超声波距离。
编码完成后,我需要进行与Thingspeak的通信。
渠道:
正如我在上面的段落中提到的,需要创建 4 个通道(免费版本)才能允许我将数据上传到 Thingspeak。
创建频道只需要创建一个名称并记住打开所有字段(提要)以允许雷达数据可以传输到 Thingspeak。
MQTT 设备:
为了让Thingspeak能够从MQTT接收您的数据,需要我们在Thingspeak中创建一个包含所有通道的MQTT设备。
MQTT设备
从上图中,我已经为我的所有频道创建了一个 MQTT 设备。 它具有发布和订阅MQTT的能力。
完成上述设置后,W5100S-EVB-PICO 的数据将上传到 Thingspeak。
Adafruit 和 CircuitPython 为我开发应用程序提供了很多库。 它还有一个特定的库,可以让我轻松地与 Adafruit 的 IOT 平台 - Adafruit IO 进行通信。
但是,它没有图形/图表创建功能,无法让我为我的项目创建雷达图。
于是,我找到了一个IOT平台,叫做:
Thingspeak.
Thingspeak 有一个名为 MATLAB Visualizations 的应用程序。 它允许我将数据组织成有用的信息并远程显示在物联网平台上。
通讯方法也很简单。 它为用户提供 HTML 和 MQTT。
由于我的数据不是那么大,而且我习惯于使用 Adafruit 的 MQTT 库。
Adafruit's MQTT library.
我使用 MQTT 协议上传我的 SG90 + RUS04 组合收集的数据。
由于我只是使用免费版本,因此它限制了我制作完美雷达的能力。
但是,当您支付他们的服务费用后,这些问题就可以解决。
我目前的免费计划是:
免费计划限制
一个通道包含 8 个源(字段),因此我只能上传 32 组数据来创建我的雷达。
第二个问题是 MATLAB Visualizations 仅提供自动刷新我的雷达图。
据我所知,付费版本会自动更新你的图表,并提供更多的渠道,让你在有限的时间内上传更多的数据。
库:
import adafruit_minimqtt.adafruit_minimqtt as MQTT
连接到 Thingspeak:
# Initialize MQTT interface with the ethernet interface
MQTT.set_socket(socket, eth)
# Initialize a new MQTT Client object
mqtt_client = MQTT.MQTT(
broker="mqtt3.thingspeak.com",
username=secrets["thingspeak_user"],
password=secrets["thingspeak_pass"],
client_id=secrets["thingspeak_id"],
is_ssl=False,
)
设置 MQTT 主题:
# MQTT Topic
# Use this topic if you'd like to connect to a standard MQTT broker
sonar1 = secrets["thingspeak_sonar1"]
sonar2 = secrets["thingspeak_sonar2"]
sonar3 = secrets["thingspeak_sonar3"]
sonar4 = secrets["thingspeak_sonar4"]
连接到 Thingspeak 并订阅所有主题:
#connect to Thingspeak
mqtt_client.connect()
#MQTT subscribe
mqtt_client.subscribe(sonar1)
mqtt_client.subscribe(sonar2)
mqtt_client.subscribe(sonar3)
mqtt_client.subscribe(sonar4)
上传超声波数据:
#format the codes correctly before upload to thingspeak
#Each channel could only upload 8 feeds (fields), so I need to publish 4 times for
#different channels
pub[0] = "field1={0}&field2={1}&field3={2}&field4={3}&field5={4}&field6={5}&field7={6}&field8={7}".format(result[0],result[1],result[2],result[3],result[4],result[5],result[6],result[7])
pub[1] = "field1={0}&field2={1}&field3={2}&field4={3}&field5={4}&field6={5}&field7={6}&field8={7}".format(result[8],result[9],result[10],result[11],result[12],result[13],result[14],result[15])
pub[2] = "field1={0}&field2={1}&field3={2}&field4={3}&field5={4}&field6={5}&field7={6}&field8={7}".format(result[16],result[17],result[18],result[19],result[20],result[21],result[22],result[23])
pub[3] = "field1={0}&field2={1}&field3={2}&field4={3}&field5={4}&field6={5}&field7={6}&field8={7}".format(result[24],result[25],result[26],result[27],result[28],result[29],result[30],result[31])
#Publish to Thingspeak 4 times to upload all the data
mqtt_client.publish(sonar1, pub[0])
mqtt_client.publish(sonar2, pub[1])
mqtt_client.publish(sonar3, pub[2])
mqtt_client.publish(sonar4, pub[3])
Thonny 的结果:
在 Thingspeak 上发布 MQTT 设备后,我可以开始使用 MATLAB Visualizations 创建雷达图。
该应用程序包含在 Thingspeak 中。
Thingspeak - MATLAB 可视化
要创建雷达图,需要使用 MATHLAB 的 Polarplot 编码。
Polarplot
代码:
% First channel
readChannelID = aaaaaaaaaaaa;
fieldID1 = 1;
fieldID2 = 2;
fieldID3 = 3;
fieldID4 = 4;
fieldID5 = 5;
fieldID6 = 6;
fieldID7 = 7;
fieldID8 = 8;
% Second Channel
readChannelID2 = bbbbbbbbb;
fieldID9 = 1;
fieldID10 = 2;
fieldID11 = 3;
fieldID12 = 4;
fieldID13 = 5;
fieldID14 = 6;
fieldID15 = 7;
fieldID16 = 8;
% Third Channel
readChannelID3 = ccccccccccccc;
fieldID17 = 1;
fieldID18 = 2;
fieldID19 = 3;
fieldID20 = 4;
fieldID21 = 5;
fieldID22 = 6;
fieldID23 = 7;
fieldID24 = 8;
% Fourth Channel
readChannelID4 =dddddddddddd;
fieldID25 = 1;
fieldID26 = 2;
fieldID27 = 3;
fieldID28 = 4;
fieldID29 = 5;
fieldID30 = 6;
fieldID31 = 7;
fieldID32 = 8;
% Channel Read API Key
% If your channel is private, then enter the read API
% Key between the '' below:
readAPIKey = 'EEEEEEEEEEE';
readAPIKey2 = 'FFFFFFFFFFFF';
readAPIKey3 = 'GGGGGGGGGGGG';
readAPIKey4 = 'HHHHHHHHHHHHHHHH';
%% Read Data from all fields (feeds)
data1 = thingSpeakRead(readChannelID, 'Field', fieldID1, 'NumPoints', 1, 'ReadKey', readAPIKey);
data2 = thingSpeakRead(readChannelID, 'Field', fieldID2, 'NumPoints', 1, 'ReadKey', readAPIKey);
data3 = thingSpeakRead(readChannelID, 'Field', fieldID3, 'NumPoints', 1, 'ReadKey', readAPIKey);
data4 = thingSpeakRead(readChannelID, 'Field', fieldID4, 'NumPoints', 1, 'ReadKey', readAPIKey);
data5 = thingSpeakRead(readChannelID, 'Field', fieldID5, 'NumPoints', 1, 'ReadKey', readAPIKey);
data6 = thingSpeakRead(readChannelID, 'Field', fieldID6, 'NumPoints', 1, 'ReadKey', readAPIKey);
data7 = thingSpeakRead(readChannelID, 'Field', fieldID7, 'NumPoints', 1, 'ReadKey', readAPIKey);
data8 = thingSpeakRead(readChannelID, 'Field', fieldID8, 'NumPoints', 1, 'ReadKey', readAPIKey);
data9 = thingSpeakRead(readChannelID2, 'Field', fieldID9, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data10 = thingSpeakRead(readChannelID2, 'Field', fieldID10, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data11 = thingSpeakRead(readChannelID2, 'Field', fieldID11, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data12 = thingSpeakRead(readChannelID2, 'Field', fieldID12, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data13 = thingSpeakRead(readChannelID2, 'Field', fieldID13, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data14 = thingSpeakRead(readChannelID2, 'Field', fieldID14, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data15 = thingSpeakRead(readChannelID2, 'Field', fieldID15, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data16 = thingSpeakRead(readChannelID2, 'Field', fieldID16, 'NumPoints', 1, 'ReadKey', readAPIKey2);
data17 = thingSpeakRead(readChannelID3, 'Field', fieldID17, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data18 = thingSpeakRead(readChannelID3, 'Field', fieldID18, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data19 = thingSpeakRead(readChannelID3, 'Field', fieldID19, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data20 = thingSpeakRead(readChannelID3, 'Field', fieldID20, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data21 = thingSpeakRead(readChannelID3, 'Field', fieldID21, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data22 = thingSpeakRead(readChannelID3, 'Field', fieldID22, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data23 = thingSpeakRead(readChannelID3, 'Field', fieldID23, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data24 = thingSpeakRead(readChannelID3, 'Field', fieldID24, 'NumPoints', 1, 'ReadKey', readAPIKey3);
data25 = thingSpeakRead(readChannelID4, 'Field', fieldID25, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data26 = thingSpeakRead(readChannelID4, 'Field', fieldID26, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data27 = thingSpeakRead(readChannelID4, 'Field', fieldID27, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data28 = thingSpeakRead(readChannelID4, 'Field', fieldID28, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data29 = thingSpeakRead(readChannelID4, 'Field', fieldID29, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data30 = thingSpeakRead(readChannelID4, 'Field', fieldID30, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data31 = thingSpeakRead(readChannelID4, 'Field', fieldID31, 'NumPoints', 1, 'ReadKey', readAPIKey4);
data32 = thingSpeakRead(readChannelID4, 'Field', fieldID32, 'NumPoints', 1, 'ReadKey', readAPIKey4);
%% Process Data
% Set the angles. Change from degee to Radian
theta1 = deg2rad(0)
theta2 = deg2rad(5)
theta3 = deg2rad(10)
theta4 = deg2rad(15)
theta5 = deg2rad(20)
theta6 = deg2rad(25)
theta7 = deg2rad(30)
theta8 = deg2rad(35)
theta9 = deg2rad(40)
theta10 = deg2rad(45)
theta11 = deg2rad(50)
theta12 = deg2rad(55)
theta13 = deg2rad(60)
theta14 = deg2rad(65)
theta15 = deg2rad(70)
theta16 = deg2rad(75)
theta17 = deg2rad(80)
theta18 = deg2rad(85)
theta19 = deg2rad(90)
theta20 = deg2rad(95)
theta21 = deg2rad(100)
theta22 = deg2rad(105)
theta23 = deg2rad(110)
theta24 = deg2rad(115)
theta25 = deg2rad(120)
theta26 = deg2rad(125)
theta27 = deg2rad(130)
theta28 = deg2rad(135)
theta29 = deg2rad(140)
theta30 = deg2rad(145)
theta31 = deg2rad(150)
theta32 = deg2rad(155)
%Input data to rho
rho1 = data1
rho2 = data2
rho3 = data3
rho4 = data4
rho5 = data5
rho6 = data6
rho7 = data7
rho8 = data8
rho9 = data9
rho10 = data10
rho11 = data11
rho12 = data12
rho13 = data13
rho14 = data14
rho15 = data15
rho16 = data16
rho17 = data17
rho18 = data18
rho19 = data19
rho20 = data20
rho21 = data21
rho22 = data22
rho23 = data23
rho24 = data24
rho25 = data25
rho26 = data26
rho27 = data27
rho28 = data28
rho29 = data29
rho30 = data30
rho31 = data31
rho32 = data32
%% Visualize Data
polarplot(theta1,rho1,'*',theta2,rho2,'*',theta3,rho3,'*',theta3,rho3,'*',theta4,rho4,'*',theta5,rho5,'*',theta6,rho6,'*',theta7,rho7,'*',theta8,rho8,'*',theta9,rho9,'*',theta10,rho10,'*',theta11,rho11,'*',theta12,rho12,'*',theta13,rho13,'*',theta14,rho14,'*',theta15,rho15,'*',theta16,rho16,'*',theta17,rho17,'*',theta18,rho18,'*',theta19,rho19,'*',theta20,rho20,'*',theta21,rho21,'*',theta22,rho22,'*',theta23,rho23,'*',theta24,rho24,'*',theta25,rho25,'*',theta26,rho26,'*',theta27,rho27,'*',theta28,rho28,'*',theta29,rho29,'*',theta30,rho30,'*',theta31,rho31,'*',theta32,rho32,'*')
% Set the graph from 0 to 180 degree
thetalim([0 180])
按保存并运行后,它将显示如下图。
通过与实际测试环境的比较,可以看出该图也显示出类似的结果。
文件:
代码