NRF вроде как поддерживает аппаратно контроль целостности передаваемых данных, только не знаю поддерживается ли это ардуиновской библиотекой.необходимость контроля целостности передачи,
NRF вроде как поддерживает аппаратно контроль целостности передаваемых данных, только не знаю поддерживается ли это ардуиновской библиотекой.необходимость контроля целостности передачи,
Можно хоть 1мс. Лишь бы передача успевала отправлять.На глаз даже не заметно.Каждые 20мс, тогда задержка будет в +20мс.
Тут жеж получается что нажатие одной кнопки блокирует другие,ниже расположеные в коде.Код gamepad SEGA c nrf24l01
мерцания лампы накаливания вы не видите не потому, что не можете уловить 50 Гц, а в основном потому, что нить лампы за 20мс просто не успевает погаснуть.20мс это 50 Гц. Кто различит отдельные мерцания лампы накаливания?)))
150 мсек это 0,15 секунды. Если я Вас правильно понял. Это чуть менее 7 Герц. Человек различает картинку со сменой кадров вплоть до 300 герц. Но задержек в 20 мкс вполне достаточно для управления в рассматриваемом случае. А вот почему так, сильно долго объяснять и мало кому будет интересно.@te238s, 20мсек - за глаза. У человека средняя реакция на визуальный раздражитель - 150-300мсек, а если еще с распознаванием типа раздражителя - и того больше. Я не понимаю людей, которые гонятся за около-нулевой задержки ввода.
Именно. Коряво выражаясь,пальцы так не могут быстро на кнопки нажиматьА в самодельном пульте оно мало критично и соответственно совсем не нужно.
В принципе так и выходит. Около 150мкс без подтверждения приёма на скорости 2 Мбит/с и spi на 10МГц(что нереально на авр). Да и то,в теории. Никто не знает какие там микросхемы,Китай или КитайПишут что максимум у nrf24l01 около 6500 пакетов в секунду.
Да, я тоже печатаю 1534 знака в минуту, но такая хня выхордит! (с)Около 150мкс без подтверждения приёма на скорости 2 Мбит/с
Ну да, так и получается, пока одна зажата вторую не нажмёшьТут жеж получается что нажатие одной кнопки блокирует другие,ниже расположеные в коде.
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10);
#define UP_OR_Z 2
#define DOWN_OR_Y 3
#define LEFT_OR_X 4
#define RIGHT_OR_MODE 5
#define B_OR_A 6
#define SEL 7
#define C_OR_START 8
bool sega_up = false;
bool sega_down = false;
bool sega_left = false;
bool sega_right = false;
bool sega_start = false;
bool sega_mode = false;
bool sega_a = false;
bool sega_b = false;
bool sega_c = false;
bool sega_x = false;
bool sega_y = false;
bool sega_z = false;
byte up, down, left, right, start, mode, a, b, c, x, y, z;
byte batton_transmit[12];
void segaRead() {
digitalWrite(SEL, HIGH);
sega_up = (digitalRead(UP_OR_Z) == LOW);
sega_left = (digitalRead(LEFT_OR_X) == LOW);
sega_right = (digitalRead(RIGHT_OR_MODE) == LOW);
sega_down = (digitalRead(DOWN_OR_Y) == LOW);
sega_c = (digitalRead(C_OR_START) == LOW);
sega_b = (digitalRead(B_OR_A) == LOW);
digitalWrite(SEL, LOW);
sega_a = (digitalRead(B_OR_A) == LOW);
sega_start = (digitalRead(C_OR_START) == LOW);
digitalWrite(SEL, HIGH);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
sega_x = (digitalRead(LEFT_OR_X) == LOW);
sega_y = (digitalRead(DOWN_OR_Y) == LOW);
sega_z = (digitalRead(UP_OR_Z) == LOW);
sega_mode = (digitalRead(RIGHT_OR_MODE) == LOW);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
}
void batton_byte () {
up = sega_up;
left = sega_left;
right = sega_right;
down = sega_down;
start = sega_start;
mode = sega_mode;
a = sega_a;
b = sega_b;
c = sega_c;
x = sega_x;
y = sega_y;
z = sega_z;
}
void setup() {
radio.begin();
radio.setChannel(0x70);
radio.setPALevel (RF24_PA_MAX);
radio.setDataRate (RF24_1MBPS);
radio.openWritingPipe(0x0123456789LL);
radio.powerUp();
radio.stopListening();
pinMode(SEL, OUTPUT);
pinMode(UP_OR_Z, INPUT);
pinMode(DOWN_OR_Y, INPUT);
pinMode(LEFT_OR_X, INPUT);
pinMode(RIGHT_OR_MODE, INPUT);
pinMode(B_OR_A, INPUT);
pinMode(C_OR_START, INPUT);
}
void loop() {
segaRead();
batton_byte();
{
batton_transmit[0] = up;
batton_transmit[1] = left;
batton_transmit[2] = right;
batton_transmit[3] = down;
batton_transmit[4] = start;
batton_transmit[5] = mode;
batton_transmit[6] = a;
batton_transmit[7] = b;
batton_transmit[8] = c;
batton_transmit[9] = x;
batton_transmit[10] = y;
batton_transmit[11] = z;
radio.write(&batton_transmit, sizeof(batton_transmit));
delay(20);
}
}
Ну зачем? Зачем долбить максимальной мощностью для устройства которое по сути находится на паре метров дистанции? Минимальной мощности для домашних устройств - за глаза, да и потребление гораздо меньше будет.radio.setPALevel (RF24_PA_MAX);
О,уже более унивесальный алгоритм. А что за нюансы?Вот что у меня получилось,
но есть нюансы.
Ну я не совсем для домашнего устройства делаю. Машинка RC и на улице может эксплуатироваться.Ну зачем? Зачем долбить максимальной мощностью для устройства которое по сути находится на паре метров дистанции? Минимальной мощности для домашних устройств - за глаза, да и потребление гораздо меньше будет.
Попробовал ещё дописать режим энергоэкономии, как у Гайвера в "заметках ардуинщика".О,уже более унивесальный алгоритм. А что за нюансы?
Пользуясь случаем,хочу замутить ещё алгоритм автоматического поиска наилучшего канала.
void segaRead() {
digitalWrite(SEL, HIGH);
sega_up = (digitalRead(UP_OR_Z) == LOW);
sega_left = (digitalRead(LEFT_OR_X) == LOW);
sega_right = (digitalRead(RIGHT_OR_MODE) == LOW);
sega_down = (digitalRead(DOWN_OR_Y) == LOW);
sega_c = (digitalRead(C_OR_START) == LOW);
sega_b = (digitalRead(B_OR_A) == LOW);
digitalWrite(SEL, LOW);
sega_a = (digitalRead(B_OR_A) == LOW);
sega_start = (digitalRead(C_OR_START) == LOW);
digitalWrite(SEL, HIGH);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
sega_x = (digitalRead(LEFT_OR_X) == LOW);
sega_y = (digitalRead(DOWN_OR_Y) == LOW);
sega_z = (digitalRead(UP_OR_Z) == LOW);
sega_mode = (digitalRead(RIGHT_OR_MODE) == LOW);
digitalWrite(SEL, LOW);
digitalWrite(SEL, HIGH);
}
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10);
uint8_t pipe;
bool up, down, left, right, start, mode, a, b, c, x, y, z;
byte batton_transmit[12];
int total_battons;
void batton_bool () {
up = batton_transmit[0];
left = batton_transmit[1];
right = batton_transmit[2];
down = batton_transmit[3];
start = batton_transmit[4];
mode = batton_transmit[5];
a = batton_transmit[6];
b = batton_transmit[7];
c = batton_transmit[8];
x = batton_transmit[9];
y = batton_transmit[10];
z = batton_transmit[11];
}
void setup() {
Serial.begin(57600);
radio.begin();
radio.setChannel(0x70);
radio.setDataRate(RF24_1MBPS);
radio.setPALevel(RF24_PA_MAX);
radio.openReadingPipe(1, 0x0123456789LL);
radio.startListening();
}
void loop() {
batton_bool ();
if (radio.available(&pipe)) {
radio.read(&batton_transmit, sizeof(batton_transmit));
}
Serial.println ("TEST battons");
Serial.println ("SEGA game PAD");
Serial.println ("NRF 24L01 2.4Ghz");
for (int i; i < 12; i++) {
batton_transmit[i];
Serial.print(batton_transmit[i]);
}
Serial.println (" ");
if (up == 1) {
Serial.println ("UP");
} else if (left == 1)
{ Serial.println("LEFT");
} else if (right == 1)
{ Serial.println("RIGHT");
} else if (down == 1)
{ Serial.println("DOWN");
} else if (start == 1)
{ Serial.println("START");
} else if (mode == 1)
{ Serial.println("MODE");
} else if (a == 1)
{ Serial.println("A");
} else if (b == 1)
{ Serial.println("B");
} else if (c == 1)
{ Serial.println("C");
} else if (x == 1)
{ Serial.println("X");
} else if (y == 1)
{ Serial.println("Y");
} else if (z == 1)
Serial.println("Z");
delay(150);
Serial.println("Total buttons game pad");
total_battons = up + down + left + right + start + mode + a + b + c + x + y + z;
Serial.println(total_battons);
}


#include <OLED_I2C.h>
#include <SPI.h>
#include <EEPROM.h>
#include "nRF24L01.h"
#include "RF24.h"
OLED myOLED(SDA, SCL, 4);
extern uint8_t door_L[];
extern uint8_t door_R[];
extern uint8_t fon[];
extern uint8_t circle[];
extern uint8_t SmallFont[];
RF24 radio(9, 10);
#define SEL 7
#define UP_OR_Z 2
#define DOWN_OR_Y 3
#define LEFT_OR_X 4
#define RIGHT_OR_MODE 5
#define B_OR_A 6
#define C_OR_START 8
// Режимы кнопок
#define MODE_MOMENTARY 0
#define MODE_TRIGGER 1
#define MODE_PULSE 2
#define MODE_TURBO 3
const char* mode_names[] = { "MOMENT", "TRIGGR", "PULSE ", "TURBO " };
// Режимы пульта (Глобальный тип модели)
#define MODEL_CAR 0
#define MODEL_PLANE 1
const char* model_names[] = { "CAR ", "PLANE" };
byte device_mode = MODEL_CAR; // По умолчанию машина
uint16_t current_mask = 0;
uint16_t last_mask = 0;
uint16_t out_mask = 0;
uint16_t trigger_states = 0;
uint8_t signal_quality = 0;
byte btn_modes[6]; // A, B, C, X, Y, Z
const char* btn_names[] = { "A", "B", "C", "X", "Y", "Z" };
bool in_menu = false;
int menu_cursor = 0; // От 0 до 6 (всего 7 пунктов)
bool radio_link = false;
int oled_power_target = 0;
int oled_trimL = 0;
int oled_trimR = 0;
// Переменные для коробки передач машинки
int car_gear = 5; // По умолчанию 5 скорость (макс)
bool c_was_pressed = false; // Переменная для отслеживания клика кнопки C
void openSpaceDoors() {
for (int offset = 0; offset <= 64; offset++) {
myOLED.clrScr();
myOLED.drawBitmap(0 - offset, 0, door_L, 64, 64);
myOLED.drawBitmap(64 + offset, 0, door_R, 64, 64);
if (offset > 35) {
myOLED.print("SYSTEM READY", CENTER, 28);
}
myOLED.update();
}
}
void setup() {
myOLED.begin();
myOLED.setFont(SmallFont);
openSpaceDoors();
radio.begin();
radio.setChannel(102);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setRetries(5, 15);
radio.enableDynamicPayloads();
radio.openWritingPipe(0x0123456789LL);
radio.stopListening();
pinMode(SEL, OUTPUT);
pinMode(UP_OR_Z, INPUT_PULLUP);
pinMode(DOWN_OR_Y, INPUT_PULLUP);
pinMode(LEFT_OR_X, INPUT_PULLUP);
pinMode(RIGHT_OR_MODE, INPUT_PULLUP);
pinMode(B_OR_A, INPUT_PULLUP);
pinMode(C_OR_START, INPUT_PULLUP);
// Читаем настройки кнопок (адреса 0..5)
for (int i = 0; i < 6; i++) {
btn_modes[i] = EEPROM.read(i);
if (btn_modes[i] > 3) btn_modes[i] = 0;
}
// Читаем тип модели из ячейки 6
device_mode = EEPROM.read(6);
if (device_mode > 1) device_mode = MODEL_CAR;
}
void showSaveAnimation() {
myOLED.clrScr();
myOLED.setFont(SmallFont);
myOLED.print("SAVE SETTINGS", CENTER, 15);
int xStart = 14;
int yStart = 30;
int width = 100;
int height = 10;
myOLED.drawRect(xStart, yStart, xStart + width, yStart + height);
for (int i = 1; i < width; i++) {
myOLED.drawLine(xStart + i, yStart + 1, xStart + i, yStart + height);
if (i % 2 == 0) {
myOLED.update();
delay(20);
}
}
myOLED.update();
delay(500);
}
void readSega() {
uint16_t state = 0;
digitalWrite(SEL, HIGH);
delayMicroseconds(20);
if (digitalRead(UP_OR_Z) == LOW) state |= (1 << 0);
if (digitalRead(DOWN_OR_Y) == LOW) state |= (1 << 1);
if (digitalRead(LEFT_OR_X) == LOW) state |= (1 << 2);
if (digitalRead(RIGHT_OR_MODE) == LOW) state |= (1 << 3);
if (digitalRead(B_OR_A) == LOW) state |= (1 << 4);
if (digitalRead(C_OR_START) == LOW) state |= (1 << 5);
digitalWrite(SEL, LOW);
delayMicroseconds(20);
if (digitalRead(B_OR_A) == LOW) state |= (1 << 6);
if (digitalRead(C_OR_START) == LOW) state |= (1 << 7);
digitalWrite(SEL, HIGH);
delayMicroseconds(20);
digitalWrite(SEL, LOW);
delayMicroseconds(20);
digitalWrite(SEL, HIGH);
delayMicroseconds(20);
if (digitalRead(LEFT_OR_X) == LOW) state |= (1 << 8);
if (digitalRead(DOWN_OR_Y) == LOW) state |= (1 << 9);
if (digitalRead(UP_OR_Z) == LOW) state |= (1 << 10);
if (digitalRead(RIGHT_OR_MODE) == LOW) state |= (1 << 11);
digitalWrite(SEL, LOW);
current_mask = state;
}
void handleLogic() {
uint16_t click_mask = current_mask & (~last_mask);
// Вход/Выход из меню (MODE + START)
if ((current_mask & (1 << 11)) && (click_mask & (1 << 7))) {
in_menu = !in_menu;
if (!in_menu) {
// Сохраняем кнопки
for (int i = 0; i < 6; i++) EEPROM.update(i, btn_modes[i]);
// Сохраняем глобальный режим модели
EEPROM.update(6, device_mode);
// БАГФИКС: Сбрасываем коробку передач и флаг кнопки при смене режима
if (device_mode == MODEL_CAR) {
car_gear = 5; // Возвращаем максимальную 5 скорость по умолчанию
c_was_pressed = false; // Обнуляем флаг клика, чтобы не было фантомных нажатий
}
showSaveAnimation();
}
return;
}
if (in_menu) {
// Навигация вверх/вниз по 7 пунктам (0..6)
if (click_mask & (1 << 0)) menu_cursor--;
if (click_mask & (1 << 1)) menu_cursor++;
if (menu_cursor < 0) menu_cursor = 6;
if (menu_cursor > 6) menu_cursor = 0;
// Изменение значений кликами влево/вправо
if (click_mask & (1 << 3)) { // RIGHT
if (menu_cursor == 6) {
device_mode = (device_mode + 1) % 2;
} else {
btn_modes[menu_cursor] = (btn_modes[menu_cursor] + 1) % 4;
}
}
if (click_mask & (1 << 2)) { // LEFT
if (menu_cursor == 6) {
device_mode = (device_mode == 0) ? 1 : 0;
} else {
btn_modes[menu_cursor] = (btn_modes[menu_cursor] == 0) ? 3 : btn_modes[menu_cursor] - 1;
}
}
} else {
out_mask = 0;
out_mask |= (current_mask & 0x0F); // Стрелки
out_mask |= (current_mask & (1 << 7)); // START
out_mask |= (current_mask & (1 << 11)); // MODE
// Логика коробки передач (Кнопка C) — ТОЛЬКО ДЛЯ МАШИНЫ
if (device_mode == MODEL_CAR) {
bool c_now_pressed = (current_mask & (1 << 5)); // Кнопка C (бит 5)
if (c_now_pressed && !c_was_pressed) {
car_gear++;
if (car_gear > 5) car_gear = 0; // Круговой сброс 0..5
}
c_was_pressed = c_now_pressed;
}
int mapping[] = { 6, 4, 5, 8, 9, 10 }; // A, B, C, X, Y, Z
for (int i = 0; i < 6; i++) {
int bitIdx = mapping[i];
switch (btn_modes[i]) {
case MODE_MOMENTARY:
if (current_mask & (1 << bitIdx)) out_mask |= (1 << bitIdx);
break;
case MODE_TRIGGER:
if (click_mask & (1 << bitIdx)) trigger_states ^= (1 << bitIdx);
if (trigger_states & (1 << bitIdx)) out_mask |= (1 << bitIdx);
break;
case MODE_PULSE:
if (click_mask & (1 << bitIdx)) out_mask |= (1 << bitIdx);
break;
case MODE_TURBO:
if ((current_mask & (1 << bitIdx)) && ((millis() / 100) % 2 == 0)) {
out_mask |= (1 << bitIdx);
}
break;
}
}
// Расчеты полетных данных
static uint16_t prev_out_mask = 0;
uint16_t out_click_mask = out_mask & (~prev_out_mask); // Клик из ОБРАБОТАННЫХ кнопок
static uint32_t oled_timer = 0;
if (millis() - oled_timer > 80) {
oled_timer = millis();
// Кнопки C и Z меняют газ только в режиме самолёта (смотрим в out_mask!)
if (device_mode == MODEL_PLANE) {
if (out_mask & (1 << 5)) oled_power_target = min(oled_power_target + 1, 255); // C
if (out_mask & (1 << 10)) oled_power_target = max(oled_power_target - 1, 0); // Z
}
// Сброс триммеров по удержанию Z (смотрим в out_mask)
if (out_mask & (1 << 10)) {
if (oled_trimL > 0) oled_trimL--;
else if (oled_trimL < 0) oled_trimL++;
if (oled_trimR > 0) oled_trimR--;
else if (oled_trimR < 0) oled_trimR++;
}
}
// Триммеры реагируют на КЛИКИ из меню (out_click_mask)
if (out_click_mask & (1 << 6)) oled_trimL = constrain(oled_trimL + 5, -50, 255); // A
if (out_click_mask & (1 << 4)) oled_trimR = constrain(oled_trimR + 5, -50, 255); // B
// Сброс всего по кнопке Y (смотрим в out_mask)
if (out_mask & (1 << 9)) {
oled_power_target = 0;
oled_trimL = 0;
oled_trimR = 0;
}
prev_out_mask = out_mask; // Запоминаем обработанную маску для следующего цикла
}
}
void lossPercentage() {
if (!in_menu) {
radio_link = radio.write(&out_mask, sizeof(out_mask));
if (radio_link) {
uint8_t retries = radio.getARC();
signal_quality = map(retries, 0, 15, 13, 1);
} else {
signal_quality = 0;
}
}
}
void draw() {
myOLED.clrScr();
myOLED.drawBitmap(0, 0, fon, 128, 64);
if (in_menu) {
myOLED.clrScr();
myOLED.print("- CONFIGURATION -", CENTER, 0);
// Выводим первые 6 пунктов (Кнопки)
for (int i = 0; i < 6; i++) {
String line = (i == menu_cursor ? "> " : " ");
line += btn_names[i];
line += ": ";
line += mode_names[btn_modes[i]];
myOLED.print(line, 0, 10 + (i * 7));
}
// Выводим 7-й глобальный пункт выбора модели
String line = (menu_cursor == 6 ? "> " : " ");
line += "MODEL: ";
line += model_names[device_mode];
myOLED.print(line, 0, 10 + (6 * 7));
} else {
// --- ГЛАВНЫЙ ЭКРАН ---
myOLED.print("r/ch 102 SEGA-PAD", LEFT, 0);
int barX = 126;
int barY = 44;
if (radio_link) {
for (int i = 0; i < 13; i++) {
if (signal_quality > i) {
int yPos = barY - (i * 3);
myOLED.drawLine(barX, yPos, barX - 8, yPos);
myOLED.drawLine(barX, yPos - 1, barX - 8, yPos - 1);
}
}
}
myOLED.print("RF24 PA_MAX 250KBPS", LEFT, 8);
// Локальные переменные длин баров для отрисовки
int barLengt_tL = 0;
int barLengt_tR = 0;
int turboL = 0;
int turboR = 0;
// =========================================================================
// ЖЕСТКОЕ РАЗГРАНИЧЕНИЕ ЭКРАННОЙ ЛОГИКИ
// =========================================================================
if (device_mode == MODEL_CAR) {
// ----------------- РЕЖИМ МАШИНЫ -----------------
turboL = 0;
turboR = 0;
turboL = (out_mask & (1 << 2)) ? 32 : 0;
turboR = (out_mask & (1 << 3)) ? 32 : 0;
// Нижние бары четко показывают дискретное питание мостов L298N
if (out_mask & (1 << 4)) barLengt_tR = 38; // Нажата B
if (out_mask & (1 << 6)) barLengt_tL = 38; // Нажата A
String bottomStr = String(car_gear);
myOLED.print("G |MODE+START-MENU", LEFT, 56);
myOLED.print(bottomStr, 7, 56);
} else {
// ----------------- РЕЖИМ САМОЛЁТА -----------------
// Верхние бары заполняются от кренов (Влево/Вправо)
turboL = (out_mask & (1 << 2)) ? 32 : 0;
turboR = (out_mask & (1 << 3)) ? 32 : 0;
// Нижние бары плавно растут от общего газа и триммеров
int cruiseL_val = constrain(oled_power_target + oled_trimL, 0, 255);
int cruiseR_val = constrain(oled_power_target + oled_trimR, 0, 255);
barLengt_tL = map(cruiseL_val, 0, 255, 0, 38);
barLengt_tR = map(cruiseR_val, 0, 255, 0, 38);
myOLED.print("MODE+START-MENU", CENTER, 56);
}
// --- ФИЗИЧЕСКАЯ ОТРИСОВКА ВЕРХНИХ БАРОВ (Самолетные крены) ---
if (turboL > 0) {
for (int h = 20; h <= 24; h++) {
myOLED.drawLine(16, h, 15 + turboL, h);
}
}
if (turboR > 0) {
for (int h = 20; h <= 24; h++) {
myOLED.drawLine(73, h, 72 + turboR, h);
}
}
// --- ФИЗИЧЕСКАЯ ОТРИСОВКА НИЖНИХ БАРОВ (Базовый Газ / Моторы Машины) ---
if (barLengt_tL > 0) {
for (int h = 28; h <= 31; h++) {
myOLED.drawLine(18, h, 17 + barLengt_tL, h);
}
}
if (barLengt_tR > 0) {
for (int h = 28; h <= 31; h++) {
myOLED.drawLine(75, h, 74 + barLengt_tR, h);
}
}
// =========================================================================
if (radio_link) {
myOLED.drawBitmap(112, 48, circle, 16, 16);
}
int yRow1 = 35;
int yRow2 = 44;
if (out_mask & (1 << 8)) myOLED.print("[X]", 65, yRow1);
if (out_mask & (1 << 9)) myOLED.print("[Y]", 82, yRow1);
if (out_mask & (1 << 10)) myOLED.print("[Z]", 99, yRow1);
if (out_mask & (1 << 6)) myOLED.print("A", 71, yRow2);
if (out_mask & (1 << 4)) myOLED.print("B", 88, yRow2);
if (out_mask & (1 << 5)) myOLED.print("C", 105, yRow2);
if (out_mask & (1 << 11)) myOLED.print("MODE", 37, yRow1);
if (out_mask & (1 << 7)) myOLED.print("START", 37, yRow2);
if (out_mask & (1 << 0)) myOLED.print("[U]", 4, yRow1);
if (out_mask & (1 << 1)) myOLED.print("[D]", 20, yRow1);
if (out_mask & (1 << 2)) myOLED.print("[L]", 4, yRow2);
if (out_mask & (1 << 3)) myOLED.print("[R]", 20, yRow2);
}
myOLED.update();
}
void loop() {
readSega();
handleLogic();
lossPercentage();
draw();
last_mask = current_mask;
}
#include <avr/pgmspace.h>
const uint8_t door_L[] PROGMEM = {
0x00, 0x00, 0x00, 0xfc, 0x04, 0x04, 0xc4, 0xe4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4,
0xf4, 0xf4, 0x74, 0x74, 0xe4, 0xc4, 0x04, 0x04, 0x04, 0xc4, 0xe4, 0xf4, 0xd4, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x14,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x6f, 0x67, 0x73,
0x39, 0x1c, 0x0e, 0x07, 0x83, 0x41, 0x20, 0x90, 0xa0, 0x20, 0x41, 0x53, 0x53, 0x93, 0xb3, 0xb3,
0x33, 0x73, 0x53, 0x53, 0x93, 0x93, 0x13, 0x13, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93,
0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x13,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf8, 0xfc, 0x1c, 0x6c, 0x04, 0x04, 0xe4, 0x14, 0x04, 0xf8,
0x00, 0x00, 0x00, 0xfc, 0xfd, 0xd9, 0x5a, 0x12, 0x34, 0x34, 0x64, 0x68, 0x4a, 0xd2, 0xd0, 0x90,
0xa1, 0x29, 0x4a, 0x42, 0x42, 0x84, 0xa5, 0xa9, 0x09, 0x0a, 0x12, 0x12, 0xa5, 0xa4, 0x29, 0x4a,
0x49, 0x52, 0x95, 0x92, 0x25, 0x2a, 0x15, 0x4a, 0x55, 0xaa, 0x95, 0xaa, 0x55, 0x2a, 0x55, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x01, 0x03, 0x07, 0x1a, 0xe2, 0xfe, 0xe4, 0x15, 0x09, 0x0a, 0x0a, 0x12, 0x14, 0x24, 0x28,
0x28, 0x4a, 0xd2, 0x90, 0xa1, 0x21, 0x11, 0xca, 0x26, 0x10, 0x08, 0x08, 0x09, 0x29, 0xea, 0xea,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0xc0, 0xe0, 0x58, 0x47, 0x7f, 0x27, 0xa8, 0x90, 0x50, 0x50, 0x48, 0x28, 0x24, 0x14,
0x14, 0x52, 0x4b, 0x09, 0x85, 0x84, 0x88, 0x53, 0x64, 0x08, 0x13, 0x12, 0x94, 0x94, 0x54, 0x55,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1f, 0x3f, 0x38, 0x36, 0x20, 0x20, 0x27, 0x28, 0x20, 0x1f,
0x00, 0x00, 0x00, 0x3f, 0xbf, 0x9b, 0x5a, 0x48, 0x2c, 0x2c, 0x26, 0x16, 0x52, 0x4b, 0x0b, 0x09,
0x85, 0x94, 0x52, 0x42, 0x42, 0x21, 0xa5, 0x95, 0x90, 0x50, 0x48, 0x48, 0x25, 0xa5, 0x54, 0x92,
0x52, 0xaa, 0x49, 0xa9, 0x54, 0xa4, 0x50, 0xaa, 0x52, 0xa9, 0x55, 0xa9, 0x54, 0xaa, 0x55, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xf6, 0xe6, 0xce,
0x9c, 0x38, 0x70, 0xe0, 0xc1, 0x82, 0x04, 0x09, 0x05, 0x04, 0x82, 0xca, 0xca, 0xc9, 0xcd, 0xcd,
0xcc, 0xce, 0xca, 0xca, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8,
0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8,
0x00, 0x00, 0x00, 0x3f, 0x20, 0x20, 0x23, 0x27, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0x2f, 0x2f, 0x2e, 0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x23, 0x27, 0x2f, 0x2b, 0x29, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x28
};
const uint8_t door_R[] PROGMEM = {
0x14, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x94, 0x94, 0x94, 0xd4, 0xf4, 0xe4, 0xc4, 0x04, 0x04, 0x04, 0xc4, 0xe4, 0x74, 0x74, 0xf4, 0xf4,
0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xe4, 0xc4, 0x04, 0x04, 0xfc, 0x00, 0x00, 0x00,
0x13, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13,
0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x93, 0x13, 0x13, 0x13, 0x93, 0x93, 0x53, 0x53, 0x73, 0x33,
0xb3, 0xb3, 0x93, 0x53, 0x53, 0x41, 0x20, 0xa0, 0x90, 0x20, 0x41, 0x83, 0x07, 0x0e, 0x1c, 0x39,
0x73, 0x67, 0x6f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x00, 0x55, 0x2a, 0x55, 0xaa, 0x95, 0xaa, 0x55, 0x4a, 0x15, 0x2a, 0x25, 0x92, 0x95, 0x52, 0x49,
0x4a, 0x29, 0xa4, 0xa5, 0x12, 0x12, 0x0a, 0x09, 0xa9, 0xa5, 0x84, 0x42, 0x42, 0x4a, 0x29, 0xa1,
0x90, 0xd0, 0xd2, 0x4a, 0x68, 0x64, 0x34, 0x34, 0x12, 0x5a, 0xd9, 0xfd, 0xfc, 0x00, 0x00, 0x00,
0xf8, 0x04, 0x14, 0xe4, 0x04, 0x04, 0x6c, 0x1c, 0xfc, 0xf8, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0xea, 0xea, 0x29, 0x09, 0x08, 0x08, 0x10, 0x26, 0xca, 0x11, 0x21, 0xa1, 0x90, 0xd2, 0x4a, 0x28,
0x28, 0x24, 0x14, 0x12, 0x0a, 0x0a, 0x09, 0x15, 0xe4, 0xfe, 0xe2, 0x1a, 0x07, 0x03, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x55, 0x54, 0x94, 0x94, 0x12, 0x13, 0x08, 0x64, 0x53, 0x88, 0x84, 0x85, 0x09, 0x4b, 0x52, 0x14,
0x14, 0x24, 0x28, 0x48, 0x50, 0x50, 0x90, 0xa8, 0x27, 0x7f, 0x47, 0x58, 0xe0, 0xc0, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x55, 0xaa, 0x54, 0xa9, 0x55, 0xa9, 0x52, 0xaa, 0x50, 0xa4, 0x54, 0xa9, 0x49, 0xaa, 0x52,
0x92, 0x54, 0xa5, 0x25, 0x48, 0x48, 0x50, 0x90, 0x95, 0xa5, 0x21, 0x42, 0x42, 0x52, 0x94, 0x85,
0x09, 0x0b, 0x4b, 0x52, 0x16, 0x26, 0x2c, 0x2c, 0x48, 0x5a, 0x9b, 0xbf, 0x3f, 0x00, 0x00, 0x00,
0x1f, 0x20, 0x28, 0x27, 0x20, 0x20, 0x36, 0x38, 0x3f, 0x1f, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9,
0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xce, 0xcc,
0xcd, 0xcd, 0xc9, 0xca, 0xca, 0x82, 0x04, 0x05, 0x09, 0x04, 0x82, 0xc1, 0xe0, 0x70, 0x38, 0x9c,
0xce, 0xe6, 0xf6, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x29, 0x2b, 0x2f, 0x27, 0x23, 0x20, 0x20, 0x20, 0x23, 0x27, 0x2e, 0x2e, 0x2f, 0x2f,
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x27, 0x23, 0x20, 0x20, 0x3f, 0x00, 0x00, 0x00
};
const uint8_t fon[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0x02, 0x0a, 0x0a, 0x32, 0xe6, 0x0c, 0xf8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xe0, 0x38, 0x0c, 0x06, 0x02, 0x03, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xe1, 0xf1,
0x19, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x29, 0x29, 0x29, 0x29, 0x49, 0x19, 0xf1, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0xf9, 0x49, 0xc9, 0x49, 0x31, 0x01, 0x01, 0xe1, 0xf1, 0x19, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x29, 0x29, 0x29, 0x29, 0x49,
0x19, 0xf1, 0xe1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x0a, 0x02, 0x12, 0xf2, 0x10, 0x00, 0xf0, 0x81,
0x83, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x09, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfb, 0x08, 0x00, 0x11, 0xf2, 0x10, 0x00, 0xf0, 0x51, 0xa3, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x03, 0x09, 0xf8, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x03, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x60, 0x40, 0x40, 0x40, 0x40, 0xc0, 0xcf, 0xe0, 0xff, 0x00,
0x00, 0x01, 0x07, 0x0c, 0x18, 0x10, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
0xe0, 0x38, 0xcc, 0xf6, 0xfa, 0xfb, 0x3d, 0xbd, 0x01, 0x81, 0x82, 0x82, 0x84, 0x19, 0xe3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x0c, 0x10, 0x20, 0x20, 0x40, 0x40, 0x5e, 0x5e, 0x6f, 0x2f, 0x37, 0x19, 0x0e, 0x03, 0x00
};
const uint8_t circle[] PROGMEM = {
0xE0, 0x38, 0x8C, 0x86, 0x82, 0x83, 0x01, 0xBD, 0x3D, 0xFB, 0xFA, 0xF6, 0xCC, 0x39, 0xE3, 0x00, // 0x0010 (16) pixels
0x03, 0x0E, 0x19, 0x37, 0x2F, 0x6F, 0x5E, 0x5E, 0x40, 0x60, 0x20, 0x30, 0x18, 0x0E, 0x03, 0x00, // 0x0020 (32) pixels
};