วันพฤหัสบดีที่ 9 กุมภาพันธ์ พ.ศ. 2560

โปรแกรมไฟวิ่ง LED 10 ตัวขับออกผ่านพอร์ตดิจิตอล

เขียนโปรแกรมไฟวิ่ง LED 10 ตัวขับออกผ่านพอร์ตดิจิตอล
 
ฟังก์ชั่นที่ใช้งาน
-pinMode() http://arduino.cc/en/Reference/PinMode
-digitalWrite() http://arduino.cc/en/Reference/DigitalWrite
-delay() http://arduino.cc/en/reference/delay

โจทย์การทดลอง
-เชื่อมต่อ LED Bar 10 digit เข้ากับพอร์ตดิจิตอลตามวงจร
-เขียนโปรแกรมไฟวิ่งที่มีรูปแบบและเป็นระเบียบ (ไม่ใช่การติดดับแบบสุ่ม)
-โปรแกรมรายละเอียดพิเศษรายกลุ่ม (แจ้งให้ทราบเมื่อถึงชั่วโมงเรียน)

ผังขาต่อใช้งานของ Arduino Nano 


วงจรที่ใช้ในการทดลองสำหรับผู้ที่ใช้บอร์ด Arduino


วงจรที่ใช้ในการทดลองสำหรับผู้ที่ใช้ไอซี ATmega328 (ที่มี Boot Loader Arduino)


บริเวณใช้งานบอร์ดทดลอง


ตัวอย่างที่ 1

โค๊ด: [Select]
byte x;
byte LED_pin[] = {2,3,4,5,6,7,8,9,10,11 };
 
void setup()  
{                
  for (x=0; x<=10; x++)
  {
      pinMode(LED_pin[x], OUTPUT);
  }
}
void loop()                     
{
  for (x=0; x<=10; x++)
  {
    digitalWrite(LED_pin[x],HIGH);
  } 
  delay(1000);
  for (x=0; x<=10; x++)
  {
    digitalWrite(LED_pin[x],LOW);
  } 
  delay(1000);
}

ตัวอย่างที่ 2
สเต็ปการติดดับของ LED ที่ต่อไว้ที่ขาดิจิตอลที่กำหนดในแต่ละจังหวะเวลา

โค๊ด: [Select]
void setup()  
{                
  pinMode(2,OUTPUT);pinMode(3,OUTPUT);pinMode(4,OUTPUT);pinMode(5,OUTPUT);pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);pinMode(8,OUTPUT);pinMode(9,OUTPUT);pinMode(10,OUTPUT);pinMode(11,OUTPUT);  
}
void loop()                     
{
digitalWrite(2,LOW);digitalWrite(3,LOW);digitalWrite(4,LOW);digitalWrite(5,LOW);digitalWrite(6,LOW);
digitalWrite(7,LOW);digitalWrite(8,LOW);digitalWrite(9,LOW);digitalWrite(10,LOW);digitalWrite(11,LOW);  
delay(100); 
digitalWrite(2,HIGH);digitalWrite(3,LOW);digitalWrite(4,LOW);digitalWrite(5,LOW);digitalWrite(6,LOW);
digitalWrite(7,LOW);digitalWrite(8,LOW);digitalWrite(9,LOW);digitalWrite(10,LOW);digitalWrite(11,HIGH);  
delay(100); 
digitalWrite(2,HIGH);digitalWrite(3,HIGH);digitalWrite(4,LOW);digitalWrite(5,LOW);digitalWrite(6,LOW);
digitalWrite(7,LOW);digitalWrite(8,LOW);digitalWrite(9,LOW);digitalWrite(10,HIGH);digitalWrite(11,HIGH);  
delay(100);
digitalWrite(2,LOW);digitalWrite(3,HIGH);digitalWrite(4,HIGH);digitalWrite(5,LOW);digitalWrite(6,LOW);
digitalWrite(7,LOW);digitalWrite(8,LOW);digitalWrite(9,HIGH);digitalWrite(10,HIGH);digitalWrite(11,LOW);  
delay(100);
digitalWrite(2,LOW);digitalWrite(3,LOW);digitalWrite(4,HIGH);digitalWrite(5,HIGH);digitalWrite(6,LOW);
digitalWrite(7,LOW);digitalWrite(8,HIGH);digitalWrite(9,HIGH);digitalWrite(10,LOW);digitalWrite(11,LOW);  
delay(100); 
digitalWrite(2,LOW);digitalWrite(3,LOW);digitalWrite(4,LOW);digitalWrite(5,HIGH);digitalWrite(6,HIGH);
digitalWrite(7,HIGH);digitalWrite(8,HIGH);digitalWrite(9,LOW);digitalWrite(10,LOW);digitalWrite(11,LOW);  
delay(100);  
digitalWrite(2,LOW);digitalWrite(3,LOW);digitalWrite(4,LOW);digitalWrite(5,LOW);digitalWrite(6,HIGH);
digitalWrite(7,HIGH);digitalWrite(8,LOW);digitalWrite(9,LOW);digitalWrite(10,LOW);digitalWrite(11,LOW);  
delay(100);   
}

ตัวอย่างฟังก์ชั่นการส่งค่าออกพอร์ตโดยการคำนวณค่า

โค๊ด: [Select]
char LED_pin[] = {2,3,4,5,6,7,8,9,10,11 };
...
...
void send2port(int data)
{
    if (data & 1 ){digitalWrite(LED_pin[0],HIGH);} else {digitalWrite(LED_pin[0],LOW);}
    if (data & 2 ){digitalWrite(LED_pin[1],HIGH);} else {digitalWrite(LED_pin[1],LOW);}
    if (data & 4 ){digitalWrite(LED_pin[2],HIGH);} else {digitalWrite(LED_pin[2],LOW);}
    if (data & 8 ){digitalWrite(LED_pin[3],HIGH);} else {digitalWrite(LED_pin[3],LOW);}
    if (data & 16 ){digitalWrite(LED_pin[4],HIGH);} else {digitalWrite(LED_pin[4],LOW);}
    if (data & 32 ){digitalWrite(LED_pin[5],HIGH);} else {digitalWrite(LED_pin[5],LOW);}
    if (data & 64 ){digitalWrite(LED_pin[6],HIGH);} else {digitalWrite(LED_pin[6],LOW);}
    if (data & 128 ){digitalWrite(LED_pin[7],HIGH);} else {digitalWrite(LED_pin[7],LOW);}
    if (data & 256 ){digitalWrite(LED_pin[8],HIGH);} else {digitalWrite(LED_pin[8],LOW);}
    if (data & 512 ){digitalWrite(LED_pin[9],HIGH);} else {digitalWrite(LED_pin[9],LOW);}
}
Example

Arduino LED กระพริบ

Arduino LED กระพริบ
           ไฟ LED ที่มีขนาดเล็ก, ไฟที่มีประสิทธิภาพที่จะใช้ในการใช้งานที่แตกต่างกัน ในการเริ่มต้นที่เราจะทำงานในกระพริบไฟ LED, สวัสดีโลกของไมโครคอนโทรลเลอร์ มันเป็นเรื่องง่ายเหมือนการเปิดไฟและปิด สร้างพื้นฐานที่สำคัญนี้จะทำให้คุณมีรากฐานที่มั่นคงในขณะที่เราทำงานต่อการทดลองที่มีความซับซ้อนมากขึ้น

ส่วนประกอบที่จำเป็น
คุณจะต้ององค์ประกอบต่อไปนี้

          1 × เขียงหั่นขนม
          1 ×  Arduino Uno R3
          1 ×  LED
          1 × 330Ωต้านทาน
          2 × จัมเปอร์

ขั้นตอน
ทำตามแผนภาพวงจรและขอขึ้นส่วนประกอบในชนบทตามที่แสดงในภาพด้านล่าง


หมายเหตุ - เพื่อหาขั้วของไฟ LED ที่มองมันอย่างใกล้ชิด ที่สั้นกว่าของทั้งสองขาต่อขอบแบนของหลอดไฟบ่งชี้ขั้วลบ


          ส่วนประกอบเช่นตัวต้านทานจะต้องมีขั้วของพวกเขาก้มลงไปใน 90 °มุมเพื่อให้พอดีกับซ็อกเก็ตชนบทได้อย่างถูกต้อง นอกจากนี้คุณยังสามารถตัดขั้วสั้น


ร่าง
          เปิดซอฟต์แวร์ Arduino IDE บนคอมพิวเตอร์ของคุณ การเขียนโปรแกรมในภาษา Arduino จะควบคุมวงจรของคุณ เปิดแฟ้มร่างใหม่โดยคลิกที่ใหม่


รหัส Arduino
-------------------------------------------------------------------------------------------------------------------------
/*
   Blink
   Turns on an LED on for one second, then off for one second, repeatedly.
*/

// the setup function runs once when you press reset or power the board

void setup() {  // initialize digital pin 13 as an output.
   pinMode(2, OUTPUT);
}

// the loop function runs over and over again forever

void loop() {
   digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
   delay(1000); // wait for a second
   digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
   delay(1000); // wait for a second
}
-------------------------------------------------------------------------------------------------------------------------
รหัสหมายเหตุ
          pinMode (2 เอาท์พุท) - ก่อนที่คุณสามารถใช้หนึ่งหมุด Arduino ของคุณจะต้องบอก Arduino Uno R3 ไม่ว่าจะเป็น input หรือ output เราใช้ในตัว "ฟังก์ชั่น" ที่เรียกว่า pinMode () เพื่อทำเช่นนี้ 
digitalWrite (2, สูง) - เมื่อคุณกำลังใช้เข็มเป็นออกคุณสามารถสั่งมันจะสูง (output 5 โวลต์) หรือต่ำ (output 0 โวลต์)

ผล
          คุณควรจะเห็นการเปิดไฟ LED ของคุณในและนอก ถ้าผลลัพธ์ที่ต้องการจะมองไม่เห็นให้แน่ใจว่าคุณได้รวบรวมวงจรอย่างถูกต้องและการตรวจสอบและอัปโหลดรหัสเพื่อบอร์ดของคุณ

Fan Module for Arduino

Fan Module for Arduino (Keyes L9110)


Fan Module for Arduino (Keyes L9110)


    โมดูลพัดลมที่ทาง Arduitronics.com เอามาจำหน่ายตัวนี้เหมาะสำหรับการทดลองศึกษาเรื่องการใช้งาน DC motor นะครับ  สามารถควบคุมความเร็ว และทิศทางการหมุนได้จาก Sketch ที่เขียนใน Arduino ครับ

Specification

  • ขนาดของบอร์ด  50x26x15 mm
  • ขนาดใบพัด 75 mm
  • แรงดันทำงาน 5 โวลต์
  • ใช้ IC L9110 เป็นตัวขับมอเตอร์

Specifications
  • Product size: 50*26*15mm (not including the propeller)
  • The propeller diameter: 75mm
  • Working voltage: 5V
// wired connections
#define HG7881_B_IA 10 // D10 --> Motor B Input A --> MOTOR B +
#define HG7881_B_IB 11 // D11 --> Motor B Input B --> MOTOR B -

// functional connections
#define MOTOR_B_PWM HG7881_B_IA // Motor B PWM Speed
#define MOTOR_B_DIR HG7881_B_IB // Motor B Direction

// the actual values for "fast" and "slow" depend on the motor
#define PWM_SLOW 50  // arbitrary slow speed PWM duty cycle
#define PWM_FAST 200 // arbitrary fast speed PWM duty cycle
#define DIR_DELAY 1000 // brief delay for abrupt motor changes

void setup()
{
  Serial.begin( 9600 );
  pinMode( MOTOR_B_DIR, OUTPUT );
  pinMode( MOTOR_B_PWM, OUTPUT );
  digitalWrite( MOTOR_B_DIR, LOW );
  digitalWrite( MOTOR_B_PWM, LOW );
}

void loop()
{
  boolean isValidInput;
  // draw a menu on the serial port
  Serial.println( "-----------------------------" );
  Serial.println( "MENU:" );
  Serial.println( "1) Fast forward" );
  Serial.println( "2) Forward" );
  Serial.println( "3) Soft stop (coast)" );
  Serial.println( "4) Reverse" );
  Serial.println( "5) Fast reverse" );
  Serial.println( "6) Hard stop (brake)" );
  Serial.println( "-----------------------------" );
  do
  {
    byte c;
    // get the next character from the serial port
    Serial.print( "?" );
    while( !Serial.available() )
      ; // LOOP...
    c = Serial.read();
    // execute the menu option based on the character recieved
    switch( c )
    {
      case '1': // 1) Fast forward
        Serial.println( "Fast forward..." );
        // always stop motors briefly before abrupt changes
        digitalWrite( MOTOR_B_DIR, LOW );
        digitalWrite( MOTOR_B_PWM, LOW );
        delay( DIR_DELAY );
        // set the motor speed and direction
        digitalWrite( MOTOR_B_DIR, HIGH ); // direction = forward
        analogWrite( MOTOR_B_PWM, 255-PWM_FAST ); // PWM speed = fast
        isValidInput = true;
        break;      
         
      case '2': // 2) Forward      
        Serial.println( "Forward..." );
        // always stop motors briefly before abrupt changes
        digitalWrite( MOTOR_B_DIR, LOW );
        digitalWrite( MOTOR_B_PWM, LOW );
        delay( DIR_DELAY );
        // set the motor speed and direction
        digitalWrite( MOTOR_B_DIR, HIGH ); // direction = forward
        analogWrite( MOTOR_B_PWM, 255-PWM_SLOW ); // PWM speed = slow
        isValidInput = true;
        break;      
         
      case '3': // 3) Soft stop (preferred)
        Serial.println( "Soft stop (coast)..." );
        digitalWrite( MOTOR_B_DIR, LOW );
        digitalWrite( MOTOR_B_PWM, LOW );
        isValidInput = true;
        break;      

      case '4': // 4) Reverse
        Serial.println( "Fast forward..." );
        // always stop motors briefly before abrupt changes
        digitalWrite( MOTOR_B_DIR, LOW );
        digitalWrite( MOTOR_B_PWM, LOW );
        delay( DIR_DELAY );
        // set the motor speed and direction
        digitalWrite( MOTOR_B_DIR, LOW ); // direction = reverse
        analogWrite( MOTOR_B_PWM, PWM_SLOW ); // PWM speed = slow
        isValidInput = true;
        break;      
         
      case '5': // 5) Fast reverse
        Serial.println( "Fast forward..." );
        // always stop motors briefly before abrupt changes
        digitalWrite( MOTOR_B_DIR, LOW );
        digitalWrite( MOTOR_B_PWM, LOW );
        delay( DIR_DELAY );
        // set the motor speed and direction
        digitalWrite( MOTOR_B_DIR, LOW ); // direction = reverse      
        analogWrite( MOTOR_B_PWM, PWM_FAST ); // PWM speed = fast
        isValidInput = true;
        break;
         
      case '6': // 6) Hard stop (use with caution)
        Serial.println( "Hard stop (brake)..." );
        digitalWrite( MOTOR_B_DIR, HIGH );
        digitalWrite( MOTOR_B_PWM, HIGH );
        isValidInput = true;
        break;      
         
      default:
        // wrong character! display the menu again!
        isValidInput = false;
        break;
    }
  } while( isValidInput == true );

  // repeat the main loop and redraw the menu...
}

 

โมดูลนาฬิกา

Arduino DS3231 + AT24C32 โมดูลนาฬิกา ใช้ได้ใน 3 นาที

Arduino DS3231 + AT24C32 โมดูลนาฬิกา ใช้ได้ใน นาที



ต่อวงจรจากบอร์ด DS3231 -> Arduino Uno ตามนี้
  • GND >> GND
  • VCC>> +5V
  • SDA>> A4
  • SCL>>A5
โคด
// Date, Time and Alarm functions using a DS3231 RTC connected via I2C and Wire lib

#include "Wire.h"
#include "SPI.h"  // not used here, but needed to prevent a RTClib compile error
#include "RTClib.h"

RTC_DS3231 RTC;

void setup () {

  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  DateTime now = RTC.now();
  /* ตั้งเวลา ในตัวอย่างนี้ เซตค่าเป็นเวลา 23:09 ถ้าถึงเวลานี้จะให้ทำงานที่ฟังก์ชัน
    RTC.setAlarm1Simple(23, 9);
   if (RTC.checkIfAlarm(1)) {
   Serial.println("Alarm Triggered");
   }*/
  RTC.setAlarm1Simple(23, 9);

  RTC.turnOnAlarm(1);

  if (RTC.checkAlarmEnabled(1)) {
    Serial.println("Alarm Enabled");
  }

}

void loop () {

  DateTime now = RTC.now();
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);

  if (RTC.checkIfAlarm(1)) {
    Serial.println("Alarm Triggered");
  }

  Serial.println();
  Serial.print("Tempeature = ");
  Serial.print(RTC.getTemperature()); // คำสั่งดึงอุณหภูมิออกมาแสดง
  Serial.println(" C");

  Serial.println("By ArduinoALL");
  Serial.println();
  delay(1000);
}

โคดตัวอย่างนี้จะเป็นการตั้งค่าให้กับ RTC ถ้าเซคค่าแล้วให้เอา RTC.adjust(DateTime(__DATE__, __TIME__)); ออก แล้วอัพโหลดโคดใหม่ เพราะคำสั่งนี้จะตั้งค่าเวลาใหม่ทุกครั้งที่รันโปรแกรม
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
   //เมื่อตั้งเวลาแล้ว ใส่หมายเหตุคำสั่งตั้งเวลาไว้ แล้วอัพโหลดโคดใหม่ เวลาจะได้ถูกต้อง โคดตรงนี้

  //RTC.adjust(DateTime(__DATE__, __TIME__));

RC Servo Motor

01
RC Servo Motor รุ่นที่มีจำหน่าย:
          Servo เป็นคำศัพท์ที่ใช้กันทั่วไปในระบบควบคุมอัตโนมัติ มาจากภาษาละตินคำว่า Sevus หมายถึง “ทาส” (Slave) ในเชิงความหมายของ Servo Motor ก็คือ Motor ที่เราสามารถสั่งงานหรือตั้งค่า แล้วตัว Motor จะหมุนไปยังตำแหน่งองศาที่เราสั่งได้เองอย่างถูกต้อง โดยใช้การควบคุมแบบป้อนกลับ (Feedback Control) ในบทความนี้จะกล่าวถึง RC Servo Motor ซึ่งนิยมนำมาใช้ในเครื่องเล่นที่บังคับด้วยคลื่นวิทยุ (RC = Radio - Controlled) เช่น เรือบังคับวิทยุ รถบังคับวิทยุ เฮลิคอปเตอร์บังคับวิทยุ เป็นต้น
          Feedback Control คือ ระบบควบคุมที่มีการวัดค่าเอาต์พุตของระบบนำมาเปรียบเทียบกับค่าอินพุตเพื่อควบคุมและปรับแต่งให้ค่าเอาต์พุตของระบบให้มีค่า เท่ากับ หรือ ใกล้เคียงกับค่าอินพุต 
ส่วนประกอบภายนอก RC Servo Motor
02
- Case ตัวถัง หรือ กรอบของตัว Servo Motor
- Mounting Tab ส่วนจับยึดตัว Servo กับชิ้นงาน
- Output Shaft เพลาส่งกำลัง
- Servo Horns ส่วนเชื่อมต่อกับ Output shaft เพื่อสร้างกลไกล
- Cable สายเชื่อมต่อเพื่อ จ่ายไฟฟ้า และ ควบคุม Servo Motor จะประกอบด้วยสายไฟ 3 เส้น และ ใน RC Servo Motor จะมีสีของสายแตกต่างกันไปดังนี้ 
         o สายสีแดง คือ ไฟเลี้ยง (4.8-6V)
         o สายสีดำ หรือ น้ำตาล คือ กราวด์
         o สายสีเหลือง (ส้ม ขาว หรือฟ้า) คือ สายส่งสัญญาณพัลซ์ควบคุม (3-5V) 
- Connector จุดเชื่อมต่อสายไฟ 
ส่วนประกอบภายใน RC Servo Motor
03Ref: www.pololu.com
1. Motor เป็นส่วนของตัวมอเตอร์
2. Gear Train หรือ Gearbox เป็นชุดเกียร์ทดแรง
3. Position Sensor เป็นเซ็นเซอร์ตรวจจับตำแหน่งเพื่อหาค่าองศาในการหมุน
4. Electronic Control System เป็นส่วนที่ควบคุมและประมวลผล 
Servo Motor Block Diagram
04
หลักการทำงานของ RC Servo Motor 
             เมื่อจ่ายสัญญาณพัลซ์เข้ามายัง RC Servo Motor ส่วนวงจรควบคุม (Electronic Control System) ภายใน Servo จะทำการอ่านและประมวลผลค่าความกว้างของสัญญาณพัลซ์ที่ส่งเข้ามาเพื่อแปลค่าเป็นตำแหน่งองศาที่ต้องการให้ Motor หมุนเคลื่อนที่ไปยังตำแหน่งนั้น แล้วส่งคำสั่งไปทำการควบคุมให้ Motor หมุนไปยังตำแหน่งที่ต้องการ โดยมี Position Sensor เป็นตัวเซ็นเซอร์คอยวัดค่ามุมที่ Motor กำลังหมุน เป็น Feedback กลับมาให้วงจรควบคุมเปรียบเทียบกับค่าอินพุตเพื่อควบคุมให้ได้ตำแหน่งที่ต้องการอย่างถูกต้องแม่นยำ
สัญญาณ RC ในรูปแบบ PWM
            ตัว RC Servo Motor ออกแบบมาใช้สำหรับรับคำสั่งจาก Remote Control ที่ใช้ควบคุมของเล่นด้วยสัญญาณวิทยุต่างๆ เช่น เครื่องบินบังคับ รถบังบังคับ เรือบังคับ เป็นต้น ซึ่ง Remote จำพวกนี้ที่ภาครับจะแปลงความถี่วิทยุออกมาในรูปแบบสัญญาณ PWM (Pulse Width Modulation)
05           มุมหรือองศาจะขึ้นอยู่กับความกว้างของสัญญาณพัลซ์ ซึ่งโดยส่วนมากความกว้างของพัลซ์ที่ใช้ใน RC Servo Motor จะอยู่ในช่วง 1-2 ms หรือ 0.5-2.5 ms 
           ยกตัวอย่างเช่นหากกำหนดความกว้างของสัญญาณพัลซ์ไว้ที่ 1 ms ตัว Servo Motor จะหมุนไปทางด้ายซ้ายจนสุด ในทางกลับกันหากกำหนดความกว้างของสัญญาณพัลซ์ไว้ที่ 2 ms ตัว Servo Motor จะหมุนไปยังตำแหน่งขวาสุด แต่หากกำหนดความกว้างของสัญญาณพัลซ์ไว้ที่ 1.5 ms ตัว Servo Motor ก็จะหมุนมาอยู่ที่ตำแหน่งตรงกลางพอดี
06
           ดังนั้นสามารถกำหนดองศาการหมุนของ RC Servo Motor ได้โดยการเทียบค่า เช่น RC Servo Motor สามารถหมุนได้ 180 องศา โดยที่ 0 องศาใช้ความกว้างพัลซ์เท่ากับ 1000 us ที่ 180 องศาความกว้างพัลซ์เท่ากับ 2000 us เพราะฉะนั้นค่าที่เปลี่ยนไป 1 องศาจะใช้ความกว้างพัลซ์ต่างกัน (2000-1000)/180 เท่ากับ 5.55 us
           จากการหาค่าความกว้างพัลซ์ที่มุม 1 องศาข้างต้น หากต้องกำหนดให้ RC Servo Motor หมุนไปที่มุม 45 องศาจะหาค่าพัลซ์ที่ต้องการได้จาก 5.55 x 45 เท่ากับ 249.75 us แต่ที่มุม 0 องศาเราเริ่มที่ความกว้างพัลซ์ 1ms หรือ 1000 us เพราะฉะนั้นความกว้างพัลซ์ที่ใช้กำหนดให้ RC Servo Motor หมุนไปที่ 45 องศา คือ 1000 + 249.75 เท่ากับประมาณ 1250 us
07
วิธีควบคุม RC Servo Motor ด้วย Arduino
            Arduino มีไลบรารี่สำหรับสั่งงาน RC Servo Motor มาให้ใช้งานอยู่แล้วเป็นฟังก์ชั่นสำเร็จรูปและใช้งานได้ง่าย ในหน้าเว็บไซต์ http://arduino.cc/en/reference/servo ได้ให้ข้อมูลไว้ว่า Servo Library ของ Arduino สามารถสั่งงาน RC Servo Motor ได้ทั้งแบบหมุนไป-กลับได้ 0-180 องศา (ที่กล่าวถึงตามตัวอย่างข้างต้น) และแบบต่อเนื่องที่หมุนครบรอบได้เรียกว่าเป็น Continuous Rotation Servo (ซึ่งในช่วงท้ายบทความจะกล่าวถึงเพิ่มเติม) โดยสามารถรองรับการเชื่อมต่อ RC Servo Motor ได้ถึง 12 ตัวกับบอร์ด Arduino UNO และรองรับสูงสุดถึง 48 ตัวหากใช้บอร์ด Arduino Mega 
ฟังก์ชั่นภายใน Servo Library
- attach()
- write()
- writeMicroseconds()
- read()
- attached()
- detach()
attach()
Description
          คือฟังก์ชั่นที่ใช้ในการกำหนดขาสัญญาณที่ Servo Motor ต่อกับ Arduino และกำหนดความกว้างของพัลซ์ที่ 0 องศาและ 180 องศา 
Syntax
          Servo.attach(pin)
          Servo.attach(pin,min,max)
Parameters
          Pin: คือ ขาสัญญาณของ Arduino ที่ใช้เชื่อมต่อกับ Servo Motor
          Min: คือ ความกว้างของพัลซ์ที่ 0 องศาของ Servo ตัวที่ใช้ในหน่วยไมโครวินาที (us) โดยปกติแล้วหากไม่มีการตั้งค่าโปรแกรมจะกำหนดค่าไว้ที่ 544 us
          Max: คือ ความกว้างของพัลซ์ที่ 180 องศาของ Servo ตัวที่ใช้ในหน่วยไมโครวินาที (us) โดยปกติแล้วหากไม่มีการตั้งค่าโปรแกรมจะกำหนดค่าไว้ที่ 2400 us
Write()
Description
          คือฟังก์ชั่นที่ใช้ควบคุมตำแหน่งที่ต้องการให้ Servo Motor หมุนไปยังองศาที่กำหนดสามารถกำหนดเป็นค่าองศาได้เลย คือ 0-180 องศา แต่ใน Servo Motor ที่เป็น Full Rotation คำสั่ง write จะเป็นการกำหนดความเร็วในการหมุน โดย 
          ค่าเท่ากับ 90 คือคำสั่งให้ Servo Motor หยุดหมุน
          ค่าเท่ากับ 0 คือการหมุนด้วยความเร็วสูงสุดในทิศทางหนึ่ง
          ค่าเท่ากับ 180 คือการหมุนด้วยความเร็วสูงสุดในทิศทางตรงกันข้าม
Syntax
          servo.write(angle)
Parameters
          Angle: คือมุมที่ต้องการให้ RC Servo Motor แบบ 0-180 องศาหมุนไป แต่หากเป็น RC Servo Motor แบบ Full Rotation ค่า Angle คือ การกำหนดความเร็วและทิศทางในการหมุน
writeMicroseconds()
Description
          คือฟังก์ชั่นที่ใช้ควบคุมตำแหน่งที่ให้ Servo Motor หมุนไปยังตำแหน่งองศาที่กำหนดโดยกำหนดเป็นค่าความกว้างของพัลซ์ในหน่วย us ซึ่งปกติแล้ว RC Servo Motor จะใช้ความกว้างของพัลซ์อยู่ที่ 1000-2000 us ตามที่ได้กล่าวไปข้างต้นแล้ว แต่ RC Servo Motor บางรุ่นหรือบางยี่ห้อไม่ได้ใช้ ช่วงความกว้างของพัลซ์ตามที่ได้กล่าวเอาไว้นี้ อาจจะใช้ช่วง 700-2300 แทนก็สามารถใช้ฟังก์ชั่น writeMicroseconds นี้เพื่อกำหนดความกว้างพัลซ์ได้เอง
          การใช้ฟังก์ชั่น writeMicroseconds สามารถกำหนดค่าได้อิสระ ตรงนี้ ”ต้องระวังในการใช้งาน” หากสั่งงาน RC Servo Motor (แบบ 0 - 180 องศา) จนหมุนไปเกินจุดสิ้นสุดคือเกินทั้งฝั่ง 0 หรือ 180 องศา จะทำให้เกิดเสียงครางดังจากการหมุนไปต่อไม่ได้และมอเตอร์จะกินกระแสสูงขึ้นด้วยในเวลาเดียวกันนั้น ซึ่งอาจทำให้ RC Servo Motor เกิดความเสียหายได้
Syntax
          servo.writeMicroseconds(uS)
Parameters
          uS: คือค่าความกว้างของพัลซ์ที่ต้องการกำหนดในหน่วยไมโครวินาที (โดยตัวแปร int)
read()
Description
          คือฟังก์ชั่นอ่านค่าองศาที่สั่งเข้าไปด้วยฟังก์ชั่น write() เพื่อให้รู้ว่าตำแหน่งองศาสุดท้ายที่เราสั่งเข้าไปนั้นมีค่าเท่าไหร่ซึ่งค่าที่อ่านออกมานั้นจะมีค่าอยู่ในช่วง 0 - 180 
Syntax
          servo.read()
Parameters
          ไม่มี: จะ Return ค่า 0-180
attached()
Description
           คือฟังก์ชั่นตรวจสอบว่า Servo ที่เราต้องการใช้กำลังต่ออยู่กับขสัญญาณของ Arduino หรือไม่
Syntax
           servo.attached()
Parameters
           ไม่มี: จะ Return ค่า True ออกมา หาก Servo Motor เชื่อมต่ออยู่กับ Arduino แต่ถ้าหาก Return ออกมาเป็นค่าอื่นถือว่าไม่เชื่อมต่อ
detach()
Description
           คือฟังก์ชั่นคืนสถานะของขาที่เรากำหนดให้เป็นขาควบคุม Servo Motor ด้วยคำสั่ง attached() ให้กลับคือสู่การใช่งานปกติ
Syntax
           servo.detach()
Parameters
           ไม่มี
ตัวอย่างการเชื่อมต่อ RC Servo Motor เข้ากับบอร์ด Arduino
08
อุปกรณ์ RC Servo Motor ที่ใช้ในบทความ :  EFDV245 Futaba S3003 Servo Motor
โค้ดตัวอย่างการควบคุมตำแหน่ง RC Servo Motor
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Servo.h>
Servo myservo;  
void setup()
{
  myservo.attach(9);
}
void loop()
{       myservo.write(0);
        delay(1000);     
        myservo.write(90);
        delay(1000);     
        myservo.write(180);
        delay(1000);                    
}

ผลการทำงานของโค้ด

09
myservo.write(0); 
delay(1000);
Servo Motor จะหมุนไปที่ตำแหน่ง 0 องศา และ หยุดเป็นเวลา 1 วินาที 
10
myservo.write(90); 
delay(1000);
Servo Motor จะหมุนไปที่ตำแหน่ง 90 องศา และ หยุดเป็นเวลา 1 วินาที
11
myservo.write(90); 
delay(1000);
Servo Motor จะหมุนไปที่ตำแหน่ง 180 องศา และ หยุดเป็นเวลา 1 วินาที
จากนั้นจะหมุนกลับไปที่ตำแหน่ง 0 องศา และวนรอบไปเช่นนี้เรื่อยๆ
โค้ดตัวอย่างการควบคุมตำแหน่ง RC Servo Motor แบบ Sweep
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <Servo.h>
Servo myservo;        //create servo object to control a servo
                              // a maximum of eight servo objects can be created
int pos = 0;             // variable to store the servo position
void setup(){
       myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop(){
       for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
      {
            myservo.write(pos); // tell servo to go to position in variable 'pos'
            delay(15); // waits 15ms for the servo to reach the position
       }
       for(pos = 180; pos>=1; pos-=1)// goes from 180 degrees to 0 degrees
      {
            myservo.write(pos); // tell servo to go to position in variable 'pos'
           delay(15); // waits 15ms for the servo to reach the position
      }
}
ผลการทำงานของโค้ด
for(pos = 0; pos < 180; pos += 1){
myservo.write(pos);
delay(15);
}
            ลูป for กำหนดให้ค่า pos มีค่าเท่ากับ 0 และทุกๆ การทำงานคำสั่งภายใน for loop ค่า pos จะเพิ่มค่าขึ้น 1 ค่า จนจนถึง 180 ก็จะหลุดออกจาก loop
           ภายใน loop for คำสั่ง myservo.write(pos); ก็คือการกำหนดให้ Servo Motor หมุนไปยังตำแหน่ง มุมตามค่าในตัวแปร pos และหน่วงเวลา 15ms ด้วยคำสั่ง delay(15); ดังนั้น Servo Motor จะค่อยๆ หมุนอย่างช้าๆ จากตำแหน่ง 0 องศาไปที่ 180 องศา
for(pos = 180; pos>=1; pos-=1) 

myservo.write(pos);
delay(15); 
}
           ใน loop for ที่สองนี้จะทำงานเช่นเดียวกับใน loop for แรกเพียงแต่เปลี่ยนค่าเริ่มต้นจาก 180 เป็น 0 และลดลงค่าลง 1 ค่าทุกๆ การทำงาน 1 รอบ ส่งผลให้ Servo Motor จะหมุนจากตำแหน่งมุม 180 องศา ไปยังมุม 0 องศาอย่างช้าๆ 
           !!! ทดลองเพิ่มค่าในคำสั่ง delay() ให้มากขึ้นจะพบว่า Servo Motor จะหมุนช้าลงและในทางกลับกันหากลดค่าใน delay() ลงจะพบว่า Servo Motor จะหมุนเร็วขึ้น
ตัวอย่างการควบคุมตำแหน่ง RC Servo Motor โดยใช้ Potentiometer
13
โค้ดตัวอย่างการควบคุมตำแหน่ง RC Servo Motor โดยใช้ Potentiometer
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
  
void setup(){
         myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop(){
         val = analogRead(potpin); // reads the value of the potentiometer (value // between 0 and 1023)
         val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value
                                                        // between 0 and 180)
         myservo.write(val); // sets the servo position according to the
                                      // scaled value
         delay(15); // waits for the servo to get there
}
ผลการทำงานของโค้ด
val = analogRead(potpin); 
           อ่านค่า Analog จาก Potentiometer ที่ต่ออยู่ที่ขา A0 เก็บไว้ในตัวแปร val
val = map(val, 0, 1023, 0, 179);
           เนื่องจาก ADC ภายใน Arduino เป็น ADC ขนาด 10-bit จึงอ่านค่า Analog ได้ตั้งแต่ 0 – 1023 แต่ RC Servo Motor สามารถหมุนได้เพียงแค่ 1-180 องศา จึงต้องใช้ Function map เพื่อทำการสเกลค่าลงจาก 0-1023 เป็น 0-179 แล้วนำไปเก็บไว้ในตัวแปร val 
myservo.write(val);
           เมื่อสเกลค่า จาก 0-1023 ลงเหลือ 0-179 แล้วก็นำมาสั่งให้ Servo Motor หมุนไปยังตำแหน่งในค่าตัวแปร val
delay(15); 
           หน่วงเวลา 15 ms
ผลของการทำงานทำให้สามารถปรับตำแหน่งองศาของ Servo Motor ได้โดยการหมุนปรับค่า Potentiometer
Continuous Rotation Servo
14
           Continuous Rotation Servo คือ RC Servo Motor แบบที่สามารถหมุนได้ 360 องศา ส่วนประกอบภายนอกนั้นจะมีหน้าตาคล้ายกับ RC Servo Motor แบบที่หมุนได้ 180 องศา เพียงแต่จะมี Potentiometer เพื่อใช้สำหรับปรับ ตำแหน่ง Center Stop Adjust ของตัว Servo 
           ลักษณะการใช้งาน RC Servo Motor ชนิดนี้จะแตกต่างจากการใช้งาน RC Servo Motor แบบ 180 องศาตรงที่ Servo ชนิดนี้จะใช้ความกว้างของสัญญาณพัลซ์ในการกำหนดความเร็วและทิศทางในการหมุน ไม่ได้ใช้เพื่อกำหนดมุมจึงไม่สามารถกำหนดให้ Motor หมุนไปยังตำแหน่งมุมต่างๆ ตามความต้องการได้ สัญญาณความกว้างของพัลซ์ที่ใช้ควบคุมจะอยู่ในช่วง 1000-2000 us แต่จะมีความแตกในความหมายของแต่ละความกว้างของพัลซ์ดังนี้
           ความกว้าง 1000 us หมายถึงการหมุนไปทางซ้ายด้วยความเร็วสูงสุดที่ Servo Motor จะหมุนได้ 
15
            ความกว้าง 1500 us หมายถึงการสั่งให้ Servo Motor หยุดหมุน
16
            ความกว้าง 2000 us หมายถึงการหมุนไปทางขวาด้วยความเร็วสูงสุดที่ Servo Motor จะหมุนได้
17
การ Calibrate Center Stop
            ในการใช้งาน Continuous Rotation Servo เมื่อซื้อมาใหม่หรือใช้งานไปสักระยะหนึ่งจุด Center Stop อาจมีการคลาดเคลื่อนได้ ซึ่งแม้เราสั่งให้สัญญาณพัลซ์มีความกว้างเท่ากับ 1500 us ไป Continuous rotation servo ก็จะไม่หยุดหมุน เราจึงต้องปรับตั้งค่า Center Stop ดังนี้ 
- ต่อ Continuous rotation servo เข้ากับ Arduino
18
- เขียนโปรแกรมจ่ายความกว้างพัลซ์ 1500 us ให้กับ Servo Motor
#include <Servo.h>
Servo myServo;
void setup() {
          myServo.attach(9);
          myServo.writeMicroseconds(1500); // Stop 
}
- เมื่อรันโปรแกรมจ่ายความกว้างพัลซ์ 1500 us แล้ว Servo Motor ไม่หยุดหมุน ให้ใช้ไขควงขนาดเล็กหมุนปรับ Center Stop Adjust จน Servo Motor หยุดหมุน

19
การควบคุม Continuous Rotation Servo โดยใช้ Potentiometer ปรับความเร็วและทิศทางการหมุน
20
โค้ดตัวอย่างการควบคุม Continuous Rotation Servo โดยใช้ Potentiometer
?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
void setup(){
          myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop(){
          val = analogRead(potpin); // reads the value of the potentiometer (value // between 0 and 1023)
          val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value // between 0 and 180)
          myservo.write(val); // sets the servo position according to the scaled value
          delay(15); // waits for the servo to get there
}
!!! โค้ดเหมือนกับตัวอย่าง RC Servo Motor โดยใช้ Potentiometer แต่ผลการทำงานจะแตกต่างกัน
ผลการทำงานของ Code
val = analogRead(potpin); 
          อ่านค่า Analog จาก Potentiometer ที่ต่ออยู่ที่ขา A0 เก็บไว้ในตัวแปร val
val = map(val, 0, 1023, 0, 179);
          เนื่องจาก ADC ภายใน Arduino เป็น ADC ขนาด 10-bit จึงอ่านค่า Analog ได้ตั้งแต่ 0-1023 แต่ Continuous Rotation Servo รับค่าได้ในช่วง 1-180 จึงต้องใช้ Function map เพื่อสเกลค่าจาก 0-1023 เป็น 0-179 แล้วนำไปเก็บไว้ในตัวแปร val
myservo.write(val);
          เมื่อสเกลค่า จาก 0-1023 ลงเหลือ 0-179 แล้วก็นำมาสั่งให้ Servo Motor หมุนในความเร็วและ ทิศทางตามค่าความกว้างของพัลซ์ที่จ่ายออกไป
delay(15); 
          หน่วงเวลา 15 ms
          ผลของการทำงานในโค้ดนี้จะเห็นได้ว่า หากปรับ Potentiometer ไปทางด้านใดด้านหนึ่งจนสุด Continuous Rotation Servo จะหมุนในทิศทางหนึ่งด้วยความเร็วสูงสุดและเมื่อเราค่อยๆ ปรับ Potentiometer กลับมาให้มาอยู่ในตำแหน่งกึ่งกลาง Servo Motor จะค่อยหมุนช้าลงแต่ยังหมุนในทิศทางเดิม และจะหยุดสนิทหากเราปรับ Potentiometer มาที่ตำแหน่งกึ่งกลางพอดี เมื่อปรับ Potentiometer เกินกว่า ครึ่งหนึ่งในทิศตรงกันข้าม Servo Motor จะเปลี่ยนทิศการหมุน แต่จะหมุนอย่างช้าๆ และจะค่อยๆหมุนเร็วขึ้นเมื่อเราปรับ Potentiometer มากขึ้น