เข ยน serial.monitor ม เง อนไข กด a ให แสดงช

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

การสื่อสารระหว่างอุปกรณ์สามารถแบ่งได้ 2 รูปแบบ คือ

การสื่อสารแบบขนาน

คือการใช้สาย 1 เส้น แทนบิตข้อมูล 1 บิต โดยทั่วไปแล้วมักจะนิยมใช้งานแบบ 4 บิต 7 บิต และ 8 บิต โดยจะมีสาย 1 เส้นเป็นสายควบคุมที่บอกว่าจะให้รับข้อมูลเขาไปเมื่อใด ข้อดีของการสื่อสารรูปแบบนี้คือมีความเร็วที่สูงมาก และมีข้อเสียคือใช้สายจำนวนมากในการสื่อสาร การสื่อสารแบบขนานใช้ในอุปกรณ์อ่านจอ LCD ขนาดต่าง ๆ ซึ่งจะใช้งานได้ทั้งแบบ 4 บิต และ 8 บิต ใช้ขา EN ในการควบคุมการรับข้อมูล

การสื่อสารแบบอนุกรม

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

  • แบบซิงโคนัส (Synchronous) – เป็นการสื่อสารที่ใช้สายสัญญาณข้อมูลอย่างน้อย 1 เส้น และมีสายอีก 1 เส้นกำหนดจังหวะการรับข้อมูล ข้อดีของการสื่อสารแบบนี้คือการรับส่งข้อมูลมีความผิดพลาดน้อยหรือไม่มีความผิดพลาดเลย แต่ข้อเสียคือต้องใช้สายสัญญาณอย่างน้อย 2 เส้นในการสื่อสาร โดยโปรโตคอลที่ทำงานแบบซิงโคนัสได้แก่ I2C I2S และ SPI
  • แบบอะซิงโคนัส (Asynchronous) – เป็นการสื่อสารที่ใช้สายสัญญาณข้อมูลเพียงเส้นเดียวในการทำงาน โดยอาศัยสัญญาณจากบิตเริ่มต้น และบิตสิ่นสุดในการบอกจังหวะการรับส่งข้อมูล การสื่อสารแบบนี้จำเป็นต้องอาศัยเวลามาเป็นตัวกำหนดการรับสัญญาณเข้ามาซึ่งหากมีการตั้งค่าที่ผิดจะทำให้อ่านข้อมูลที่ส่งมาได้ผิดพลาด ข้อดีของการสื่อสารแบบนี้คือใช้สายสัญญาณเพียง 1 เส้นก็สามารถรับ-ส่งข้อมูลได้แล้ว แต่ข้อเสียคือมีความผิดพลาดในการสื่อสารได้ง่าย โดยโปรโตคอลที่ทำงานแบบอะซิงโคนัสคือ UART

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

การสื่อสารผ่าน UART

UART ย่อมาจาก Universal Asynchronous Receiver Transmitter ใช้การสื่อสารแบบอนุกรมโดยเป็นแบบอะซิงโคนัสใช้สายสัญญาณเพียง 2 เส้น คือ Tx และ Rx ในการรับ – ส่งข้อมูล โดยเส้น Tx จะเป็นเส้นที่ใช้ส่งข้อมูล และเส้น Rx เป็นเส้นที่ใช้รับข้อมูล เมื่อนำไปต่อใช้งานจะต้องต่อไขว้กันระหว่างอุปกรณ์และไมโครคอนโทรลเลอร์ และต้องกำหนดความเร็วในการสื่อสารซึ่งสามารถเลือกได้ดังนี้ 300 600 1200 2400 4800 9600 14400 19200 28800 38400 57600 และ 115200 ทั้งนี้ความเร็วที่กำหนดมักขึ้นอยู่กับอุปกรณ์ที่จะเชื่อมต่อด้วยโดยมักจะกำหนดเป็น 9600 เมื่ออุปกรณ์กำหนดเป็น 9600 ที่ตัวไมโครคอนโทรลเลอร์ต้องกำหนดเป็น 9600 ด้วย จึงจะสามารถรับ-ส่งข้อมูลได้ถูกต้อง

อุปกรณ์ที่ใช้ UART ในการสื่อสารที่เห็นได้บ่อย ๆ คือ GPS, GSM/3G/4G Module, Bluetooth รวมไปถึงการสื่อสารกับคอมพิวเตอร์ ตัว ESP32 เองก็ใช้ UART ในการอัพโหลดโปรแกรมโดยมีชิปไอซีแปลง USB เป็น UART ทำให้สามารถใช้งาน UART ผ่าน USB เพื่ออัพโหลดโปรแกรมได้

ใน ESP32 มีช่องสำหรับใช้งาน UART จำนวน 3 ช่อง ซึ่งแบ่งเป็น UART0 ใช้อัพโหลดโปรแกรม และอีก 2 ช่อง UART1 UART2 สามารถนำมาใช้เชื่อมต่อกับอุปกรณ์ต่าง ๆ ได้ ทั้งนี้ในการเขียนโปรแกรมแต่ละช่องจะมีชื่อคลาสที่แตกต่างกัน แต่ฟังก์ชั่นภายในคลาสเหมือนกันทุกประการ

การใช้งาน UART0

UART0 เชื่อมต่ออยู่กับชิปไอซีแปลง USB เป็น UART ดังนั้นการใช้งานจะเป็นการสื่อสารระหว่างตัว ESP32 และคอมพิวเตอร์ มีฟังก์ชั่นให้ใช้งานหลาย ๆ ตัว แต่ยกเป็นเคสขึ้นมาเพื่อให้สามารถทำความเข้าใจได้ง่ายมากขึ้น

กำหนดเริ่มต้นสื่อสาร – จะใช้ฟังก์ชั่น Serial.begin() ในการเริ่มต้นการสื่อสาร โดยมีรูปแบบการใช้งานดังนี้

void Serial.begin(long speed);

มีค่าพารามิเตอร์ตัวเดียว ดังนี้

  • (long) speed – ความเร็วในการสื่อสาร สามารถเลือกได้เป็น 300 600 1200 2400 4800 9600 14400 19200 28800 38400 57600 และ 115200 สำหรับบน ESP32 จะนิยมใช้ความเร็วสูงสุดคือ 115200

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

การส่งข้อมูลออกไป – ในการส่งข้อมูลออกไป จะมีฟังก์ชั่นให้ใช้งานทั้งหมด 3 ฟังก์ชั่น ซึ่งแต่ละฟังก์ชั่นจะมีคุณสมบัติการใช้งานแตกต่างกัน

ฟังก์ชั่น Serial.write() เป็นฟังก์ชั่นที่ใช้ส่งข้อมูลที่มีชนิดเป็น char byte หรือข้อมูลที่มีขนาด 8 บิตออกไป หากนำมาใช้ส่งข้อความจะสามารถส่งได้ครั้งละ 1 ตัวอังษรนั้น มีรูปแบบการใช้งานดังนี้

void Serial.write(buf, int len=1);

มีรายละเอียดของพารามิเตอร์แต่ละตัวดังนี้

  • buf – ข้อมูล หรือตัวอักษรที่ต้องการส่งออกไป สามารถใช้เป็นสตริงแบบ char array ได้
  • (int) len – ใช้กำหนดความยาวของสตริง กรณีใช้ char array ในพารามิเตอร์ buf มีค่าดีฟอลเป็น 1

และไม่มีการตอบกลับ

ฟังก์ชั่น Serial.print() เป็นฟังก์ชั่นที่ใช้ส่งข้อมูลออกไปโดยรองรับข้อมูลทุกชนิด และแปลงข้อมูลที่เป็น int long เป็นสตริงอัตโนมัติ มีรูปแบบการใช้งานดังนี้

void Serial.print(val); หรือ void Serial.print(int val, int format);

มีรายละเอียดของพารามิเตอร์ดังนี้

  • val – ข้อมูลที่ต้องการส่งออกไป โดยรองรับข้อมูลทุกชนิด กรณีใส่ตัวเลขลงไปจะแปลงเป็นสตริงอัตโนมัติ
  • (int) format – กรณีที่ข้อมูลเป็นตัวเลข สามารถกำหนดเงื่อนไขการแปลงตัวเลขเป็สตริงได้โดยกำหนดพารามิเตอร์นี้ ค่าที่กำหนดในพารามิเตอร์นี้ได้มีดังนี้
    • BIN – แปลงข้อมูลตัวเลขเป็นสตริงในรูปของเลขฐาน 2 เช่น 15 -> 1111
    • OCT – แปลงข้อมูลตัวเลขเป็นสตริงในรูปของเลขฐาน 8 เช่น 15 -> 17
    • DEC – แปลงข้อมูลตัวเลขเป็นสตริงในรูปของเลขฐาน 10 เช่น 15 -> 15
    • HEX – แปลงข้อมูลตัวเลขเป็นสตริงในรูปของเลขฐาน 16 เช่น 15 -> F

นอกจากนี้หากชนิดข้อมูลเป็น float หรือ double พารามิเตอร์ตัวนี้จะใช้กำหนดจำนวนทศนิยมที่ต้องการ

ฟังก์ชั่น Serial.println() เป็นฟังก์ชั่นที่ใช้ส่งข้อมูลออกไปและขึ้นบรรทัดใหม่ (\r\n) ให้อัตโนมัติ มีรูปแบบการใช้งานแบบเดียวกับ Serial.print() และไม่มีการส่งค่ากลับ

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

ฟังก์ชั่น Serial.available() ใช้ตรวจสอบว่ามีข้อมูลเข้ามาหรือไม่ แล้วส่งเข้ามาเท่าไร มีรูปแบบการใช้งานดังนี้

int Serial.available();

ไม่มีพารามิเตอร์ และมีค่าที่ตอบกลับเป็นจำนวนข้อมูลที่ถูกส่งเข้ามา

ฟังก์ชั่น Serial.read() ใช้อ่านข้อมูลที่ส่งเข้ามา โดยอ่านได้ครั้งละ 1 ไบต์ หรือ 1 ตัวอักษร มีรูปแบบการใช้งานดังนี้

byte Serial.read();

ไม่มีพารามิเตอร์ และตอบกลับเป็นข้อมูลที่ส่งเข้ามาความยาว 1 ไบต์

ฟังก์ชั่น Serial.readString() ใช้สำหรับอ่านข้อมูลออกมาเป็นข้อความ เหมาะสำหรับใช้อ่านข้อมูลที่ส่งมาเป็นชุดต่อเนื่องโดยหลักการของฟังก์ชั่นนี้จะอาศัย Timeout เป็นตัวกำหนดว่าจะถือว่าสิ้นสุดข้อมูลเมื่อใด ซึ่งมี้รูปแบบการใช้งานดังนี้

String Serial.readString();

ไม่มีพารามิเตอร์ และตอบกลับมาเป็นข้อมูลชนิด String

ฟังก์ชั่น Serial.setTimeout() เป็นฟังก์ชั่นที่ใช้กำหนดเวลาที่จะตัดสินว่าจะนับเป็นจุดสิ้นสุดของข้อมูลเมื่อใด โดยมีรูปแบบการใช้งานดังนี้

void Serial.setTimeout(long timeout);

มีพารามิเตอร์ 1 ตัว คือ

  • (long) timeout – กำหนดเวลาในหน่วยมิลิวินาที

และไม่มีข้อมูลตอบกลับ ทั้งนี้หากไม่เรียกใช้ฟังก์ชั่น Serial.setTimeout() จะกำหนดให้หมดเวลาที่ 1 วินาที โดยผู้เขียนพบว่าหากใช้ความเร็วในการสื่อสารตั้งแต่ 9600 ขึ้นไป สามารถกำหนดเวลาเป็น 100 มิลิวินาทีได้ ซึ่งฟังก์ชั่น Serial.readString() สามารถทำงานได้รวดเร็วและถูกต้อง

ตัวอย่างการใช้งาน UART สื่อสารกับคอมพิวเตอร์ สามารถนำโค้ดต่อไปนี้อัพโหลดลงบอร์ด NodeMCU-32S ได้เลย

จากนั้นเปิด Serial Monitor ขึ้นมา เลือก Band เป็น 115200 และเลือก No line ending พิมพ์ข้อความลงในช่อง แล้วกดปุ่ม Enter บนคีย์บอร์ด หรือกดปุ่ม Send ผลที่ได้คือข้อความที่เราพิมพ์ลงไปจะปรากฏขึ้นมาอย่างรวดเร็ว

บรรทัดที่ 1 สร้างฟังก์ชั่น setup

บรรทัดที่ 2 ใช้ฟังก์ชั่น Serial.setTimeout() กำหนดหมดเวลาเมื่อตัวอักษรสุดท้ายผ่านไป 100 มิลิวินาที

บรรทัดที่ 3 ใช้ฟังก์ชั่น Serial.begin() กำหนดเริ่มใช้งาน UART0 โดยตั้งความเร็วไว้ที่ 115200

บรรทัดที่ 4 จบคำสั่งในฟังก์ชั่น setup

บรรทัดที่ 5 ไม่นำมาวิเคราะห์

บรรทัดที่ 6 สร้างฟังก์ชั่น loop

บรรทัดที่ 7 นำค่าที่ได้ฟังก์ชั่น Serial.available() มาเปรียบเทียบว่าส่งกลับค่ามามากกว่า 0 หรือไม่ หากมากกว่า ให้ทำคำสั่งในปีกกา

บรรทัดที่ 8 ใช้ฟังก์ชั่น Serial.readString() อ่านข้อมูลที่ส่งเข้ามาเป็นสตริง แล้วเอาไปเก็บไว้ที่ตัวแปร msg

บรรทัดที่ 9 ใช้ฟังก์ชั่น Serial.print() ส่งข้อความว่า “Echo: ”

บรรทัดที่ 10 ใช้ฟังก์ชั่น Serial.println() ส่งข้อความในตัวแปร msg พร้อมขึ้นบรรทัดใหม่

บรรทัดที่ 11 จบคำสั่งใน if

บรรทัดที่ 12 จบคำสั่งในฟังก์ชั่น loop

ตัวอย่างต่อไปเป็นการทดลองควบคุมหลอด LED บนบอร์ด NodeMCU-32S ด้วยการส่งข้อมูลผ่าน UART0

อัพโหลดโค้ดด้านล่างนี้ลงบอร์ด NodeMCU-32S

เปิด Serial Monitor ขึ้นมา แล้วพิมพ์คำว่า ON หลอด LED บนบอร์ด NodeMCU-32S ติดขึ้นมา และพิมพ์คำว่า OFF หลอด LED จะดับ และในหน้าต่าง Serial Monitor ขึ้นคำว่า “OK.”

บรรทัดที่ 1 ใช้คำสั่ง

define แทนข้อความ LED_PIN ด้วย LED_BUILTIN ทั้งหมด ใช้กำหนดขา GPIO ที่ต่ออยู่กับหลอด LED

บรรทัดที่ 2 ไม่นำมาวิเคราะห์

บรรทัดที่ 3 สร้างฟังก์ชั่น setup

บรรทัดที่ 4 ใช้คำสั่ง pinMode() กำหนดหมายเลขขา GPIO ใน LED_PIN เป็นขาเอาต์พุตแบบดิจิตอล

บรรทัดที่ 5 ไม่นำมาวิเคราะห์

บรรทัดที่ 6 ใช้ฟังก์ชั่น Serial.setTimeout() กำหนดหมดเวลาเมื่อตัวอักษรสุดท้ายผ่านไป 100 มิลิวินาที

บรรทัดที่ 7 ใช้ฟังก์ชั่น Serial.begin() กำหนดเริ่มใช้งาน UART0 โดยตั้งความเร็วไว้ที่ 115200

บรรทัดที่ 8 จบคำสั่งในฟังก์ชั่น setup

บรรทัดที่ 9 ไม่นำมาวิเคราะห์

บรรทัดที่ 10 สร้างฟังก์ชั่น loop

บรรทัดที่ 11 นำค่าที่ได้ฟังก์ชั่น Serial.available() มาเปรียบเทียบว่าส่งกลับค่ามามากกว่า 0 หรือไม่ หากมากกว่า ให้ทำคำสั่งในปีกกา

บรรทัดที่ 12 ใช้ฟังก์ชั่น Serial.readString() อ่านข้อมูลที่ส่งเข้ามาเป็นสตริง แล้วเอาไปเก็บไว้ที่ตัวแปร msg

บรรทัดที่ 13 ใช้ฟังก์ชั่น digitalWrite() เขียนสถานะตามการใช้ Ternary Operators เปรียบเทียบสตริงในตัวแปร msg ว่าเป็น “ON” หรือไม่ ถ้าใช้ก็ส่งค่า HIGH กลับไป ทำให้สถานะเอาต์พุตของ GPIO มีสถานะเป็น HIGH และหากไม่ใช่ “ON” ก็ส่งค่า LOW กลับไป ทำให้สถานะเอาต์พุตของ GPIO มีสถานะเป็น LOW โดยขา GPIO คือ LED_PIN

บรรทัดที่ 14 ใช้ฟังก์ชั่น Serial.print() ส่งข้อความว่า “OK.”

บรรทัดที่ 15 จบคำสั่งใน if

บรรทัดที่ 16 จบคำสั่งในฟังก์ชั่น loop

การใช้งาน UART1 และ UART2

ฟังก์ชั่นการใช้งานจะเหมือนกับ UART1 และ UART2 เพียงเปลี่ยนคำนำหน้าเป็น Serial1 และ Serial2 ในแต่ละฟังก์ชั่น เช่น Serial1.begin() Serial1.write() Serial2.read() เป็นต้น

การสื่อสารผ่าน I2C

I2C เป็นโปรโตคอลที่ใช้การสื่อสารแบบซิงโคนัส คิดค้นโดย NXP โดยอาจมีการใช้ชื่ออื่นในการเรียก เช่น 2-wire สำหรับในประเทศไทยมักใช้คำว่า ไอ-สแควร์-ซี (I-squared-C) หรือ ไอ-ทู-ซี (I-two-C) ใช้สายจำนวน 2 เส้นในการสื่อสาร ดังนี้

  • Serial Data (SDA) – เป็นขาที่ใช้รับ-ส่งข้อมูล
  • Serial Clock (SCL) – เป็นขาที่ใช้ควบคุมการรับ-ส่งข้อมูลของอุปกรณ์ปลายทาง

โดยปกติแล้วการใช้การเชื่อมต่อแบบ I2C จะมีตัวต้านทานค่าประมาณ 4.7kΩ – 10kΩ ต่อแบบ Pull-up ที่ขาสัญญาณทั้ง 2 ด้วย แต่ในบางโมดูลจะมีตัวต้านทานต่ออยู่แล้วจึงไม่ต้องต่อเพิ่ม

โปรโตคอลแบบ I2C รองรับการเชื่อมต่ออุปกรณ์ตัวลูก (ไมโครคอนโทรลเลอร์ถือเป็นตัวแม่) มากกว่า 1 ตัว โดยแต่ละตัวจะมีเลขประจำตัวที่เรียกว่า Address เป็นตัวกำหนด หากต้องการคุยกับอุปกรณ์ตัวลูกต้องมีการอ้างอิง Address ก่อนเสมอ

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

การใช้งาน I2C

ในการใช้งาน I2C จะใช้งานผ่านไลบารี่ Wire.h โดยในส่วนหัวจะต้องมีการใช้คำสั่ง

include เสมอ โดยไลบารี่จะสร้างออปเจคขึ้นมาอัตโนมัติชื่อ Wire การใช้งานจะแบ่งเป็นเคสได้ดังนี้

การเริ่มต้นสื่อสาร – ในการเริ่มต้นสื่อสารจะต้องเรียกใช้ Wire.begin() เพื่อกำหนดขาที่จะใช้เป็น SCL และ SDA ซึงมีรูปแบบการใช้งานดังนี้

void Wire.begin(int sda=-1, int scl=-1, long frequency=100000);

มีรายละเอียดของค่าพารามิเตอร์ดังนี้

  • (int) sda – หมายเลขขา GPIO ที่ต้องการใช้เป็นขา SDA มีค่าเริ่มต้นเป็น -1
  • (int) scl – หมายเลขขา GPIO ที่ต้องการใช้เป็นขา SCL มีค่าเริ่มต้นเป็น -1
  • (long) frequency – ความเร็วในการส่งข้อมูล มีค่าเริ่มต้นเป็น 100kHz

และไม่มีการส่งค่ากลับ หากไม่มีการกำหนดค่าในพารามิเตอร์ sda และ scl โปรแกรมจะไปใช้ขาตาม Pinout ซึ่งใน NodeMCU-32S จะใช้ขา GPIO22 เป็น SCL และขา GPIO21 เป็น SDA

การส่งข้อมูล – ใน I2C การจะส่งข้อมูลจะมีฟังก์ชั่นที่เกี่ยวข้องหลาย ๆ ฟังก์ชั่น เนื่องจากการสื่อสารแบบ I2C เป็นแบบกึ่ง 2 ทาง การรับ-ส่งข้อมูลจะต้องรัดกุมเพื่อไม่ให้อุปกรณ์รับ-ส่งข้อมูลชนกันภายในสาย

ฟังก์ชั่น Wire.beginTransmission() ใช้เริ่มการส่งข้อมูลไปยังอุปกรณ์ที่มี Address ที่กำหนด มีรายละเอียดการใช้งานดังนี้

void Wire.beginTransmission(byte address);

มีพารามิเตอร์ตัวเดียว คือ

  • (byte) address – หมายเลขประจำตัวของอุปกรณ์ที่จะสื่อสารด้วย

และไม่มีการส่งค่ากลับ

ฟังก์ชั่น Wire.write() ใช้ส่งข้อมูลขนาด 1 ไบต์ หรือ 8 บิตออกไป โดยก่อนจะใช้ฟังก์ชั่นนี้จะต้องใช้ Wire.beginTransmission() ก่อน ฟังก์ชั่น Wire.write() มีรูปแบบการใช้งานดังนี้

void Wire.write(byte data);

มีพารามิเตอร์ตัวเดียวคือ

  • (byte) data – ข้อมูลที่ต้องการส่งขนาด 1 ไบต์ หรือ 8 บิต

และไม่มีการตอบกลับ

ฟังก์ชั่น Wire.endTransmission() ใช้จบการส่งข้อมูล มีรูปแบบดังนี้

int Wire.endTransmission();

ไม่มีพารามิเตอร์ แต่มีการตอบกลับเป็นข้อมูลชนิด int ซึ่งมีรายละเอียดการตอบกลับดังนี้

  • 0 – รับ – ส่งข้อมูลสำเร็จ
  • 1 – มีข้อมูลที่จะส่งมากเกินไป
  • 2 – อุปกรณ์ตัวลูกไม่ได้รับข้อมูลตาม Address หรือไม่มีอุปกรณ์ตัวลูกที่มี Address ตรงตามที่กำหนด
  • 3 – อุปกรณ์ตัวลูกไม่ได้รับข้อมูล
  • 4 – มีข้อผิดพลาดอื่น ๆ

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

ฟังก์ชั่น Wire.requestFrom() ใช้ร้องขอข้อมูลไปยังอุปกรณ์ตัวลูกตาม Address และความยาวของข้อมูลตามที่กำหนด มีรูปแบบการใช้งานดังนี้

int Wire.requestFrom(byte address, int quantity);

มีพารามิเตอร์ดังนี้

  • (byte) address – หมายเลขประจำตัวของอุปกรณ์ที่จะขอข้อมูล
  • (int) quantity – ความยาวของข้อมูลที่ต้องการร้องขอ มีหน่วยเป็นไบต์

และมีการตอบกลับเป็นความยาวของข้อมูลที่อุปกรณ์ตัวลูกส่งกลับมา

ฟังก์ชั่น Wire.available() ใช้ตรวจสอบว่ามีข้อมูลจากตัวลูกส่งเข้ามาเท่าไร มีหน่วยเป็นไบต์ และมีรูปแบบการใช้งานดังนี้

int Wire.available();

ไม่มีค่าพารามิเตอร์ และมีการตอบกลับมาเป็นความยาวข้อมูลที่ส่งเข้ามา มีหน่วยเป็นไบต์

ฟังก์ชั่น Wire.read() ใช้อ่านค่าที่อุปกรณ์ตัวลูกส่งเข้ามา โดยอ่านได้ครั้งละ 1 ไบต์ มีรูปแบบการใช้งานดังนี้

byte Wire.read();

ไม่มีพารามิเตอร์ และตอบกลับเป็นข้อมูลที่อ่านได้จำนวน 1 ไบต์

ตัวอย่างการใช้งาน PCF8574

PCF8574 เป็นไอซีที่ช่วยขยาย I/O หรือขับอุปกรณ์ต่าง ๆ แทนไมโครคอนโทรลเลอร์ โดยใช้การเชื่อมต่อผ่าน I2C มีการใช้งานที่ง่าย โดยสามารถส่งข้อมูลที่ต้องการควบคุม I/O ออกไปได้เลย

ก่อนอื่นต้องมาทำความเข้าใจกับ Address ก่อน ตัวไอซี PCF8574 สามารถกำหนด Address ได้โดยใช้ขา A0 A1 และ A2 ทั้งนี้แม้จะตั้งลอจิกขา A0 A1 A2 เหมือนกัน แต่อาจจะให้ตำแหน่งไม่เหมือนกัน เนื่องจาก PCF8574 จะมีทั้งรุ่นธรรมดา และรุ่นอักษรท้ายเป็น A เมื่อกำหนดขา A0 A1 A2 แล้ว ต้องนำค่าที่กำหนดมาพิจารณาเป็น Address ตามตารางด้านล่างนี้

สถานะของขาต่าง ๆ

ตำแหน่ง Address

A2 A1 A0 PCF8574 PCF8574A LOW LOW LOW 0x20 0x38 LOW LOW HIGH 0x21 0x39 LOW HIGH LOW 0x22 0x3A LOW HIGH HIGH 0x23 0x3B HIGH LOW LOW 0x24 0x3C HIGH LOW HIGH 0x25 0x3D HIGH HIGH LOW 0x26 0x3E HIGH HIGH HIGH 0x27 0x3F

เมื่อรู้ตำแหน่งแล้ว ให้ต่อวงจรตามรูปด้านล่างนี้ได้เลย

สังเกตว่าการใช้งาน PCF8574 จะต่อวงจรแบบ Active LOW ให้หลอด LED เนื่องจากผู้เขียนได้ทดสอบแล้วว่าการต่อแบบ Active HIGH ไม่สามารถนำไปใช้งานได้จริง เนื่องจากการจัดวงจรภายในไอซีเองทำให้การปล่อยลอจิก 1 หรือสถานะ HIGH มีค่าความต้านทานสูงจนอุปกรณ์ที่ต่ออย่างหลอด LED ทำงานได้ไม่เต็มที่ จึงเปลี่ยนวงจรมาต่อแบบ Active LOW ซึ่งใช้สถานะทางลอจิก 0 หรือสถานะ LOW ในการทำงานแทน

ในการต่อใช้งานโปรโตคอลแบบ I2C หากเป็นการต่ออุปกรณ์ตัวลูกเพียงชิ้นเดียว สามารถยกเว้นตัวต้านทาน Pull-up ที่ขา SDA และ SCL ได้ ทำให้ประหยัดอุปกรณ์ในการทดลองมากขึ้น

หลังจากต่อวงจรเรียบร้อยแล้ว ให้อัพโหลดโปรแกรมด้านล่างนี้ (แก้ตำแหน่งอุปกรณ์ในบรรทัดที่ 3) ลงบอร์ด

จะพบว่า หลอด LED จะติดครั้งละ 4 ดวงแบ่งเป็น 2 ฝั่งกระพริบสลับกันไปมา ซึ่งสามารถอธิบายโค้ดโปรแกรมได้ดังนี้

บรรทัดที่ 1 ใช้คำสั่ง

include เพื่อใช้งานไลบารี่ Wire.h สำหรับติดต่อสื่อสารผ่าน I2C

บรรทัดที่ 2 ไม่นำมาวิเคราะห์

บรรทัดที่ 3 ใช้คำสั่ง

define แทนที่คำว่า ADDR ด้วยตำแหน่ง Address ของอุปกรณ์

บรรทัดที่ 4 ไม่นำมาวิเคราะห์

บรรทัดที่ 5 สร้างฟังก์ชั่นย่อย PCF_Write() สำหรับใช้ส่งข้อมูลไปที่อุปกรณ์ โดยมีพารามิเตอร์ data รับข้อมูลที่จะส่งเข้ามา

บรรทัดที่ 6 ใช้ฟังก์ชั่นเริ่มต้นการส่งข้อมูลผ่าน I2C ไปอุปกรณ์ตำแหน่ง ADDR

บรรทัดที่ 7 ส่งข้อมูลไปยังอุปกรณ์โดยใช้ข้อมูลจากพารามิเตอร์ data ที่รับเข้ามา

บรรทัดที่ 8 ใช้ฟังก์ชั่นจบการรับ-ส่งข้อมูลผ่าน I2C

บรรทัดที่ 9 จบคำสั่งในฟังก์ชั่นย่อย PCF_Write()

บรรทัดที่ 10 ไม่นำมาวิเคราะห์

บรรทัดที่ 11 สร้างฟังก์ชั่น setup

บรรทัดที่ 12 ใช้คำสั่งเริ่มต้นการใช้งาน I2C โดยใช้ค่าในพารามิเตอร์เป็นค่าเริ่มต้นทั้งหมด

บรรทัดที่ 13 จบคำสั่งในฟังก์ชั่น setup

บรรทัดที่ 14 ไม่นำมาวิเคราะห์

บรรทัดที่ 15 สร้างฟังก์ชั่น loop

บรรทัดที่ 16 ใช้ฟังก์ชั่น PCF_Write() ส่งข้อมูล B00001111 ออกไป (การใช้ B นำหน้าตัวเลขคือการป้อนข้อมูลแบบเลขฐาน 2 โดยให้คิดว่าเลข 1 แทนให้หลอด LED ตำแหน่งนั้น ๆ ติด และเลข 0 แทนหลอด LED ตำแหน่งนั้น ๆ ดับ)

บรรทัดที่ 17 หน่วงเวลาครึ่งวินาที หรือ 500 มิลิวินาที

บรรทัดที่ 18 ใช้ฟังก์ชั่น PCF_Write() ส่งข้อมูล B11110000 ออกไป

บรรทัดที่ 19 หน่วงเวลาครึ่งวินาที หรือ 500 มิลิวินาที

บรรทัดที่ 20 จบคำสั่งในฟังก์ชั่น loop

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

การแก้ปัญหาอุปกรณ์ที่สื่อสารผ่าน I2C ไม่ทำงาน

ปัญหาอุปกรณ์ I2C ไม่ทำงานตามที่ได้เขียนโปรแกรมไว้สามารถพบได้บ่อยครั้ง การแก้ปัญหาเบื้องต้นคือการตรวจสอบการต่อวงจรว่าถูกต้องหรือไม่ สำหรับทางด้านซอฟแวร์จะมีโค้ดที่ใช้ตรวจสอบว่าไมโครคอนโทรลเลอร์หรือ ESP32 สามารถติดต่อกับอุปกรณ์ตัวใดได้บ้าง รวมทั้งสามารถบอกได้ว่าอุปกรณ์ตัวนั้น ๆ มีตำแหน่ง Address เป็นอะไร โดยโค้ดที่ใช้มีชื่อว่า I2cScanner เนื่องจากโค้ดจะยาวมาก ดังนั้นจึงแนะนำให้เข้าไปคัดลอกจาก //playground.arduino.cc/Main/I2cScanner ได้เลย

หลังจากอัพโหลดโค้ดไปแล้ว ในหน้าต่าง Serial Monitor จะแสดงผลอุปกรณ์ที่ค้นหาเจอ พร้อมแสดงผลตำแหน่งของอุปกรณ์นั้น

การสื่อสารผ่าน SPI

SPI ย่อมาจาก Serial Peripheral Interface ถือเป็นบัสสื่อสารยอดนิยมอีกตัวหนึ่ง มีความสามารถในการเชื่อมต่ออุปกรณ์หลาย ๆ ตัวเข้าด้วยกันโดยใช้สายเส้นเดียวกัน การทำงานจะใช้สายสัญญาณ 2 เส้นในการรับ-ส่งข้อมูล และมีขาควบคุมการรับ-ส่งข้อมูล การใช้งานจะแบ่งเป็นตัวแม่ (Master) ซึ่งเป็นไมโครคอนโทรลเลอร์ และตัวลูก (Slave) คืออุปกรณ์ที่นำมาต่อเพื่อสื่อสารด้วย

การสื่อสารผ่านบัส SPI มีสายสัญญาณจำนวน 4 เส้น คือ

  • MOSI (Master-Out Slave-In) – เป็นสายที่ใช้ส่งสัญญาณข้อมูลจากตัวแม่ออกไปยังตัวลูก
  • MISO (Master-In Slave-Out) – เป็นสายที่ใช้รับสัญญาณจากตัวลูก
  • SCK (Serial Clock) – เป็นสายควบคุมจังหวะการรับ – ส่งข้อมูล
  • /SS (Slave Select, Active-Low) หรือ CS – เป็นสายใช้ควบคุมอุปกรณ์ที่ต้องการจะคุยด้วย

สำหรับขา MOSI MISO SCK แต่ละอุปกรณ์จะใช้งานสายทั้ง 3 นี้ร่วมกัน แต่สำหรับ /SS หรือ CS จะต้องใช้แยกกันในแต่ละอุปกรณ์ เมื่อไมโครคอนโทรลเลอร์ต้องการสื่อสารกับอุปกรณ์ตัวใดจะต้องดึงสถานะขา /SS หรือ CS เป็น LOW จึงจะเริ่มการสื่อสารได้

การใช้งาน SPI

ในการใช้งาน SPI จะต้องอ้างอิงจากอุปกรณ์ที่จะสื่อสารด้วย โดยอุปกรณ์แต่ละตัวจะใช้ SPI ในการสื่อสารไม่เหมือนกัน และบางครั้งชื่อขาจะไม่ระบุโดยตรงว่าเป็น MOSI MISO แต่จะใช้ชื่อขาอื่น ๆ แทน ซึ่งจะต้องดูข้อมูลจากผู้ผลิตเป็นหลัก

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

สรุปท้ายบท

ในการใช้งานการสื่อสารแบบอนุกรมจะแบ่งออกได้หลายโปรโตคอล ซึ่งแต่ละโปรโตคอลจะใช้สาย และรูปแบบการสื่อสารที่ต่างกัน ทั้งแบบการใช้สัญญาณซิงค์เพื่อควบคุมการรับข้อมูล (Synchronous) และไม่ใช้สัญญาณซิงค์ (Asynchronous) ซึ่งการใช้อุปกรณ์ที่สื่อสารแบบอนุกรมมักมีคนเขียนไลบารี่ไว้รองรับแล้ว ทำให้เราสามารถใช้งานอุปกรณ์นั้นได้โดยง่ายโดยไม่จำเป็นต้องเข้าไปทำความเข้าใจอุปกรณ์นั้นลึก ๆ สำหรับบทถัดไปจะเป็นการนำเซ็นเซอร์ต่าง ๆ มาใช้งานร่วมกับ ESP32 ซึ่งบางตัวใช้การสื่อสารแบบ UART I2C หรือ SPI ฉะนั้นข้อมูลในบทนี้จึงช่วยปูพื้นฐานการใช้งานอุปกรณ์เหล่านั้นได้เป็นอย่างดี

Toplist

โพสต์ล่าสุด

แท็ก

ไทยแปลอังกฤษ แปลภาษาไทย ห่อหมกฮวกไปฝากป้าmv โปรแกรม-แปล-ภาษา-อังกฤษ พร้อม-คำ-อ่าน แปลภาษาอาหรับ-ไทย Terjemahan ข้อสอบคณิตศาสตร์ พร้อมเฉลย แปลภาษาอังกฤษเป็นไทย pantip ศัพท์ทางทหาร military words แอพแปลภาษาอาหรับเป็นไทย การ์ดแคปเตอร์ซากุระ ภาค 4 พจนานุกรมศัพท์ทหาร ศัพท์ทหาร ภาษาอังกฤษ pdf ห่อหมกฮวกไปฝากป้า หนังเต็มเรื่อง ไทยแปลอังกฤษ ประโยค lmyour แปลภาษา การ์ดแคปเตอร์ซากุระ ภาค 3 ประปาไม่ไหล วันนี้ ฝยก. ย่อมาจาก หยน ห่อหมกฮวก แปลว่า เมอร์ซี่ อาร์สยาม ล่าสุด แปลภาษาจีน ่้แปลภาษา onet ม3 การ์ดแคปเตอร์ซากุระ ภาค 1 ข้อสอบโอเน็ต ม.3 ออกเรื่องอะไรบ้าง ตตตตลก บบบย ห่อหมกฮวกไปฝากป้า คาราโอเกะ เขียน อาหรับ แปลไทย เนื้อเพลง ห่อหมกฮวก แปลไทย asus zenfone 2e กรมส่งเสริมการปกครองท้องถิ่น การประปานครหลวง ก่อนจะนิ่งก็ต้องกลิ้งมาก่อน เนื้อเพลง ข้อสอบภาษาอังกฤษ ม.ปลาย พร้อมเฉลย คะแนน o-net โรงเรียน ชขภใ ชื่อเต็ม ร.9 คําอ่าน ตัวอย่าง flowchart ขั้นตอนการทํางาน นยน. ย่อมาจาก ทหาร บทที่ 1 ที่มาและความสําคัญของปัญหา ฝสธ. ย่อมาจาก มัดหัวใจเจ้าชายเย็นชา 2 ซับไทย มัดหัวใจเจ้าชายเย็นชา 2 เต็มเรื่อง ยศทหารบก เรียงลําดับ ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้างและการบริหารพัสดุภาครัฐ พ.ศ. 2560 รัชกาลที่ 10 ห่อหมกฮวกไปฝากป้า คอร์ด