วันพฤหัสบดีที่ 28 สิงหาคม พ.ศ. 2557

RGB LED / PWM-based Dimming


คุณสมบัติของโค้ดสำหรับ Arduino และวงจร


  • วงจรทำงานโดยใช้ระดับแรงดันสำหรับ I/O ที่ 5V เท่านั้น
  • มีปุ่มกด 3 ปุ่ม (ให้ชื่อว่า R, G, B) ทำงานแบบ Pull-up (active-low) ให้ต่อวงจรปุ่มกดเอง เพื่อใช้งานกับบอร์ด Arduino
  • มีเอาต์พุต 3 ขา ต่อกับวงจร RGB LED (จะใช้แบบ Common-Anode หรือ Common-Cathode ก็ได้) พร้อมตัวต้านทานจำกัดกระแส 3 ตัว
  • เขียนโค้ดด้วยภาษา C++ สำหรับ Arduino เพื่อสร้าง Class ที่มีชื่อว่า "RGB_LED"
  • กำหนดให้ constructor สำหรับคลาส RGB_LED เป็นดังนี้                                                
    -  RGB_LED( int red_pin, int_green_pin, int blue_pin );                                  
    -  โดยรับค่ามาเป็นหมายเลขของ I/O pins สำหรับ 3 ขาของ Arduino ที่จะถูกใช้งานเป็นเอาต์พุตแบบ PWM
  • มีเมธอดอย่างเช่น                                                                                                      -  void setRed( int duty_cycle ), void setGreen( int duty_cycle ),                  
    -  void setBlue( int duty_cycle ) เพื่อใช้กำหนดค่า duty cycle ของขาเอาต์พุต PWM และใช้ในการกำหนดความสว่างของแต่ละสี ใช้คำสั่ง analogWrite() ในการกำหนดค่า
  • กำหนดสมาชิก instance members ตามความจำเป็น เช่น ค่า duty cycles สำหรับแต่ละสี
  • ใช้คลาสดังกล่าวในการเขียนโค้ด (สร้าง object จากคลาสดังกล่าวและเรียกใช้เมธอด) เพื่อสาธิตการทำงานร่วมกับฮาร์ดแวร์จริง
  • เมื่อกดปุ่ม R, G หรือ B แล้วปล่อยแต่ละครั้ง จะทำให้ค่า duty cycle ของสีดังกล่าวเพิ่มขึ้นทีละ 8 ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่ (ค่าเริ่มต้นสำหรับ duty cycles เป็น 0)
  • เมื่อกดปุ่ม R, G หรือ B ค้างไว้อย่างน้อย 100 msec จะเพิ่มค่าขึ้นทีละ 8 (แล้วเริ่มนับเวลาใหม่) ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่


อุปกรณ์ทดลอง (Apparatus) 



      อุปกรณ์     
         จำนวน         
RGB LED 5mm.
(Anode)
1


ตัวต้านทาน 330 โอห์ม 


(ส้ม ส้ม น้ำตาล ทอง)
6


BREADBOARD 


บอร์ดทดลองอิเล็กทรอนิกส์
1
Arduino Uno R3 
1
ปุ่มกด
3
สาย USB Cable
1
สายไฟต่อวงจร
-



ผังวงจร (Breadboard Layout)


ผังวงจร



รูปภาพจากการต่อวงจรจริง


Arduino Sketch


ข้อ1 : โค้ด Arduino สำหรับ เมื่อกดปุ่ม R, G หรือ B แล้วปล่อยแต่ละครั้ง จะทำให้ค่า duty cycle ของสีดังกล่าวเพิ่มขึ้นทีละ 8 ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่ (ค่าเริ่มต้นสำหรับ duty cycles เป็น 0)

class RGB_LED{
  public:
    //constructor
    RGB_LED( int red_pin, int green_pin, int blue_pin );
    //variable
    int duty_red,duty_blue,duty_green,_R,_G,_B;
    //methode
    void setRed(int duty_cycle);
    void setGreen(int duty_cycle);
    void setBlue(int duty_cycle);
};

RGB_LED::RGB_LED( int red_pin, int green_pin, int blue_pin ){                                      
  duty_red = 255;
  duty_blue = 255;
  duty_green = 255;
  _R = red_pin;
  _G = green_pin;
  _B = blue_pin;
  pinMode(_R,OUTPUT); // use as output
  pinMode(_G,OUTPUT); // use as output
  pinMode(_B,OUTPUT); // use as output
}

void RGB_LED :: setRed(int duty_cycle){
  duty_red = duty_cycle;
  duty_red -= 8;
  if(duty_red<0){
    duty_red = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

void RGB_LED :: setGreen(int duty_cycle){
  duty_green = duty_cycle;
  duty_green -= 8;
  if(duty_green<0){
    duty_green = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

void RGB_LED :: setBlue(int duty_cycle){
  duty_blue = duty_cycle;
  duty_blue -= 8;
  if(duty_blue <0){
    duty_blue = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

     เป็นสร้างคลาส RGB_LED โดยมี constructor ที่มีพารามีเตอร์ 3 ตัว ซึ่งคือ output ของวงจรนี้ ไปต่อกับ RGB LED และมี method ซึ่งจะทำการเพิ่มค่าสีของแต่ละขาที่ออกจากวงจร โดยเมื่อขาของoutput ที่ไปต่อกับ RGB LED สว่างมากที่สุดแล้ว จะทำการรีเซตค่าให้เป็นค่าตั้งต้นในขานั้นๆ 


RGB_LED led = RGB_LED(9,10,11);  //call class RGB_LED                                               
const int R = 2; // input of button red
const int G = 4; // input of button green
const int B = 7; // input of button blue
int a=0;
int b=0;
int c=0;
int red_State = 1; 
int green_State = 1; 
int blue_State = 1;

void setup(){
  pinMode(R,INPUT);
  pinMode(G,INPUT);
  pinMode(B,INPUT);
}

void loop(){
  red_State = digitalRead(R);
  green_State = digitalRead(G);
  blue_State = digitalRead(B);
  // button_red
  if(red_State == LOW){ //active-low
    a = 1;
  }
  if(green_State == LOW){ //active-low
    b = 1;
  }
  if(blue_State == LOW){ //active-low
    c = 1;
  }
  
  if(a == 1 && red_State == HIGH){
    a = 0;
    led.setRed(led.duty_red);
  }else if(b == 1 && green_State == HIGH){
    b = 0;
    led.setGreen(led.duty_green);
  }else if(c == 1 && blue_State == HIGH){
    c = 0;
    led.setBlue(led.duty_blue);
  }
}


     โดยประกาศ object ของคลาส RGB_LED และกำหนดค่าคงที่ซึ่งใช้เป็น input ในการรับเข้ามา และกำหนดค่าต่างๆที่ใช้ในcode ด้วย สำหรับ void setup() เป็นการกำหนดให้เป็น input ของวงจร ส่วน void loop() เป็นการกำหนดให้มีการกดปุ่มแล้วปล่อยถึงจะทำการเพิ่มสีของขานั้นๆ

ผลการทดลองข้อ1






ข้อ2 : โค้ด Arduino สำหรับ เมื่อกดปุ่ม R, G หรือ B ค้างไว้อย่างน้อย 100 msec จะเพิ่มค่าขึ้นทีละ 8 (แล้วเริ่มนับเวลาใหม่) ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่
RGB_LED led = RGB_LED(9,10,11);                                                                               
const int R = 2; // input of button red
const int G = 4; // input of button green
const int B = 7; // input of button blue
int a=0;
int b=0;
int c=0;
int red_State = 1;
int green_State = 1;
int blue_State = 1;
unsigned long time00,time01,time10,time11,time20,time21;

void setup(){
  pinMode(R,INPUT);
  pinMode(G,INPUT);
  pinMode(B,INPUT);
  Serial.begin(9600);
}

void loop(){
  red_State = digitalRead(R);
  green_State = digitalRead(G);
  blue_State = digitalRead(B);
  // button_red
  if(red_State == LOW){ //active-low
    time01=millis();
    if(a == 0){
      time00 = time01;
      a = 1;
    }
    if(time01-time00 >= 100  ){
      led.setRed(led.duty_red);
      Serial.println(time01);
      time00 = 0;
    }
  }
  if(green_State == LOW){ //active-low
    time11=millis();
    if(b == 0){
      time10 = time11;
      b = 1;
    }
    if(time11-time10 >= 100  ){
      led.setGreen(led.duty_green);
      Serial.println(time11);
      time10 = 0;
    }
  }
  if(blue_State == LOW){ //active-low
    time21=millis();
    if(c == 0){
      time20 = time21;
      c = 1;
    }
    if(time21-time20 >= 100  ){
      led.setBlue(led.duty_blue);
      Serial.println(time21);
      time20 = 0;
    }
  }
}

     มีการเปลี่ยนแปลง code จากข้อ 1 แค่ในส่วนที่ไม่ใช่ class เท่านั้น ดังนี้ ใช้ millis() ในการแสดงค่าของเวลาในช่วงที่กดปุ่ม แล้วเช็คไปเรื่อยๆว่าปุ่มนั้นๆมีการกดเกิน 100 ms หรือยัง ถ้าเกินแล้ว ก็จะให้แสดงไฟในขานั้นๆสว่างมากขึ้น 



ผลการทดลองข้อ2





ทฤษฎี (Theory)

Pulse Width Modulation (PWM) เป็นเทคนิคในการควบคุมกำลังไฟฟ้า เป็นสัญญาณดิจิตอลแบบมีคาบ ในที่นี้ใช้ควบคุมความสว่างของหลอดไฟ แผนภาพด้านล่างแสดงให้เห็นสัญญาณ PWM ใน arduino
รูปจาก : https://learn.adafruit.com/adafruit-arduino-lesson-3-rgb-leds/theory-pwm

ทุกๆ 1/500 วินาที สัญญาณเอาต์พุท PWM จะสร้างสัญญาณพัลส์ ซึ่งความกว้างของสัญญาณพัลส์นี้จะถูกควบคุมโดยฟังก์ชัน "analogWrite" ดังนั้น "analogWrite(0)" จะไม่สร้างสัญญาณพัลส์ มีค่าลอจิกเป็น LOW และ "analogWrite(255)" จะสร้างสัญญาณพัลส์ที่มีค่าลอจิกเป็น HIGH ตลอดสัญญาณ


ต้องกำหนดค่าใน analogWrite เป็นค่าตั้งแต่ 0 ถึง 255 จึงจะสร้างสัญญาณพัลส์ได้ 


ความถี่ 1 Hz หทายถึง สัญญาณ Pulse 1 ลูก ในเวลา 1 วินาที ฉะนั้น ความถี่ 100 Hz ก็คือ สัญญาณ Pulse 100 ลูก ในเวลา 1 วินาที

วันพฤหัสบดีที่ 21 สิงหาคม พ.ศ. 2557

ความแตกต่างระหว่าง Arduino Yun กับ Arduino Due


Arduino Yun


บอร์ด Arduino Yún (ATmega32U4, Atheros AR9331) (ด้านหน้า)


         Arduino Yun เป็นบอร์ดในกลุ่มบอร์ด Arduino ใช้ชิปไมโครคอนโทรลเลอร์ ATmega32U4 ไปต่อกับชิป Wi-Fi ที่อยู่บนบอร์ดอีกตัวคือ Atheros AR9331 จาก MIPS ที่ใช้ใน Wi-Fi Router และได้ติดตั้ง Linino ซึ่งเป็น Linux จาก Arduino ที่ต่อยอดมาจาก OpenWRT การเชื่อมต่อมีทั้ง SPI และ UART ซึ่งคาดว่าการต่อแบบ UART คงต่อเป็น Serial Port เพื่อใช้งาน Linux ผ่าน Terminal และ SPI คงเหมือนกับ Ethernet Shield และนอกจาก Ethernet และ Wi-Fi แล้ว ที่บอร์ด Atheros AR9331 ก็มีพอร์ต USB host ด้วย

         Arduino Yun มีคุณสมบัติหลายอย่าง เช่น มี 14 digital input/output pins, 7 pulse width modulation(PWM) channels และ 12 analog inputs นอกจากนั้น ยังมี 16 MHz crystal oscillatior และ microUSB connector รวมถึง Standard-A  type USB connection และ PoE compatible microSD card socket เพื่อให้เก็บข้อมูลได้มากขึ้น เมื่อ Arduino Yun เริ่มทำงานครั้งแรกจะทำหน้าที่เป็นจุดเชื่อมต่อ Wi-Fi และสร้างเครือข่าย Wi-Fi ชื่อ "Arduino" จากนั้นผู้ใช้สามารถตั้งค่าบอร์ด ได้ ด้วยการใส่ชื่อและรหัสผ่านของเครือข่าย Wi-Fi

         สำหรับคำว่า Yun (ยวิ๋น) เป็นภาษาจีน แปลว่า เมฆ การใช้คำว่าเมฆ เพื่อต้องการสื่อสารว่าเป็น Cloud ซึ่งไม่ได้ใช้แค่ Wi-Fi ที่มีบอร์ดในการสื่อสาร แต่ใช้การติดตั้งโปรแกรมลงสู่ตัว Arduino Yun แบบไร้สาย หรือผ่าน Cloud (และ web service) ด้วย

บอร์ด Arduino Yún ฺ[ATmega32U4, Atheros AR9331 (5V/16MHz)]



Arduino Due


บอร์ด Arduino Due (AT91SAM3X8E,  3.3V/84MHz)

         Arduino Due เป็นบอร์ดไมโครคอนโทรลเลอร์ซึ่งเป็นชิป Atmel AT91SAM3X8E ซึ่งเป็นตระกูล ARM Cortex-M3

         Arduino Due เป็นบอร์ดไมโครคอนโทรลเลอร์ รุ่นแรกของ Arduino ที่ใช้ไมโครคอนโทรลเลอร์ 32 บิต และมีพอร์ตดิจิตอลอินพุตเอาต์พุต จำนวน 54 ขา โดยเป็นโมดูล PWM จำนวน 12 ช่อง, แอนะล๊อกอินพุต 12 ช่อง,  UART จำนวน 4 ช่อง, DAC จำนวน 2 ช่อง, I2C จำนวน 2 ช่อง, โมดูล CAN และสัญญาณนาฬิกาที่มีความถี่ 84 MHz และรองรับการทำงานของอุปกรณ์ USB ในแบบ USB-OTG ซึ่งถือว่าเป็นบอร์ดที่มีความสามารถสูง ในราคาที่ไม่แพง

        โดย Arduino Due ต้องใช้กับ ซอฟแวร์ Arduino IDE เวอร์ชั่น 1.5 ขึ้นไป

***คำเตือน ต้องใช้เข้าบอร์ด เพื่อให้บอร์ดทำงาานได้ที่ 3.3V เท่านั้น ถ้ามากกว่านี้จะส่งผลให้บอร์ดเสียหายได้***

บอร์ด Arduino Due USB Port




ข้อมูลเชิงเทคนิคเปรียบเทียบระหว่างบอร์ด Arduino Yun กับ บอร์ด Arduino Due 


     เนื่องจากบอร์ด Arduino Yun มีการประมวลผล 2 ที่ คือ ชิปไมโครคอนโทรลเลอร์ ATmega32U4 และชิป Wi-Fi Atheros AR9331 ข้อมูลเชิงเทคนิคจะแสดงลักษณะของแต่ละอันในตาราง ดังต่อไปนี้

Detail
Arduino Yun
Arduino Due

Arduino microcontroller
Micro controllerATmega32u4 AT91SAM3X8E
Operating Voltage5V3.3V
Input Voltage (recommended)5V7-12V
Input Voltage (limits)5V6-16V
Digital I/O Pins20 (7 PWM)54 (12 PWM)
Analog Input Pins1212
Analog Outputs Pins-2 (DAC)
Total DC Output Current on all I/O lines40 mA130 mA
DC Current for 3.3V Pin50 mA800 mA
DC Current for 5V Pin-800 mA
Clock Speed16 MHz84 MHz
Flash Memory32 KB (of which 4 KB used by bootloader)512 KB all available for the user applications
SRAM2.5 KB96 KB (two banks: 64KB and 32KB)
EEPROM1 KB-
Costs€52.00 + VAT (ประมาณ 2761.03 บาท ยังไม่รวมภาษี)€36.00 +VAT(ประมาณ 1911.48 บาท
ยังไม่รวมภาษี
)

Linux microprocessor
ProcessorAtheros AR9331-
ArchitectureMIPS @400MHz-
Operating Voltage3.3V-
EthernetIEEE 802.3 10/100Mbit/s-
WiFiIEEE 802.11 b/g/n-
USB Type-A2.0 Host-
Card ReaderMicro-SD only-
RAM64 MB DDR2-
Flash Memory16 MB-



สรุป


     Arduino Due เหมาะสำหรับงานที่ต้องการ การประมวลผลเร็ว อย่างเช่น การคำนวณเกี่ยวกับการบิน ซึ่งต้องคำนวณและประมวลผลข้อมูลอย่างมากใน 1 วินาที
     ส่วน Arduino Yun เหมาะสำหรับงานที่ต้องใช้ Wifi ในการเชื่อมต่อ อย่างเช่น ถ้าต้องการสร้างเครื่องบินบังคับที่ถูกควบคุมโดยแอพพลิเคชั่น บนแอนดรอยด์ ก็ควรจะใช้ Wifi ในการเชื่อมต่อระหว่างสองอุปกรณ์
     เพราะอย่างนั้น จึงไม่สามารถสรุปได้แน่ชัดว่า อะไรที่คุ้มค่ามากที่สุด แต่ความคุ้มค่าจะขึ้นอยู่กับการนำไปใช้งานให้ถูกต้องและเหมาะสม



แหล่งอ้างอิง http://arduino.cc/