ไฟเตือนลมยางโชว์... แต่ไม่รู้ล้อไหน? (จุดเริ่มต้นของโปรเจกต์)
ภรรยาของผมขับรถ Toyota Auris Hybrid ครับ แล้ววันดีคืนดีไฟเตือนระบบวัดแรงดันลมยาง (TPMS) บนหน้าปัดก็สว่างขึ้นมา ปัญหาคือรถมันบอกแค่นั้นแหละครับ! ไม่ยอมบอกว่าล้อไหนอ่อน หรือเกิดอะไรขึ้น ผมเลยต้องไปไล่เช็คลมยางทีละล้อแล้วรีเซ็ตระบบใหม่ พอเอารถเข้าศูนย์ ช่างก็บอกแค่ว่า "ลมยางล้อใดล้อหนึ่งน่าจะอ่อน" (ซึ่งผมแอบเถียงในใจเพราะเพิ่งเช็คมา) ถึงแม้ปัญหาจะหายไป แต่มันก็คาใจอยู่ดีครับ
จนกระทั่งวันนึง ผมเอาอุปกรณ์ดักฟังคลื่นวิทยุ (RTL2832U dongle SDR) และซอฟต์แวร์ RTL_433 มาลองแสกนคลื่น 433MHz เล่นๆ ปรากฏว่าดันไปเจอข้อความข้อมูลลมยางของรถ Toyota เด้งขึ้นมา! สรุปคือมันมาจากรถของภรรยาผมที่จอดอยู่หน้าบ้านนี่เอง ผมเลยปิ๊งไอเดียว่า เราน่าจะใช้ Arduino มาดักจับข้อมูลพวกนี้แล้วสร้างจอแสดงผลไว้ในรถได้เลย โดยไม่ต้องไปยุ่งกับพอร์ต OBD2 ของรถเลยด้วยซ้ำ
เกี่ยวกับระบบ TPMS และข้อควรระวัง
ผู้ผลิตรถยนต์แต่ละค่ายใช้ระบบ TPMS ไม่เหมือนกันนะครับ โปรเจกต์นี้ถูกออกแบบมาเพื่อ Toyota Auris Hybrid โดยเฉพาะ (แต่อาจจะใช้กับ Toyota รุ่นอื่นได้) ถ้ารถคุณเป็นยี่ห้ออื่น ต้องเช็คให้ชัวร์ก่อนว่าใช้เซ็นเซอร์แบบไหน ไม่งั้นอาจจะทำแล้วไม่เวิร์คนะครับ
- เซ็นเซอร์ของ Auris จะส่งสัญญาณที่คลื่น 433MHz ประมาณทุกๆ 90 วินาที (เพื่อกันสัญญาณชนกัน)
- ข้อมูลที่ส่งมาจะมี: รหัสเซ็นเซอร์ (Sensor ID), แรงดันลมยาง, อุณหภูมิลมยาง, และรหัสตรวจสอบ (Checksum)
- เราจะไม่รู้ว่า ID ไหนคือล้อไหน ต้องใช้วิธีลองปล่อยลมยางทีละล้อเพื่อจด ID เอาเองครับ
- สัญญาณจากล้อไม่ได้แรงมาก ต้องอยู่ใกล้ๆ รถระยะ 2-3 เมตรถึงจะรับสัญญาณได้เสถียร
-
หมายเหตุ: เซ็นเซอร์บางรุ่นจะไม่ส่งสัญญาณตอนรถจอดนิ่งนะครับ จะส่งเฉพาะตอนล้อหมุน หรือตอนที่ลมยางเปลี่ยนกะทันหันเท่านั้น
คำขอบคุณ (Acknowledgements)
ขอขอบคุณทีมพัฒนา RTL_433 (โดยเฉพาะ Christian W. Zuckschwerdt) และ 'shcm' จากเว็บบอร์ด RAV4 Drivers Club ที่ช่วยให้ผมเข้าใจโปรโตคอล 433MHz และขอบคุณ Steven Andrews สำหรับความช่วยเหลือเรื่องการเพิ่มเซ็นเซอร์รถรุ่นอื่นๆ เข้ามาในโค้ดครับ
โปรเจกต์นี้มีการใช้ไลบรารีจอแสดงผลหลายตัว ได้แก่ Adafruit_SSD1306 (ไม่ได้ใช้ในตอนท้ายเพราะแรมไม่พอ), SSD1306Ascii ของ Bill Greiman, Adafruit_ST7735 และ Adafruit_GC9A01A รวมถึงใช้ EasyEDA ในการเขียนวงจรด้วยครับ
อุปกรณ์ที่ต้องใช้ (Hardware Components)
-
SparkFun Pro Micro (3.3V/8MHz): เป็นบอร์ดตัวหลัก (ห้ามซื้อผิดเป็นรุ่น 5V นะครับ!)
-
โมดูลวิทยุ TI CC1101 (387-464MHz): ตัวรับสัญญาณ
-
จอ OLED 0.96in I2C 128x64 (เหลือง/ฟ้า): ไว้แสดงผล
- สาย USB-A to Micro-USB
ตัวเลือกอัปเกรด (ทางเลือก):
-
Seeed Studio Seeeduino Xiao: สามารถใช้แทน Pro Micro ได้ (ถูกกว่า, เล็กกว่า, แรมเยอะกว่า และเร็วกว่ามาก แต่ยังคงใช้ไฟ 3.3V)
-
3v Piezo buzzer (ลำโพงบัซเซอร์): ต่อเพิ่มเพื่อทำเสียงเตือนลมยางอ่อน (กินกระแสไฟต้องน้อยกว่า 7mA)
-
จอ 1.8in TFT SPI 128 x 160 RGB: หากใช้บอร์ด Xiao จะมีแรมเหลือพอใช้จอสีตัวนี้ได้
เจาะลึกเบื้องหลังทางเทคนิค (Technical Details)
จากการใช้ซอฟต์แวร์ SDR แกะรอย ผมพบว่าเซ็นเซอร์ล้อส่งสัญญาณแบบ FSK (Frequency Shift Keying) ที่ความถี่ศูนย์กลางประมาณ 433.88 MHz บวก/ลบ 24-30kHz ข้อมูลถูกเข้ารหัสแบบ Biphase Mark Coded ความยาว 72 บิต อัตราส่ง 10kHz รวมความยาวข้อความประมาณ 8 มิลลิวินาที (8ms)
ผมใช้โมดูล CC1101 จาก Texas Instruments เป็นตัวรับสัญญาณ โดยตั้งค่าพินให้อ่านสัญญาณดิบ (Raw receive) และสัญญาณ Carrier Sense (CS) ออกมา แม้ตอนแรกจะตั้งค่า Register ยากไปหน่อย แต่ซอฟต์แวร์ SMART RF Studio ช่วยได้เยอะครับ
View more (ดูรูปโมดูล CC1101 และการอ่านกราฟคลื่นสัญญาณ)
เนื่องจาก CC1101 ใช้ไฟ 3.3V ผมเลยเลือกใช้บอร์ด Arduino Pro Micro 3v3 เพื่อไม่ให้ต้องใช้วงจรแปลงไฟ (Level translator) แต่ข้อเสียคือบอร์ดรุ่นนี้มีแรมน้อยมาก พอรวมกับไลบรารีจอ OLED แล้วแรมเต็ม ผมเลยต้องเลี่ยงไปใช้ไลบรารีจอแบบ Text-only (ข้อความล้วน) แทน
ภาพด้านล่างนี้คือตัวอย่างคลื่นข้อมูลที่รับได้จากล้อรถโดยใช้ Logic Analyser จับสัญญาณเมื่อมีความยาว 8ms เพื่อกรองคลื่นรบกวนขยะออกไปครับ
โครงสร้างข้อมูลที่ส่งมา: 4 ไบต์แรกคือ Sensor ID, ตามด้วยสถานะ 1 บิต, แรงดัน (P) 8 บิต, อุณหภูมิ (T) 8 บิต, สถานะ 7 บิต, แรงดันซ้ำอีกรอบแต่กลับกลับบิต (Inverted), และปิดท้ายด้วย CRC 8 บิต
สูตรคำนวณ: อุณหภูมิจริง = (T - 40) °C / แรงดันจริง = ((P/4) - 7) PSI
การถอดรหัสของ Arduino: ผมใช้วิธีรอให้สถานะ CS ขึ้นเป็น High -> ใช้ Interrupt ของ Arduino จับเวลาความกว้างคลื่น -> ถ้ากว้างประมาณ 8ms ก็นำข้อมูลที่ได้มาแปลงเป็น 0 กับ 1 เก็บลงบิตบัฟเฟอร์ -> ตรวจสอบว่าครบ 72 บิตและเช็คความถูกต้อง (Checksum) -> สุดท้ายแปลงเป็นตัวเลขส่งขึ้นจอ OLED ครับ
วิธีประกอบและอัปโหลดโค้ด (How to Build One)
การเดินสายไฟทำได้ง่ายมากครับตามแผนผัง (Schematic) ข้อแนะนำคือถ้าคุณใช้บอร์ด Pro Micro ครั้งแรก ให้ทำตาม คู่มือจาก Sparkfun เพื่อโหลดบอร์ดเข้า Arduino IDE ก่อนครับ เลือก "Sparkfun Pro Micro" และ "ATmega32U4 (3.3V 8MHz)" ให้ถูกต้อง
- โหลดไฟล์โค้ดทั้ง 5 ไฟล์เข้า Arduino IDE และอัปโหลดลงบอร์ด
- เปิดไฟล์
globals.h ไปที่บรรทัด 64/65 จะเจอ ID ล้อทั้ง 4 ของรถผมตั้งไว้ คุณต้องลบคอมเมนต์บรรทัด SHOWDEGUGINFO ออกก่อน เพื่อเปิดดู Serial Monitor
- เมื่อเห็น ID ล้อของคุณใน Serial Monitor ให้นำรหัสเหล่านั้นไปแทนที่รหัสของผมในโค้ด เพื่อให้จอแสดงผลจัดเรียงตำแหน่งล้อ (หน้าซ้าย, หน้าขวา, หลังซ้าย, หลังขวา) ได้ถูกต้องครับ
View more (ดูรูปการต่อวงจรทดลอง)
การอัปเกรดระบบ (Later Additions)
ในเวอร์ชันหลังๆ เราเปลี่ยนมาใช้บอร์ด Seeeduino Xiao ได้ครับ เนื่องจากมันเร็วและแรมเยอะกว่า ทำให้เราขยับไปใช้หน้าจอสี 1.8" ST7735 TFT ได้สบายๆ เลย (ถ้าใช้บอร์ด Pro Micro เดิมจะใช้จอสีตัวนี้ไม่ได้เพราะแรมเต็ม)
การทำเคส 3D Print (Custom Enclosures)
คุณสามารถโหลดไฟล์ 3D โมเดล (STL, F3D) ของกล่องเคสที่เราออกแบบไว้ ทั้งแบบที่ใช้บอร์ด Pro Micro และบอร์ด Xiao ได้ที่ด้านล่างของบทความเลยครับ นำไปปริ้นท์ประกอบใช้งานในรถได้สวยๆ
💡 ทริคเพิ่มเติม: หากคุณไม่มีเครื่อง 3D Printer คุณสามารถใช้บริการสั่งพิมพ์ 3D ในประเทศไทยได้ง่ายๆ ที่ https://openlink.co/globalbyte ครับ
วิธีการใช้งาน (How to Use)
เสียบปลั๊ก USB 5V (เช่น ที่ชาร์จในรถ) หน้าจอจะโชว์ชื่อระบบสีเหลือง หากอยู่ใกล้รัศมีของล้อรถที่มีเซ็นเซอร์ TPMS Toyota มันจะทยอยแสดงข้อมูลล้อขึ้นมาทีละล้อ โดยมีตัวเลขใหญ่สุดคือแรงดัน (PSI) เส้นขีดด้านล่างคืออุณหภูมิ และตัวเลข 1-5 ด้านล่างสุดคือระดับความสดใหม่ของข้อมูล (5=ใหม่สุด, 1=เก่าสุด) หากผ่านไป 30 นาทีแล้วล้อนั้นไม่ส่งข้อมูลมาเลย ระบบจะลบค่าของล้อนั้นทิ้งจากจอครับ
ประวัติการอัปเดต และการตั้งค่า Config.h
ตลอดการพัฒนาโปรเจกต์นี้ เรามีอัปเดตมากกว่า 10 เวอร์ชัน และปรับจูนโค้ดให้รองรับเซ็นเซอร์ของรถรุ่นต่างๆ เยอะมากครับ ใครที่ใช้รถรุ่นอื่น สามารถกดกางดูประวัติและวิธีตั้งค่าล้อรุ่นอื่นๆ ได้เลยครับ
View more (ดูประวัติการอัปเดต และวิธีการ Config แบบละเอียด)
Versions:
-
V1.0 Originally published version using asynchronous data output from CC1101
-
V2.0 Updated to allow support for spare tyre reporting
-
V3.0 Added #define in globals.h to switch between BAR and PSI
-
V4.0 Significant changes to use synchronous data output from CC1101.
-
V5.0 Bug fix - improvements to better detect start of valid data.
-
V5.1.1 Added functions for extracting RSSI as dbm
-
V6.0 Added code for options for US (315MHz) or UK (433MHz), also for different sensor types (PMV-C210, PMV-107J)
-
V6.1 Added support for Seeeduino Xiao processor
-
V6.2 - V6.4 Included support for Renault, Citroen and code rationalisation.
-
V6.5 - V6.7 Improved PMV-107J decode. Added Fahrenheit option. Re-introduced flashing display for alarms.
-
V7.0 Included option for 1.8" TFT display (requires Seeeduino Xiao). Tested OK on Nissan Leaf (2016).
-
V8.0 Added (optional) audible alarm for pressure alarms. Improved display flashing.
-
V9.0 - V9.9 Added Pontiac (US) decoder, 240x240 round display support, temperature compensation, kPA option, Renault Zoe support, Summer/Winter tyre sets, Ford E-Series support.
-
V10.0 - V10.8 Improved Ford handling, bug fixes for ILI9341, improved PMV-107J & PMV-C210 detection. Added TRW-C070 (Toyota Sienna) and Schrader C1100/C8000 (Hyundai Tucson). Added support for Xiao RP2040.
-
V11.0 - V11.8 Added Winter tyre pressure limits. Added Adafruit 3v itsybitsy support. Bug fixes for Manchester decoding.
-
V12.X Trial version only for ESP32. Eliminates use of CD signal by continuously monitoring RX pin.
สถานะการทดสอบเซ็นเซอร์รถรุ่นต่างๆ:
Toyota PMV-C210 (433MHz - OK), Toyota PMV-107J (315MHz - OK), Toyota TRW-C070 (433MHz - OK), Nissan Leaf 2016 (433MHz - OK), Pontiac G800 (315MHz - OK), Smart Fortwo (433MHz - OK) *และรุ่นอื่นๆ ที่กำลังทดสอบเพิ่มเติม
Display settings (การเลือกประเภทจอ):
ในโค้ดให้เอาเครื่องหมายคอมเมนต์ (//) ออกที่หน้า #define ตามจอที่คุณใช้:
- จอ OLED 0.96" I2C: #define USE_1_INCH_YB_I2C_DISPLAY 1
- จอ TFT 1.8" SPI: #define USE_2_INCH_ST7753_DISPLAY 1
- จอกลม TFT 240x240 SPI: #define USE_2_INCH_ST7789_DISPLAY 1
- จอ TFT 2.4" 240x320: #define USE_24_INCH_ILI9341_DISPLAY 1
การตั้งค่าหน่วยและการแจ้งเตือน (Readout & Alarm options):
เปิดใช้งานแจ้งเตือนไฟกระพริบ: #define ENABLE_PRESSURE_ALARMS ใน configs.h
เปิดเสียงเตือนบัซเซอร์: #define ENABLE_AUDIBLE_ALARM
ตั้งหน่วยเป็น BAR หรือ kPA: #define DISPLAY_PRESSURE_AS_BAR 1 หรือ KPA 1 (ค่าเริ่มต้นคือ PSI)
การเลือกรุ่นรถ (ตัวอย่างสำหรับ Toyota ในไทย/UK 433MHz):
#define UK_433MHz 1 //#define US_315MHz 1 #define Toyota_PMV_C210 1 //#define Toyota_PMV_107J 1 //#define NissanLeaf 1
ดาวน์โหลดไฟล์โปรเจกต์ (Custom Parts & Files)
สำหรับเพื่อนๆ ที่พร้อมลุย สามารถดาวน์โหลดไฟล์ทุกอย่างได้จากลิงก์ด้านล่างนี้ครับ:
ไฟล์ 3D โมเดล (Enclosures):
แผนผังวงจร (Schematics):
รายชื่อไฟล์ Source Code ทั้งหมดที่ต้องใช้ใน Arduino IDE:
- CommonC Header File
- displayC Header File
- globalsC Header File
- Toyota_PMV_107JC Header File
- Toyota_PMV_C210C Header File
- RenaultC Header File
- CitroenC Header File
- configsC Header File
- FordC Header File
- JansiteC Header File
- JansiteSolarC Header File
- bitmapC Header File
- display_128x160C Header File
- AudibleAlarmC Header File
- CommonFunctionDeclarationsC Header File
- display_240x240roundC Header File
- PontiacG82009C Header File
- display_240x320C Header File
- ไฟล์หลัก:
UKUS_Toyota_TPMS_Monitor_V11_8.ino
อัปเกรดฮาร์ดแวร์และรถของคุณให้ล้ำกว่าใคร!
อยากทำโปรเจกต์แฮ็กระบบรถยนต์ หรือสนใจทำอุปกรณ์ IoT เจ๋งๆ แบบนี้ใช้เอง? แวะมาพูดคุยและหาซื้อบอร์ดและเซ็นเซอร์ได้เลยครับ!
คำเตือน: เนื้อหานี้เป็นการสรุปและเรียบเรียงจากบทความต้นฉบับภาษาอังกฤษ ข้อมูลฉบับภาษาไทยอาจมีความคลาดเคลื่อนบางประการจากการตีความหรือย่อเนื้อหา การแฮ็กระบบอิเล็กทรอนิกส์ในรถยนต์มีความเสี่ยง โปรดศึกษาข้อมูลและทดสอบอย่างระมัดระวัง