ทดลองใช้ Accessory Shield
ผมได้ซื้อ Shield ของ Arduino มา 1 บอร์ด บอร์ดนี้ผลิตโดยบริษัท waveshare โดยหน้าตาของบอร์ดแสดงดังรูปด้านล่าง
จึงนำมารีวิวกัน เผื่อใครจะสนใจ
ความสามารถของบอร์ด
- Joystick 5 ทิศทาง (หมายเลข 9)
- potentiometer (หมายเลข 6)
- Buzzer (หมายเลข 5)
- RGB LED (หมายเลข 4) แสดงสีได้ 256×256×256 สี
- เซ็นเซอร์วัดอุณหภูมิ (หมายเลข 8) เบอร์ M75BDP มีความละเอียด 0.125 องศา
- ตัววัดความเร่งแบบ 3-แกน (หมายเลข 7) โดยเป็นเบอร์ ADXL345 สามารถวัดได้สูงสุด +- 16g
- Real Time Clock ความละเอียดสูง (หมายเลข 14) เบอร์ DS3231 พร้อม Battery Backup ขนาด CR1220 (ไม่มี Battery มาให้ ต้องซื้อเอง)
- จอแสดงผล OLED ขนาด 0.96inch ความละเอียด 128×64
- ส่วนเชื่อมต่อสื่อสารตามแบบ XBee สามารถต่อ Bluetooth ได้
ทดสอบ OLED
จะเริ่มด้วยการทดสอบ OLED ก่อน เพราะการทดสอบอื่นๆ จะแสดงผลใน OLED โดยส่วนของ Library ให้ Download ได้ที่ https://github.com/khthana/SSD1306 โดยนำไป copy ไว้ในโฟลเดอร์ libraries ใน Arduino
จากนั้นก็ลองทดสอบ Code ง่ายๆ ดังนี้
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> #define OLED_RESET 7
#define OLED_SA0 8 Adafruit_SSD1306 display(OLED_RESET, OLED_SA0); #if (SSD1306_LCDHEIGHT != 64) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
} void loop() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("1234");
//display.setTextColor(BLACK, WHITE); // 'inverted' text
display.println(3.141592);
//display.setTextColor(WHITE);
//display.print("0x"); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
}
ทดสอบ Joystick
จะเป็นโปรแกรมง่ายๆ โดยเมื่อกดปุ่มไหนก็แสดงผลใน OLED โดยขาที่ต่อกับ Joystick มีดังนี้
- กดขึ้นบนต่อกับขา A1
- กดลงล่างต่อกับขา A5
- กดซ้ายต่อกับขา A3
- กดขวาต่อกับ A2
- กดลงตรงกลางต่อกับ A4
โปรแกรมที่ทดสอบก็เป็นโปรแกรมง่ายๆ คือ กดปุ่มไหนก็แสดงปุ่มนั้น
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>#define KEY_UP A1
#define KEY_DOWN A5
#define KEY_LEFT A3
#define KEY_RIGHT A2
#define KEY_ENTER A4#define OLED_RESET 7
#define OLED_SA0 8
Adafruit_SSD1306 display(OLED_RESET, OLED_SA0);#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endifvoid setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(KEY_UP, INPUT); digitalWrite(KEY_UP, HIGH);
pinMode(KEY_DOWN, INPUT); digitalWrite(KEY_DOWN, HIGH);
pinMode(KEY_LEFT, INPUT); digitalWrite(KEY_LEFT, HIGH);
pinMode(KEY_RIGHT, INPUT); digitalWrite(KEY_RIGHT, HIGH);
pinMode(KEY_ENTER, INPUT); digitalWrite(KEY_ENTER, HIGH);
showString(“ “);
}void showString(String str)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(str);
display.display();
}void loop() {
if (digitalRead(KEY_UP) == LOW) {
showString(“Up Pressed”);
digitalWrite(KEY_UP, HIGH);
delay(1000);
}
else if (digitalRead(KEY_DOWN) == LOW) {
showString(“Down Pressed”);
digitalWrite(KEY_DOWN, HIGH);
delay(1000);
}
else if (digitalRead(KEY_LEFT) == LOW) {
showString(“Left Pressed”);
digitalWrite(KEY_LEFT, HIGH);
delay(1000);
}
else if (digitalRead(KEY_RIGHT) == LOW) {
showString(“Right Pressed”);
digitalWrite(KEY_RIGHT, HIGH);
delay(1000);
}
else if (digitalRead(KEY_ENTER) == LOW) {
showString(“Enter Pressed”);
digitalWrite(KEY_ENTER, HIGH);
delay(1000);
}
showString(“ “);
delay(200);
}
ทดสอบ Potentiometer
จะเป็นโปรแกรมง่ายๆ อีกเช่นกัน รูปแบบจะคล้ายกับโปรแกรมที่ผ่านมา โดยจะอ่านค่าจาก Potentiometer จากนั้นแสดงผลบนจอภาพ
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>#define OLED_RESET 7
#define OLED_SA0 8
Adafruit_SSD1306 display(OLED_RESET, OLED_SA0);#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endifvoid setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
showString(“ “);
}void showString(String str)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(str);
display.display();
}void loop() {
float adcvalue = analogRead(0);
String str=(String)adcvalue;
showString(str);
delay(200);
}
ทดสอบตัววัดอุณหภูมิ LM75
เริ่มต้นต้องติดตั้ง Library โดยไปที่ Tools -> Manage Libraries… จากนั้นจะขึ้นหน้าจอเป็น Library Manager ให้ค้นหา LM75 แล้วติดตั้ง ตามภาพ (อันที่ 2) โดยการติดต่อระหว่างไอซี LM75 กับ Arduino จะใช้ I2C ผ่าน Port 0x48
จากนั้นทดสอบโดยใช้โปรแกรมต่อไปนี้
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <M2M_LM75A.h>#define OLED_RESET 7
#define OLED_SA0 8
Adafruit_SSD1306 display(OLED_RESET, OLED_SA0);#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endifM2M_LM75A lm75a;void setup()
{
lm75a.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}void loop()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print(“Temp. in C: “);
display.print(lm75a.getTemperature());
display.println(“ *C”);
display.print(“Temp. in F: “);
display.print(lm75a.getTemperatureInFarenheit());
display.println(“ *F”);
display.display();
// Shutdown/Wake up
display.println(“Shutting down”);
lm75a.shutdown();
display.print(“Is shutdown: “);
display.println(lm75a.isShutdown());
delay(5000);
display.display();
display.println(“Waking up”);
lm75a.wakeup();
display.print(“Is shutdown: “);
display.println(lm75a.isShutdown());
delay(2000);
display.display();
}
ทดสอบตัววัดความเร่งแบบ 3 แกน ADXL345
เริ่มต้นต้องติดตั้ง Library โดยไปที่ Tools -> Manage Libraries… จากนั้นจะขึ้นหน้าจอเป็น Library Manager ให้ค้นหา ADXL345 แล้วติดตั้ง ตามภาพ (อันแรก) โดยการติดต่อระหว่างไอซี ADXL345 กับ Arduino จะใช้ I2C ผ่าน Port 0x53
จากนั้นทดสอบโดยใช้โปรแกรมต่อไปนี้
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ADXL345.h>#define OLED_RESET 7
#define OLED_SA0 8
Adafruit_SSD1306 display(OLED_RESET, OLED_SA0);#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endifADXL345 adxl; //variable adxl is an instance of the ADXL345 libraryvoid setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
adxl.powerOn();
}void loop() {
int x, y, z;
adxl.readXYZ(&x, &y, &z); //read the accelerometer values
// Output x,y,z values
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print(“values of X , Y , Z: “);
display.print(x);
display.print(“ , “);
display.print(y);
display.print(“ , “);
display.println(z); double xyz[3];
double ax, ay, az;
adxl.getAcceleration(xyz);
ax = xyz[0];
ay = xyz[1];
az = xyz[2];
display.print(“X=”);
display.print(ax);
display.println(“ g”);
display.print(“Y=”);
display.print(ay);
display.println(“ g”);
display.print(“Z=”);
display.print(az);
display.println(“ g”);
display.display();
delay(1000);
}
ทดสอบ RGB
เริ่มต้นต้องติดตั้ง Library โดยไปที่ Tools -> Manage Libraries… จากนั้นจะขึ้นหน้าจอเป็น Library Manager ให้ค้นหา Chainable RGB แล้วติดตั้ง ตามภาพ โดยขาที่ควบคุมการทำงานของ LED RGB จะมี 2 ขา คือ ขา 6 (Clock) และขา 5 (Data)
โดยโปรแกรมสาธิตการทำงานมีดังนี้ (ดัดแปลงจากโปรแกรมตัวอย่าง โดยกำหนดจำนวน LED ซึ่งมีดวงเดียว จากนั้นก็เพิ่มค่า Hue ไปเรื่อยๆ ซึ่งจะทำให้สีเปลี่ยนไปเรื่อยๆ เช่นกัน และเมื่อค่า Hue เป็น 1 ก็จะเปลี่ยนเป็นลดค่า Hue แทน เมื่อถึง 0 ก็เปลี่ยนเป็นเพิ่มขึ้นใหม่ วนไปเรื่อยๆ
#include <ChainableLED.h>#define NUM_LEDS 1ChainableLED leds(6, 5, NUM_LEDS);//defines the pin used on arduino.void setup()
{
//nothing
}float hue = 0.0;
boolean up = true;void loop()
{
for (byte i = 0; i < NUM_LEDS; i++)
leds.setColorHSB(i, hue, 1.0, 0.5); delay(50); if (up)
hue += 0.025;
else
hue -= 0.025; if (hue >= 1.0 && up)
up = false;
else if (hue <= 0.0 && !up)
up = true;
}
ทดสอบ Buzzer
Buzzer ของบอร์ดจะต่ออยู่ที่ขา 11 โดยจะทดสอบโดยใช้เพลง Jinger Bell ดังนี้
int buzzerPin = 11;
int tempo = 200;
char notes[] = “eeeeeeegcde fffffeeeeddedg”;
int duration[] = {1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};void playTheShit(char note, int duration) {
char notesName[] = { ‘c’, ‘d’, ‘e’, ‘f’, ‘g’ };
int tones[] = { 261, 293, 329, 349, 392 }; for (int i = 0; i < sizeof(tones); i++) {
// Bind the note took from the char array to the array notesName
if (note == notesName[i]) {
// Bind the notesName to tones
tone(buzzerPin, tones[i], duration);
}
}
}void setup() {
pinMode(buzzerPin, OUTPUT);
}void loop() {
// Scan each char from “notes”
for (int i = 0; i < sizeof(notes) — 1; i++) {
if (notes[i] == ‘ ‘) {
// If find a space it rests
delay(duration[i] * tempo);
} else {
playTheShit(notes[i], duration[i] * tempo);
} // Pauses between notes
delay((tempo * 2)*duration[i]);
}
}
ทดสอบ RTC
เริ่มต้นต้องติดตั้ง Library โดยไปที่ Tools -> Manage Libraries… จากนั้นจะขึ้นหน้าจอเป็น Library Manager ให้ค้นหา ds3231FS แล้วติดตั้ง ตามภาพ โดยการติดต่อระหว่างไอซี ds3231 กับ Arduino จะใช้ I2C ผ่าน Port 0x68
Library ตัวนี้จะมีฟังก์ชันเยอะสักหน่อย ก็ขออธิบายฟังก์ชันก่อนก็แล้วกัน
- ฟังก์ชัน DS3231_init ใช้สำหรับเริ่มทำงาน
ฟังก์ชัน DS3231_set ใช้สำหรับกำหนดค่าเวลาให้กับ RTC โดยมี Input เป็น Struct ts โดยมีโครงสร้างของ struct ดังนี้
struct ts {
uint8_t sec; /* seconds */
uint8_t min; /* minutes */
uint8_t hour; /* hours */
uint8_t mday; /* day of the month */
uint8_t mon; /* month */
int16_t year; /* year */
uint8_t wday; /* day of the week */
uint8_t yday; /* day in the year */
uint8_t isdst; /* daylight saving time */
uint8_t year_s; /* year in short notation*/
#ifdef CONFIG_UNIXTIME
uint32_t unixtime; /* seconds since 01.01.1970 00:00:00 UTC*/
#endif
};
ผมได้เอาตัวอย่างโปรแกรมของ Library มาดัดแปลงเป็นโปรแกรม สำหรับเอาค่าใน RTC มาแสดงผลใน OLED และ โดยมีโปรแกรมดังนี้
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ds3231.h>#define OLED_RESET 7
#define OLED_SA0 8
Adafruit_SSD1306 display(OLED_RESET, OLED_SA0);#if (SSD1306_LCDHEIGHT != 64)
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endifts t; //ts is a struct findable in ds3231.hvoid setup() {
Wire.begin(); //start i2c (required for connection)
DS3231_init(DS3231_INTCN);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
t.sec = 00; t.min = 30; t.hour = 10;
t.mday = 7; t.mon = 10; t.year = 2019;
DS3231_set(t);
}void loop() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
DS3231_get(&t);
display.print(“Day : “); // Print day
display.print(t.mon);
display.print(“/”);
display.print(t.mday);
display.print(“/”);
display.println(t.year); display.print(“Hour : “); // Print time
if (t.hour < 10) display.print(“0”); display.print(t.hour);
display.print(“:”);
if (t.min < 10) display.print(“0”); display.print(t.min);
display.print(“.”);
if (t.sec < 10) display.print(“0”); display.println(t.sec);
display.println();
display.display();
delay(1000);
}
การกำหนดเวลาให้กับ RTC จะกระทำโดยคำสั่ง ดังนั้นต้องการให้มีเวลาเป็นเท่าไรก็สามารถกำหนดได้เลย จากนั้นเรียกคำสั่ง DS3231_set() เพื่อส่งไปยัง RTC
t.sec = 00; t.min = 30; t.hour = 10;
t.mday = 7; t.mon = 10; t.year = 2019;
DS3231_set(t);
สำหรับฟังก์ชันใน loop() จะเริ่มด้วยเรียก DS3231_get(&t); เพื่ออ่านเวลาปัจจุบัน ซึ่งจะส่งค่ากลับมาใน struct t จากนั้นก็นำค่าใน struct มา print โดยจะแสดงผลเป็น 2 บรรทัด คือ วันเดือนปี 1 บรรทัด และเวลาอีก 1 บรรทัด จากนั้นหน่วงเวลา 1 วินาที
Demo
โปรแกรมข้างล่างนี้เป็นโปรแกรมสาธิตการทำงานของบอร์ด โดยนำหลายๆ ส่วนมาทำงานด้วยกัน โดยดัดแปลงมาจาก https://libstock.mikroe.com/projects/view/1502/waveshare-arduino-accessory-shield-demo
สำหรับโปรแกรมขอใส่ใน gist เพราะยาวมากพอสมควร
โปรแกรมนี้จะนำนาฬิกา วันเวลา มาแสดงผล บนจอ โดยเวลาที่แสดงผลจะอยู่ในส่วนของ Setup
สรุป
การทดสอบบอร์ดก็จบลงเพียงเท่านี้ ผู้ที่จะนำไปลองใช้ก็น่าจะได้ข้อมูลกันตามสมควร แต่จากที่ทดสอบมา พบปัญหาหนึ่ง คือ เนื่องจากบอร์ดนี้มีอุปกรณ์ที่ทำงานร่วมกันเป็นจำนวนมาก ดังนั้นการทำงานร่วมกันของ Library ก็เป็นปัญหาพอสมควร การสนับสนุนข้อมูลก็มีไม่มากนัก ตามสไตล์บอร์ดจีน
อย่างไรก็ตาม บอร์ดนี้ถือได้ว่าเป็นบอร์ด Shield สำหรับ Arduino ที่มีความสามารถมากบอร์ดหนึ่ง อาจจะตอบโจทย์สำหรับงานบางด้าน แต่ผู้ที่นำไปใช้ก็ต้องมีประสบการณ์พอสมควรครับ