Skip to content

custom device 'PM detector': case study

Marco Sillano edited this page Apr 11, 2023 · 29 revisions

custom device 'PM detector'

PM detector display

This device measures PM1.0, PM2.5, PM10 (μg/m³), T (°C), RH (%), AQI (0..500) and n@0.3, n@0.5, n@1.0, n@2.5, n@5.0, n@10 (number of particles). About atmospheric particulate matter see Wikipedia for info and limits and aqicn or sensor.community for actual values.

aqi

This device has a double-colored screen and can exchange data via USB. It shows, sends, and also stores the measurements.

The protocol is USB-serial, 115200:8N1.

Installation notes (Windows)

The basic application is 'PM2.5'. On Windows is required a driver for CH340.

  1. Download the 'PM2.5' software
  2. Download the 'driver for CH340'
  3. Connect the device to a USB port
  4. Select START > Device Manager - you will see an "unknown USB device" with a question mark under the USB devices
  5. Click > Update Driver - browse to the downloaded driver file
  6. Check the Port assignment after updating the driver - COM port number
  7. Launch PM2.5.EXE from the download
  8. Click the last option in the top menu to change language (English)
  9. Click the Equipment > Config menu and set the COM Port from that in the device manager and the baud rate to 115200
  10. SAVE.

protocol reverse engeenering

Using the basic application 'PM2.5' and 'SerialMon', (by DuNovo) I captured the following 'functions':

 send to device				receive from device

 {"fun":"01","sendtime":"002"}}             {"res":"1"}
 {"fun":"02","storetime":"004"}}            {"res":"2"}  
 {"fun":"03","clock":"21-03-05 20:57:24"}}  {"res":"3"}                     (YY-MM-DD hh:mm:ss)
 {"fun":"04"}}                              {"res":"10","total":"004354"}   (start dump historical data)
    (push RT/dump historical data)          {"res":"4","y":"2021","m":"03","d":"05","h":"11","min":"53","sec":"03", 
                                    "cpm2.5":"0033","cpm1.0":"0022","cpm10":"0037",   (cpm: Condensable Particulate Matter)
                                    "apm2.5":"0036","apm1.0":"0023","apm10":"0037",   (apm: Ambient Particulate Matter)
                                    "aqi":"033","t":"19.6","r":"45"}  ...             (aqi: Air Quality Index) 
                                            {"res":"0"}                     (end historical data)
 {"fun":"05","flag":"1"}}                   {"res":"5"}                     (start to push RT data)
 {"fun":"05","flag":"0"}}                   none                            (stop push RT data)                                                                             
 {"fun":"06"}}                              {"res":"6"}                     (clear internal memory)
 {"fun":"80"}}                              {"res":"80","SendInteralTime":"000002","StoreInteralTime":"000005", 
                                     "WritePoint":"000046","ReadPoint":"000000","SendInteralFlag":"000000",}
                                            {"res":"-4"}                    (error condition, e.g. no data)

notes

  • Data is like JSON data, but with some exceptions: The extra ending '}' is from 'PM23.5' app and is not mandatory (a bug) The extra ending ',' in "res":"80" is a bug.
  • The display is updated every second, the data is sent every "sendtime" sec, and stored every "storetime" sec.
  • The "particle number" is shown on display but not sent.
  • The data shown on display as PM is APM (total). Sent also CPM (Condensable PM).

Custom device definitions

In a custom device, we can choose the DPs as we want. I used the following criteria:

  • This custom device, like many tuya devices, will use atomic data points.
  • Any SET will echo the update data, the response messages {"res":"xx"} are used as ack.
  • Internal memory can be used in many ways. I have chosen to produce daily stats every hour, as well as TVR Thermostatic Valve, so I can use the same interface.
  • The complete definition of all 27 DPs is on the standard documentation.

implementation

See extra/custom PM detector. node-red

pick and execute

  • Format standard input commands from tuyaDAEMON device/capability/value to the required serial command. note: The input 'fake' commands have 2 extra fields: msg.to:<deviceId> and msg.infodp:<dp> added by CORE to speed up the process.
  • Setup: initializes the 'tuyastatus' structure.

RT data processing

  • Convert serial responses to standard Tuya answer object with multiple DPs.
  • The answer {"res":"10"...} enter the 'skipdata' mode (historical processing) and stop RT

start dump

  • Initialize required data structures
  • Sends the command {"fun":"04"} (start dump data)

historical data processing (only in the 'skipdata' mode)

  • Cumulates data to do averages.
  • The answer {"res":"0"} (end data):
    • produces the output
    • terminates the 'skipdata' mode
    • restarts RT mode

timers

  • At 00:00: clear data in device memory
  • Every hour: create historical data

startup (init)

  • Initializations with defaults: sendtime, storetime, clock, RT on

Manual commands for test.

more resources

  • patching in Fahrenheit by bsilvereagle: how to change the firmware to have temperatures in Fahrenheit instead of Celsius on the UI (thanks to rhermsen).

2023: implementation (Android)

In Android, the node-serialport does not work. See also node-serialport on Termux (Linux on Android).

After testing some APP (ServerBridgeX, ArduinoMQTT, etc...) I found a workaround to use the serial devices in Android + Termux: The USB telnet server from apkpure. Download the APK file and install it.

This application maintains a bridge between a serial COM and a Telnet port in the background. Node-red just interacts only with Telnet. Actual limit: works with only one serial device.

This simple test flow works very well:

I updated the device flow, so it can work on Windows and Android.

Clone this wiki locally