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);
  }

ผลการทดลอง



Thursday, September 11, 2014

Warm-Up 2

  โจทย์กำหนดให้สร้าง class StringStack เป็นคลาสที่เก็บตัวแปร String แบบ Stack โดยรับค่าจาก Serial และนำค่าออกจาก Stack โดยการกดปุ่มที่ต่อกับ Arduino แบบ Active Low

Button With Arduino

Fritzing

โดยกำหนด API  ของ class StringStack ดังนี้

/////////////////////////////////////////////////////////////////////////
‪#‎include‬ 
class StringStack {
public:
StringStack( int capacity=10 ); // constructor
boolean put( String s ); // put a String object on stack
boolean get( String &s ); // get a String object from stack
inline int size(); // return the number of String objects on the stack
inline boolean isEmpty(); // return true if stack is empty, otherwise false
inline boolean 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 objects stored
String *buf; // used to store String objects on stack
};
/////////////////////////////////////////////////////////////////////////

Method ต่างๆใน Class

  • StringStack( int capacity=10 ); ใช้ในการสร้างตัวแปร Class
  • boolean put( String s ); ใช้ในการรับ String เข้ามาเก็บใน Class แบบ Stack
  • boolean get( String &s ); ใช้ในการส่ง String ออกไปโดยส่งผ่านทาง Address ของตัวแปรที่รับเข้ามา
  • inline int size(); ใช้ในการส่งค่าของจำนวนของ String ใน Stack
  • inline boolean isEmpty(); ใช้ในการตรวจสอบว่า StringStack ว่างหรือไม่
  • inline boolean isFull(); ใช้ในการตรวจสอบว่า StringStack เต็มหรือไม่

Variable ต่างๆใน Class

  • int capacity; ตัวแปรสำหรับเก็บ ค่าความจุ ของ StringStack
 • int count; ตัวแปรสำหรับนับจำนวนของข้อมูลใน StringStack  • String *buf; ตัวแปรสำหรับเก็บ String ในรูปแบบของ Stack

Class StringStack <StringStack.h>

//StringStack Libraly
#ifndef StringStack_h
#define StringStack_h

#include "Arduino.h"
#include "string.h"

class StringStack {
  public:
    StringStack( int capacity ); // constructor
    boolean put( String s ); // put a String object on stack
    boolean get( String &s ); // get a String object from stack
    inline int size(); // return the number of String objects on the stack
    inline boolean isEmpty(); // return true if stack is empty, otherwise false
    inline boolean isFull(); // return true if stack is full, otherwise false
    String* getStack();
  private:
    int capacity; // the max. capacity of the stack
    int count; // used to count the number of string objects stored
    String *buf; // used to store String objects on stack
};

#endif

Class StringStack <StringStack.cpp>

#include "StringStack.h"

StringStack::StringStack( int capacity=10 ) {
  this->capacity = capacity; // constructor
  count = 0;
  buf = new String[capacity];
}

boolean StringStack::put( String s ) {
  if(!isFull()){
    buf[count] = s;
    if(count<9){
      count++;
    }
    return true;
  }
  else{
    return false;
  }
}

boolean StringStack::get( String &s ) {
  if(!isEmpty()){
     if(count>0){
      count--;
    }
    *&s = buf[count];
    buf[count] = "";
   return true;
  }
  else{
    return false;
  }
}

inline int StringStack::size() { // return the number of String objects on the stack
  return count;
}

inline boolean StringStack::isEmpty() {
  if(count == 0){
    return true;
  }
  else{
    return false;
  }
}

inline boolean StringStack::isFull(){
  if(count == 9){
    return true;
  }
  else{
    return false;
  }
}

String* StringStack::getStack(){
  return buf;
}

Arduino Code

#include "StringStack.h"
int num = 10; // capacity
StringStack st( num );
String str;
int state;
void setup(){
  pinMode(2,INPUT);
  Serial.begin(115200);
  Serial.print("Put String into Stack(stack keep 20 character) : ");
}
void loop(){
  str = "";
  String temp;
  char buffer[20];
  if(digitalRead(2) == 0){
    delay(100);
    if(digitalRead(2) == 1){
      if ( st.get( temp ) ) {
        temp.toCharArray( buffer, 20 );
        Serial.print("Get : [ ");
        Serial.print( buffer );
        Serial.println(" ] From Stack");
        Serial.println();
        Serial.println("Typing words to stack or Press Button to get words from stack : ");
      } 
      else if(!st.get( temp )){
        Serial.println("");
        Serial.println("Stack is Emtry !!!");
        Serial.println("Please !!! Typing words to stack : ");
      }
      else {
        Serial.println( "\nGet string error!" );
      }
      delay(50);
    }
  }
  while(Serial.available() > 0)
  {
    str = Serial.readStringUntil('\n');
  }
  if(str.length()>20){
    str = str.substring(0, 20);
  }
  if(str.length()<=20 && str.length()>0){
    if ( !st.put( str ) ) {
      Serial.println("");
      Serial.println( "Stack is Full" );
      Serial.println("Press Button to get words from stack : ");
    }
    else {
      Serial.print( "add : >> " );
      Serial.print( str );
      Serial.println( " << to Stack" );
      Serial.print("Stack Have : [ ");
      for(int i = 0 ; i < num ; i++){        
        if(st.getStack()[i] != ""){
          Serial.print(st.getStack()[i]);
          if(st.getStack()[i+1] != ""){
            Serial.print(" , ");
          }
        }
      }  
      Serial.println(" ]");
      Serial.println("");
      Serial.println("Put String into Stack or Press Button For get String : ");
    }
  }
}
เงื่อนไขการทำงาน
• ใส่อักขระได้ไม่เกิน 20 ตัว หากเกินจะตัดให้เหลือ 20 ตัว
• เมื่อกดปุ่มจะนำค่าออกจาก Stack มาแสดง
• เมื่อ Stack เต็มไม่สามารถเพิ่มข้อมูลได้แล้วจะแสดงคำเตือนว่า Stack is Full
• เมื่อ Queue ว่างไม่สามารถดึงข้อมูลได้แล้วจะแสดงคำเตือนว่า Stack is Empty 

ผลการทดลอง

Extra >> StringQueue

  ใช้ API แบบ StringStack แต่เก็บข้อมูลในรูปแบบ Queue (เข้าก่อนออกก่อน)

Class StringQueue <StringQueue.h>

//StringQueue Libraly
#ifndef StringQueue_h
#define StringQueue_h

#include "Arduino.h"
#include "String.h"

class StringQueue {
  public:
    StringQueue( int capacity ); // constructor
    boolean put( String s ); // put a String object on stack
    boolean get( String &s ); // get a String object from stack
    inline int size(); // return the number of String objects on the stack
    inline boolean isEmpty(); // return true if stack is empty, otherwise false
    inline boolean isFull(); // return true if stack is full, otherwise false
    String* getQueue();
  private:
    int capacity; // the max. capacity of the stack
    int count; // used to count the number of string objects stored
    String *buf; // used to store String objects on stack
};

#endif

Class StringQueue <StringQueue.cpp>

#include "StringQueue.h"

StringQueue::StringQueue( int capacity=10 ) {
  this->capacity = capacity; // constructor
  count = 0;
  buf = new String[capacity];
}

boolean StringQueue::put( String s ) {
  if(!isFull()){
    buf[count] = s;
    if(count<9){
      count++;
    }
    return true;
  }
  else{
    return false;
  }
}

boolean StringQueue::get( String &s ) {
  if(!isEmpty()){
      if(count>0){
      count--;
    }
    String temp = buf[0];
    *&s = temp;
    for(int i = 0;i<9;i++){
    buf[i] = buf[i+1];
}
  
   return true;
  }
  else{
    return false;
  }
}

inline int StringQueue::size() { // return the number of String objects on the Queue
  return count;
}

inline boolean StringQueue::isEmpty() {
  if(count == 0){
    return true;
  }
  else{
    return false;
  }
}

inline boolean StringQueue::isFull(){
  if(count == 9){
    return true;
  }
  else{
    return false;
  }
}

String* StringQueue::getQueue(){
  return buf;
}

Arduino Code

#include "StringQueue.h"
int num = 10; // capacity
StringQueue st( num );
String str;
void setup(){
  pinMode(2,INPUT);
  Serial.begin(115200);
  Serial.print("Put String into Queue(Queue keep 20 character) : ");
}
void loop(){
  str = "";
  String temp;
  char buffer[20];
  if(digitalRead(2) == 0){
    delay(100);
    if(digitalRead(2) == 1){
      if ( st.get( temp ) ) {
        temp.toCharArray( buffer, 20 );
        Serial.print("Get : [ ");
        Serial.print( buffer );
        Serial.println(" ] From Queue");
        Serial.println();
        Serial.println("Typing words to Queue or Press Button to get words from Queue : ");
      } 
      else if(!st.get( temp )){
        Serial.println("");
        Serial.println("Queue is Emtry !!!");
        Serial.println("Please !!! Typing words to Queue : ");
      }
      else {
        Serial.println( "\nGet string error!" );
      }
      delay(50);
    }
  }
  while(Serial.available() > 0)
  {
    str = Serial.readStringUntil('\n');
  }
  if(str.length()>20){
    str = str.substring(0, 20);
  }
  if(str.length()<=20 && str.length()>0){


    if ( !st.put( str ) ) {
      Serial.println("");
      Serial.println( "Queue is Full" );
      Serial.println("Press Button to get words from Queue : ");
    }
    else {
      Serial.print( "add : >> " );
      Serial.print( str );
      Serial.println( " << to Queue" );
      Serial.print("Queue Have : [ ");
      for(int i = 0 ; i < num ; i++){        
        if(st.getQueue()[i] != ""){
          Serial.print(st.getQueue()[i]);
          if(st.getQueue()[i+1] != ""){
            Serial.print(" , ");
          }
        }
      }  
      Serial.println(" ]");
      Serial.println("");
      Serial.println("Put String into Queue or Press Button For get String : ");
    }
  }
}

ผลการทดลอง

Source Code >> Download <<

Wednesday, August 27, 2014

RGB LED using arduino by C++ class

RGB LED using arduino by C++ class

    จากโจทย์กำหนดให้ใช้ arduino ร่วมกับ rgb led โดยใช้ push button ในการรับอินพุตสำหรับเพิ่มความสว่างของแต่ละสีโดยเขียนเป็น class RGB_LED

ออกแบบวงจร


  การออกแบบวงจร จากโจทย์กำหนดให้ใช้วงจรปุ่มกดแบบ Pull-Up (Active low) เพื่อรับค่าการกดแล้วส่งค่าไปยังบอร์ด Arduino เพื่อเปลี่ยนแปลงค่า duty cycle เพื่อปรับความสว่างของ RGB led แต่ละสี

ออกแบบโค้ด

//RGB_LED Libraly
#ifndef RGB_LED_h
#define RGB_LED_h
#include "Arduino.h"
class RGB_LED {
  public:
    RGB_LED( byte red_pin, byte green_pin, byte blue_pin);
    void add_dc( byte color );
  private:
    void update();
    byte pins[3], rgb[3];
};
#endif

  สร้าง RGB_LED.h เป็น  Abtract class กำหนดตัวแปรอาเรย์ pin[3] สำหรับเก็บค่าขาต่อใช้ RGB led แต่ละสีและ rgb[3] สำหรับเก็บค่าความสว่าง (duty cycle) ของ RGB led แต่ละสีโดยใส่เมธอดดังต่อไปนี้
  RGB_LED( byte red_pin, byte green_pin, byte blue_pin);
    เป็นคอนสตรัคเตอร์สำหรับสร้างตัวแปรคลาสโดยรับค่าเป็นขาต่อใช้งานของ  RGB led แต่ละสี
  void add_dc( byte color );
    สำหรับเรียกใช้เพื่อเพิ่มค่าความสว่าง RGB led แต่ละสีโดยรับค่าเป็น 1 สำหรับสีแดง 2 สำหรับสีเขียว 3 สำหรีบสีฟ้า
  void update();
    สำหรับเปลี่ยนแปลงค่าความสว่างที่ได้จากเมธอด add_dc เพื่อนำค่าที่ถูกปรับไปใช้เปลี่ยนแปลงความสว่างถูกเรียกใช้ใน add_dc

#include "RGB_LED.h"

RGB_LED::RGB_LED( byte red_pin, byte green_pin, byte blue_pin) {
  pins[0] = red_pin;
  pins[1] = green_pin;
  pins[2] = blue_pin;
  for ( int i=0; i < 3; i++ ) {
    pinMode( pins[i], OUTPUT ); // use this pin as output
  }
  rgb[0] = 0;
  rgb[1] = 0;
  rgb[2] = 0;
}

void RGB_LED::add_dc( byte color ) {
  if( rgb[color]<255 ){
    rgb[color] = rgb[color]+8;
  }
  else{
    rgb[color] = 0;
  }
  update();
}

void RGB_LED::update() {
  for ( int i=0; i < 3; i++ ) {
    analogWrite( pins[i], rgb[i] );
  }
}

  ใส่รายละเอียดของแต่ละเมธอด

Arduino Code

#include "RGB_LED.h"

RGB_LED rgb(9,10,11);

void setup() {
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
}

void loop() {

  delay(100);
  if(digitalRead(2)==0){rgb.add_dc(0);}
  if(digitalRead(3)==0){rgb.add_dc(1);}
  if(digitalRead(4)==0){rgb.add_dc(2);}
}
**แก้ไขโค้ด**
#include "RGB_LED.h"
int count_startR = 0;
int count_startG = 0;
int count_startB = 0;
int count_stopR = 0;
int count_stopG = 0;
int count_stopB = 0;
int stateR = 0;
int stateG = 0;
int stateB = 0;
RGB_LED rgb(9,10,11);
void setup() {
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  Serial.begin(9600);
}
void loop() {
  delay(100);
  switch(stateR){ //defult stateR = 0
    case 0 : if(digitalRead(2)==0){ //เมื่อกดปุ่มจะนับเวลาเริ่มต้นและเปลี่ยน state เป็น 1
                count_startR=millis(); 
                stateR = 1;
             } 
             break;
    case 1 : if(digitalRead(2)==0){ //เมื่อ state = 1 จะนับเวลาเพื่อเทียบกับเวลาเริ่มต้น
                count_stopR=millis(); 
                if((count_stopR-count_startR) > 100){  //เมื่อเวลาเทียบกับเวลาเริ่มต้นต่างกัน 100ms
                    stateR = 2; //เปลี่ยน state = 2
             }} 
                break;
    case 2 : rgb.add_dc(0); // เมื่อ state = 2 จะเพิ่มค่าความสว่างหรือ duty cycle
             if(digitalRead(2)==1){ // เมื่อปล่อยปุ่มกดจะเปลี่ยน state เป็น 0 เพื่อเริ่มใหม่
                stateR =0;
             } 
             break;
  }
  
    switch(stateG){ //defult stateG = 0
    case 0 : if(digitalRead(3)==0){ //เมื่อกดปุ่มจะนับเวลาเริ่มต้นและเปลี่ยน state เป็น 1
                count_startG=millis(); 
                stateG = 1;
             } 
             break;
    case 1 : if(digitalRead(3)==0){ //เมื่อ state = 1 จะนับเวลาเพื่อเทียบกับเวลาเริ่มต้น
                count_stopG=millis(); 
                if((count_stopG-count_startG) > 100){ //เมื่อเวลาเทียบกับเวลาเริ่มต้นต่างกัน 100ms
                    stateG = 2; //เปลี่ยน state = 2
             }} 
             break;
    case 2 : rgb.add_dc(1); // เมื่อ state = 2 จะเพิ่มค่าความสว่างหรือ duty cycle
             if(digitalRead(3)==1){ // เมื่อปล่อยปุ่มกดจะเปลี่ยน state เป็น 0 เพื่อเริ่มใหม่
                stateG =0;
             } 
             break;
    }
    
    switch(stateB){ //defult stateฺB = 0
    case 0 : if(digitalRead(4)==0){ //เมื่อกดปุ่มจะนับเวลาเริ่มต้นและเปลี่ยน state เป็น 1
                count_startB=millis(); 
                stateB = 1;
             } 
             break;
    case 1 : if(digitalRead(4)==0){ //เมื่อ state = 1 จะนับเวลาเพื่อเทียบกับเวลาเริ่มต้น
                count_stopB=millis(); 
                 if((count_stopB-count_startB) > 100){ //เมื่อเวลาเทียบกับเวลาเริ่มต้นต่างกัน 100ms
                    stateB = 2; //เปลี่ยน state = 2
             }} 
             break;
    case 2 : rgb.add_dc(2); // เมื่อ state = 2 จะเพิ่มค่าความสว่างหรือ duty cycle
             if(digitalRead(4)==1){ // เมื่อปล่อยปุ่มกดจะเปลี่ยน state เป็น 0 เพื่อเริ่มใหม่
                stateB =0;
             } 
             break;
    }

}

  สร้างตัวแปร RGB_LED rgb(9,10,11) โดยใส่อินพุตเป็นขาต่อใช้งานของ LED แต่ละสี
  สร้างโค้ดเก็บข้อมูลจากปุ่มกดแต่ละปุ่มและเรียกใช้เมธอด rgb.add_dc(0) โดยใส่อินพุตเป็น 1, 2, 3 เพื่อเปลี่ยนแปลงความสว่างของสีที่เราต้องการ
  

ผลการทดลอง



source code :')

>> Schematic <<

Sunday, August 17, 2014

Arduino Yun Vs Arduino Due Comparision

Arduino Yun Vs Arduino Due

       Arduino หรือ "อาดูยโน่" บอร์ดไมโครคอนโทรลเลอร์ยอดฮิตจากประเทศอิตาลี ที่ปัจจุบันใช้กันอย่างแพร่หลายมาก โดยเริ่มต้น Massimo Banzi และ David Cuartielles ผู้ก่อตั้ง Arduino เพียงแค่ต้องการสร้างไมโครคอนโทรลเลอร์ราคาถูกเพื่อให้นนักเรียนหรือนักศึกษาสามารถเป็นเจ้าของได้ง่ายเพื่อการเรียนรู้เกี่ยวกับอุปกรณ์อิเล็คทรอนิกส์       แต่ในปัจจุบัน Arduino ได้แตกสายพันธ์ุออกไปเยอะมากเพื่อเข้าถึงการใช้งานทุกรูปแบบ โดยในปัจจุบัน Arduino มีมากถึง 20 model (ยังไม่รวมเวอร์ชั่นโคลนอื่นๆ) และยังมี Shields และ Accessories อีกมากมายเพื่อตอบโจทย์ความต้องการของทุกโปรเจค โดยยังคงคอนเซ็ป Open Source และมีราคาที่ถูกกว่าไมโครคอนโทรลเลอร์อื่นๆ       บทความนี้จะอธิบายและเปรียบเทียบ Arduino 2 Model นั่นคือ Arduino Yun และ Arduino Due แต่อาจจะเป็นการเปรียบเทียบข้ามรุ่นกันไปหน่อยเพราะจริงๆแล้วสองบอร์ดนี้เหมาะกับการใช้งานที่ต่างกันมาก

specification

Detail
Arduino Due Arduino Yun
Arduino microcontroller
Micro controller AT91SAM3X8E ATmega32u4
Operating Voltage 3.3V 5V
Input Voltage (recommended) 7-12V 5V
Input Voltage (limits) 6-16V 5V
Digital I/O Pins 54 (12 PWM) 20 (7 PWM)
Analog Input Pins 12 12
Analog Outputs Pins 2 (DAC) -
Total DC Output Current on all I/O lines 130 mA 40 mA
DC Current for 3.3V Pin 800 mA 50 mA
DC Current for 5V Pin 800 mA -
Flash Memory 512 KB all available for the user applications 32 KB (of which 4 KB used by bootloader)
SRAM 96 KB (two banks: 64KB and 32KB) 2.5 KB
EEPROM - 1 KB
Linux microprocessor
Processor - Atheros AR9331
Architecture - MIPS @400MHz
Operating Voltage - 3.3V
Ethernet - IEEE 802.3 10/100Mbit/s
WiFi - IEEE 802.11 b/g/n
USB Type-A - 2.0 Host
Card Reader - Micro-SD only
RAM - 64 MB DDR2
Flash Memory - 16 MB
*Arduino Yun : PoE compatible 802.3af card support (see the note below)

       จากตารางจะเห็นได้ว่าใน Arduino Yun นั้นใส่ Linux Microprocessor มาด้วยนี่จึงเป็นข้อแตกต่างที่ได้กล่าวในข้างต้นว่าเหมาะกับการใช้งานที่ต่างกัน

       Arduino Yun



       Arduino Yun นั้นใช้โครงสร้างบอร์ดแบบเดียวกันกับ Arduino UNO แต่ใช้ชิบไมโคคอนโทรลเลอร์ ATmega32u4 แบบเดียวกับ Arduino Leonardo โดยขาต่อใช้งานเหมือนกันทำให้สามารถใช้ Shield ได้หลากหลาย

       ข้อแตกต่างคือมันมาพร้อมกับ Linux Microprocessor จากค่าย Qualcomm Atheros AR9331 ซึ่งปกติ CPU ตัวนี้นิยมใช้ใน Wireless router ซะเป็นส่วนใหญ่โดยใช้ระบบปฏบัติการที่รู้จักกันในชื่อ OpenWRT โดยเวอร์ชั่นที่ใช้บน Arduino Yun นั้นใช้ชื่อว่า Linino โดยฝังอยู่บน Flash Memory ขนาด 16MB และสามารถเพิ่มพื้นที่เก็บข้อมูลได้ด้วย Micro SD Card
       การเชื่อมต่อมีทั้ง LAN 10/100M โดยพอร์ตแลนนั้นรองรับการจ่ายไฟผ่านพอร์ตแลนด้วย (POE) และ Wifi 802.11 b/g/n และยังสามารถอัพโหลด Sketches ผ่านทาง Network ได้โดยไม่ต้องต่อสาย USB อีกต่อไป!! และยังมี USB 2.0 หนึ่งพอร์ทสำหรับเสียบอุปกรณ์เช่น Webcam, Joy Stick เป็นต้น
       ด้วยอุปกรณ์ที่เพิ่มขึ้นทั้ง Linux Microprocessor และการเชื่อมต่อทั้ง LAN, Wifi ทำให้มันทำงานได้หลากหลายกว่าบอร์ด Arduino ตัวอื่นๆเช่นมันสามารถนำมาทำ Web Server,กล้องวงจรปิดด้วยการ streaming video จาก webcam หรือแม้กระทั้งควบคุมอุปกรณ์ไฟฟ้าภายในบ้านจากมือถือหรือคอมพิวเตอร์นอกบ้านได้โดยเราเรียกว่า Internet Of Things

       Arduino Due


       Arduino Due จะแตกต่างจากบอร์ด Arduino ทั่วไปเพราะมันใช้ชิปไมโครคอนโทรลเลอร์ Atmel SAM3X8E ซึ่งอยู่ในตระกูล ARM Cortex-M3 CPU แทนที่จะเป็น AVR แบบ Arduino ทั่วๆและเป็น Arduino ตัวแรกที่ใช้ CPU แบบ 32bit ข้อดีของมันก็คือมีการประมวลผลที่ไวกว่าโดยมันมี Clock (สัญญาณนาฬิกา) 84Mhz ซึ่งแรงกว่า Arduino ที่มี Clock เพียง 16Mhz โดยมี digital I/O 54 ขาและ analog input 12 ขาซึ่งเหมาะสำหรับการเชื่อมต่อกันอุปกรณ์หลายๆอย่างและยังมี USB OTG สำหรับเชื่อมต่ออุปกรณ์ภายนอกด้วย
ปล. Arduino Due ใช้ไฟเลี้ยง 3.3V ไม่ควรนำ input ที่มีแรงดัน 5v มาต่อเพราะบอร์ดอาจจะพังได้(ซึ่งมันพังแน่ๆ)***

       Comparision

       ข้อแตกต่างของแต่ละบอร์ด
Detail
Arduino Due Arduino Yun
Arduino MCU 23-bit arm cortex-M3 @84 MHz 8-bit AVR @16MHz
Linux MCU - Atheros AR9331 @400 MHz
Flash Memory 512 KB 32KB (4 KB used by bootloader)
SRAM 96 KB (two banks: 64KB and 32KB) 2.5 KB
Current Consumption 800 mA 50 mA
Digital I/O Pins 54 (12 PWM) 20 (7 PWM)
Analog Input Pins 12 12

       Arduino MCU ใช้กันคนละตระกูล Arduino Due ได้เปรียบในเรื่องนี้เนื่องจากสามารถประมวลผลได้ไวกว่า
       Linux MCU ข้อนี้ทำให้ Arduino Yun ได้เปรียบกว่าเนื่องจากมี Linux MCU สามารถทำงานได้หลากหลายมากกว่า
       Flash Memory ใช้สำหรับเก็บ Sketches หรือโปรแกรมของเรา Arduino Due อาจจะได้เปรียบถ้าเทียบกับการเขียน Sketches แต่ Arduino Yun สามารถสั่ง I/O ผ่านโปรแกรมบน Linux ได้และมีพื้นที่เก็บมากกว่าหลายเท่าหากเพิ่ม Micro SD Card เข้าไปในข้อนี้จึงอาจจะเปรียบเทียบกันยากขึ้นอยู่กับการนำไปใช้งาน
       SRAM ใช้สำหรับเก็บข้อมูลโดยอ่านและเขียนโดย Sketches หรือ โปรแกรม ที่เราเขียนเข้าไป
**Static RAM (SRAM) มีขนาดจำกัด อยู่ในระดับกิโลไบต์ (KB) ดังนั้น สำหรับการประยุกต์ใช้งานในบางกรณี อาจต้องต่อวงจรเพื่อใช้หน่วยความจำภายนอกเสริม สำหรับเก็บข้อมูลชั่วคราวในขณะทำงาน การที่ SRAM มีขนาดใหญ่ทำให้มีเนื้อที่เพียงพอในการประมวลผลโปรแกรมรวมทั้งข้อมูลทั้งหมด โดยช่วยทำให้ประหยัดค่าใช้จ่ายลงได้ เพราะไม่จำเป็นต้องติดตั้ง Flash ซึ่งมีราคาแพงเข้าไปข้างใน และไม่ต้องใช้ SRAM จากภายนอก (External SRAM) อีกทั้งยังช่วยทำให้แผ่นวงจรมีขนาดเล็กลงอีกด้วย
       Current Consumption อัตราการใช้พลังงานหากเปรียบเทียบเฉพาะ Arduino MCU Arduino Due จะกินพลังงานมากกว่าเนื่องจาก I/O pin ของมันเยอะกว่า แต่ถ้าหากเปรียบเทียบการใช้พลังงานของทั้งบอร์ด [ยังตอบไม่ได้เนื่องจากหาอัตราการใช้พลังงานของ Linux MCU Atheros AR9331 ยังไม่เจอ]
       Digital I/O Pins Arduino Due ได้เปรียบกว่าในเรื่องนี้เพราะมีขาต่อใช้งานมากกว่าถึงเท่านึงรอบรับอุปกรณ์ได้เยอะมากกว่า

       Summary

       อาจจะเปรียบเทียบกันได้ยากในเชิงการใช้งานโดยทั้งสองเหมาะกับการใช้งานที่ต่างกัน เช่นหากเราจะทำระบบวัดอุณหภูมิภายในบ้านแล้วส่งขึ้น Web Server เพื่อให้สามารถดูได้จากนอกบ้านเราก็ต้องเลือกใช้ Arduino Yun เนื่องจากตอบโจทย์ได้มากกว่า [Arduino Due อาจจะทำได้โดยใช้ Ethernet Shield,Wifi Shield แต่อาจจะยุ่งยากในการใช้งานมากกว่า] หรือหากเราต้องการนำไปใช้งานที่ต้องการความเร็วในกระประมวลผลสูงเช่น ใช้ร่วมกับเซ็นเซอร์ต่างๆ ที่มีความละเอียดหรือมีการต่อใช่งาน I/O เยอะกว่าบอร์ดธรรมดาเป็นต้น :')

Cr. arduino.cc/