ดิว.นินจา

ดิว.นินจา

Sunday, April 29, 2018

การอ่านค่าจากโมดูล LSM9DS1 เพื่อแสดงผลบน NETPIE Freeboard

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

เพื่อความสะดวกบอร์ดฮาร์ดแวร์สำหรับบทความนี้จะเลือกใช้ node32pico จากบริษัท Ayarafun/LamLoei ในรูปที่ 1 เพราะมีโมดูล LSM9DS1 อยู่บนบอร์ด หากผู้อ่านต้องการใช้ผลิตภัณฑ์ ESP32 อื่นก็สามารถต่อวงจรเพิ่มเติมได้โดยหาบอร์ดเสริมที่มีโมดูลนี้อยู่ ตัวอย่างเช่น STEVAL-MKI159V1 จากบริษัท ST ผู้ผลิตโมดูล หรือผลิตภัณฑ์จากบริษัท SparkFun หรือ Adafruit ก็ได้ โดยเชื่อมต่อเข้ากับบัส i2c (โมดูลสามารถต่อกับบัส SPI ได้ แต่ตัวอย่างในบทความนี้จะกล่าวถึงเฉพาะ i2c)

รูปที่ 1 บอร์ด node32pico จากบริษัท Ayarafun/LamLoei

การทำงานของ LSM9DS1

ประโยชน์ของโมดูล LSM9DS1 คือใช้วัดคุณสมบัติการเคลื่อนที่สำคัญ 3 ค่า คือความเร่ง ความเร็วเชิงมุม และความแรง/ทิศทางสนามแม่เหล็ก ในชิพเดียวกัน

  • มาตรวัดความเร่ง (accelerometer) : เป็นตัวแสดงว่าความเร็วเปลี่ยนแปลงตามเวลาอย่างไร หน่วยวัดที่นิยมใช้คือ m/s2 และ g (มีค่าประมาณ 9.8 m/s2) วัตถุบนโลกที่ไม่เคลื่อนที่จะมีค่าความเร่งในทิศทางลงสู่พื้นเท่ากับ 1 g (วัดที่ระดับน้ำทะเล) โมดูล LSM9DS1 วัดค่าความเร่งมีหน่วยเป็น g และสามารถตั้งค่ามาตราส่วนเท่ากับ +/- 2, 4, 8 หรือ 16 g
  • ไจโรสโคป (gyroscope) : ใช้สำหรับวัดความเร็วเชิงมุม มีหน่วยเป็น องศาต่อเวลา (degree per second) มักใช้ตัวย่อ DPS สามารถตั้งค่ามาตราส่วน +/- 245, 500 หรือ 2000 DPS
  • มาตรวัดสนามแม่เหล็ก (magnetometer) : ใช้วัดกำลังและทิศทางของสนามแม่เหล็ก โดยตรวจจับจากอุปกรณ์ที่มีแม่เหล็กถาวร หรืออุปกรณ์ที่กำเนิดคลื่นแม่เหล็กไฟฟ้า หรือสนามแม่เหล็กของโลก โมดูลจะวัดค่ามีหน่วยเป็น เก้าส์ (gauss) ตัวย่อคือ Gs และสามารถตั้งมาตราส่วน +/- 4, 8, 12 หรือ 16 Gs

รูปที่ 2 แสดงการกำหนดแกนทั้ง 3 ของโมดูลเมื่อเทียบกับจุดกำหนดขาบนไอซี ทิศทางจะเป็นไปตามกฏมือขวา สังเกตว่าแกนของสนามแม่เหล็กจะถูกหมุน 90 องศารอบแกน z เมื่อเทียบกับแกนความเร่งและความเร็วเชิงมุม

รูปที่ 2 การกำนดทิศทางของแกนในโมดูล LSM9DS1 (ภาพจากดาต้าชีท)

ดังนั้นจะเห็นได้ว่าโมดูล LSM9DS1 สามารถวัดค่าความเร่ง ความเร็วเชิงมุม และสนามแม่เหล็กได้ 3 มิติ รวมเป็นข้อมูลทั้งหมด 9 ค่า หรือมองได้ว่าโมดูลประกอบด้วย 2 วงจรรวมอยู่ในตัวเดียวกัน ครึ่งหนึ่งคือส่วนไจโรและมาตรวัดความเร่ง ส่วนอีกครึ่งหนึ่งคือมาตรวัดสนามแม่เหล็ก โดยพิจารณาได้จากสัญญาณควบคุมแยกจากกัน เช่นขาเลือกชิพ (CS_AG และ CS_M) และขาข้อมูลออกสำหรับ SPI (SDO_AG และ SDO_M ซึ่งในการใช้งานกับบัส i2c จะใช้เป็นขาเลือกแอดเดรส)

โมดูล LSM9DS1 ใช้กับแรงดันไฟเลี้ยง 3.3 โวลต์ เท่านั้น หากนำไปต่อกับ Arduino ที่มีระดับลอจิก 5 โวลต์และใช้บัส SPI จะต้องมีตัวแปลงระดับแรงดัน ในที่นี้จะใช้ร่วมกับ ESP32 จึงไม่มีปัญหาเรื่องระดับแรงดัน

แอดเดรสของโมดูลเมื่อใช้งานกับบัส i2c

ในการใช้งานโมดูลร่วมกับบัส i2c แอดเดรสของโมดูลจะถูกกำหนดโดยขา CS_AG, CS_M, SDO_AG และ SDO_M ซึ่งศึกษาได้จากคู่มือ จากผังวงจรของบอร์ด node32pico พบว่าขา CS_AG, CS_M ต่อกับ 3.3 โวลต์ และ SDO_AG, SDO_M ต่อกับกราวด์ ในกรณีนี้แอดเดรสของภาค AG และ M จะถูกกำหนดเป็น 0x6A และ 0x1C ตามลำดับ

ไลบรารีสำหรับ Arduino

ในการใช้งานร่วมกับ Arduino IDE แนะนำให้ใช้ไลบรารีที่มีอยู่แทนการเขียนโปรแกรมเองใหม่ทั้งหมดเพื่อดึงข้อมูลจากโมดูล ทั้งนี้โมดูล LSM9DS1 มิใช่ผลิตภัณฑ์ใหม่ แต่ได้มีการใช้งานมาเป็นเวลาพอสมควรทำให้มีไลบรารีให้เลือกจากหลายผู้พัฒนา ส่วนใหญ่เป็นบริษัทที่จำหน่ายผลิตภัณฑ์ที่เกี่ยวข้อง เช่นบอร์ดเสริม เช่นบริษัท Adafruit และ SparkFun ในบทความนี้จะเลือกใช้ไลบรารีจากบริษัท SparkFun ซึ่งสามารถดาวน์โหลดได้จากเว็บของบริษัท รวมถึงข้อมูลเพิ่มเติมที่เป็นประโยชน์ เช่นขั้นตอนการติดตั้งไลบรารี ซึ่งในบทความนี้ขอข้ามไปเนื่องจากจะเหมือนกับการติดตั้งไลบรารีอื่นซึ่งผู้อ่านคงมีประสบการณ์แล้ว

ลิงก์สำหรับดาวน์โหลดไลบรารีของ SparkFun

หลังจากติดตั้งไลบรารีแล้ว เลือกตัวอย่างจากเมนูดังในรูปที่ 3 เซฟตัวอย่างนี้ในไดเรคทอรีอื่น เนื่องจากเราต้องแก้ไขส่วนของแอดเดรสให้ตรงกับวงจรบนบอร์ด node32pico

รูปที่ 3 เลือกตัวอย่าง LSM9DS1_Basic_I2C

ค้นหาบรรทัดที่กำหนดแอดเดรส และเปลี่ยนเป็นค่าดังนี้


#define LSM9DS1_M 0x1c 
#define LSM9DS1_AG 0x6A

คอมไพล์และโหลดลงบนบอร์ด node32pico เมื่อเปิดหน้าต่าง Serial Monitor จะแสดงข้อมูลที่อ่านได้จากโมดูล LSM9DS1 ดังเช่นในรูปที่ 4

รูปที่ 4 ผลจากการรันตัวอย่างที่แก้ไขแอดเดรสแล้ว

โปรแกรมตัวอย่างนี้จะแสดงการใช้งานไลบรารีพื้นฐาน ซึ่งมีลักษณะเป็นการโปรแกรมเชิงวัตถุ อธิบายโดยสังเขปคือเริ่มต้นวัตถุ imu จะถูกสร้างขึ้นและตั้งค่าให้ตรงตามการใช้งาน หลังจากนั้นจะเรียกใช้วิธี (methods) เพื่อดึงค่าข้อมูลที่ต้องการ ซึ่งโปรแกรมสาธิตการอ่านค่าทั้งหมดจากโมดูล และแสดงผลเป็นค่าที่ผ่านการคำนวณให้เป็นหน่วยที่ต้องการแล้ว สำหรับรายละเอียดการตั้งค่าต่างๆ สามารถศึกษาเพิ่มเติมได้จากข้อมูลในไลบรารีและจากเว็บของผู้พัฒนา

การแสดงผลบน NETPIE Freeboard

เมื่อสามารถอ่านข้อมูลจากโมดูลได้สำเร็จ การนำไปแสดงผลบน NETPIE ก็ไม่ใช่เรื่องยาก เพราะขั้นตอนก็จะเหมือนกับที่เคยนำเสนอในบทความก่อนหน้าและในหนังสือ

  • สร้าง Application และ keys สำหรับบอร์ด node32pico และ Freeboard
  • นำข้อมูล App ID, Key, Secret ใส่ด้านบนของโปรแกรม
  • กำหนดชื่อ Alias ของอุปกรณ์
  • กำหนดชื่อ topic ที่ต้องการ publish
  • สร้างสตริงข้อมูล และส่งให้คำสั่ง microgear.publish()
  • สร้าง Freeboard และ datasource เลือกแบบ microgear
  • บน Freeboard สร้าง widget แบบ Gauge จำนวน 9 ตัว เท่ากับจำนวนข้อมูลที่ publish
  • ในฟิลด์ Value ของ Gauge ใส่คำสั่งที่จะเลือกข้อมูลจากทั้งหมดที่ส่งมา แยกโดยเครื่องหมาย ","

ในส่วนของโปรแกรมบน ESP32 ได้ดัดแปลงจากตัวอย่างในไลบรารีโดยใช้ตัวแปรแบบ struct เพื่อทำให้จัดการข้อมูลได้ง่ายขึ้น ตามนิยามดังนี้


struct IMUData
{
  // acceleration data
  float ax;   // unit in g
  float ay;
  float az;
  // gyro data
  float gx;   // unit in deg/s
  float gy;
  float gz;
  // magnetic data 
  float mx;     // unit in Gs
  float my;
  float mz;
 };
struct IMUData imudata;

ซึ่งจะเก็บข้อมูลที่คำนวณให้เป็นหน่วยที่ต้องการแล้ว ตัวอย่างเช่น imudata.ax เก็บข้อมูลความเร่งในแนวแกน X และ imudata.gz เก็บข้อมูลความเร็วเชิงมุมรอบแกน Z เป็นต้น ข้อมูลจะถูกพับลิชให้ NETPIE เรียงลำดับดังนี้


ax, ay, az, gx, gy, gz, mx, my, mz

ไฟล์ทั้งหมดรวมอยู่ใน LSM9DS1_netpie.ino ดาวน์โหลดได้จากด้านล่างบทความนี้ เมื่อรันโปรแกรมและเปิด Serial Monitor จะเห็นการแสดงผลดังในรูปที่ 5 ซึ่งเมื่อสร้าง gauges บน NETPIE Freeboard แล้วจะเห็นการแสดงผลในรูปที่ 6

รูปที่ 5 ข้อมูลที่ถูก publish ให้ NETPIE
รูปที่ 6 การแสดงค่าข้อมูลบน NETPIE Freeboard

ซึ่งการแสดงผลแบบกราฟิกนี้จะทำให้เข้าใจการทำงานของโมดูล LSM9DS1 ได้ดีกว่าข้อความใน Serial Monitor มาก ตัวอย่างเช่นหากต้องการศึกษาผลจากแรงโน้มถ่วงที่กระทำกับแนวแกนทั้ง 3 ของโมดูล ทำได้โดยจับโมดูลให้มีทิศทางตามรูปที่ 7, 8, 9 ซึ่งจะได้ค่าความเร่ง (จากแรงโน้มถ่วง) ประมาณ 1 g ตามแนวแกน X,Y,Z ตามลำดับ

รูปที่ 7 วัดความเร่งจากแรงโน้มถ่วงตามแนวแกน X
รูปที่ 8 วัดความเร่งจากแรงโน้มถ่วงตามแนวแกน Y
รูปที่ 9 วัดความเร่งจากแรงโน้มถ่วงตามแนวแกน Z

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

รูปที่ 10 การวัดค่าสนามแม่เหล็กจากแม่เหล็กถาวร

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

คลิปวีดีโอนี้แสดงการเปลี่ยนแปลงของ Gauges ทั้งหมดเมื่อบอร์ดเคลื่อนที่

ดาวน์โหลดโปรแกรม : LSM9DS1_netpie.ino

1 comment:

  1. พีคับผมใช้บอร์ดเดียวกันแต่ทำไมตอน run ไม่ขึ้น fail to communLSM9DS1 นะครับผมปรับ address แล้วตรง define ก็ไม่หายคับ

    ReplyDelete

แนะนำหนังสือ “ตัวควบคุมป้อนกลับบนอินเทอร์เน็ตโดย ESP8266”

ปัจจุบันเมื่อกล่าวถึงอุปกรณ์ IoT (Internet of Things) คงมีน้อยคนที่จะไม่รู้จัก ในยุคที่การเข้าถึงอินเทอร์เน็ตเป็นกิจวัตรประจำวันของมนุษย์เ...