diff --git a/src/Makefile b/src/Makefile index 602f2cf..0fd0eb4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,6 +4,9 @@ EXTRA_COMPONENTS = \ extras/dht \ extras/http-parser \ extras/rboot-ota \ + extras/ssd1306 \ + extras/fonts \ + extras/i2c \ $(abspath ../components/esp-wolfssl) \ $(abspath ../components/esp-cjson) \ $(abspath ../components/esp-homekit) diff --git a/src/wifi_thermostat.c b/src/wifi_thermostat.c index 4bb6880..9af630d 100644 --- a/src/wifi_thermostat.c +++ b/src/wifi_thermostat.c @@ -21,7 +21,7 @@ */ #define DEVICE_MANUFACTURER "David B Brown" -#define DEVICE_NAME "Wifi Thermostat" +#define DEVICE_NAME "Wifi-Thermostat" #define DEVICE_MODEL "Basic" #define DEVICE_SERIAL "12345678" #define FW_VERSION "1.0" @@ -37,12 +37,15 @@ #include #include +#include + #include #include //#include "wifi.h" #include +#include "wifi_thermostat.h" #define TEMPERATURE_SENSOR_PIN 4 #define TEMPERATURE_POLL_PERIOD 10000 @@ -51,6 +54,60 @@ // it can be used in Eve, which will show it, where Home does not // and apply the four other parameters in the accessories_information section + + +/// I2C + +/* Remove this line if your display connected by SPI */ +#define I2C_CONNECTION + +#ifdef I2C_CONNECTION + #include +#endif + +#include "fonts/fonts.h" + +/* Change this according to you schematics and display size */ +#define DISPLAY_WIDTH 128 +#define DISPLAY_HEIGHT 64 + +#ifdef I2C_CONNECTION + #define PROTOCOL SSD1306_PROTO_I2C + #define ADDR SSD1306_I2C_ADDR_0 + #define I2C_BUS 0 + #define SCL_PIN 14 + #define SDA_PIN 5 +#else + #define PROTOCOL SSD1306_PROTO_SPI4 + #define CS_PIN 5 + #define DC_PIN 4 +#endif + +#define DEFAULT_FONT FONT_FACE_TERMINUS_16X32_ISO8859_1 + +/* Declare device descriptor */ +static const ssd1306_t dev = { + .protocol = PROTOCOL, +#ifdef I2C_CONNECTION +.i2c_dev.bus = I2C_BUS, +.i2c_dev.addr = ADDR, +#else + .cs_pin = CS_PIN, + .dc_pin = DC_PIN, +#endif + .width = DISPLAY_WIDTH, + .height = DISPLAY_HEIGHT +}; + +/* Local frame buffer */ +static uint8_t buffer[DISPLAY_WIDTH * DISPLAY_HEIGHT / 8]; + +#define SECOND (1000 / portTICK_PERIOD_MS) + +// I2C + + + #include "ota-api.h" homekit_characteristic_t ota_trigger = API_OTA_TRIGGER; homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, DEVICE_NAME); @@ -80,11 +137,117 @@ homekit_characteristic_t current_humidity = HOMEKIT_CHARACTERISTIC_( CURRENT_ +// LCD ssd1306 + +static void ssd1306_task(void *pvParameters) +{ + char target_temp_string[20]; + char mode_string[20]; + char temperature_string[20]; + char humidity_string[20]; + int count =0; + + + vTaskDelay(SECOND); + ssd1306_set_whole_display_lighting(&dev, false); + + ssd1306_load_xbm(&dev, homekit_logo, buffer); + if (ssd1306_load_frame_buffer(&dev, buffer)) + goto error_loop; + vTaskDelay(SECOND*5); + + ssd1306_clear_screen(&dev); + + while (1) { + if (ssd1306_fill_rectangle(&dev, buffer, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, OLED_COLOR_BLACK)){ + printf("Error printing rectangle\bn"); + } + + + sprintf(target_temp_string, "Target: %g", (float)target_temperature.value.float_value); + sprintf(mode_string, "Mode: %i", (int)current_state.value.int_value); +// ssd1306_draw_string(&dev, buffer, font_builtin_fonts[0], 0, 0, "Hello", OLED_COLOR_WHITE, OLED_COLOR_BLACK) + + + + if (ssd1306_draw_string(&dev, buffer, font_builtin_fonts[0], 0, 30, target_temp_string, OLED_COLOR_WHITE, OLED_COLOR_BLACK) < 1){ + printf("Error printing target temp\n"); + } + + if (ssd1306_draw_string(&dev, buffer, font_builtin_fonts[0], 0, 45, mode_string, OLED_COLOR_WHITE, OLED_COLOR_BLACK) < 1 ){ + printf("Error printing mode\n"); + } + + sprintf(temperature_string, "Temperature: %g", (float)current_temperature.value.float_value); + sprintf(humidity_string, "Humidity: %g", (float)current_humidity.value.float_value); + if (ssd1306_draw_string(&dev, buffer, font_builtin_fonts[0], 0, 0, temperature_string, OLED_COLOR_WHITE, OLED_COLOR_BLACK) < 1){ + printf("Error printing temperature\n"); + } + if (ssd1306_draw_string(&dev, buffer, font_builtin_fonts[0], 0, 15, humidity_string, OLED_COLOR_WHITE, OLED_COLOR_BLACK) < 1){ + printf("Error printing humidity\n"); + } + + count ++; + if (count == 60){ + + count = 0; + + ssd1306_clear_screen(&dev); + ssd1306_load_xbm(&dev, homekit_logo, buffer); + if (ssd1306_load_frame_buffer(&dev, buffer)) + goto error_loop; + vTaskDelay(SECOND*5); + ssd1306_clear_screen(&dev); + } + + + if (ssd1306_load_frame_buffer(&dev, buffer)) + goto error_loop; + + vTaskDelay(SECOND); + + + } + + error_loop: + printf("%s: error while loading framebuffer into SSD1306\n", __func__); + for (;;) { + vTaskDelay(2 * SECOND); + printf("%s: error loop\n", __FUNCTION__); + } +} + + +void screen_init(void) +{ + //uncomment to test with CPU overclocked + //sdk_system_update_cpu_freq(160); + + + printf("Screen Init SDK version:%s\n", sdk_system_get_sdk_version()); + +#ifdef I2C_CONNECTION + i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K); +#endif + + while (ssd1306_init(&dev) != 0) { + printf("%s: failed to init SSD1306 lcd\n", __func__); + vTaskDelay(SECOND); + } + ssd1306_set_whole_display_lighting(&dev, true); + + xTaskCreate(ssd1306_task, "ssd1306_task", 512, NULL, 2, NULL); + +} + +// LCD ssd1306 + void on_update(homekit_characteristic_t *ch, homekit_value_t value, void *context) { process_setting_update(); } void process_setting_update() { + uint8_t state = target_state.value.int_value; if ((state == 1 && current_temperature.value.float_value < target_temperature.value.float_value) || (state == 3 && current_temperature.value.float_value < heating_threshold.value.float_value)) { @@ -130,6 +293,7 @@ void temperature_sensor_task(void *_args) { homekit_characteristic_notify(¤t_humidity, current_humidity.value); process_setting_update(); + } else { printf("Couldnt read data from sensor\n"); } @@ -215,6 +379,10 @@ void user_init(void) { thermostat_init(); + printf ("Calling screen init\n"); + printf ("fonts count %i\n", font_builtin_fonts_count); + screen_init(); + printf ("Screen init called\n"); int c_hash=ota_read_sysparam(&manufacturer.value.string_value,&serial.value.string_value, &model.value.string_value,&revision.value.string_value); if (c_hash==0) c_hash=1; diff --git a/src/wifi_thermostat.h b/src/wifi_thermostat.h index 8874c7a..6e22009 100644 --- a/src/wifi_thermostat.h +++ b/src/wifi_thermostat.h @@ -1,68 +1,90 @@ -// 'Homekit Icon', 128x64px -const unsigned char homekit_logo [] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x70, 0x3c, 0x1c, 0x0e, 0x07, 0x03, - 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xe0, 0xfc, 0xfc, 0x1c, 0x1c, 0x0c, 0x0c, 0x1c, 0x1c, - 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, - 0xe0, 0xf0, 0x78, 0x3c, 0x1e, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x6f, 0xe7, 0xe3, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0x60, 0x60, 0x60, 0x70, 0x70, - 0x70, 0x70, 0x60, 0x60, 0x60, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe3, 0xe7, 0x6f, 0x7e, 0x7c, 0x78, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x07, 0x43, 0xe1, 0x71, 0x38, 0x38, 0x1c, 0x1c, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8c, 0x1c, 0x1c, 0x38, 0x38, 0x71, 0xe1, 0x43, 0x07, 0x0e, 0x0e, 0x00, 0x00, 0xf0, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x07, 0x03, 0x03, 0x03, 0x01, - 0x01, 0x03, 0x03, 0x07, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, - 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, - 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; +#define home_kit_logo_width 128 +#define home_kit_logo_height 64 +char homekit_logo[] = { + 0x00, 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, + 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x07, 0xFF, 0x01, 0x00, 0xF8, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1F, 0xF0, 0x0F, 0xF8, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x7F, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0x7F, 0xF0, 0xE0, 0x77, + 0xF0, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, + 0xFF, 0x80, 0xF0, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, + 0xFF, 0x7F, 0xF0, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x07, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0xFF, 0x97, + 0xF9, 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x80, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x04, 0x00, 0xFF, 0x7F, + 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x0F, 0xC0, 0xFF, + 0xFF, 0x03, 0xF0, 0xFF, 0xD0, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0x01, 0xFE, 0xFF, 0xFF, 0x7F, 0x80, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0x7F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x7E, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x3F, 0xF8, 0x7F, 0x00, + 0x80, 0xFF, 0x1F, 0xFC, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0xFE, 0x07, 0x00, 0x00, 0xE0, 0xBF, 0x7E, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0x00, 0xFD, 0x3F, 0x00, 0xFF, 0xFF, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x1F, 0xF0, 0xFF, + 0xFF, 0x07, 0xFC, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0x3F, 0xF8, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFD, 0xFF, 0xFF, 0x0F, 0xFF, 0x7F, 0xFF, 0x03, 0xD0, 0xFF, 0xFE, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x3F, 0x00, + 0x00, 0xFE, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0xFF, 0x0F, 0xE8, 0x07, 0xF0, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xF0, 0xFF, 0xFF, 0x7F, + 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xBF, 0xDB, 0xBD, 0x7E, 0xDB, + 0x6F, 0x7D, 0xDB, 0x6D, 0xFE, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, + 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xEA, 0xF7, 0xF7, 0xDF, 0xDF, 0xDF, 0xF7, 0x7D, 0xEF, + 0x56, 0x00, 0x00, 0x00};