บทความการพัฒนาโปรแกรมบน Raspberry Pi ด้วย Qt
ตอนที่ 4 แนะนำการควบคุม GPIO บนบอร์ด Raspberry Pi ผ่าน Shell
โดยเนื้อหาหลักๆ จะประกอบด้วยหัวข้อดังนี้
- ตอนที่ 1 รู้จักกับบอร์ด Raspberry Pi พร้อมเรียนรู้วิธีการติดตั้งระบบปฏิบัติการ Linux ให้กับ Raspberry Pi (อ่านต่อ…)
- ตอนที่ 2 เรียนรู้วิธีการติดตั้งและใช้งาน Qt บน Raspberry Pi (อ่านต่อ…)
- ตอนที่ 3 แนะนำการใช้งาน Qt Creator และการใช้ Widget ต่างๆ บน Qt Creator (อ่านต่อ…)
- ตอนที่ 4 แนะนำการควบคุม GPIO บนบอร์ด Raspberry Pi ผ่าน Shell (อ่านต่อ…)
- ตอนที่ 5 แนะนำให้รู้จักไลบรารี่ WiringPi, วิธีการติดตั้ง พร้อมตัวอย่างการเขียนโปรแกรมควบคุมฮาร์ดแวร์ด้วยไลบรารี่ WiringPi (อ่านต่อ…)
- ตอนที่ 6 ตัวอย่างการเขียนโปรแกรมรับ-ส่งข้อมูลผ่านทาง UART ด้วย QtserialPort (อ่านต่อ…)
- ตอนที่ 7 ตัวอย่างการเขียนโปรแกรมรับ-ส่งข้อมูลผ่านทางบัส I2C (อ่านต่อ…)
- ตอนที่ 8 ตัวอย่างการเขียนโปรแกรมรับ-ส่งข้อมูลผ่านทาง SPI (อ่านต่อ…)
Shell คือ โปรแกรมที่เป็นส่วนเชื่อมต่อระหว่าง Application กับ Kernel โดย User สามารถสั่งงาน Kernel ได้ผ่านทาง Shell นอกจากนี้ Shell ยังมีคุณสมบัติของ Shell Progamming Language ทำให้นำคำสั่งต่างๆ ของ Shell มาเขียนเป็นโปรแกรมได้เรียกว่า Shell Script

(Ref: เอกสารการใช้ Shell Script เบื้องต้น ftp://ftp.psu.ac.th/pub/bash-howto/Shell%20Script.pdf)
การต่อวงจร LED เข้ากับบอร์ด Raspberry Pi


ทดลองสั่ง On/Off LED ด้วย Shell
– เปิดโปรแกรม LXTerminal
– กำหนดสิทธิ์ให้เป็น Superuser พิมพ์คำสั่ง sudo su

– จากวงจรต่อ LED ที่ Pin 4 เปิดใช้งานโดยสร้างไฟล์ควบคุม GPIO Pin 4 ขึ้นมาด้วยคำสั่ง
echo 4 > /sys/class/gpio/export

– กำหนด Direction ของ Pin 4 ให้เป็น Output ด้วยคำสั่ง
echo out > /sys/class/gpio/gpio4/direction

– สั่งให้ Pin4 จ่าย Output เป็น High ให้ LED ติดด้วยคำสั่ง
echo 1 > /sys/class/gpio/gpio4/value

– สั่งให้ Pin4 จ่าย Output เป็น Low ให้ LED ดับด้วยคำสั่ง
echo 0 > /sys/class/gpio/gpio4/value

– เลิกใช้งานโดยลบไฟล์ควบคุม GPIO Pin 4 ด้วยคำสั่ง
echo 4 > /sys/class/gpio/unexport

เขียนโปรแกรมควบคุม LED ด้วย Qt
จากการทดลองควบคุม LED ผ่าน Shell จะเห็นว่าการสั่งงานมีลักษณะคล้ายกับการเปิดไฟล์ขึ้นมาแล้วใส่ค่าต่างๆ เข้าไปเพื่อให้ไฟล์ควบคุมไปทำงานเพื่อควบคุม Hardware ในการทดลองนี้ก็จะใช้หลักการทำงานคล้ายกับ Shell โดยการอ่านหรือเขียนไฟล์แทนการพิมพ์ผ่าน Shell
การเขียน Code ภาษา C
ฟังก์ชั่นที่สำคัญที่ใช้ในการทดลองนี้ คือ fopen fwrite fread fclose ซึ่งอยู่ใน Standard Library เรียกใช้โดย #include<stdion.h>
ฟังก์ชั่น fopen
FILE *fopen(const char *filename, const char *mode);
const char *filename = Path ที่อยู่ของไฟล์ที่ต้องการเปิด
const char *mode = โหมดในการใช้งานไฟล์ซึ่งมีดังนี้
“r” เปิดไฟล์เพื่ออ่านอย่างเดียวโดยไฟล์นั้นต้องมีอยู่แล้ว
“w” เปิดแบบสร้างไฟล์ใหม่ หากมีไฟล์เดิมอยู่จะลบเนื้อหาภายในไฟล์ทิ้งเหมือนสร้างใหม่
“a” เปิดไฟล์เพื่อเขียนข้อมูลลงในท้ายไฟล์ต่อจากเดิมที่มีอยู่แล้ว หากไม่มีไฟล์เดิมอยู่จะ สร้างขึ้นมาใหม่
“r+” เปิดไฟล์เพื่ออัพเดท สามารถเขียนและอ่านได้ โดยไฟล์ต้องมีอยู่แล้ว
“w+” เปิดแบบสร้างไฟล์ใหม่เพื่ออัพเดท สามารถเขียนและอ่านได้ หากมีไฟล์เดิมอยู่จะลบเนื้อหาภายในไฟล์ทิ้งเหมือนสร้างใหม่
“a+” เปิดไฟล์เพื่ออัพเดท สามารถอ่านโดยเลื่อนตำแหน่งในไฟล์ได้ และเมื่อเขียนข้อมูลจะบันทึกลงในท้ายไฟล์ต่อจากเดิมที่มีอยู่ หากไม่มีไฟล์เดิมอยู่จะสร้างขึ้นมาใหม่
ฟังก์ชั่น fwrite
size_t fwrite(const void * ptr, size_t size, size_t count, FILE * stream);
const void * ptr = ตำแหน่งที่เก็บข้อมูลที่ต้องการเขียน
size_t size = ขนาดของแต่ละไบต์ที่ต้องการเขียน
size_t count = จำนวนของไบต์ที่ต้องการเขียน
FILE * stream = ตำแหน่ง Object ของไฟล์ที่ต้องการเขียน
ฟังก์ชั่น fread
size_t fread(void * ptr, size_t size, size_t count, FILE * stream);
const void * ptr = ตำแหน่งที่เก็บข้อมูลที่ได้จากการอ่าน
size_t size = ขนาดของแต่ละไบต์ที่ต้องการอ่าน
size_t count = จำนวนของไบต์ที่ต้องการอ่าน
FILE * stream = ตำแหน่ง Object ของไฟล์ที่ต้องการอ่าน
ฟังก์ชั่น fclose
int fclose ( FILE * stream );
FILE * stream = ตำแหน่ง Object ของไฟล์ที่ต้องการปิด
ตัวอย่างการเขียนโปรแกรมควบคุม GPIO
– เปิดโปรแกรม Qt Creator
– สร้างหน้าตา User Interface ดังนี้

– คลิกขวาที่ PushButton ทั้งสอง แล้วสร้าง Slot เลือก Signal = clicked

– ไปที่ไฟล์ mainwindows.cpp เพิ่ม #include <stdion.h>

– กำหนดตัวแปร FILE *file

– เพิ่มโค้ดลงในฟังก์ชั่น MainWindow::MainWindow(QWidget *parent):QMainWindow(pa rent),ui(new Ui::MainWindow)

เมื่อเปิดโปรแกรมขึ้นมาโปรแกรมจะเข้ามาทำงานในฟังก์ชั่นนี้เป็นฟังก์ชั่นแรกจึงนำโค้ดในส่วนของการสร้างไฟล์ควบคุม GPIO Pin 4 และการกำหนดทิศทางของอินพุตและเอาท์พุตมาวางในฟังก์ชั่นนี้
บรรทัดที่ 12 เปิดไฟล์ export แบบ “w” เพื่อเขียนไฟล์
บรรทัดที่ 13 ตรวจเช็คว่าสามารถเปิดไฟล์สำเร็จหรือไม่
บรรทัดที่ 15 หากไม่สำเร็จให้แสดงข้อความออกทาง qDebug
บรรทัดที่ 17 หากเปิดไฟล์สำเร็จ
บรรทัดที่ 19 เขียนค่า “4” ลงไปในไฟล์ export
บรรทัดที่ 20 ปิดไฟล์
บรรทัดที่ 22 เปิดไฟล์ direction
บรรทัดที่ 27 เขียนค่า “out” กำหนดให้เป็นเอาท์พุตลงในไฟล์ dicrection
บรรทัดที่ 28 ปิดไฟล์
– เพิ่มโค้ดลงในฟังก์ชั่น MainWindow::~MainWindow()

เมื่อปิดโปรแกรมจะเข้ามาทำงานภายในฟังก์ชั่นนี้ก่อนจึงนำโค้ดในส่วนของการเขียนไฟล์ unexport เพื่อลบไดเรกทอรี่ของ GPIO Pin 4 ก่อนที่จะปิดโปรแกรม
บรรทัดที่ 36 เปิดไฟล์ unexport
บรรทัดที่ 43 เขียนค่า “4” ลงไปในไฟล์ unexport
บรรทัดที่ 44 ปิดไฟล์ unexport
– เพิ่มโค้ดลงในฟังก์ชั่น void MainWindow::on_pushButton_clicked()

เมื่อคลิกที่ปุ่ม LED On ในโปรแกรมจะเข้ามาทำงานที่ฟังก์ชั่นนี้ โค้ดในส่วนนี้ก็คือการเปิดไฟล์ value เพื่อเขียนค่าไปกำหนดให้ GPIO Pin 4 ส่ง Output เป็น High
บรรทัดที่ 51 เปิดไฟล์ value
บรรทัดที่ 58 เขียนค่า “1” ลงไปในไฟล์ value เพื่อจ่าย Output เป็น High
บรรทัดที่ 59 ปิดไฟล์ value
– เพิ่มโค้ดลงในฟังก์ชั่น void MainWindow::on_pushButton_2_clicked()

เมื่อคลิกที่ปุ่ม LED Off ในโปรแกรมจะเข้ามาทำงานที่ฟังก์ชั่นนี้ โค้ดในส่วนนี้ก็คือการเปิดไฟล์ value เพื่อเขียนค่าไปกำหนดให้ GPIO Pin 4 ส่ง Output เป็น Low
บรรทัดที่ 65 เปิดไฟล์ value
บรรทัดที่ 72 เขียน “0” ลงไปในไฟล์ value เพื่อจ่าย Output เป็น Low
บรรทัดที่ 73 ปิดไฟล์ value
– ทดลอง Run โปรแกรม