POP-X2 Rover บทที่ 3 อุปกรณ์อินพุตเอาต์พุตบน POP-X2

การสร้างเสียงออกลำโพง

บอร์ด POP-X2 ติดตั้งลำโพงเปียโซขนาดเล็กไว้ด้านล่างของจอ GLCD โดยลำโพงเปียโซสามารถตอบสนองความถี่ย่าน 300 Hz ถึง 3000 Hz มีคำสั่งสำหรับขับเสียง 2 คำสั่ง ประกอบด้วย คำสั่ง beep() และ sound()

คำสั่ง beep()

ใช้สร้างเสียงออกลำโพงความถี่ 500 Hz ดังนาน 0.1 วินาที

ตัวอย่าง

สร้างเสียง 500 Hz นาน 0.1 วินาที หยุดเสียง 0.5 วินาทีอย่างต่อเนื่อง

 #include <popx2.h>
void setup() {}
void loop() {
  beep();
  delay(500);
}

 

คำสั่ง sound(freq,time)

ใช้สร้างเสียงออกลำโพง โดยระบุความถี่เสียง freq
และระยะเวลาให้เสียงดัง time
ได้

ตัวอย่าง

สร้างเสียงไซเรน ดัง 2 ความถี่สลับกันอย่างต่อเนื่อง

 #include <popx2.h>
void setup() {}
void loop() {
  sound(1500, 500);
  sound(2000, 500);
}

จากคำสั่ง sound เราสามารถกำหนดเป็นโน๊ตดนตรี แล้วเอามาต่อกันเพื่อเป็นเสียงเมโลดี้ได้

ตัวอย่าง เสียงเมโลดี้จากเกมส์ Mario

เนื่องจากโค้ดค่อนข้างยาว ขอแนบเป็นลิงก์เอาไว้เพื่อให้ไปคัดลอก และทดสอบผลดูครับ

https://pastebin.com/Ak5aLfi1

การรับค่าอินพุตจากสวิตช์

บนบอร์ด POP-X2 มีสวิตช์ให้เขียนติดต่อด้วย 2 ตัว คือ SW1 และ SW_OK โดยมีคำสั่งให้ใช้งานหลายคำสั่งดังนี้

คำสั่งรอจนกดสวิตช์

 

คำสั่งคืนค่าเงื่อนไข จริง/เท็จ (ใช้คู่กับคำสั่งตรวจสอบเงื่อนไข)

 

คำสั่ง OK()

ตัวอย่างที่ 2 การใช้งาน sw1_press() แบบที่ 1

 #include <popx2.h>
void setup() {
  sw1_press();
  beep();
}
void loop() {
}

เมื่อกดสวิตช์ sw1 แล้วจะมีเสียงออกลำโพง ตัวอย่างนี้เอาชุดคำสั่งไว้ที่ void setup() ทำให้การทำงานเกิดขึ้นแค่ครั้งเดียว

ตัวอย่างที่ 3 การใช้งาน sw1_press() แบบที่ 2

#include <popx2.h>
void setup() {
}
void loop() {
  sw1_press();
  beep();
}

เมื่อกดสวิตช์ sw1 จะมีเสียงออกลำโพง 1 ครั้ง สามารถกดซ้ำเพื่อให้เกิดเสียงใหม่ได้

ตัวอย่างที่ 4 การใช้งาน sw_OK_press()

 #include <popx2.h>
void setup() {
  setTextSize(2);  
  glcd(0,0,"Sw1 First");
}
void loop() {
  sw1_press();
  glcd(1,0,"SW1  ");
  beep();  
  sw_OK_press();
  glcd(1,0,"SW_OK");
  beep();
}

ตัวอย่างนี้จะต้องกดสวิตช์ตามลำดับ โดยเริ่มจากกดสวิตช์ SW1 ก่อนจึงจะสามารถกดสวิตช์ SW_OK ได้

คำสั่งตรวจสอบเงื่อนไข if-else

รูปแบบ

if (เงื่อนไข)    {

        คำสั่ง1 ทำเมื่อเงื่อนไขเป็นจริง;

        …

    }

    else    {

        คำสั่ง2 ทำเมื่อเงื่อนไขเป็นเท็จ;

        …

    }

เงื่อนไขในที่นี้ให้ผลลัพธ์ 2 อย่างคือจริงกับเท็จ อาจจะมาจากเปรียบเทียบ หรือมาจากตัวแปรที่เป็นชนิด Boolean อยู่แล้วก็ได้

ตัวอย่างที่ 5 ตรวจสอบการกดสวิตช์ sw_OK() ด้วยคำสั่ง if

 #include <popx2.h>
void setup() {
}
void loop() {
  if (sw_OK()) {
    glcdFillScreen(GLCD_RED);
  }
  else {
    glcdFillScreen(GLCD_BLACK);
  }
}

เมื่อไม่กดสวิตช์ OK หน้าจอ GLCD จะเป็นสีดำ เมื่อกดสวิตช์หน้าจอจะเปลี่ยนเป็นสีแดง

ข้อสังเกต

คำสั่ง if จะต้องอยู่ใน void loop() เนื่องจากการตรวจสอบ เราไม่ทราบว่าการกดสวิตช์เกิดขึ้นเมื่อใด จึงต้องวนคอยตรวจสอบค่าไปเรื่อยๆ

ตัวอย่างที่ 6 การใช้ && (AND)

เหตุการณ์ต้องเป็นจริงทั้งคู่จึงจะให้ผลลัพธ์เป็นจริง

 #include <popx2.h>
void setup() {}
void loop() {
  if (sw_OK() && sw1()) {
    glcdFillScreen(GLCD_RED);
  }
  else if (sw_OK()) {
    glcdFillScreen(GLCD_GREEN);
  }
  else if (sw1()) {
    glcdFillScreen(GLCD_BLUE);
  }
  else {
    glcdFillScreen(GLCD_BLACK);
  }
}
การทำงาน

เมื่อกดปุ่ม 2 ปุ่มพร้อมกัน หน้าจอ GLCD จะแสดงเป็นสีแดง

เมื่อกด sw_OK() ปุ่มเดียวจะแสดงเป็นสีเขียว

เมื่อกด sw1() ปุ่มเดียวจะแสดงเป็นสีน้ำเงิน

ถ้าไม่กดเลยจะเป็นสีดำ

ตัวแปร

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

boolean
ใช้เก็บสถานะลอจิก มีค่า 0 หรือ 1 กินหน่วยความจำ 1 บิต

char
ใช้เพื่อเก็บข้อมูลตัวอักษร ค่าอยู่ระหว่าง -128 ถึง 127 กินหน่วยความจำ 1 ไบต์

byte หรือ unsigned char
ใช้เพื่อเก็บข้อมูลระหว่าง 0 ถึง 255 กินหน่วยความจำ 1 ไบต์

int
ใช้เพื่อเก็บค่าตัวเลขจำนวนเต็ม ค่าอยู่ระหว่าง -32768 ถึง 32767 กินหน่วยความจำ 2 ไบต์

unsigned int
ใช้ตัวเลขจำนวนเต็มไม่คิดเครื่องหมายค่าอยู่ระหว่าง 0 ถึง 65535 กินหน่วยความจำ 2 ไบต์

long
ใช้เก็บเลขจำนวนเต็ม ค่าอยู่ระหว่าง -2,147,483,648 ถึง 2,147,483,647 กินหน่วยความจำ 4 ไบต์

float
ใช้เก็บเลขทศนิยม ค่าอยู่ระหว่าง -3.4 x 1038 ถึง 3.4 x 1038 กินหน่วยความจำ 4 ไบต์

 

ตัวแปรอะเรย์ (Array)

ตัวแปร Array คือตัวแปรหลายๆ ตัวถูกรวมในชื่อเดียวกัน แล้วอ้างถึงตัวแปรแต่ละตัวด้วยหมายเลขหรือดัชนีที่เขียนไว้ในวงเล็บสี่เหลี่ยม

ตัวอย่าง การประกาศตัวแปรแบบ Array

int myInts[6];

int myPins[] = {2,4,5,7};

char msg[6] = “hello”

 

คำสั่งวนลูปตามจำนวนครั้ง for

รูปแบบ

for (ค่าเริ่มต้น; เงื่อนไข ;ส่วนเพิ่มค่า){

    ทำคำสั่ง จนครบเงื่อนไข;

}

 

ตัวอย่างที่ 7 วนลูปเปลี่ยน 4 หน้าจอ 10 รอบ

 #include <popx2.h>
int i;
void setup() {
  for (i = 0; i < 10; i++) {
    glcdFillScreen(color[i]);
    delay(200);
  }
}
void loop() {
}
การทำงาน

สีมาตรฐานของจอ GLCD ถูกเก็บไว้ในตัวแปรแบบ Array สามารถเรียกใช้งานผ่านตัวแปร color[] โดยระบุค่าดัชนีตามค่าของคำสั่ง for ซึ่งจะวนลูปและตรวจสอบค่าตัวแปร i ไม่ให้เกินค่า 10 และทุกครั้งที่วนจะเพิ่มค่า i ขึ้นทีละ 1 ค่า ทำให้เกิดการวนลูปจำนวน 10 รอบและแสดงสีออกที่หน้าจอ GLCD 10 สี

ตัวอย่างที่ 8 วนลูปนับเลขขึ้น แสดงผลที่ GLCD

 #include <popx2.h>  
int i;
void setup() {
  setTextSize(3);
  for(i=0;i<=20;i++){
    glcd(0,0,"%d",i);
    delay(200);    
  }
  beep();
}
void loop() {
}
การทำงาน

คำสั่ง glcd นอกจากแสดงตัวอักษรได้แล้ว ในกรณีที่ต้องการแสดงตัวเลข สามารถใช้เครื่องหมายพิเศษต่างๆ เพื่อแทนรูปแบบตัวเลขที่ต้องการแสดงผลได้ โดย

ค่าพิเศษของ glcd

%d แสดงตัวเลขจำนวนเต็มในช่วง -32,768 ถึง 32,767

%h แสดงตัวเลขฐานสิบหก

%b แสดงตัวเลขฐานสอง

%l แสดงตัวเลขจำนวนเต็มในช่วง -2,147,483,648 ถึง 2,147,483,647

%f แสดงผลตัวเลขจำนวนจริง (แสดงทศนิยม 3 หลัก)

จากตัวอย่าง คำสั่ง glcd (0,0,”%d”,i); จะเป็นการนำค่าจากตัวแปร i ไปแสดงยังตำแหน่งที่ระบุด้วยเครื่องหมาย %d นั่นเอง

ตัวอย่างที่ 9 การนับเลขลงแสดงผลที่ GLCD

 #include <popx2.h>  
int i;
void setup() {
  setTextSize(3);
  for(i=20;i>0;i--){
    glcd(0,0,"%d",i);
    delay(200);    
  }
  beep();
}
void loop() {
}
การทำงาน

เปลี่ยนรูปแบบคำสั่ง for เพื่อนับค่าลงจาก 20 และหยุดเมื่อค่าเท่ากับ 0 แต่เมื่อทดสอบการทำงาน พบว่าค่าตัวเลขแสดงค่าไม่ถูกต้อง โดยพบว่าตัวเลขเมื่อนับต่ำกว่า 10 แล้วกลายเป็น 90 80 แทน เนื่องจากว่าการเปลี่ยนเลขจากหลัก 10 ไปเป็นหลักหน่วย (10 ไปเป็น 9) เลข 0 ที่ต่อท้ายไม่ถูกลบ กลายเป็นแสดง 90 แทนเลข 9

แก้ปัญหาเลขค้างด้วยการเคาะวรรคเพิ่ม

เมื่อมีการเคาะเว้นวรรคหลัง %d จะทำให้เมื่อแสดงตัวเลขค่าใดค่าหนึ่งแล้วมีวรรคต่อท้าย ซึ่งจะไปลบตัวเลขส่วนเกินจากคำสั่งก่อนหน้านี้ได้นั่นเอง

ตัวอย่างที่ 10 การนับเลขลงแสดงผลที่ GLCD ปรับแก้แล้ว

 #include <popx2.h>
int i;
void setup() {
  setTextSize(3);
  for (i = 20; i > 0; i--) {
    glcd(0, 0, "%d  ", i);
    delay(200);
  }
  beep();
}
void loop() {
}

ปุ่มปรับเพื่ออ่านค่าแอนะล็อก : knob

คำสั่ง knob()

รูปแบบ

knob();

// คืนค่า 0-1000 ตามการหมุนปุ่มปรับ

ตัวอย่าง

glcd(0,0,”%d “,knob());

 

คำสั่ง knob(x)

รูปแบบ

knob(x);

// ค่าที่อ่านได้จาก knob มีค่าระหว่าง 0 ถึงค่า x ตามการหมุนปุ่มปรับ

ตัวอย่าง
int val=0;
val=knob(180);
glcd("%d ",val);

// หน้าจอ GLCD แสดงค่าตัวเลขระหว่าง 0-180 ตามการหมุนปุ่มปรับ

 

คำสั่ง knob(x,y)

รูปแบบ

knob(x,y)

// ค่าที่อ่านได้อยู่ระหว่างค่า x และค่า y ตามการหมุนปุ่มปรับ

ตัวอย่าง

glcd(1,1,”%d “,knob(10,90));

// GLCD แสดงค่าตัวเลขระหว่าง 10-90 ตามการหมุนปุ่มปรับ

 

ตัวอย่างที่ 11 แสดงบาร์กราฟตามการปรับ knob

 #include <pop7.h>
int x;
void setup() {
  setTextSize(3);
}
void loop() {
  glcd(1, 0, "%d  ", knob(128));
  glcdFillRect(0, 80, knob(128), 10, GLCD_RED);
  glcdFillRect(knob(128), 80, 128 - knob(128), 10, GLCD_BLACK);
}
การทำงาน

คำสั่ง glcd จะนำค่า knob ที่อ่านได้ในช่วง 0-128 มาแสดง ซึ่งค่า 0-128 คือค่าความกว้างของพิกเซลของจอ glcd นั่นเอง ดังนั้น สามารถเอาค่า knob() ไปใส่เป็นค่าความกว้างของ glcd ในคำสั่ง glcdFillRect ได้ เมื่อหมุนปรับความกว้างของ glcd จะเพิ่มขึ้น แต่เมื่อปรับค่ากลับจะต้องสร้างสี่เหลี่ยมสีดำขึ้นมาอีกตัวเพื่อลบส่วนเกินของความกว้างทิ้ง ค่าความกว้างที่ถูกลบเท่ากับ 128-knob(128) ส่วนตำแหน่งเริ่มต้นของสี่เหลี่ยมสีดำนี้ จะต้องเริ่มที่ปลายสุดของค่า knob() นั่นเอง

เป็นอย่างไรบ้างครับ กับการทดสอบปรับพื้นการเขียนโค้ดภาษา C ตอนต่อไป จะลงมือสร้างโครงสร้างของรถ กันบ้าง ติดตามกันต่อได้เลยครับ

Facebook Comments Box