繼上期電子發(fā)燒友用戶分享的HZHY-AI300G的測(cè)評(píng)之后,本期我們又迎來(lái)了一位新用戶的測(cè)評(píng)。測(cè)評(píng)內(nèi)容如下:
終于懷著激動(dòng)的心情拿到了這塊專門(mén)為工業(yè)應(yīng)用設(shè)計(jì)的RK3588智能盒。除了主機(jī)外,還附帶了兩根天線和一個(gè)電源。
我拿到的是4G+32G的版本。
在接下來(lái)的一個(gè)月中,我會(huì)深度評(píng)測(cè)這塊開(kāi)發(fā)板,并用它完成一個(gè)完整的項(xiàng)目。項(xiàng)目分為以下幾個(gè)部分完成:
車(chē)窗智能防結(jié)冰;
后視鏡智能調(diào)整;
倒車(chē)?yán)走_(dá)方案對(duì)比;
可視無(wú)線倒車(chē)?yán)走_(dá);
車(chē)窗自動(dòng)關(guān)閉及防夾手功能;
自動(dòng)駐車(chē)及自動(dòng)取消功能。
車(chē)窗智能防結(jié)冰
要實(shí)現(xiàn)車(chē)窗智能防結(jié)冰,方法是對(duì)車(chē)內(nèi)的溫度實(shí)時(shí)監(jiān)控,當(dāng)車(chē)內(nèi)外溫差過(guò)大時(shí)啟動(dòng)風(fēng)扇讓空氣流通,降低溫差。
那么實(shí)現(xiàn)項(xiàng)目的本質(zhì)就是,如何通過(guò)MCU檢測(cè)到溫度變化,并實(shí)現(xiàn)與HZHY-AI300G智能盒的雙向通訊,不但可以把溫度上報(bào)給HZHY-AI300G智能盒,同時(shí)當(dāng)HZHY-AI300G智能盒下發(fā)通風(fēng)指令時(shí),MCU也可以正確執(zhí)行。
我搭了一個(gè)簡(jiǎn)單的電路來(lái)進(jìn)行測(cè)試。其中使用BMP280作為溫度傳感器進(jìn)行數(shù)據(jù)測(cè)量,而用一個(gè)小LED作為執(zhí)行器,用來(lái)代表同風(fēng)扇。MCU使用的是ESP32-S3開(kāi)發(fā)板,開(kāi)發(fā)環(huán)境方便起見(jiàn)使用的是Circuitpython。
Circuitpython開(kāi)發(fā)環(huán)境準(zhǔn)備這一步我就直接跳過(guò),因?yàn)楹臀覀冊(cè)u(píng)測(cè)的HZHY-AI300G智能盒無(wú)關(guān)。
我們通過(guò)兩個(gè)MQTT Topic來(lái)進(jìn)行通信。第一個(gè)Topic是test/topic,這個(gè)topic用來(lái)從mcu上報(bào)傳感器數(shù)據(jù)到HZHY-AI300G智能盒;另一個(gè)topic是test/cmd,用來(lái)讓HZHY-AI300G智能盒下發(fā)指令給MCU。
MCU的主要功能為,測(cè)量溫度并每秒鐘上報(bào);如果接收到HZHY-AI300G智能盒下發(fā)的信息則按指令開(kāi)關(guān)LED。具體代碼如下,注意要把MQTT broker的地址改為HZHY-AI300G智能盒的IP:
import time
import wifi
import socketpool
import ssl
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import json
# Define callback methods which are called when events occur
def connect(client, userdata, flags, rc):
# This function will be called when the client is connected
# successfully to the broker.
print("Connected to MQTT Broker!")
print("Flags: {0}\\n RC: {1}".format(flags, rc))
def disconnect(client, userdata, rc):
# This method is called when the client disconnects
# from the broker.
print("Disconnected from MQTT Broker!")
def subscribe(client, userdata, topic, granted_qos):
# This method is called when the client subscribes to a new feed.
print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))
def unsubscribe(client, userdata, topic, pid):
# This method is called when the client unsubscribes from a feed.
print("Unsubscribed from {0} with PID {1}".format(topic, pid))
def publish(client, userdata, topic, pid):
# This method is called when the client publishes data to a feed.
print("Published to {0} with PID {1}".format(topic, pid))
def message(client, topic, message):
# This method is called when a topic the client is subscribed to
# has a new message.
print(f"New message on topic {topic}: {message}")
pool = socketpool.SocketPool(wifi.radio)
ssl_context = ssl.create_default_context()
# Set up a MiniMQTT Client
# NOTE: We'll need to connect insecurely for ethernet configurations.
mqtt_client = MQTT.MQTT(
broker="192.168.x.x",
port=1883,
username="",
password="",
is_ssl=False,
socket_pool=pool,
ssl_context=ssl_context,
# Connect callback handlers to client
mqtt_client.on_connect = connect
mqtt_client.on_disconnect = disconnect
mqtt_client.on_subscribe = subscribe
mqtt_client.on_unsubscribe = unsubscribe
mqtt_client.on_publish = publish
mqtt_client.on_message = message
def func():
pass
# MQTT Topic
# Use this topic if you'd like to connect to a standard MQTT broker
mqtt_topic = "test/topic"
print("Attempting to connect to %s" % mqtt_client.broker)
try:
mqtt_client.disconnect()
except:
pass
mqtt_client.connect()
# print("Subscribing to %s" % mqtt_topic)
# mqtt_client.subscribe(mqtt_topic)
# print("Publishing to %s" % mqtt_topic)
# mqtt_client.publish(mqtt_topic, "Hello Broker!")
# print("Unsubscribing from %s" % mqtt_topic)
# mqtt_client.unsubscribe(mqtt_topic)
# print("Disconnecting from %s" % mqtt_client.broker)
# mqtt_client.disconnect()
import board
import busio
i2c = busio.I2C(scl=board.GPIO7, sda=board.GPIO6)
assert i2c.try_lock()
print(i2c.scan())
i2c.unlock()
# 溫度測(cè)試
if 1:
import adafruit_bmp280
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, address=0x76)
bmp280.sea_level_pressure = 1013.25
import digitalio
led = digitalio.DigitalInOut(board.GPIO15)
led.direction = digitalio.Direction.OUTPUT
led.value = True
mqtt_client.subscribe("test/cmd")
def func(client, topic, message):
led.value = int(message)
print(f"New message on topic {topic}: {message}")
mqtt_client.on_message = func
while True:
# Poll the message queue
mqtt_client.loop(timeout=1)
msg = {"Temperature": bmp280.temperature}
# Send a new message
mqtt_client.publish(mqtt_topic, json.dumps(msg))
print(msg)
time.sleep(1)
接線方式:
SCL: 7
SDA: 6
LED: 15
HZHY-AI300G智能盒的代碼我們可以基于上一篇MQTT測(cè)試代碼修改。兩邊信息傳遞使用的json文本,這是一種非常有效的指令及數(shù)據(jù)傳遞方式。代碼如下,如果檢測(cè)到上報(bào)的溫度大于31度,則會(huì)要求開(kāi)啟LED,否則則熄滅LED。
from paho.mqtt import client as mqtt_client
import json
broker = '127.0.0.1'
port = 1883
topic = "test/topic"
client_id = "receiver"
# username = 'user'
# password = 'password'
def connect_mqtt():
def on_connect(client, userdata, flags, rc, properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\\n", rc)
# Set Connecting Client ID
client = mqtt_client.Client(client_id=client_id, callback_api_version=mqtt_client.CallbackAPIVersion.VERSION2)
# client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
my_dict = json.loads(msg.payload.decode())
if 'Temperature' in my_dict:
temp = int(my_dict["Temperature"])
if temp > 31:
client.publish("test/cmd", "0")
print("Too Hot!!!")
else:
client.publish("test/cmd", "1")
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()
同時(shí)運(yùn)行兩邊的代碼,可以看到智能盒打印出了收到的溫度信息,當(dāng)溫度高于31度時(shí),打印對(duì)應(yīng)文本,并點(diǎn)亮MCU上的LED。
后視鏡智能調(diào)整
接下來(lái)我們來(lái)看一下執(zhí)行器的控制。譬如后視鏡調(diào)整,警報(bào)驅(qū)動(dòng),窗機(jī)啟停等功能,實(shí)際上都是HZHY-AI300G智能盒向MCU下發(fā)指令控制執(zhí)行器的過(guò)程。
我們使用一個(gè)舵機(jī)作為執(zhí)行器,依然先完成MCU部分的增量代碼。代碼內(nèi)容非常簡(jiǎn)單,把接收到的舵機(jī)角度直接傳遞給舵機(jī)即可。
# 舵機(jī)測(cè)試
if 1:
import pwmio
from adafruit_motor import servo
pwm = pwmio.PWMOut(board.GPIO14, frequency=50)
s1 = servo.Servo(pwm, min_pulse=500, max_pulse=2500)
mqtt_client.subscribe("test/cmd")
def func(client, topic, message):
print(f"New message on topic {topic}: {message}")
s1.angle = int(message)
msg = {"angle": int(message)}
mqtt_client.publish(mqtt_topic, json.dumps(msg))
mqtt_client.on_message = func
while True:
# Poll the message queue
mqtt_client.loop(timeout=1)
舵機(jī)記得要使用5V供電,接在14號(hào)引腳上。
HZHY-AI300G智能盒由于是單純的下發(fā)指令,因此這次代碼我們可以基于一開(kāi)始的發(fā)送代碼進(jìn)行修改。出于測(cè)試目的,我們讓HZHY-AI300G智能盒下發(fā)每間隔1S旋轉(zhuǎn)舵機(jī)180度的指令:
import time
from paho.mqtt import client as mqtt_client
broker = '127.0.0.1'
port = 1883
topic = "test/topic"
client_id = "sender"
# username = 'user'
# password = 'password'
def connect_mqtt():
def on_connect(client, userdata, flags, rc, properties):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\\n", rc)
# Set Connecting Client ID
client = mqtt_client.Client(client_id=client_id, callback_api_version=mqtt_client.CallbackAPIVersion.VERSION2)
# client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(1)
msg = f"messages: {msg_count}"
result = client.publish(topic, msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
def run():
client = connect_mqtt()
# client.loop_start()
# publish(client)
# client.loop_stop()
# 舵機(jī)測(cè)試
if 1:
while True:
client.publish("test/cmd", "0")
time.sleep(1)
client.publish("test/cmd", "180")
time.sleep(1)
if __name__ == '__main__':
run()
兩邊代碼同時(shí)運(yùn)行,我們就可以觀察到舵機(jī)按照要求運(yùn)動(dòng)起來(lái)。觀察MCU的控制臺(tái)輸出,可以看到打印出了接收到的數(shù)據(jù)信息:
而如果我們同步運(yùn)行HZHY-AI300G智能盒上的接收代碼,也可以看到對(duì)應(yīng)的反饋信息:
倒車(chē)?yán)走_(dá)方案對(duì)比
倒車(chē)?yán)走_(dá)兩種方案的驗(yàn)證,同樣也是使用MCU獲取兩個(gè)傳感器得到的信號(hào),并把數(shù)據(jù)一起上報(bào)給HZHY-AI300G智能盒。
MCU的代碼可以基于之前的代碼上做增量修改,因?yàn)镸QTT通訊部份都是一樣的。增加如下部分就可以實(shí)現(xiàn)讀取兩個(gè)距離傳感器的數(shù)據(jù),并上報(bào)給HZHY-AI300G智能盒:
# 測(cè)距測(cè)試
if 0:
import adafruit_vl53l0x
vl53 = adafruit_vl53l0x.VL53L0X(i2c)
import adafruit_us100
# Connect TX to TX, RX to RX
uart = busio.UART(board.GPIO4, board.GPIO5, baudrate=9600)
sonar = adafruit_us100.US100(uart)
while True:
# Poll the message queue
mqtt_client.loop(timeout=1)
msg = {"vl53l0x": vl53.range, "sonar": int(sonar.distance * 10)}
# Send a new message
mqtt_client.publish(mqtt_topic, json.dumps(msg))
print(msg)
time.sleep(1)
HZHY-AI300G智能盒部分的代碼可以不用做修改。兩邊同時(shí)運(yùn)行,我們可以看到HZHY-AI300G智能盒有如下輸出:
兩個(gè)傳感器都可以測(cè)量距離,但是原理不同。一個(gè)是基于超聲波,使用聲納的方式來(lái)測(cè)距;另外一個(gè)是基于激光,測(cè)量方式也和聲納類似,但在激光上被叫做TOF。
兩者很難說(shuō)優(yōu)略,與其說(shuō)是替代的關(guān)系,不如說(shuō)是互補(bǔ)的關(guān)系。因?yàn)榧す獠ㄩL(zhǎng)遠(yuǎn)小于超聲波,因此超聲波測(cè)量范圍會(huì)比較大,但是精度稍低;而激光精度會(huì)高一些,但是范圍比較小。因此兩種傳感器搭配使用的話會(huì)獲得更好的結(jié)果。
我們誠(chéng)摯感謝這位發(fā)燒友對(duì)HZHY-AI300G智能盒的熱情支持和積極反饋。內(nèi)容會(huì)持續(xù)更新,歡迎大家前往發(fā)燒友平臺(tái)查看。若您也愿意分享使用體驗(yàn),請(qǐng)?jiān)谄脚_(tái)上發(fā)布,我們將贈(zèng)送一份精美禮品,以表謝意!
-
輔助系統(tǒng)
+關(guān)注
關(guān)注
0文章
57瀏覽量
11624 -
駐車(chē)輔助
+關(guān)注
關(guān)注
0文章
2瀏覽量
7429 -
智能盒子
+關(guān)注
關(guān)注
0文章
12瀏覽量
3032 -
RK3588
+關(guān)注
關(guān)注
6文章
303瀏覽量
4144
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論