- เขียนโค้ดสำหรับบอร์ด Arduino โดยสร้างเป็น C++ Class ดังต่อไปนี้ => Class StringQueue เป็นโครงสร้างข้อมูลแบบ Queue สำหรับเก็บ String objects สร้างคลาส StringQueue และทดสอบการทำงานโดยใช้โค้ดตัวอย่างต่อไปนี้ และทดสอบโดยใช้ฮาร์ดแวร์จริง (ใช้บอร์ด Arduino และแสดงผลผ่าน Serial Monitor ของ Arduino IDE)
- ใช้คลาส StringQueue ในข้อแรก นำมาเขียนโค้ด Arduino เพื่อให้มีพฤติกรรมการทำงานดังนี้ กำหนดให้มีความจุเช่น 10 ข้อความ
- บอร์ด Arduino มีวงจรปุ่มกด Get ทำงานแบบ Active-Low (ใช้ตัวต้านทานแบบ Pull-up, 10k)
- ผู้ใช้สามารถส่งข้อความ (ภาษาอังกฤษ) ทีละบรรทัด (ไม่เกิน 16 ตัวอักขระต่อบรรทัด) จาก คอมพิวเตอร์ โดยส่งผ่าน Serial Monitor ของ Arduino IDE ไปยังบอร์ด Arduino ใช้ baudrate 115200
- ข้อความแต่ละบรรทัดที่ถูกส่งไปยัง Arduino จะถูกจัดเก็บใน StringQueue ถ้าไม่เต็มความจุ แต่ถ้าเต็มความจุ ไม่สามารถเก็บข้อความใหม่ได้ Arduino จะต้องส่งข้อความ "Full" กลับมา และมี LED "Full" ติด
- เมื่อมีการกดปุ่ม Get แล้วปล่อยหนึ่งครั้ง ข้อความแรก (ถ้ามี) ของ StringQueue จะถูกดึงออกมาแล้วส่งผ่าน Serial Monitor ไปยังคอมพิวเตอร์ และนำไปแสดงผลบนจอ 16x2 LCD ที่ต่อกับบอร์ด Arduino ด้วย แต่ถ้าไม่ข้อความใดๆ Arduino จะต้องส่งข้อความ "Empty" กลับมา เมื่อกดปุ่มแล้วปล่อย และให้มี LED "Empty" ติด
- บรรทัดแรกของ LCD แสดงข้อความที่ถูกอ่านออกมาล่าสุดจาก StringQueue บรรทัดที่สอง ให้แสดงจำนวนข้อความที่มีอยู่ใน StackQueue ในขณะนั้น
- การเขียนโค้ดเพื่อใช้งาน LCD สามารถใช้ไลบรารี่ของ Arduino ได้
ผลการทดลอง
หลังจากได้ทำการออกแบบการทำงานของวงจรแล้ว จึงดำเนินการแบ่งโค้ดสำหรับ class StringQueue ออกเป็น 2 ไฟล์ คือ StringQueue.h และ StringQueue.cpp ซึ่งมีรายละเอียดดังต่อไปนี้
- ไฟล์ StringQueue.h ใช้สำหรับการประกาศคลาส, ฟังก์ชัน และตัวแปรต่างๆ ที่ต้องการใช้งาน
// class declaration
#ifndef StringQueue_H
#define StringQueue_H
#include <String.h>
using namespace std;
#include <stdbool.h>
#include <inttypes.h>
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
class StringQueue {
private:
int capacity; // the max capacity of the queue
int count; // used to count the number of string object stored
int in; // used to count index for add String object
int out; // used to count index for get String object
String *buf; // used to store String object in queue
public:
StringQueue(int capacity = 10); // constructor method
bool enqueue(String s); // add a String object in queue
bool dequeue(String &s); // get a String object from queue
int size(); // return the number of String object in the queue
bool isEmpty(); // return true if stack is empty, otherwise false
bool isFull(); // return true if stack is Full, otherwise false
};
#endif;
การทำงานของโค้ด
- ในส่วน private
- ประกาศตัวแปรแบบ int ชื่อ capacity ใช้สำหรับระบุขนาดของ queue
- ประกาศตัวแปรแบบ int ชื่อ count ใช้สำหรับนับจำนวน String object ที่มีอยู่ใน queue
- ประกาศตัวแปรแบบ int ชื่อ in ใช้สำหรับระบุ index ในการเพิ่ม String object ลงใน queue
- ประกาศตัวแปรแบบ int ชื่อ out ใช้สำหรับระบุ index ในการนำ String object ออกจาก queue
- ประกาศตัวแปร pointer แบบ String ชื่อ buf ใช้สำหรับเก็บข้อมูล String object ใน queue
- ในส่วน public
- ประกาศฟังก์ชันชื่อ StringQueue เป็น constructor method สำหรับสร้าง object และรับค่าเป็น int ใช้สำหรับกำหนดขนาดของ queue
- ประกาศฟังก์ชันชื่อ enqueue แล้วรับค่าเป็น String ใช้สำหรับการเพิ่ม String object ลงใน queue ถ้าเพิ่มได้สำเร็จจะ return ค่าเป็น true แต่ถ้าไม่สามารถเพิ่มได้จะ return ค่าเป็น false
- ประกาศฟังก์ชันชื่อ dequeue แล้วรับค่าเป็นที่อยู่ของ String ใช้สำหรับการนำ String object ออกจาก queue แล้วนำค่าที่ได้ไปเป็นข้อมูลของ String ตามที่อยู่ที่รับเข้ามา ถ้าสามารถนำค่าออกจาก queue ได้สำเร็จจะ return ค่าเป็น true แต่ถ้าไม่สามารถนำค่าออกจาก queue ได้จะ return ค่าเป็น false
- ประกาศฟังก์ชันชื่อ size ใช้สำหรับบอกจำนวน String object ที่มีอยู่ใน queue
- ประกาศฟังก์ชันชื่อ isEmpty ใช้สำหรับบอกว่า queue นั้นว่างอยู่หรือไม่ ถ้าหากว่า queue ไม่มีข้อมูลอยู่เลยจะ return ค่าเป็น true แต่ถ้าหากใน queue มีข้อมูลอยู่ก็จะ retuen ค่าเป็น false
- ประกาศฟังก์ชันชื่อ isFull ใช้สำหรับบอกว่า queue นั้นเต็มหรือไม่ ถ้าหากว่า queue มีข้อมูลอยู่จนเต็มจะ return ค่าเป็น true แต่ถ้าหาก queue ยังมีที่ว่างอยู่จะ return ค่าเป็น false
- ไฟล์ StringQueue.cpp สำหรับการนำฟังก์ชันต่างๆ ที่ประกาศไว้ในไฟล์ StringQueue.h มาสร้างให้ฟังก์ชันเหล่านั้นสามารถทำงานตามฟังก์ชันการทำงานที่กำหนดไว้
#include "StringQueue.h"
StringQueue::StringQueue(int capacity){
this->capacity = capacity;
count, in, out = 0;
buf = new String[capacity];
}
bool StringQueue::enqueue(String s){
if (!isFull()){
*(buf + in) = s;
count += 1;
in += 1;
if (in == capacity){
in = 0;
}
return true;
}
else {
return false;
}
}
bool StringQueue::dequeue(String &s){
if (!isEmpty()){
s = *(buf + out);
count -= 1;
out += 1;
if (out == capacity){
out = 0;
}
return true;
}
else {
return false;
}
}
int StringQueue::size(){
return count;
}
bool StringQueue::isEmpty(){
if (in == out && count <= 0){
return true;
}
else {
return false;
}
}
bool StringQueue::isFull(){
if (in == out && count >= capacity){
return true;
}
else {
return false;
}
}
สำหรับในไฟล์ StringQueue.cpp เราจะเขียนโค้ดของแต่ละฟังก์ชันเพื่อให้สามารถทำงานได้ตามที่กำหนดไว้ในไฟล์ StringQueue.h
หลังจากที่สร้างไฟล์ StringQueue.h และไฟล์ StringQueue.cpp แล้ว จึงใช้โค้ดสำหรับ Arduino ดังต่อไปนี้เพื่อทดสอบการทำงานของ class StringQueue ที่สร้างขึ้น
โค้ด Arduino สำหรับการทดสอบ class StringQueue
#include "StringQueue.h"
int num = 10; //capacity
StringQueue st(num);
void setup(){
Serial.begin(115200);
}
char buf[20];
String str;
void loop(){
Serial.print("\nAdd strings: ");
for(int i=0; i<num; i++){
str = String((i+1)*10);
if (!st.enqueue(str)){
Serial.println("\nAdd string error!");
break;
}else{
Serial.print(str);
Serial.print(" ");
}
str = NULL;
delay(50);
}
delay(500);
Serial.print("\nGet strings: ");
for(int i=0; i<num; i++){
if(st.dequeue(str)){
str.toCharArray(buf, 20);
Serial.print(buf);
Serial.print(" ");
}else{
Serial.println("\nGet string error!");
break;
}
delay(50);
}
delay(500);
}
สำหรับโค้ดทดสอบ class StringQueue นี้จะสร้าง queue ที่มีขนาด 10 แล้วทำการเพิ่มข้อมูลลงใน queue เป็นข้อความตัวเลขคือ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 แล้วค่อยนำข้อมูลใน queue ออกมาทีละตัวเพื่อดูว่าลำดับในการนำข้อมูลออกถูกต้องหรือไม่ ซึ่งเอาต์พุตที่ได้จากการทดสอบได้ดังภาพด้านล่าง
![]() |
| ภาพเอาต์พุตจาก Serial Monitor สำหรับการทดสอบ class StringQueue |
จากภาพเอาต์พุตที่ได้แสดงให้เห็นลำดับของการนำข้อมูลใส่ลงใน queue และลำดับของการนำข้อมูลออกจาก queue ซึ่งมีความสอดคล้องกัน โดยข้อมูลที่ถูกเพิ่มลงไปก่อนจะถูกนำออกมากจาก queue ก่อน และข้อมูลที่ถูกเพิ่มไปทีหลังจะถูกนำออกมาจาก queue ทีหลัง
หลังจากที่ได้ทำการทดสอบ class StringQueue แล้วพบว่ามีการเพิ่มข้อมูลใน queue และนำข้อมูลออกจาก queue ได้อย่างถูกต้องแล้ว เราจึงดำเนินการสร้างโค้ดสำหรับ Arduino เพื่อให้ทำงานได้ตามฟังก์ชันต่อไปนี้
- มีวงจรปุ่มกด Get ทำงานแบบ Active-Low (ใช้ตัวต้านทานแบบ Pull-up, 10k)
- ผู้ใช้สามารถส่งข้อความ (ภาษาอังกฤษ) ทีละบรรทัด (ไม่เกิน 16 ตัวอักขระต่อบรรทัด) จาก คอมพิวเตอร์ โดยส่งผ่าน Serial Monitor ของ Arduino IDE ไปยังบอร์ด Arduino ใช้ baudrate 115200
- ข้อความแต่ละบรรทัดที่ถูกส่งไปยัง Arduino จะถูกจัดเก็บใน StringQueue ถ้าไม่เต็มความจุ แต่ถ้าเต็มความจุ ไม่สามารถเก็บข้อความใหม่ได้ Arduino จะต้องส่งข้อความ "Full" กลับมา และมี LED "Full" ติด
- เมื่อมีการกดปุ่ม Get แล้วปล่อยหนึ่งครั้ง ข้อความแรก (ถ้ามี) ของ StringQueue จะถูกดึงออกมาแล้วส่งผ่าน Serial Monitor ไปยังคอมพิวเตอร์ และนำไปแสดงผลบนจอ 16x2 LCD ที่ต่อกับบอร์ด Arduino ด้วย แต่ถ้าไม่ข้อความใดๆ Arduino จะต้องส่งข้อความ "Empty" กลับมา เมื่อกดปุ่มแล้วปล่อย และให้มี LED "Empty" ติด
- บรรทัดแรกของ LCD แสดงข้อความที่ถูกอ่านออกมาล่าสุดจาก StringQueue บรรทัดที่สอง ให้แสดงจำนวนข้อความที่มีอยู่ใน StackQueue ในขณะนั้น
#include <StringQueue.h>
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
StringQueue textarray(5);
String recieved_text = "";
String str = NULL;
int Full = 8;
int Empty = 9;
int buttonState = HIGH; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 100; // the debounce time; increase if the output flickers
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(INPUT,4);
pinMode(OUTPUT,5);
pinMode(OUTPUT,7);
delay(5);
Serial.println("start");
}
void loop() {
while (Serial.available()) {
delay(30);
char c = Serial.read(); //gets one byte from serial buffer
recieved_text += c;
}
if (recieved_text.length() > 0) {
if(recieved_text.length() > 16){
recieved_text = recieved_text.substring(0,16);
}
if(!textarray.enqueue(recieved_text)){
Serial.println("FULL");
str = "FULL";
digitalWrite(Full,HIGH);
} else {
Serial.println("recieve " + recieved_text);
str = "";
digitalWrite(Full,LOW);
digitalWrite(Empty,LOW);
}
recieved_text = ""; //clears text for new text
}
int get_button = digitalRead(4);
// If the switch changed, due to noise or pressing:
if (get_button != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
// *************debouce state**************
if ((millis() - lastDebounceTime) > debounceDelay) {
// if the button state has changed:
if (get_button != buttonState) {
buttonState = get_button;
//if the new button state is HIGH
if (buttonState == HIGH) {
if(!textarray.dequeue(str)){
Serial.println("Empty");
digitalWrite(Empty,HIGH);
str = "Empty";
} else {
Serial.println("get " + str);
digitalWrite(Empty,LOW);
digitalWrite(Full,LOW);
}
}
}
}
lastButtonState = get_button;
lcd.clear();
lcd.print(str);
lcd.setCursor(0, 1);
lcd.print(textarray.size());
delay(10);
}
หลังจากเขียนโค้ดสำหรับ Arduino แล้ว จึงทำการต่อวงจรดังต่อไปนี้เพื่อทำการทดสอบการทำงานของโค้ด Arduino
ภาพสำหรับวงจร Arduino
![]() |
| ภาพแผงผังวงจร |
![]() |
| ภาพสำหรับการต่อวงจรจริง |
หลังจากต่อวงจรและทดสอบโค้ดสำหรับ Arduino ได้ผลการทดลองดังภาพด้านล่าง
- เมื่อให้ queue มีขนาด 5 แล้วทดลองกดปุ่มเพื่อนำข้อมูลออกพบว่าใน Serial Monitor จะขึ้นข้อความ “Empty” จากนั้นทดลองใส่ข้อมูลเรื่อยจนเต็ม queue จะขึ้นข้อความ “FULL” และทดลองนำข้อมูลออกจาก queue จนหมด
![]() |
| ภาพเอาต์พุตจาก Serial Monitor |
- เมื่อทดลองกดปุ่มในขณะที่ queue ยังไม่มีข้อมูลอยู่เลย
![]() |
| ภาพเอาต์พุตจาก Serial Monitor |
- เมื่อทดลองใส่ข้อมูลจนเต็ม queue ขนาด 5
![]() |
| ภาพเอาต์พุตจาก Serial Monitor |
- เมื่อทดลองใส่ข้อความที่มีขนาดเกิน 16 ตัวอักษรลงใน queue แล้วทดลองกดปุ่มเพื่อนำข้อมูลออกมาจาก queue พบว่าข้อความที่แสดงออกมามีขนาดเท่ากับ 16 ตัวอักษร ดังนั้นแสดงว่าใน queue จะเก็บข้อมูลที่มีขนาดตัวอักษรไม่เกิน 16 ตัวอักษร
![]() |
| ภาพจาก Serial Monitor แสดงการใส่ข้อความยาวเกิน 16 ตัวอักษร |
![]() |
| ภาพจาก Serial Monitor เมื่อนำข้อมูลออกจาก queue |









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