Posted on Leave a comment

Simplex vs Duplex (communication) คืออะไร

Simplex communication คืออะไร

Simplex communication คือ การส่งสัญญาณระหว่างจุด 2 จุด โดยที่จุดหนึ่งส่งสัญญาณ อีกจุดรับสัญญาณ ไม่สามารถส่งกลับได้ สมมติว่าเป็นการส่งสัญญาณระหว่างจุด A กับจุด B โดยจุด A จะมีอุปกรณ์ในการส่งสัญญาณเท่านั้น ไม่สามารถรับสัญญาณได้ ส่วนจุด B มีอุปกรณ์รับสัญญาณเท่านั้น ไม่สามารถส่งสัญญาณได้ ตัวอย่างเช่น การถ่ายทอดสัญญาณโทรทัศน์ สถานีโทรทัศน์ก็จะมีเครื่องส่งสัญญาณอย่างเดียว ส่วนทีวีก็ทำหน้าที่รับสัญญาณอย่างเดียว ไม่สามารถส่งสัญญาณกลับไปที่สถานีได้ นอกจากนี้ อุปกรณ์พวก remote control ต่างๆ ก็เป็นการส่งสัญญาณแบบ simplex ด้วยเหมือนกัน คือ ตัวรีโมท ทำหน้าที่ส่งอย่างเดียว ส่วนเครื่องใช้ไฟฟ้าก็ทำหน้าที่รับอย่างเดียว ส่งกลับไม่ได้

Duplex communication คืออะไร

Duplex communication คือ การส่งสัญญาณระหว่างจุด 2 จุด โดยที่ทั้งสองจุดสามารถส่งสัญญาณสวนทางกันได้ คือ ทั้งสองจุดมีทั้งตัวส่งสัญญาณ และตัวรับสัญญาณ แต่การส่งข้อมูลสวนทางกันได้นี้ก็แบ่งได้เป็น 2 แบบ คือ Half-Duplex (HDX) และ Full-Duplex (FDX)

Half-Duplex 

คือ ระบบ duplex ที่สามารถสื่อสารสวนทางกันได้ แต่ต้องผลัดกัน ไม่สามารถสื่อสารสวนทางกันได้พร้อมกัน เช่น walkie-talkie โดยเมื่อฝ่ายหนึ่งจะพูดต้องกด switch เมื่อกดแล้ว ระบบจะปิดการทำงานของตัวรับสัญญาณ ทำให้ไม่สามารถรับสัญญาณได้ และเปิดการทำงานของตัวส่งสัญญาณ ทำให้สามารถพูดหรือส่งสัญญาณได้ และเมื่อปล่อย switch ระบบก็จะปิดการทำงานของตัวส่งสัญญาณ และเปิดการทำงานของตัวรับสัญญาณอีกครั้ง เพื่อรอรับสัญญาณ จะเห็นว่า ถ้าทั้งสองฝั่งกด switch พูดพร้อมกัน ก็ไม่มีตัวรับสัญญาณ การส่งสัญญาณหรือการสื่อสารก็ไม่สมบูรณ์

Full-Duplex 

คือ ระบบ duplex ที่ทั้งสองจุดสามารถสื่อสารสวนทางกันได้พร้อมกัน เช่น โทรศัพท์ ที่เราใช้กัน

อ้างอิง

Posted on Leave a comment

การใช้งาน e-paper 2.13 inch 250×122 pixel White-Black-Red

ในบทความนี้จะเป็นการใช้งาน e-paper ง่าย ๆ ไม่ใช้ RAM เยอะ และใช้ library แค่ SPI เท่านั้น

สิ่งที่ต้องมี

การต่อสาย

Arduino NanoE-paper
5VVCC
GNDGND
11SDI
13SCLK
10CS
9D/C
8Reset
7Busy
Arduino Nano and E-paper connecting table
Arduino Nano and E-paper wiring

ขั้นตอน

ขั้นตอนการใช้งาน ก็มีแค่ 4 ขั้นตอนง่าย ๆ คือ อันดับแรก เราต้องสร้างภาพที่เราต้องการแบบเต็มจอ (screen) เสียก่อน แล้วนำภาพนั้นไปแปลงเป็นตัวเลข จากนั้นก็ทำตัวเลขเหล่านั้นมาใส่ลง file แล้วโปรแกรมลง microcontroller ก็เป็นอันเสร็จเรียบร้อย

ขั้นตอนการใช้ e-paper

สร้างภาพแบบเต็ม screen

เนื่องจาก screen นี้มีขนาด 250×122 pixel โดยมีสามสี คือ ขาว ดำ และ แดง ดังนั้นเราก็จะต้องสร้างภาพที่มีขนาดและสีตามนี้ (ในที่นี้จะไม่กล่าวถึงวิธีทำภาพ)

ภาพที่ต้องการแสดงบน screen (mavigo_bwr.png)

เมื่อได้ภาพที่ต้องการแล้ว ก็ทำการแบ่งเป็น 2 ภาพ คือ ภาพที่เป็นสีดำล้วน กับสีแดงล้วน (เนื่องจาก memory สำหรับภาพสีดำ กับสีแดงใน e-paper นั้นจะแยกกัน) โดยให้ภาพอยู่ในรูปแบบของ JPG, JPEG, PNG, หรือ BMP

mavigo_bw.png
mavigo_r.png

เปลี่ยนภาพให้เป็นตัวเลข

ในการเปลี่ยนภาพให้เป็นตัวเลข ขอแนะนำเว็บของผู้ผลิต screen นั่นคือ good-display.com ซึ่งที่จริง เค้ามีโปรแกรมแบบไม่ online ให้ใช้ด้วย แต่ในที่นี้จะแนะนำแบบ online เท่านั้น เมื่อเปิดหน้าเว็บแล้วให้ใส่ข้อมูลดังนี้

1. เลือก screen model 2.13 และ GDEH213Z98 แล้ว check confirm

2. กด “Choose Files” แล้วเลือก file ภาพสีดำที่เตรียมไว้

3. ตรวจสอบว่า Preview ถูกต้องหรือไม่ โดยที่จะเป็นภาพกลับด้าน ถ้าไม่ถูกต้อง ลองตรวจสอบชนิดของ file, ขนาดของภาพ หรือนำ alpha channel ออกจากภาพ แล้วค่อย upload อีกครั้ง

4. เลือก Output Type: เป็นแบบ “Plain” , Pattern: “Horizontal -1 bit per pixel” แล้วกด “Output” ก็จะได้ ตัวเลขออกมา แล้วกด copy

นำตัวเลขที่ได้ใส่ลง file

เมื่อได้ตัวเลขแล้ว เราก็นำตัวเลขมาใส่ file โดยที่ file จะมีรูปแบบด้านล่าง (รูปแบบ file อ้างอิงมาจาก good-display.com) โดยให้วางตัวเลขที่ copy มานั้น ใส่ลงใน array ตัวแรก ซึ่งเตรียมไว้สำหรับภาพสีดำ จากนั้น ก็กลับไปที่เว็บอีกครั้ง โดยคราวนี้ทำเหมือนเดิม แต่เลือกภาพสีแดงแทน แล้วนำตัวเลขที่ได้มาใส่ลงใน array ที่สอง (ที่จริงเว็บรองรับที่จะทำการ convert พร้อมกันทีละ 2 ภาพ แต่เพื่อลดโอกาสสับสน จึงให้ทำทีละภาพ)

#include <avr/pgmspace.h>
const unsigned char gImage_BW[4000] PROGMEM= { /* For black image */


};

const unsigned char gImage_R[4000] PROGMEM= { /* For red image */


};
avr/pgmspace.h เป็น library ช่วยในการจัดการ memory สำหรับ microcontroller ตระกูล avr จะเห็นว่า เราประกาศ array แล้วมี keyword “PROGMEM” ด้วย นั่นเป็นการบอกให้ compiler นำตัวแปลนี้ใส่ลงใน Flash memory แทนที่จะเป็น RAM เหมือนตัวแปลอื่น ๆ ทำให้ประหยัด RAM ไปได้ ถ้าเอา PROGMEM ออก compiler ก็จะฟ้องว่า RAM ไม่พอ เพราะ ATmega328p มี RAM แค่ 2k byte แต่เราประกาศตัวแปลตัวละ 4k byte เลยทีเดียว 

เมื่อใส่ตัวเลขลงใน array ทั้งสองตัวเรียบร้อยแล้วจะได้ file ลักษณะด้านล่างนี้ ต่อไปให้ save file ในชื่อ mavigo_demo.h เก็บไว้ที่เดียวกับ file ที่เก็บ code (___.ino) ถ้าเก็บไว้คนละที่กัน ตัว code จะเรียกหาไม่เจอ

#include <avr/pgmspace.h>
const unsigned char gImage_BW[4000] PROGMEM= { /* For black image */
// 'mavigo_bw', 122x250px
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x3f, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf0, 0x07, 0x1e, 0x00, 0x00, 0x01, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xe0, 0x07, 0x07, 0x00, 0x00, 0x01, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xe0, 0x0f, 0x00, 0xe0, 0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x1f, 0x00, 0x1c, 0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x1f, 0x00, 0x07, 0x00, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x3f, 0x00, 0x00, 0xe0, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x3f, 0x00, 0x00, 0x1c, 0x01, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x3f, 0x80, 0x00, 0x03, 0x01, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xe0, 0x00, 0x00, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xff, 0x00, 0x00, 0x03, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x01, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x01, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x01, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xff, 0xc0, 0x00, 0x03, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xfe, 0x00, 0x00, 0x0f, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xf0, 0x00, 0x00, 0x7f, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x7f, 0xc0, 0x00, 0x01, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0x80, 0x3f, 0x00, 0x00, 0x0e, 0x01, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x3f, 0x00, 0x00, 0x70, 0x01, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x1f, 0x00, 0x01, 0xc0, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xc0, 0x1f, 0x00, 0x0e, 0x00, 0x01, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xe0, 0x0f, 0x00, 0x70, 0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xe0, 0x0f, 0x01, 0xc0, 0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf0, 0x07, 0x8e, 0x00, 0x00, 0x01, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf0, 0x03, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x80, 0x00, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x0f, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x8e, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0x04, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xfe, 0x08, 0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xfe, 0x18, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xfe, 0x18, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xfe, 0x10, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x0e, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x7e, 0x01, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x06, 0x01, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x07, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x0f, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x07, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x7f, 0xff, 0xfc, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x0f, 0xff, 0xff, 0x9f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xe3, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x0c, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x04, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x04, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x04, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x02, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0x86, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x0f, 0x87, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x0f, 0x86, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x3c, 0xfc, 0x30, 0x06, 0x00, 0x0f, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x3c, 0xfc, 0x30, 0x06, 0x00, 0x0f, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf9, 0xff, 0x30, 0xff, 0x39, 0xfe, 0x7f, 0xcf, 0xc0, 
0xff, 0xfc, 0x00, 0x3e, 0x00, 0x1f, 0xff, 0xf9, 0xff, 0x30, 0xff, 0x39, 0xfe, 0x7f, 0xcf, 0xc0, 
0xff, 0xfc, 0x01, 0xff, 0xc0, 0x1f, 0xff, 0xf9, 0x81, 0x30, 0xc3, 0x37, 0x9e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x03, 0xff, 0xe0, 0x0f, 0xff, 0xf9, 0x81, 0x30, 0xc3, 0x37, 0x9e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xf9, 0x81, 0x33, 0xfc, 0xc0, 0x7e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xf9, 0x81, 0x33, 0xfc, 0xc0, 0x7e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x0f, 0xff, 0xf8, 0x0f, 0xff, 0xf9, 0x81, 0x30, 0xcc, 0x08, 0x7e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x0f, 0xc0, 0x78, 0x0f, 0xff, 0xf9, 0x81, 0x30, 0xcc, 0x08, 0x7e, 0x60, 0x4f, 0xc0, 
0xff, 0xf8, 0x07, 0xc0, 0x78, 0x0f, 0xff, 0xf9, 0xff, 0x30, 0x33, 0x31, 0xe6, 0x7f, 0xcf, 0xc0, 
0xff, 0xf8, 0x07, 0xc0, 0x70, 0x0f, 0xff, 0xf9, 0xff, 0x30, 0x33, 0x31, 0xe6, 0x7f, 0xcf, 0xc0, 
0xff, 0xf8, 0x03, 0xc0, 0x70, 0x0f, 0xff, 0xf8, 0x00, 0x33, 0x33, 0x36, 0x66, 0x00, 0x0f, 0xc0, 
0xff, 0xf8, 0x01, 0xc0, 0x60, 0x1f, 0xff, 0xf8, 0x00, 0x33, 0x33, 0x36, 0x66, 0x00, 0x0f, 0xc0, 
0xff, 0xfc, 0x00, 0xc0, 0x60, 0x1f, 0xff, 0xff, 0xff, 0xf3, 0x33, 0xff, 0xe7, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x01, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf3, 0x33, 0xff, 0xe7, 0xff, 0xff, 0xc0, 
0xff, 0xfc, 0x01, 0xc0, 0x00, 0x1f, 0xff, 0xf9, 0xf8, 0x3f, 0xf0, 0xff, 0xe0, 0x00, 0x3f, 0xc0, 
0xff, 0xfe, 0x01, 0xc0, 0x00, 0x3f, 0xff, 0xf9, 0xf8, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xc0, 
0xff, 0xfe, 0x01, 0xc0, 0x00, 0x3f, 0xff, 0xfe, 0x06, 0xf3, 0x3f, 0xff, 0x80, 0x79, 0x8f, 0xc0, 
0xff, 0xff, 0x01, 0xc0, 0x00, 0x7f, 0xff, 0xf9, 0xe0, 0x3c, 0xf8, 0x0f, 0x61, 0xe7, 0x9f, 0xc0, 
0xff, 0xff, 0xc3, 0xc0, 0x00, 0xff, 0xff, 0xf9, 0xe0, 0x3c, 0xe0, 0x03, 0xe1, 0xe7, 0xbf, 0xc0, 
0xff, 0xff, 0xe3, 0xc0, 0x00, 0xff, 0xff, 0xfe, 0x7f, 0xcf, 0xc3, 0xe1, 0xff, 0x87, 0xbf, 0xc0, 
0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xfe, 0x7f, 0xcf, 0x87, 0xf8, 0xff, 0x87, 0xbf, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x98, 0x03, 0x9f, 0xfc, 0x61, 0x81, 0xbf, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x98, 0x03, 0x11, 0x06, 0x61, 0x81, 0xbf, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfe, 0xf3, 0x30, 0x66, 0x77, 0x98, 0x4f, 0xc0, 
0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xf9, 0xfe, 0xf7, 0x3c, 0x0e, 0x37, 0x98, 0x4f, 0xc0, 
0xff, 0xff, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x01, 0x07, 0x3f, 0x87, 0x3e, 0x06, 0x4f, 0xc0, 
0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xff, 0xf8, 0x01, 0x07, 0x3f, 0x87, 0x3e, 0x06, 0x4f, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x3c, 0x0e, 0x3e, 0x00, 0x0f, 0xc0, 
0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x30, 0x26, 0x7e, 0x00, 0x0f, 0xc0, 
0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x18, 0x03, 0x11, 0x06, 0x61, 0x86, 0x4f, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x18, 0x03, 0x9f, 0xfc, 0x61, 0x86, 0x4f, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x60, 0xcd, 0x8f, 0xf8, 0xe0, 0x18, 0x4f, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x60, 0xcd, 0xc3, 0xe1, 0xe0, 0x18, 0x4f, 0xc0, 
0xff, 0xfc, 0x00, 0x3e, 0x00, 0x1f, 0xff, 0xff, 0x99, 0x0c, 0xe0, 0x03, 0xf9, 0x99, 0xff, 0xc0, 
0xff, 0xfc, 0x01, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0x99, 0x0c, 0x78, 0x0f, 0xf9, 0x99, 0xff, 0xc0, 
0xff, 0xf8, 0x03, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xf9, 0xff, 0x3f, 0xff, 0xe6, 0x18, 0x4f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf1, 0xff, 0x0f, 0xff, 0xe6, 0x18, 0x4f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xfe, 0x60, 0x3c, 0xcc, 0x0e, 0x00, 0x00, 0x3f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3d, 0xe7, 0xe0, 0x7f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x39, 0xe7, 0xe0, 0x7f, 0xc0, 
0xff, 0xf8, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xf8, 0x00, 0x3c, 0x0c, 0xd8, 0x06, 0x66, 0x0f, 0xc0, 
0xff, 0xf8, 0x03, 0xff, 0xf0, 0x0f, 0xff, 0xf8, 0x00, 0x3c, 0x0c, 0xc8, 0x06, 0x66, 0x0f, 0xc0, 
0xff, 0xfc, 0x01, 0xff, 0xe0, 0x1f, 0xff, 0xf9, 0xff, 0x30, 0xc3, 0x3e, 0x07, 0xe0, 0x7f, 0xc0, 
0xff, 0xfc, 0x00, 0xff, 0x80, 0x1f, 0xff, 0xf9, 0xff, 0x30, 0xc3, 0x3e, 0x07, 0xe0, 0x7f, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf9, 0x81, 0x30, 0xfc, 0xc9, 0x80, 0x06, 0x0f, 0xc0, 
0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf9, 0x81, 0x30, 0xfc, 0xc9, 0x80, 0x06, 0x0f, 0xc0, 
0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf9, 0x81, 0x3c, 0xcc, 0xc6, 0x19, 0x81, 0xbf, 0xc0, 
0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf9, 0x81, 0x3c, 0xcc, 0xc6, 0x19, 0x81, 0xbf, 0xc0, 
0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf9, 0x81, 0x3f, 0xf3, 0xf1, 0xe7, 0xe0, 0x4f, 0xc0, 
0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x81, 0x3f, 0xf3, 0xf1, 0xe7, 0xe0, 0x4f, 0xc0, 
0xff, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xf9, 0xff, 0x3f, 0xc0, 0xf1, 0xe1, 0x86, 0x3f, 0xc0, 
0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xf9, 0xff, 0x3f, 0xc0, 0xf1, 0xe1, 0x86, 0x3f, 0xc0, 
0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x30, 0xf0, 0xf9, 0xe1, 0x9f, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x30, 0xf0, 0xf9, 0xe1, 0x9f, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
};

const unsigned char gImage_R[4000] PROGMEM= { /* For red image */
// 'mavigo_r', 122x250px
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xfc, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1e, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0e, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1b, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1b, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x19, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0x80, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7e, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x70, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0x80, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7c, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x60, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1c, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x09, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x19, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1b, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0x80, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1c, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x06, 0x58, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xfc, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x19, 0xec, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0x6c, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0x7c, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x38, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1c, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0x80, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0d, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x19, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1b, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x5f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xf8, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xfc, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x19, 0xec, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0x6c, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1e, 0x78, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x30, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0c, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x20, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x08, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0x80, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x18, 0x60, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xc0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xe0, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
};

Upload ไปยัง Arduino Nano

เมื่อเตรียมข้อมูลเรียนร้อยแล้ว ก็ทำการ upload ข้อมูลพร้อมทั้ง code ที่ช่วยในการนำข้อมูลภาพจาก flash memory ไปส่งให้กับ display ก็เป็นอันเสร็จเรียบร้อย แต่ก่อนอื่น เรามาทำความเข้าใจตัว code ที่ว่ากันก่อน (ตัว code นี้ได้ดัดแปลงมากจาก code ของ good-display.com

#include

ส่วนนี้จะ  include 2 อย่างคือ SPI.h ซึ่งเป็น library ที่เราใช้ในการสื่อสารกับ display อีก file คือ mavigo_demo.h ซึ่งเป็น file ที่เก็บภาพที่จะแสดงบน screen ซึ่งเราสร้างไว้ในขั้นตอนก่อนหน้านี้

#include <SPI.h>
#include"mavigo_demo.h"

IO setting

ส่วนนี้เป็นการกำหนดหน้าที่ให้กับ pin ต่าง ๆ 

int BUSY_Pin = 7; 
int RES_Pin = 8; 
int DC_Pin = 9; 
int CS_Pin = 10; 

#define

เป็นการกำหนดชื่อให้กับค่าคงที่เพื่อให้เข้าใจง่าย ในที่นี้เป็นการกำหนดขนาดของ RAM ที่ใช้แสดงภาพเต็ม screen ซึ่งก็คือ 4000 byte

#define ALLSCREEN_GRAGHBYTES  4000

//Functions declaration

เป็นการประกาศ function ที่จะใช้ โดยตัวเนื้อของ function จะถูกเขียนไว้หลังจาก loop() ในส่วนของ function definition

setup()

ในส่วนนี้เป็นการกำหนดทิศทางของข้อมูลของแต่ละ pin และ เตรียมพร้อมสำหรับการสื่อสาร SPI

   pinMode(BUSY_Pin, INPUT); 
   pinMode(RES_Pin, OUTPUT);  
   pinMode(DC_Pin, OUTPUT);    
   pinMode(CS_Pin, OUTPUT);   
   //SPI
   SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); 
   SPI.begin ();  

loop()

ใน loop function นี้จะแบ่ง code เป็นสองส่วนหลัก ๆ คือ ส่วนที่แสดงภาพบน screen กับส่วนที่ clear screen ในแต่ละส่วนก็จะมี function การทำงานที่ครบถ้วน คือ เริ่มตั้งแต่ Initial hardware (EPD_HW_Init()) นำภาพขึ้น screen (EPD_WhiteScreen_ALL()) หรือ clear screen (EPD_WhiteScreen_ALL_Clean()) และ เข้าสู่ Deep sleep mode (EPD_DeepSleep()) เพื่อประหยัดพลังงาน ซึ่งหลังจาก Deep sleep ถ้าจะให้ display ทำงานอีกครั้ง ต้องส่งสัญญาณ Hardware reset ซึ่งอยู่ใน (EPD_HW_Init())

    //Full screen refresh
    EPD_HW_Init(); //Electronic paper initialization
    EPD_WhiteScreen_ALL(gImage_BW,gImage_R); //Refresh the picture in full screen
    EPD_DeepSleep(); //Enter deep sleep,Sleep instruction is necessary, please do not delete!!! 
    delay(2000);   
    
    //Clean
    EPD_HW_Init(); //Electronic paper initialization
    EPD_WhiteScreen_ALL_Clean();
    EPD_DeepSleep(); //Enter deep sleep,Sleep instruction is necessary, please do not delete!!!
    delay(2000); 
    
    while(1); 

// Functions definition

ในส่วนสุดท้ายนี้เป็นรายละเอียดของ function ที่ใช้ในการควบคุม display ถ้าอยากทราบรายละเอียดอาจต้องเปิดคู่มือของ display และ driver IC (SSD1680) ควบคู่กันไป โดยในที่นี้จะยังไม่กล่าวถึงรายละเอียดของ function เหล่านี้

เพื่อความสะดวกให้สร้าง “New Sketch” copy code ด้านล่างนี้ไปวางทับ แล้วอย่าลืม วาง file ที่เก็บตัวเลขของภาพ (ในที่นี้คือ mavigo_demo.h) ไว้ใน folder เดียวกันนะครับ

#include <SPI.h>
#include"mavigo_demo.h"

//IO settings
int BUSY_Pin = 7; 
int RES_Pin = 8; 
int DC_Pin = 9; 
int CS_Pin = 10; 

//250*122///////////////////////////////////////

#define ALLSCREEN_GRAGHBYTES  4000

// Function declaration

void SPI_Write(unsigned char value);
void Epaper_Write_Command(unsigned char command);
void Epaper_Write_Data(unsigned char command);
//EPD
void Epaper_READBUSY(void);
void EPD_HW_Init(void); //Electronic paper initialization
void EPD_Update(void);
void EPD_DeepSleep(void);

//Display 
void EPD_WhiteScreen_ALL(const unsigned char *BW_datas,const unsigned char *R_datas);
void EPD_WhiteScreen_ALL_Clean(void);

void setup() {

   pinMode(BUSY_Pin, INPUT); 
   pinMode(RES_Pin, OUTPUT);  
   pinMode(DC_Pin, OUTPUT);    
   pinMode(CS_Pin, OUTPUT);   
   //SPI
   SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); 
   SPI.begin ();  

}

//Tips//
/*When the electronic paper is refreshed in full screen, the picture flicker is a normal phenomenon, and the main function is to clear the display afterimage in the previous picture.
  When the local refresh is performed, the screen does not flash.*/
/*When you need to transplant the driver, you only need to change the corresponding IO. The BUSY pin is the input mode and the others are the output mode. */
  
void loop() {
    //Full screen refresh
    EPD_HW_Init(); //Electronic paper initialization
    EPD_WhiteScreen_ALL(gImage_BW,gImage_R); //Refresh the picture in full screen
    EPD_DeepSleep(); //Enter deep sleep,Sleep instruction is necessary, please do not delete!!! 
    delay(2000);   
    
    //Clean
    EPD_HW_Init(); //Electronic paper initialization
    EPD_WhiteScreen_ALL_Clean();
    EPD_DeepSleep(); //Enter deep sleep,Sleep instruction is necessary, please do not delete!!!
    delay(2000); 
    
    while(1); 

}


// Function definition

//////////////////////SPI///////////////////////////////////

void SPI_Write(unsigned char value)                                    
{                                                           
  SPI.transfer(value);
}

void Epaper_Write_Command(unsigned char command)
{
  digitalWrite(CS_Pin,LOW);                   
  digitalWrite(DC_Pin,LOW);   // command write
  SPI_Write(command);
  digitalWrite(CS_Pin,HIGH);
}

void Epaper_Write_Data(unsigned char command)
{
  digitalWrite(CS_Pin,LOW);                   
  digitalWrite(DC_Pin,HIGH);   // data write
  SPI_Write(command);
  digitalWrite(CS_Pin,HIGH);
}

/////////////////EPD settings Functions/////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////
//SSD1680
void EPD_HW_Init(void)
{
  digitalWrite(RES_Pin,LOW);  // Module reset      
  delay(10); //At least 10ms delay 
  digitalWrite(RES_Pin,HIGH); 
  delay(10); //At least 10ms delay  

  Epaper_READBUSY();   
  Epaper_Write_Command(0x12);  //SWRESET
  Epaper_READBUSY();   

  Epaper_Write_Command(0x01); //Driver output control      
  Epaper_Write_Data(0xF9);
  Epaper_Write_Data(0x00);
  Epaper_Write_Data(0x00);

  Epaper_Write_Command(0x11); //data entry mode       
  Epaper_Write_Data(0x01);

  Epaper_Write_Command(0x44); //set Ram-X address start/end position   
  Epaper_Write_Data(0x00);
  Epaper_Write_Data(0x0F);    //0x0F-->(15+1)*8=128

  Epaper_Write_Command(0x45); //set Ram-Y address start/end position          
  Epaper_Write_Data(0xF9);   //0xF9-->(249+1)=250
  Epaper_Write_Data(0x00);
  Epaper_Write_Data(0x00);
  Epaper_Write_Data(0x00); 

  Epaper_Write_Command(0x3C); //BorderWavefrom
  Epaper_Write_Data(0x05); //0x05 or 0xC0

  Epaper_Write_Command(0x18); //Read built-in temperature sensor
  Epaper_Write_Data(0x80);  
  
  Epaper_Write_Command(0x21); //  Display update control
  Epaper_Write_Data(0x00);  
  Epaper_Write_Data(0x80);  

  Epaper_Write_Command(0x4E);   // set RAM x address count to 0;
  Epaper_Write_Data(0x00);
  
  Epaper_Write_Command(0x4F);   // set RAM y address count to 0XF9;    
  Epaper_Write_Data(0xF9);
  Epaper_Write_Data(0x00);
  Epaper_READBUSY();
  
}
//////////////////////////////All screen update////////////////////////////////////////////
void EPD_WhiteScreen_ALL(const unsigned char *BW_datas,const unsigned char *R_datas)
{
   unsigned int i;  
  Epaper_Write_Command(0x24);   //write RAM for black(0)/white (1)
   for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
   {               
     Epaper_Write_Data(pgm_read_byte(&BW_datas[i]));
   }
  Epaper_Write_Command(0x26);   //write RAM for black(0)/white (1)
   for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
   {               
     Epaper_Write_Data(~(pgm_read_byte(&R_datas[i])));
   }
   EPD_Update();   
}

void EPD_WhiteScreen_ALL_Clean(void)
{
   unsigned int i;  
  Epaper_Write_Command(0x24);   //write RAM for black(0)/white (1)
   for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
   {               
     Epaper_Write_Data(0xff);
   }
  Epaper_Write_Command(0x26);   //write RAM for black(0)/white (1)
   for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
   {               
     Epaper_Write_Data(0x00);
   }
   EPD_Update();   
}

/////////////////////////////////////////////////////////////////////////////////////////
void EPD_Update(void)
{
  Epaper_Write_Command(0x22); //Display Update Control
  Epaper_Write_Data(0xF7);   
  Epaper_Write_Command(0x20);  //Activate Display Update Sequence
  Epaper_READBUSY();   

}

void EPD_DeepSleep(void)
{  
  Epaper_Write_Command(0x10); //enter deep sleep
  Epaper_Write_Data(0x01); 
  delay(100);
}

void Epaper_READBUSY(void)
{ 
  while(1)
  {   //=1 BUSY
     if(digitalRead(BUSY_Pin)==0) break;
  }  
}

//////////////////////////////////END//////////////////////////////////////////////////

ในการแสดงภาพบน screen จะมีการกะพริบหลายครั้งถือเป็นเรื่องปกติครับ ถ้า upload แล้วไม่เกิด error อะไร แต่ไม่แสดงภาพ ให้ลองตรวจสอบการต่อสายดูนะครับ หรือลองถอดสาย Busy แล้วเสียบใหม่ดูนะครับ

สรุป

การที่เราทำข้อมูลเป็นลักษณะของรูปภาพใส่ file แล้ว upload ไปยัง microcontroller ทำให้ความซับซ้อนในการโปรแกรมน้อย เพราะเขียนโปรแกรมแค่นำข้อมูลใน flash memory ไปส่งให้ตัว display เท่านั้นเอง และเนื่องจากความซับซ้อนของโปรแกรมน้อย ก็ทำให้ใช้ RAM น้อยไปด้วย เหมาะกับ microcontroller ขนาดเล็ก RAM ไม่มาก อย่าง ATmega328p ในบอร์ด Arduino Nano ส่วนในกรณีที่เราอยากให้มีการเปลี่ยนภาพได้ โดยที่เราไม่อยากมาทำการ upload ใหม่ทุกครั้งที่ต้องการเปลี่ยนภาพ เราก็สามารถทำภาพเตรียมไว้ใน flash memory ได้ แล้วก็เขียน code ให้สามารถเลือกได้ว่าจะนำภาพไหน ( array ตัวไหน)ใน memory ขึ้นมาแสดง โดยปกติแล้วถ้าเป็น screen แบบอื่น เช่น OLED หรือ TFT มักจะไม่ใช้วิธีนี้ เพราะ screen เหล่านั้นมักจะใช้แสดงภาพที่มีการ update บ่อย ๆ ดังนั้นการที่ต้องมา upload ใหม่ทุกครั้งจึงไม่สมเหตุสมผล แต่ไม่ค่อยมีปัญหาสำหรับ e-paper เพราะมักจะถูกใช้ในงานที่ไม่ต้อง update บ่อยอยู่แล้ว

Posted on Leave a comment

Arduino Nano with sensor (ก้าวที่สาม)

จาก Arduino Nano with Serial (ก้าวที่สอง) หวังว่าจะเข้าใจและทำแบบฝึกหัดกันได้นะครับ แต่ถ้าไม่ได้ก็ไม่เป็นไร เพราะค่อนข้างยากสำหรับมือใหม่ แต่ถ้าเข้าใจในก้าวที่สามนี้ จะต้องกลับไปทำแบบฝึกหัดได้อย่างแน่นอนเลยละครับ

จากตอนที่แล้ว(ก้าวที่สอง) เราได้เรียนรู้ function สำคัญที่ช่วยให้เราส่งข้อมูลจาก computer ให้ Arduino Nano ไปแล้ว คราวนี้เราจะให้ Arduino Nano ส่งข้อมูลกลับมาให้เราบ้าง โดยให้ Arduino Nano รับข้อมูลจาก sensor แล้วส่งมายัง computer โดยในที่นี้เราจะใช้ sensor ที่ผู้เขียนชอบตัวหนึ่งคือ BME280 ซึ่งเป็น sensor ที่วัด อุณหภูมิ ความชื้น และแรงดันอากาศ ด้วย 

โดยปกติแล้ว ถ้าเราจะเขียนโปรแกรมดึงข้อมูลจาก sensor สักตัว เราต้องเข้าใจการทำงานของ sensor ตัวนั้นอย่างละเอียด โดยดูจากคู่มือของ sensor นั้น ๆ จึงจะสามารถดึงข้อมูลมาได้อย่างถูกต้อง BME280 เองก็เหมือนกัน ถ้าเราจะเขียนโปรแกรมติดต่อเพื่อดึงข้อมูลเองนั้น เป็นเรื่องที่ต้องใช้เวลามากเลยทีเดียว (คู่มือ BME280) ดังนั้นจึงมีใครบางคนหรือบางกลุ่ม ได้ศึกษาการใช้งาน sensor และเขียนโปรแกรมเตรียมไว้ให้เรานำไปใช้ได้ง่าย ๆ สิ่งที่เค้าเขียนเตรียมไว้ให้นี้ ก็เป็นลักษณะของ function ให้เราเรียกใช้ โดยทั้งหมดที่เค้าเตรียมไว้ให้นั้น เรียกว่า library ดังนั้น เราต้องติดตั้ง library ของ BME280 ก่อน โดยวิธีการติดตั้ง library นั้นสามารถศึกษาได้จาก ขั้นตอนการติดตั้ง library ได้เลยครับ ในตัวอย่างนี้จะใช้ library ของ Adafruit ซึ่งต้องขอบคุณที่เค้าทำให้เราได้ใช้กันง่าย ๆ ฟรี ๆ ถ้ามีโอกาสก็อยากให้สนับสนุนสินค้าของ Adafruit เค้าด้วยนะครับ แล้วเราก็มาเริ่มกันเลย

สิ่งที่ต้องมี

เมื่อเตรียมอุปกรณ์พร้อมแล้ว ก็มาเริ่มกันเลย

Hardware

ต่อสาย โดยให้ต่อสายจาก Arduino Nano ไปที่ BME280 sensor module ดังนี้

Arduino Nano↔︎BME280 (Adafruit)
5V↔︎Vin
GND↔︎GND
A5↔︎SCK
A4↔︎SDI
Arduino Nano and BME280 connecting table
Arduino Nano and BME280 wiring

Software

หลังจากติดตั้ง library แล้ว มักจะมีตัวอย่างการใช้งาน library มาให้ด้วย และเป็นจุดเริ่มต้นที่ดีในการศึกษาการใช้ library นั้น ๆ ดังนั้น เราก็มาดูตัวอย่างกันเลย จากเมนู ให้ไปที่ File -> Examples -> AdafruitBME280 Library -> bme280test

//Comment

เมื่อเปิด code ตัวอย่าง เราต้องอ่านทั้ง comment และ code เพื่อให้เข้าใจว่า code ตัวอย่างนี้ถูกเขียนให้ใช้ hardware แบบไหน เช่น BME280 สามารถสื่อสารได้ทั้งแบบ I2C หรือ SPI แต่ใน code มักจะถูกเขียนให้เลือกใช้อย่างเดียว เราก็ต้องดูว่า code นั้นเลือกใช้การสื่อสารแบบไหน เหมือนกับที่เราต่อ hardware ไว้หรือไม่ เช่น ในระบบของเรา เราต่อ hardware เพื่อใช้ I2C อย่างน้อยเราก็ต้องดูให้แน่ใจว่า code ตัวอย่างนั้นใช้ I2C ด้วยเช่นกัน

เราเริ่มจาก comment ที่หัว file กันเลย จะเห็นว่า comment ก็บอกว่า ใช้ได้ทั้ง I2C หรือ SPI ถ้าเป็น I2C จะต้องใช้ address อะไรในการติดต่อกับ sensor และ อื่น ๆ ที่ผู้เขียนอยากจะสื่อสาร รวมทั้งใครเป็นคนเขียน code นี้ขึ้นมา และคนอื่น ๆ มีสิทธิใช้ code นี้แค่ไหนอย่างไร

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
  See the LICENSE file for details.
 ***************************************************************************/

#include

ส่วนต่อมา เป็นการรวม file ที่เป็น header (filename.h) ที่เป็นของ library ต่าง ๆ ที่ต้องใช้ รวมเข้ามาใน code นี้ด้วย ถ้าไม่รวมเข้ามา เราก็จะใช้ library เหล่านั้นไม่ได้ ในที่นี้ ก็มีการรวม header ของ Wire, SPI, Adafruit_Sensor และ Adafruit_BME280 เข้ามา ซึ่งใน file เหล่านี้จะมีการประกาศค่าต่าง ๆ ที่ใช้ใน library เช่น ค่าคงที่ หรือ function ต่างๆ ที่เราสามารถเรียกใช้ได้

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define

ส่วนต่อมา เป็นเรื่องของการ กำหนดค่าคงที่ต่าง ๆ ในส่วนแรก เป็นการกำหนดชื่อให้ขา 13, 12, 11, และ 10 แล้วหลังจากนี้จะอ้างถึงขาเหล่านนี้โดยใช้ชื้อพวกนี้แทนเลขขา ต่อมาเป็นการกำหนดชื่อให้กับค่าคงที่ตัวหนึ่ง

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

ส่วนต่อมา เป็นการประกาศตัว bme เป็นชนิด Adafruit_BME280 เสมือนว่า กำหนดให้ bme คือ sensor BME280 นั่นเอง โดยรายละเอียดของตัวแปรชนิดนี้จะอยู่ใน library ตรงนี้จะเห็นว่ามี 3 บรรทัด และ active เฉพาะบรรทัดแรก อีกสองบรรทัดถูก comment ไว้ ตรงนี้จะเป็นการเลือกว่า เราจะติดต่อสื่อสารกับ sensor แบบไหน โดยที่บรรทัดแรก เป็นการติดต่อแบบ I2C ซึ่งก็ตรงกับที่ต่อ hardware ไว้ บรรทัดที่สองเป็นแบบ SPI โดยใช้ hardware SPI ส่วนบรรทัดที่สามเป็นการติดต่อแบบ SPI แต่เป็นแบบ software SPI

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

ต่อมาเป็นการประกาศตัวแปร ชื่อ “delayTime” ก็น่าจะเอาไว้เก็บค่าเวลาที่จะให้ microcontroller หยุดนี่ง แต่ยังไม่กำหนดว่าให้เป็นค่าเท่าไร

unsigned long delayTime;

setup()

เริ่มด้วย เชื่อมต่อการสื่อสารกับ computer โดยใช้ฟังก์ชั้น Serial ที่ 9600 baud (baud คืออะไร) แล้วรอให้การเชื่อต่อเรียบร้อยก่อนที่จะไปต่อ จากตัวอย่างที่แล้ว “ก้าวที่สอง” ไม่มีคำสั่งนี้ เพราะหลังจากที่เราสั่งให้เริ่มการเชื่อมต่อแล้ว เราให้ microcontroller ทำอย่างอื่นต่อไปก่อนที่เราจะใช้การสื่อสาร จึงไม่จำเป็นต้องรอให้เชื่อมต่อเสร็จ แต่ในที่นี้ ตัวอย่างจะใช้การสื่อสารในคำสั่งต่อไปทันที เราจึงต้องให้ microcontroller หยุดรอให้การเชื่อมต่อเสร็จสิ้นก่อนที่จะเรียกใช้คำสั่งในการสื่อสารต่อไป

    Serial.begin(9600);
    while(!Serial);    // time to get serial running

เมื่อการเชื่อต่อเสร็จสิ้นแล้ว คำสั่งถัดมาคือ สั่งให้ microcontroller ส่งข้อมูล “BME280 test” กลับไปยัง computer ซึ่งจะแสดงที่หน้าต่าง serial monitor

    Serial.println(F("BME280 test"));

ต่อมาเป็น การประกาศตัวแปร status ขึ้นมา แล้วนำตัวแปรที่เพิ่งประกาศมารับค่าที่ส่งกลับมาจาก bme.begin() ซึ่งเป็นการสั่งให้เริ่มเตรียมพร้อมที่จะใช้งาน sensor BME280 (รายละเอียดของ function อยู่ใน library)

    unsigned status;
    
    // default settings
    status = bme.begin();  

แล้วตรวจดูว่า ผลที่ส่งมาให้กับ status เป็นอย่างไร ถ้าเริ่มเตรียมตัวไม่สำเร็จก็จะ ส่งข้อมูลใน if ไปที่ computer แล้วหยุดที่ while(1) delay10; ถ้าเข้าใจ ภาษา C ก็จะทราบว่า microcontroller จะหยุดอยู่ตรงนี้ ไม่ไปคำสั่งอื่นต่อแล้วจนกว่าจะถูก reset

    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }

ถ้าการเริ่มต้น ไม่มีปัญหาอะไร ก็จะส่งข้อมูล “–Default Test –” ไปที่แสดงที่ computer

    Serial.println("-- Default Test --");

กำหนดค่า 1000 ให้กับ ตัวแปร delayTime ซึ่งก่อนหน้านี้ไม่ได้กำหนด

    delayTime = 1000;

แล้วส่งบรรทัดว่าง ๆ 1 บรรทัดไปแสดงที่ computer

    Serial.println();

loop()

ใน loop นี้ไม่มีอะไรมากนอกจาก การเรียก function 2 คือ printValue() และ delay(1000) ซึ่งเป็นการสั่งให้หยุดนิ่ง 1000 ms ส่วน printValue() คืออะไร ก็ต้องไปดูรายละเอียดที่ function printValue() ที่อยู่ด้านล่าง

void loop() { 
    printValues();
    delay(delayTime);
}

printValues()

เริ่มแรกเป็นการส่งข้อมูล “Temperature = “ ไปที่ computer 

    Serial.print("Temperature = ");

ต่อมาเป็นการส่งข้อมูล bme.readTemperature() ไปที่ computer (รายละเอียดของคำสั่งนี้ก็อยู่ใน library) ซึ่งข้อมูลนี้ก็คือ ให้อ่านค่าอุณหภูมิจาก sensor ดังนั้นบรรทัดที่สองนี้จึงมีสองคำสั่งซ้อนกันอยู่ คืออ่านค่าอุณหภูมิจากsensor แล้ว ส่งให้ computer ด้วยคำสั่ง Serial.print() 

    Serial.print(bme.readTemperature());

จากนั้นก็ส่ง “ °C” ไปที่ computer 

    Serial.println(" °C");

สั่งเกตว่า คำสั่งสุดท้ายนี้ต่างจากสองคำสั่งก่อนหน้า คือ print() กับ println() โดยที่ print() เป็นการส่งข้อมูลที่อยู่ในวงเล็บเท่านั้น แต่ println() คือส่งข้อมูลในวงเล็บแล้วตามด้วยข้อมูลที่บอกให้ขึ้นบรรทัดใหม่ด้วย (‘\r’ และ ‘\n’) 

คำสั่งสามบรรทัดแรกนี้ เป็นชุดที่เป็นการส่งค่าอุณหภูมิไปให้ computer นั่นเอง แล้วมีการอ่านค่าอื่น ๆ แล้วส่งให้ computer ด้วย รูปแบบคำสั่งที่ซ้ำๆ กัน อีก 3 ชุด แล้วปิดท้ายด้วย การส่งข้อมูลให้ขึ้นบรรทัดใหม่

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();

Output

ให้กด upload แล้วดู output ที่ Serial monitor โดยกดที่เครื่องหมายคล้ายแว่นขยายที่มุมบนขวา หรือ ไปที่เมนู Tools -> Serial Monitor ก็จะได้หน้าต่าง Serial Monitor แล้ว ข้อมูลที่ส่งมาจาก microcontroller ก็จะมาแสดงที่นี่

BME280 output

สรุป

คราวนี้เราได้เรียนรู้

  1. เราสามารถใช้ library ช่วยในการติดต่อกับ sensor หรือ อุปกรณ์อื่น ๆ ได้
  2. เราสามารถเรียนรู้การใช้ library ต่าง ๆ จากตัวอย่างของ library เองได้
  3. เราสามารถส่งข้อมูลจาก microcontroller กลับไปที่ computer โดยใช้ Serial function ได้

ทุกคนสามารถใช้แนวทางนี้ในการศึกษาการต่อ sensor อื่น ๆ รวมทั้งอุปกรณ์อื่น ๆ ที่ไม่ใช่ sensorด้วย เช่น display ซึ่งจะทำให้อุปกรณ์ของเราน่าสนใจมากยิ่งขึ้น

อย่าลืมกด like ที่ Facebook Page เพื่อติดตามเรื่องราวใหม่ ๆ จากเรานะครับ

Posted on Leave a comment

การติดตั้ง Library (Arduino IDE)

ในการเขียนโปรแกรม เรามักต้องเรียกใช้ library ต่าง ๆ ดังนั้นในตอนนี้เรามาดูกันว่า การ ติดตั้ง library ให้กับ Arduino IDE ทำอย่างไร ก่อนอื่น เราต้องรู้ก่อนว่าเราจะใช้ library อะไร เช่น library ที่ช่วยในการสื่อสารกับ sensor ในตัวอย่างนี้เป็นการติดตั้ง library สำหรับติดต่อ หรือควบคุม sensor วันอุณหภูมิ ความชื่น และแรงดันอากาศ นั่นคือ BME280 เมื่อเรารู้ว่าเราจะติดตั้ง library สำหรับ sensor ตัวไหนแล้ว เราก็เริ่มทำการค้นหาและติดตั้งกันเลย

ขั้นแรก จากเมนูของ IDE ให้ไปที่ Tools -> Manage Libraries… หรือ กดที่รูปหนังสือที่ด้านซ้ายของ IDE จะมีช่องให้ค้นหาขึ้นมา

จากนั้นก็พิมพ์ key word ที่คิดว่าเกี่ยวกับ library ของเราแน่ ๆ ในที่นี้ก็คือ BME280 จะเห็นว่ามี library ที่เกี่ยวกับ BME280 ขึ้นมาหลายรายการ โดยมีชื่อ library ชื่อผู้ที่สร้าง library ขึ้นมา รายละเดียดเกี่ยวกับ library และ รุ่นของ library สิ่งที่เราต้องทำคือ ให้เราอ่านที่ รายละเอียดเกี่ยวกับ library ว่าใช่ที่เราต้องการหรือไม่ และผู้ที่สร้างขึ้นมาคือใคร แล้วเลือกที่เราไว้ใจได้ ในที่นี้จะเลือกของ Adafruit แล้วก็กด INSTALL ได้เลย 

หลังจากกด INSTALL แล้ว IDE อาจถามเราว่า จะลงแค่ library ตัวนี้ หรือตัวอื่นที่ต้องใช้ร่วมด้วย ให้เรากด INSTALL ALL ไม่อย่างนั้น อาจใช้งานไม่ได้ 

เมื่อติดตั้งเสร็จแล้ว ก็จะขึ้นว่า INSTALLED เราสามารถที่จะเปลี่ยนรุ่นของ library ได้ โดยการเลือก รุ่นแล้ว กด INSTALL อีกครั้ง หรือถ้าต้องการ uninstall หรือถอดการติดตั้ง ก็เลื่อน mouse ไปที่ INSTALLED มันก็จะเปลี่ยนเป็น UNINSTALL แล้วก็กดได้เลย มันก็จะถอดการติดตั้งออกให้ ก็เป็นอันว่าจบเรื่องการติดตั้ง library ลงใน Arduino IDE เพียงเท่านี้

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

อย่าลืมกด like ที่ page facebook เพื่อติดตามเรื่องราวใหม่ ๆ จากเรานะครับ

Posted on Leave a comment

Baud Rate กับ Bit Rate ต่างกันอย่างไร

หลายท่านอาจพอเข้าใจได้ว่า bit rate คืออะไร แต่แล้ว baud rate คืออะไร มันเหมือนกับ bit rate ไหม หรือต่างกันอย่างไร วันนี้เราจะมาดูความหมาย และลองเปรียบเทียบกันดูว่าเหมือนหรือต่างกันอย่างไร

Baud Rate

Baud หรือ baud rate คือจำนวนสัญญาณที่ส่งได้ใน 1 วินาที (เน้นว่า “สัญญาณ” นะครับ) โดยสัญญาณที่ว่านี้อาจเป็น ระดับแรงดันทางไฟฟ้า อาจเป็นความถี่ หรืออาจเป็น pattern หรืออะไรก็ได้ที่มีความหมายตรงกันสำหรับผู้ส่งและผู้รับ ถ้า ใน 1 วินาทีเราส่งได้ 5 สัญญาณ แสดงว่าเราส่งสัญญาณด้วยความเร็ว 5 สัญญาณต่อวินาที หรือ 5 baud

Bit Rate 

bit rate คือ จำนวนบิตที่ส่งได้ต่อวินาที (bit/s) สมมติว่า ใน 1 วินาที เราส่งข้อมูลได้ 5 bits เช่น “0” “1” “1” “0” “1” แสดงว่าเราส่งข้อมูลด้วยความเร็วที่ 5 bit/s หรือ 5 bps (bit per second)

ความสัมพันธ์

baud กับ bit rate อาจเท่ากันหรือไม่ก็ได้ เพื่อให้เข้าใจมากขึ้นลองพิจารณา 2 ตัวอย่างนี้ดูนะครับ

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

สมมติว่าการส่งข้อมูลในระบบ A เป็นการส่งข้อมูลผ่านสายไฟ โดยใช้ระดับแรงดันไฟฟ้าเป็นสัญญาณ และสัญญาณที่เป็นไปได้มีทั้งหมด 2 แบบคือ 0 V และ 5 V โดยทั้งฝ่ายผู้ส่งและผู้รับ เข้าใจความหมายตรงกันว่า 0V หมายถึงข้อมูล 0 และ 5V หมายถึงข้อมูล 1 ดังนั้น ถ้าต้องการส่งข้อมูล 4 bits “0101” ผู้ส่งก็ต้องส่งแรงดันไฟฟ้า 0V 5V 0V 5V ตามลำดับ ฝ่ายรับก็จะเข้าใจได้ว่า มีข้อมูล 4 bit ส่งมา คือ “0101”  ถ้าการส่ง 4 สัญญาณนี้ใช้เวลา 1 วินาที แสดงว่าระบบนี้ส่งสัญญาณด้วยความเร็ว 4 สัญญาณต่อวินาที หรือ 4 baud และถ้านับเป็น bit ก็จะได้ bit rate เท่ากับ 4 bit/s หรือ 4 bps นั่นเอง สังเกตว่า ตัวอย่างนี้ baud กับ bit rate มีค่าเท่ากัน

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

สมมติว่าการส่งข้อมูลในระบบ B เป็นการส่งข้อมูลผ่านสายไฟ โดยใช้ระดับแรงดันไฟฟ้าเป็นสัญญาณเหมือนระบบ A แต่ต่างกันตรงที่ ระบบ B มีสัญญาณหรือระดับแรงดันไฟฟ้าที่เป็นไปได้ทั้งหมด 4 แบบ คือ 0V 1V 2V และ 3V โดยทั้งฝ่ายผู้ส่งและผู้รับเข้าใจความหมายตรงกันว่าแรงดัน 0V หมายถึงข้อมูล “00” แรงดัน 1V หมายถึงข้อมูล “01” แรงดัน 2V หมายถึงข้อมูล “10” และแรงดัน 3V หมายถึงข้อมูล “11” ดังนั้น ถ้าระบบ B ต้องการส่งข้อมูล “0110”  ผู้ส่งต้องส่งแรงดันไฟฟ้า 1V 2V ตามลำดับ ผู้รับก็จะเข้าใจว่า มีข้อมูล “0110” ส่งมานั่นเอง แล้วถ้าสัญญาณทั้งสองนี้ใช้เวลาส่ง 1 วินาที แสดงว่าส่งสัญญาณด้วยความเร็ว 2 สัญญาณต่อวินาที หรือ 2 baud แล้วถ้านับเป็น bit rate ก็จะได้ 4 bps นั่นเอง สังเกตว่า ตัวอย่างนี้ baud กับ bit rate มีค่าไม่เท่า กัน

สรุป

เมื่อเราพูดถึง bit rate เรามักกำลังมองในมุมมองของข้อมูล ว่าเราส่งข้อมูลได้เร็วแค่ไหน โดยไม่สนใจว่าส่งอย่างไร หรือส่งทีละกี่บิต แต่เมื่อเราพูดถึง baud เรามักกำลังมองในมุมมองของสัญญาณที่ส่งในตัวกลาง ซึ่งอาจเป็นสายไฟ หรืออากาศ (ในกรณีที่เป็นแบบไร้สาย) ว่าเราส่งสัญญาณได้เร็วแค่ไหน โดยที่ไม่สนใจว่า 1 สัญญาณแทนข้อมูลกี่ bit อย่างไรก็ตามเราสามารถแปลงระหว่าง baud กับ bit rate ได้ หากเรารู้ว่า 1 สัญญาณแทนด้วยกี่ bit จะได้ bit rate = baud x (จำนวน bit ต่อ 1 สัญญาณ) นั่นเอง

ชวนคิด

จากตัวอย่างที่ 1 สงสัยหรือไม่ว่า ถ้าระบบต้องการส่ง “0011” แน่นอนว่า ผู้ส่งจะต้องส่ง 0V 0V 5V 5V ตามลำดับ แต่เนื่องจากไม่มีการเปลี่ยนแปลงของสัญญาณระหว่าง 0V ตัวแรก กับ 0V ตัวที่สอง และไม่มีการเปลี่ยนแปลงระหว่า 5V แรก กับ 5V ที่สองด้วยเช่นกัน แล้วผู้รับจะรู้ได้อย่างไรว่า ผู้ส่งกำลังส่ง “0011” หรือ ส่งแค่ “01” กันแน่

คำตอบคือ ไม่รู้ ดังนั้นเพื่อแก้ปัญหานี้ จึงต้องมีตัวช่วย เช่น มีสายสัญญาณเพิ่มมาอีกเส้น เพื่อบอกว่านี่เป็นข้อมูลตัวใหม่แล้วนะ ไม่ใช่ตัวเก่าแล้ว อย่างในระบบ synchronous serial communication หรือ ต้องมีการนัดแนะกันก่อนว่า เราจะส่งสัญญาณกันโดยที่แต่ละสัญญาณจะคงสภาพนั้นนานเท่าไร ถ้านานเกินกว่านั้นแปลว่า นี่เป็นสัญญาณตัวใหม่ที่เหมือนกับตัวก่อนหน้าอย่างในระบบ Asynchronous serial communication นั่นเอง

ศึกษาเพิ่มเติม

Posted on Leave a comment

Arduino Nano with Serial (ก้าวที่สอง)

หลังจากที่ผ่าน ก้าวแรก กันมาแล้ว คราวนี้มาทำความรู้จักกับอีกหนึ่ง function ที่สำคัญมากและใช้กันน่าจะทุกครั้งที่มีการเขียนโปรแกรมเลยทีเดียว นั่นคือ Serial ซึ่งเป็น function การสื่อสารผ่าน UART โดยในที่นี้จะเป็นการสื่อสารระหว่าง Arduino Nano กับ computer ผ่านทางสาย USB ที่ใช้ upload โปรแกรมนั่นเอง โดยส่งข้อมูลหรือสัญญาณเพื่อควบคุม Arduino Nano หรือให้ Arduino Nano ส่งข้อมูลกลับมาให้ computer โดยที่คราวนี้เราใช้ตัวอย่างที่มีอยู่ใน IDE ที่ชื่อว่า PhysicalPixel

อันดับแรกให้เปิด code ตัวอย่าง โดยไปที่ File -> Examples -> 04. Communication -> PhysicalPixel

แล้วลองอ่านในส่วนของ comment ดูจะพบว่า เป็น code ที่ควบคุมการเปิดปิด LED ที่ขา 13 ของ Arduino Nano ด้วยการส่ง H หรือ L จาก computer

Code ส่วนต่างๆ

การประกาศต่าง ๆ (พื้นที่ก่อนถึง setup())

มีการประกาศค่าตัวแปรสองตัว ตัวแรกคือ ledPin เป็นตัวแปร const (เปลี่ยนแปลงภายหลังจากที่ประกาศไม่ได้) ให้มีค่า 13 ก็คือหมายเลขของขาที่ต่อกับ LED

const int lidPin = 13;

ตัวที่สองคือ incomingByte คือตัวแปรที่ใช้เก็บข้อมูลที่ส่งมาจาก computer 

int incomingByte;

setup()

คำสั่งแรกใน setup() เป็นการสั่งให้เริ่มเชื่อมต่อกับ computer โดยกำหนด baud (ความเร็วในการส่งข้อมูล) ที่ 9600 baud

Serial.begin(9600);

การเริ่มการเชื่อมต่อนั้น เมื่อสั่งไปแล้วอาจต้องใช้เวลาสัก 2~3 วินาทีก่อนที่จะเชื่อมต่อเรียบร้อย จึงมักจะเขียนเป็นคำสั่งแรก ๆ

คำสั่งต่อมาน่าจะคุ้นเคยอยู่แล้ว นั่นคือกำหนดให้ขา 13 เป็น Output

pinMode(ledPin, OUTPUT);

loop()

คำสั่งแรกใน loop() เป็นการตรวจสอบว่า มีข้อมูลส่งเข้ามาหรือไม่ 

if (Serial.available() > 0)

ถ้ามีข้อมูลส่งเข้ามา ให้อ่านข้อมูลแล้วมาเก็บไว้ที่ ตัวแปร incommingByte ถ้าไม่มีก็วน loop มาตรวจสอบใหม่

incommingByte = Serial.read()

จากนั้นตรวจสอบว่า ข้อมูลที่อ่านเข้ามาคือ H หรือไม่

if (incommingByte == ‘H’)

ถ้าใช่ ก็ให้ส่ง High ออกไปที่ขา ledPin ถ้าไม่ใช่ก็ข้ามไป

digitalWrite(ledPin, HIGH);

จากนั้นตรวจสอบว่า ข้อมูลที่อ่านเข้ามาคือ L หรือไม่

if (incommingByte == ‘L’)

ถ้าใช่ก็ให้ส่ง Low ออกไปที่ขา ledPin แต่ถ้าไม่ใช่ก็ข้ามไป

digitalWrite(ledPin, LOW);

เมื่อทำเสร็จหมดแล้ว ก็กลับไปเริ่มที่คำสั่งแรกของ loop() อีกครั้ง

เมื่อเข้าใจ code แล้ว เราก็ลอง upload กันเลย จากนั้นก็กดที่ Serial monitor ที่มุมขวา (คล้ายแว่นขยาย) ก็จะได้หน้าต่าง Serial monitor ขึ้นมาด้านล่าง จากนั้นให้กำหนด baud ให้เป็น 9600 baud เหมือนที่เราตั้งไว้ใน code 

แล้วลอง พิมพ์ H ในช่อง Message แล้ว enter จะเห็นว่า LED ที่ Arduino Nano สว่างขึ้นมา ถ้ากด L แล้ว enter ก็จะดับไป คราวนี้ถ้าเป็น ตัวพิมพ์เล็กบ้างล่ะ จะเป็นอย่างไร ไม่มีการเปลี่ยนแปลงใช่ไหมล่ะครับ แล้วถ้ากดแป้นอื่น ๆ ดู จะเป็นอย่างไร ก็ไม่มีอะไรเปลี่ยนแปลงเหมือนเดิมใช่ไหม แสดงว่า การทำงานเป็นไปตามที่เราสั่งทุกอย่าง

ส่วนคำสั่งที่อยู่ใน comment ด้านล่างของ code เอาไว้ใช้กับโปรแกรม Processing หรือ Max/MSP อาจลองศึกษาเพิ่มเติมด้วยตัวเองดูนะครับ

สรุป

คราวนี้เราได้เรียนรู้การสื่อสารผ่านสาย USB โดยให้คำสั่งในกลุ่มของ Serial ซึ่งมีคำสั่งในกลุ่มนี้ที่น่าสนใจอีกหลายตัว ผู้อ่านสามารถศึกษาเพิ่มเติมได้จาก function reference ได้เลยนะครับ

แบบฝึกหัด

คราวนี้ลองคิดกันดูนะครับว่า 

  1. ถ้าอยากให้ใช้ h, l แทน H, L ล่ะ จะต้องปรับ code อย่างไร 
  2. ถ้าอยากให้ใช้ได้ทั้งตัวพิมพ์ใหญ่และพิมพ์เล็กต้องปรับ code อย่างไร ( guide: ลองศึกษาเรื่อง Boolean Operators ดูนะครับ)
  3. จากข้อ 2 ถ้าเราส่งตัวอักษรอื่นที่ไม่ใช่ทั้ง H, h, L หรือ l แล้วให้ Arduino Nano ส่งข้อความกลับมาที่ Serial monitor เพื่อบอกเราว่า ระบบรองรับแค่ H, h, L หรือ l เท่านั้นนะ จะต้องปรับ codeอย่างไร ( guide: ลองศึกษา function ในกลุ่มของ Serial เพิ่มเติมดูนะครับ)

ขอแนะนำว่า เวลาเขียน code ในระดับเริ่มต้นนี้ ยังไม่ต้องกังวลว่า code จะสวยหรือไม่ เร็วที่สุดหรือไม่ ใช้ memory น้อยที่สุดแล้วหรือไม่ ขอแค่ทำได้ตามที่เราต้องการ และอ่านเข้าใจง่าย ก็ถือว่าดีมากแล้ว เพียงเท่านี้ เราก็สามารถควบคุมการเปิดปิด LED ที่ต่อกับ Arduino Nano จาก computer ผ่านสาย USB ได้แล้ว ไม่ยากเลยใช่ไหมล่ะครับ

ศึกษาเพิ่มเติม

Posted on Leave a comment

Library (programming) คืออะไร

ในการเขียนโปรแกรม Library หมายถึง code ที่ถูกเขียนเตรียมไว้ โดยที่ programmer สามารถเรียกใช้งาน code ส่วนนี้ได้โดยไม่ต้องเขียนซ้ำ หรือไม่ต้องเขียนเอง เพียงแค่บอกกับ compiler ว่า ให้รวม code ที่อยู่ใน library เข้ามาใน code ของเราด้วย ซึ่งถ้าเป็นภาษา C/C++ ก็จะใช้คำสั่ง #include “filename” โดยที่ filename คือชื่อ file ที่มี code ที่เตรียมไว้

ดังนั้น library จึงมักเป็น code ที่มักถูกเขียนซ้ำๆ หรือ code ที่มีความซับซ้อน หรือ ต้องใช้ความรู้เฉพาะทาง เพื่อลดงานให้กับ programmer จึงได้มีการทำ code และนำมาจัดกลุ่มให้เข้าใจง่าย และสามารถเรียกใช้ได้ถ้าต้องการ เรียกว่า library นั่นเอง

Posted on Leave a comment

IDE: Integrated Development Environment คืออะไร

IDE หรือ Integrated Development Environment คือ software ที่รวมเอา software ที่จำเป็นในการเขียนโปรแกรมมาอยู่ในที่เดียวกัน นั่นคือ โดยปกติแล้วเวลาที่เราจะเขียนโปแกรมอะไรสักอย่างนั้น เราต้องใช้ software หลายตัวร่วมด้วยช่วยกัน เช่น 

  1. text editor คือ software ที่เราใช้เขียน code โดยใช้ software อะไรก็ได้ ที่เขียนตัวหนังสือลงไปได้
  2. compiler คือ software ที่ทำหน้าที่ แปลภาษาที่เราเขียน ซึ่งอาจเป็นภาษา c/c++ หรือภาษาอื่น ๆ ให้เป็นภาษาเครื่อง ที่ computer หรือ microcontroller เข้าใจ ซึ่ง compiler ก็มีหลายตัว ขึ้นอยู่กับว่าเราจะเขียนภาษาอะไร และ โปรแกรมที่เราเขียนนั้นจะไปใช้บนอะไร หรือ microcontroller ตัวไหน
  3. linker คือ software ที่ทำหน้าที่เชื่อม code ที่ compile แล้วเข้าด้วยกันในกรณีที่เราใช้ library 
  4. uploader หรือ programmer คือ software ที่ทำหน้าที่ upload code ที่ compile และ link เสร็จเรียบร้อยแล้ว ใส่เข้าไปใน microcontroller
  5. debugger คือ software ที่ทำหน้าที่ช่วยให้เราเห็น register หรือ memory หรือ สถานการณ์ทำงานของโปรแกรมที่เราเขียนว่าทำงานอย่างไร ช่วยให้เราหาจุดบกพร่องและแก้ปัญหาได้ง่ายขึ้น

ในบางระบบ อาจมีมากกว่าหรือน้อยกว่านี้บ้าง จะเห็นว่ากว่าจะเขียนโปรแกรมจนใช้งานได้นั้นมีขั้นตอน และ software ที่เกี่ยวข้องหลายตัว ดังนั้นเพื่อความสะดวกจึงได้มีการสร้าง software เพื่อรวมการเรียกใช้ software เหล่านี้เข้าด้วยกัน ซึ่งก็คือ IDE หรือ Integrated Development Environment นั่นเอง

Posted on Leave a comment

Microcontroller ก้าวแรก

หลังจากที่เราแนะนำ Arduino Nano คืออะไร มาก่อนหน้านี้แล้ว คราวนี้เราจะมาลองใช้กันจริง ๆ ว่าการใช้งานเป็นอย่างไร

สิ่งที่ต้องมี

  1. บอร์ดควบคุม Arduino Nano หรือ Arduino Nano compatible
  2. โปรแกรม Arduino IDE โดยใช้ version 1.8.19 หรือ version 2.x ก็ได้ แต่ในตัวอย่างจะใช้ 2.0.2 (IDE คืออะไร)
  3. สายเชื่อมต่อระหว่าง computer และ บอร์ดควบคุม

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

หลังจากลองสำรวจคร่าว ๆ แล้ว เราก็มาเริ่มกันเลย

  1. เริ่มแรกให้เปิดโปรแกรม Arduino IDE ขึ้นมา จะเจอกับหน้าว่าง ๆ ที่มี 2 ฟังก์ชั้นคือ setup() กับ loop()
  2. ต่อบอร์ด microcontroller เข้ากับ computer แล้วเลือก Arduino Nano ถ้าไม่มีให้เลือกให้ไปข้อ 3 ถ้ามีให้เลือกให้ไปที่ข้อ 4 ได้เลย
  3. กดที่เครื่องหมายสามเหลี่ยม เพื่อดูว่ามีอะไรบ้าง แล้วถอดสาย Arduino Nano สัก 5 วินาทีแล้วต่อกับ computer อีกครั้ง แล้วดูว่า มีอะไรหายไปตอนถอดและกลับเข้ามาตอนเสียบ ให้เลือกอันนั้น แล้วเลือก Arduino Nano แล้วกด OK (ตัว clone ให้เลือกเหมือนตัวจริง)
  4. ถ้าทุกอย่างเรียบร้อยดี เราจะได้ ชื่อ Arduino Nano และมีสัญลักษณ์ USB อยู่ข้างหน้า
  5. กดที่ลูกศร ซึ่งจะเป็นการ compile โปรแกรม และ upload โปรแกรมที่ compile แล้วไปใส่ใน Arduino Nano ระหว่างนั้น ตัว IDE ก็จะแสดง output ของการ compile และการ upload ที่หน้าต่าง output ส่วนที่ตัว Arduino Nano ก็จะเห็นว่ามี LED สว่างดวงเดียวนิ่งๆ ซึ่งก็ถูกแล้ว เพราะทั้งใน setup() และ loop() ไม่มีคำสั่งอะไร board ก็ไม่ทำอะไรนั่นเอง ส่วน LED ที่สว่างอยู่ดวงเดียวนั้น แสดงว่ามีไฟเลี้ยงบอร์ดอยู่เท่านั้นเอง ถ้าของใครมีปัญหา ขึ้นตัวแดงๆ ในหน้าต่าง Output ให้ไปข้อ 6 ถ้าไม่มีปัญหาให้ไปข้อ 7
  6. สำหรับคนที่ขึ้นตัวแดงว่า “avrdude: stk500_recv(): programmer is not responding” อาจเป็นเพราะว่าใช้ Bootloader คนละ version ให้ลองไปเปลี่ยนที่เมนู Tools -> Processor -> แล้วเลือก ATmega328P ตัวที่ยังไม่ได้เลือก แล้วกด compile และ upload อีกครั้ง
  7. ต่อไปจะเป็นการใส่โปรแกรมจริงๆลงไป โดยไปที่เมนู file -> examples -> 01_Basic -> Blink นี่เป็นการเปิด code ตัวอย่างขึ้นมา ตอนนี้ถึงจะขอให้ดูอะไรก็คงไม่สนใจแล้ว อยากกด compile และ upload กันแล้วใช่ไหมครับ (บางคนอาจกดแล้วด้วยซ้ำ) ถ้าอย่างนั้น กดเลยครับ!! เมื่อ upload เสร็จ เราจะเห็น LED ที่ บอร์ด Arduino Nano อีกดวงกะพริบเหมือนอย่างที่ชื่อบอก (Blink) เย้!!!! ถึงตอนนี้ เราสามารถถอดบอร์ด Arduino Nano ออกจาก computer แล้วนำไปต่อกับ charger หรือ power bank เพื่อจ่ายไฟเข้าบอร์ด แล้วเราก็จะเห็น LED กะพริบ นั่นคือโปรแกรมที่เรา upload เข้าไปเมื่อสักครู่ และมันจะอยู่จนกว่าจะ upload โปรแกรมอื่นลงไปใหม่นั่นเอง
  8. คราวนี้ให้เราลองสำรวจดูว่ามีอะไรใน Blink บ้าง จะเห็นว่า มีเนื้อหาแบ่งได้เป็นสองส่วนหลัก ๆ คือ ส่วนที่เป็นตัวหนังสือสีเทาที่อยู่ระหว่าง /* กับ */ หรือ อยู่หลัง //  ส่วนสีเทานี้เรียกว่า comment กับส่วนที่ไม่เป็นสีเทา เรียกว่า code โดยที่ส่วนที่เป็น comment เป็นส่วนที่เขียนไว้เพื่อให้คนอ่าน microcontroller จะไม่รับรู้ในส่วนนี้ microcontroller จะรับรู้เฉพาะส่วนที่เป็น code เท่านั้น คนที่เขียน code จะเขียน comment เพื่อสื่อสารกับคนอื่นว่า โปรแกรมนี้มีไว้เพื่ออะไร หรือแต่ละส่วนทำงานอย่างไร หรืออาจเขียนไว้เพื่อเตือนความจำตัวเองเฉย ๆ ก็ได้ ตัวอย่างของ Blink นี้ ในส่วนแรก ก็เป็น comment ที่บอกว่า code นี้ใช้ทำอะไร ใช้กับอุปกรณ์ตัวไหนได้บ้าง ใช้ port ไหนบ้าง ถูกเขียนขึ้นโดยใคร และเมื่อไร หรืออื่นๆที่อยากจะสื่อสารเลยครับ
  9. คราวนี้ลองมาดูในส่วนของ code กันบ้าง จะเห็นว่า แบ่งเป็นสองส่วน หรือ สองฟังก์ชั่น คือ setup() และ loop() ถ้าใครเคยอ่านเรื่อง Microcontroller ทำงานอย่างไร ก็คงจะพอเข้าใจว่ามันหมายถึงอะไร ทบทวนง่าย ๆ ก็คือ ส่วนที่เป็น setup() นั้นจะทำงานครั้งเดียว ในขณะที่ loop() นั้น จะทำงานซ้ำๆ ไปเรื่อยๆ ไม่มีวันจบ จนกว่าจะกด reset ระบบก็จะทำงานที่ setup() อีกครั้ง แล้วก็มาวนที่ loop() เหมือนเดิม โดยมีรายละเอียดดังนี้
    • setup() นั้นจะมีคำสั่งเดียว คือ pinMode(LED_BUILTIN, OUTPUT); นี่คือคำสั่งที่กำหนดให้ ขาที่ชื่อ LED_BUILTIN ทำหน้าที่เป็น OUTPUT เนื่องจากขานี้เป็นได้ทั้งขา INPUT (รับข้อมูลเข้ามา) หรือ OUTPUT (ส่งข้อมูลออกไป) ดังนั้นก่อนจะใช้งาน เราต้องกำหนดเสียก่อนว่าจะใช้เป็น INPUT หรือ OUTPUT จะเห็นว่า การกำหนดหน้าที่ให้ LED_BUILTIN เป็น OUTPUT นั้น เราสั่งครั้งเดียวก็พอ แล้วไม่ต้องสั่งอีก หลังจากนี้ก็แค่สั่งให้ output เป็น 1 (HIGH) หรือ เป็น 0 (LOW) แค่นั้น ดังนั้น การกำหนดให้ขานี้เป็น OUTPUT นั้นจึงเขียนไว้ใน setup() ก็เหมาะสมดีแล้ว แต่หาก เราอยากให้ขานี้เปลี่ยนเป็น OUTPUT บ้าง INPUT บ้าง เราก็ต้องนำไปเขียนใน loop() นั่นเอง แต่มักจะไม่ทำอย่างนั้นถ้าไม่จำเป็น มักจะหาขาอื่นเป็น input จะดีกว่า เพราะยิ่งคำสั่งมากขึ้น ก็ยิ่งซับซ้อนมากขึ้น มีโอกาสผิดพลาดมากขึ้น และเสียเวลามากขึ้น และอาจมีข้อจำกัดอื่น ๆ ที่ต้องระวังอีก code ที่ดีต้องอ่านแล้วเข้าใจง่าย
    • Loop() คำสั่งในนี้จะถูกเรียกซ้ำวนไปเรื่อยๆ
      • คำสั่งแรกคือ digitalWrite(LED_BUILTIN, HIGH); ถ้าอ่านจาก comment ด้านหลังคำสั่งนี้ก็คงเข้าใจได้ว่า เป็นการส่ง HIGH หรือ 1 ออกไปให้ LED ซึ่งก็จะทำให้ LED สว่างนั่นเอง
      • คำสั่งที่สองคือ delay(1000); คือให้ controller หยุดนิ่ง ไม่ทำอะไรเลยเป็นเวลา 1000 ms หรือ 1 วินาที
      • คำสั่งที่สามคือ dititalWrite(LED_BUILTIN, LO); ใช่ครับ คือสั่งให้ส่ง LOW หรือ 0 ออกไปให้ LED ก็จะทำให้ LED ดับนั่นเอง
      • คำสั่งที่สี่ คือ delay(1000); ก็ให้หยุดนิ่ง 1 วินาทีอีกครั้ง
  10. หลังจากที่คิดว่าเข้าใจคำสั่งต่างๆแล้ว ลองเปลี่ยนคำว่า LED_BUILTIN ทั้ง 3 ที่ ให้เป็น 13 แล้ว กด compile และ upload ดู จะเห็นว่า ผลเหมือนกัน นั่นคือ LED_BUILTIN คือ ขา 13 (D13) นั่นเอง ซึ่งถ้าเคยอ่านเรื่อง Arduino Nano คืออะไร ก็จะรู้ว่า จะมี LED ต่ออยู่กับขา D13 ของ board (D คือ Digital)

หวังว่า ผู้อ่านจะเห็นภาพรวมการเขียนโปรแกรมและ upload โปรแกรมลงบอร์ด Arduino Nano กันแล้วนะครับใครสนใจอยากรู้ว่า นอกจากคำสั่งในตัวอย่างนี้แล้ว มีคำสั่งอะไรให้ใช้บ้าง ลองเข้าไปดูรายละเอียดได้ที่ Language Reference ได้นะครับ

แบบฝึกหัด

สุดท้ายนี้อยากให้ลอง แก้ code ให้ LED กะพริบ โดยสว่างครึ่งวินาที และดับครึ่งวินาทีดูนะครับ หวังว่าจะสนุกนะครับ แล้วพบกันใหม่

แนวทางการเรียนรู้เพิ่มเติม

สิ่งสำคัญอย่างหนึ่งคือ ภาษาที่ใช้ในการเขียนโปรแกม ภาษา C/C++ เป็นภาษาที่ใช้กันมายาวนาน และน่าจะอยู่ไปอีกนานเช่นกัน โดยมีแหล่งความรู้มากมายให้เลือก เช่น w3schools หรือ ลองศึกษาจากตัวอย่างใน IDE เหมือนในตัวอย่างนี้ ซึ่งก็มีตัวอย่างที่น่าสนใจหลายอย่าง หรืออาจค้นหาตัวอย่างที่น่าสนใจใน internet ซึ่งมีให้เลือกมากมายเลยทีเดียว

Posted on Leave a comment

Firmware คืออะไร

Firmware คือโปรแกรมที่ฝังอยู่ที่ Hardware (หรือ เครื่องใช้ไฟฟ้า) ที่ทำให้ Hardware ทำงานได้ตามจุดประสงค์ที่ Hardware นั้นถูกสร้างขึ้น โดยไม่ต้องการ Software อะไรเพิ่ม เช่น เครื่องซักผ้า ไมโครเวฟ นาฬิกา เป็นต้น สิ่งเหล่านี้ก็จะมี โปรแกรมที่เรียกว่า Firmware คอยควบคุมให้ทำงานตามหน้าที่ของมัน

การที่เราเขียนโปรแกรมสั่งให้ Arduino Nano กะพริบ LED หรือ อ่านค่าของ sensor แล้วแสดงออกที่ display โปรแกรมนั้นก็คือ Firmware นั่นเอง