前言
感谢野火提供的鲁班猫网口板卡,同时感谢“华仔stm32”提供的MQTT服务器软件EMQX。
项目材料
- 鲁班猫卡片电脑
- 检测甲醛传感器,ZE08-CH2O
- 鲁班猫ubuntu20.04固件
连接甲醛传感器
-
选择5V的电源供电并选用UART4作为通讯口
-
在/boot/uEnv/uEnvLubanCatZN.txt 取消dtoverlay=/dtb/overlay/rk356x-lubancat-uart4-m1-overlay.dtbo,dtoverlay=/dtb/overlay/rk356x-lubancat-uart8-m0-overlay.dtbo,dtoverlay=/dtb/overlay/rk356x-lubancat-uart9-m1-overlay.dtbo注释。重启鲁班猫电脑卡片,可以在/dev/ 目录下找到ttyS4 、ttyS8 、ttyS9 。
-
硬件连接如下
安装软件环境
-
安装emqx
-
增加emqx 的apt源
cat@lubancat:~/serial$ curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
Detected operating system as Ubuntu/focal.
Checking for curl...
Detected curl...
Checking for gpg...
Detected gpg...
Running apt-get update... done.
Installing apt-transport-https... done.
Installing /etc/apt/sources.list.d/emqx_emqx.list...done.
Importing gpg key... done.
Running apt-get update...
done.
-
安装emqx
cat@lubancat:~/serial$ sudo apt install emqx
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
emqx
0 upgraded, 1 newly installed, 0 to remove and 37 not upgraded.
Need to get 38.3 MB of archives.
After this operation, 127 MB of additional disk space will be used.
Get:1 https://packages.emqx.com/emqx/emqx/ubuntu focal/main arm64 emqx arm64 5.0.23 [38.3 MB]
Fetched 38.3 MB in 28s (1362 kB/s)
Selecting previously unselected package emqx.
(Reading database ... 104851 files and directories currently installed.)
Preparing to unpack .../archives/emqx_5.0.23_arm64.deb ...
Unpacking emqx (5.0.23) ...
Setting up emqx (5.0.23) ...
Adding group emqx' (GID 124) ... Done. Adding system user emqx' (UID 113) ...
Adding new user emqx' (UID 113) with group emqx' ...
Not creating home directory `/var/lib/emqx'.
● lubancat
State: degraded
Jobs: 0 queued
Failed: 2 units
Since: Thu 2023-04-20 14:44:34 CST; 1h 32min ago
CGroup: /
├─user.slice
│ └─user-1000.slice
│ ├─user@1000.service …
│ │ └─init.scope
│ │ ├─431 /lib/systemd/systemd --user
│ │ └─435 (sd-pam)
│ ├─session-c14.scope
│ │ ├─ 324 /bin/login -p --
│ │ ├─22463 -bash
│ │ └─22531 python3 ./ze08_ch2o.py
│ ├─session-c1.scope
│ │ ├─ 421 sshd: cat [priv]
│ │ ├─ 507 sshd: cat@pts/0
│ │ ├─ 510 -bash
│ │ ├─23492 sudo apt install emqx
│ │ ├─23497 apt install emqx
│ │ ├─23651 /usr/bin/dpkg --status-fd 50 --configure --pending
│ │ ├─23652 /bin/sh /var/lib/dpkg/info/emqx.postinst configure
│ │ └─23706 systemctl status --no-pager
│ └─session-c15.scope
│ ├─23517 sshd: cat [priv]
│ ├─23592 sshd: cat@pts/1
│ ├─23595 -bash
│ └─23610 htop
├─init.scope
│ └─1 /sbin/init
└─system.slice
├─systemd-udevd.service
│ └─158 /lib/systemd/systemd-udevd
├─cron.service
│ └─254 /usr/sbin/cron -f
├─polkit.service
│ └─262 /usr/lib/policykit-1/polkitd --no-debug
├─networkd-dispatcher.service
│ └─260 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
├─wpa_supplicant.service
│ └─269 /sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
├─systemd-journald.service
│ └─132 /lib/systemd/systemd-journald
├─ssh.service
│ └─332 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─NetworkManager.service
│ └─257 /usr/sbin/NetworkManager --no-daemon
├─vsftpd.service
│ └─321 /usr/sbin/vsftpd /etc/vsftpd.conf
├─rsyslog.service
│ └─267 /usr/sbin/rsyslogd -n -iNONE
├─cups-browsed.service
│ └─289 /usr/sbin/cups-browsed
├─cups.service
│ └─255 /usr/sbin/cupsd -l
├─systemd-resolved.service
│ └─226 /lib/systemd/systemd-resolved
├─ntp.service
│ └─330 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 102:103
├─dbus.service
│ └─256 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
├─system-getty.slice
│ └─getty@tty1.service
│ └─323 /sbin/agetty -o -p -- \u --noclear tty1 linux
├─avahi-daemon.service
│ ├─253 avahi-daemon: running [lubancat.local]
│ └─270 avahi-daemon: chroot helper
└─systemd-logind.service
└─268 /lib/systemd/systemd-logind
Created symlink /etc/systemd/system/multi-user.target.wants/emqx.service → /lib/systemd/system/emqx.service.
-
启动emqx
cat@lubancat:~/serial$ sudo systemctl start emqx.service
- 安装
pyserial
- 安装
crc
项目代码
class MyMqtt(object):
def __init__(self, ip, username):
self.client = mqtt.Client()
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.client.on_disconnect = self.on_disconnect
self.client.connect(ip, 1883, 60)
self.client.username_pw_set(username)
self.client.loop_start()
self.onConnect = False
def on_connect(self, client, userdata, flags, rc):
print("Connected with result code "+str(rc))
if rc == 0:
self.onConnect = True
def on_disconnect(self, client, userdata, rc):
if rc != 0:
self.onConnect = False
def on_message(self, client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
def publish(self, value):
if self.onConnect:
msg = '{"formaldehyde": ' +str(value) + ' }'
self.client.publish(topic="v1/devices/me/telemetry", payload=msg)
class MySerial(object):
def __init__(self):
self.ser = None
def get_port_list(self):
port_list = list(serial.tools.list_ports.comports())
return port_list
def open_serial_port(self, port, baud):
try:
self.ser = serial.Serial(port, baud, timeout=0.3, interCharTimeout=0.05)
except Exception as e:
self.ser = None
raise Exception(e)
def close_serial_port(self):
if self.ser == None:
raise Exception("no selected serial")
try:
self.ser.close()
self.ser = None
except Exception as e:
raise Exception(e)
def read(self):
if self.ser == None:
raise Exception("no selected serial")
try:
time.sleep(0.001)
return self.ser.read(self.ser.in_waiting)
except Exception as e:
raise Exception(e)
class ze08_ch20(object):
def __init__(self) -> None:
self.tools = MyTools()
self.serial = MySerial()
self.interface = MyMqtt(MQTT_IP, MQTT_USERNAME)
self.serial.open_serial_port('/dev/ttyS4', 9600)
self.recv_thread_ = threading.Thread(target=self.recv_thread)
self.recv_thread_.start()
def calc_checksum(self, bytes_value):
checksum = 0
for byte_ in bytes_value:
checksum += byte_
checksum = checksum % (0xff + 1)
if checksum == 0xff:
return True
return False
def recv_thread(self):
recv_buffer = bytes()
while True:
try:
recv_buffer += self.serial.read()
except Exception as e:
print(str(e))
if len(recv_buffer) < 9:
time.sleep(0.01)
continue
else:
if recv_buffer[0] != 0xff:
recv_buffer = recv_buffer[1:]
else:
if len(recv_buffer) >= 9:
phase_buffer = recv_buffer[:9]
recv_buffer = recv_buffer[9:]
if self.calc_checksum(phase_buffer) == True:
int_formaldehyde = int.from_bytes(phase_buffer[4:6], byteorder='big')
float_formaldehyde = int_formaldehyde /1000.0 *1.25
self.interface.publish(float_formaldehyde)
time.sleep(0.001)
mqtt数据显示
|