IoT platform

ต้นปีนี้ว่างงานมากขึ้น งบประมาณรัฐไม่ออกสักที เลยต้องหาอะไรทำ ประกอบกับมีที่ดินสำหรับทดลองทำอะไรๆละ ก็เลยกลับมาดูเรื่อง IoT อีกครั้ง
ตั้งใจจะขายอปุกรณ์พร้อมแพลตฟอร์มอาจจะเก็บรายเดือนสำหรับ dashboard หรือรวมไปในค่าอุปกรณ์เลย เช่นชุด weather station ชุดใหญ่

ทีนี้กลับมาอีกที เลือกลอง ThingsBoard ก่อน เหมือนเริ่มใหม่ งงๆ แต่ดันอยากให้ dash board ดูกล้องได้ด้วย ก็เลยออกนอกเส้นทาง ไปคุ้ยๆที่เคยลองเล่น นั่นคือ webRTC อยากรู้ว่า จะเอาไปใส่เข้าใน dash board ได้หรือไม่
แต่ก่อนหน้านั้น ก็ต้องไปรื้อฟื้นว่า webRTC มันคืออะไร จะเอามาใช้งานอย่างที่คิดได้มั้ย เสียเวลาไปอีก
หาๆไป ก็ไปแฉลบออกไปทาง Node-Red เพราะไป search เจอว่ามันมีปลั๊กอิน webRTC ด้วย แต่ก็ยังหาไม่เจอว่าใช้งานยังงัย
ก็เลย ลง Node-Red อีกตัวแม่งเลย

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

พอดูๆไป เออ Node-RED มันทำ UI ในการสร้าง flow ได้น่าเล่นแหะ ก็เลยว่าจะลองบน Node-Red ก่อนละกัน

คีออส เคออส 2023

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

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

มาปีนี้ปีสุดท้าย ปีหน้าจะขึ้นเลข 5 ละ โลกเริ่มมาทาง ai จริงๆเราก็เริ่มเตรียมตัวก่อนใครนะ แต่รู้สึกว่าจะกลายเป็นเต่าไปละ ตามไม่ทัน อย่างเรื่อง chat GPT ก็ยังไม่เคยได้ลองเล่นจริงจังกับเค้าเลย

เรื่องหุ่นยนต์อัตโนมัติ เดี๋ยวนี้ก็ไปไกลกว่าการใช้ล้อละ มีทั้งเดิน 2 ขา 4 ขา หลายขา รวมถึงการนำทาง เรื่อง vision ไปจนถึง lidar

ในเรื่องของ smart farming ก็นั่งดูและทดลองสั่งเซ็นเซอร์ต่างๆ มา รวมถึงสินค้าที่เคยขายดีอย่าง weather station ตอนนี้ก็เงียบๆไป เนื่องด้วยเพราะผมเงียบๆไปด้วยแหละ ไม่ได้เขียนบล็อกเขียนอะไรมากระตุ้นยอดขายให้ร้านเลย

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

พอพิมพ์มาถึงตรงนี้ ก็ได้ไอเดียโปรเจ็คกระตุ้นเศรษฐกิจใหม่ละ ฮ่าๆ ขอไปเตรียมของก่อน

smart card reader

ว่าด้วยเรื่องของ smart card reader แบบบัตร EMV เจาะจงลงไปที่ใช้ interface แบบ USB port ด้วย

เคยเขียนโปรแกรมอ่านบัตรประชาชนผ่านเครื่องอ่านแบบ USB บน Windows มาเมื่อหลายปีก่อน ถึงแม้จะใช้ Linux มาอย่างยาวนาน แต่ก็ไม่เคยพอร์ทโค้ดมาลงสักที เนื่องจากไม่เคยมีลูกค้า request มาเลย จนกระทั่งช่วงนี้ ทาง บางกอกเดฟ ได้ทำการขึ้นโมเดลตู้คีออสใหม่ และ ใช้จอ open frame แบบ all-in-one โดยได้ built-in บอร์ดคอมพิวเตอร์เข้าไปด้วย สามารถเลือกได้ทั้ง PC และ Android

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

บน Windows มีไลบราลี่ชื่อ winscard เอาไว้จัดการกับการอ่านบัตร smart card ส่วนบน Linux ก็มีโมดูลที่แทบจะ compatible กับ winscard เลย ชื่อ pcsc (คือมันมีส่วนที่เป็น daemon และ lib สำหรับการทำงาน) ผมก็ลอง port โปรแกรมที่เคยรันบน windows มาทำให้รันบนลินุกส์ได้ ก็ไม่ยากเย็นเท่าใดนัก จากนั้นจึงมาลองศึกษาหาวิธีการเพื่อให้สามารถอ่านบัตรประชาชนด้วยเครื่องอ่านที่มี interface แบบ USB ได้บน Android ดูบ้าง

โดยเริ่มจากวิธีคิดว่า แอนดรอยด์ มันก็คือลินุกส์ น่ะแหละ มันต้องใช้วิธีการคล้ายๆกัน ก็เริ่มไล่ไปจาก interface ก่อนคือ USB อันนี้ผมยังยึดการเขียนโปรแกรมด้วย Qt/C++ ไว้นะ เมื่อลองดู dependencies ของ pcsc ก็จะพบว่ามันใช้ libUSB ด้วย CCID ด้วยรึป่าว ยังไม่แน่ใจ ก็เลยเริ่มด้วยการคอมไพล์ libUSB ก่อนเลย

ผมเป็น android dev มือใหม่ คือว่า ถึงแม้จะเขียนมาหลายที แต่ห่างกันหลายปีจะเขียนสักครั้ง ก็ลืมหมดทุกสิ่งอย่าง เหมือนมาเริ่มต้นใหม่น่ะแหละ ก็ต้องทำการ set up dev env กันใหม่ โดยเฉพาะ NDK ส่วน SDK ก็ได้ตัวช่วยคือ Qt Creator ในการเลือกลงแพคเกจเวอร์ชั่นต่างๆ

ปัญหาคือ pcsc นี่ละ ที่มีทั้ง lib และ deamon จะคอมไพล์ออกมาอย่างไร คอมไพล์ออกมาแล้วจะรันอย่างไร ตรงนี้เสียเวลาไปหลายวันในการหยิบจับโค้ดที่เค้าเคยทำๆกันมาแล้วมาลอง แต่ก็น่าประหลาดใจว่า มันเป็นเรื่องเก่ามาตั้งแต่ 8-9 ปีที่แล้วนู่นเลย ทำให้ประสบปัญหาการคอมไพล์มาก เพราะจาก android 7 มันก็เปลี่ยนเครื่องมือในการคอมไพล์และสร้างแพคเกจไปหมดเลย ไม่รวมถึง lib ที่มีการเปลี่ยนแปลงไปด้วย ไม่ compat กับของเดิม ก็นั่งมั่วนิ่มจนคอมไพล์ผ่านมาได้ จนมาติดกับการสร้าง apk ก็เลยท้อใจ หยุดไว้ก่อน ลองมาหาวิธีอื่นดูบ้าง

จากที่ลองหาข้อมูลดู ก็อาจจะต้อง เขียนขึ้นมาเองใหม่หมด โดยไม่ใช้ pcsc แต่ใช้การรับส่งข้อมูลโดยมองมันเป็น USB device ไปเลย โดยต้องใช้การหา file description หรือ file handle ของ USB deivce ตัวนี้ให้ได้ซะก่อน ตรงนี้อาจจะต้องเขียนด้วย Java แล้วค่อยส่งมาให้โค้ด C++ ต่อ อันนี้ก็เพื่อไม่ต้องเปลี่ยนโค้ด UI ที่เขียนด้วย QML ไว้แล้ว

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

webRTC

สำหรับการทำ streaming

จากคราวที่แล้วที่ลองเล่น openHAB ก็เกิดสงสัยขึ้นมาว่า ถ้าเราต้องการเพิ่มอุปกรณ์ที่เป็นกล้องเข้าไปจะต้องทำยังงัย เพิ่มกล้องที่ใช้ๆกันทั่วไป อย่าง xiaomi ได้มั้ย หรือ ถ้าจะทำขึ้นมาเองจาก raspberry pi zero ละ ทำได้หรือเปล่า ก็เลยต้องมานั่งค้นหาข้อมูลและทดลองทำกันดู

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

https://stackoverflow.com/questions/29830728/streaming-video-of-wifi-access-point-camera-to-a-remote-computer

ในโจทย์เดิม ก็มีวิธีทำแบบอื่นๆ อย่างเช่น ใช้ tinc VPN โดยอาศัย VPS หรือ cloud server เป็นตัวกลาง อันนี้ก็น่าสนใจ แต่เราจะลองวิธีที่น่าสนใจที่สุดอันนึง ก็คือ webRTC เริ่มด้วย

ลง janus บน VPS เนื่องจากเราต้องการเข้าถึงกล้องได้จากทุกที่ผ่านอินเตอร์เน็ต
ทำ reverse proxy ด้วย nignx
ทำ SSL ให้ nginx ด้วย certbot ลง package ได้เลย ง่ายๆ

ทดลองเล่น janus ดูแล้ว ต่อไป ก็ทำ POC ทำให้กล้อง IP camera ดูผ่านเน็ตได้

ผมต้องการทำ rasberry pi zero ที่เคยต่อกล้องเป็น wifi ip camera เดิม ให้ดูผ่านเน็ตได้ ด้วย Janus (เพื่อความง่าย เพราะยังไม่ต้องลงมือเขียนโปรแกรมอะไร)

ก็เริ่มด้วยการลงแพคเกจต่างๆของ UV4L ที่ทำให้มันรองรับ webRTC ด้วย

หลังจากนั้น ก็มาเซ็ตให้มันรู้จัก Janus แล้วก็ บิงโก!!! ด้วยหลักการของ webRTC มันไม่ควรจะใช้แบนด์วิธของ เครื่องที่ลง Janus (ในที่นี้คือ VPS) มาก แล้วเท่าที่ดูกราฟ traffic ที่เกิดขึ้น ก็เป็นอย่างนั้นจริงๆ เย้ ทีนี้ก็ไม่ต้องยุ่งยาก เวลาติดกล้องแล้วส่งสตรีมด้วย sim 3G/4G หรือ ผ่าน wifi ในสถานที่ห่างไกลละ

มาทำ smart home ด้วย openHAB กัน

วันนี้ผม กับ IoT e-shop จะมารีวิว การควบคุมการเปิดปิดหลอดไฟภายในบ้าน ผ่านแอพบนมือถือกัน สั้นๆก็ว่ากันแบบนี้ ยาวอีกหน่อยก็คือ มาลองเล่น openHAB และ tasmota เพื่อทำระบบ smart home กันครับ

เริ่มแรกเลย เรามาดูกันว่า ในการที่จะทำแบบนั้นได้ เราต้องการอะไรบ้าง
1. platform สำหรับควบคุมการเปิดปิดอุปกรณ์ต่างๆ ไม่ว่าเราจะอยู่ที่ไหน (ขอให้มีเน็ต) ผ่านแอพบนมือถือ โดย platform ที่เราจะนำมาใช้ ชื่อ openHAB โดยเราจะทำการลงระบบบน VPS
สำหรับใครที่ไม่มี หรือไม่ได้เช่า VPS เอาไว้ ก็สามารถลงแบบ local ได้ สามารถลงได้ทั้งบน pc และ raspberry pi
2. smart switch หรือ อุปกรณ์ที่ทำให้เราสามารถสั่งเปิดปิดหลอดไฟได้ ในที่นี้เราก็จะใช้ ESP8266 + relay
โดย protocol ที่ทำให้ทั้งสองอันมาเชื่อมต่อกันได้ ก็คือ Mosquitto เช่นเคย นั่นเอง

การลง openHAB
รายละเอียดขั้นตอนในการลง openHAB บนระบบต่างๆ สามารถดูได้จาก document บนเว็บไซต์ของ openHAB
ในคราวนี้ผมจะลงบน Linux Ubuntu ก็แนะนำให้ทำตามนี้เลยครับ
https://www.openhab.org/docs/installation/linux.html
โดยขั้นตอนแรก ควรจะเช็ค JVM ว่าใช้งานเวอร์ชั่นอะไรอยู่ แต่โดยปกติก็ต้องลงใหม่ละครับ openHAB ต้องการเวอร์ชั่น 11 และแนะนำให้ลงจาก Azul Zulu ตามลิ้งนี้
https://docs.azul.com/core/zulu-openjdk/install/debian
หลังจากนั้นค่อยลง openHAB ตามลิ้งด้านบน

การลง MQTT broker
เนื่องจาก เราจะใช้งาน MQTT ในการควบคุมอุปกรณ์ของเรา ดังนั้นจึงต้องทำการลง MQTT broker ก่อน ในตอนนี้เราจะยังไม่ไปเซ็ตค่าอะไรให้ยุ่งยาก เช่น user/password หรือ secure channel
รายละเอียด ดูได้จาก https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-18-04

เมื่อทำการลง MQTT broker แล้ว เราก็จะสามารถลง add-on MQTT broker ใน openHAB ได้ละ โดย ทำตามนี้ https://community.openhab.org/t/oh3-mqtt-setup-and-configuration/111494

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

ในขั้นตอนนี้ เริ่มต้นด้วย การอัพโหลด firmware ที่ชื่อ tasmota เข้าไปใน ESP8266
https://tasmota.github.io/docs/
คราวนี้ผมใช้บอร์ด NodeMCU รุ่นเก่าๆนี่ละ เอามาเล่น โดยจากภาพจะเห็นได้ว่า ผมจ่ายไฟและต่อ serial port ผ่านทาง port USB ของมัน ซึ่งทำให้ง่ายต่อการ flash image ไฟล์ .bin ด้วยโปรแกรม ที่ชื่อ tasmotizer


เมื่อทำการ flash แล้ว เราจะสามารถหา WIFI SSID ของบอร์ด เพื่อเชื่อมต่อเข้าไปทำการคอนฟิกค่าเครือข่าย SSID ที่เราจะให้ ESP8266 ไปเกาะได้ ซึ่งก็คือเน็ตบ้านของเรานั่นเอง หลังจากนั้น เราก็จะสามารถเข้าถึง web UI ของบอร์ดนี้ได้จากเครือข่ายปกติละ


ขั้นต่อมา คือการ config module เมื่อเลือกเข้าไปแล้ว เราจะสามารถทำการกำหนดว่า เราจะใช้ pin ไหนเป็น input หรือ output ในที่นี้ ผมเล่นง่ายๆก่อนๆ กำหนดให้มันเป็น SONOFF BASIC ใช้ขา GPIO1 เพื่อควบคุมรีเลย์ 1 ตัว
ต่อมาก็ทำการกำหนดค่า config MQTT โดยที่เราต้องสนใจก็คือ ค่า host และ topic
โดย host ก็คือ URL หรือ IP ของเครื่องที่ลง MQTT broker
และ topic คือหัวข้อที่เรากำหนดขึ้นสำหรับการควบคุมรีเลย์

เมื่อทำการบันทึกค่าเรียบร้อยแล้ว เราสามารถทดลองสั่ง toggle เปลี่ยนค่า เพื่อทำการ on/off รีเลย์ดูได้ ถ้าถูกต้อง รีเลย์ก็จะเปิด/ปิด สลับกันไปในแต่ละครั้งที่เรากด toggle

เมื่อกำหนดค่าอุปกรณ์เรียบร้อย ก็กลับมาฝั่ง openHAB เราจะทำการ bniding โดยการสร้าง generic MQTT Thing ขึ้นมา โดยค่าที่สำคัญที่ต้องกำหนด คือ ผูก broker ที่เราสร้างไว้ข้างต้น และกำหนด topic ให้ตรงกับอุปกรณ์ตรงค่า Availability Topic โดยปกติจะเซ็ตเป็น tele/<TOPIC>/LWT
หากทำถูกต้อง เราจะเห็นสถานะ เป็น online ทั้ง Thing และ broker
ต่อมาเราจะทำการสร้าง channel ขึ้นเพื่อควบคุม relay โดยเลือกไปที่ tab Add Channel เลือก type เป็น on/off switch ตั้งชื่อเป็น power และทำการกำหนดค่าต่างๆให้ topic รายละเอียดขั้นตอนให้ดูได้จากลิ้งนี้ครับ
https://community.openhab.org/t/oh3-tasmota-relay-via-mqtt-sonoff-basic-with-optional-dht22/111485
ขึ้นตอนต่อไปก็คือ การ add equipment to model ในขึ้นตอนนี้ ถ้าไม่มีการเซ็ตโมเดลมาก่อน ก็ไม่เป็นไรครับ มันก็จะเป็น NULL ไป ให้เราไปเซ็ตค่าอื่นๆ เช่น ชื่อ, label, type, category และ class ให้เรียบถูกต้องเรียบร้อย โดยผมจะเลือก type เป็น switch lightbulb หลังจากนั้นก็ทำการผูกเข้ากับ channel ที่เราได้สร้างไว้ก่อนหน้านี้

หลังจากนี้ เราก็จะสามารถควบคุมการเปิดปิดรีเลย์ได้ด้วย openHAB แล้วครับ โดยผมลองเอา Lamp1 ที่สร้าง มาไว้ที่หน้าแรกหรือหน้า overview เลยครับ

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

นี่เป็นเพียงแค่การทดลองใช้งาน openHAB และ tasmota ครั้งแรก ยังมีรายละเอียดอีกมากมายให้ลองเล่นและศึกษาใช้งานดูครับ

อีกประเด็นที่น่าสนใจคือเรื่องของ security ซึ่งเป็นเรื่องสำคัญมาก ว่าเราจะกำหนดหรือใช้งาน openHAB ได้อย่างปลอดภัยได้อย่างไร เดี๋ยวมาว่ากันต่อในตอนถัดไปครับ

รีวิวบอร์ด ARM ขนาดเล็ก ราคาประหยัด

ช่วงนี้ได้มีโอกาส มองหาบอร์ด ARM ขนาดเล็กราคาประหยัด เพื่อนำมาทำเป็นโปรดักขาย ก็พวกตู้อัตโนมัตินั่นแหละครับ คราวนี้ก็เป็นเครื่องแลกเหรียญ 10 บาท โดยทั่วไปนักอิเล็กทรอนิกส์อาจจะไปเลือกใช้บอร์ดไมโครคอนโทรลเลอร์สำหรับงานนี้แทนที่จะใช้บอร์ด ARM ซึงเรียกได้ว่าเป็น SBC หรือ Single Board Computer นั่นเอง แต่ด้วยความที่ผมถนัดเขียนโปรแกรมบน Linux มากกว่าก็เลยเลือกอย่างหลัง เมื่อก่อนช่วงที่เริ่มทำตู้เติมเงินกัน บางคนก็ไปใช้บอร์ด BeagleBone ก็ยังมี แต่เดี๋ยวนี้บอร์ดหลายรุ่นราคาถูกลงมาเยอะ โดยเฉพาะจากจีนและเกาหลี

ทีนี้พอเลือกแบบนั้นแล้วก็เลยมองหาของดีราคาถูกมาใช้ในเงื่อนไขที่ว่า RAM ต้องไม่น้อยกว่า 512 MB และมี EMMC ในตัว จากข้อกำหนดนี้ ก็เลยมีตัวเลือก อยู่ 3 บอร์ด คือ

  • Banana Pi M2 magic
  • Orange Pi Zero Plus 2 H3
  • NanoPi Neo Air

ตัวแรกใช้ CPU AllWinner A33 ส่วนที่เหลือเป็น AllWinner H3 ความแตกต่างของ CPU 2 รุ่นนี้น่าจะมีแค่ clock ที่ A33 จะเร็วกว่านิดหน่อย และ H3 จะรองรับ HDMI ซึ่งชิพทั้ง 2 รุ่นผลิตออกมาในเวลาใกล้เคียงกัน คือปี 2014

แล้วอะไรจะเป็นตัวตัดสินใจว่าจะใช้บอร์ดไหนดีละ อันนี้ก็แล้วแต่ความต้องการในงานนั้นๆของแต่ละท่านเลย อย่างเช่น ถ้าต้องการต่อจอ HDMI ก็ตัด bpi M2 กับ nanoPi (ถึง CPU จะรองรับ แต่ nanoPi ไม่ใส่คอนเน็กเตอร์ HDMI มาให้) ไปได้เลย หรือ ถ้าเรื่องการเชื่อมต่อ USB port บอร์ด nanoPI และ OrangePi จะมีมาให้ 2 พอร์ต (แต่ไม่มีหัวคอนเน็กเตอร์มาให้นะ) ส่วน bpi มีให้พอร์ตเดียวแต่ใส่คอนเน็กเตอร์มาให้เลย

ในด้านอื่นๆ ก็ถือได้ว่า มีมาให้ใกล้เคียงกัน เมื่อเลือกจากการเชื่อมต่อได้แล้ว มาดูที่การจะใช้งานมันบ้าง นั่นคือเรื่องของ document ข้อมูลการใช้งานนั่นเอง เท่าที่เปิดหาอ่านทั้ง 3 ตัว เรียงลำดับจากดีที่สุดไป ก็คือ nanoPi bpi และสุดท้าย OrangePi เรื่องเอกสารก็เป็นเรื่องสำคัญมากๆเรื่องหนึ่งเลย ถ้าจะทำอะไรแล้วหาข้อมูลลำบาก อย่าไปไปใช้มันจะดีกว่า

อีกเรื่องที่สำคัญสำหรับตัวผมเอง คือ การพัฒนาโปรแกรมโดยใช้ Qt ซึ่งอันนี้เป็นเรื่องแปลกที่หาสาเหตุไม่ได้ว่าทำไม บอร์ดที่ใช้ AllWinner H3 ตัว Linux image ที่ทำไว้ให้ download จึงมีแต่ Qt 4.8 ส่วน bpi ซึ่งใช้ AllWinner A33 นั้น Ubuntu Image ที่ทำไว้ให้รองรับ Qt 5

ก็ลองเลือกใช้งานดูนะครับ สำหรับบอร์ดราคาประหยัดเหล่านี้ เอาไปใช้กับงาน IoT ก็ได้ เพราะแต่ละตัวก็มี WIFI+Bluetooth ให้มาอยู่แล้ว

หากใครสนใจบอร์ดตัวไหน สามารถลองเข้าไปดูได้ที่ IoT e-shop ครับผม

บันทึก node.js + express + mongodb

ลง software ต่างๆ ตามลิ้งนี้
https://www.sitepoint.com/build-simple-beginner-app-node-bootstrap-mongodb/
และลง robomongo ด้วย mognodb management GUI tool ใช้ดีใช้ได้

เริ่มต้นเขียนด้วยไฟล์ start.js เพื่อกำหนด port ที่ server จะรันและรอรับ connection จาก client
และอาจจะสร้างไฟล์ app.js ขึ้นมาอีกไฟล์เพื่อกำหนดโครงสร้างของเว็บ เช่น การโหลด express, pug และโมดูลที่จำเป็นอื่นๆ

ต่อไปก็ การใช้งาน mongodb เริ่มแรกเลย เพื่อความปลอดภัย ก็ควรใส่ authorization เข้าไปด้วย โดยการสร้าง user และกำหนด password และ role ของการเข้าถึง database

เมื่อได้ user, password สำหรับ database ที่เราต้องการสร้างหรือใช้งานแล้ว ต่อไปก็ต้องทำให้ mongoose connect database แบบมี authen
วิธีกำหนด user, password เวลา connect คือใช้ auth: { user: xxx, password: xxx } เนื่องจาก version ของ mongoose ที่ใช้ จึงต้องใส่ useNewUrlParser: true และ useUnifiedTopology: true ด้วย

เมื่อ connect ได้แล้ว ก็ต้องทำ model schema สำหรับ collection ที่เราต้องการจัดการ ก็ทำแยก 1 .js ไฟล์ ต่อ 1 schema เก็บไว้ใน folder ชื่อ models ก็ได้
เวลา exports module ถ้าชื่อ collection ไม่เหมือนกับชื่อของ schema เราต้องบอกมันด้วยตอน export

เมื่อได้ model ก็ถึงตา view ทำการแสดงผล โดยเราจะแสดงผล documents ทั้งหมด ใน collection ด้วย table สิ่งแรดกที่ต้องทำคือ กำหนดเส้นทางให้ router เช่น เมื่อต้องการกำหนด path เป็น /paid เพื่อแสดงผล table ข้อมูลใน collection ชื่อ paid

เมื่อมี GET request ‘/paid’ เข้ามา เราทำการ query documents ใน collection ได้โดยใช้คำสั่ง find() เมื่อได้ก้อนข้อมูลมาเก็บไว้ในตัวแปรตัวหนึ่งแล้ว ก็ส่งต่อให้ view ทำการแสดงผล โดยใช้ pug และ bootstrap

ก่อนจะไปถึงเรื่อง bootstrap มาดูเรื่อง HTTP authentication ก่อน คือ user ต้องทำการ login สำเร็จก่อนจึงจะสามารถเข้าถึงหน้า paid ได้
เราได้ทำโดยใช้ โมดูล http-auth เมื่อทำเสร็จแล้ว จะมี pop-up ขึ้นมาให้ใส่ user name, password เมื่อจะเข้าหน้าที่กำหนด

ก่อนจะใช้งาน bootstrap ซึ่งก็คือเรื่องของ style sheet เราต้องทำการบอก path ที่อยู่ เพื่อให้สามารถเรียกโหลดไฟล์ที่วางอยู่ในนั้นได้ ในที่นี้ก็คือพวก css, js, images โดย ทำการกำหนด static path ให้แก่ express ก่อน หลังจากนั้น เราก็จะสร้าง css ไฟล์กำหนดค่าการแสดงผลให้กับส่วนต่างๆของ view ได้

ส่วน view นี้ เราใช้ pug เป็น template engine เมื่อก่อนชื่อ jade ยังมี engine ตัวอื่นๆอีกที่สามารถนำมาใช้ได้ การใช้งาน pug ก็เหมือนเราเขียนไฟล์ html นั่นเอง แต่จะมีรูปแบบการเขียนที่ง่ายขึ้น ไฟล์จะเป็นนามสกุล .pug แทน ซึ่งชื่อไฟล์ก็จะต้องเหมือนกับในฟังก์ชั่น render

ถึงตรงนี้เราก็ทำเว็บด้วย node.js ได้กะเค้าบ้างแล้ว แต่ที่ทำต่อเพื่อจะส่งงานให้ลูกค้า นั่นคือ การแสดงผล table ให้สวยงามและมีฟังก์ชั่นการทำงานมากขึ้น เช่น การเรียงคอลัมน์ การค้นหา การทำเพจ และการ export ข้อมูล ซึ่งได้หยิบ DataTables มาใช้งาน

กว่าจะใช้งานได้ก็เล่นเอาเหนื่อยเหมือนกัน เพราะ DataTables ใช้ jqeury เลยต้องนั่งหาวิธีที่จะเรียกใช้ $(document) หรืออ้างถึง Element ต่างๆ ในไฟล์ .pug ให้ได้ สุดท้ายจึงพบว่ามันทำได้ง่ายๆเลย โดยการลง package jquery ด้วย npm และใช้วิธีกำหนด static path ไปที่ folder ที่ไฟล์ใน package เหล่านั้นถูกวางอยู่ โดยใช้ app.use() นั่นเอง ก็เลยแก้ปัญหาเรื่อง jQuery และ $ is not undefined ลงได้

Deep Learning กับ nvidia jetson nano ตอนที่ 1

ตอนนี้ เราจะมาทดลองรันโปรแกรมบน jetbot กัน โดยจะเป็น examples ที่มากับตัว install 2 ตัวอย่างแรกจะเป็นการแนะนำการเขียนโปรแกรมเพื่อควบคุม jetbot ทั้งด้วย widgets และจอย

โปรแกรมตัวอย่างเขียนด้วย jupyter notebook และระบบที่รัน jetbot ก็ลงมาให้เรียบร้อยแล้ว เราสามารถรันแบบรีโมทผ่านบราวเซอร์จากเครื่องคอมเราได้เลย โดยเราก็รัน jetbot ด้วย power bank ทีติดตั้งไว้แล้ว เพื่อไม่ให้เป็นอุปสรรคในการเคลื่อนที่ของ jetbot การทดลองรันก็เพียงแค่เปิดไฟล์ ขึ้นมาแล้วให้มันรัน จะทีละส่วน(เค้าเรียกว่า cell)เพื่อทำความเข้าใจ หรือสั่งรันทั้งหมดเลยก็ได้ แต่ไม่แนะนำ เพราะ cell ท้ายๆ อาจจะเป็นการสั่งหยุดการทำงาน

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

1. ขั้นตอนแรก จะเป็นการเก็บ samples โดยโค้ดจะทำการเก็บภาพและให้เราแยกว่าภาพไหนคือ blocked หุ่นจะไปต่อไม่ได้ หรือ ภาพไหนคือ free หุ่นสามารถเคลื่อนที่ไปได้ เพื่อจะนำไป train
2. ทำการ train ขั้นตอนนี้ยุ่งยากหน่อย ผมพบว่า หากเก็บ samples จำนวนมาก (> 100) จะทำการ train บน jetbot ไม่สำเร็จ มีอาการดับไปซะเฉยๆ (เรื่องนี้ เดี๋ยวว่ากันอีกที) ดังนั้นจึงต้องทำการ train บนเครื่อง pc แทน ซึ่งใช้เป็น ubuntu 18.04 ก็ต้องไปทำการ install โปรแกรมที่จำเป็นทั้งหมด เรียกว่า ก็ต้องให้เหมือนบน jetbot นั่นเอง
หลังจากงมอยู่นาน จึงได้ขั้นตอนการ install ดังนี้

  • ลง anaconda ก็จะได้ python มาด้วย
  • ลง pytorch โดยเลือกได้ว่าจะใช้ cuda หรือไม่ ซึ่งบางคนใช้การ์ดจอ nvidia อาจอยากใช้ gpu ในการคำนวณ ก็ต้องไปลง driver cuda ก่อนนะ
  • ลง jupyter (อันนี้ไม่แน่ใจว่าตอนลง anaconda มันลงให้เลยอัตโนมัติแล้วหรือเปล่า)

*** ข้อที่ต้องระวังคือ เวอร์ชั่นของ pytorch บนเครื่องที่ใช้เทรนกับบน jetbot จะต้องเหมือนกัน ไม่งั้นจะโหลดโมเดลที่เทรนมาไม่ได้ ของผมใช้วิธีอัพเกรด jetpack เป็น เวอร์ชั่น 4.4 และอัพเกรด pytorch ไปเป็นเวอร์ชั่น 1.6

3. คือการนำ model ที่เทรนได้มาใช้งาน ซึ่งตอนนี้เจอปัญหาว่า แค่ออกตัวก็ดับตายสนิท ฮ่าๆ จากที่ลองหาข้อมูลในฟอรั่มดู น่าจะเป็นจังหวะมอเตอร์เริ่มหมุน พร้อมๆกับการที่กล้องทำงานจับภาพ น่าจะกินกระแสแบบพุ่งขึ้นทันทีทันใดก็เลยดับไป ลองใช้วิธีเขียนโค้ดให้มอเตอร์หมุนไปสักแป๊บนึงก่อนค่อยเริ่มจับภาพ ก็ใช้ได้ผลนะ

*เดี๋ยวจะลองเปลี่ยนไปใช้กล้อง USB ดูบ้างว่าอาการจะแตกต่างกันมั้ย

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

Deep Learning กับ nvidia jetson nano ตอนที่ 0

ตั้งใจจะเขียนเป็นซีรียส์ หนึ่งเพื่อเป็นการสรุปข้อมูลที่ได้เรียนรู้ สองก็เพื่อเป็นประโยชน์แก่ผู้ที่สนใจ

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

คำถาม คือ ทำไมต้อง jetbot ทำไมต้อง nvidia jetson nano
– เพราะมันฮอต และมันง่าย เนื่องจากมีเครื่องมือ มีซอฟแวร์ มีไกด์ไลน์ ให้เราทำตามไปก่อน ทำให้เริ่มต้นได้ง่าย ตัวบอร์ดถึงแม้จะราคาสูงกว่า raspberry pi ไปพอสมควร แต่ผมว่าคุ้มนะ
– ตัว hardware อุปกรณ์ไม่เยอะ ประกอบง่าย บัดกรี ไม่กี่จุด ก็เล่นได้ละ

เพิ่มเติมอีกหน่อย
nvidia ไม่ได้มีเพียงแค่โปรเจ็ค jetbot เท่านั้น ยังมีโปรเจ็คอื่นๆ ซึ่งใช้ซอฟแวร์ ISAAC SDK เช่น Kaya robot ก็จะมีอุปกรณ์ที่ต้องประกอบมากขึ้น
หรือถ้าไม่ใช้ SDK จาก nvidia จะไปใช้ ROS ก็ได้ ก็จะมีโปรเจ็คอย่างเช่น racecar ซึ่งแตกย่อยไปอีกหลายโปรเจ็คจากหลากหลายนักพัฒนา มีรายละเอียดที่แตกต่างกันในเรื่องของการใช้ hardware บางตัว

คำถามต่อมา แล้วเกี่ยวอะไรกับ deep learning
– deep learning มันก็คือเรื่องของ AI กรณีศึกษาในเรื่องนี้มักเกี่ยวข้องกับ vision system เกี่ยวข้องกับภาพ เช่น รู้จำป้ายทะเบียน รู้จำสิ่งกีดขวาง การนำทาง ดังนั้น jetbot หุ่นที่มีล้อ และติดกล้อง มันจึงเป็นอะไรที่เหมาะมากในการเอามาเรียนรู้ แถมสนุกด้วย

เริ่มต้นยังงัย
– อย่างน้อย ก็ต้องมีความรู้ มีประสบการณ์ ทั้ง hardware และ software สักหน่อย ใครที่ไม่เคยประกอบหุ่นเล่นเลย ก็ไปหาชุดคิทประกอบหุ่นยนต์มาลองเล่นก่อน ลองดูที่ www.ioteshop.com ร้านของผมเองก็มี อิอิ ให้รู้จักส่วนประกอบต่างๆของตัวหุ่นยนต์ หลักการไฟฟ้า อิเล็กทรอนิกส์เบื้องต้น อาจจะต้องมีเครื่องมือสำหรับงานประกอบ งานบัดกรี ต่างๆ
– ส่วน software ก็ต้องรู้เรื่อง linux เคยใช้งานมาบ้าง อ่านภาษาอังกฤษพอได้ เพราะต้องไป download และอ่านข้อมูลจากเว็บของ nvidia ส่วนภาษาที่ใช้เขียน สำหรับ jetbot นี้เป็น python ก็มีพื้นฐานสักหน่อย ภาษาอื่นก็ได้แต่เข้าใจหลักการเขียนโปรแกรม ก็โอเค

Hardware
1. nvidia jetson nano
ตัวบอร์ด jetson nano จริงๆประกอบด้วย 2 ส่วน คือ core module ที่มี CPU กับส่วนที่เรียกว่า carrier board ก็เป็นบอร์ดขยาย ที่ทำให้เราสามารถต่ออุปกรณ์อื่นๆได้ผ่านทางพอร์ทต่างๆ รวมทั้งจ่ายไฟให้มันด้วย
การจ่ายไฟให้ jetson nano ทำได้สองทาง คือผ่านทาง micro USB port และ jack DC เป็น 5V ทั้งคู่ เลือกเอาอย่างใดอย่างหนึ่ง โดยการใช้ jumper
ความแตกต่างนั้น ตามความเข้าใจของผม USB port นั้นสามารถรับ-จ่ายกระแสได้น้อยกว่า อย่าง jetbot นี้ ตอนรันใช้ไฟจาก power bank ผ่าน USB port ระบบจะถูกกำหนดให้ทำงานในโหมดกินพลังงานต่ำ
ส่วน jack DC คงไม่มีปัญหานี้ จัดเต็มได้เลย บริโภคไฟกันได้สุดๆ ดังนั้น adapter ที่ใช้ ก็น่าจะเป็น 5V 4A ขึ้นไป ก็เผื่อคุณภาพและประสิทธิภาพการทำงานของตัว adapter ไว้ด้วย

2. ชุดคิท jetbot
ประกอบไปด้วย 3D printed โครงหุ่นและล้อ ส่วนที่เป็นอุปกรณ์อิเล็กทรอนิกส์ ก็มีเพียง มอเตอร์ บอร์ดขับมอเตอร์ featherwing และกล้อง raspberry pi camera แค่นั้นเอง อ้อแล้วก็ power bank อีกอย่างนึง

เรื่องการประกอบ ใน github ของ jetbot มีอธิบายไว้ชัดเจนพอสมควร ผมคงไม่เขียนถึง

ก็ไปเตรียมหุ่นกันไว้นะ แล้วในตอนหน้า มาเริ่มใช้งานกันดีกว่า

ว่าด้วยเรื่องของ thermal printer

ไม่ได้เขียนลงที่นี่ซะนานเลย เนื่องด้วยเพราะเวลาเขียนอะไรสั้นๆ หรือแนะนำสินค้า ตอนนี้มีหน้าเพจ iot e-shop ด้วย ก็เลยไปโพสลงในนั้น รวมถึงถ้าเกี่ยวข้องกับ kiosk ก็ยังมีเพจ bangkokdev ให้ลงอีกด้วย

ตั้งแต่ตั้งใจมาทำตู้ kiosk ขาย สิ่งหนึ่งที่พยายามหาโซลูชั่นมาตลอดนั่นก็คือเรื่องของ thermal printer โจทย์เรื่องนี้นั้นแยกย่อย ไปได้หลายประเด็น คือ
1. ใช้งานอยู่บนระบบปฎิบัติการอะไร Windows, Linux, Android รวมถึง สถาปัตยกรรม CPU อะไร x86 หรือ ARM
2. รองรับภาษาไทย
3. interface port ที่ต้องการใช้ USB หรือ Serial port
4. ใช้งานผ่าน driver (หมายถึงเราต้องลงหรือทำการ install driver ปรินเตอร์จากผู้ผลิตก่อนใช้งาน) หรือ ESC/POS command
5. ราคา

ถ้าไม่ต้องคำนึงถึง ข้อ 5. มีงบเหลือๆ ใช้ EPSON หรือยี่ห้ออื่นๆ ที่รองรับภาษาไทยได้ดี ทั้ง ESC/POS และ driver ก็จบได้เลย
แต่ถ้าคิดว่า คุณต้องการทำตู้บัตรคิว ที่สามารถพิมพ์บัตรคิวหรือสลิปขนาดหน้ากระดาษกว้าง 58 มม. มีการพิมพ์ไม่กี่คำ ไม่กี่บรรทัด รูปแบบตายตัว มีปรินท์เตอร์สำหรับตู้คีออสที่ราคาถูกกว่ากันหลายพันบาทเมื่อเทียบกับระดับ EPSON สักตัวนึง ถ้าคุณสามารถทำให้มันรองรับงานได้ ก็ลดต้นทุนไปได้ ทั้งในระยะเริ่มต้นและการบำรุงรักษา
ข้อจำกัดที่ปรินท์เตอร์จีนราคาถูก ไม่สามารถทำได้ดี คือ ข้อ 2 การพิมพ์ภาษาไทย บวกกับข้อ 4 คือในกรณี ที่ใช้ ESC/POS นั่นเอง เนื่องจากภาษาไทยมีการพิมพ์ 3 แถวสำหรับ 1 บรรทัด เพราะมีทั้ง สระ และวรรณยุกต์ ถึงแม้ว่า ตัวปรินท์เตอร์จะฝังฟ้อนท์ไทยมาให้ แต่ตัวเฟิร์มแวร์ ไม่ได้รองรับ เราจึงต้องเขียนโปรแกรมเพื่อแก้ไขปัญหานี้เอาเอง

ถ้าว่ากันในเรื่อง software และ programming ก็จะเกี่ยวข้องกับ ข้อ 3 และ 4 โดยเฉพาะบน Linux และการใช้งาน printer ที่เป็น USB interface
หลายคนเขียนระบบคิวแบบ web app และใช้โมดูล escpos-php ในการติดต่อกับปรินท์เตอร์ โดยเบื้องหลังนั้น ถ้าใช้ USB printer บน windows นั้น เป็นการเขียนคำสั่งลงบน mapped file โดยเราต้องทำการ share printer ก่อนจึงจะใช้งานได้ ส่วนบน Linux นั้นใช้ CUPS command line ในการพิมพ์

แล้วถ้าเป็น C++ ละ ผมเคยนั่งเขียนโค้ดด้วย Qt/C++ โดยใช้ escpos-php เป็นไกด์ไลน์ เพื่อใช้กับ printer ผ่านทาง serial port
แต่สำหรับ USB printer บน Linux ผมนั่งหาในกูเกิ้ล จนเจอ escpospp เมื่อลองศึกษาดูโค้ดแล้ว ก็พบว่า ใช้การเขียนข้อมูลไปที่ printer โดยใช้ libusb อาจจะเรียกได้ว่าเป็น user mode driver ก็ได้ครับ นอกจากนั้นยังมีโปรเจ็ค QtUSB ที่ทำให้สามารถใช้งาน libUSB บน Qt ได้ ทำนองเดียวกันกับ QtSerialport
สำหรับการใช้งาน libUSB จำเป็นต้องรู้จัก USB device ว่าประกอบด้วยอะไรบ้าง เช่น interface, endpoint เพื่อให้สามารถระบุปรินท์เตอร์ที่เราต้องการเชื่อมต่อได้ รวมถึงวิธีการหรือฟังก์ชั่นในส่งข้อมูลให้กับ device (ในกรณีส่ง ESC/POS command เห็นใช้ bulk transfer กัน)

สุดท้าย ถ้าต้องการจะพิมพ์ด้วยฟ้อนท์ไทยสวยๆ หลากหลายแบบและขนาด ก็คงต้องเขียนโปรแกรมสั่งพิมพ์ผ่าน driver เอา อย่างเช่นใน Qt ก็มีโมดูล QPrinter ให้ใช้ครับ