Wednesday, September 24, 2014

Warm-Up 3


โจทย์ฝึกปฏิบัติสำหรับสัปดาห์นี้
1) เขียนโค้ดสำหรับบอร์ด Arduino โดยสร้างเป็น C++ Class ดังต่อไปนี้
=> Class StringQueue เป็นโครงสร้างข้อมูลแบบ Queue สำหรับเก็บ String objects สร้างคลาส StringQueue และทดสอบการทำงานโดยใช้โค้ดตัวอย่างต่อไปนี้ และทดสอบโดยใช้ฮาร์ดแวร์จริง (ใช้บอร์ด Arduino และแสดงผลผ่าน Serial Monitor ของ Arduino IDE)
2) ใช้คลาส StringQueue ในข้อแรก นำมาเขียนโค้ด Arduino เพื่อให้มีพฤติกรรมการทำงานดังนี้ กำหนดให้มีความจุเช่น 10 ข้อความ
2.1) บอร์ด Arduino มีวงจรปุ่มกด Get ทำงานแบบ Active-Low (ใช้ตัวต้านทานแบบ Pull-up, 10k)
2.2) ผู้ใช้สามารถส่งข้อความ (ภาษาอังกฤษ) ทีละบรรทัด (ไม่เกิน 16 ตัวอักขระต่อบรรทัด) จากคอมพิวเตอร์ โดยส่งผ่าน Serial Monitor ของ Arduino IDE ไปยังบอร์ด Arduino ใช้ baudrate 115200
2.3) ข้อความแต่ละบรรทัดที่ถูกส่งไปยัง Arduino จะถูกจัดเก็บใน StringQueue ถ้าไม่เต็มความจุ แต่ถ้าเต็มความจุ ไม่สามารถเก็บข้อความใหม่ได้ Arduino จะต้องส่งข้อความ "Full" กลับมา และมี LED "Full" ติด
2.4) เมื่อมีการกดปุ่ม Get แล้วปล่อยหนึ่งครั้ง ข้อความแรก (ถ้ามี) ของ StringQueue จะถูกดึงออกมาแล้วส่งผ่าน Serial Monitor ไปยังคอมพิวเตอร์ และนำไปแสดงผลบนจอ 16x2 LCD ที่ต่อกับบอร์ด Arduino ด้วย แต่ถ้าไม่ข้อความใดๆ Arduino จะต้องส่งข้อความ "Empty" กลับมา เมื่อกดปุ่มแล้วปล่อย และให้มี LED "Empty" ติด
2.5) บรรทัดแรกของ LCD แสดงข้อความที่ถูกอ่านออกมาล่าสุดจาก StringQueue บรรทัดที่สอง ให้แสดงจำนวนข้อความที่มีอยู่ใน StackQueue ในขณะนั้น
2.6 16x2 LCD module สามารถยืมได้จากห้อง ESL และการเขียนโค้ดเพื่อใช้งาน LCD สามารถใช้ไลบรารี่ของ Arduino ได้

ผลการทดสอบคลาสจากโค้ดทดสอบ

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

Class StringQueue

  StringQueue.h

  StringQueue.cpp


โครงสร้างคลาส
class StringQueue {
  public:
    StringQueue( int capacity ); // constructor
    boolean put( String s ); // ใช้สำหรับส่งค่า String Object เข้าไปเก็บใน StringQueue
    boolean get( String &s ); // คืนค่าออกจาก StringQueue
    int size(); // คืนค่าจำนวนข้อมูลใน StringQueue
    inline boolean isEmpty(); // ตรวจสอบว่า StringQueue ว่างหรือไม่
    inline boolean isFull(); // ตรวจสอบว่า StringQueue เต็มหรือไม่
  private:
    int capacity; // จำนวนข้อมูลสูงสุดใน StringQueue
    int count; // ใช้นับจำนวน String Object ที่เก็บใน StringQueue
    String *buf; // ใช้ในการเก็บ String Object บน StingQueue
};

หลักการทำงานของเมธอดต่างๆ
boolean StringQueue::put( String s ) {
  if(!isFull()){                        //เช็คว่า StringQueue เต็มหรือไม่
    buf[count] = s;                //ให้ buf ช่องที่ปัจจุบันเก็บค่า ข้อความที่รับเข้ามา
    if(count<10){                  //บวกค่า count เพื่อเพิ่มเลื่อนช่องสำหรับเก็บข้อความ
      count++;
    }
    return true;                    //return true เพื่อส่งไปบอกว่าทำการเพิ่มสำเร็จ
  }
  else{
    return false;                             //return false ในกรณีที่ StringQueue เต็ม
  }
}

boolean StringQueue::get( String &s ) {
  if(!isEmpty()){                     //เช็คว่า StringQueue ว่างหรือไม่
      if(count>0){                  //เลื่อนช่องสำหรับคืนค่าข้อความ
      count--;
    }
    String temp = buf[0];       
    *&s = temp;                             //คืนค่าข้อความผ่านทางแอดเดรสที่รับเข้ามา
    for(int i = 0;i<9;i++){         //เลื่อนช่องของทุกข้อความ 1 ช่อง
    buf[i] = buf[i+1];
}
   return true;                     //return true ในกรณีที่คืนค่าสำเร็จ
  }
  else{
    return false;                             //return false ในกรณีที่ StringQueue ว่างหรือไม่มีข้อความ
  }
}

int StringQueue::size() {       // ใช้บอกจำนวน String Object ใน StringQueue
  return count;
}

inline boolean StringQueue::isEmpty()                //ใช้สำหรับเช็คว่า StringQueue ว่างหรือไม่
inline boolean StringQueue::isFull()                    //ใช้สำหรับเช็คว่า StringQueue เต็มหรือไม่

Work with Arduino

  Wiring Diagram / Breadboard View

  Arduino Code

Arduino Code
รับค่าจาก Serial Monitor
while(Serial.available() > 0){
    str = Serial.readStringUntil('\n');                                    //รับค่าจาก Serial Monitor
  }
  if(str.length()> 20 ){                                           //ตัดข้อความให้เหลือ 20 ตัวอักษร
    str = str.substring(0,20);
  }
  if(str.length()<=20 && str.length() > 0){                //ถ้าข้อความไม่เกิน 20 ตัวอักษรส่งไปเก็บใน StringQueue
    if(!st.put(str)){
      Serial.println("\nQueue is Full!!!");                   //แสดงข้อความในกรณีที่ StringQueue
      Serial.println("Press Button to get words from Queue!!!");
    }
    else{
      Serial.println("add : >>>" + str + "<<< to Queue\n");    //แสดงข้อความว่าเพิ่มข้อความเข้า StringQueue แล้ว
      Serial.println("Put String into Queue or Press Button For Get String : ");
      lcd.clear();                                                               //เคลียร์จอ LCD
      lcd.setCursor(0,1);                                                     //เซ็ตบรรทัดสำหรับแสดงผล
      lcd.print(st.size());                                                     //แสดงผลจำนวนข้อมูลใน StringQueue
    }
  }

คืนค่าจาก StringQueue มาแสดงผลบน Serial Monitor และ LCD
  if(digitalRead(button) == 0){
    delay(100);
    if(digitalRead(button) == 1){
      if (st.get( temp )){                 //รับค่าคืนจาก String Queue
        temp.toCharArray(buffer,20);          
        Serial.println("\nGet : [" + (String)buffer + " ] Queue");
        Serial.println("Typing words to Queue or Press Button to get word from Queue");
        lcd.clear();                         //สั่ง LCD แสดงค่าที่ได้จาก StringQueue
        lcd.setCursor(0,0);
        lcd.print(buffer);
        lcd.setCursor(0,1);
        lcd.print(st.size());
      }
      else if(!st.get(temp)){
        Serial.println("\nQueue is Empty !!!");
        Serial.println("Please !!! Typing words to Queue : ");
      }
      else{
        Serial.println("\nGet String error!");
      }
      delay(50);
    }
  }

แสดงผลไฟ
if(st.size() == 10){                                               //แสดงไฟสีแดงในกรณีที่ StringQueue เต็ม
    digitalWrite(red_led,HIGH);
    lcd.setCursor(3,1);
    lcd.print("Queue is Full !!!");
  }
  else if(st.size() == 0){                            //แสดงไฟสีเขียวในกรณีที่ StringQueue ว่าง
    digitalWrite(green_led,HIGH);
    lcd.setCursor(3,1);
    lcd.print("Queue is Empty !!!");
  }
  else{                                                   //ดับไฟทุกสีในกรณีที่ StringQueue ไม่เต็มและไม่ว่าง
    digitalWrite(red_led,LOW);
    digitalWrite(green_led,LOW);
  }

ผลการทดลอง



No comments:

Post a Comment