野火科技
直播中

jf_25674040

2年用户 108经验值
擅长:可编程逻辑 接口/总线/驱动 控制/MCU MEMS/传感技术
私信 关注
[经验]

【鲁班猫创意氛围赛】环境甲醛浓度的检测和MQTT显示

前言

感谢野火提供的鲁班猫网口板卡,同时感谢“华仔stm32”提供的MQTT服务器软件EMQX。

项目材料

  • 鲁班猫卡片电脑
  • 检测甲醛传感器,ZE08-CH2O
  • 鲁班猫ubuntu20.04固件

连接甲醛传感器

  • 选择5V的电源供电并选用UART4作为通讯口
    image.png

  • /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/目录下找到ttyS4ttyS8ttyS9
    image.png

  • 硬件连接如下
    微信图片_20230420175057.jpg

    安装软件环境

    • 安装emqx

      1. 增加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.

      2. 安装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.

      3. 启动emqx

        cat@lubancat:~/serial$ sudo systemctl start emqx.service

      • 安装pyserial
        image.png
      • 安装crc
        image.png

      项目代码

      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)
                            #print(float_formaldehyde)
                        time.sleep(0.001)

mqtt数据显示

image.png

更多回帖

发帖
×
20
完善资料,
赚取积分