- เขียนโค้ดสำหรับบอร์ด Arduino โดยสร้างเป็น C++ Class ดังต่อไปนี้
- Class StringStack เป็นโครงสร้างข้อมูลแบบ Stack (กองซ้อน) สำหรับเก็บ String objects (http://arduino.cc/en/Reference/StringObject) และกำหนด API สำหรับคลาสดังกล่าว เป็นดังนี้
#include <String.h> class StringStack { public: StringStack(int capacity = 10); // constructor method bool put(String s); // put a String object on stack bool get(String &s); // get a String object from stack inline int size(); // return the number of String object on the stack inline bool isEmpty(); // return true if stack is empty, otherwise false inline bool isFull(); // return true if stack is Full, otherwise false private: int capacity; // the max capacity of the stack int count; // used to count the number of string object stored String *buf; // used to store String object on stack };จงสร้างคลาส StringStack และทดสอบการทำงานโดยใช้โค้ดตัวอย่างต่อไปนี้ และทดสอบโดยใช้ฮาร์ดแวร์จริง (ใช้บอร์ด Arduino และแสดงผลผ่าน Serial Monitor ของ Arduino IDE)
#include "StringStack.h" int num = 10; //capacity StringStack st(num); void setup(){ Serial.begin(115200); } char buf[20]; String str; void loop(){ Serial.print("\nPut strings: "); for(int i=0; i<num; i++){ str = String((i+1)*10); if (!st.put(str)){ Serial.println("\nPut 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.get(str)){ str.toCharArray(buf, 20); Serial.print(buf); Serial.print(" "); }else{ Serial.println("\nGet string error!"); break; } delay(50); } delay(500); }
ผลการทดลอง
หลังจากทำการออกแบบการเขียนโค้ดเพื่อให้ทำงานตามโจทย์ที่ได้รับ ได้ผลดังต่อไปนี้
- ด้านล่างนี้เป็นโค้ดสำหรับไฟล์ StringStack.h ซึ่งเป็น Header File ตามโจทย์ที่ได้รับ
// class declaration #ifndef StringStack_H #define StringStack_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 StringStack { private: int capacity; // the max capacity of the stack int count; // used to count the number of string object stored String *buf; // used to store String object on stack public: StringStack(int capacity = 10); // constructor method bool put(String s); // put a String object on stack bool get(String &s); // get a String object from stack inline int size(); // return the number of String object on the stack inline bool isEmpty(); // return true if stack is empty, otherwise false inline bool isFull(); // return true if stack is Full, otherwise false }; #endif;
- ด้านล่างนี้เป็นโค้ดสำหรับไฟล์ StringStack.cpp ซึ่งเป็นโค้ดภาษา C++ ใช้สำหรับการเขียนโค้ดให้ทำงานที่ต้องการ ตามที่ได้ประกาศไว้ใน Header ไฟล์
#include "StringStack.h" StringStack::StringStack(int capacity){ this->capacity = capacity; count = 0; buf = new String[capacity]; } bool StringStack::put(String s){ // put a String object on stack if (!isFull()){ *(buf+count) = s; // store s (input) value in stack count += 1; // update number of String object store return true; } else{ return false; // if stack is full then return false } } bool StringStack::get(String &s){ // get a String object from stack if (!isEmpty()){ count -= 1; // update number of String object store s = *(buf+count); // set value of s (output) is equal top value in stack return true; } else{ return false; // if stack if empty then return false } } inline int StringStack::size(){ return count; // return the number of String object on the stack } inline bool StringStack::isEmpty(){ // return true if stack is empty, otherwise false if (count <= 0){ return true; } else{ return false; } } inline bool StringStack::isFull(){ // return true if stack is Full, otherwise false if (count >= capacity){ return true; } else{ return false; } }
การทำงานของโค้ด
- ในบรรทัดที่ 6 ตัวแปร buf ซึ่งเป็นตัวแปรแบบ pointer ให้ชี้ไปที่ array แบบ String เพื่อใช้ในการเก็บข้อมูลของ String object
- ฟังก์ชัน put ถ้า stack ยังไม่เต็มจะเป็นการเก็บข้อมูลลงใน stack โดยรับข้อมูลแบบ String ที่ต้องการเก็บลงใน stack ในบรรทัดที่ 11 จะเป็นการนำข้อมูล String ที่รับเข้ามาไปเก็บไว้ใน array แบบ String ที่ตัวแปร buf กำลังชี้อยู่ ซึ่งใช้ buf + count ในการระบุ index ที่ต้องการเก็บข้อมูล แล้วใช้คำสั่ง *(buf + count) = s; ในการกำหนดค่าของ array ตาม index ที่ระบุ ให้มีค่าเท่ากับค่าของ s เพื่อเก็บข้อมูลลง stack
- ฟังก์ชัน get ถ้ามีข้อมูลอยู่ใน stack จะเป็นการนำข้อมูลบนสุดของ stack ออก และแสดงผลข้อมูลนั้น โดยฟังก์ชันนี้จะรับข้อมูลเป็น Address ของ string ที่ต้องการให้นำข้อมูลไปแสดง ดังนั้นในบรรทัดที่ 23 จึงใช้คำสั่ง s = *(buf + count) เพื่อกำหนดให้ค่าของ s มีค่าเท่ากับค่าที่บนสุดของ stack โดยใช้คำสั่ง buf + count ในการระบุ index บนสุดของ stack
- ฟังก์ชัน size ใช้ในการดูว่ามีจำนวนข้อมูลอยู่ใน stack เท่าใด
- ฟังก์ชัน isEmpty ใช้สำหรับการดูว่า stack นั้นว่างหรือไม่ ถ้าหาก stack ไม่มีข้อมูลอยู่เลยจะให้ค่าเป็น true แต่ถ้ามีข้อมูลอยู่ใน stack จะให้ค่าเป็น false
- ฟังก์ชัน isFull ใช้ในการดูว่า stack นั้นเต็มหรือไม่ ถ้าหากมีข้อมูลอยู่ใน stack จนเต็ม จะให้ค่าเป็น true แต่ถ้าหากยังไม่เต็มจะให้ค่าเป็น false
เมื่อนำโค้ดที่ออกแบบไปใช้กับโค้ดเพื่อการทดสอบตามโจทย์ ได้ผลของเอาต์พุตใน Serail Monitor ดังภาพด้านล่าง
จากภาพด้านบน มีการ put ข้อมูลเป็น string ของตัวเลขที่เรียงลำดับกันตั้งแต่ 0 ถึง 9 ดังนั้น เมื่อมีการ get ข้อมูลออกมา จึงเรียงตามลำดับจาก 9 จนถึง 0
โจทย์ปัญหา ข้อ 2
2. ใช้คลาส StringStack ในข้อแรก นำมาเขียนโค้ด Arduino เพื่อให้มีพฤติกรรมการทำงานดังนี้
- บอร์ด Arduino มีวงจรปุ่มกด Get ทำงานแบบ Active-Low (ใช้ตัวต้านทานแบบ Pull-up 10k)
- ผู้ใช้สามารถส่งข้อความ (ภาษาอังกฤษ) ทีละบรรทัด (ไม่ 20 อักขระต่อบรรทัด) จากคอมพิวเตอร์ โดยส่งผ่าน Serial Monitor ของ Arduino IDE ไปยังบอร์ด Arduino
- ข้อความแต่ละบรรทัดที่ถูกส่งไปยัง Arduino จะถูกจัดเก็บใน StringStack (เก็บบนกองซ้อน) ถ้าไม่เต็มความจุ แต่ถ้าเต็มความจุ ไม่สามารถเก็บข้อความใหม่ได้ Arduino จะต้องส่งข้อความ "FULL" กลับมา
- เมื่อมีการกดปุ่ม Get แล้วปล่อยหนึ่งครั้ง ข้อความบนสุด (ถ้ามี) ของ StringStack จะถูกดึงออกมาแล้วส่งผ่าน Serial Monitor ไปยังคอมพิวเตอร์ แต่ถ้าไม่มีข้อความใดๆ Arduino จะต้องส่งข้อความ "Empty" กลับมา เมื่อกดปุ่มแล้วปล่อย
ผลการทดลอง
หลังจากการออกแบบและเขียนโค้ดเพื่อให้ทำงานได้ตามโจทย์ที่ได้รับ แล้วได้โค้ดสำหรับ Arduino ดังด้านล่าง
#include "StringStack.h"; StringStack textarray(20); String recieved_text = ""; String str = NULL; void setup() { pinMode(INPUT,4); Serial.begin(9600); Serial.println("start"); } void loop() { while (Serial.available()) { delay(10); char c = Serial.read(); //gets one byte from serial buffer recieved_text += c; } if (recieved_text.length() > 0) { if(recieved_text.length() > 20){ recieved_text = recieved_text.substring(0, 20); } if(!textarray.put(recieved_text)){ Serial.println("FULL"); } else { Serial.println("Add: \"" + recieved_text + "\" in Stack"); } recieved_text = ""; //clears text for new text } if(!digitalRead(4)){ delay(10); if(digitalRead(4)){ if(!textarray.get(str)){ Serial.println("Empty"); } else { Serial.println("Get: \"" + str + "\" from Stack"); } } } }
การทำงานของโค้ด
จากโจทย์ที่รับข้อมูลจาก ผ่าน Serial Monitor จึงได้เปิด Serial port ตั้ง baud rate ที่ 9600 จากนั้นจึง Serial.available() ด้วย while() ให้รับข้อมูลที่ส่งมาทุกตัวเก็บไว้ในตัวแปร String ตัวนึง ใช้ substring() ตัดข้อมูลที่เกินโดยจำกัดไว้ที่ 20 อักขระ จากนั้นจึงใช้คำสั่ง put() ถ้า true จะปริ้นค่าที่ใส่ แต่เมื่อ false คือ stack เต็มจะปริ้น FULL คือข้อมูลเต็มแล้ว เมื่อกดปุ่มจะใช้คำสั่ง pop() เมื่อ true จะปริ้นข้อความที่ pop() ออกมา แต่ถ้า false จะปริ้น Empty
ภาพด้านล่างสำหรับวงจรปุ่มกด
ภาพแผนผังสำหรับวงจรปุ่มกด |
ภาพการต่อวงจรจริง |
เมื่อนำโค้ดที่ได้ไปใช้กับวงจรจริงได้ผลการทดลองดังภาพด้านล่าง
ภาพเอาต์พุต เมื่อกดปุ่มขณะที่ยังไม่มีข้อมูลใน StringStack |
ภาพเอาต์พุต เมื่อพยายามเพิ่มข้อมูลมากกว่าความจุของ StringStack ในที่นี้คือ 20 |
ภาพเอาต์พุต เมื่อมีการ put และการ get ใน StringStack |
ภาพเอาต์พุต เมื่อพยายามจะใส่ข้อมูลที่มีความยาวมากกว่า 20 อักขระ |
ไม่มีความคิดเห็น:
แสดงความคิดเห็น