M5StickCで新型コロナウイルス接触確認アプリが周囲に何個あるか数えてみるデバイスを作ってみます
例によってM5Stack,AtomMatrix,ESP32 dev kitなどESP32搭載デバイスなら表示部分を変更すればなんでも作れます
##デバイスの紹介##
M5StickC - スイッチサイエンス
https://www.switch-science.com/catalog/5517/
Arduino互換なESP32がケースに入っててボタンとディスプレイとバッテリーがついててWifiとBluetoothも使える欲張りセット
ATOM Matrix - スイッチサイエンス
https://www.switch-science.com/catalog/6260/
M5シリーズの小さい奴でMatrixは5x5のneopixel LEDが搭載されています
今回はこのMatrixでも数字を表示します
##コードの作成##
ミクミンPさん https://twitter.com/ksasao が新型コロナウイルス接触確認アプリを検出するスケッチを作られていましたのでそちらを参照します
M5ATOM で接触確認アプリが有効かどうかを調べるやつをつくった。有効だと素早く点滅する。モバイルバッテリーで動作。 pic.twitter.com/aOdHc8Z5B6
— ミクミンP/Kazuhiro Sasao (@ksasao) June 20, 2020
接触確認アプリが有効になっているかを調べるアプリです
GitHub
https://gist.github.com/ksasao/0da6437d3eac9b2dbd675b6fee5d1117
ソース上の流れとしては
pBLEScan->start(scanTime, false)実行
↓
BLEAdvertisedDeviceCallbacksがBLEデバイスの数だけ実行されるのでUUIDを数える
↓
start()から復帰する
という流れになりますのでBLEAdvertisedDeviceCallbacksの中で特定のUUIDが何個あるのか数えます
RSSI(電波強度?)は無視して自分のデバイスを含めた数を表示します
// 接触確認アプリのUUID
const char* uuid = "0000fd6f-0000-1000-8000-00805f9b34fb";
int deviceNum = 0;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if(advertisedDevice.haveServiceUUID()){
if(strncmp(advertisedDevice.getServiceUUID().toString().c_str(),uuid, 36) == 0){
// 該当のUUIDならdeviceNumを++
int rssi = advertisedDevice.getRSSI();
Serial.print("RSSI: ");
Serial.println(rssi);
Serial.print("ADDR: ");
Serial.println(advertisedDevice.getAddress().toString().c_str());
Serial.println("Found!");
deviceNum++;
}
}
}
};
void loop() {
deviceNum = 0;
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
pBLEScan->clearResults();
// 画面描画処理を書く
drawScreen();
}
##画面に数を表示する##
M5StickCで表示します
自分はこのようにしてますがお好みで変更してください
M5.Lcd.setRotation(1);
の数字を変えると画面の向きが変わるので縦画面にもできます
void drawScreen() {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextColor(RED);
M5.Lcd.print("COCOA Counter\n");
M5.Lcd.setTextSize(7);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.printf(" %2d",deviceNum); // 接触確認アプリの数
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(0, M5.Lcd.height() - 10);
// バッテリの電圧(3.3V近くになると電源が切れます)
M5.Lcd.printf("Bat:%5.1fV ", M5.Axp.GetBatVoltage());
// バッテリの充電状態(満充電になると0になります)
M5.Lcd.printf("Charge:%5.1f\n",
M5.Axp.GetBatCurrent());
}
##つまりどういうことだってばよ?##
今までのをことを踏まえてM5StickCで新型コロナウイルス接触確認アプリが周囲に何個あるか数えてみます
M5と描かれたボタンを押すと電源が切れます
#include <Arduino.h>
#include <M5StickC.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 4; //BLEタイムアウト
BLEScan* pBLEScan;
// 接触確認アプリのUUID
const char* uuid = "0000fd6f-0000-1000-8000-00805f9b34fb";
int deviceNum = 0;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if(advertisedDevice.haveServiceUUID()){
if(strncmp(advertisedDevice.getServiceUUID().toString().c_str(),uuid, 36) == 0){
int rssi = advertisedDevice.getRSSI();
Serial.print("RSSI: ");
Serial.println(rssi);
Serial.print("ADDR: ");
Serial.println(advertisedDevice.getAddress().toString().c_str());
Serial.println("Found!");
deviceNum++;
}
}
}
};
void drawScreen() {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextColor(RED);
M5.Lcd.print("COCOA Counter\n");
M5.Lcd.setTextSize(7);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.printf(" %2d",deviceNum);
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(0, M5.Lcd.height() - 10);
M5.Lcd.printf("Bat:%5.1fV ", M5.Axp.GetBatVoltage());
M5.Lcd.printf("Charge:%5.1f\n", M5.Axp.GetBatCurrent());
}
void Task1(void *pvParameters) {
// loop()に書くとBLEスキャン中M5.update()が実行されなくてボタンが取れないのでマルチスレッド化している
while(1) {
deviceNum = 0;
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(deviceNum);
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
drawScreen();
}
}
void setup() {
M5.begin();
Serial.begin(115200);
M5.Lcd.setRotation(1);
M5.Axp.ScreenBreath(8);
M5.Lcd.fillScreen(BLACK);
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(5000); // スキャン間隔5秒
pBLEScan->setWindow(4999); // less or equal setInterval value
xTaskCreatePinnedToCore(Task1,"Task1", 4096, NULL, 3, NULL, 1);
}
void loop() {
M5.update();
if ( M5.BtnA.wasReleased() ) {
M5.Axp.PowerOff();
}
}
##Atom Matrixに数を表示する##
Atom Matrixにパターンを表示するにはLEDのパターンを配列で用意します 公式で用意されてるWindowsアプリを利用しますミクミンPさんのソースコード改変して近くに接触確認アプリが何個あるか表示できたよー
— もけ@ムギ㌠ (@coppercele) June 21, 2020
強度関係なしに特定のUUIDが何個あるか数えてるだけです pic.twitter.com/tLxZQAUtZB
GitHub - m5stack/M5Atom: M5Stack Atom Arduino Library
https://github.com/m5stack/M5Atom
内の
Atom pixel toolを使います
図形を書いてからTOOLS>SAVEを実行するとファイルに保存できます
// File URLZ:/0.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_0[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
この配列をM5.dis.Displaybuff()に渡すとLED Matrixに表示できます
extern const unsigned char image_0[77]; // 0.cファイル内に定義されてる配列
M5.dis.displaybuff((uint8_t*)image_0,0,0);
なので数字の数だけファイルを作成して用意しておきます
スーパーで試してみたら自分以外に二人いたようです
Atom Matrix Ver
#include <M5Atom.h>
#include <BLEDevice.h>
// 各数字の配列データ 10以上は+で表示
extern const unsigned char image_0[77];
extern const unsigned char image_1[77];
extern const unsigned char image_2[77];
extern const unsigned char image_3[77];
extern const unsigned char image_4[77];
extern const unsigned char image_5[77];
extern const unsigned char image_6[77];
extern const unsigned char image_7[77];
extern const unsigned char image_8[77];
extern const unsigned char image_9[77];
extern const unsigned char image_plus[77];
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 4; //BLEタイムアウト
BLEScan* pBLEScan;
// 接触確認アプリのUUID
const char* uuid = "0000fd6f-0000-1000-8000-00805f9b34fb";
int deviceNum = 0;
bool dark = false;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if(advertisedDevice.haveServiceUUID()){
if(strncmp(advertisedDevice.getServiceUUID().toString().c_str(),uuid, 36) == 0){
int rssi = advertisedDevice.getRSSI();
Serial.print("RSSI: ");
Serial.println(rssi);
Serial.print("ADDR: ");
Serial.println(advertisedDevice.getAddress().toString().c_str());
Serial.println("Found!");
deviceNum++;
}
}
}
};
void Task1(void *pvParameters) {
// loop()内にdelay()を書くとM5.update()が実行されなくてボタンが取れないのでマルチスレッド化している
while(1) {
deviceNum = 0;
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
switch (deviceNum) {
case 0:
M5.dis.displaybuff((uint8_t*)image_0,0,0);
break;
case 1:
M5.dis.displaybuff((uint8_t*)image_1,0,0);
break;
case 2:
M5.dis.displaybuff((uint8_t*)image_2,0,0);
break;
case 3:
M5.dis.displaybuff((uint8_t*)image_3,0,0);
break;
case 4:
M5.dis.displaybuff((uint8_t*)image_4,0,0);
break;
case 5:
M5.dis.displaybuff((uint8_t*)image_5,0,0);
break;
case 6:
M5.dis.displaybuff((uint8_t*)image_6,0,0);
break;
case 7:
M5.dis.displaybuff((uint8_t*)image_7,0,0);
break;
case 8:
M5.dis.displaybuff((uint8_t*)image_8,0,0);
break;
case 9:
M5.dis.displaybuff((uint8_t*)image_9,0,0);
break;
default:
M5.dis.displaybuff((uint8_t*)image_plus,0,0);
break;
}
M5.dis.setBrightness(dark ? 3 : 10);
Serial.print("Devices found: ");
Serial.println(deviceNum);
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000); // LEDの点灯時間
M5.dis.clear();
}
}
void setup() {
M5.begin(true, false, true);
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
xTaskCreatePinnedToCore(Task1,"Task1", 4096, NULL, 3, NULL, 1);
}
void loop() {
M5.update();
if ( M5.Btn.wasReleased() ) {
// ボタンを押すと明るさチェンジ
Serial.printf("brightness=%d",dark ? 3 : 10);
dark = !dark;
}
}
おまけ:数字のマトリクス配列
num.c
// File URLZ:/0.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_0[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/1.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_1[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};
// File URLZ:/2.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_2[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 004 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, //
};
// File URLZ:/3.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_3[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/4.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_4[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};
// File URLZ:/5.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_5[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/Temp/RarSFX0/6.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_6[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/Temp/RarSFX0/7.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_7[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, //
/* Line 001 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};
// File URLZ:/Temp/RarSFX0/8.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_8[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 003 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/Temp/RarSFX0/9.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_9[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0xaa,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 002 */ 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xaa,0xff, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0xaa,0xff, 0x00,0x00,0x00, //
};
// File URLZ:/Temp/RarSFX0/plus.c
// Image Size: width=5,height=5
// Data Size: 77
const unsigned char image_plus[77]=
{
/* width 005 */ 0x05,
/* height 005 */ 0x05,
/* Line 000 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xc4, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 001 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xc4, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 002 */ 0xff,0x00,0xc4, 0xff,0x00,0xc4, 0xff,0x00,0xc4, 0xff,0x00,0xc4, 0xff,0x00,0xc4, //
/* Line 003 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xc4, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line 004 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xc4, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};