วันอาทิตย์ที่ 17 พฤศจิกายน พ.ศ. 2562

Module:Environment:Dust

Dust Sensor Module

    โมดูลตรวจจับฝุ่น ทำการประมาณอนุภาคเล็กๆต่อปริมาตรอากาศ รุ่นที่ราคาถูกหน่อยใช้หลักการกระเจิงของแสง  อนุภาคขนาดต่างๆจะมีการกระเจิงแตกต่างกัน เซนเซอร์จะมีพัดลมดูดอากาศปริมาณน้อยเข้าไปผ่านตัววัด ดังนั้นค่าอาจจะไม่ได้สะท้อนความเป็นจริงของอากาศบริเวณนั้น นึกถึงน้ำขุ่นบริเวณต่างๆมันฟุ้งไม่เท่ากันอากาศก็เหมือนกัน จากประสบการณ์ค่าที่วัดได้จะแกว่งมาก เซนเซอร์สองตัววางติดกันค่าที่วัดได้อาจจะต่างกันถึง 10 หน่วยเลยทีเดียว แต่ค่าที่วัดโดยเฉลี่ยถ้าวัดถี่หน่อยทั้งวันก็จะใกล้เคียงกัน 

Plantower PMS x003

  รุ่น PMS1003, PMS3003, PMS5003, PMS6003, PMS7003 ใช้งานง่านผ่าน Serial Port ถือเป็นรุ่นยอดนิยมหาซื้อง่าย วิธีใช้งานเหมือนกัน ค่ามีการปรับเทียบจากโรงงานแล้ว(calibrate)  มีรุ่นที่ใช้เป็น I2C ด้วยแต่หาซื้อยากผมยังไม่เคยใช้ และมีรุ่นพิเศษที่เป็นรหัสลงท้าย ST จะอ่านอุณหภูมิ ความชื้น และ Formaldehyde ได้แต่หาซื้อยากราคาแพงรุ่นใหม่กว่าไม่ได้ต่างกันแต่มีขนาดเล็กลงมาก







  เซนเซอร์ต้องการไฟเลี้ยง 5V  แต่ขา RX TX ใช้ 3.3v ที่ผมเคยใช้คือ PMS7003 และ PMS5003 เป็นรุ่นยอดนิยมมี 6 สายที่ใช้งานได้
 ใช้ 4 เส้น(5v,GND,RX,TX) ก็ทำงานได้  
  • +5V - ไฟเลี้ยงเซนเซอร์
  •  0V  - Ground
  • TX  ส่งข้อมูลให้ไปต่อที่ RX ของไมโครคอนโทรลเลอร์
  • RX  รับข้อมูลให้ไปต่อที่ TX ของไมโครคอนโทรลเลอร์
  • Set ปกติปล่อยลอย(ไม่ต้องต่อ) หรือ ต่อวงจร Pullup 10K กับ GPIO ให้ High เพื่อ Wakeup หรือ Lowเพื่อ Sleep
  • Reset - ปกติปล่อยลอย(ไม่ต้องต่อ) หรือต่อ Pullup 10K กับ GPIO ถ้า ส่งลอจิก Low เพื่อ reset ตัวเซนเซอร์
ภาพล่างเป็นตัวอย่างขาของ PMS5003 จะมีสายที่มีหัวต่อสองด้านมา ผมตัดแล้วต่อวงจรหรือเข้าหัวเพื่อเชื่อมกับอุปกรณ์
 แนะนำให้ดูจาก DataSheet ของแต่ละรุ่นจะได้ต่อสายไม่พลาด
การใช้งานแบบทั่วอ่านค่าต่อแค่ 5V,Ground และ TX มันจะส่งค่า PM10 PM2.5 และ PM1 มาเรื่อยๆ
ถ้าจะรับคำสั่งเพื่อเซ็ตค่าก็ต้องต่อ RX กับ TX ของ MCU ทุกคำสั่งหรือข้อมูลจะขึ้นต้นด้วย 2 ไบต์แรก x42, x4D มีโหมดและคำสั่งดังนี้(ไปอ่าน Data Sheet จะมีอธิบาย)  ตอนส่งคำสั่งก็จะมีการตอบสนองกลับมา
Activate passive mode:
- request: 42 4D E1 00 00 01 70
- response: 42 4D 00 04 E1 00 01 74 

Activate active mode:
- request: 42 4D E1 00 01 01 71
- response: 42 4D 00 04 E1 01 01 75

Initiate measurement in passive mode:
- request: 42 4D E2 00 00 01 71
- response: one data telegram

Send to sleep:
- request: 42 4D E4 00 00 01 73
- response: 42 4D 00 04 E4 00 01 77 

Wake-up:
- request: 42 4D E4 00 01 01 74
- response: none


โดยสรุปจ่ายไฟจะเป็นโหมด Active จะมี respond เป็นค่าข้อมูลฝุ่นมาเรื่อยๆ ไม่หยุด ถ้าค่าฝุ่นมีการเปลี่ยนแปลงมากก็จะส่งถี่หน่อย ถ้าจะเปลี่ยนโหมดต้องส่งคำสั่ง เช่นส่งคำสั่งเพื่อเปลี่ยนเป็น Passive ต่างจาก Active ตรงที่ ถ้าต้องการอ่านค่าก็ต้อง ส่งคำสั่งเพื่อขอค่า  เซนเซอร์มีอายุการใช้งาน(ประมาณ 1-3 ปี) เราควรให้มัน Sleep เป็นระยะเพื่อยืดอายุการทำงานของเซนเซอร์ ถ้าจะอ่านค่าอีกทีต้อง Wakeup ล่วงหน้า 30 วินาทีแล้วค่อยเริ่มอ่านค่า จากประสบการณ์ที่เคยใช้จะมีโอกาสที่ส่งคำสั่ง sleep แล้วเซนเซอร์ไม่ยอม Sleep  แนะนำให้ใช้ขา set เพื่อควบคุมการ wakeup/sleep เนื่องจากเป็นเซนเซอร์ที่ใช้ภายในอาคาร ถ้าใช้ภายนอก ใช้ในครัว หรือในห้องน้ำ อาจจะต้องมีการออกแบบตัวป้องกันที่ดีพอเพราะฝุ่นหรือละอองน้ำอนุภาคใหญ่จะเข้าไปในตัวเซนเซอร์ได้ 
    สามารถใช้งานกับอุปกรณ์ทุกตัวที่รองรับการสื่อสารผ่านซีเรียลพอร์ต (ESP32,ESP8266,Raspberry PI,คอมพิวเตอร์ ฯลฯ) สามารถใช้ USB2Serial เพื่อใช้ต่อกับคอมพิวเตอร์ได้(PC/Mac ดูในภาพ) 

ESP32/ESP8266 ใช้ง่ายแค่ให้ติดตั้งไลบารี่ PMS เพิ่มจาก Library Manager แนะนำให้ดูตัวอย่างที่มากับ Library หรือจะอ่านค่าจาก Serial แล้วดึงออกมาเองก็ได้

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
1213
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//ESP32: อ่านค่าจากเซนเซอร์วัดฝุ่น PMS1003, PMS3003, PMS5003, PMS6003, PMS7003
//
#include "PMS.h"  // PMS Library by Mariusz Kachi Version 1.1.0
PMS pms(Serial2); // ต่อเซนเซอร์ที่ Serial2
PMS::DATA data;
#define RXD2 13 // ต่อ TX ของเซนเซอร์
#define TXD2 12 // ต่อ RX ของเซนเซอร์
void setup()
{
  Serial.begin(9600);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);   
  pms.passiveMode();    // ใช้โหมด passive mode ต้อง requestRead 
}
void loop()
{
  Serial.println("Waking up, wait 30 seconds for stable readings...");
  pms.wakeUp(); //ปลุกเซนเซอร์ขึ้นมาทำงาน
  delay(30000);
  Serial.println("Send read request...");
  pms.requestRead(); //ขอข้อมูล จากเซนเซอร์ ของโหมด passive
  Serial.println("Reading data...");
  if (pms.readUntil(data))
  {
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_1_0);

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data.PM_AE_UG_2_5);

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_10_0);
  }
  else
  {
    Serial.println("No data.");
  }
  Serial.println("Going to sleep for 60 seconds.");
  pms.sleep(); //พักการทำงานของเซนเซอร์
  delay(60000);
}

สำหรับ Raspberry PI  ต้องเปิดใช้งาน Serial Port ก่อน สำหรับคอมพิวเตอร์(PC/Mac) ให้ต่อผ่าน USB to Serial Adapter มีโค้ดตัวอย่างหาได้ง่ายส่วนใหญ่เป็น Python ผมเขียนไม่เป็นเลยหาที่เป็น JavaScript(Node.js) มี Library ให้ใช้งานแต่ปัญหาเยอะเหมือนกัน ยังมีไลบารีพื้นฐาน  Node SerialPort ซึ่งจำเป็นต้องคอมไฟล์โค้ดด้วย สำหรับ Windows ต้องติดตั้ง C++ build tools ก่อน เนื่องจาก Library สำหรับอ่านค่าฝุ่นมีปัญหาและไม่ได้อัปเดต ผมเลยเขียนแบบง่ายๆขึ้นมาเองใช้แค่ Node SerialPort แก้ค่า COM3 เป็นค่าของเครื่องที่ใช้คร้บ สำหรับ Linux จะเป็นหน้าตาประมาณนี้ /dev/ttyAMA0


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
var SerialPort = require("serialport")
var serialPort = new SerialPort("COM3", {
	baudRate: 9600,
})
function processData(info) {
	var s = ""
	for (var j = 0; j < info.length; j++) {
		s = s + ":" + info[j].toString(16)
	}
	console.log("Data", info)
	var temp2, tem1, pm1, pm2_5, pm10, n03, n05, n1, n25, n5, n10
	pm1 = (info[4] << 8) | info[5]
	pm2_5 = (info[6] << 8) | info[7]
	pm10 = (info[8] << 8) | info[9]
	console.log("pm1 :" + pm1 + ", pm2.5 :" + pm2_5 + ", pm10 :" + pm10)

	pm1 = (info[10] << 8) | info[11]
	pm2_5 = (info[12] << 8) | info[13]
	pm10 = (info[14] << 8) | info[15]
	console.log("pm1a:" + pm1 + ", pm2.5a:" + pm2_5 + ", pm10a:" + pm10)

	n03 = (info[16] << 8) | info[17]
	n05 = (info[18] << 8) | info[19]
	n1 = (info[20] << 8) | info[21]
	n25 = (info[22] << 8) | info[23]
	n5 = (info[24] << 8) | info[25]
	n10 = (info[26] << 8) | info[27]

	console.log("n03:" + n03 + ",n05:" + n05 + ",n1:" + n1 + 
                ",n25:" + n25 + ",n5:" + n5 + ",n10:" + n10)
}

function init() {
	serialPort.on("open", function () {
		// sleep  0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73
		// wakeup 0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74
		// active 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71
		// passive 0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70
		// request read 0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71
		serialPort.write(Buffer.from([0x42, 0x4d, 0xe4, 0x00, 0x01, 0x01
                    , 0x74, 0x42, 0x4d, 0xe1, 0x00, 0x01, 0x01, 0x71]), 
                function (err) {
			if (err) {
				return console.log("Error on write : ", err.message)
			}
			console.log("message written")
		})
		var sign = 0
		counter = 0
		a = new Array(32).fill(0)

		serialPort.on("data", function (data) {
			//console.log('data received: ' + data);
			//console.log( data[0].toString() + ":"+ data.byteLength );
			for (var i = 0; i < data.byteLength; i++) {
				if (counter == 0 && data[0] != 0x42) return
				if (counter == 1 && data[i] != 0x4d) {
					counter = 0
					return
				}
				a[counter] = data[i]
				counter++
				if (counter == a.length) {
					counter = 0
					sign = 1
				}
				//process array
				if (sign) {
					sign = 0
					processData(a)
				}
			}
		})
	})
}
init()

ผมแก้ไข Library จากของเดิมใหม่แต่มีหลายไฟล์ ไว้ขึ้น Git แล้วจะมาอัปเดตที่นี้ครับ

เพิ่มเติม


Shinyei Model PPD42NS Dust Sensor

เป็นเซนเซอร์แบบอนาล็อก คิดว่าน่าจะต้องมีเครื่องวัดที่เที่ยงตรงอีกตัวแล้วทำการ calibrate  ผมมีอยู่ตัวหนึ่งถ้ามีเวลาจะเอามาลองใช้ ตอนนี้ให้ดูตัวอย่างในลิงค์นี้ จะต้องต่อ Voltage Devider เพื่อให้ใช้กับ 3.3โวลต์ได้



ข้อมูลทั่วไป



ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Module:Control:IFR 520

MOSFET Module  สวิตซ์ปิดเปิดไฟเหมือน Relay แต่เป็น Solid state (ไม่มีส่วนที่เคลื่อนไหว) มันทำงานที่ความถี่สูงได้เหมาะกับเอาไปใช้งาน PWM ...