C# Interface Arduino ผ่าน serial port และ Auto-Detect comport

1. เขียน C# คุยกับ Arduino แบบง่ายๆ

       เริ่มจากการเขียนฝั่ง C# ก่อน โดยสร้าง Windows form เล็กๆขึ้นมา 

       จากนั้นภายใน Code เรียกใช้ IO.Ports กับ threading เอาไว้ sleep หน่วงเวลา

       และประกาศตัวแปร SerialPort ไว้

       ใน event ของ form load เราก็จะมาประกาศ new serialport ที่ "COM10" ซึ่งเป็น comport ของ arduino ที่กำลังต่ออยู่กับคอม

       แล้วก็ set baudrate ในนี้ใช้ 9600 จากนั้นก็สั่ง Open port เลย

       ใน event ของปุ่มกด เราจะทำการ clear buffer ทั้งขาเข้าและออกของ Serial port ก่อนจะกระทำการส่งข้อมูลใดๆ แล้วก็ส่งข้อความ string ว่า "Hello!! from C#\n" ใส่ "\n" ไปด้วยเพื่อเป็นเงื่อนไขในการจบการส่งข้อมูลที่จะส่งให้ arduino จากนั้นหน่วงเวลา 100ms โดยใช้ Thread.Sleep เนื่องจากว่า Process มันไม่ได้มีอะไรเยอะแยะ จึงใช้อะไรง่ายๆ เพื่อรอ arduino ตอบกลับ และเราก็อ่านค่าจาก serial port แล้วก็ใช้ MessageBox ในการแสดงข้อมูลนั้น

       ทีนี้มาในฝั่งของ arduino กันบ้าง เริ่มจากการประกาศตัวแปร inputString เอาไว้เก็บค่าที่อ่านจาก serial port และ stringComplete เอาไว้เช็คว่าข้อความนั้นสมบูรณ์แล้วหรือยัง

ใน setup ก็แค่ begin serial port ที่ baudrate 9600

จากนั้นก็สร้าง serialEvent ขึ้นมาเพื่อใช้ ในการคอยอ่านค่าที่ส่งเข้ามาใน Serial port

       เมื่อมีข้อมูลเข้ามา inputString จะรวบรวม chractor จาก inChar จนกว่าจะเจอ "\n" ที่ส่งเเข้ามาจาก C# เพื่อบอกว่าครบประโยคแล้ว จากนั้นจึงเปลี่ยนให้ stringComplete เป็น Ture ซึ่งใน serialEvent เราจะไม่ Process อะไรเยอะแยะ เพราะจะเอาไว้แค่คอยรับ data จาก serial port เท่านั้น อย่างอื่นเราจะไปทำใน loop

       ใน loop เราจะเช็คว่า stringComplete เป็น True หรือไม่

เมื่อเป็น True แล้ว จะให้ค่าของ inputString เปลี่ยนเป็นตัวพิมพ์เล็กทั้งหมด เพื่อให้ง่ายในการตรวจสอบ 

แล้วก็จะเช็คว่า data ที่เข้ามาเป็น string ว่า "hello!! from c#\n" หรือไม่ 

ถ้าใช่ ก็จะส่งคำว่า "Hello!! from Arduino" กลับไป

แล้วก็เปลี่ยน inputString ให้เป็นค่าว่าง และ stringComplete ให้เป็น false เพื่อรอ data ครั้งต่อไป

       ทีนี้ลองมาทดสอบดูเมื่อกดปุ่ม button1 ส่งข้อมูลไปให้ arduino เราก็จะได้รับข้อความมาจาก arduino คือ "Hello!! from Arduino" ตามที่เราเขียนไว้

2. C# หา comport ของ Arduino และ Connect แบบ อัตโนมัติ

       หลักการก็คือถ้าเราไม่รู้ว่า arduino นั้นเป็น comport อะไร ให้เราส่งอะไรสักอย่างไปถาม arduino แล้วให้มันตอบกลับมาว่าใช่ arduino ของเราหรือเปล่านั่นเอง ยกตัวอย่างเช่น arduino nano ใช้ Chip ttl เป็น CH340 comport ก็จะชื่อ USB-SERIAL CH340 (COMxx) เราก็จะใช้ชื่อนี้เป็น keyword ในการกรองค้นหาอันดับแรก ทีนี้เราก็เพิ่ม button ใหม่มาอันนึง และสร้างฟังก์ชั่นขึ้นมาบน C# ฟังก์ชั่นนึง แล้ว เรียกใช้ System.Management เพิ่มด้วย

form load จะเหลือแค่ set enable button อย่างเดียว

ในฟังก์ findcomport จะทำงานดังนี้

34 เราจะสร้าง boolean flagbutton1 มาเพื่อเอาไว้เซ็ต enable ปุ่ม send

35,36,37 จะให้ objOSDetails หาค่าพวก  device ที่มีสถานะเป็น comport

38 ให้ osDetailsCollection เก้บค่าว่ามี comport อะไรอยู่บ้าง

40 เราจะ foreach comport ทั้งหมดใน osDetailsColletion มาใส่ usblist ทีละตัว

42 เช็ค "Description" ของ usblist ทีละตัวว่าอันไหนเป็น "USB-DERIAL CH340" 

44 เมื่อเราเจอแล้ว เราจะได้ชื่อเต็มๆมาเป็น USB-SERIAL CH340 (COMxx) ดังนั้นเราจึงต้อง split วงเล็บ '(' ')' ออก แล้วเราจะได้ arrport ที่มี array 3 ตัวดังรูป

46 แล้วก็เอาตัวแปร portX เก็บค่า array ที่ 1 ไว้ เพราะมันคือ COM10 จากนั้นก็ใส่ try catch ดัก error ไว้ตอนที่ open comport ไม่ได้ จากนั้นก็ เซ็ต port แล้ว open เหมือนเดิม และ clear buffer ก่อนที่จะยิง string ไปว่า "My Arduino?\n" แล้วรอ 100ms จากนั้นอ่านค่าจาก Serial port ออกมา

58 เอาตัวแปร  string data แปลงเป็นตัวพิมพ์เล็กทั้งหมด

59 ใช้ if มาดักหาคำว่า "i am arduino" ที่ arduino เราจะส่งกลับมา ตรงนี้เราใช้ Cotains แทน == เพราะว่าจะได้ไม่ต้องใส่ "\r\n" ที่ arduino ส่งมาด้วย เมื่อได้คำตอบแล้วก็จะเปิดปุ่ม send ให้ส่ง data ได้แล้ว break foreach เลย แต่ถ้าไม่ใช่ ใน else เราจะ close port ก่อนไปหา port ต่อไป 

จากนั้นก็เอาฟังก์ชั่นนี้ไปใส่ใน event ปุ่ม connect

โดยใส่ try catch ปิด comport ทุกครั้งที่กดเผื่อไว้

ทีนี้ในฝั่งของ arduino เราเพิ่มแค่ else if เดียว

จากนั้นก็ลองทดสอบ

ปุ่ม send จะปิดไว้จนกว่าจะ connect arduino ได้

******************

แต่ถ้าเรามี arduino หลายตัว connect ถ้าจะเขียน firmware arduino ให้ตอบกลับมาคนละคำ ก็คงไม่ไหวเพราะถ้ามันทำงานเหมือนกัน  เราก็คงไม่อยากจะแก้ firmware หลายรอบ เพราะงั้นเราจึงใช้ทริคเล็กๆ มาช่วยแก้ปัญหานั้น โดยการทำให้ arduino มี address เหมือน I2C ดังนี้

กำหนดให้ pin arduino สัก 3 pin เป็น input ในนี้จะเป็น A0 A1 A2

เมื่อถูกถามมาก็ให้ arduino ตอบกลับไปพร้อม address ของตัวมันเอง

ฝั่งของ C# เราก็ตั้งรับใหม่เป็นค่า address ที่ arduino จะส่งมาด้วย

ทีนี้ถ้ามี arduino หลายตัวเราก็แค่ pullup pulldown pin address ของเราตามต้องการ ซึ่ง 3pin นี้ก็จะได้ address ที่ต่างกันถึง 2^3 = 8 ตัว


โหลด CODE ทดลองที่นี่


Tokusatsu Kamen Rider GIF - Tokusatsu KamenRider KamenRiderZiO GIFs


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

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