diff --git a/boards/obp60_s3_light_n8r8.json b/boards/obp60_s3_light_n8r8.json new file mode 100644 index 0000000..b7b808a --- /dev/null +++ b/boards/obp60_s3_light_n8r8.json @@ -0,0 +1,56 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32s3_out.ld", + "partitions": "default_8MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_ESP32S3_DEV", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "obp60s3_light" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": [ + "esp-builtin" + ], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "OBP60 Light ESP32-S3-N8R8 (8 MB QD, 8 MB PSRAM)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://open-boat-projects.org/en/diy-multifunktionsdisplay-obp-60/", + "vendor": "Open Boat Projects" +} diff --git a/lib/obp60task/Atari16px8b.h b/lib/obp60task/Atari16px8b.h new file mode 100644 index 0000000..c12a5ba --- /dev/null +++ b/lib/obp60task/Atari16px8b.h @@ -0,0 +1,338 @@ +const uint8_t Atari16pxBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0x0F, 0xCF, 0x3C, 0xF3, 0xCF, 0x30, 0x66, 0x66, 0xFF, + 0xFF, 0x66, 0x66, 0xFF, 0xFF, 0x66, 0x66, 0x30, 0xC7, 0xFF, 0xC3, 0x0F, + 0x9F, 0x0C, 0x3F, 0xFE, 0x30, 0xC0, 0xCF, 0x3D, 0x86, 0x30, 0xC6, 0x1B, + 0xCF, 0x30, 0x38, 0xF9, 0xB3, 0x63, 0x87, 0x1C, 0x38, 0xDF, 0xBF, 0x36, + 0x6F, 0xEE, 0xC0, 0xFF, 0xF0, 0x36, 0xEC, 0xCC, 0xCC, 0xCE, 0x63, 0xC6, + 0x73, 0x33, 0x33, 0x37, 0x6C, 0x66, 0x66, 0x3C, 0x3C, 0xFF, 0xFF, 0x3C, + 0x3C, 0x66, 0x66, 0x30, 0xC3, 0x3F, 0xFC, 0xC3, 0x0C, 0x6D, 0xBD, 0x00, + 0xFF, 0xF0, 0xFF, 0x0C, 0x30, 0xC6, 0x18, 0xC3, 0x18, 0x63, 0x0C, 0x30, + 0x7B, 0xFC, 0xF3, 0xCF, 0x7E, 0xF3, 0xCF, 0x3F, 0xDE, 0x30, 0xC7, 0x1C, + 0x30, 0xC3, 0x0C, 0x30, 0xCF, 0xFF, 0x7B, 0xFC, 0xF3, 0x18, 0x63, 0x0C, + 0x61, 0x8F, 0xFF, 0xFF, 0xF1, 0x86, 0x30, 0xC1, 0x86, 0xCF, 0x3F, 0xDE, + 0x18, 0x63, 0x8E, 0x79, 0xED, 0xB6, 0xFF, 0xF1, 0x86, 0xFF, 0xFC, 0x30, + 0xFB, 0xF0, 0xC3, 0x0F, 0x3F, 0xDE, 0x39, 0xEE, 0x30, 0xC3, 0xEF, 0xF3, + 0xCF, 0x3F, 0xDE, 0xFF, 0xF0, 0xC3, 0x18, 0x63, 0x0C, 0x61, 0x86, 0x18, + 0x7B, 0xFC, 0xF3, 0x79, 0xEC, 0xF3, 0xCF, 0x3F, 0xDE, 0x7B, 0xFC, 0xF3, + 0xFD, 0xF0, 0xC3, 0x0C, 0x77, 0x9C, 0xFF, 0x0F, 0xF0, 0x6D, 0xB0, 0x1B, + 0x6F, 0x40, 0x0E, 0x38, 0xE3, 0x8E, 0x0E, 0x0E, 0x0E, 0x0E, 0xFF, 0xF0, + 0x00, 0xFF, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE3, 0x8E, 0x38, 0xE0, 0x7B, + 0xFC, 0xF3, 0x18, 0x63, 0x0C, 0x30, 0x03, 0x0C, 0x38, 0xFB, 0x9E, 0x1D, + 0xBA, 0xF5, 0xEE, 0xC1, 0xC5, 0xF9, 0xE0, 0x31, 0xEF, 0xF3, 0xCF, 0x3F, + 0xFF, 0xCF, 0x3C, 0xF3, 0xFB, 0xFC, 0xF3, 0xFF, 0xEC, 0xF3, 0xCF, 0x3F, + 0xFE, 0x7B, 0xFC, 0xF3, 0xC3, 0x0C, 0x30, 0xCF, 0x3F, 0xDE, 0xF3, 0xED, + 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x7F, 0xBC, 0xFF, 0xFC, 0x30, 0xFB, 0xEC, + 0x30, 0xC3, 0x0F, 0xFF, 0xFF, 0xFC, 0x30, 0xFB, 0xEC, 0x30, 0xC3, 0x0C, + 0x30, 0x7F, 0xFC, 0x30, 0xDF, 0x7C, 0xF3, 0xCF, 0x3F, 0xDE, 0xCF, 0x3C, + 0xF3, 0xFF, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xFF, 0xF3, 0x0C, 0x30, 0xC3, + 0x0C, 0x30, 0xCF, 0xFF, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0xCF, 0x3F, + 0xDE, 0xCD, 0x9B, 0x66, 0xCF, 0x1E, 0x36, 0x6C, 0xCD, 0x9B, 0x1E, 0x30, + 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0F, 0xFF, 0xC7, 0x8F, 0xBF, + 0x7F, 0xFA, 0xF5, 0xE3, 0xC7, 0x8F, 0x1E, 0x30, 0xCF, 0x3C, 0xFB, 0xEF, + 0xFF, 0xF7, 0xDF, 0x3C, 0xF3, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, + 0x3F, 0xDE, 0xFB, 0xFC, 0xF3, 0xCF, 0x3F, 0xFE, 0xC3, 0x0C, 0x30, 0x7B, + 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x5F, 0x9B, 0xF9, 0xFB, 0x36, 0x6C, + 0xDF, 0xBE, 0x6C, 0xCD, 0x9B, 0x1E, 0x30, 0x7F, 0xFC, 0x30, 0xE1, 0xC3, + 0x87, 0x0C, 0x3F, 0xFE, 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xCF, 0x3F, 0xDE, 0xCF, 0x3C, + 0xF3, 0xCF, 0x3C, 0xF3, 0x79, 0xE3, 0x0C, 0xC7, 0x8F, 0x1E, 0x3C, 0x7A, + 0xF5, 0xFF, 0xFF, 0xDF, 0x1C, 0x10, 0xCF, 0x3C, 0xDE, 0x78, 0xC3, 0x1E, + 0x7B, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0x79, 0xE3, 0x0C, 0x30, 0xC3, 0x0C, + 0xFF, 0xF1, 0x86, 0x30, 0xC6, 0x18, 0xC3, 0x0F, 0xFF, 0xFF, 0xCC, 0xCC, + 0xCC, 0xCC, 0xFF, 0xC3, 0x0C, 0x18, 0x60, 0xC3, 0x06, 0x18, 0x30, 0xC3, + 0xFF, 0x33, 0x33, 0x33, 0x33, 0xFF, 0x10, 0x20, 0xE1, 0xC6, 0xCD, 0xB1, + 0xE3, 0xFF, 0xFC, 0x86, 0x38, 0xE3, 0x8C, 0x20, 0x79, 0xF0, 0xDF, 0xFF, + 0x3C, 0xFF, 0x7C, 0xC3, 0x0C, 0x3E, 0xFF, 0x3C, 0xF3, 0xCF, 0x3F, 0xFE, + 0x7B, 0xEC, 0x30, 0xC3, 0x0C, 0x3F, 0x7C, 0x0C, 0x30, 0xDF, 0xFF, 0x3C, + 0xF3, 0xCF, 0x3F, 0xDF, 0x7B, 0xFC, 0xF3, 0xFF, 0x0C, 0x3F, 0x7C, 0x1C, + 0xF3, 0x0C, 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x7F, 0xFC, 0xF3, 0xCF, + 0x3F, 0xDF, 0x0F, 0xFF, 0x80, 0xC3, 0x0C, 0x3E, 0xFF, 0x3C, 0xF3, 0xCF, + 0x3C, 0xF3, 0x66, 0x0E, 0xE6, 0x66, 0x66, 0xFF, 0x18, 0xC0, 0x31, 0x8C, + 0x63, 0x18, 0xC6, 0x3F, 0xF8, 0xC1, 0x83, 0x06, 0x6D, 0xDF, 0x3C, 0x7C, + 0xD9, 0x9B, 0x3E, 0x30, 0xEE, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x6D, 0xFF, + 0xFE, 0xBD, 0x7A, 0xF1, 0xE3, 0xC6, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, + 0xCC, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0xFB, 0xFC, 0xF3, 0xCF, + 0x3C, 0xFF, 0xFB, 0x0C, 0x00, 0x7F, 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x7C, + 0x30, 0xC0, 0xFB, 0xFC, 0xF0, 0xC3, 0x0C, 0x30, 0xC0, 0x7F, 0xFC, 0x38, + 0x78, 0x70, 0xFF, 0xF8, 0x30, 0xCF, 0xFF, 0x30, 0xC3, 0x0C, 0x30, 0xF1, + 0xC0, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x7C, 0xCF, 0x3C, 0xF3, 0xCD, + 0xE7, 0x8C, 0x30, 0xC7, 0x8F, 0x5E, 0xBF, 0xFF, 0xFB, 0xE3, 0x82, 0xCF, + 0x37, 0x9E, 0x31, 0xE7, 0xB3, 0xCC, 0xCF, 0x3C, 0xF3, 0xCF, 0x3F, 0xDF, + 0x0F, 0xFF, 0x80, 0xFF, 0xF1, 0x8C, 0x31, 0x86, 0x3F, 0xFC, 0x0E, 0x30, + 0x60, 0xC1, 0x87, 0x3C, 0x78, 0x38, 0x30, 0x60, 0xC1, 0x81, 0xC0, 0xFF, + 0xFF, 0xFF, 0xF0, 0xE0, 0x60, 0xC1, 0x83, 0x07, 0x07, 0x8F, 0x38, 0x60, + 0xC1, 0x83, 0x1C, 0x00, 0x63, 0xE6, 0xFC, 0xE0, 0xFC, 0x63, 0x18, 0xC6, + 0x31, 0x8C, 0x7E, 0x00, 0xF3, 0xFF, 0xFF, 0x30, 0xC7, 0xBF, 0xCF, 0x0C, + 0x33, 0xFD, 0xE3, 0x0C, 0x0E, 0x1E, 0x38, 0x30, 0x30, 0x30, 0x30, 0xFE, + 0x30, 0x30, 0x30, 0x7F, 0xFF, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7E, + 0xCF, 0x3C, 0xF3, 0xFD, 0xE3, 0x3F, 0x30, 0xC3, 0x0C, 0xFC, 0x63, 0x18, + 0xC6, 0x31, 0x8C, 0x7E, 0x39, 0xB6, 0x4C, 0x7B, 0x3C, 0xDE, 0x32, 0x6D, + 0x9C, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7E, 0x7D, 0x8E, 0x0D, 0xDA, + 0x34, 0x68, 0xDD, 0x83, 0x8D, 0xF0, 0x79, 0xF0, 0xDF, 0xFF, 0x3C, 0xFF, + 0x7C, 0x0F, 0xC0, 0x1A, 0x6D, 0xB6, 0xC6, 0xC6, 0xC6, 0x80, 0xFF, 0xF0, + 0xC3, 0x0C, 0xFF, 0x7D, 0x8E, 0x0D, 0xDA, 0xB6, 0x6E, 0xD5, 0x83, 0x8D, + 0xF0, 0xFF, 0xFC, 0x76, 0xE3, 0xB7, 0x00, 0x30, 0xC3, 0x3F, 0xFC, 0xC3, + 0x0C, 0x03, 0xFF, 0xC0, 0x69, 0x36, 0xCF, 0xF3, 0x63, 0x96, 0xFC, 0x63, + 0x18, 0xC6, 0x31, 0x8C, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7F, + 0x5D, 0xC0, 0x80, 0x7B, 0x97, 0x2E, 0x5C, 0xB9, 0x5E, 0x85, 0x0A, 0x14, + 0x28, 0x50, 0x6F, 0xF6, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7E, 0xD5, + 0x50, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0x0F, 0xC0, 0xB1, 0xB1, + 0xB1, 0xB6, 0xDB, 0x2C, 0x00, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7E, + 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7E, 0xFC, 0x63, 0x18, 0xC6, 0x31, + 0x8C, 0x7E, 0x30, 0xC0, 0x0C, 0x30, 0xC6, 0x18, 0xCF, 0x3F, 0xDE, 0xC1, + 0x83, 0x00, 0x7B, 0xFC, 0xF3, 0xFF, 0xFC, 0xF3, 0xCF, 0x30, 0x0C, 0x63, + 0x00, 0x7B, 0xFC, 0xF3, 0xFF, 0xFC, 0xF3, 0xCF, 0x30, 0x31, 0xEC, 0xC0, + 0x7B, 0xFC, 0xF3, 0xFF, 0xFC, 0xF3, 0xCF, 0x30, 0x67, 0xD9, 0x80, 0x7B, + 0xFC, 0xF3, 0xFF, 0xFC, 0xF3, 0xCF, 0x30, 0xCF, 0x33, 0x1E, 0xFF, 0x3C, + 0xFF, 0xFF, 0x3C, 0xF3, 0xCC, 0x7B, 0x37, 0x8C, 0x7B, 0xFC, 0xF3, 0xFF, + 0xFC, 0xF3, 0xCF, 0x30, 0x3E, 0xFF, 0xE6, 0xCD, 0x9B, 0xF7, 0xFC, 0xF9, + 0xB3, 0x66, 0xFD, 0xE0, 0x7B, 0xFC, 0xF3, 0xC3, 0x0C, 0x30, 0xCF, 0x3F, + 0xDE, 0x19, 0xC0, 0xC1, 0x83, 0x00, 0xFF, 0xFC, 0x3E, 0xFB, 0x0C, 0x30, + 0xFF, 0xF0, 0x0C, 0x63, 0x00, 0xFF, 0xFC, 0x3E, 0xFB, 0x0C, 0x30, 0xFF, + 0xF0, 0x31, 0xEC, 0xC0, 0xFF, 0xFC, 0x3E, 0xFB, 0x0C, 0x30, 0xFF, 0xF0, + 0xCF, 0x30, 0x3F, 0xFF, 0x0F, 0xBE, 0xC3, 0x0C, 0x3F, 0xFC, 0xC1, 0x83, + 0x00, 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0xFF, 0xF0, 0x0C, 0x63, 0x00, + 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0xFF, 0xF0, 0x31, 0xEC, 0xC0, 0xFF, + 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0xFF, 0xF0, 0xCF, 0x30, 0x3F, 0xFC, 0xC3, + 0x0C, 0x30, 0xC3, 0x3F, 0xFC, 0x78, 0xF9, 0xBB, 0x36, 0x7E, 0xFD, 0xB3, + 0x66, 0xDD, 0xF3, 0xC0, 0x67, 0xD9, 0x80, 0xCF, 0x3E, 0xFF, 0xFF, 0x7C, + 0xF3, 0xCC, 0xC1, 0x83, 0x00, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, + 0xE0, 0x0C, 0x63, 0x00, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, 0xE0, + 0x31, 0xEC, 0xC0, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, 0xE0, 0x67, + 0xD9, 0x80, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, 0xE0, 0xCF, 0x30, + 0x1E, 0xFF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0xCD, 0xE3, 0x1E, 0xCC, + 0x01, 0x3D, 0x7E, 0x66, 0x66, 0x6E, 0x6E, 0x76, 0x76, 0x66, 0x66, 0x7E, + 0xBC, 0x80, 0xC1, 0x83, 0x00, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, + 0xE0, 0x0C, 0x63, 0x00, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, 0xE0, + 0x31, 0xEC, 0xC0, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xF3, 0xFD, 0xE0, 0xCF, + 0x30, 0x33, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0x0C, 0x63, 0x00, + 0xCF, 0x3C, 0xF3, 0x79, 0xE3, 0x0C, 0x30, 0xC0, 0xC3, 0x0F, 0xBF, 0xCF, + 0x3C, 0xFF, 0xFB, 0x0C, 0x30, 0x31, 0xEC, 0xF3, 0xCF, 0xEC, 0xF3, 0xCF, + 0xED, 0xB0, 0x80, 0xC1, 0x83, 0x00, 0x79, 0xF0, 0xDF, 0xFF, 0x3C, 0xFF, + 0x7C, 0x0C, 0x63, 0x00, 0x79, 0xF0, 0xDF, 0xFF, 0x3C, 0xFF, 0x7C, 0x31, + 0xEC, 0xC0, 0x79, 0xF0, 0xDF, 0xFF, 0x3C, 0xFF, 0x7C, 0x67, 0xD9, 0x80, + 0x79, 0xF0, 0xDF, 0xFF, 0x3C, 0xFF, 0x7C, 0xCF, 0x30, 0x1E, 0x7C, 0x37, + 0xFF, 0xCF, 0x3F, 0xDF, 0x39, 0xB3, 0x80, 0x79, 0xF0, 0xDF, 0xFF, 0x3C, + 0xFF, 0x7C, 0x76, 0x7F, 0x1B, 0x7B, 0xFF, 0xD8, 0xD8, 0xFF, 0x7F, 0x7B, + 0xEC, 0x30, 0xC3, 0x0C, 0x3F, 0x7C, 0x67, 0x00, 0xC1, 0x83, 0x00, 0x7B, + 0xFC, 0xF3, 0xFF, 0x0C, 0x3F, 0x7C, 0x0C, 0x63, 0x00, 0x7B, 0xFC, 0xF3, + 0xFF, 0x0C, 0x3F, 0x7C, 0x31, 0xEC, 0xC0, 0x7B, 0xFC, 0xF3, 0xFF, 0x0C, + 0x3F, 0x7C, 0xCF, 0x30, 0x1E, 0xFF, 0x3C, 0xFF, 0xC3, 0x0F, 0xDF, 0xC3, + 0x0C, 0x07, 0x38, 0xC6, 0x31, 0x8C, 0xF7, 0x80, 0x19, 0x98, 0x0E, 0x71, + 0x8C, 0x63, 0x19, 0xEF, 0x00, 0x31, 0xEC, 0xC0, 0x71, 0xC3, 0x0C, 0x30, + 0xC3, 0x1E, 0x78, 0xCF, 0x30, 0x1C, 0x70, 0xC3, 0x0C, 0x30, 0xC7, 0x9E, + 0x78, 0xC7, 0x86, 0x7F, 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0x67, 0xD9, + 0x80, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xF3, 0xCC, 0xC1, 0x83, 0x00, 0x7B, + 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, 0x0C, 0x63, 0x00, 0x7B, 0xFC, 0xF3, + 0xCF, 0x3C, 0xFF, 0x78, 0x31, 0xEC, 0xC0, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, + 0xFF, 0x78, 0x67, 0xD9, 0x80, 0x7B, 0xFC, 0xF3, 0xCF, 0x3C, 0xFF, 0x78, + 0xCF, 0x30, 0x1E, 0xFF, 0x3C, 0xF3, 0xCF, 0x3F, 0xDE, 0x30, 0xC0, 0x3F, + 0xFC, 0x03, 0x0C, 0x01, 0x3D, 0x7E, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x7E, + 0xBC, 0x80, 0xC1, 0x83, 0x00, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x7C, + 0x0C, 0x63, 0x00, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x7C, 0x31, 0xEC, + 0xC0, 0xCF, 0x3C, 0xF3, 0xCF, 0x3C, 0xFF, 0x7C, 0xCF, 0x30, 0x33, 0xCF, + 0x3C, 0xF3, 0xCF, 0x3F, 0xDF, 0x0C, 0x63, 0x00, 0xCF, 0x3C, 0xF3, 0xCF, + 0x3F, 0xDF, 0x0F, 0xFF, 0x80, 0xC3, 0x0C, 0x3E, 0xFF, 0x3C, 0xF3, 0xCF, + 0x3F, 0xFE, 0xC3, 0x00, 0xCF, 0x30, 0x33, 0xCF, 0x3C, 0xF3, 0xCF, 0xF7, + 0xC3, 0xFF, 0xE0 }; + +const GFXglyph Atari16pxGlyphs[] PROGMEM = { + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' U+0020 + { 1, 2, 12, 8, 3, -11 }, // 0x21 '!' U+0021 + { 4, 6, 6, 8, 1, -11 }, // 0x22 '"' U+0022 + { 9, 8, 10, 8, 0, -11 }, // 0x23 '#' U+0023 + { 19, 6, 14, 8, 1, -13 }, // 0x24 '$' U+0024 + { 30, 6, 10, 8, 1, -11 }, // 0x25 '%' U+0025 + { 38, 7, 14, 8, 0, -13 }, // 0x26 '&' U+0026 + { 51, 2, 6, 8, 3, -11 }, // 0x27 ''' U+0027 + { 53, 4, 12, 8, 3, -11 }, // 0x28 '(' U+0028 + { 59, 4, 12, 8, 1, -11 }, // 0x29 ')' U+0029 + { 65, 8, 10, 8, 0, -11 }, // 0x2a '*' U+002A + { 75, 6, 8, 8, 1, -10 }, // 0x2b '+' U+002B + { 81, 3, 6, 8, 2, -3 }, // 0x2c ',' U+002C + { 84, 6, 2, 8, 1, -7 }, // 0x2d '-' U+002D + { 86, 2, 4, 8, 3, -3 }, // 0x2e '.' U+002E + { 87, 6, 12, 8, 1, -11 }, // 0x2f '/' U+002F + { 96, 6, 12, 8, 1, -11 }, // 0x30 '0' U+0030 + { 105, 6, 12, 8, 1, -11 }, // 0x31 '1' U+0031 + { 114, 6, 12, 8, 1, -11 }, // 0x32 '2' U+0032 + { 123, 6, 12, 8, 1, -11 }, // 0x33 '3' U+0033 + { 132, 6, 12, 8, 1, -11 }, // 0x34 '4' U+0034 + { 141, 6, 12, 8, 1, -11 }, // 0x35 '5' U+0035 + { 150, 6, 12, 8, 1, -11 }, // 0x36 '6' U+0036 + { 159, 6, 12, 8, 1, -11 }, // 0x37 '7' U+0037 + { 168, 6, 12, 8, 1, -11 }, // 0x38 '8' U+0038 + { 177, 6, 12, 8, 1, -11 }, // 0x39 '9' U+0039 + { 186, 2, 10, 8, 3, -9 }, // 0x3a ':' U+003A + { 189, 3, 12, 8, 2, -9 }, // 0x3b ';' U+003B + { 194, 7, 9, 8, 0, -10 }, // 0x3c '<' U+003C + { 202, 6, 6, 8, 1, -9 }, // 0x3d '=' U+003D + { 207, 7, 9, 8, 0, -10 }, // 0x3e '>' U+003E + { 215, 6, 12, 8, 1, -11 }, // 0x3f '?' U+003F + { 224, 7, 12, 8, 0, -11 }, // 0x40 '@' U+0040 + { 235, 6, 12, 8, 1, -11 }, // 0x41 'A' U+0041 + { 244, 6, 12, 8, 1, -11 }, // 0x42 'B' U+0042 + { 253, 6, 12, 8, 1, -11 }, // 0x43 'C' U+0043 + { 262, 6, 12, 8, 1, -11 }, // 0x44 'D' U+0044 + { 271, 6, 12, 8, 1, -11 }, // 0x45 'E' U+0045 + { 280, 6, 12, 8, 1, -11 }, // 0x46 'F' U+0046 + { 289, 6, 12, 8, 1, -11 }, // 0x47 'G' U+0047 + { 298, 6, 12, 8, 1, -11 }, // 0x48 'H' U+0048 + { 307, 6, 12, 8, 1, -11 }, // 0x49 'I' U+0049 + { 316, 6, 12, 8, 1, -11 }, // 0x4a 'J' U+004A + { 325, 7, 12, 8, 0, -11 }, // 0x4b 'K' U+004B + { 336, 6, 12, 8, 1, -11 }, // 0x4c 'L' U+004C + { 345, 7, 12, 8, 0, -11 }, // 0x4d 'M' U+004D + { 356, 6, 12, 8, 1, -11 }, // 0x4e 'N' U+004E + { 365, 6, 12, 8, 1, -11 }, // 0x4f 'O' U+004F + { 374, 6, 12, 8, 1, -11 }, // 0x50 'P' U+0050 + { 383, 6, 12, 8, 1, -11 }, // 0x51 'Q' U+0051 + { 392, 7, 12, 8, 0, -11 }, // 0x52 'R' U+0052 + { 403, 6, 12, 8, 1, -11 }, // 0x53 'S' U+0053 + { 412, 6, 12, 8, 1, -11 }, // 0x54 'T' U+0054 + { 421, 6, 12, 8, 1, -11 }, // 0x55 'U' U+0055 + { 430, 6, 12, 8, 1, -11 }, // 0x56 'V' U+0056 + { 439, 7, 12, 8, 0, -11 }, // 0x57 'W' U+0057 + { 450, 6, 12, 8, 1, -11 }, // 0x58 'X' U+0058 + { 459, 6, 12, 8, 1, -11 }, // 0x59 'Y' U+0059 + { 468, 6, 12, 8, 1, -11 }, // 0x5a 'Z' U+005A + { 477, 4, 12, 8, 3, -11 }, // 0x5b '[' U+005B + { 483, 6, 12, 8, 1, -11 }, // 0x5c '\' U+005C + { 492, 4, 12, 8, 1, -11 }, // 0x5d ']' U+005D + { 498, 7, 8, 8, 0, -12 }, // 0x5e '^' U+005E + { 505, 7, 2, 8, 0, -1 }, // 0x5f '_' U+005F + { 507, 5, 7, 8, 1, -13 }, // 0x60 '`' U+0060 + { 512, 6, 9, 8, 1, -8 }, // 0x61 'a' U+0061 + { 519, 6, 12, 8, 1, -11 }, // 0x62 'b' U+0062 + { 528, 6, 9, 8, 1, -8 }, // 0x63 'c' U+0063 + { 535, 6, 12, 8, 1, -11 }, // 0x64 'd' U+0064 + { 544, 6, 9, 8, 1, -8 }, // 0x65 'e' U+0065 + { 551, 6, 12, 8, 1, -11 }, // 0x66 'f' U+0066 + { 560, 6, 11, 8, 1, -8 }, // 0x67 'g' U+0067 + { 569, 6, 12, 8, 1, -11 }, // 0x68 'h' U+0068 + { 578, 4, 12, 8, 2, -11 }, // 0x69 'i' U+0069 + { 584, 5, 14, 8, 1, -11 }, // 0x6a 'j' U+006A + { 593, 7, 12, 8, 0, -11 }, // 0x6b 'k' U+006B + { 604, 4, 12, 8, 2, -11 }, // 0x6c 'l' U+006C + { 610, 7, 9, 8, 0, -8 }, // 0x6d 'm' U+006D + { 618, 6, 9, 8, 1, -8 }, // 0x6e 'n' U+006E + { 625, 6, 9, 8, 1, -8 }, // 0x6f 'o' U+006F + { 632, 6, 11, 8, 1, -8 }, // 0x70 'p' U+0070 + { 641, 6, 11, 8, 1, -8 }, // 0x71 'q' U+0071 + { 650, 6, 9, 8, 1, -8 }, // 0x72 'r' U+0072 + { 657, 6, 9, 8, 1, -8 }, // 0x73 's' U+0073 + { 664, 6, 11, 8, 1, -10 }, // 0x74 't' U+0074 + { 673, 6, 9, 8, 1, -8 }, // 0x75 'u' U+0075 + { 680, 6, 9, 8, 1, -8 }, // 0x76 'v' U+0076 + { 687, 7, 9, 8, 0, -8 }, // 0x77 'w' U+0077 + { 695, 6, 9, 8, 1, -8 }, // 0x78 'x' U+0078 + { 702, 6, 11, 8, 1, -8 }, // 0x79 'y' U+0079 + { 711, 6, 9, 8, 1, -8 }, // 0x7a 'z' U+007A + { 718, 7, 14, 8, 0, -12 }, // 0x7b '{' U+007B + { 731, 2, 14, 8, 3, -12 }, // 0x7c '|' U+007C + { 735, 7, 14, 8, 0, -12 }, // 0x7d '}' U+007D + { 748, 7, 4, 8, 0, -8 }, // 0x7e '~' U+007E + { 752, 5, 11, 8, 1, -10 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370 + { 759, 1, 1, 8, 0, 0 }, // 0x80 'NO-BREAK SPACE' U+00A0 + { 760, 2, 12, 8, 3, -10 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1 + { 763, 6, 12, 8, 1, -11 }, // 0x82 'CENT SIGN' U+00A2 + { 772, 8, 13, 8, 0, -12 }, // 0x83 'POUND SIGN' U+00A3 + { 785, 5, 11, 8, 1, -10 }, // 0x84 'CURRENCY SIGN' U+00A4 + { 792, 6, 12, 8, 1, -11 }, // 0x85 'YEN SIGN' U+00A5 + { 801, 5, 11, 8, 1, -10 }, // 0x86 'BROKEN BAR' U+00A6 + { 808, 6, 12, 8, 1, -11 }, // 0x87 'SECTION SIGN' U+00A7 + { 817, 5, 11, 8, 1, -10 }, // 0x88 'DIAERESIS' U+00A8 + { 824, 7, 11, 8, 0, -11 }, // 0x89 'COPYRIGHT SIGN' U+00A9 + { 834, 6, 11, 8, 1, -9 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA + { 843, 7, 7, 8, 0, -7 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB + { 850, 6, 5, 8, 1, -4 }, // 0x8c 'NOT SIGN' U+00AC + { 854, 4, 2, 8, 2, -4 }, // 0x8d 'SOFT HYPHEN' U+00AD + { 855, 7, 11, 8, 0, -11 }, // 0x8e 'REGISTERED SIGN' U+00AE + { 865, 7, 2, 8, 0, -12 }, // 0x8f 'MACRON' U+00AF + { 867, 5, 5, 8, 1, -12 }, // 0x90 'DEGREE SIGN' U+00B0 + { 871, 6, 11, 8, 1, -10 }, // 0x91 'PLUS-MINUS SIGN' U+00B1 + { 880, 4, 6, 8, 1, -11 }, // 0x92 'SUPERSCRIPT TWO' U+00B2 + { 883, 4, 6, 8, 1, -11 }, // 0x93 'SUPERSCRIPT THREE' U+00B3 + { 886, 5, 11, 8, 1, -10 }, // 0x94 'ACUTE ACCENT' U+00B4 + { 893, 8, 10, 8, 0, -8 }, // 0x95 'MICRO SIGN' U+00B5 + { 903, 7, 12, 8, 0, -11 }, // 0x96 'PILCROW SIGN' U+00B6 + { 914, 4, 4, 8, 2, -6 }, // 0x97 'MIDDLE DOT' U+00B7 + { 916, 5, 11, 8, 1, -10 }, // 0x98 'CEDILLA' U+00B8 + { 923, 2, 6, 8, 1, -11 }, // 0x99 'SUPERSCRIPT ONE' U+00B9 + { 925, 6, 11, 8, 1, -9 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA + { 934, 7, 7, 8, 0, -7 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB + { 941, 5, 11, 8, 1, -10 }, // 0x9c 'VULGAR FRACTION ONE QUARTER' U+00BC + { 948, 5, 11, 8, 1, -10 }, // 0x9d 'VULGAR FRACTION ONE HALF' U+00BD + { 955, 5, 11, 8, 1, -10 }, // 0x9e 'VULGAR FRACTION THREE QUARTERS' U+00BE + { 962, 6, 12, 8, 1, -11 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF + { 971, 6, 14, 8, 1, -13 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0 + { 982, 6, 14, 8, 1, -13 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1 + { 993, 6, 14, 8, 1, -13 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2 + { 1004, 6, 14, 8, 1, -13 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3 + { 1015, 6, 13, 8, 1, -12 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4 + { 1025, 6, 14, 8, 1, -13 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5 + { 1036, 7, 13, 8, 0, -12 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6 + { 1048, 6, 14, 8, 1, -11 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7 + { 1059, 6, 14, 8, 1, -13 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8 + { 1070, 6, 14, 8, 1, -13 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9 + { 1081, 6, 14, 8, 1, -13 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA + { 1092, 6, 13, 8, 1, -12 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB + { 1102, 6, 14, 8, 1, -13 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC + { 1113, 6, 14, 8, 1, -13 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD + { 1124, 6, 14, 8, 1, -13 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE + { 1135, 6, 13, 8, 1, -12 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF + { 1145, 7, 12, 8, 0, -11 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0 + { 1156, 6, 13, 8, 1, -12 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1 + { 1166, 6, 14, 8, 1, -13 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2 + { 1177, 6, 14, 8, 1, -13 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3 + { 1188, 6, 14, 8, 1, -13 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4 + { 1199, 6, 14, 8, 1, -13 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5 + { 1210, 6, 13, 8, 1, -12 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6 + { 1220, 6, 5, 8, 1, -6 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7 + { 1224, 8, 14, 8, 0, -12 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8 + { 1238, 6, 14, 8, 1, -13 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9 + { 1249, 6, 14, 8, 1, -13 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA + { 1260, 6, 14, 8, 1, -13 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB + { 1271, 6, 13, 8, 1, -12 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC + { 1281, 6, 14, 8, 1, -13 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD + { 1292, 6, 12, 8, 1, -11 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE + { 1301, 6, 13, 8, 1, -11 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF + { 1311, 6, 13, 8, 1, -12 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0 + { 1321, 6, 13, 8, 1, -12 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1 + { 1331, 6, 13, 8, 1, -12 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2 + { 1341, 6, 13, 8, 1, -12 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3 + { 1351, 6, 12, 8, 1, -11 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4 + { 1360, 6, 13, 8, 1, -12 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5 + { 1370, 8, 9, 8, 0, -8 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6 + { 1379, 6, 11, 8, 1, -8 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7 + { 1388, 6, 13, 8, 1, -12 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8 + { 1398, 6, 13, 8, 1, -12 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9 + { 1408, 6, 13, 8, 1, -12 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA + { 1418, 6, 12, 8, 1, -11 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB + { 1427, 5, 13, 8, 1, -12 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC + { 1436, 5, 13, 8, 2, -12 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED + { 1445, 6, 13, 8, 1, -12 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE + { 1455, 6, 12, 8, 1, -11 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF + { 1464, 6, 13, 8, 1, -12 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0 + { 1474, 6, 13, 8, 1, -12 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1 + { 1484, 6, 13, 8, 1, -12 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2 + { 1494, 6, 13, 8, 1, -12 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3 + { 1504, 6, 13, 8, 1, -12 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4 + { 1514, 6, 13, 8, 1, -12 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5 + { 1524, 6, 12, 8, 1, -11 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6 + { 1533, 6, 8, 8, 1, -10 }, // 0xd7 'DIVISION SIGN' U+00F7 + { 1539, 8, 11, 8, 0, -9 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8 + { 1550, 6, 13, 8, 1, -12 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9 + { 1560, 6, 13, 8, 1, -12 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA + { 1570, 6, 13, 8, 1, -12 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB + { 1580, 6, 12, 8, 1, -11 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC + { 1589, 6, 15, 8, 1, -12 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD + { 1601, 6, 14, 8, 1, -11 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE + { 1612, 6, 14, 8, 1, -11 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF + +const GFXfont Atari16px PROGMEM = { + (uint8_t *)Atari16pxBitmaps, + (GFXglyph *)Atari16pxGlyphs, + 0x20, 0xDF, 16 }; + +// Approx. 2974 bytes diff --git a/lib/obp60task/Create_new_pages.txt b/lib/obp60task/Create_new_pages.txt index 5ad71fd..b318985 100644 --- a/lib/obp60task/Create_new_pages.txt +++ b/lib/obp60task/Create_new_pages.txt @@ -2,5 +2,5 @@ Craete new page for OBP60 1. Create page under /lib/obp60task/PageXXXX.cpp 2. Set page name in PageXXXX.cpp on file name 3. Register new page in /lib/obp60task/obp60task.cpp line 242 (registerAllPages) -4. Add new page in /lib/obp60task/config.json for each page type or add new page to gen_set.pl and run it to auto-generate the relevant section of config.json +4. Add new page in /lib/obp60task/config.json for each page type or add new page to gen_set.py and run it to auto-generate the relevant section of config.json diff --git a/lib/obp60task/LedSpiTask.h b/lib/obp60task/LedSpiTask.h index 5c2e82c..c058503 100644 --- a/lib/obp60task/LedSpiTask.h +++ b/lib/obp60task/LedSpiTask.h @@ -4,7 +4,6 @@ #include "GwApi.h" #include "OBP60Hardware.h" - class Color{ public: uint8_t r; @@ -33,6 +32,7 @@ static Color COLOR_BLACK=Color(0,0,0); Color setBrightness(const Color &color,uint8_t brightness); +enum BacklightMode {OFF, ON, SUN, BUS, TIME, KEY}; class LedInterface { private: @@ -92,5 +92,4 @@ class LedTaskData{ //task function void createSpiLedTask(LedTaskData *param); - -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 282a1e2..153ecbb 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -1,9 +1,6 @@ #ifdef BOARD_OBP60S3 #include -#define FASTLED_ALL_PINS_HARDWARE_SPI -#define FASTLED_ESP32_SPI_BUS FSPI -#define FASTLED_ESP32_FLASH_LOCK 1 #include // Driver for PCF8574 output modul from Horter #include // I2C #include // Driver for DS1388 RTC @@ -11,6 +8,7 @@ #include "Pagedata.h" #include "OBP60Hardware.h" #include "OBP60Extensions.h" +#include "imglib.h" // Character sets #include "Ubuntu_Bold8pt7b.h" @@ -24,6 +22,7 @@ #include "DSEG7Classic-BoldItalic30pt7b.h" #include "DSEG7Classic-BoldItalic42pt7b.h" #include "DSEG7Classic-BoldItalic60pt7b.h" +#include "Atari16px8b.h" // Key label font // E-Ink Display #define GxEPD_WIDTH 400 // Display width @@ -60,6 +59,10 @@ GxEPD2_BW & getdisplay(){r // Horter I2C moduls PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter +// FRAM +Adafruit_FRAM_I2C fram; +bool hasFRAM = false; + // Global vars bool blinkingLED = false; // Enable / disable blinking flash LED bool statusLED = false; // Actual status of flash LED on/off @@ -69,7 +72,7 @@ int uvDuration = 0; // Under voltage duration in n x 100ms LedTaskData *ledTaskData=nullptr; -void hardwareInit() +void hardwareInit(GwApi *api) { Wire.begin(); // Init PCF8574 digital outputs @@ -77,12 +80,27 @@ void hardwareInit() if(pcf8574_Out.begin()){ // Initialize PCF8574 pcf8574_Out.write8(255); // Clear all outputs } - -} - -void startLedTask(GwApi *api){ - ledTaskData=new LedTaskData(api); - createSpiLedTask(ledTaskData); + fram = Adafruit_FRAM_I2C(); + if (esp_reset_reason() == ESP_RST_POWERON) { + // help initialize FRAM + api->getLogger()->logDebug(GwLog::LOG,"Delaying I2C init for 250ms due to cold boot"); + delay(250); + } + // FRAM (e.g. MB85RC256V) + if (fram.begin(FRAM_I2C_ADDR)) { + hasFRAM = true; + uint16_t manufacturerID; + uint16_t productID; + fram.getDeviceID(&manufacturerID, &productID); + // Boot counter + uint8_t framcounter = fram.read(0x0000); + fram.write(0x0000, framcounter+1); + api->getLogger()->logDebug(GwLog::LOG,"FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter); + } + else { + hasFRAM = false; + api->getLogger()->logDebug(GwLog::LOG,"NO FRAM detected"); + } } void setPortPin(uint pin, bool value){ @@ -95,6 +113,11 @@ void togglePortPin(uint pin){ digitalWrite(pin, !digitalRead(pin)); } +void startLedTask(GwApi *api){ + ledTaskData=new LedTaskData(api); + createSpiLedTask(ledTaskData); +} + // Valid colors see hue Color colorMapping(const String &colorString){ Color color = COLOR_RED; @@ -108,6 +131,21 @@ Color colorMapping(const String &colorString){ return color; } +BacklightMode backlightMapping(const String &backlightString) { + static std::map const table = { + {"Off", BacklightMode::OFF}, + {"Control by Bus", BacklightMode::BUS}, + {"Control by Time", BacklightMode::TIME}, + {"Control by Key", BacklightMode::KEY}, + {"On", BacklightMode::ON}, + }; + auto it = table.find(backlightString); + if (it != table.end()) { + return it->second; + } + return BacklightMode::OFF; +} + // All defined colors see pixeltypes.h in FastLED lib void setBacklightLED(uint brightness, const Color &color){ if (ledTaskData == nullptr) return; @@ -179,6 +217,48 @@ String xdrDelete(String input){ return input; } +Point rotatePoint(const Point& origin, const Point& p, double angle) { + // rotate poind around origin by degrees + Point rotated; + double phi = angle * M_PI / 180.0; + double dx = p.x - origin.x; + double dy = p.y - origin.y; + rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy; + rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy; + return rotated; +} + +std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle) { + std::vector rotatedPoints; + for (const auto& p : pts) { + rotatedPoints.push_back(rotatePoint(origin, p, angle)); + } + return rotatedPoints; +} + +void fillPoly4(const std::vector& p4, uint16_t color) { + getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color); + getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color); +} + +// Draw centered text +void drawTextCenter(int16_t cx, int16_t cy, String text) { + int16_t x1, y1; + uint16_t w, h; + getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); + getdisplay().setCursor(cx - w / 2, cy + h / 2); + getdisplay().print(text); +} + +// Draw right aligned text +void drawTextRalign(int16_t x, int16_t y, String text) { + int16_t x1, y1; + uint16_t w, h; + getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); + getdisplay().setCursor(x - w, y); + getdisplay().print(text); +} + // Show a triangle for trend direction high (x, y is the left edge) void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){ getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color); @@ -207,15 +287,11 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa if(commonData.config->getBool(commonData.config->statusLine) == true){ - if(commonData.config->getString(commonData.config->displaycolor) == "Normal"){ - textcolor = GxEPD_BLACK; - } - else{ - textcolor = GxEPD_WHITE; - } + // Header separator line (optional) + // getdisplay().drawLine(0, 19, 399, 19, commonData.fgcolor); // Show status info - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData.fgcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(0, 15); if(commonData.status.wifiApOn){ @@ -250,20 +326,22 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa usbRxOld = commonData.status.usbRx; usbTxOld = commonData.status.usbTx; + // Display key lock status + if (commonData.keylock) { + getdisplay().drawXBitmap(170, 1, lock_bits, icon_width, icon_height, commonData.fgcolor); + } else { + getdisplay().drawXBitmap(166, 1, swipe_bits, swipe_width, swipe_height, commonData.fgcolor); + } + // Heartbeat as dot - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData.fgcolor); getdisplay().setFont(&Ubuntu_Bold32pt7b); getdisplay().setCursor(205, 14); - if(heartbeat == true){ - getdisplay().print("."); - } - else{ - getdisplay().print(" "); - } + getdisplay().print(heartbeat ? "." : " "); heartbeat = !heartbeat; // Date and time - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData.fgcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(230, 15); // Show date and time if date present @@ -293,6 +371,59 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa } } +void displayFooter(CommonData &commonData) { + + getdisplay().setFont(&Atari16px); + getdisplay().setTextColor(commonData.fgcolor); + + // Frame around key icon area + if (! commonData.keylock) { + // horizontal elements + const uint16_t top = 280; + const uint16_t bottom = 299; + getdisplay().drawLine(commonData.keydata[0].x, top, commonData.keydata[0].x+10, top, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[1].x-10, top, commonData.keydata[1].x+10, top, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[2].x-10, top, commonData.keydata[2].x+10, top, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[4].x-10, top, commonData.keydata[4].x+10, top, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[5].x-10, top, commonData.keydata[5].x+10, top, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[5].x + commonData.keydata[5].w - 10, top, commonData.keydata[5].x + commonData.keydata[5].w + 1, top, commonData.fgcolor); + // vertical key separators + getdisplay().drawLine(commonData.keydata[0].x + commonData.keydata[0].w, top, commonData.keydata[0].x + commonData.keydata[0].w, bottom, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[1].x + commonData.keydata[1].w, top, commonData.keydata[1].x + commonData.keydata[1].w, bottom, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[3].x + commonData.keydata[3].w, top, commonData.keydata[3].x + commonData.keydata[3].w, bottom, commonData.fgcolor); + getdisplay().drawLine(commonData.keydata[4].x + commonData.keydata[4].w, top, commonData.keydata[4].x + commonData.keydata[4].w, bottom, commonData.fgcolor); + for (int i = 0; i < 6; i++) { + uint16_t x, y; + if (commonData.keydata[i].label.length() > 0) { + // check if icon is enabled + String icon_name = commonData.keydata[i].label.substring(1); + if (commonData.keydata[i].label[0] == '#') { + if (iconmap.find(icon_name) != iconmap.end()) { + x = commonData.keydata[i].x + (commonData.keydata[i].w - icon_width) / 2; + y = commonData.keydata[i].y + (commonData.keydata[i].h - icon_height) / 2; + getdisplay().drawXBitmap(x, y, iconmap[icon_name], icon_width, icon_height, commonData.fgcolor); + } else { + // icon is missing, use name instead + x = commonData.keydata[i].x + commonData.keydata[i].w / 2; + y = commonData.keydata[i].y + commonData.keydata[i].h / 2; + drawTextCenter(x, y, icon_name); + } + } else { + x = commonData.keydata[i].x + commonData.keydata[i].w / 2; + y = commonData.keydata[i].y + commonData.keydata[i].h / 2; + drawTextCenter(x, y, commonData.keydata[i].label); + } + } + } + // Current page number in a small box + getdisplay().drawRect(190, 280, 23, 19, commonData.fgcolor); + drawTextCenter(200, 289, String(commonData.data.actpage)); + } else { + getdisplay().setCursor(65, 295); + getdisplay().print("Press 1 and 6 fast to unlock keys"); + } +} + // Sunset und sunrise calculation SunData calcSunsetSunrise(GwApi *api, double time, double date, double latitude, double longitude, double timezone){ GwLog *logger=api->getLogger(); @@ -404,4 +535,45 @@ void generatorGraphic(uint x, uint y, int pcolor, int bcolor){ getdisplay().print("G"); } -#endif \ No newline at end of file +// Function to handle HTTP image request +// http://192.168.15.1/api/user/OBP60Task/screenshot +void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request) { + GwLog *logger = api->getLogger(); + + String imgformat = api->getConfig()->getConfigItem(api->getConfig()->imageFormat,true)->asString(); + imgformat.toLowerCase(); + String filename = "Page" + String(*pageno) + "_" + pages[*pageno].description->pageName + "." + imgformat; + + logger->logDebug(GwLog::LOG,"handle image request [%s]: %s", imgformat, filename); + + uint8_t *fb = getdisplay().getBuffer(); // EPD framebuffer + std::vector imageBuffer; // image in webserver transferbuffer + String mimetype; + + if (imgformat == "gif") { + // GIF is commpressed with LZW, so small + mimetype = "image/gif"; + if (!createGIF(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT)) { + logger->logDebug(GwLog::LOG,"GIF creation failed: Hashtable init error!"); + return; + } + } + else if (imgformat == "bmp") { + // Microsoft BMP bitmap + mimetype = "image/bmp"; + createBMP(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT); + } + else { + // PBM simple portable bitmap + mimetype = "image/x-portable-bitmap"; + createPBM(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT); + } + + AsyncWebServerResponse *response = request->beginResponse_P(200, mimetype, (const uint8_t*)imageBuffer.data(), imageBuffer.size()); + response->addHeader("Content-Disposition", "inline; filename=" + filename); + request->send(response); + + imageBuffer.clear(); +} + +#endif diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index e02cd8b..a529da7 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -3,13 +3,28 @@ #include #include "OBP60Hardware.h" -#define FASTLED_ALL_PINS_HARDWARE_SPI -#define FASTLED_ESP32_SPI_BUS FSPI -#define FASTLED_ESP32_FLASH_LOCK 1 #include "LedSpiTask.h" #include // E-paper lib V2 +#include // I2C FRAM -// Fonts declarations for display (#inclues see OBP60Extensions.cpp) +// FRAM address reservations 32kB: 0x0000 - 0x7FFF +// 0x0000 - 0x03ff: single variables +#define FRAM_PAGE_NO 0x0002 +// Voltage page +#define FRAM_VOLTAGE_AVG 0x000A +#define FRAM_VOLTAGE_TREND 0x000B +#define FRAM_VOLTAGE_MODE 0x000C +#define FRAM_WIND_SIZE 0x000D +#define FRAM_WIND_SRC 0x000E +#define FRAM_WIND_MODE 0x000F +// Barograph history data +#define FRAM_BAROGRAPH_START 0x0400 +#define FRAM_BAROGRAPH_END 0x13FF + +extern Adafruit_FRAM_I2C fram; +extern bool hasFRAM; + +// Fonts declarations for display (#includes see OBP60Extensions.cpp) extern const GFXfont Ubuntu_Bold8pt7b; extern const GFXfont Ubuntu_Bold10pt7b; extern const GFXfont Ubuntu_Bold12pt7b; @@ -22,7 +37,7 @@ extern const GFXfont DSEG7Classic_BoldItalic30pt7b; extern const GFXfont DSEG7Classic_BoldItalic42pt7b; extern const GFXfont DSEG7Classic_BoldItalic60pt7b; -// Gloabl functions +// Global functions #ifdef DISPLAY_GDEW042T2 GxEPD2_BW & getdisplay(); #endif @@ -39,7 +54,15 @@ GxEPD2_BW & getdisplay(); GxEPD2_BW & getdisplay(); #endif -void hardwareInit(); +struct Point { + double x; + double y; +}; +Point rotatePoint(const Point& origin, const Point& p, double angle); +std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle); +void fillPoly4(const std::vector& p4, uint16_t color); + +void hardwareInit(GwApi *api); void setPortPin(uint pin, bool value); // Set port pin for extension port @@ -48,6 +71,7 @@ void togglePortPin(uint pin); // Toggle extension port pin Color colorMapping(const String &colorString); // Color mapping string to CHSV colors void setBacklightLED(uint brightness, const Color &color);// Set backlight LEDs void toggleBacklightLED(uint brightness,const Color &color);// Toggle backlight LEDs +BacklightMode backlightMapping(const String &backlightString);// Configuration string to value void setFlashLED(bool status); // Set flash LED void blinkingFlashLED(); // Blinking function for flash LED @@ -58,10 +82,14 @@ void setBuzzerPower(uint power); // Set buzzer power String xdrDelete(String input); // Delete xdr prefix from string +void drawTextCenter(int16_t cx, int16_t cy, String text); +void drawTextRalign(int16_t x, int16_t y, String text); + void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color); void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color); void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatValue *time, GwApi::BoatValue *hdop); // Draw display header +void displayFooter(CommonData &commonData); SunData calcSunsetSunrise(GwApi *api, double time, double date, double latitude, double longitude, double timezone); // Calulate sunset and sunrise @@ -70,4 +98,84 @@ void solarGraphic(uint x, uint y, int pcolor, int bcolor); // S void generatorGraphic(uint x, uint y, int pcolor, int bcolor); // Generator graphic with fill level void startLedTask(GwApi *api); -#endif \ No newline at end of file +void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUMBER], AsyncWebServerRequest *request); + +// Icons +#define icon_width 16 +#define icon_height 16 + +static unsigned char left_bits[] PROGMEM = { + 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x01, 0xf0, 0x01, 0xf8, 0x01, 0xfc, 0x7f, + 0xfe, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xfe, 0x7f, 0xfc, 0x7f, 0xf8, 0x01, + 0xf0, 0x01, 0xe0, 0x01, 0xc0, 0x01, 0x00, 0x00 }; + +static unsigned char right_bits[] PROGMEM = { + 0x00, 0x00, 0x80, 0x03, 0x80, 0x07, 0x80, 0x0f, 0x80, 0x1f, 0xfe, 0x3f, + 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0x80, 0x1f, + 0x80, 0x0f, 0x80, 0x07, 0x80, 0x03, 0x00, 0x00 }; + +static unsigned char lock_bits[] PROGMEM = { + 0xc0, 0x03, 0x60, 0x06, 0x30, 0x0c, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, + 0xfc, 0x3f, 0x04, 0x20, 0x04, 0x20, 0x84, 0x21, 0x84, 0x21, 0x84, 0x21, + 0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0xfc, 0x3f }; + +static unsigned char plus_bits[] PROGMEM = { + 0x00, 0x00, 0xe0, 0x01, 0x18, 0x06, 0x04, 0x08, 0xc4, 0x08, 0xc2, 0x10, + 0xf2, 0x13, 0xf2, 0x13, 0xc2, 0x10, 0xc4, 0x08, 0x04, 0x0c, 0x18, 0x1e, + 0xe0, 0x39, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0 }; + +static unsigned char minus_bits[] PROGMEM = { + 0x00, 0x00, 0xe0, 0x01, 0x18, 0x06, 0x04, 0x08, 0x04, 0x08, 0x02, 0x10, + 0xf2, 0x13, 0xf2, 0x13, 0x02, 0x10, 0x04, 0x08, 0x04, 0x0c, 0x18, 0x1e, + 0xe0, 0x39, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0 }; + +static unsigned char fram_bits[] PROGMEM = { + 0xf8, 0x1f, 0xff, 0xff, 0x9f, 0xff, 0x98, 0x1f, 0xf8, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, + 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f }; + +static unsigned char ap_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0xc2, 0x21, 0x30, 0x06, 0x08, 0x08, + 0xc0, 0x01, 0x20, 0x02, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }; + +static unsigned char dish_bits[] PROGMEM= { + 0x3c, 0x00, 0x42, 0x18, 0xfa, 0x1b, 0x02, 0x04, 0x02, 0x0a, 0x02, 0x09, + 0x82, 0x08, 0x06, 0x0a, 0x0e, 0x1b, 0x9c, 0x2b, 0x38, 0x2b, 0x74, 0x20, + 0xec, 0x1f, 0x1c, 0x00, 0xf4, 0x00, 0xfe, 0x03 }; + +static std::map iconmap = { + {"LEFT", left_bits}, + {"RIGHT", right_bits}, + {"LOCK", lock_bits}, + {"PLUS", plus_bits}, + {"MINUS", minus_bits}, + {"DISH", dish_bits}, + {"AP", ap_bits} +}; + +// Other symbols +#define swipe_width 24 +#define swipe_height 16 +static unsigned char swipe_bits[] PROGMEM = { + 0x00, 0x06, 0x00, 0x24, 0x09, 0x24, 0x12, 0x09, 0x48, 0x7f, 0x09, 0xfe, + 0x12, 0xb9, 0x48, 0x24, 0xc9, 0x25, 0x40, 0x49, 0x02, 0xa0, 0x49, 0x06, + 0x20, 0x01, 0x0a, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, + 0x80, 0x00, 0x04, 0x00, 0x01, 0x04, 0x00, 0x02, 0x02, 0x00, 0xfc, 0x01 }; + +#define exclamation_width 32 +#define exclamation_height 32 +static unsigned char exclamation_bits[] PROGMEM = { + 0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0xb0, 0x0d, 0x00, + 0x00, 0xd8, 0x1b, 0x00, 0x00, 0xec, 0x37, 0x00, 0x00, 0xf6, 0x6f, 0x00, + 0x00, 0x3b, 0xdc, 0x00, 0x80, 0x3d, 0xbc, 0x01, 0xc0, 0x3e, 0x7c, 0x03, + 0x60, 0x3f, 0xfc, 0x06, 0xb0, 0x3f, 0xfc, 0x0d, 0xd8, 0x3f, 0xfc, 0x1b, + 0xec, 0x3f, 0xfc, 0x37, 0xf6, 0x3f, 0xfc, 0x6f, 0xfb, 0x3f, 0xfc, 0xdf, + 0xfd, 0x3f, 0xfc, 0xbf, 0xfd, 0x3f, 0xfc, 0xbf, 0xfb, 0x3f, 0xfc, 0xdf, + 0xf6, 0x3f, 0xfc, 0x6f, 0xec, 0x3f, 0xfc, 0x37, 0xd8, 0xff, 0xff, 0x1b, + 0xb0, 0xff, 0xff, 0x0d, 0x60, 0x3f, 0xfc, 0x06, 0xc0, 0x3e, 0x7c, 0x03, + 0x80, 0x3d, 0xbc, 0x01, 0x00, 0x3b, 0xdc, 0x00, 0x00, 0xf6, 0x6f, 0x00, + 0x00, 0xec, 0x37, 0x00, 0x00, 0xd8, 0x1b, 0x00, 0x00, 0xb0, 0x0d, 0x00, + 0x00, 0x60, 0x06, 0x00, 0x00, 0xc0, 0x03, 0x00 }; + +#endif diff --git a/lib/obp60task/OBP60Hardware.h b/lib/obp60task/OBP60Hardware.h index 7f0abe2..f146d13 100644 --- a/lib/obp60task/OBP60Hardware.h +++ b/lib/obp60task/OBP60Hardware.h @@ -1,6 +1,7 @@ // General hardware definitions // CAN and RS485 bus pin definitions see obp60task.h +#ifdef HARDWARE_V21 // Direction pin for RS485 NMEA0183 #define OBP_DIRECTION_PIN 18 // I2C @@ -30,6 +31,8 @@ #define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator // Horter modules #define PCF8574_I2C_ADDR1 0x20 // First digital out module + // FRAM (e.g. MB85RC256V) + #define FRAM_I2C_ADDR 0x50 // SPI (E-Ink display, Extern Bus) #define OBP_SPI_CS 39 #define OBP_SPI_DC 40 @@ -39,11 +42,6 @@ #define OBP_SPI_DIN 48 #define SHOW_TIME 6000 // Show time in [ms] for logo and WiFi QR code #define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function) - #define MAX_PAGE_NUMBER 10 // Max number of pages for show data - #define FONT1 "Ubuntu_Bold8pt7b" - #define FONT2 "Ubuntu_Bold24pt7b" - #define FONT3 "Ubuntu_Bold32pt7b" - #define FONT4 "DSEG7Classic_BoldItalic80pt7b" // GPS (NEO-6M, NEO-M8N, ATGM336H) #define OBP_GPS_RX 2 @@ -57,7 +55,7 @@ #define TONE3 3500 // 3500Hz #define TONE4 4000 // 4000Hz // Analog Input - #define OBP_ANALOG0 4 // Analog input for voltage power supplay + #define OBP_ANALOG0 4 // Analog input for voltage power supply #define MIN_VOLTAGE 10.0 // Min voltage for under voltage detection (then goto deep sleep) #define POWER_FAIL_TIME 2 // in [ms] Accept min voltage until 2 x 1ms (for under voltage gaps by engine start) // Touch buttons @@ -72,9 +70,92 @@ #define NUM_FLASH_LED 1 // Number of flash LED #define OBP_FLASH_LED 7 // GPIO port // Backlight LEDs (6x WS2812B) - #define NUM_BACKLIGHT_LED 6 // Numebr of Backlight LEDs + #define NUM_BACKLIGHT_LED 6 // Number of Backlight LEDs #define OBP_BACKLIGHT_LED 15 // GPIO port // Power Rail #define OBP_POWER_50 5 // 5.0V power rail +#endif +// Hardware configuration for OBP60 LIGHT + +#ifdef HARDWARE_LIGHT + // Direction pin for RS485 NMEA0183 + #define OBP_DIRECTION_PIN 8 + // I2C + #define I2C_SPEED 10000UL // 10kHz clock speed on I2C bus + #define OBP_I2C_SDA 21 + #define OBP_I2C_SCL 38 + // DS1388 RTC + #define DS1388_I2C_ADDR 0x68 // Addr. 0x68 + // BME280 + #define BME280_I2C_ADDR 0x76 // Addr. 0x76 (0x77) + // BMP280 + #define BMP280_I2C_ADDR 0x77 // Addr. 0x77 (0x76) Attention: Pull up resistor + // BMP085 / BMP180 + #define BMP180_I2C_ADDR 0x77 // Addr. 0x77 (fix) + // SHT21 / HUT21 + #define SHT21_I2C_ADDR 0x40 // Addr. 0x40 (fix) + // AS5600 + #define AS5600_I2C_ADDR 0x36 // Addr. 0x36 (fix) + // INA219 + #define SHUNT_VOLTAGE 0.075 // Shunt voltage in V by max. current (75mV) + #define INA219_I2C_ADDR1 0x40 // Addr. 0x41 (fix A0 = 5V, A1 = GND) for battery + #define INA219_I2C_ADDR2 0x41 // Addr. 0x44 (fix A0 = GND, A1 = 5V) for solar panels + #define INA219_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator + // INA226 + #define INA226_I2C_ADDR1 0x41 // Addr. 0x41 (fix A0 = 5V, A1 = GND) for battery + #define INA226_I2C_ADDR2 0x44 // Addr. 0x44 (fix A0 = GND, A1 = 5V) for solar panels + #define INA226_I2C_ADDR3 0x45 // Addr. 0x45 (fix A0 = 5V, A1 = 5V) for generator + // Horter modules + #define PCF8574_I2C_ADDR1 0x20 // First digital out module + // FRAM (e.g. MB85RC256V) + #define FRAM_I2C_ADDR 0x50 + // SPI (E-Ink display, Extern Bus) + #define OBP_SPI_CS 45 + #define OBP_SPI_DC 46 + #define OBP_SPI_RST 47 + #define OBP_SPI_BUSY 48 + #define OBP_SPI_CLK 12 + #define OBP_SPI_DIN 11 + #define SHOW_TIME 6000 // Show time in [ms] for logo and WiFi QR code + #define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function) + // SPI SD-Card + #define SD_SPI_CS 10 + #define SD_SPI_MOSI 40 + #define SD_SPI_CLK 39 + #define SD_SPI_MISO 13 + + // GPS (NEO-6M, NEO-M8N, ATGM336H) + #define OBP_GPS_RX 19 + #define OBP_GPS_TX 20 + // 1Wire (DS18B20) + #define OBP_1WIRE 17 // External 1Wire + // Buzzer + #define OBP_BUZZER 18 + #define TONE1 1500 // 1500Hz + #define TONE2 2500 // 2500Hz + #define TONE3 3500 // 3500Hz + #define TONE4 4000 // 4000Hz + // Analog Input + #define OBP_ANALOG0 3 // Analog input for voltage power supply + #define MIN_VOLTAGE 10.0 // Min voltage for under voltage detection (then goto deep sleep) + #define POWER_FAIL_TIME 2 // in [ms] Accept min voltage until 2 x 1ms (for under voltage gaps by engine start) + // Buttons + #define UP 6 // Wheel up + #define DOWN 4 // Wheel down + #define CONF 5 // Wheel press + #define MENUE 2 // Button top + #define EXIT 1 // Button bottom + + // Flash LED (1x WS2812B) + #define NUM_FLASH_LED 1 // Number of flash LED + #define OBP_FLASH_LED 10 // GPIO port + // Backlight LEDs (6x WS2812B) + #define NUM_BACKLIGHT_LED 6 // Number of Backlight LEDs + #define OBP_BACKLIGHT_LED 40 // GPIO port + // Power Rail + #define OBP_POWER_50 41 // Power LED + #define OBP_POWER_EPD 7 // ePaper power + #define OBP_POWER_SD 42 // SD card power +#endif diff --git a/lib/obp60task/OBP60Keypad.h b/lib/obp60task/OBP60Keypad.h index c3a11d2..887015f 100644 --- a/lib/obp60task/OBP60Keypad.h +++ b/lib/obp60task/OBP60Keypad.h @@ -14,176 +14,277 @@ int keycode = 0; // Keycode of pressed key [0...8], 0 = nothing touched int keycode2 = 0; // Keycode of very short pressed key [0...8], 0 = nothing touched int keycodeold = 0; // Old keycode int keycodeold2 = 0; // Old keycode for short pressed key +int keystatus = 0; // Status of key [0...11] bool keyoff = false; // Disable all keys int keydelay = 250; // Delay after key pressed in [ms] bool keylock = false; // Key lock after pressed key is valid (repeat protection by conginous pressing) long starttime = 0; // Start time point for pressed key +void initKeys(CommonData &commonData) { + // coordinates for virtual keyboard keys -int readKeypad(uint thSensitivity) { - - // Touch sensor values - // 35000 - Not touched - // 50000 - Light toched with fingertip - // 70000 - Touched - // 170000 - Strong touched - uint32_t touchthreshold = (thSensitivity * -1200) + 170000; // thSensitivity 0...100% + static uint16_t top = 281; + static uint16_t width = 65; + static uint16_t height = 18; - int keystatus = 0; // Status of key [0...11], 0 = processed, 1...8 = key 1..8, 9 = right swipe , 10 = left swipe, 11 keys disabled - keycode = 0; + commonData.keydata[0].x = 0; + commonData.keydata[0].y = top; + commonData.keydata[0].w = width + 1; + commonData.keydata[0].h = height; - // Read key code - if(touchRead(14) > touchthreshold){ // Touch pad 1 - keypad[1] = 1; - } - else{ - keypad[1] = 0; - } - if(touchRead(13) > touchthreshold){ // Touch pad 2 - keypad[2] = 1; - } - else{ - keypad[2] = 0; - } - if(touchRead(12) > touchthreshold){ // Touch pad 3 - keypad[3] = 1; - } - else{ - keypad[3] = 0; - } - if(touchRead(11) > touchthreshold){ // Touch pad 4 - keypad[4] = 1; - } - else{ - keypad[4] = 0; - } - if(touchRead(10) > touchthreshold){ // Touch pad 5 - keypad[5] = 1; - } - else{ - keypad[5] = 0; - } - if(touchRead(9) > touchthreshold){ // Touch pad 6 - keypad[6] = 1; - } - else{ - keypad[6] = 0; - } - // Nothing touched - if(keypad[1] == 0 && keypad[2] == 0 && keypad[3] == 0 && keypad[4] == 0 && keypad[5] == 0 && keypad[6] == 0){ - keypad[0] = 1; - } - else{ - keypad[0] = 0; - } + commonData.keydata[1].x = commonData.keydata[0].x + commonData.keydata[0].w + 1; + commonData.keydata[1].y = top; + commonData.keydata[1].w = width; + commonData.keydata[1].h = height; - for (int i = 0; i < 9; i++) { - if(i > 0){ - // Convert keypad to keycode - if(keypad[i] == 1){ - key = 1; - } - else{ - key = 0; - } - keycode += key * i; - } - } + commonData.keydata[2].x = commonData.keydata[1].x + commonData.keydata[1].w + 1; + commonData.keydata[2].y = top; + commonData.keydata[2].w = width; + commonData.keydata[2].h = height; - // Detect short keynumber - if (keycode > 0 ){ - if(keylock == false){ - starttime = millis(); - keylock = true; + commonData.keydata[3].x = commonData.keydata[2].x + commonData.keydata[2].w + 1; + commonData.keydata[3].y = top; + commonData.keydata[3].w = width; + commonData.keydata[3].h = height; + + commonData.keydata[4].x = commonData.keydata[3].x + commonData.keydata[3].w + 1; + commonData.keydata[4].y = top; + commonData.keydata[4].w = width; + commonData.keydata[4].h = height; + + commonData.keydata[5].x = commonData.keydata[4].x + commonData.keydata[4].w + 1; + commonData.keydata[5].y = top; + commonData.keydata[5].w = width; + commonData.keydata[5].h = height; +} + + #ifdef HARDWARE_V21 + // Keypad functions for original OBP60 hardware + int readKeypad(uint thSensitivity) { + + // Touch sensor values + // 35000 - Not touched + // 50000 - Light toched with fingertip + // 70000 - Touched + // 170000 - Strong touched + uint32_t touchthreshold = (thSensitivity * -1200) + 170000; // thSensitivity 0...100% + + keystatus = 0; // Status of key [0...11], 0 = processed, 1...8 = key 1..8, 9 = right swipe , 10 = left swipe, 11 keys disabled + keycode = 0; + + // Read key code + if(touchRead(14) > touchthreshold){ // Touch pad 1 + keypad[1] = 1; } - if (keycode != keycodeold){ - keylock = false; + else{ + keypad[1] = 0; } - // Detect a very short keynumber (10ms) - if (millis() > starttime + 10 && keycode == keycodeold && keylock == true) { - // Process only valid keys - if(keycode == 1 || keycode == 6){ - keycode2 = keycode; + if(touchRead(13) > touchthreshold){ // Touch pad 2 + keypad[2] = 1; + } + else{ + keypad[2] = 0; + } + if(touchRead(12) > touchthreshold){ // Touch pad 3 + keypad[3] = 1; + } + else{ + keypad[3] = 0; + } + if(touchRead(11) > touchthreshold){ // Touch pad 4 + keypad[4] = 1; + } + else{ + keypad[4] = 0; + } + if(touchRead(10) > touchthreshold){ // Touch pad 5 + keypad[5] = 1; + } + else{ + keypad[5] = 0; + } + if(touchRead(9) > touchthreshold){ // Touch pad 6 + keypad[6] = 1; + } + else{ + keypad[6] = 0; + } + // Nothing touched + if(keypad[1] == 0 && keypad[2] == 0 && keypad[3] == 0 && keypad[4] == 0 && keypad[5] == 0 && keypad[6] == 0){ + keypad[0] = 1; + } + else{ + keypad[0] = 0; + } + + for (int i = 0; i < 9; i++) { + if(i > 0){ + // Convert keypad to keycode + if(keypad[i] == 1){ + key = 1; + } + else{ + key = 0; + } + keycode += key * i; + } + } + + // Detect short keynumber + if (keycode > 0 ){ + if(keylock == false){ + starttime = millis(); + keylock = true; } - // Clear by unvalid keys - else{ + if (keycode != keycodeold){ + keylock = false; + } + // Detect a very short keynumber (10ms) + if (millis() > starttime + 10 && keycode == keycodeold && keylock == true) { + // Process only valid keys + if(keycode == 1 || keycode == 6){ + keycode2 = keycode; + } + // Clear by unvalid keys + else{ + keycode2 = 0; + keycodeold2 = 0; + } + } + // Timeout for very short pressed key + if(millis() > starttime + 200){ + keycode2 = 0; + } + // Detect a short keynumber (200ms) + if (keyoff == false && millis() > starttime + 200 && keycode == keycodeold && keylock == true) { + keystatus = keycode; + keycode = 0; + keycodeold = 0; keycode2 = 0; keycodeold2 = 0; + buzzer(TONE4, 100); + keylock = false; + delay(keydelay); } } - // Timeout for very short pressed key - if(millis() > starttime + 200){ - keycode2 = 0; - } - // Detect a short keynumber (200ms) - if (keyoff == false && millis() > starttime + 200 && keycode == keycodeold && keylock == true) { - keystatus = keycode; + + // System page with key 5 and 4 in fast series + if (keycode2 == 5 && keycodeold2 == 4) { keycode = 0; keycodeold = 0; keycode2 = 0; keycodeold2 = 0; - buzzer(TONE4, 100); + keystatus = 12; + } + + // Key lock with key 1 and 6 or 6 and 1 in fast series + if((keycode2 == 1 && keycodeold2 == 6) || (keycode2 == 6 && keycodeold2 == 1)) { + keycode = 0; + keycodeold = 0; + keycode2 = 0; + keycodeold2 = 0; + buzzer(TONE4, 1000); keylock = false; delay(keydelay); + keyoff = !keyoff; + keystatus = 11; } + + // Detect swipe right + if (keyoff == false && keycode > 0 && keycodeold > 0 && keycode > keycodeold && !((keycode == 1 && keycodeold == 6) || (keycode == 6 && keycodeold == 1))){ + //if (keycode > 0 && keycodeold > 0 && keycode > keycodeold){ + keycode = 0; + keycodeold = 0; + keycode2 = 0; + keycodeold2 = 0; + keystatus = 9; + buzzer(TONE3, 150); + buzzer(TONE4, 150); + } + + // Detect swipe left + if (keyoff == false && keycode > 0 && keycodeold > 0 && keycode < keycodeold && !((keycode == 1 && keycodeold == 6) || (keycode == 6 && keycodeold == 1))){ + //if (keycode > 0 && keycodeold > 0 && keycode < keycodeold){ + keycode = 0; + keycodeold = 0; + keycode2 = 0; + keycodeold2 = 0; + keystatus = 10; + buzzer(TONE4, 150); + buzzer(TONE3, 150); + } + + // Reset keylock after release + if (keycode == 0){ + keylock = false; + } + + // Copy keycode + keycodeold = keycode; + keycodeold2 = keycode2; + + return keystatus; } + #endif - // System page with key 5 and 4 in fast series - if (keycode2 == 5 && keycodeold2 == 4) { - keycode = 0; - keycodeold = 0; - keycode2 = 0; - keycodeold2 = 0; - keystatus = 12; + #ifdef HARDWARE_LIGHT + int readSensorpads(){ + // Read key code + if(digitalRead(UP) == LOW){ + keycode = 10; // Left swipe + } + else if(digitalRead(DOWN) == LOW){ + keycode = 9; // Right swipe + } + else if(digitalRead(CONF) == LOW){ + keycode = 3; // Key 3 + } + else if(digitalRead(MENUE) == LOW){ + keycode = 1; // Key 1 + } + else if(digitalRead(EXIT) == LOW){ + keycode = 2; // Key 2 + } + else{ + keycode = 0; // No key activ + } + return keycode; + } + + // Keypad functions for OBP60 clone (thSensitivity is inactiv) + int readKeypad(uint thSensitivity) { + pinMode(UP, INPUT); + pinMode(DOWN, INPUT); + pinMode(CONF, INPUT); + pinMode(MENUE, INPUT); + pinMode(EXIT, INPUT); + + // Raed pad values + readSensorpads(); + + // Detect key + if (keycode > 0 ){ + if(keycode != keycodeold){ + starttime = millis(); // Start key pressed + keycodeold = keycode; + } + // If key pressed longer than 200ms + if(millis() > starttime + 200 && keycode == keycodeold) { + keystatus = keycode; + // Copy keycode + keycodeold = keycode; + while(readSensorpads() > 0){} // Wait for pad lesease + delay(keydelay); + } + } + else{ + keycode = 0; + keycodeold = 0; + keystatus = 0; + } + + return keystatus; } + #endif - // Key lock with key 1 and 6 or 6 and 1 in fast series - if((keycode2 == 1 && keycodeold2 == 6) || (keycode2 == 6 && keycodeold2 == 1)) { - keycode = 0; - keycodeold = 0; - keycode2 = 0; - keycodeold2 = 0; - buzzer(TONE4, 1000); - keylock = false; - delay(keydelay); - keyoff = !keyoff; - keystatus = 11; - } - - // Detect swipe right - if (keyoff == false && keycode > 0 && keycodeold > 0 && keycode > keycodeold && !((keycode == 1 && keycodeold == 6) || (keycode == 6 && keycodeold == 1))){ - //if (keycode > 0 && keycodeold > 0 && keycode > keycodeold){ - keycode = 0; - keycodeold = 0; - keycode2 = 0; - keycodeold2 = 0; - keystatus = 9; - buzzer(TONE3, 150); - buzzer(TONE4, 150); - } - - // Detect swipe left - if (keyoff == false && keycode > 0 && keycodeold > 0 && keycode < keycodeold && !((keycode == 1 && keycodeold == 6) || (keycode == 6 && keycodeold == 1))){ - //if (keycode > 0 && keycodeold > 0 && keycode < keycodeold){ - keycode = 0; - keycodeold = 0; - keycode2 = 0; - keycodeold2 = 0; - keystatus = 10; - buzzer(TONE4, 150); - buzzer(TONE3, 150); - } - - // Reset keylock after release - if (keycode == 0){ - keylock = false; - } - - // Copy keycode - keycodeold = keycode; - keycodeold2 = keycode2; - - return keystatus; -} - -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/OBP60QRWiFi.h b/lib/obp60task/OBP60QRWiFi.h index 6e83067..3bd7646 100644 --- a/lib/obp60task/OBP60QRWiFi.h +++ b/lib/obp60task/OBP60QRWiFi.h @@ -5,21 +5,7 @@ #include "OBP60Extensions.h" #include "qrcode.h" -void qrWiFi(String ssid, String passwd, String displaycolor){ - // Set display color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } +void qrWiFi(String ssid, String passwd, uint16_t fgcolor, uint16_t bgcolor){ // Set start point and pixel size int16_t box_x = 100; // X offset @@ -40,7 +26,7 @@ void qrWiFi(String ssid, String passwd, String displaycolor){ // Each horizontal module for (uint8_t x = 0; x < qrcode.size; x++) { if(qrcode_getModule(&qrcode, x, y)){ - getdisplay().fillRect(box_x, box_y, box_s, box_s, pixelcolor); + getdisplay().fillRect(box_x, box_y, box_s, box_s, fgcolor); } else { getdisplay().fillRect(box_x, box_y, box_s, box_s, bgcolor); } @@ -50,10 +36,10 @@ void qrWiFi(String ssid, String passwd, String displaycolor){ box_x = init_x; } getdisplay().setFont(&Ubuntu_Bold32pt7b); - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(fgcolor); getdisplay().setCursor(140, 285); getdisplay().print("WiFi"); getdisplay().nextPage(); // Full Refresh } -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/OBPSensorTask.cpp b/lib/obp60task/OBPSensorTask.cpp index be9f1b1..e2faa5d 100644 --- a/lib/obp60task/OBPSensorTask.cpp +++ b/lib/obp60task/OBPSensorTask.cpp @@ -198,7 +198,7 @@ void sensorTask(void *param){ else{ api->getLogger()->logDebug(GwLog::LOG,"Modul BME280 found"); sensors.airTemperature = bme280.readTemperature(); - sensors.airPressure = bme280.readPressure()/100; + sensors.airPressure = bme280.readPressure(); sensors.airHumidity = bme280.readHumidity(); BME280_ready = true; } @@ -210,7 +210,7 @@ void sensorTask(void *param){ else{ api->getLogger()->logDebug(GwLog::LOG,"Modul BMP280 found"); sensors.airTemperature = bmp280.readTemperature(); - sensors.airPressure =bmp280.readPressure()/100; + sensors.airPressure = bmp280.readPressure(); BMP280_ready = true; } } @@ -221,7 +221,7 @@ void sensorTask(void *param){ else{ api->getLogger()->logDebug(GwLog::LOG,"Modul BMP085/BMP180 found"); sensors.airTemperature = bmp085.readTemperature(); - sensors.airPressure =bmp085.readPressure()/100; + sensors.airPressure = bmp085.readPressure(); BMP180_ready = true; } } @@ -456,7 +456,7 @@ void sensorTask(void *param){ } } - // Send supplay voltage value all 1s + // Send supply voltage value all 1s if(millis() > starttime5 + 1000 && String(powsensor1) == "off"){ starttime5 = millis(); sensors.batteryVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 @@ -479,10 +479,10 @@ void sensorTask(void *param){ starttime6 = millis(); unsigned char TempSource = 2; // Inside temperature unsigned char PressureSource = 0; // Atmospheric pressure - unsigned char HumiditySource=0; // Inside humidity + unsigned char HumiditySource = 0; // Inside humidity if(envsensor == "BME280" && BME280_ready == true){ sensors.airTemperature = bme280.readTemperature(); - sensors.airPressure = bme280.readPressure()/100; + sensors.airPressure = bme280.readPressure(); sensors.airHumidity = bme280.readHumidity(); // Send to NMEA200 bus if(!isnan(sensors.airTemperature)){ @@ -494,33 +494,33 @@ void sensorTask(void *param){ api->sendN2kMessage(N2kMsg); } if(!isnan(sensors.airPressure)){ - SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) mBarToPascal(PressureSource), sensors.airPressure); + SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) PressureSource, sensors.airPressure); api->sendN2kMessage(N2kMsg); } } else if(envsensor == "BMP280" && BMP280_ready == true){ sensors.airTemperature = bmp280.readTemperature(); - sensors.airPressure =bmp280.readPressure()/100; + sensors.airPressure = bmp280.readPressure(); // Send to NMEA200 bus if(!isnan(sensors.airTemperature)){ SetN2kPGN130312(N2kMsg, 0, 0,(tN2kTempSource) TempSource, CToKelvin(sensors.airTemperature), N2kDoubleNA); api->sendN2kMessage(N2kMsg); } if(!isnan(sensors.airPressure)){ - SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) mBarToPascal(PressureSource), sensors.airPressure); + SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) PressureSource, sensors.airPressure); api->sendN2kMessage(N2kMsg); } } else if((envsensor == "BMP085" || envsensor == "BMP180") && BMP180_ready == true){ sensors.airTemperature = bmp085.readTemperature(); - sensors.airPressure =bmp085.readPressure()/100; + sensors.airPressure = bmp085.readPressure(); // Send to NMEA200 bus if(!isnan(sensors.airTemperature)){ SetN2kPGN130312(N2kMsg, 0, 0,(tN2kTempSource) TempSource, CToKelvin(sensors.airTemperature), N2kDoubleNA); api->sendN2kMessage(N2kMsg); } if(!isnan(sensors.airPressure)){ - SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) mBarToPascal(PressureSource), sensors.airPressure); + SetN2kPGN130314(N2kMsg, 0, 0, (tN2kPressureSource) PressureSource, sensors.airPressure); api->sendN2kMessage(N2kMsg); } } @@ -698,4 +698,4 @@ void sensorTask(void *param){ void createSensorTask(SharedData *shared){ xTaskCreate(sensorTask,"readSensors",10000,shared,3,NULL); } -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageApparentWind.cpp b/lib/obp60task/PageApparentWind.cpp deleted file mode 100644 index 92849c3..0000000 --- a/lib/obp60task/PageApparentWind.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#ifdef BOARD_OBP60S3 - -#include "Pagedata.h" -#include "OBP60Extensions.h" - -class PageApparentWind : public Page -{ -bool keylock = false; // Keylock -int16_t lp = 80; // Pointer length - -public: - PageApparentWind(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageApparentWind"); - } - - // Key functions - virtual int handleKey(int key){ - // Reduce instrument size - if(key == 2){ // Code for reduce - lp = lp - 10; - if(lp < 10){ - lp = 10; - } - return 0; // Commit the key - } - - // Enlarge instrument size - if(key == 5){ // Code for enlarge - lp = lp + 10; - if(lp > 80){ - lp = 80; - } - return 0; // Commit the key - } - - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock - return 0; // Commit the key - } - return key; - } - - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; - - static String svalue1old = ""; - static String unit1old = ""; - static String svalue2old = ""; - static String unit2old = ""; - - // Get config data - String lengthformat = config->getString(config->lengthFormat); - // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); - bool holdvalues = config->getBool(config->holdvalues); - String flashLED = config->getString(config->flashLED); - String backlightMode = config->getString(config->backlight); - - // Get boat values for AWS - GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue) - String name1 = bvalue1->getName().c_str(); // Value name - name1 = name1.substring(0, 6); // String length limit for value name - double value1 = bvalue1->value; // Value as double in SI unit - // bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value - - // Get boat values for AWD - GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue) - String name2 = bvalue2->getName().c_str(); // Value name - name2 = name2.substring(0, 6); // String length limit for value name - double value2 = bvalue2->value; // Value as double in SI unit - // bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value - - // Optical warning by limit violation (unused) - if(String(flashLED) == "Limit Violation"){ - setBlinkingLED(false); - setFlashLED(false); - } - - // Logging boat values - if (bvalue1 == NULL) return; - LOG_DEBUG(GwLog::LOG,"Drawing at PageApparentWind, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2); - - // Draw page - //*********************************************************** - - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } - // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - - // Show values AWS - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold20pt7b); - getdisplay().setCursor(20, 50); - if(holdvalues == false){ - getdisplay().print(name1); // Value name - getdisplay().print(": "); - getdisplay().print(svalue1); // Value - getdisplay().print(" "); - getdisplay().print(unit1); // Unit - } - else{ - getdisplay().print(name1); // Value name - getdisplay().print(": "); - getdisplay().print(svalue1old); // Value old - getdisplay().print(" "); - getdisplay().print(unit1old); // Unit old - } - - // Show values AWD - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold20pt7b); - getdisplay().setCursor(20, 260); - if(holdvalues == false){ - getdisplay().print(name2); // Value name - getdisplay().print(": "); - getdisplay().print(svalue2); // Value - getdisplay().print(" "); - getdisplay().print(unit2); // Unit - } - else{ - getdisplay().print(name2); // Value name - getdisplay().print(": "); - getdisplay().print(svalue2old); // Value old - getdisplay().print(" "); - getdisplay().print(unit2old); // Unit old - } - - // Draw wind pointer - static int16_t x0 = 200; // Center point - static int16_t y0 = 145; - static int16_t x1 = x0; // Start point for pointer - static int16_t y1 = y0; - static int16_t x2 = x0; // End point for pointer - static int16_t y2 = y0; - - //Draw instrument - getdisplay().fillCircle(x0, y0, lp + 5, pixelcolor); // Black circle - getdisplay().fillCircle(x0, y0, lp + 1, bgcolor); // White circle - - // Calculation end point of pointer - value2 = value2 - 3.14 / 2; - x1 = x0 + cos(value2) * lp * 0.6; - y1 = y0 + sin(value2) * lp * 0.6; - x2 = x0 + cos(value2) * lp; - y2 = y0 + sin(value2) * lp; - getdisplay().drawLine(x1, y1, x2, y2, pixelcolor); - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - - // Update display - getdisplay().nextPage(); // Partial update (fast) - - }; -}; - -static Page *createPage(CommonData &common){ - return new PageApparentWind(common); -} -/** - * with the code below we make this page known to the PageTask - * we give it a type (name) that can be selected in the config - * we define which function is to be called - * and we provide the number of user parameters we expect (0 here) - * and will will provide the names of the fixed values we need - */ -PageDescription registerPageApparentWind( - "ApparentWind", // Page name - createPage, // Action - 0, // Number of bus values depends on selection in Web configuration - {"AWS","AWA"}, // Bus values we need in the page - true // Show display header on/off -); - -#endif \ No newline at end of file diff --git a/lib/obp60task/PageBME280.cpp b/lib/obp60task/PageBME280.cpp index 7c17b73..f0f02c0 100644 --- a/lib/obp60task/PageBME280.cpp +++ b/lib/obp60task/PageBME280.cpp @@ -5,24 +5,24 @@ class PageBME280 : public Page { - bool keylock = false; // Keylock - public: PageBME280(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageBME280"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageBME280"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; double value1 = 0; double value2 = 0; @@ -34,7 +34,6 @@ class PageBME280 : public Page // Get config data String tempformat = config->getString(config->tempFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); String useenvsensor = config->getString(config->useEnvSensor); @@ -43,7 +42,7 @@ class PageBME280 : public Page String name1 = "Temp"; // Value name name1 = name1.substring(0, 6); // String length limit for value name if(simulation == false){ - value1 = commonData.data.airTemperature; // Value as double in SI unit + value1 = commonData->data.airTemperature; // Value as double in SI unit } else{ value1 = 23.0 + float(random(0, 10)) / 10.0; @@ -61,7 +60,7 @@ class PageBME280 : public Page String name2 = "Humid"; // Value name name2 = name2.substring(0, 6); // String length limit for value name if(simulation == false){ - value2 = commonData.data.airHumidity; // Value as double in SI unit + value2 = commonData->data.airHumidity; // Value as double in SI unit } else{ value2 = 43 + float(random(0, 4)); @@ -79,14 +78,14 @@ class PageBME280 : public Page String name3 = "Press"; // Value name name3 = name3.substring(0, 6); // String length limit for value name if(simulation == false){ - value3 = commonData.data.airPressure; // Value as double in SI unit + value3 = commonData->data.airPressure; // Value as double in SI unit } else{ value3 = 1006 + float(random(0, 5)); } // Display data when sensor activated if((String(useenvsensor) == "BME280") or (String(useenvsensor) == "BMP280")){ - svalue3 = String(value3, 0); // Formatted value as string including unit conversion and switching decimal places + svalue3 = String(value3 / 100, 1); // Formatted value as string including unit conversion and switching decimal places } else{ svalue3 = "---"; @@ -105,33 +104,19 @@ class PageBME280 : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 55); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 90); getdisplay().print(unit1); // Unit @@ -146,18 +131,16 @@ class PageBME280 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 105, 400, 3, pixelcolor); + getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 145); getdisplay().print(name2); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 180); getdisplay().print(unit2); // Unit @@ -172,47 +155,27 @@ class PageBME280 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 195, 400, 3, pixelcolor); + getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 235); getdisplay().print(name3); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 270); getdisplay().print(unit3); // Unit // Switch font if format for any values getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b); - getdisplay().setCursor(180, 270); + getdisplay().setCursor(140, 270); // Show bus data getdisplay().print(svalue3); // Real value as formated string - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageBattery.cpp b/lib/obp60task/PageBattery.cpp index 3cb3fc7..bbde098 100644 --- a/lib/obp60task/PageBattery.cpp +++ b/lib/obp60task/PageBattery.cpp @@ -5,12 +5,17 @@ class PageBattery : public Page { - bool keylock = false; // Keylock int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s public: PageBattery(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageBattery"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageBattery"); + } + + virtual void setupKeys(){ + Page::setupKeys(); + commonData->keydata[0].label = "AVG"; } virtual int handleKey(int key){ @@ -23,15 +28,15 @@ class PageBattery : public Page // Code for keylock if(key == 11){ - keylock = !keylock; // Toggle keylock + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function double value1 = 0; @@ -47,7 +52,6 @@ class PageBattery : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); String powsensor1 = config->getString(config->usePowSensor1); @@ -59,19 +63,19 @@ class PageBattery : public Page // Switch average values switch (average) { case 0: - value1 = commonData.data.batteryVoltage; // Live data + value1 = commonData->data.batteryVoltage; // Live data break; case 1: - value1 = commonData.data.batteryVoltage10; // Average 10s + value1 = commonData->data.batteryVoltage10; // Average 10s break; case 2: - value1 = commonData.data.batteryVoltage60; // Average 60s + value1 = commonData->data.batteryVoltage60; // Average 60s break; case 3: - value1 = commonData.data.batteryVoltage300; // Average 300s + value1 = commonData->data.batteryVoltage300; // Average 300s break; default: - value1 = commonData.data.batteryVoltage; // Default + value1 = commonData->data.batteryVoltage; // Default break; } } @@ -88,19 +92,19 @@ class PageBattery : public Page if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){ switch (average) { case 0: - value2 = commonData.data.batteryCurrent; // Live data + value2 = commonData->data.batteryCurrent; // Live data break; case 1: - value2 = commonData.data.batteryCurrent10; // Average 10s + value2 = commonData->data.batteryCurrent10; // Average 10s break; case 2: - value2 = commonData.data.batteryCurrent60; // Average 60s + value2 = commonData->data.batteryCurrent60; // Average 60s break; case 3: - value2 = commonData.data.batteryCurrent300; // Average 300s + value2 = commonData->data.batteryCurrent300; // Average 300s break; default: - value2 = commonData.data.batteryCurrent; // Default + value2 = commonData->data.batteryCurrent; // Default break; } } @@ -117,19 +121,19 @@ class PageBattery : public Page if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){ switch (average) { case 0: - value3 = commonData.data.batteryPower; // Live data + value3 = commonData->data.batteryPower; // Live data break; case 1: - value3 = commonData.data.batteryPower10; // Average 10s + value3 = commonData->data.batteryPower10; // Average 10s break; case 2: - value3 = commonData.data.batteryPower60; // Average 60s + value3 = commonData->data.batteryPower60; // Average 60s break; case 3: - value3 = commonData.data.batteryPower300; // Average 300s + value3 = commonData->data.batteryPower300; // Average 300s break; default: - value3 = commonData.data.batteryPower; // Default + value3 = commonData->data.batteryPower; // Default break; } } @@ -153,25 +157,11 @@ class PageBattery : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // Show average settings - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData->fgcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); switch (average) { case 0: @@ -219,13 +209,11 @@ class PageBattery : public Page // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 55); getdisplay().print(name1); // Value name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 90); getdisplay().print(unit1); // Unit @@ -245,18 +233,16 @@ class PageBattery : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 105, 400, 3, pixelcolor); + getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 145); getdisplay().print(name2); // Value name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 180); getdisplay().print(unit2); // Unit @@ -276,18 +262,16 @@ class PageBattery : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 195, 400, 3, pixelcolor); + getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 235); getdisplay().print(name3); // Value name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 270); getdisplay().print(unit3); // Unit @@ -304,27 +288,6 @@ class PageBattery : public Page getdisplay().print("---"); // No sensor data (sensor is off) } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(10, 290); - getdisplay().print("[AVG]"); - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageBattery2.cpp b/lib/obp60task/PageBattery2.cpp index d2c3e47..b8694a7 100644 --- a/lib/obp60task/PageBattery2.cpp +++ b/lib/obp60task/PageBattery2.cpp @@ -7,15 +7,21 @@ class PageBattery2 : public Page { bool init = false; // Marker for init done -bool keylock = false; // Keylock int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s bool trend = true; // Trend indicator [0|1], 0=off, 1=on double raw = 0; public: PageBattery2(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageBattery2"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageBattery2"); } + + virtual void setupKeys(){ + Page::setupKeys(); + commonData->keydata[0].label = "AVG"; + } + virtual int handleKey(int key){ // Change average if(key == 1){ @@ -32,16 +38,16 @@ public: // Code for keylock if(key == 11){ - keylock = !keylock; // Toggle keylock + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) + virtual void displayPage(PageData &pageData) { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Polynominal coefficients second order for battery energy level calculation // index 0 = Pb, 1 = Gel, 2 = AGM, 3 = LiFePo4 @@ -53,7 +59,6 @@ public: // Get config data bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String batVoltage = config->getString(config->batteryVoltage); @@ -72,42 +77,42 @@ public: // Create trend value if(init == false){ // Load start values for first page run - valueTrend = commonData.data.batteryVoltage10; + valueTrend = commonData->data.batteryVoltage10; init = true; } else{ // Reading trend value - valueTrend = commonData.data.batteryVoltage10; + valueTrend = commonData->data.batteryVoltage10; } // Get raw value for trend indicator - raw = commonData.data.batteryVoltage; // Live data + raw = commonData->data.batteryVoltage; // Live data // Switch average values switch (average) { case 0: - value1 = commonData.data.batteryVoltage; // Live data - value2 = commonData.data.batteryCurrent; - value3 = commonData.data.batteryPower; + value1 = commonData->data.batteryVoltage; // Live data + value2 = commonData->data.batteryCurrent; + value3 = commonData->data.batteryPower; break; case 1: - value1 = commonData.data.batteryVoltage10; // Average 10s - value2 = commonData.data.batteryCurrent10; - value3 = commonData.data.batteryPower10; + value1 = commonData->data.batteryVoltage10; // Average 10s + value2 = commonData->data.batteryCurrent10; + value3 = commonData->data.batteryPower10; break; case 2: - value1 = commonData.data.batteryVoltage60; // Average 60s - value2 = commonData.data.batteryCurrent60; - value3 = commonData.data.batteryPower60; + value1 = commonData->data.batteryVoltage60; // Average 60s + value2 = commonData->data.batteryCurrent60; + value3 = commonData->data.batteryPower60; break; case 3: - value1 = commonData.data.batteryVoltage300; // Average 300s - value2 = commonData.data.batteryCurrent300; - value3 = commonData.data.batteryPower300; + value1 = commonData->data.batteryVoltage300; // Average 300s + value2 = commonData->data.batteryCurrent300; + value3 = commonData->data.batteryPower300; break; default: - value1 = commonData.data.batteryVoltage; // Default - value2 = commonData.data.batteryCurrent; - value3 = commonData.data.batteryPower; + value1 = commonData->data.batteryVoltage; // Default + value2 = commonData->data.batteryCurrent; + value3 = commonData->data.batteryPower; break; } bool valid1 = true; @@ -178,37 +183,22 @@ public: // Draw page //*********************************************************** - // Clear display, set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(10, 65); getdisplay().print("Bat."); // Show battery type - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(90, 65); getdisplay().print(batType); // Show voltage type - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 140); int bvoltage = 0; @@ -219,7 +209,6 @@ public: getdisplay().print("V"); // Show battery capacity - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 200); if(batCapacity <= 999) getdisplay().print(batCapacity, 0); @@ -236,10 +225,9 @@ public: getdisplay().print("Battery Type"); // Show battery with fill level - batteryGraphic(150, 45, batPercentage, pixelcolor, bgcolor); + batteryGraphic(150, 45, batPercentage, commonData->fgcolor, commonData->bgcolor); // Show average settings - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(150, 145); switch (average) { @@ -261,7 +249,6 @@ public: } // Show fill level in percent - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(150, 200); getdisplay().print(batPercentage); @@ -269,7 +256,6 @@ public: getdisplay().print("%"); // Show time to full discharge - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(150, 260); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -297,7 +283,6 @@ public: getdisplay().print("Sensor Modul"); // Reading bus data or using simulation data - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 140); if(simulation == true){ @@ -326,7 +311,6 @@ public: getdisplay().print("V"); // Show actual current in A - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 200); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -339,7 +323,6 @@ public: getdisplay().print("A"); // Show actual consumption in W - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 260); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -351,24 +334,6 @@ public: getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().print("W"); - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(10, 290); - getdisplay().print("[AVG]"); - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; diff --git a/lib/obp60task/PageClock.cpp b/lib/obp60task/PageClock.cpp index 29cea4b..3442797 100644 --- a/lib/obp60task/PageClock.cpp +++ b/lib/obp60task/PageClock.cpp @@ -5,27 +5,26 @@ class PageClock : public Page { -bool keylock = false; // Keylock - public: PageClock(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageClock"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageClock"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) + virtual void displayPage(PageData &pageData) { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; static String svalue1old = ""; static String unit1old = ""; @@ -44,7 +43,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -62,8 +60,8 @@ public: value1 = 38160; // Simulation data for time value 11:36 in seconds } // Other simulation data see OBP60Formater.cpp bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value if(valid1 == true){ svalue1old = svalue1; // Save old value unit1old = unit1; // Save old unit @@ -75,8 +73,8 @@ public: name2 = name2.substring(0, 6); // String length limit for value name value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value if(valid2 == true){ svalue2old = svalue2; // Save old value unit2old = unit2; // Save old unit @@ -88,8 +86,8 @@ public: name3 = name3.substring(0, 6); // String length limit for value name value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value if(valid3 == true){ svalue3old = svalue3; // Save old value unit3old = unit3; // Save old unit @@ -108,25 +106,12 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show values GPS date - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(10, 65); if(holdvalues == false) getdisplay().print(svalue2); // Value @@ -136,10 +121,9 @@ public: getdisplay().print("Date"); // Name // Horizintal separator left - getdisplay().fillRect(0, 149, 60, 3, pixelcolor); + getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor); // Show values GPS time - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(10, 250); if(holdvalues == false) getdisplay().print(svalue1); // Value @@ -151,11 +135,10 @@ public: // Show values sunrise String sunrise = "---"; if(valid1 == true && valid2 == true && valid3 == true){ - sunrise = String(commonData.sundata.sunriseHour) + ":" + String(commonData.sundata.sunriseMinute + 100).substring(1); + sunrise = String(commonData->sundata.sunriseHour) + ":" + String(commonData->sundata.sunriseMinute + 100).substring(1); svalue5old = sunrise; } - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(335, 65); if(holdvalues == false) getdisplay().print(sunrise); // Value @@ -165,16 +148,15 @@ public: getdisplay().print("SunR"); // Name // Horizintal separator right - getdisplay().fillRect(340, 149, 80, 3, pixelcolor); + getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor); // Show values sunset String sunset = "---"; if(valid1 == true && valid2 == true && valid3 == true){ - sunset = String(commonData.sundata.sunsetHour) + ":" + String(commonData.sundata.sunsetMinute + 100).substring(1); + sunset = String(commonData->sundata.sunsetHour) + ":" + String(commonData->sundata.sunsetMinute + 100).substring(1); svalue6old = sunset; } - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(335, 250); if(holdvalues == false) getdisplay().print(sunset); // Value @@ -189,8 +171,8 @@ public: int rInstrument = 110; // Radius of clock float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle for(int i=0; i<360; i=i+1) { @@ -231,7 +213,7 @@ public: if(i % 6 == 0){ float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); sinx=sin(i/180.0*pi); cosx=cos(i/180.0*pi); } @@ -245,23 +227,20 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } // Print Unit in clock - getdisplay().setTextColor(textcolor); + getdisplay().setFont(&Ubuntu_Bold12pt7b); + getdisplay().setCursor(175, 110); if(holdvalues == false){ - getdisplay().setFont(&Ubuntu_Bold12pt7b); - getdisplay().setCursor(175, 110); getdisplay().print(unit2); // Unit } else{ - getdisplay().setFont(&Ubuntu_Bold12pt7b); - getdisplay().setCursor(175, 110); getdisplay().print(unit2old); // Unit } @@ -290,7 +269,7 @@ public: float yy2 = -(rInstrument * 0.5); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -300,7 +279,7 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } // Draw minute pointer @@ -316,7 +295,7 @@ public: float yy2 = -(rInstrument - 15); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -326,29 +305,12 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 150, startwidth + 6, bgcolor); - getdisplay().fillCircle(200, 150, startwidth + 4, pixelcolor); - -//******************************************************************************************* - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } + getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor); + getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor); // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageDST810.cpp b/lib/obp60task/PageDST810.cpp index dff5ea3..0da67ff 100644 --- a/lib/obp60task/PageDST810.cpp +++ b/lib/obp60task/PageDST810.cpp @@ -5,24 +5,24 @@ class PageDST810 : public Page { - bool keylock = false; // Keylock - - public: +public: PageDST810(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageDST810"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageDST810"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -37,7 +37,6 @@ class PageDST810 : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -48,8 +47,8 @@ class PageDST810 : public Page name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Get boat values #2 GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) @@ -57,8 +56,8 @@ class PageDST810 : public Page name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value // Get boat values #3 GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue) @@ -66,8 +65,8 @@ class PageDST810 : public Page name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value // Get boat values #4 GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue) @@ -75,8 +74,8 @@ class PageDST810 : public Page name4 = name4.substring(0, 6); // String length limit for value name double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information - String svalue4 = formatValue(bvalue4, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit4 = formatValue(bvalue4, commonData).unit; // Unit of value + String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -91,33 +90,19 @@ class PageDST810 : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - + + getdisplay().setTextColor(commonData->fgcolor); + // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 55); getdisplay().print("Depth"); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 90); if(holdvalues == false){ @@ -146,18 +131,16 @@ class PageDST810 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 105, 400, 3, pixelcolor); + getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 145); getdisplay().print("Speed"); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 180); if(holdvalues == false){ @@ -186,18 +169,16 @@ class PageDST810 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 195, 400, 3, pixelcolor); + getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 220); getdisplay().print("Log"); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 240); if(holdvalues == false){ @@ -226,18 +207,16 @@ class PageDST810 : public Page // ############### Vertical Line ################ // Vertical line 3 pix - getdisplay().fillRect(200, 195, 3, 75, pixelcolor); + getdisplay().fillRect(200, 195, 3, 75, commonData->fgcolor); // ############### Value 4 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(220, 220); getdisplay().print("Temp"); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(220, 240); if(holdvalues == false){ @@ -263,25 +242,6 @@ class PageDST810 : public Page unit4old = unit4; // Save the old unit } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageFluid.cpp b/lib/obp60task/PageFluid.cpp index 76764ef..4c121da 100644 --- a/lib/obp60task/PageFluid.cpp +++ b/lib/obp60task/PageFluid.cpp @@ -22,43 +22,6 @@ TODO */ -struct Point { - double x; - double y; -}; - -Point rotatePoint(const Point& origin, const Point& p, double angle) { - // rotate poind around origin by degrees - Point rotated; - double phi = angle * M_PI / 180.0; - double dx = p.x - origin.x; - double dy = p.y - origin.y; - rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy; - rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy; - return rotated; -} - -std::vector rotatePoints(const Point& origin, const std::vector& pts, double angle) { - std::vector rotatedPoints; - for (const auto& p : pts) { - rotatedPoints.push_back(rotatePoint(origin, p, angle)); - } - return rotatedPoints; -} - -void fillPoly4(const std::vector& p4, int color) { - getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color); - getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color); -} - -void drawTextCentered(int16_t tx, int16_t ty, String text) { - int16_t x, y; - uint16_t w, h; - getdisplay().getTextBounds(text, 0, 0, &x, &y, &w, &h); - getdisplay().setCursor(tx - w / 2, ty + h / 2); - getdisplay().print(text); -} - #define fuel_width 16 #define fuel_height 16 static unsigned char fuel_bits[] = { @@ -94,29 +57,48 @@ static unsigned char gasoline_bits[] = { 0x98, 0xcf, 0x38, 0xe7, 0x78, 0xf0, 0xf8, 0xfa, 0xf8, 0xfa, 0x78, 0xf0, 0x38, 0xe7, 0x98, 0xcf, 0xf8, 0xff, 0xf0, 0x7f }; -class PageFluid : public Page{ - bool keylock = false; // Keylock +#define fish_width 16 +#define fish_height 16 +static unsigned char fish_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x37, + 0xfc, 0x7f, 0xfc, 0x7f, 0xec, 0x3f, 0xfc, 0x7f, 0xfc, 0x7f, 0xf8, 0x37, + 0xf0, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00 }; + +class PageFluid : public Page +{ + bool holdvalues = false; + int fluidtype; public: PageFluid(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageFluid"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageFluid"); + holdvalues = common.config->getBool(common.config->holdvalues); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayNew(PageData &pageData){ + fluidtype = commonData->config->getInt("page" + String(pageData.pageNumber) + "fluid", 0); + commonData->logger->logDebug(GwLog::LOG,"New PageFluid: fluidtype=%d", fluidtype); + } + + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; + + // Old values for hold function + static double value1old; // Get config data String flashLED = config->getString(config->flashLED); - String displaycolor = config->getString(config->displaycolor); String backlightMode = config->getString(config->backlight); // Optical warning by limit violation (unused) @@ -125,31 +107,23 @@ class PageFluid : public Page{ setFlashLED(false); } - // Logging boat values - LOG_DEBUG(GwLog::LOG,"Drawing at PageFluid"); - GwApi::BoatValue *bvalue1 = pageData.values[0]; String name1 = bvalue1->getName(); - double value1 = bvalue1->value; - bool valid1 = bvalue1->valid; + if (holdvalues and bvalue1->valid) { + value1old = bvalue1->value; + } - int fluidtype = config->getInt("page" + String(commonData.data.actpage) + "fluid", 0); + // Logging boat values + LOG_DEBUG(GwLog::LOG,"Drawing at PageFluid: value=%f", bvalue1->value); // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor != "Normal"){ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); + getdisplay().setTextColor(commonData->fgcolor); + // descriptions getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 60); @@ -166,11 +140,11 @@ class PageFluid : public Page{ uint8_t r = 110; // circular frame - getdisplay().drawCircle(c.x, c.y, r+5, pixelcolor); - getdisplay().fillCircle(c.x, c.y, r+2, pixelcolor); - getdisplay().fillCircle(c.x, c.y, r-1, bgcolor); + getdisplay().drawCircle(c.x, c.y, r+5, commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, r+2, commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, r-1, commonData->bgcolor); // center of pointer as dot - getdisplay().fillCircle(c.x, c.y, 8, pixelcolor); + getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor); // value down centered char buffer[6]; @@ -179,24 +153,30 @@ class PageFluid : public Page{ } else { strcpy(buffer, "---"); } - drawTextCentered(c.x, c.y + r - 20, String(buffer)); + drawTextCenter(c.x, c.y + r - 20, String(buffer)); // draw symbol (as bitmap) switch (fluidtype) { case 0: - getdisplay().drawXBitmap(c.x-8, c.y-50, fuel_bits, fuel_width, fuel_height, pixelcolor); + getdisplay().drawXBitmap(c.x-8, c.y-50, fuel_bits, fuel_width, fuel_height, commonData->fgcolor); break; case 1: - getdisplay().drawXBitmap(c.x-8, c.y-50, water_bits, water_width, water_height, pixelcolor); + getdisplay().drawXBitmap(c.x-8, c.y-50, water_bits, water_width, water_height, commonData->fgcolor); + break; + case 2: // gray water no symbol yet + // getdisplay().drawXBitmap(c.x-8, c.y-50, gray_bits, gray_width, gray_height, commonData->fgcolor); + break; + case 3: + getdisplay().drawXBitmap(c.x-8, c.y-50, fish_bits, fish_width, fish_height, commonData->fgcolor); break; case 4: - getdisplay().drawXBitmap(c.x-8, c.y-50, oil_bits, oil_width, oil_height, pixelcolor); + getdisplay().drawXBitmap(c.x-8, c.y-50, oil_bits, oil_width, oil_height, commonData->fgcolor); break; case 5: - getdisplay().drawXBitmap(c.x-8, c.y-50, waste_bits, waste_width, waste_height, pixelcolor); + getdisplay().drawXBitmap(c.x-8, c.y-50, waste_bits, waste_width, waste_height, commonData->fgcolor); break; case 6: - getdisplay().drawXBitmap(c.x-8, c.y-50, gasoline_bits, gasoline_width, gasoline_height, pixelcolor); + getdisplay().drawXBitmap(c.x-8, c.y-50, gasoline_bits, gasoline_width, gasoline_height, commonData->fgcolor); break; } @@ -205,18 +185,18 @@ class PageFluid : public Page{ // scale texts getdisplay().setFont(&Ubuntu_Bold8pt7b); p = {c.x, c.y - r + 30}; - drawTextCentered(p.x, p.y, "1/2"); + drawTextCenter(p.x, p.y, "1/2"); pr = rotatePoint(c, p, -60); - drawTextCentered(pr.x, pr.y, "1/4"); + drawTextCenter(pr.x, pr.y, "1/4"); pr = rotatePoint(c, p, 60); - drawTextCentered(pr.x, pr.y, "3/4"); + drawTextCenter(pr.x, pr.y, "3/4"); // empty and full getdisplay().setFont(&Ubuntu_Bold12pt7b); p = rotatePoint(c, {c.x, c.y - r + 30}, -130); - drawTextCentered(p.x, p.y, "E"); + drawTextCenter(p.x, p.y, "E"); p = rotatePoint(c, {c.x, c.y - r + 30}, 130); - drawTextCentered(p.x, p.y, "F"); + drawTextCenter(p.x, p.y, "F"); // lines std::vector pts = { @@ -225,11 +205,11 @@ class PageFluid : public Page{ {c.x + 2, c.y - (r - 16)}, {c.x - 2, c.y - (r - 16)} }; - fillPoly4(rotatePoints(c, pts, -120), pixelcolor); - fillPoly4(rotatePoints(c, pts, -60), pixelcolor); - fillPoly4(rotatePoints(c, pts, 0), pixelcolor); - fillPoly4(rotatePoints(c, pts, 60), pixelcolor); - fillPoly4(rotatePoints(c, pts, 120), pixelcolor); + fillPoly4(rotatePoints(c, pts, -120), commonData->fgcolor); + fillPoly4(rotatePoints(c, pts, -60), commonData->fgcolor); + fillPoly4(rotatePoints(c, pts, 0), commonData->fgcolor); + fillPoly4(rotatePoints(c, pts, 60), commonData->fgcolor); + fillPoly4(rotatePoints(c, pts, 120), commonData->fgcolor); // dots // rotate 0 to 360 in 12 degree steps @@ -238,7 +218,7 @@ class PageFluid : public Page{ continue; } p = rotatePoint(c, {c.x, c.y - r + 10}, angle); - getdisplay().fillCircle(p.x, p.y, 3, pixelcolor); + getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor); } // pointer @@ -249,26 +229,11 @@ class PageFluid : public Page{ {c.x + 6, c.y + 15}, {c.x - 6, c.y + 15} }; - fillPoly4(rotatePoints(c, pts, -120 + bvalue1->value * 2.4), pixelcolor); + fillPoly4(rotatePoints(c, pts, -120 + bvalue1->value * 2.4), commonData->fgcolor); // Pointer axis is white - getdisplay().fillCircle(c.x, c.y, 6, bgcolor); + getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor); } - // Key Layout - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 296); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 296); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 296); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index 546f903..73329e4 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -5,24 +5,24 @@ class PageFourValues : public Page { - bool keylock = false; // Keylock - public: PageFourValues(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageFourValues"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageFourValues"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -37,7 +37,6 @@ class PageFourValues : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -48,8 +47,8 @@ class PageFourValues : public Page name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Get boat values #2 GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) @@ -57,8 +56,8 @@ class PageFourValues : public Page name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value // Get boat values #3 GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue) @@ -66,8 +65,8 @@ class PageFourValues : public Page name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value // Get boat values #4 GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue) @@ -75,8 +74,8 @@ class PageFourValues : public Page name4 = name4.substring(0, 6); // String length limit for value name double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information - String svalue4 = formatValue(bvalue4, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit4 = formatValue(bvalue4, commonData).unit; // Unit of value + String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -91,33 +90,19 @@ class PageFourValues : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(20, 45); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 65); if(holdvalues == false){ @@ -156,18 +141,16 @@ class PageFourValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 80, 400, 3, pixelcolor); + getdisplay().fillRect(0, 80, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(20, 113); getdisplay().print(name2); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 133); if(holdvalues == false){ @@ -206,18 +189,16 @@ class PageFourValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 146, 400, 3, pixelcolor); + getdisplay().fillRect(0, 146, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(20, 181); getdisplay().print(name3); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 201); if(holdvalues == false){ @@ -256,18 +237,16 @@ class PageFourValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 214, 400, 3, pixelcolor); + getdisplay().fillRect(0, 214, 400, 3, commonData->fgcolor); // ############### Value 4 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(20, 249); getdisplay().print(name4); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 269); if(holdvalues == false){ @@ -303,25 +282,6 @@ class PageFourValues : public Page unit4old = unit4; // Save the old unit } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageFourValues2.cpp b/lib/obp60task/PageFourValues2.cpp index 8d05485..6ac5981 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -5,24 +5,24 @@ class PageFourValues2 : public Page { - bool keylock = false; // Keylock - public: PageFourValues2(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageFourValues2"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageFourValues2"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; // Toggle keylock return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -37,7 +37,6 @@ class PageFourValues2 : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -48,8 +47,8 @@ class PageFourValues2 : public Page name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Get boat values #2 GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) @@ -57,8 +56,8 @@ class PageFourValues2 : public Page name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value // Get boat values #3 GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue) @@ -66,8 +65,8 @@ class PageFourValues2 : public Page name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value // Get boat values #4 GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue) @@ -75,8 +74,8 @@ class PageFourValues2 : public Page name4 = name4.substring(0, 6); // String length limit for value name double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information - String svalue4 = formatValue(bvalue4, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit4 = formatValue(bvalue4, commonData).unit; // Unit of value + String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -91,33 +90,19 @@ class PageFourValues2 : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 55); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 90); if(holdvalues == false){ @@ -156,18 +141,16 @@ class PageFourValues2 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 105, 400, 3, pixelcolor); + getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 145); getdisplay().print(name2); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 180); if(holdvalues == false){ @@ -206,18 +189,16 @@ class PageFourValues2 : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 195, 400, 3, pixelcolor); + getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 220); getdisplay().print(name3); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(20, 240); if(holdvalues == false){ @@ -256,18 +237,16 @@ class PageFourValues2 : public Page // ############### Vertical Line ################ // Vertical line 3 pix - getdisplay().fillRect(200, 195, 3, 75, pixelcolor); + getdisplay().fillRect(200, 195, 3, 75, commonData->fgcolor); // ############### Value 4 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(220, 220); getdisplay().print(name4); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(220, 240); if(holdvalues == false){ @@ -303,25 +282,6 @@ class PageFourValues2 : public Page unit4old = unit4; // Save the old unit } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/PageGenerator.cpp b/lib/obp60task/PageGenerator.cpp index 3a496ee..20e7652 100644 --- a/lib/obp60task/PageGenerator.cpp +++ b/lib/obp60task/PageGenerator.cpp @@ -6,30 +6,27 @@ class PageGenerator : public Page { -bool init = false; // Marker for init done -bool keylock = false; // Keylock - public: PageGenerator(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageGenerator"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageGenerator"); } virtual int handleKey(int key){ // Code for keylock if(key == 11){ - keylock = !keylock; // Toggle keylock + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) + virtual void displayPage(PageData &pageData) { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Get config data bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String batVoltage = config->getString(config->batteryVoltage); @@ -48,13 +45,13 @@ public: // Get raw value for trend indicator if(powerSensor != "off"){ - value1 = commonData.data.generatorVoltage; // Use voltage from external sensor + value1 = commonData->data.generatorVoltage; // Use voltage from external sensor } else{ - value1 = commonData.data.batteryVoltage; // Use internal voltage sensor + value1 = commonData->data.batteryVoltage; // Use internal voltage sensor } - value2 = commonData.data.generatorCurrent; - value3 = commonData.data.generatorPower; + value2 = commonData->data.generatorCurrent; + value3 = commonData->data.generatorPower; genPercentage = value3 * 100 / (double)genPower; // Load value // Limits for battery level if(genPercentage < 0) genPercentage = 0; @@ -85,25 +82,12 @@ public: // Draw page //*********************************************************** - // Clear display, set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(10, 65); getdisplay().print("Power"); @@ -112,7 +96,6 @@ public: getdisplay().print("Generator"); // Show voltage type - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 140); int bvoltage = 0; @@ -123,7 +106,6 @@ public: getdisplay().print("V"); // Show solar power - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 200); if(genPower <= 999) getdisplay().print(genPower, 0); @@ -140,10 +122,9 @@ public: getdisplay().print("Power Modul"); // Show generator - generatorGraphic(200, 95, pixelcolor, bgcolor); + generatorGraphic(200, 95, commonData->fgcolor, commonData->bgcolor); // Show load level in percent - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(150, 200); getdisplay().print(genPercentage); @@ -171,7 +152,6 @@ public: getdisplay().print("Sensor Modul"); // Reading bus data or using simulation data - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 140); if(simulation == true){ @@ -200,7 +180,6 @@ public: getdisplay().print("V"); // Show actual current in A - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 200); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -213,7 +192,6 @@ public: getdisplay().print("A"); // Show actual consumption in W - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 260); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -225,22 +203,6 @@ public: getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().print("W"); - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; @@ -264,4 +226,4 @@ PageDescription registerPageGenerator( true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageKeelPosition.cpp b/lib/obp60task/PageKeelPosition.cpp index ecdb11e..f3eac49 100644 --- a/lib/obp60task/PageKeelPosition.cpp +++ b/lib/obp60task/PageKeelPosition.cpp @@ -5,27 +5,26 @@ class PageKeelPosition : public Page { -bool keylock = false; // Keylock - public: PageKeelPosition(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageKeelPosition"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageKeelPosition"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) + virtual void displayPage(PageData &pageData) { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; double value1 = 0; double value1old = 0; @@ -33,7 +32,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -41,9 +39,9 @@ public: String rotfunction = config->getString(config->rotFunction); // Get boat values for Keel position - bool valid1 = commonData.data.validRotAngle; // Valid information + bool valid1 = commonData->data.validRotAngle; // Valid information if(simulation == false && rotsensor == "AS5600" && rotfunction == "Keel"){ - value1 = commonData.data.rotationAngle; // Raw value without unit convertion + value1 = commonData->data.rotationAngle; // Raw value without unit convertion } else{ value1 = 0; @@ -69,20 +67,6 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update @@ -92,9 +76,9 @@ public: int rInstrument = 110; // Radius of KeelPosition float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle - getdisplay().fillRect(0, 30, 400, 122, bgcolor); // Delete half top circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle + getdisplay().fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle for(int i=90; i<=270; i=i+10) { @@ -132,7 +116,7 @@ public: // Draw sub scale with dots float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); float sinx=sin(i/180.0*pi); float cosx=cos(i/180.0*pi); @@ -145,10 +129,10 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } @@ -182,7 +166,7 @@ public: float yy2 = -(rInstrument * 0.6); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -192,20 +176,19 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); // Draw counterweight - getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, pixelcolor); + getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 140, startwidth + 22, bgcolor); - getdisplay().fillCircle(200, 140, startwidth + 20, pixelcolor); // Boat circle - getdisplay().fillRect(200 - 30, 140 - 30, 2 * 30, 30, bgcolor); // Delete half top of boat circle - getdisplay().fillRect(150, 150, 100, 4, pixelcolor); // Water line + getdisplay().fillCircle(200, 140, startwidth + 22, commonData->bgcolor); + getdisplay().fillCircle(200, 140, startwidth + 20, commonData->fgcolor); // Boat circle + getdisplay().fillRect(200 - 30, 140 - 30, 2 * 30, 30, commonData->bgcolor); // Delete half top of boat circle + getdisplay().fillRect(150, 150, 100, 4, commonData->fgcolor); // Water line // Print label - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(100, 70); getdisplay().print("Keel Position"); // Label @@ -223,23 +206,6 @@ public: getdisplay().print("No sensor data"); // Info missing sensor } -//******************************************************************************************* - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) @@ -264,4 +230,4 @@ PageDescription registerPageKeelPosition( true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageOneValue.cpp b/lib/obp60task/PageOneValue.cpp index 283fc4f..84aff6d 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -3,25 +3,26 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -class PageOneValue : public Page{ - bool keylock = false; // Keylock - +class PageOneValue : public Page +{ public: PageOneValue(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageOneValue"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageOneValue"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -30,7 +31,6 @@ class PageOneValue : public Page{ // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -41,8 +41,8 @@ class PageOneValue : public Page{ name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -57,31 +57,16 @@ class PageOneValue : public Page{ // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } /// Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // Show name - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData->fgcolor); getdisplay().setFont(&Ubuntu_Bold32pt7b); getdisplay().setCursor(20, 100); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(270, 100); if(holdvalues == false){ @@ -117,22 +102,6 @@ class PageOneValue : public Page{ unit1old = unit1; // Save the old unit } - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) @@ -157,4 +126,4 @@ PageDescription registerPageOneValue( true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageRollPitch.cpp b/lib/obp60task/PageRollPitch.cpp index 0674e2b..320e43f 100644 --- a/lib/obp60task/PageRollPitch.cpp +++ b/lib/obp60task/PageRollPitch.cpp @@ -5,27 +5,25 @@ class PageRollPitch : public Page { -bool keylock = false; // Keylock - public: PageRollPitch(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageRollPitch"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageRollPitch"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; double value1 = 0; double value2 = 0; @@ -38,7 +36,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -118,25 +115,12 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show roll limit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 65); getdisplay().print(rolllimit); // Value @@ -150,10 +134,9 @@ public: getdisplay().print("DEG"); // Horizintal separator left - getdisplay().fillRect(0, 149, 60, 3, pixelcolor); + getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor); // Show roll value - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 270); if(holdvalues == false) getdisplay().print(svalue1); // Value @@ -166,10 +149,9 @@ public: getdisplay().print("Deg"); // Horizintal separator right - getdisplay().fillRect(340, 149, 80, 3, pixelcolor); + getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor); // Show pitch value - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(295, 270); if(holdvalues == false) getdisplay().print(svalue2); // Value @@ -187,8 +169,8 @@ public: int rInstrument = 100; // Radius of instrument float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle for(int i=0; i<360; i=i+10) { @@ -196,7 +178,7 @@ public: if((i >= 0 && i <= 60) || (i >= 300 && i <= 360)){ // Scaling values float x = 200 + (rInstrument+25)*sin(i/180.0*pi); // x-coordinate dots - float y = 150 - (rInstrument+25)*cos(i/180.0*pi); // y-coordinate cots + float y = 150 - (rInstrument+25)*cos(i/180.0*pi); // y-coordinate cots const char *ii = ""; switch (i) { @@ -223,7 +205,7 @@ public: // Draw sub scale with dots float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); float sinx=sin(i/180.0*pi); float cosx=cos(i/180.0*pi); @@ -236,10 +218,10 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } } @@ -260,7 +242,7 @@ public: float yy2 = -(rInstrument * 0.7); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -270,26 +252,26 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); // Draw counterweight - getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, pixelcolor); + getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 150, startwidth + 22, bgcolor); - getdisplay().fillCircle(200, 150, startwidth + 20, pixelcolor); // Boat circle + getdisplay().fillCircle(200, 150, startwidth + 22, commonData->bgcolor); + getdisplay().fillCircle(200, 150, startwidth + 20, commonData->fgcolor); // Boat circle int x0 = 200; int y0 = 150; int x1 = x0 + 50*cos(value1); int y1 = y0 + 50*sin(value1); int x2 = x0 + 50*cos(value1 - pi/2); int y2 = y0 + 50*sin(value1 - pi/2); - getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, bgcolor); // Clear half top side of boat circle (right triangle) + getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (right triangle) x1 = x0 + 50*cos(value1 + pi); y1 = y0 + 50*sin(value1 + pi); - getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, bgcolor); // Clear half top side of boat circle (left triangle) - getdisplay().fillRect(150, 160, 100, 4, pixelcolor); // Water line + getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (left triangle) + getdisplay().fillRect(150, 160, 100, 4, commonData->fgcolor); // Water line // Draw roll pointer startwidth = 4; // Start width of pointer @@ -304,7 +286,7 @@ public: float yy2 = -(rInstrument - 15); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -314,7 +296,7 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } else{ // Print sensor info @@ -323,23 +305,6 @@ public: getdisplay().print("No sensor data"); // Info missing sensor } -//******************************************************************************************* - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) @@ -359,10 +324,10 @@ static Page *createPage(CommonData &common){ PageDescription registerPageRollPitch( "RollPitch", // Page name createPage, // Action - 0, // Number of bus values depends on selection in Web configuration + 2, // Number of bus values depends on selection in Web configuration // {"xdrROLL", "xdrPTCH"},// Bus values we need in the page - {"xdrRoll", "xdrPitch"},// Bus values we need in the page + //{"xdrRoll", "xdrPitch"},// Bus values we need in the page true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageRudderPosition.cpp b/lib/obp60task/PageRudderPosition.cpp index 02125a0..6ed0d4c 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -5,27 +5,25 @@ class PageRudderPosition : public Page { -bool keylock = false; // Keylock - public: PageRudderPosition(CommonData &common){ + commonData = &common; common.logger->logDebug(GwLog::LOG,"Show PageRudderPosition"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; static String unit1old = ""; double value1 = 0.1; @@ -34,7 +32,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -45,8 +42,8 @@ public: name1 = name1.substring(0, 6); // String length limit for value name value1 = bvalue1->value; // Raw value without unit convertion bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value if(valid1 == true){ value1old = value1; // Save old value unit1old = unit1; // Save old unit @@ -74,20 +71,6 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update @@ -97,9 +80,9 @@ public: int rInstrument = 110; // Radius of RudderPosition float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle - getdisplay().fillRect(0, 30, 400, 122, bgcolor); // Delete half top circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle + getdisplay().fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle for(int i=90; i<=270; i=i+10) { @@ -137,7 +120,7 @@ public: // Draw sub scale with dots float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); float sinx=sin(i/180.0*pi); float cosx=cos(i/180.0*pi); @@ -150,16 +133,15 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } // Print label - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().setCursor(80, 70); getdisplay().print("Rudder Position"); // Label @@ -206,7 +188,7 @@ public: float yy2 = -(rInstrument * 0.5); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -216,29 +198,12 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 150, startwidth + 6, bgcolor); - getdisplay().fillCircle(200, 150, startwidth + 4, pixelcolor); - -//******************************************************************************************* - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } + getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor); + getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor); // Update display getdisplay().nextPage(); // Partial update (fast) @@ -263,4 +228,4 @@ PageDescription registerPageRudderPosition( true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageSolar.cpp b/lib/obp60task/PageSolar.cpp index 06b5022..646a568 100644 --- a/lib/obp60task/PageSolar.cpp +++ b/lib/obp60task/PageSolar.cpp @@ -6,30 +6,26 @@ class PageSolar : public Page { -bool init = false; // Marker for init done -bool keylock = false; // Keylock - public: PageSolar(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageSolar"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageSolar"); } virtual int handleKey(int key){ // Code for keylock if(key == 11){ - keylock = !keylock; // Toggle keylock + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Get config data bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String batVoltage = config->getString(config->batteryVoltage); @@ -48,13 +44,13 @@ public: // Get raw value for trend indicator if(powerSensor != "off"){ - value1 = commonData.data.solarVoltage; // Use voltage from external sensor + value1 = commonData->data.solarVoltage; // Use voltage from external sensor } else{ - value1 = commonData.data.batteryVoltage; // Use internal voltage sensor + value1 = commonData->data.batteryVoltage; // Use internal voltage sensor } - value2 = commonData.data.solarCurrent; - value3 = commonData.data.solarPower; + value2 = commonData->data.solarCurrent; + value3 = commonData->data.solarPower; solPercentage = value3 * 100 / (double)solPower; // Load value // Limits for battery level if(solPercentage < 0) solPercentage = 0; @@ -85,31 +81,17 @@ public: // Draw page //*********************************************************** - // Clear display, set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(10, 65); getdisplay().print("Solar"); // Show voltage type - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 140); int bvoltage = 0; @@ -120,7 +102,6 @@ public: getdisplay().print("V"); // Show solar power - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 200); if(solPower <= 999) getdisplay().print(solPower, 0); @@ -137,10 +118,9 @@ public: getdisplay().print("Solar Modul"); // Show solar panel - solarGraphic(150, 45, pixelcolor, bgcolor); + solarGraphic(150, 45, commonData->fgcolor, commonData->bgcolor); // Show load level in percent - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(150, 200); getdisplay().print(solPercentage); @@ -168,7 +148,6 @@ public: getdisplay().print("Sensor Modul"); // Reading bus data or using simulation data - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 140); if(simulation == true){ @@ -197,7 +176,6 @@ public: getdisplay().print("V"); // Show actual current in A - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 200); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -210,7 +188,6 @@ public: getdisplay().print("A"); // Show actual consumption in W - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(260, 260); if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){ @@ -222,22 +199,6 @@ public: getdisplay().setFont(&Ubuntu_Bold16pt7b); getdisplay().print("W"); - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; @@ -261,4 +222,4 @@ PageDescription registerPageSolar( true // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageThreeValues.cpp b/lib/obp60task/PageThreeValues.cpp index 8759570..c740b30 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -5,24 +5,24 @@ class PageThreeValues : public Page { - bool keylock = false; // Keylock - public: PageThreeValues(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageThreeValue"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageThreeValue"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -35,7 +35,6 @@ class PageThreeValues : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -46,8 +45,8 @@ class PageThreeValues : public Page name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Get boat values #2 GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) @@ -55,8 +54,8 @@ class PageThreeValues : public Page name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value // Get boat values #3 GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue) @@ -64,8 +63,8 @@ class PageThreeValues : public Page name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -80,33 +79,18 @@ class PageThreeValues : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } /// Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData->fgcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 55); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 90); if(holdvalues == false){ @@ -145,18 +129,16 @@ class PageThreeValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 105, 400, 3, pixelcolor); + getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 145); getdisplay().print(name2); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 180); if(holdvalues == false){ @@ -195,18 +177,16 @@ class PageThreeValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 195, 400, 3, pixelcolor); + getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor); // ############### Value 3 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 235); getdisplay().print(name3); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 270); if(holdvalues == false){ @@ -242,25 +222,6 @@ class PageThreeValues : public Page unit3old = unit3; // Save the old unit } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; diff --git a/lib/obp60task/PageTwoValues.cpp b/lib/obp60task/PageTwoValues.cpp index 48e8210..6b8d0d1 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -5,24 +5,24 @@ class PageTwoValues : public Page { - bool keylock = false; // Keylock - public: PageTwoValues(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageTwoValue"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageTwoValue"); } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Old values for hold function static String svalue1old = ""; @@ -33,7 +33,6 @@ class PageTwoValues : public Page // Get config data String lengthformat = config->getString(config->lengthFormat); // bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -44,8 +43,8 @@ class PageTwoValues : public Page name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value // Get boat values #2 GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue) @@ -53,8 +52,8 @@ class PageTwoValues : public Page name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value // Optical warning by limit violation (unused) if(String(flashLED) == "Limit Violation"){ @@ -69,33 +68,18 @@ class PageTwoValues : public Page // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // ############### Value 1 ################ // Show name - getdisplay().setTextColor(textcolor); + getdisplay().setTextColor(commonData->fgcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 80); getdisplay().print(name1); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 130); if(holdvalues == false){ @@ -134,18 +118,16 @@ class PageTwoValues : public Page // ############### Horizontal Line ################ // Horizontal line 3 pix - getdisplay().fillRect(0, 145, 400, 3, pixelcolor); + getdisplay().fillRect(0, 145, 400, 3, commonData->fgcolor); // ############### Value 2 ################ // Show name - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(20, 190); getdisplay().print(name2); // Page name // Show unit - getdisplay().setTextColor(textcolor); getdisplay().setFont(&Ubuntu_Bold12pt7b); getdisplay().setCursor(20, 240); if(holdvalues == false){ @@ -181,25 +163,6 @@ class PageTwoValues : public Page unit2old = unit2; // Save the old unit } - - // ############### Key Layout ################ - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index cc1f9bb..cc77b01 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -7,45 +7,105 @@ class PageVoltage : public Page { bool init = false; // Marker for init done -bool keylock = false; // Keylock -int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s +uint8_t average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s bool trend = true; // Trend indicator [0|1], 0=off, 1=on double raw = 0; +char mode = 'D'; // display mode (A)nalog | (D)igital public: PageVoltage(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageVoltage"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageVoltage"); + if (hasFRAM) { + average = fram.read(FRAM_VOLTAGE_AVG); + trend = fram.read(FRAM_VOLTAGE_TREND); + mode = fram.read(FRAM_VOLTAGE_MODE); + } } + + virtual void setupKeys(){ + Page::setupKeys(); + commonData->keydata[0].label = "AVG"; + commonData->keydata[1].label = "MODE"; + commonData->keydata[4].label = "TRD"; + } + virtual int handleKey(int key){ // Change average if(key == 1){ average ++; average = average % 4; // Modulo 4 + if (hasFRAM) fram.write(FRAM_VOLTAGE_AVG, average); return 0; // Commit the key } + // Switch display mode + if (key == 2) { + if (mode == 'A') { + mode = 'D'; + } else { + mode = 'A'; + } + if (hasFRAM) fram.write(FRAM_VOLTAGE_MODE, mode); + return 0; + } + // Trend indicator if(key == 5){ trend = !trend; + if (hasFRAM) fram.write(FRAM_VOLTAGE_TREND, trend); return 0; // Commit the key } // Code for keylock if(key == 11){ - keylock = !keylock; // Toggle keylock + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + void printAvg(int avg, uint16_t x, uint16_t y, bool prefix) { + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(x, y); + if (prefix) { + getdisplay().print("Avg: "); + } + switch (average) { + case 0: + getdisplay().print("1s"); + break; + case 1: + getdisplay().print("10s"); + break; + case 2: + getdisplay().print("60s"); + break; + case 3: + getdisplay().print("300s"); + break; + default: + getdisplay().print("1s"); + break; + } + } + + void printVoltageSymbol(uint16_t x, uint16_t y, uint16_t color) { + getdisplay().setFont(&Ubuntu_Bold16pt7b); + getdisplay().setCursor(x, y); + getdisplay().print("V"); + getdisplay().fillRect(x, y + 6, 22, 3, color); + getdisplay().fillRect(x, y + 11, 6, 3, color); + getdisplay().fillRect(x + 8, y + 11, 6, 3, color); + getdisplay().fillRect(x + 16, y + 11, 6, 3, color); + } + + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Get config data bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String batVoltage = config->getString(config->batteryVoltage); @@ -60,32 +120,32 @@ public: // Create trend value if(init == false){ // Load start values for first page run - valueTrend = commonData.data.batteryVoltage10; + valueTrend = commonData->data.batteryVoltage10; init = true; } else{ // Reading trend value - valueTrend = commonData.data.batteryVoltage10; + valueTrend = commonData->data.batteryVoltage10; } // Get raw value for trend indicator - raw = commonData.data.batteryVoltage; // Live data + raw = commonData->data.batteryVoltage; // Live data // Switch average values switch (average) { case 0: - value1 = commonData.data.batteryVoltage; // Live data + value1 = commonData->data.batteryVoltage; // Live data break; case 1: - value1 = commonData.data.batteryVoltage10; // Average 10s + value1 = commonData->data.batteryVoltage10; // Average 10s break; case 2: - value1 = commonData.data.batteryVoltage60; // Average 60s + value1 = commonData->data.batteryVoltage60; // Average 60s break; case 3: - value1 = commonData.data.batteryVoltage300; // Average 300s + value1 = commonData->data.batteryVoltage300; // Average 300s break; default: - value1 = commonData.data.batteryVoltage; // Default + value1 = commonData->data.batteryVoltage; // Default break; } bool valid1 = true; @@ -133,132 +193,178 @@ public: // Draw page //*********************************************************** - // Clear display, set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - // Show name - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold32pt7b); - getdisplay().setCursor(20, 100); - getdisplay().print(name1); // Value name + if (mode == 'D') { + // Display mode digital - // Show unit - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold20pt7b); - getdisplay().setCursor(270, 100); - getdisplay().print("V"); + // Show name + getdisplay().setTextColor(commonData->fgcolor); + getdisplay().setFont(&Ubuntu_Bold32pt7b); + getdisplay().setCursor(20, 100); + getdisplay().print(name1); // Value name - // Show battery type - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - getdisplay().setCursor(295, 100); - getdisplay().print(batType); + // Show unit + getdisplay().setFont(&Ubuntu_Bold20pt7b); + getdisplay().setCursor(270, 100); + getdisplay().print("V"); - // Show average settings - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - getdisplay().setCursor(320, 84); - switch (average) { - case 0: - getdisplay().print("Avg: 1s"); - break; - case 1: - getdisplay().print("Avg: 10s"); - break; - case 2: - getdisplay().print("Avg: 60s"); - break; - case 3: - getdisplay().print("Avg: 300s"); - break; - default: - getdisplay().print("Avg: 1s"); - break; - } + // Show battery type + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(295, 100); + getdisplay().print(batType); - // Reading bus data or using simulation data - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b); - getdisplay().setCursor(20, 240); - if(simulation == true){ - if(batVoltage == "12V"){ - value1 = 12.0; - } - if(batVoltage == "24V"){ - value1 = 24.0; - } - value1 += float(random(0, 5)) / 10; // Simulation data - getdisplay().print(value1,1); - } - else{ - // Check for valid real data, display also if hold values activated - if(valid1 == true || holdvalues == true){ - // Resolution switching - if(value1 < 10){ - getdisplay().print(value1,2); + // Show average settings + printAvg(average, 320, 84, true); + + // Reading bus data or using simulation data + getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b); + getdisplay().setCursor(20, 240); + if(simulation == true){ + if(batVoltage == "12V"){ + value1 = 12.0; } - if(value1 >= 10 && value1 < 100){ - getdisplay().print(value1,1); - } - if(value1 >= 100){ - getdisplay().print(value1,0); + if(batVoltage == "24V"){ + value1 = 24.0; } + value1 += float(random(0, 5)) / 10; // Simulation data + getdisplay().print(value1,1); } else{ - getdisplay().print("---"); // Missing bus data - } - } - - // Trend indicator - // Show trend indicator - if(trend == true){ - getdisplay().fillRect(310, 240, 40, 120, bgcolor); // Clear area - getdisplay().fillRect(315, 183, 35, 4, textcolor); // Draw separator - if(int(raw * 10) > int(valueTrend * 10)){ - displayTrendHigh(320, 174, 11, textcolor); // Show high indicator + // Check for valid real data, display also if hold values activated + if(valid1 == true || holdvalues == true){ + // Resolution switching + if(value1 < 10){ + getdisplay().print(value1,2); + } + if(value1 >= 10 && value1 < 100){ + getdisplay().print(value1,1); + } + if(value1 >= 100){ + getdisplay().print(value1,0); + } + } + else{ + getdisplay().print("---"); // Missing bus data + } } - if(int(raw * 10) < int(valueTrend * 10)){ - displayTrendLow(320, 195, 11, textcolor); // Show low indicator - } - } - // No trend indicator - else{ - getdisplay().fillRect(310, 240, 40, 120, bgcolor); // Clear area - } - - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(10, 290); - getdisplay().print("[AVG]"); - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - getdisplay().setCursor(293, 290); - getdisplay().print("[TRD]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); + // Show trend indicator + if(trend == true){ + getdisplay().fillRect(315, 183, 35, 4, commonData->fgcolor); // Draw separator + if(int(raw * 10) > int(valueTrend * 10)){ + displayTrendHigh(320, 174, 11, commonData->fgcolor); // Show high indicator + } + if(int(raw * 10) < int(valueTrend * 10)){ + displayTrendLow(320, 195, 11, commonData->fgcolor); // Show low indicator + } } + } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); + else { + // Display mode analog + + // center + Point c = {260, 270}; + uint8_t r = 240; + + Point p1, p2; + std::vector pts; + + // Instrument + getdisplay().drawCircleHelper(c.x, c.y, r + 2, 0x01, commonData->fgcolor); + getdisplay().drawCircleHelper(c.x, c.y, r + 1, 0x01, commonData->fgcolor); + getdisplay().drawCircleHelper(c.x, c.y, r , 0x01, commonData->fgcolor); + + // Scale + // angle to voltage scale mapping + std::map mapping = { + {15, "10"}, {30, "11"}, {45, "12"}, {60, "13"}, {75, "14"} + }; + pts = { + {c.x - r, c.y - 1}, + {c.x - r + 12, c.y - 1}, + {c.x - r + 12, c.y + 1}, + {c.x - r, c.y + 1} + }; + getdisplay().setFont(&Ubuntu_Bold10pt7b); + for (int angle = 3; angle < 90; angle += 3) { + if (angle % 15 == 0) { + fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor); + p1 = rotatePoint(c, {c.x - r + 30, c.y}, angle); + drawTextCenter(p1.x, p1.y, mapping[angle]); + } + else { + p1 = rotatePoint(c, {c.x - r, c.y}, angle); + p2 = rotatePoint(c, {c.x - r + 6, c.y}, angle); + getdisplay().drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor); + } + } + + // Pointer rotation and limits + double angle; + if (not valid1) { + angle = -0.5; + } + else { + if (value1 > 15.0) { + angle = 91; + } + else if (value1 <= 9) { + angle = -0.5; + } + else { + angle = (value1 - 9) * 15; + } + } + + // Pointer + // thick part + pts = { + {c.x - 2, c.y + 3}, + {c.x - r + 38, c.y + 2}, + {c.x - r + 38, c.y - 2}, + {c.x - 2, c.y - 3} + }; + fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor); + // thin part + pts = { + {c.x - r + 40, c.y + 1}, + {c.x - r + 5, c.y + 1}, + {c.x - r + 5, c.y -1}, + {c.x - r + 40, c.y - 1}, + }; + fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor); + + // base + getdisplay().fillCircle(c.x, c.y, 7, commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, 4, commonData->bgcolor); + + // Symbol + printVoltageSymbol(40, 60, commonData->fgcolor); + + // Additional information at right side + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(300, 60); + getdisplay().print("Source:"); + getdisplay().setCursor(300, 80); + getdisplay().print(name1); + + getdisplay().setCursor(300, 110); + getdisplay().print("Type:"); + getdisplay().setCursor(300, 130); + getdisplay().print(batType); + + getdisplay().setCursor(300, 160); + getdisplay().print("Avg:"); + printAvg(average, 300, 180, false); + + // FRAM indicator + if (hasFRAM) { + getdisplay().drawXBitmap(300, 240, fram_bits, icon_width, icon_height, commonData->fgcolor); + } + } // Update display diff --git a/lib/obp60task/PageWhite.cpp b/lib/obp60task/PageWhite.cpp index e941732..4c9d0c7 100644 --- a/lib/obp60task/PageWhite.cpp +++ b/lib/obp60task/PageWhite.cpp @@ -3,17 +3,17 @@ #include "Pagedata.h" #include "OBP60Extensions.h" -class PageWhite : public Page{ - bool keylock = false; // Keylock - +class PageWhite : public Page +{ public: PageWhite(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageWhite"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageWhite"); } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Get config data String flashLED = config->getString(config->flashLED); @@ -60,4 +60,4 @@ PageDescription registerPageWhite( false // Show display header on/off ); -#endif \ No newline at end of file +#endif diff --git a/lib/obp60task/PageWind.cpp b/lib/obp60task/PageWind.cpp new file mode 100644 index 0000000..3702613 --- /dev/null +++ b/lib/obp60task/PageWind.cpp @@ -0,0 +1,639 @@ +#ifdef BOARD_OBP60S3 + +#include "Pagedata.h" +#include "OBP60Extensions.h" +#include "N2kMessages.h" + +#define front_width 120 +#define front_height 162 +static unsigned char front_bits[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf7, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xf3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xff, 0xe1, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xc1, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x80, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x7f, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x7f, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0xfe, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0xfe, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x1f, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x0f, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xf8, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0x03, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x80, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, + 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, + 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, + 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, + 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, + 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x07, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x80, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, + 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xf0, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, + 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x01, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x80, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, + 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x03, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, + 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0 }; + +class PageWind : public Page +{ +bool keylock = false; // Keylock +int8_t lp = 80; // Pointer length +char mode = 'N'; // page mode (N)ormal | (L)ens | e(X)ample +char source = 'A'; // data source (A)pparent | (T)rue + +public: + PageWind(CommonData &common){ + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageWind"); + if (hasFRAM) { + lp = fram.read(FRAM_WIND_SIZE); + source = fram.read(FRAM_WIND_SRC); + mode = fram.read(FRAM_WIND_MODE); + } + } + + virtual void setupKeys(){ + Page::setupKeys(); + commonData->keydata[0].label = "MODE"; + if (mode == 'X') { + commonData->keydata[1].label = "#MINUS"; + commonData->keydata[4].label = "#PLUS"; + } else { + commonData->keydata[1].label = "SRC"; + } + } + + // Key functions + virtual int handleKey(int key){ + + if(key == 1){ // Mode switch + if(mode == 'N'){ + mode = 'L'; + } else if (mode == 'L') { + mode = 'X'; + } else { + mode = 'N'; + } + if (hasFRAM) fram.write(FRAM_WIND_MODE, mode); + setupKeys(); + return 0; // Commit the key + } + + // Set source or reduce instrument size + if(key == 2){ + if(mode == 'X'){ + // Code for reduce + lp = lp - 10; + if(lp < 10){ + lp = 10; + } + if (hasFRAM) fram.write(FRAM_WIND_SIZE, lp); + } else { + // Code for set source + if(source == 'A'){ + source = 'T'; + } else { + source = 'A'; + } + if (hasFRAM) fram.write(FRAM_WIND_SRC, source); + } + return 0; // Commit the key + } + + // Enlarge instrument size + if(key == 5 && mode == 'X'){ // Code for enlarge + lp = lp + 10; + if(lp > 80){ + lp = 80; + } + if (hasFRAM) fram.write(FRAM_WIND_SIZE, lp); + return 0; // Commit the key + } + + // Keylock function + if(key == 11){ // Code for keylock + commonData->keylock = !commonData->keylock; + return 0; // Commit the key + } + return key; + } + + virtual void displayPage(PageData &pageData) + { + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; + + static String svalue1old = ""; + static String unit1old = ""; + static String svalue2old = ""; + static String unit2old = ""; + + // Get config data + String lengthformat = config->getString(config->lengthFormat); + // bool simulation = config->getBool(config->useSimuData); + bool holdvalues = config->getBool(config->holdvalues); + String flashLED = config->getString(config->flashLED); + String backlightMode = config->getString(config->backlight); + + GwApi::BoatValue *bvalue1; // Value 1 for speed on top + GwApi::BoatValue *bvalue2; // Value 2 for angle on bottom + + // Get boat values for speed (AWS/TWS) + if (source == 'A') { + bvalue1 = pageData.values[0]; + } else { + bvalue1 = pageData.values[2]; + } + String name1 = bvalue1->getName().c_str(); // Value name + name1 = name1.substring(0, 6); // String length limit for value name + double value1 = bvalue1->value; // Value as double in SI unit + // bool valid1 = bvalue1->valid; // Valid information + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value + + // Get boat values for angle (AWD/TWD) + if (source == 'A') { + bvalue2 = pageData.values[1]; + } else { + bvalue2 = pageData.values[3]; + } + String name2 = bvalue2->getName().c_str(); // Value name + name2 = name2.substring(0, 6); // String length limit for value name + double value2 = bvalue2->value; // Value as double in SI unit + // bool valid2 = bvalue2->valid; // Valid information + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value + + // Optical warning by limit violation (unused) + if(String(flashLED) == "Limit Violation"){ + setBlinkingLED(false); + setFlashLED(false); + } + + // Logging boat values + if (bvalue1 == NULL) return; + LOG_DEBUG(GwLog::LOG,"Drawing at PageWind, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2); + + // Draw page + //*********************************************************** + + // Set display in partial refresh mode + getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + + getdisplay().setTextColor(commonData->fgcolor); + + + if (mode == 'X') { + // Original example code with scaling circle + + // Show values AWS/TWS + getdisplay().setFont(&Ubuntu_Bold20pt7b); + getdisplay().setCursor(20, 50); + getdisplay().print(name1); // Value name + getdisplay().print(": "); + if(holdvalues == false){ + getdisplay().print(svalue1); // Value + getdisplay().print(" "); + getdisplay().print(unit1); // Unit + } + else{ + getdisplay().print(svalue1old); // Value old + getdisplay().print(" "); + getdisplay().print(unit1old); // Unit old + } + + // Show values AWD/TWD + getdisplay().setFont(&Ubuntu_Bold20pt7b); + getdisplay().setCursor(20, 260); + getdisplay().print(name2); // Value name + getdisplay().print(": "); + if(holdvalues == false){ + getdisplay().print(svalue2); // Value + getdisplay().print(" "); + getdisplay().print(unit2); // Unit + } + else{ + getdisplay().print(svalue2old); // Value old + getdisplay().print(" "); + getdisplay().print(unit2old); // Unit old + } + + Point c = {200, 145}; + + // Draw instrument + getdisplay().fillCircle(c.x, c.y, lp + 5, commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, lp + 1, commonData->bgcolor); + + // Wind pointer + if (bvalue2->valid) { + uint8_t lp0 = lp * 0.6; // effective pointer outside size + uint8_t lp1 = lp * 0.4; // effective pointer inside size + // zero position + std::vector pts = { + {c.x, c.y - lp}, + {c.x - 7, c.y - lp + lp0}, + {c.x, c.y - lp + lp1}, + {c.x + 7, c.y - lp + lp0} + }; + fillPoly4(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor); + } else { + getdisplay().setFont(&Ubuntu_Bold12pt7b); + drawTextCenter(c.x, c.y, "no data"); + } + + } else if (mode == 'L') { // Mode (L)ens + + Point c = {200, 155}; + uint16_t r = 150; + + Point p; + std::vector pts = { // polygon lines + {c.x - 2, c.y - r}, + {c.x + 2, c.y - r}, + {c.x + 2, c.y - (r - 16)}, + {c.x - 2, c.y - (r - 16)} + }; + int angle; + + getdisplay().setFont(&Ubuntu_Bold12pt7b); + + // starbord + // text with line + angle = 20; + for (int i = 30; i < 150; i += 30) { + p = rotatePoint(c, {c.x, c.y - r + 40}, i); + drawTextCenter(p.x, p.y, String(angle)); + angle += 10; + fillPoly4(rotatePoints(c, pts, i), commonData->fgcolor); + } + // dots + for (int i = 30; i < 138; i += 6) { + if (i % 15 != 0) { + p = rotatePoint(c, {c.x, c.y - r + 5}, i); + getdisplay().fillCircle(p.x, p.y, 2, commonData->fgcolor); + } + } + + // port + angle = 50; + // text with line + for (int i = 240; i <= 330; i += 30) { + p = rotatePoint(c, {c.x, c.y - r + 40}, i); + drawTextCenter(p.x, p.y, String(angle)); + angle -= 10; + fillPoly4(rotatePoints(c, pts, i), commonData->fgcolor); + } + // dots + for (int i = 228; i < 330; i += 6) { + if (i % 15 != 0) { + p = rotatePoint(c, {c.x, c.y - r + 5}, i); + getdisplay().fillCircle(p.x, p.y, 2, commonData->fgcolor); + } + } + + // data source + getdisplay().setFont(&Ubuntu_Bold12pt7b); + getdisplay().setCursor(8, 50); + if (source == 'A') { + getdisplay().print("APP"); + } else { + getdisplay().print("TRUE"); + } + + // Wind pointer (angle) + if (bvalue2->valid) { + float alpha = RadToDeg(value2); + bool port = (alpha > 180); + if (port) { + alpha = 360 - alpha; + } + if (alpha < 15) { + alpha = 15; // stop at start of scale + } else if (alpha > 55) { + alpha = 55; // stop at end of scale + } + alpha = 3 * alpha - 30; // convert to lens scale + if (port) { + alpha *= -1; + } + + getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor); + pts = { + {c.x - 1, c.y - (r - 20)}, + {c.x + 1, c.y - (r - 20)}, + {c.x + 6, c.y + 15}, + {c.x - 6, c.y + 15} + }; + fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor); + } else { + getdisplay().setFont(&Ubuntu_Bold12pt7b); + drawTextCenter(c.x, c.y, "no data"); + } + + // Wind speed as decimal number + getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); + getdisplay().setCursor(150, 250); + if (holdvalues == false) { + getdisplay().print(svalue1); + } else { + getdisplay().print(svalue1old); + } + // unit + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(220, 265); + getdisplay().print("kts"); + } + else { + // Normal mode + + // data source + getdisplay().setFont(&Ubuntu_Bold12pt7b); + getdisplay().setCursor(8, 50); + if (source == 'A') { + getdisplay().print("APP"); + } else { + getdisplay().print("TRUE"); + } + + // draw ship front symbol (as bitmap) + getdisplay().drawXBitmap(140, 30, front_bits, front_width, front_height, commonData->fgcolor); + + Point c = {200, 155}; + uint16_t r = 150; + + Point p; + std::vector pts = { // polygon lines + {c.x - 2, c.y - r}, + {c.x + 2, c.y - r}, + {c.x + 2, c.y - (r - 16)}, + {c.x - 2, c.y - (r - 16)} + }; + int angle; + + // starbord + // text with line + for (int i = 30; i < 150; i += 30) { + p = rotatePoint(c, {c.x, c.y - r + 40}, i); + drawTextCenter(p.x, p.y, String(i)); + fillPoly4(rotatePoints(c, pts, i), commonData->fgcolor); + } + // dots + for (int i = 30; i < 150; i += 10) { + if (i % 30 != 0) { + p = rotatePoint(c, {c.x, c.y - r + 5}, i); + getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor); + } + } + + // port + // text with line + angle = 120; + for (int i = 240; i <= 330; i += 30) { + p = rotatePoint(c, {c.x, c.y - r + 40}, i); + drawTextCenter(p.x, p.y, String(angle)); + angle -= 30; + fillPoly4(rotatePoints(c, pts, i), commonData->fgcolor); + } + // dots + for (int i = 210; i < 340; i += 10) { + if (i % 30 != 0) { + p = rotatePoint(c, {c.x, c.y - r + 5}, i); + getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor); + } + } + + // Wind speed as decimal number + getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); + getdisplay().setCursor(150, 250); + if (holdvalues == false) { + getdisplay().print(svalue1); + } else { + getdisplay().print(svalue1old); + } + // unit + getdisplay().setFont(&Ubuntu_Bold8pt7b); + getdisplay().setCursor(220, 265); + getdisplay().print("kts"); + + // Wind pointer (angle) + if (bvalue2->valid) { + float alpha = RadToDeg(value2); + getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor); + pts = { + {c.x - 1, c.y - (r - 20)}, + {c.x + 1, c.y - (r - 20)}, + {c.x + 6, c.y + 15}, + {c.x - 6, c.y + 15} + }; + fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor); + getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor); + } else { + getdisplay().setFont(&Ubuntu_Bold12pt7b); + drawTextCenter(c.x, c.y, "no data"); + } + + } + + // Update display + getdisplay().nextPage(); // Partial update (fast) + + }; +}; + +static Page *createPage(CommonData &common){ + return new PageWind(common); +} +/** + * with the code below we make this page known to the PageTask + * we give it a type (name) that can be selected in the config + * we define which function is to be called + * and we provide the number of user parameters we expect (0 here) + * and will will provide the names of the fixed values we need + */ +PageDescription registerPageWind( + "Wind", // Page name + createPage, // Action + 0, // Number of bus values depends on selection in Web configuration + {"AWS","AWA", "TWS", "TWA"}, // Bus values we need in the page + true // Show display header on/off +); + +#endif diff --git a/lib/obp60task/PageWindRose.cpp b/lib/obp60task/PageWindRose.cpp index 61aabd2..88c490f 100644 --- a/lib/obp60task/PageWindRose.cpp +++ b/lib/obp60task/PageWindRose.cpp @@ -5,28 +5,27 @@ class PageWindRose : public Page { -bool keylock = false; // Keylock int16_t lp = 80; // Pointer length public: PageWindRose(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageWindRose"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRose"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; static String svalue1old = ""; static String unit1old = ""; @@ -44,7 +43,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -55,9 +53,9 @@ public: name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - value1 = formatValue(bvalue1, commonData).value;// Format only nesaccery for simulation data for pointer - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value if(valid1 == true){ svalue1old = svalue1; // Save old value unit1old = unit1; // Save old unit @@ -69,8 +67,8 @@ public: name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value if(valid2 == true){ svalue2old = svalue2; // Save old value unit2old = unit2; // Save old unit @@ -82,8 +80,8 @@ public: name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value if(valid3 == true){ svalue3old = svalue3; // Save old value unit3old = unit3; // Save old unit @@ -95,8 +93,8 @@ public: name4 = name4.substring(0, 6); // String length limit for value name double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information - String svalue4 = formatValue(bvalue4, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit4 = formatValue(bvalue4, commonData).unit; // Unit of value + String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value if(valid4 == true){ svalue4old = svalue4; // Save old value unit4old = unit4; // Save old unit @@ -108,8 +106,8 @@ public: name5 = name5.substring(0, 6); // String length limit for value name double value5 = bvalue5->value; // Value as double in SI unit bool valid5 = bvalue5->valid; // Valid information - String svalue5 = formatValue(bvalue5, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit5 = formatValue(bvalue5, commonData).unit; // Unit of value + String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value if(valid5 == true){ svalue5old = svalue5; // Save old value unit5old = unit5; // Save old unit @@ -121,8 +119,8 @@ public: name6 = name6.substring(0, 6); // String length limit for value name double value6 = bvalue6->value; // Value as double in SI unit bool valid6 = bvalue6->valid; // Valid information - String svalue6 = formatValue(bvalue6, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit6 = formatValue(bvalue6, commonData).unit; // Unit of value + String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value if(valid6 == true){ svalue6old = svalue6; // Save old value unit6old = unit6; // Save old unit @@ -141,25 +139,12 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show values AWA - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 65); getdisplay().print(svalue1); // Value @@ -177,10 +162,9 @@ public: } // Horizintal separator left - getdisplay().fillRect(0, 149, 60, 3, pixelcolor); + getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor); // Show values AWS - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 270); getdisplay().print(svalue2); // Value @@ -198,7 +182,6 @@ public: } // Show values TWD - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(295, 65); if(valid3 == true){ @@ -221,10 +204,9 @@ public: } // Horizintal separator right - getdisplay().fillRect(340, 149, 80, 3, pixelcolor); + getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor); // Show values TWS - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(295, 270); getdisplay().print(svalue4); // Value @@ -247,16 +229,16 @@ public: int rInstrument = 110; // Radius of grafic instrument float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument - 10, pixelcolor); // Inner circle - getdisplay().fillCircle(200, 150, rInstrument - 13, bgcolor); // Inner circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle + getdisplay().fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle for(int i=0; i<360; i=i+10) { // Scaling values float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots - float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots + float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots const char *ii = ""; switch (i) { @@ -288,7 +270,7 @@ public: // Draw sub scale with dots float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); float sinx=sin(i/180.0*pi); float cosx=cos(i/180.0*pi); @@ -301,10 +283,10 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } @@ -321,7 +303,7 @@ public: float yy2 = -(rInstrument-15); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -331,17 +313,16 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 150, startwidth + 6, bgcolor); - getdisplay().fillCircle(200, 150, startwidth + 4, pixelcolor); + getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor); + getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor); //******************************************************************************************* // Show values DBT - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); getdisplay().setCursor(160, 200); getdisplay().print(svalue5); // Value @@ -356,7 +337,6 @@ public: } // Show values STW - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); getdisplay().setCursor(160, 130); getdisplay().print(svalue6); // Value @@ -370,22 +350,6 @@ public: getdisplay().print(unit6old); // Unit } - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; diff --git a/lib/obp60task/PageWindRoseFlex.cpp b/lib/obp60task/PageWindRoseFlex.cpp index f71018a..ba4b029 100644 --- a/lib/obp60task/PageWindRoseFlex.cpp +++ b/lib/obp60task/PageWindRoseFlex.cpp @@ -5,28 +5,27 @@ class PageWindRoseFlex : public Page { -bool keylock = false; // Keylock int16_t lp = 80; // Pointer length public: PageWindRoseFlex(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageWindRoseFlex"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRoseFlex"); } // Key functions virtual int handleKey(int key){ - // Keylock function - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData) - { - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; static String svalue1old = ""; static String unit1old = ""; @@ -44,7 +43,6 @@ public: // Get config data String lengthformat = config->getString(config->lengthFormat); bool simulation = config->getBool(config->useSimuData); - String displaycolor = config->getString(config->displaycolor); bool holdvalues = config->getBool(config->holdvalues); String flashLED = config->getString(config->flashLED); String backlightMode = config->getString(config->backlight); @@ -55,9 +53,9 @@ public: name1 = name1.substring(0, 6); // String length limit for value name double value1 = bvalue1->value; // Value as double in SI unit bool valid1 = bvalue1->valid; // Valid information - value1 = formatValue(bvalue1, commonData).value;// Format only nesaccery for simulation data for pointer - String svalue1 = formatValue(bvalue1, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit1 = formatValue(bvalue1, commonData).unit; // Unit of value + value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer + String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value if(valid1 == true){ svalue1old = svalue1; // Save old value unit1old = unit1; // Save old unit @@ -69,8 +67,8 @@ public: name2 = name2.substring(0, 6); // String length limit for value name double value2 = bvalue2->value; // Value as double in SI unit bool valid2 = bvalue2->valid; // Valid information - String svalue2 = formatValue(bvalue2, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit2 = formatValue(bvalue2, commonData).unit; // Unit of value + String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value if(valid2 == true){ svalue2old = svalue2; // Save old value unit2old = unit2; // Save old unit @@ -82,8 +80,8 @@ public: name3 = name3.substring(0, 6); // String length limit for value name double value3 = bvalue3->value; // Value as double in SI unit bool valid3 = bvalue3->valid; // Valid information - String svalue3 = formatValue(bvalue3, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit3 = formatValue(bvalue3, commonData).unit; // Unit of value + String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value if(valid3 == true){ svalue3old = svalue3; // Save old value unit3old = unit3; // Save old unit @@ -95,8 +93,8 @@ public: name4 = name4.substring(0, 6); // String length limit for value name double value4 = bvalue4->value; // Value as double in SI unit bool valid4 = bvalue4->valid; // Valid information - String svalue4 = formatValue(bvalue4, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit4 = formatValue(bvalue4, commonData).unit; // Unit of value + String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value if(valid4 == true){ svalue4old = svalue4; // Save old value unit4old = unit4; // Save old unit @@ -108,8 +106,8 @@ public: name5 = name5.substring(0, 6); // String length limit for value name double value5 = bvalue5->value; // Value as double in SI unit bool valid5 = bvalue5->valid; // Valid information - String svalue5 = formatValue(bvalue5, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit5 = formatValue(bvalue5, commonData).unit; // Unit of value + String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value if(valid5 == true){ svalue5old = svalue5; // Save old value unit5old = unit5; // Save old unit @@ -121,8 +119,8 @@ public: name6 = name6.substring(0, 6); // String length limit for value name double value6 = bvalue6->value; // Value as double in SI unit bool valid6 = bvalue6->valid; // Valid information - String svalue6 = formatValue(bvalue6, commonData).svalue; // Formatted value as string including unit conversion and switching decimal places - String unit6 = formatValue(bvalue6, commonData).unit; // Unit of value + String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places + String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value if(valid6 == true){ svalue6old = svalue6; // Save old value unit6old = unit6; // Save old unit @@ -141,25 +139,12 @@ public: // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // Show values AWA - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 65); getdisplay().print(svalue1); // Value @@ -177,10 +162,9 @@ public: } // Horizintal separator left - getdisplay().fillRect(0, 149, 60, 3, pixelcolor); + getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor); // Show values AWS - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(10, 270); getdisplay().print(svalue2); // Value @@ -198,11 +182,11 @@ public: } // Show values TWD - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(295, 65); if(valid3 == true){ - getdisplay().print(abs(value3 * 180 / PI), 0); // Value + // getdisplay().print(abs(value3 * 180 / PI), 0); // Value + getdisplay().print(svalue3); // Value } else{ getdisplay().print("---"); // Value @@ -221,10 +205,9 @@ public: } // Horizintal separator right - getdisplay().fillRect(340, 149, 80, 3, pixelcolor); + getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor); // Show values TWS - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b); getdisplay().setCursor(295, 270); getdisplay().print(svalue4); // Value @@ -247,16 +230,16 @@ public: int rInstrument = 110; // Radius of grafic instrument float pi = 3.141592; - getdisplay().fillCircle(200, 150, rInstrument + 10, pixelcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument + 7, bgcolor); // Outer circle - getdisplay().fillCircle(200, 150, rInstrument - 10, pixelcolor); // Inner circle - getdisplay().fillCircle(200, 150, rInstrument - 13, bgcolor); // Inner circle + getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle + getdisplay().fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle + getdisplay().fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle for(int i=0; i<360; i=i+10) { // Scaling values float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots - float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots + float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate dots const char *ii = ""; switch (i) { @@ -288,7 +271,7 @@ public: // Draw sub scale with dots float x1c = 200 + rInstrument*sin(i/180.0*pi); float y1c = 150 - rInstrument*cos(i/180.0*pi); - getdisplay().fillCircle((int)x1c, (int)y1c, 2, pixelcolor); + getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor); float sinx=sin(i/180.0*pi); float cosx=cos(i/180.0*pi); @@ -301,10 +284,10 @@ public: float yy2 = -(rInstrument+10); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor); getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), 200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2), - 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),pixelcolor); + 200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor); } } @@ -321,7 +304,7 @@ public: float yy2 = -(rInstrument-15); getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1), 200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1), - 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),pixelcolor); + 200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor); // Inverted pointer // Pointer as triangle with center base 2*width float endwidth = 2; // End width of pointer @@ -331,17 +314,16 @@ public: float iy2 = -endwidth; getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1), 200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1), - 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),pixelcolor); + 200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor); } // Center circle - getdisplay().fillCircle(200, 150, startwidth + 6, bgcolor); - getdisplay().fillCircle(200, 150, startwidth + 4, pixelcolor); + getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor); + getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor); //******************************************************************************************* // Show values DBT - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); getdisplay().setCursor(160, 200); getdisplay().print(svalue5); // Value @@ -356,7 +338,6 @@ public: } // Show values STW - getdisplay().setTextColor(textcolor); getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b); getdisplay().setCursor(160, 130); getdisplay().print(svalue6); // Value @@ -370,22 +351,6 @@ public: getdisplay().print(unit6old); // Unit } - // Key Layout - getdisplay().setTextColor(textcolor); - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 290); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 290); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 290); - getdisplay().print(" [ Keylock active ]"); - } - // Update display getdisplay().nextPage(); // Partial update (fast) }; diff --git a/lib/obp60task/PageXTETrack.cpp b/lib/obp60task/PageXTETrack.cpp index b16f9ab..7b5f487 100644 --- a/lib/obp60task/PageXTETrack.cpp +++ b/lib/obp60task/PageXTETrack.cpp @@ -26,12 +26,12 @@ static unsigned char ship_bits[] PROGMEM = { 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00 }; -class PageXTETrack : public Page{ - bool keylock = false; // Keylock - +class PageXTETrack : public Page +{ public: PageXTETrack(CommonData &common){ - common.logger->logDebug(GwLog::LOG,"Show PageXTETrack"); + commonData = &common; + common.logger->logDebug(GwLog::LOG,"Instantiate PageXTETrack"); } void drawSegment(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, @@ -52,20 +52,20 @@ class PageXTETrack : public Page{ } virtual int handleKey(int key){ - if(key == 11){ // Code for keylock - keylock = !keylock; // Toggle keylock + // Code for keylock + if(key == 11){ + commonData->keylock = !commonData->keylock; return 0; // Commit the key } return key; } - virtual void displayPage(CommonData &commonData, PageData &pageData){ - GwConfigHandler *config = commonData.config; - GwLog *logger=commonData.logger; + virtual void displayPage(PageData &pageData){ + GwConfigHandler *config = commonData->config; + GwLog *logger = commonData->logger; // Get config data String flashLED = config->getString(config->flashLED); - String displaycolor = config->getString(config->displaycolor); String backlightMode = config->getString(config->backlight); String trackStep = config->getString(config->trackStep); @@ -83,18 +83,11 @@ class PageXTETrack : public Page{ // Draw page //*********************************************************** - // Set background color and text color - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; - if(displaycolor != "Normal"){ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } // Set display in partial refresh mode getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + getdisplay().setTextColor(commonData->fgcolor); + // descriptions getdisplay().setFont(&Ubuntu_Bold8pt7b); getdisplay().setCursor(50, 188); @@ -113,25 +106,25 @@ class PageXTETrack : public Page{ uint16_t w, h; GwApi::BoatValue *bv_xte = pageData.values[0]; // XTE - String sval_xte = formatValue(bv_xte, commonData).svalue; + String sval_xte = formatValue(bv_xte, *commonData).svalue; getdisplay().getTextBounds(sval_xte, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(160-w, 170); getdisplay().print(sval_xte); GwApi::BoatValue *bv_cog = pageData.values[1]; // COG - String sval_cog = formatValue(bv_cog, commonData).svalue; + String sval_cog = formatValue(bv_cog, *commonData).svalue; getdisplay().getTextBounds(sval_cog, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(360-w, 170); getdisplay().print(sval_cog); GwApi::BoatValue *bv_dtw = pageData.values[2]; // DTW - String sval_dtw = formatValue(bv_dtw, commonData).svalue; + String sval_dtw = formatValue(bv_dtw, *commonData).svalue; getdisplay().getTextBounds(sval_dtw, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(160-w, 257); getdisplay().print(sval_dtw); GwApi::BoatValue *bv_btw = pageData.values[3]; // BTW - String sval_btw = formatValue(bv_btw, commonData).svalue; + String sval_btw = formatValue(bv_btw, *commonData).svalue; getdisplay().getTextBounds(sval_btw, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(360-w, 257); getdisplay().print(sval_btw); @@ -141,7 +134,7 @@ class PageXTETrack : public Page{ // XTETrack view // draw ship symbol (as bitmap) - getdisplay().drawXBitmap(184, 68, ship_bits, ship_width, ship_height, pixelcolor); + getdisplay().drawXBitmap(184, 68, ship_bits, ship_width, ship_height, commonData->fgcolor); // draw next waypoint name String sval_wpname = "no data"; @@ -196,28 +189,13 @@ class PageXTETrack : public Page{ } // left segments - drawSegment(0, 54, 46, 24, 75, 24, 0, 90, pixelcolor, seg[2]); - drawSegment(0, 100, 82, 24, 112, 24, 50, 100, pixelcolor, seg[1]); - drawSegment(60, 100, 117, 24, 147, 24, 110, 100, pixelcolor,seg[0]); + drawSegment(0, 54, 46, 24, 75, 24, 0, 90, commonData->fgcolor, seg[2]); + drawSegment(0, 100, 82, 24, 112, 24, 50, 100, commonData->fgcolor, seg[1]); + drawSegment(60, 100, 117, 24, 147, 24, 110, 100, commonData->fgcolor,seg[0]); // right segments - drawSegment(340, 100, 283, 24, 253, 24, 290, 100, pixelcolor, seg[3]); - drawSegment(399, 100, 318, 24, 289, 24, 350, 100, pixelcolor, seg[4]); - drawSegment(399, 54, 354, 24, 325, 24, 399, 90, pixelcolor, seg[5]); - - // Key Layout - getdisplay().setFont(&Ubuntu_Bold8pt7b); - if(keylock == false){ - getdisplay().setCursor(130, 296); - getdisplay().print("[ <<<< " + String(commonData.data.actpage) + "/" + String(commonData.data.maxpage) + " >>>> ]"); - if(String(backlightMode) == "Control by Key"){ // Key for illumination - getdisplay().setCursor(343, 296); - getdisplay().print("[ILUM]"); - } - } - else{ - getdisplay().setCursor(130, 296); - getdisplay().print(" [ Keylock active ]"); - } + drawSegment(340, 100, 283, 24, 253, 24, 290, 100, commonData->fgcolor, seg[3]); + drawSegment(399, 100, 318, 24, 289, 24, 350, 100, commonData->fgcolor, seg[4]); + drawSegment(399, 54, 354, 24, 325, 24, 399, 90, commonData->fgcolor, seg[5]); // Update display getdisplay().nextPage(); // Partial update (fast) diff --git a/lib/obp60task/Pagedata.h b/lib/obp60task/Pagedata.h index e4ff852..2a72ba6 100644 --- a/lib/obp60task/Pagedata.h +++ b/lib/obp60task/Pagedata.h @@ -3,10 +3,14 @@ #include "GwApi.h" #include #include +#include "LedSpiTask.h" + +#define MAX_PAGE_NUMBER 10 // Max number of pages for show data typedef std::vector ValueList; typedef struct{ String pageName; + uint8_t pageNumber; // page number in sequence of visible pages //the values will always contain the user defined values first ValueList values; } PageData; @@ -60,21 +64,56 @@ typedef struct{ bool sunDown = true; } SunData; +typedef struct{ + String label = ""; + bool selected = false; // for virtual keyboard function + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; +} TouchKeyData; + +typedef struct{ + Color color; // red, orange, yellow, green, blue, aqua, violet, white + BacklightMode mode; // off, on, sun, bus, time, key + uint8_t brightness; // 0% (off), user setting from 20% to 100% full power + bool on; // fast on/off detector +} BacklightData; + typedef struct{ GwApi::Status status; GwLog *logger=NULL; GwConfigHandler *config=NULL; SensorData data; SunData sundata; + TouchKeyData keydata[6]; + BacklightData backlight; GwApi::BoatValue *time=NULL; GwApi::BoatValue *date=NULL; + uint16_t fgcolor; + uint16_t bgcolor; + bool keylock = false; } CommonData; //a base class that all pages must inherit from class Page{ + protected: + CommonData *commonData; public: - virtual void displayPage(CommonData &commonData, PageData &pageData)=0; - virtual void displayNew(CommonData &commonData, PageData &pageData){} + virtual void displayPage(PageData &pageData)=0; + virtual void displayNew(PageData &pageData){} + virtual void setupKeys() { + commonData->keydata[0].label = ""; + commonData->keydata[1].label = ""; + commonData->keydata[2].label = "#LEFT"; + commonData->keydata[3].label = "#RIGHT"; + commonData->keydata[4].label = ""; + if (commonData->backlight.mode == KEY) { + commonData->keydata[5].label = "ILUM"; + } else { + commonData->keydata[5].label = ""; + } + } //return -1 if handled by the page virtual int handleKey(int key){return key;} }; @@ -112,6 +151,13 @@ class PageDescription{ } }; +class PageStruct{ + public: + Page *page=NULL; + PageData parameters; + PageDescription *description=NULL; +}; + // Structure for formated boat values typedef struct{ double value; diff --git a/lib/obp60task/config.json b/lib/obp60task/config.json index ca57f33..49ac39d 100644 --- a/lib/obp60task/config.json +++ b/lib/obp60task/config.json @@ -898,17 +898,88 @@ "obp60":"true" } }, + { + "name": "imageFormat", + "label": "Screenshot Format", + "type": "list", + "default":"PBM", + "description": "Graphics file format for screenshots [GIF|PBM|BMP]", + "list": [ + {"l":"Compressed image (GIF)","v":"GIF"}, + {"l":"Portable bitmap (PBM)","v":"PBM"}, + {"l":"Windows bitmap (BMP)","v":"BMP"} + ], + "category":"OBP60 Pages", + "capabilities": { + "obp60":"true" + } + }, { "name": "page1type", "label": "Type", "type": "list", "default": "Voltage", "description": "Type of page for page 1", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" - } + "obp60": "true" + }, + "condition": [ + { + "visiblePages": 1 + }, + { + "visiblePages": 2 + }, + { + "visiblePages": 3 + }, + { + "visiblePages": 4 + }, + { + "visiblePages": 5 + }, + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page1value1", @@ -918,9 +989,34 @@ "description": "The display for field one", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"OneValue"},{"page1type":"TwoValues"},{"page1type":"ThreeValues"},{"page1type":"FourValues"},{"page1type":"FourValues2"},{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "FourValues" + }, + { + "page1type": "FourValues2" + }, + { + "page1type": "OneValue" + }, + { + "page1type": "RollPitch" + }, + { + "page1type": "ThreeValues" + }, + { + "page1type": "TwoValues" + }, + { + "page1type": "WindRoseFlex" + }, + { + "page1type": "Fluid" + } + ] }, { "name": "page1value2", @@ -930,57 +1026,107 @@ "description": "The display for field two", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"TwoValues"},{"page1type":"ThreeValues"},{"page1type":"FourValues"},{"page1type":"FourValues2"},{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "FourValues" + }, + { + "page1type": "FourValues2" + }, + { + "page1type": "RollPitch" + }, + { + "page1type": "ThreeValues" + }, + { + "page1type": "TwoValues" + }, + { + "page1type": "WindRoseFlex" + } + ] }, { "name": "page1value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"ThreeValues"},{"page1type":"FourValues"},{"page1type":"FourValues2"},{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "FourValues" + }, + { + "page1type": "FourValues2" + }, + { + "page1type": "ThreeValues" + }, + { + "page1type": "WindRoseFlex" + } + ] }, { "name": "page1value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"FourValues"},{"page1type":"FourValues2"},{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "FourValues" + }, + { + "page1type": "FourValues2" + }, + { + "page1type": "WindRoseFlex" + } + ] }, { "name": "page1value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "WindRoseFlex" + } + ] }, { "name": "page1value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"WindRoseFlex"}] + "condition": [ + { + "page1type": "WindRoseFlex" + } + ] }, { "name": "page1fluid", @@ -988,20 +1134,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 1", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page1type":"Fluid"}] + "condition": [ + { + "page1type": "Fluid" + } + ] }, { "name": "page2type", @@ -1009,12 +1180,63 @@ "type": "list", "default": "WindRose", "description": "Type of page for page 2", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"2"},{"visiblePages":"3"},{"visiblePages":"4"},{"visiblePages":"5"},{"visiblePages":"6"},{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 2 + }, + { + "visiblePages": 3 + }, + { + "visiblePages": 4 + }, + { + "visiblePages": 5 + }, + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page2value1", @@ -1024,9 +1246,35 @@ "description": "The display for field one", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"OneValue"},{"page2type":"TwoValues"},{"page2type":"ThreeValues"},{"page2type":"FourValues"},{"page2type":"FourValues2"},{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "FourValues" + }, + { + "page2type": "FourValues2" + }, + { + "page2type": "OneValue" + }, + { + "page2type": "RollPitch" + }, + { + "page2type": "ThreeValues" + }, + { + "page2type": "TwoValues" + }, + { + "page2type": "WindRoseFlex" + }, + { + "page2type": "Fluid" + } + + ] }, { "name": "page2value2", @@ -1036,57 +1284,107 @@ "description": "The display for field two", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"TwoValues"},{"page2type":"ThreeValues"},{"page2type":"FourValues"},{"page2type":"FourValues2"},{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "FourValues" + }, + { + "page2type": "FourValues2" + }, + { + "page2type": "RollPitch" + }, + { + "page2type": "ThreeValues" + }, + { + "page2type": "TwoValues" + }, + { + "page2type": "WindRoseFlex" + } + ] }, { "name": "page2value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"ThreeValues"},{"page2type":"FourValues"},{"page2type":"FourValues2"},{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "FourValues" + }, + { + "page2type": "FourValues2" + }, + { + "page2type": "ThreeValues" + }, + { + "page2type": "WindRoseFlex" + } + ] }, { "name": "page2value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"FourValues"},{"page2type":"FourValues2"},{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "FourValues" + }, + { + "page2type": "FourValues2" + }, + { + "page2type": "WindRoseFlex" + } + ] }, { "name": "page2value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "WindRoseFlex" + } + ] }, { "name": "page2value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"WindRoseFlex"}] + "condition": [ + { + "page2type": "WindRoseFlex" + } + ] }, { "name": "page2fluid", @@ -1094,20 +1392,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 2", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page2type":"Fluid"}] + "condition": [ + { + "page2type": "Fluid" + } + ] }, { "name": "page3type", @@ -1115,24 +1438,97 @@ "type": "list", "default": "OneValue", "description": "Type of page for page 3", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"3"},{"visiblePages":"4"},{"visiblePages":"5"},{"visiblePages":"6"},{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 3 + }, + { + "visiblePages": 4 + }, + { + "visiblePages": 5 + }, + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page3value1", "label": "Field 1", "type": "boatData", - "default": "AWA", + "default": "", "description": "The display for field one", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"OneValue"},{"page3type":"TwoValues"},{"page3type":"ThreeValues"},{"page3type":"FourValues"},{"page3type":"FourValues2"},{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "FourValues" + }, + { + "page3type": "FourValues2" + }, + { + "page3type": "OneValue" + }, + { + "page3type": "RollPitch" + }, + { + "page3type": "ThreeValues" + }, + { + "page3type": "TwoValues" + }, + { + "page3type": "WindRoseFlex" + }, + { + "page3type": "Fluid" + } + ] }, { "name": "page3value2", @@ -1142,57 +1538,107 @@ "description": "The display for field two", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"TwoValues"},{"page3type":"ThreeValues"},{"page3type":"FourValues"},{"page3type":"FourValues2"},{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "FourValues" + }, + { + "page3type": "FourValues2" + }, + { + "page3type": "RollPitch" + }, + { + "page3type": "ThreeValues" + }, + { + "page3type": "TwoValues" + }, + { + "page3type": "WindRoseFlex" + } + ] }, { "name": "page3value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"ThreeValues"},{"page3type":"FourValues"},{"page3type":"FourValues2"},{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "FourValues" + }, + { + "page3type": "FourValues2" + }, + { + "page3type": "ThreeValues" + }, + { + "page3type": "WindRoseFlex" + } + ] }, { "name": "page3value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"FourValues"},{"page3type":"FourValues2"},{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "FourValues" + }, + { + "page3type": "FourValues2" + }, + { + "page3type": "WindRoseFlex" + } + ] }, { "name": "page3value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "WindRoseFlex" + } + ] }, { "name": "page3value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"WindRoseFlex"}] + "condition": [ + { + "page3type": "WindRoseFlex" + } + ] }, { "name": "page3fluid", @@ -1200,20 +1646,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 3", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page3type":"Fluid"}] + "condition": [ + { + "page3type": "Fluid" + } + ] }, { "name": "page4type", @@ -1221,84 +1692,204 @@ "type": "list", "default": "TwoValues", "description": "Type of page for page 4", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"4"},{"visiblePages":"5"},{"visiblePages":"6"},{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 4 + }, + { + "visiblePages": 5 + }, + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page4value1", "label": "Field 1", "type": "boatData", - "default": "STW", + "default": "", "description": "The display for field one", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"OneValue"},{"page4type":"TwoValues"},{"page4type":"ThreeValues"},{"page4type":"FourValues"},{"page4type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "FourValues" + }, + { + "page4type": "FourValues2" + }, + { + "page4type": "OneValue" + }, + { + "page4type": "RollPitch" + }, + { + "page4type": "ThreeValues" + }, + { + "page4type": "TwoValues" + }, + { + "page4type": "WindRoseFlex" + }, + { + "page4type": "Fluid" + } + ] }, { "name": "page4value2", "label": "Field 2", "type": "boatData", - "default": "DBT", + "default": "", "description": "The display for field two", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"TwoValues"},{"page4type":"ThreeValues"},{"page4type":"FourValues"},{"page4type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "FourValues" + }, + { + "page4type": "FourValues2" + }, + { + "page4type": "RollPitch" + }, + { + "page4type": "ThreeValues" + }, + { + "page4type": "TwoValues" + }, + { + "page4type": "WindRoseFlex" + } + ] }, { "name": "page4value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"ThreeValues"},{"page4type":"FourValues"},{"page4type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "FourValues" + }, + { + "page4type": "FourValues2" + }, + { + "page4type": "ThreeValues" + }, + { + "page4type": "WindRoseFlex" + } + ] }, { "name": "page4value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"FourValues"},{"page4type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "FourValues" + }, + { + "page4type": "FourValues2" + }, + { + "page4type": "WindRoseFlex" + } + ] }, { "name": "page4value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "WindRoseFlex" + } + ] }, { "name": "page4value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page4type": "WindRoseFlex" + } + ] }, { "name": "page4fluid", @@ -1306,20 +1897,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 4", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page4type":"Fluid"}] + "condition": [ + { + "page4type": "Fluid" + } + ] }, { "name": "page5type", @@ -1327,84 +1943,201 @@ "type": "list", "default": "ThreeValues", "description": "Type of page for page 5", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"5"},{"visiblePages":"6"},{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 5 + }, + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page5value1", "label": "Field 1", "type": "boatData", - "default": "COG", + "default": "", "description": "The display for field one", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"OneValue"},{"page5type":"TwoValues"},{"page5type":"ThreeValues"},{"page5type":"FourValues"},{"page5type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "FourValues" + }, + { + "page5type": "FourValues2" + }, + { + "page5type": "OneValue" + }, + { + "page5type": "RollPitch" + }, + { + "page5type": "ThreeValues" + }, + { + "page5type": "TwoValues" + }, + { + "page5type": "WindRoseFlex" + }, + { + "page5type": "Fluid" + } + ] }, { "name": "page5value2", "label": "Field 2", "type": "boatData", - "default": "STW", + "default": "", "description": "The display for field two", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"TwoValues"},{"page5type":"ThreeValues"},{"page5type":"FourValues"},{"page5type":"FourValues2"},{"page4type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "FourValues" + }, + { + "page5type": "FourValues2" + }, + { + "page5type": "RollPitch" + }, + { + "page5type": "ThreeValues" + }, + { + "page5type": "TwoValues" + }, + { + "page5type": "WindRoseFlex" + } + ] }, { "name": "page5value3", "label": "Field 3", "type": "boatData", - "default": "DBT", - "description": "The display for field 3", + "default": "", + "description": "The display for field three", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"ThreeValues"},{"page5type":"FourValues"},{"page5type":"FourValues2"},{"page5type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "FourValues" + }, + { + "page5type": "FourValues2" + }, + { + "page5type": "ThreeValues" + }, + { + "page5type": "WindRoseFlex" + } + ] }, { "name": "page5value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"FourValues"},{"page5type":"FourValues2"},{"page5type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "FourValues" + }, + { + "page5type": "FourValues2" + }, + { + "page5type": "WindRoseFlex" + } + ] }, { "name": "page5value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "WindRoseFlex" + } + ] }, { "name": "page5value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"WindRoseFlex"}] + "condition": [ + { + "page5type": "WindRoseFlex" + } + ] }, { "name": "page5fluid", @@ -1412,20 +2145,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 5", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page5type":"Fluid"}] + "condition": [ + { + "page5type": "Fluid" + } + ] }, { "name": "page6type", @@ -1433,84 +2191,198 @@ "type": "list", "default": "FourValues", "description": "Type of page for page 6", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"6"},{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 6 + }, + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page6value1", "label": "Field 1", "type": "boatData", - "default": "AWA", + "default": "", "description": "The display for field one", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"OneValue"},{"page6type":"TwoValues"},{"page6type":"ThreeValues"},{"page6type":"FourValues"},{"page6type":"FourValues2"},{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "FourValues" + }, + { + "page6type": "FourValues2" + }, + { + "page6type": "OneValue" + }, + { + "page6type": "RollPitch" + }, + { + "page6type": "ThreeValues" + }, + { + "page6type": "TwoValues" + }, + { + "page6type": "WindRoseFlex" + }, + { + "page6type": "Fluid" + } + ] }, { "name": "page6value2", "label": "Field 2", "type": "boatData", - "default": "AWS", + "default": "", "description": "The display for field two", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"TwoValues"},{"page6type":"ThreeValues"},{"page6type":"FourValues"},{"page6type":"FourValues2"},{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "FourValues" + }, + { + "page6type": "FourValues2" + }, + { + "page6type": "RollPitch" + }, + { + "page6type": "ThreeValues" + }, + { + "page6type": "TwoValues" + }, + { + "page6type": "WindRoseFlex" + } + ] }, { "name": "page6value3", "label": "Field 3", "type": "boatData", - "default": "COG", - "description": "The display for field 3", + "default": "", + "description": "The display for field three", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"ThreeValues"},{"page6type":"FourValues"},{"page6type":"FourValues2"},{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "FourValues" + }, + { + "page6type": "FourValues2" + }, + { + "page6type": "ThreeValues" + }, + { + "page6type": "WindRoseFlex" + } + ] }, { "name": "page6value4", "label": "Field 4", "type": "boatData", - "default": "STW", - "description": "The display for field 4", + "default": "", + "description": "The display for field four", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"FourValues"},{"page6type":"FourValues2"},{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "FourValues" + }, + { + "page6type": "FourValues2" + }, + { + "page6type": "WindRoseFlex" + } + ] }, { "name": "page6value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "WindRoseFlex" + } + ] }, { "name": "page6value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"WindRoseFlex"}] + "condition": [ + { + "page6type": "WindRoseFlex" + } + ] }, { "name": "page6fluid", @@ -1518,20 +2390,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 6", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page6type":"Fluid"}] + "condition": [ + { + "page6type": "Fluid" + } + ] }, { "name": "page7type", @@ -1539,84 +2436,195 @@ "type": "list", "default": "FourValues2", "description": "Type of page for page 7", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"7"},{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 7 + }, + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page7value1", "label": "Field 1", "type": "boatData", - "default": "AWA", + "default": "", "description": "The display for field one", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"OneValue"},{"page7type":"TwoValues"},{"page7type":"ThreeValues"},{"page7type":"FourValues"},{"page7type":"FourValues2"},{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "FourValues" + }, + { + "page7type": "FourValues2" + }, + { + "page7type": "OneValue" + }, + { + "page7type": "RollPitch" + }, + { + "page7type": "ThreeValues" + }, + { + "page7type": "TwoValues" + }, + { + "page7type": "WindRoseFlex" + }, + { + "page7type": "Fluid" + } + ] }, { "name": "page7value2", "label": "Field 2", "type": "boatData", - "default": "AWS", + "default": "", "description": "The display for field two", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"TwoValues"},{"page7type":"ThreeValues"},{"page7type":"FourValues"},{"page7type":"FourValues2"},{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "FourValues" + }, + { + "page7type": "FourValues2" + }, + { + "page7type": "RollPitch" + }, + { + "page7type": "ThreeValues" + }, + { + "page7type": "TwoValues" + }, + { + "page7type": "WindRoseFlex" + } + ] }, { "name": "page7value3", "label": "Field 3", "type": "boatData", - "default": "COG", - "description": "The display for field 3", + "default": "", + "description": "The display for field three", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"ThreeValues"},{"page7type":"FourValues"},{"page7type":"FourValues2"},{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "FourValues" + }, + { + "page7type": "FourValues2" + }, + { + "page7type": "ThreeValues" + }, + { + "page7type": "WindRoseFlex" + } + ] }, { "name": "page7value4", "label": "Field 4", "type": "boatData", - "default": "STW", - "description": "The display for field 4", + "default": "", + "description": "The display for field four", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"FourValues"},{"page7type":"FourValues2"},{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "FourValues" + }, + { + "page7type": "FourValues2" + }, + { + "page7type": "WindRoseFlex" + } + ] }, { "name": "page7value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "WindRoseFlex" + } + ] }, { "name": "page7value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"WindRoseFlex"}] + "condition": [ + { + "page7type": "WindRoseFlex" + } + ] }, { "name": "page7fluid", @@ -1624,20 +2632,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 7", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page7type":"Fluid"}] + "condition": [ + { + "page7type": "Fluid" + } + ] }, { "name": "page8type", @@ -1645,24 +2678,82 @@ "type": "list", "default": "Clock", "description": "Type of page for page 8", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"8"},{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 8 + }, + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page8value1", "label": "Field 1", "type": "boatData", - "default": "AWS", + "default": "", "description": "The display for field one", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"OneValue"},{"page8type":"TwoValues"},{"page8type":"ThreeValues"},{"page8type":"FourValues"},{"page8type":"FourValues2"},{"page8type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "FourValues" + }, + { + "page8type": "FourValues2" + }, + { + "page8type": "OneValue" + }, + { + "page8type": "RollPitch" + }, + { + "page8type": "ThreeValues" + }, + { + "page8type": "TwoValues" + }, + { + "page8type": "WindRoseFlex" + }, + { + "page8type": "Fluid" + } + ] }, { "name": "page8value2", @@ -1672,57 +2763,107 @@ "description": "The display for field two", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"TwoValues"},{"page8type":"ThreeValues"},{"page8type":"FourValues"},{"page8type":"FourValues2"},{"page8type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "FourValues" + }, + { + "page8type": "FourValues2" + }, + { + "page8type": "RollPitch" + }, + { + "page8type": "ThreeValues" + }, + { + "page8type": "TwoValues" + }, + { + "page8type": "WindRoseFlex" + } + ] }, { "name": "page8value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"ThreeValues"},{"page8type":"FourValues"},{"page8type":"FourValues2"},{"page8type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "FourValues" + }, + { + "page8type": "FourValues2" + }, + { + "page8type": "ThreeValues" + }, + { + "page8type": "WindRoseFlex" + } + ] }, { "name": "page8value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"FourValues"},{"page8type":"FourValues2"},{"page88type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "FourValues" + }, + { + "page8type": "FourValues2" + }, + { + "page8type": "WindRoseFlex" + } + ] }, { "name": "page8value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "WindRoseFlex" + } + ] }, { "name": "page8value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"WindRoseFlex"}] + "condition": [ + { + "page8type": "WindRoseFlex" + } + ] }, { "name": "page8fluid", @@ -1730,20 +2871,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 8", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page8type":"Fluid"}] + "condition": [ + { + "page8type": "Fluid" + } + ] }, { "name": "page9type", @@ -1751,24 +2917,79 @@ "type": "list", "default": "RollPitch", "description": "Type of page for page 9", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"9"},{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 9 + }, + { + "visiblePages": 10 + } + ] }, { "name": "page9value1", "label": "Field 1", "type": "boatData", - "default": "AWS", + "default": "", "description": "The display for field one", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"OneValue"},{"page9type":"TwoValues"},{"page9type":"ThreeValues"},{"page9type":"FourValues"},{"page9type":"FourValues2"},{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "FourValues" + }, + { + "page9type": "FourValues2" + }, + { + "page9type": "OneValue" + }, + { + "page9type": "RollPitch" + }, + { + "page9type": "ThreeValues" + }, + { + "page9type": "TwoValues" + }, + { + "page9type": "WindRoseFlex" + }, + { + "page9type": "Fluid" + } + ] }, { "name": "page9value2", @@ -1778,57 +2999,107 @@ "description": "The display for field two", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"TwoValues"},{"page9type":"ThreeValues"},{"page9type":"FourValues"},{"page9type":"FourValues2"},{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "FourValues" + }, + { + "page9type": "FourValues2" + }, + { + "page9type": "RollPitch" + }, + { + "page9type": "ThreeValues" + }, + { + "page9type": "TwoValues" + }, + { + "page9type": "WindRoseFlex" + } + ] }, { "name": "page9value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"ThreeValues"},{"page9type":"FourValues"},{"page9type":"FourValues2"},{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "FourValues" + }, + { + "page9type": "FourValues2" + }, + { + "page9type": "ThreeValues" + }, + { + "page9type": "WindRoseFlex" + } + ] }, { "name": "page9value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"FourValues"},{"page9type":"FourValues2"},{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "FourValues" + }, + { + "page9type": "FourValues2" + }, + { + "page9type": "WindRoseFlex" + } + ] }, { "name": "page9value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "WindRoseFlex" + } + ] }, { "name": "page9value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"WindRoseFlex"}] + "condition": [ + { + "page9type": "WindRoseFlex" + } + ] }, { "name": "page9fluid", @@ -1836,20 +3107,45 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 9", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page9type":"Fluid"}] + "condition": [ + { + "page9type": "Fluid" + } + ] }, { "name": "page10type", @@ -1857,24 +3153,76 @@ "type": "list", "default": "Battery2", "description": "Type of page for page 10", - "list":["OneValue","TwoValues","ThreeValues","FourValues","FourValues2","ApparentWind","WindRose","WindRoseFlex","Voltage","DST810","Clock","WhitePage","BME280","RudderPosition","KeelPosition","Battery","Battery2","RollPitch","Solar","Generator","XTETrack","Fluid"], + "list": [ + "BME280", + "Battery", + "Battery2", + "Clock", + "DST810", + "Fluid", + "FourValues", + "FourValues2", + "Generator", + "KeelPosition", + "OneValue", + "RollPitch", + "RudderPosition", + "Solar", + "ThreeValues", + "TwoValues", + "Voltage", + "White", + "Wind", + "WindRose", + "WindRoseFlex", + "XTETrack" + ], "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"visiblePages":"10"}] + "condition": [ + { + "visiblePages": 10 + } + ] }, { "name": "page10value1", "label": "Field 1", "type": "boatData", - "default": "AWS", + "default": "", "description": "The display for field one", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"OneValue"},{"page10type":"TwoValues"},{"page10type":"ThreeValues"},{"page10type":"FourValues"},{"page10type":"FourValues2"},{"page10type":"WindRoseFlex"}] + "condition": [ + { + "page10type": "FourValues" + }, + { + "page10type": "FourValues2" + }, + { + "page10type": "OneValue" + }, + { + "page10type": "RollPitch" + }, + { + "page10type": "ThreeValues" + }, + { + "page10type": "TwoValues" + }, + { + "page10type": "WindRoseFlex" + }, + { + "page10type": "Fluid" + } + ] }, { "name": "page10value2", @@ -1884,57 +3232,107 @@ "description": "The display for field two", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"TwoValues"},{"page10type":"ThreeValues"},{"page10type":"FourValues"},{"page10type":"FourValues2"},{"page10type":"WindRoseFlex"}] + "condition": [ + { + "page10type": "FourValues" + }, + { + "page10type": "FourValues2" + }, + { + "page10type": "RollPitch" + }, + { + "page10type": "ThreeValues" + }, + { + "page10type": "TwoValues" + }, + { + "page10type": "WindRoseFlex" + } + ] }, { "name": "page10value3", "label": "Field 3", "type": "boatData", "default": "", - "description": "The display for field 3", + "description": "The display for field three", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"ThreeValues"},{"page10type":"FourValues"},{"page10type":"FourValues2"},{"page10type":"WindRoseFlex"}] + "condition": [ + { + "page10type": "FourValues" + }, + { + "page10type": "FourValues2" + }, + { + "page10type": "ThreeValues" + }, + { + "page10type": "WindRoseFlex" + } + ] }, { "name": "page10value4", "label": "Field 4", "type": "boatData", "default": "", - "description": "The display for field 4", + "description": "The display for field four", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"FourValues"},{"page10type":"FourValues2"},{"page10type":"WindRoseFlex"}] - }, + "condition": [ + { + "page10type": "FourValues" + }, + { + "page10type": "FourValues2" + }, + { + "page10type": "WindRoseFlex" + } + ] + }, { "name": "page10value5", "label": "Field 5", "type": "boatData", "default": "", - "description": "The display for field 5", + "description": "The display for field five", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"WindRoseFlex"}] + "condition": [ + { + "page10type": "WindRoseFlex" + } + ] }, { "name": "page10value6", "label": "Field 6", "type": "boatData", "default": "", - "description": "The display for field 6", + "description": "The display for field six", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"WindRoseFlex"}] + "condition": [ + { + "page10type": "WindRoseFlex" + } + ] }, { "name": "page10fluid", @@ -1942,19 +3340,44 @@ "type": "list", "default": "0", "list": [ - {"l":"Fuel (0)","v":"0"}, - {"l":"Water (1)","v":"1"}, - {"l":"Gray Water (2)","v":"2"}, - {"l":"Live Well (3)","v":"3"}, - {"l":"Oil (4)","v":"4"}, - {"l":"Black Water (5)","v":"5"}, - {"l":"Fuel Gasoline (6)","v":"6"} + { + "l": "Fuel (0)", + "v": "0" + }, + { + "l": "Water (1)", + "v": "1" + }, + { + "l": "Gray Water (2)", + "v": "2" + }, + { + "l": "Live Well (3)", + "v": "3" + }, + { + "l": "Oil (4)", + "v": "4" + }, + { + "l": "Black Water (5)", + "v": "5" + }, + { + "l": "Fuel Gasoline (6)", + "v": "6" + } ], "description": "Fluid type in tank", "category": "OBP60 Page 10", "capabilities": { - "obp60":"true" + "obp60": "true" }, - "condition":[{"page10type":"Fluid"}] + "condition": [ + { + "page10type": "Fluid" + } + ] } ] diff --git a/lib/obp60task/gen_set.pl b/lib/obp60task/gen_set.pl deleted file mode 100755 index a83bda2..0000000 --- a/lib/obp60task/gen_set.pl +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/perl -w -#A tool to generate that part of config.json that deals with pages and fields. - -#List of all pages and the number of parameters they expect. -%NoOfFieldsPerPage=qw( - ApparentWind 0 - XTETrack 0 - Battery2 0 - Battery 0 - BME280 0 - Clock 0 - DST810 0 - FourValues2 4 - FourValues 4 - Generator 0 - KeelPosition 0 - OneValue 1 - RollPitch 0 - RudderPosition 0 - Solar 0 - ThreeValues 3 - TwoValues 2 - Voltage 0 - White 0 - WindRose 0 - WindRoseFlex 6 - ); -# No changes needed beyond this point -#max number of pages supported by OBP60 -$NoOfPages=10; -#Default selection for each page -@Defaults=qw(Voltage WindRose OneValue TwoValues ThreeValues FourValues FourValues2 Clock RollPitch Battery2); -@Numbers=qw(one two three four five six seven eight nine ten); -@Pages=sort(keys(%NoOfFieldsPerPage)); -$MaxNoOfFieldsPerPage=0; # inital value, gets updated with maximum entry from %NoOfFieldsPerPage - - -#find max. number of fields without additional modules - foreach (values(%NoOfFieldsPerPage)){ - if ($_ > $MaxNoOfFieldsPerPage){ - $MaxNoOfFieldsPerPage=$_; - } - } - -for ($PageNo=1;$PageNo<=$NoOfPages;$PageNo++){ - print "{\n"; - print "\t","\"name\": \"page", $PageNo,"type\",\n"; - print "\t","\"label\": \"Type\",\n"; - print "\t",'"type": "list",',"\n"; - print "\t",'"default": "'; - print "$Defaults[$PageNo-1]"; - print'"',"\n"; - print "\t",'"description": "Type of page for page ',$PageNo,'",',"\n"; - print "\t",'"list": ['; - for ($p=0;$p<=$#Pages;$p++) { - print '"', $Pages[$p], '"' ; - if ($p < $#Pages){print ","} - } - print "]\n"; - print "\t",'"category": "OBP60 Page ',$PageNo,'",',"\n"; - print "\t",'"capabilities": {',"\n"; - print "\t\t",'"obp60":"true"',"\n"; - print "\t",'}',"\n"; - print "\t",'"condition":['; - for ($vp=$PageNo;$vp<=$NoOfPages;$vp++){ - print '"{visiblePages":"',$vp,'"},'; - } - print "\b",']',"\n"; - print '},',"\n"; - for ($FieldNo=1; $FieldNo<=$MaxNoOfFieldsPerPage;$FieldNo++){ - print "{\n"; - print "\t",'"name": "page',$PageNo,'value',$FieldNo,'",',"\n"; - print "\t",'"label": "Field ',$FieldNo,'",',"\n"; - print "\t",'"type": "boatData",',"\n"; - print "\t",'"default": "",',"\n"; - print "\t",'"description": "The display for field ',$Numbers[$FieldNo-1],'",',"\n"; - print "\t",'"category": "OBP60 Page ',$PageNo,'",',"\n"; - print "\t",'"capabilities": {',"\n"; - print "\t",' "obp60":"true"',"\n"; - print "\t",'},',"\n"; - print "\t",'"condition":['; - foreach $page (@Pages) { - if($NoOfFieldsPerPage{$page}>=$FieldNo){ - print '{"page1type":"',$page,'"},'; - } - } - print "\b],\n"; - print '},',"\n"; - } -} diff --git a/lib/obp60task/gen_set.py b/lib/obp60task/gen_set.py new file mode 100755 index 0000000..bf40b6c --- /dev/null +++ b/lib/obp60task/gen_set.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +# A tool to generate that part of config.json that deals with pages and fields. +# +#Usage: 1. modify this script (e.g.add a page, change number of fields, etc.) +# 2. Delete all lines from config.json from the curly backet before "name": "page1type" to o the end of the file (as of today, delete from line 917 to the end of the File) +# 3. run ./gen_set.py >> config.json + +import json + +# List of all pages and the number of parameters they expect. +no_of_fields_per_page = { + "Wind": 0, + "XTETrack": 0, + "Battery2": 0, + "Battery": 0, + "BME280": 0, + "Clock": 0, + "DST810": 0, + "Fluid": 1, + "FourValues2": 4, + "FourValues": 4, + "Generator": 0, + "KeelPosition": 0, + "OneValue": 1, + "RollPitch": 2, + "RudderPosition": 0, + "Solar": 0, + "ThreeValues": 3, + "TwoValues": 2, + "Voltage": 0, + "White": 0, + "WindRose": 0, + "WindRoseFlex": 6, + "SixValues" : 6, +} + +# No changes needed beyond this point +# max number of pages supported by OBP60 +no_of_pages = 10 +# Default selection for each page +default_pages = [ + "Voltage", + "WindRose", + "OneValue", + "TwoValues", + "ThreeValues", + "FourValues", + "FourValues2", + "Clock", + "RollPitch", + "Battery2", +] +numbers = [ + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "ten", +] +pages = sorted(no_of_fields_per_page.keys()) +max_no_of_fields_per_page = max(no_of_fields_per_page.values()) + +output = [] + +for page_no in range(1, no_of_pages + 1): + page_data = { + "name": f"page{page_no}type", + "label": "Type", + "type": "list", + "default": default_pages[page_no - 1], + "description": f"Type of page for page {page_no}", + "list": pages, + "category": f"OBP60 Page {page_no}", + "capabilities": {"obp60": "true"}, + "condition": [{"visiblePages": vp} for vp in range(page_no, no_of_pages + 1)], + #"fields": [], + } + output.append(page_data) + + for field_no in range(1, max_no_of_fields_per_page + 1): + field_data = { + "name": f"page{page_no}value{field_no}", + "label": f"Field {field_no}", + "type": "boatData", + "default": "", + "description": f"The display for field {numbers[field_no - 1]}", + "category": f"OBP60 Page {page_no}", + "capabilities": {"obp60": "true"}, + "condition": [ + {f"page{page_no}type": page} + for page in pages + if no_of_fields_per_page[page] >= field_no + ], + } + output.append(field_data) + + fluid_data ={ + "name": f"page{page_no}fluid", + "label": "Fluid type", + "type": "list", + "default": "0", + "list": [ + {"l":"Fuel (0)","v":"0"}, + {"l":"Water (1)","v":"1"}, + {"l":"Gray Water (2)","v":"2"}, + {"l":"Live Well (3)","v":"3"}, + {"l":"Oil (4)","v":"4"}, + {"l":"Black Water (5)","v":"5"}, + {"l":"Fuel Gasoline (6)","v":"6"} + ], + "description": "Fluid type in tank", + "category": f"OBP60 Page {page_no}", + "capabilities": { + "obp60":"true" + }, + "condition":[{f"page{page_no}type":"Fluid"}] + } + output.append(fluid_data) + +json_output = json.dumps(output, indent=4) +# print omitting first and last line containing [ ] of JSON array +#print(json_output[1:-1]) +# print omitting first line containing [ of JSON array +print(json_output[1:]) +# print(",") \ No newline at end of file diff --git a/lib/obp60task/imglib.cpp b/lib/obp60task/imglib.cpp new file mode 100644 index 0000000..80b795e --- /dev/null +++ b/lib/obp60task/imglib.cpp @@ -0,0 +1,347 @@ +/****************************************************************************** + * Image functions: + * - Convert a 1bit framebuffer in RAM to + * - GIF, compressed, based on giflib and gif_hash + * - PBM, portable bitmap, very simple copy + * - BMP, bigger with a little bit fiddling around + * + * SPDX-License-Identifier: MIT + *****************************************************************************/ + +#include // needed for PROGMEM +#include +#include "GwLog.h" // needed for logger +#include "imglib.h" + +GifFilePrivateType gifprivate; + +void ClearHashTable(GifHashTableType *HashTable) { + memset(HashTable->HTable, 0xFF, HT_SIZE * sizeof(uint32_t)); +} + +GifHashTableType *InitHashTable(void) { + GifHashTableType *HashTable; + if ((HashTable = (GifHashTableType *)ps_malloc(sizeof(GifHashTableType))) == NULL) { + return NULL; + } + ClearHashTable(HashTable); + return HashTable; +} + +static int KeyItem(uint32_t Item) { + return ((Item >> 12) ^ Item) & HT_KEY_MASK; +} + +void InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code) { + int HKey = KeyItem(Key); + uint32_t *HTable = HashTable->HTable; + while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { + HKey = (HKey + 1) & HT_KEY_MASK; + } + HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code); +} + +int ExistsHashTable(GifHashTableType *HashTable, uint32_t Key) { + int HKey = KeyItem(Key); + uint32_t *HTable = HashTable->HTable, HTKey; + while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { + if (Key == HTKey) { + return HT_GET_CODE(HTable[HKey]); + } + HKey = (HKey + 1) & HT_KEY_MASK; + } + return -1; +} + +/****************************************************************************** + Put 2 bytes (a word) into the given file in little-endian order: +******************************************************************************/ +void GifPutWord(std::vector* gifBuffer, uint16_t Word) { + /*cuint8_t c[2]; + [0] = LOBYTE(Word); + c[1] = HIBYTE(Word); + gifBuffer->push_back(c[0]); + gifBuffer->push_back(c[1]); */ + gifBuffer->push_back(LOBYTE(Word)); + gifBuffer->push_back(HIBYTE(Word)); +} + +/****************************************************************************** + This routines buffers the given characters until 255 characters are ready + to be output. If Code is equal to -1 the buffer is flushed (EOF). + The buffer is Dumped with first byte as its size, as GIF format requires. +******************************************************************************/ +void GifBufferedOutput(std::vector* gifBuffer, GifByteType *Buf, int c) { + if (c == FLUSH_OUTPUT) { + // Flush everything out. + for (int i = 0; i < Buf[0] + 1; i++) { + gifBuffer->push_back(Buf[i]); + } + // Mark end of compressed data, by an empty block (see GIF doc): + Buf[0] = 0; + gifBuffer->push_back(0); + } else { + if (Buf[0] == 255) { + // Dump out this buffer - it is full: + for (int i = 0; i < Buf[0] + 1; i++) { + gifBuffer->push_back(Buf[i]); + } + Buf[0] = 0; + } + Buf[++Buf[0]] = c; + } +} + +/****************************************************************************** + The LZ compression output routine: + This routine is responsible for the compression of the bit stream into + 8 bits (bytes) packets. +******************************************************************************/ +void GifCompressOutput(std::vector* gifBuffer, const int Code) { + + if (Code == FLUSH_OUTPUT) { + while (gifprivate.CrntShiftState > 0) { + // Get Rid of what is left in DWord, and flush it. + GifBufferedOutput(gifBuffer, gifprivate.Buf, gifprivate.CrntShiftDWord & 0xff); + gifprivate.CrntShiftDWord >>= 8; + gifprivate.CrntShiftState -= 8; + } + gifprivate.CrntShiftState = 0; // For next time. + GifBufferedOutput(gifBuffer, gifprivate.Buf, FLUSH_OUTPUT); + } else { + gifprivate.CrntShiftDWord |= ((long)Code) << gifprivate.CrntShiftState; + gifprivate.CrntShiftState += gifprivate.RunningBits; + while (gifprivate.CrntShiftState >= 8) { + // Dump out full bytes: + GifBufferedOutput(gifBuffer, gifprivate.Buf, gifprivate.CrntShiftDWord & 0xff); + gifprivate.CrntShiftDWord >>= 8; + gifprivate.CrntShiftState -= 8; + } + } + + /* If code cannt fit into RunningBits bits, must raise its size. Note */ + /* however that codes above LZ_MAX_CODE are used for special signaling. */ + if (gifprivate.RunningCode >= gifprivate.MaxCode1 && Code <= LZ_MAX_CODE) { + gifprivate.MaxCode1 = 1 << ++gifprivate.RunningBits; + } +} + +/****************************************************************************** + Setup the LZ compression for this image: +******************************************************************************/ +void GifSetupCompress(std::vector* gifBuffer) { + gifBuffer->push_back(0x02);// Bits per pixel wit minimum 2 + + gifprivate.Buf[0] = 0; // Nothing was output yet + gifprivate.BitsPerPixel = 2; // Minimum is 2 + gifprivate.ClearCode = (1 << 2); + gifprivate.EOFCode = gifprivate.ClearCode + 1; + gifprivate.RunningCode = gifprivate.EOFCode + 1; + gifprivate.RunningBits = 2 + 1; // Number of bits per code + gifprivate.MaxCode1 = 1 << gifprivate.RunningBits; // Max. code + 1 + gifprivate.CrntCode = FIRST_CODE; // Signal that this is first one! + gifprivate.CrntShiftState = 0; // No information in CrntShiftDWord + gifprivate.CrntShiftDWord = 0; + + GifCompressOutput(gifBuffer, gifprivate.ClearCode); +} + +void createGifHeader(std::vector* gifBuffer, uint16_t width, uint16_t height) { + + // SCREEN DESCRIPTOR + gifBuffer->push_back('G'); + gifBuffer->push_back('I'); + gifBuffer->push_back('F'); + gifBuffer->push_back('8'); + gifBuffer->push_back('7'); + gifBuffer->push_back('a'); + + GifPutWord(gifBuffer, width); + GifPutWord(gifBuffer, height); + + gifBuffer->push_back(0x80 | (1 << 4)); + gifBuffer->push_back(0x00); // Index into the ColorTable for background color + gifBuffer->push_back(0x00); // Pixel Aspect Ratio + + // Colormap + gifBuffer->push_back(0xff); // Color 0 + gifBuffer->push_back(0xff); + gifBuffer->push_back(0xff); + gifBuffer->push_back(0x00); // Color 1 + gifBuffer->push_back(0x00); + gifBuffer->push_back(0x00); + + // IMAGE DESCRIPTOR + gifBuffer->push_back(DESCRIPTOR_INTRODUCER); + + GifPutWord(gifBuffer, 0); + GifPutWord(gifBuffer, 0); + GifPutWord(gifBuffer, width); + GifPutWord(gifBuffer, height); + + gifBuffer->push_back(0x00); // No colormap here , we use the global one +} + +/****************************************************************************** + The LZ compression routine: + This version compresses the given buffer Line of length LineLen. + This routine can be called a few times (one per scan line, for example), in + order to complete the whole image. +******************************************************************************/ +void GifCompressLine(std::vector* gifBuffer, const GifPixelType *Line, const int LineLen) { + int i = 0, CrntCode; + GifHashTableType *HashTable; + + HashTable = gifprivate.HashTable; + + if (gifprivate.CrntCode == FIRST_CODE) { // Its first time! + CrntCode = Line[i++]; + } else { + CrntCode = + gifprivate.CrntCode; // Get last code in compression + } + while (i < LineLen) { // Decode LineLen items + GifPixelType Pixel = Line[i++]; // Get next pixel from stream. + /* Form a new unique key to search hash table for the code + * combines CrntCode as Prefix string with Pixel as postfix + * char. + */ + int NewCode; + unsigned long NewKey = (((uint32_t)CrntCode) << 8) + Pixel; + if ((NewCode = ExistsHashTable(HashTable, NewKey)) >= 0) { + /* This Key is already there, or the string is old one, + * so simple take new code as our CrntCode: + */ + CrntCode = NewCode; + } else { + /* Put it in hash table, output the prefix code, and + * make our CrntCode equal to Pixel. + */ + GifCompressOutput(gifBuffer, CrntCode); + CrntCode = Pixel; + + /* If however the HashTable if full, we send a clear + * first and Clear the hash table. + */ + if (gifprivate.RunningCode >= LZ_MAX_CODE) { + // Time to do some clearance: + GifCompressOutput(gifBuffer, gifprivate.ClearCode); + gifprivate.RunningCode = gifprivate.EOFCode + 1; + gifprivate.RunningBits = gifprivate.BitsPerPixel + 1; + gifprivate.MaxCode1 = 1 << gifprivate.RunningBits; + ClearHashTable(HashTable); + } else { + // Put this unique key with its relative Code in hash table: + InsertHashTable(HashTable, NewKey, gifprivate.RunningCode++); + } + } + } + + // Preserve the current state of the compression algorithm: + gifprivate.CrntCode = CrntCode; + + if (gifprivate.PixelCount == 0) { + // We are done - output last Code and flush output buffers: + GifCompressOutput(gifBuffer, CrntCode); + GifCompressOutput(gifBuffer, gifprivate.EOFCode); + GifCompressOutput(gifBuffer, FLUSH_OUTPUT); + } +} + +bool createBMP(uint8_t *frameBuffer, std::vector* imageBuffer, uint16_t width, uint16_t height) { + // For BMP the line size has to be a multiple of 4 bytes. + // So padding is needed. Also the lines have to be in reverded + // order compared to plain buffer + + // BMP header for black-and-white image (1 bit per pixel) + const uint8_t bmp_header[] PROGMEM = { + // BITMAPFILEHEADER (14 Bytes) + 0x42, 0x4D, // bfType: 'BM' signature + 0x2e, 0x3d, 0x00, 0x00, // bfSize: file size in bytes + 0x00, 0x00, // bfReserved1 + 0x00, 0x00, // bfReserved2 + 0x3e, 0x00, 0x00, 0x00, // bfOffBits: offset in bytes to pixeldata + // BITMAPINFOHEADER (40 Bytes) + 0x28, 0x00, 0x00, 0x00, // biSize: DIB header size + (uint8_t)LOBYTE(width), (uint8_t)HIBYTE(width), 0x00, 0x00, // biWidth + (uint8_t)LOBYTE(height), (uint8_t)HIBYTE(height), 0x00, 0x00, // biHeight + 0x01, 0x00, // biPlanes: Number of color planes (1) + 0x01, 0x00, // biBitCount: Color depth (1 bit per pixel) + 0x00, 0x00, 0x00, 0x00, // biCompression: Compression (none) + 0xf0, 0x3c, 0x00, 0x00, // biSizeImage: Image data size (calculate) + 0x13, 0x0b, 0x00, 0x00, // biXPelsPerMeter: Horizontal resolution (2835 pixels/meter) + 0x13, 0x0b, 0x00, 0x00, // biYPelsPerMeter: Vertical resolution (2835 pixels/meter) + 0x02, 0x00, 0x00, 0x00, // biClrUsed: Colors in color palette (2) + 0x00, 0x00, 0x00, 0x00, // biClrImportant: Important colors (all) + // PALETTE: COLORTRIPLES of RGBQUAD (n * 4 Bytes) + 0x00, 0x00, 0x00, 0x00, // Color palette: Black + 0xff, 0xff, 0xff, 0x00 // Color palette: White + }; + size_t bmp_headerSize = sizeof(bmp_header); + + size_t lineSize = (width / 8); + size_t paddingSize = 0; + if (lineSize % 4 != 0) { + paddingSize = 4 - lineSize % 4; + } + size_t imageSize = bmp_headerSize + (lineSize + paddingSize) * height; + + imageBuffer->resize(imageSize); + memcpy(imageBuffer->data(), bmp_header, bmp_headerSize); + for (int y = 0; y < height; y++) { + uint8_t* srcRow = frameBuffer + (y * lineSize); + uint8_t* destRow = imageBuffer->data() + bmp_headerSize + ((height - 1 - y) * (lineSize + paddingSize)); + memcpy(destRow, srcRow, lineSize); + for (int j = 0; j < paddingSize; j++) { + destRow[lineSize + j] = 0x00; + } + } + return true; +} + +bool createPBM(uint8_t *frameBuffer, std::vector* imageBuffer, uint16_t width, uint16_t height) { + // creates binary PBM image inside imagebuffer + // returns bytesize of created image + const char pbm_header[] PROGMEM = "P4\n#Created by OBP60\n400 300\n"; + size_t pbm_headerSize = sizeof(pbm_header) - 1; // We don't want trailing zero + size_t imageSize = pbm_headerSize + width / 8 * height; + imageBuffer->resize(imageSize); + memcpy(imageBuffer->data(), pbm_header, pbm_headerSize); + memcpy(imageBuffer->data() + pbm_headerSize, frameBuffer, width / 8 * height); + return true; +} + +bool createGIF(uint8_t *framebuffer, std::vector* gifBuffer, uint16_t width, uint16_t height) { + + size_t imageSize = 0; + uint16_t bufOffset = 0; // Offset into imageBuffer for next write access + + gifprivate.HashTable = InitHashTable(); + if (gifprivate.HashTable == NULL) { + return false; + } + gifprivate.PixelCount = width * height; + + createGifHeader(gifBuffer, width, height); + + // Reset compress algorithm parameters. + GifSetupCompress(gifBuffer); + + gifBuffer->reserve(4096); // to avoid lots of alloactions + GifPixelType line[width]; + for (int y = 0; y < height; y++) { + // convert uint8_t pixels to single pixels + for (int x = 0; x < width; x++) { + int byteIndex = (y * width + x) / 8; + uint8_t bitIndex = 7 - ((y * width + x) % 8); + line[x] = (framebuffer[byteIndex] & (uint8_t)(1 << bitIndex)) == 0; + } + gifprivate.PixelCount -= width; + GifCompressLine(gifBuffer, line, width); + } + + gifBuffer->push_back(TERMINATOR_INTRODUCER); + free((GifHashTableType *)gifprivate.HashTable); + + return true; +} diff --git a/lib/obp60task/imglib.h b/lib/obp60task/imglib.h new file mode 100644 index 0000000..1299a7b --- /dev/null +++ b/lib/obp60task/imglib.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * imglib.h + * + * SPDX-License-Identifier: MIT + *****************************************************************************/ + +#ifndef _IMGLIB_H_ +#define _IMGLIB_H_ 1 + +// extract bytes from an unsigned word +#define LOBYTE(x) ((x)&0xff) +#define HIBYTE(x) (((x) >> 8) & 0xff) + +// GIF encoding constants +#define DESCRIPTOR_INTRODUCER 0x2c +#define TERMINATOR_INTRODUCER 0x3b + +#define LZ_MAX_CODE 4095 // Biggest code possible in 12 bits +#define LZ_BITS 12 + +#define FLUSH_OUTPUT 4096 // Impossible code, to signal flush +#define FIRST_CODE 4097 // Impossible code, to signal first +#define NO_SUCH_CODE 4098 // Impossible code, to signal empty + +// magfic constants and declarations for GIF LZW + +#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ +#define HT_KEY_MASK 0x1FFF /* 13bits keys */ +#define HT_KEY_NUM_BITS 13 /* 13bits keys */ +#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ +#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ + +/* The 32 bits of the long are divided into two parts for the key & code: */ +/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ +/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ +/* The key is the upper 20 bits. The code is the lower 12. */ +#define HT_GET_KEY(l) (l >> 12) +#define HT_GET_CODE(l) (l & 0x0FFF) +#define HT_PUT_KEY(l) (l << 12) +#define HT_PUT_CODE(l) (l & 0x0FFF) + +typedef unsigned char GifPixelType; +typedef unsigned char GifByteType; + +typedef struct GifHashTableType { + uint32_t HTable[HT_SIZE]; +} GifHashTableType; + +typedef struct GifFilePrivateType { + uint8_t BitsPerPixel; // Bits per pixel (Codes uses at least this + 1) + uint16_t ClearCode; // The CLEAR LZ code + uint16_t EOFCode; // The EOF LZ code + uint16_t RunningCode; // The next code algorithm can generate + uint16_t RunningBits; // The number of bits required to represent RunningCode + uint16_t MaxCode1; // 1 bigger than max. possible code, in RunningBits bits + uint16_t LastCode; // The code before the current code. + uint16_t CrntCode; // Current algorithm code + uint16_t CrntShiftState; // Number of bits in CrntShiftDWord + uint32_t CrntShiftDWord; // For bytes decomposition into codes + uint32_t PixelCount; // Number of pixels in image + GifByteType Buf[256]; // Compressed input is buffered here + GifHashTableType *HashTable; +} GifFilePrivateType; + +bool createGIF(uint8_t *framebuffer, std::vector* imageBuffer, uint16_t width, uint16_t height); +bool createBMP(uint8_t *framebuffer, std::vector* imageBuffer, uint16_t width, uint16_t height); +bool createPBM(uint8_t *framebuffer, std::vector* gifBuffer, uint16_t width, uint16_t height); + +#endif /* _IMGLIB_H */ diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 2e7ae83..3e2bd69 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -43,16 +43,26 @@ void OBP60Init(GwApi *api){ // Init hardware - hardwareInit(); + hardwareInit(api); // Init power rail 5.0V String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString(); api->getLogger()->logDebug(GwLog::DEBUG,"Power Mode is: %s", powermode.c_str()); if(powermode == "Max Power" || powermode == "Only 5.0V"){ + #ifdef HARDWARE_V21 setPortPin(OBP_POWER_50, true); // Power on 5.0V rail + #endif + #ifdef HARDWARE_LIGHT + setPortPin(OBP_POWER_EPD, true);// Power on ePaper display + #endif } else{ + #ifdef HARDWARE_V21 setPortPin(OBP_POWER_50, false); // Power off 5.0V rail + #endif + #ifdef HARDWARE_LIGHT + setPortPin(OBP_POWER_EPD, false);// Power off ePaper display + #endif } // Settings for e-paper display @@ -76,10 +86,10 @@ void OBP60Init(GwApi *api){ if(String(backlightMode) == "On"){ setBacklightLED(brightness, colorMapping(backlightColor)); } - if(String(backlightMode) == "Off"){ + else if(String(backlightMode) == "Off"){ setBacklightLED(0, COLOR_BLACK); // Backlight LEDs off (blue without britghness) } - if(String(backlightMode) == "Control by Key"){ + else if(String(backlightMode) == "Control by Key"){ setBacklightLED(0, COLOR_BLUE); // Backlight LEDs off (blue without britghness) } @@ -183,13 +193,6 @@ class PageList{ } }; -class PageStruct{ - public: - Page *page=NULL; - PageData parameters; - PageDescription *description=NULL; -}; - /** * this function will add all the pages we know to the pagelist * each page should have defined a registerXXXPage variable of type @@ -214,8 +217,8 @@ void registerAllPages(PageList &list){ list.add(®isterPageFourValues); extern PageDescription registerPageFourValues2; list.add(®isterPageFourValues2); - extern PageDescription registerPageApparentWind; - list.add(®isterPageApparentWind); + extern PageDescription registerPageWind; + list.add(®isterPageWind); extern PageDescription registerPageWindRose; list.add(®isterPageWindRose); extern PageDescription registerPageWindRoseFlex; @@ -251,15 +254,11 @@ void registerAllPages(PageList &list){ } // Undervoltage detection for shutdown display -void underVoltageDetection(GwApi *api){ - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; +void underVoltageDetection(GwApi *api, CommonData &common){ // Read settings - String displaycolor = api->getConfig()->getConfigItem(api->getConfig()->displaycolor,true)->asString(); float vslope = uint(api->getConfig()->getConfigItem(api->getConfig()->vSlope,true)->asFloat()); float voffset = uint(api->getConfig()->getConfigItem(api->getConfig()->vOffset,true)->asFloat()); - // Read supplay voltage + // Read supply voltage float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // V = 1/20 * Vin actVoltage = actVoltage * vslope + voffset; if(actVoltage < MIN_VOLTAGE){ @@ -269,17 +268,9 @@ void underVoltageDetection(GwApi *api){ buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off // Shutdown EInk display - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - getdisplay().fillScreen(bgcolor); // Clear screen - getdisplay().setTextColor(textcolor); + getdisplay().fillScreen(common.bgcolor); // Clear screen + getdisplay().setTextColor(common.fgcolor); getdisplay().setFont(&Ubuntu_Bold20pt7b); getdisplay().setCursor(65, 150); getdisplay().print("Undervoltage"); @@ -302,6 +293,12 @@ void OBP60Task(GwApi *api){ startLedTask(api); PageList allPages; registerAllPages(allPages); + CommonData commonData; + commonData.logger=logger; + commonData.config=config; + + // Keyboard coordinates for page footer + initKeys(commonData); tN2kMsg N2kMsg; @@ -309,18 +306,23 @@ void OBP60Task(GwApi *api){ for (auto it=allPages.pages.begin();it != allPages.pages.end();it++){ LOG_DEBUG(GwLog::LOG,"found registered page %s",(*it)->pageName.c_str()); } - + // Init E-Ink display String displaymode = api->getConfig()->getConfigItem(api->getConfig()->display,true)->asString(); String displaycolor = api->getConfig()->getConfigItem(api->getConfig()->displaycolor,true)->asString(); + if (displaycolor == "Normal") { + commonData.fgcolor = GxEPD_BLACK; + commonData.bgcolor = GxEPD_WHITE; + } + else{ + commonData.fgcolor = GxEPD_WHITE; + commonData.bgcolor = GxEPD_BLACK; + } String systemname = api->getConfig()->getConfigItem(api->getConfig()->systemName,true)->asString(); String wifipass = api->getConfig()->getConfigItem(api->getConfig()->apPassword,true)->asString(); bool refreshmode = api->getConfig()->getConfigItem(api->getConfig()->refresh,true)->asBoolean(); String fastrefresh = api->getConfig()->getConfigItem(api->getConfig()->fastRefresh,true)->asString(); uint fullrefreshtime = uint(api->getConfig()->getConfigItem(api->getConfig()->fullRefreshTime,true)->asInt()); - int textcolor = GxEPD_BLACK; - int pixelcolor = GxEPD_BLACK; - int bgcolor = GxEPD_WHITE; #ifdef DISPLAY_GDEY042T81 getdisplay().init(115200, true, 2, false); // Use this for Waveshare boards with "clever" reset circuit, 2ms reset pulse @@ -329,39 +331,29 @@ void OBP60Task(GwApi *api){ #endif getdisplay().setRotation(0); // Set display orientation (horizontal) - if(displaycolor == "Normal"){ - textcolor = GxEPD_BLACK; - pixelcolor = GxEPD_BLACK; - bgcolor = GxEPD_WHITE; - } - else{ - textcolor = GxEPD_WHITE; - pixelcolor = GxEPD_WHITE; - bgcolor = GxEPD_BLACK; - } getdisplay().setFullWindow(); // Set full Refresh getdisplay().firstPage(); // set first page - getdisplay().fillScreen(bgcolor); // Draw white sreen - getdisplay().setTextColor(textcolor); // Set display color + getdisplay().fillScreen(commonData.bgcolor); + getdisplay().setTextColor(commonData.fgcolor); getdisplay().nextPage(); // Full Refresh getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update - getdisplay().fillScreen(bgcolor); // Draw white sreen + getdisplay().fillScreen(commonData.bgcolor); getdisplay().nextPage(); // Fast Refresh getdisplay().nextPage(); // Fast Refresh if(String(displaymode) == "Logo + QR Code" || String(displaymode) == "Logo"){ - getdisplay().fillScreen(bgcolor); // Draw white sreen - getdisplay().drawBitmap(0, 0, gImage_Logo_OBP_400x300_sw, getdisplay().width(), getdisplay().height(), pixelcolor); // Draw start logo + getdisplay().fillScreen(commonData.bgcolor); + getdisplay().drawBitmap(0, 0, gImage_Logo_OBP_400x300_sw, getdisplay().width(), getdisplay().height(), commonData.fgcolor); // Draw start logo getdisplay().nextPage(); // Fast Refresh getdisplay().nextPage(); // Fast Refresh delay(SHOW_TIME); // Logo show time if(String(displaymode) == "Logo + QR Code"){ - getdisplay().fillScreen(bgcolor); // Draw white sreen - qrWiFi(systemname, wifipass, displaycolor); // Show QR code for WiFi connection + getdisplay().fillScreen(commonData.bgcolor); + qrWiFi(systemname, wifipass, commonData.fgcolor, commonData.bgcolor); // Show QR code for WiFi connection getdisplay().nextPage(); // Fast Refresh getdisplay().nextPage(); // Fast Refresh delay(SHOW_TIME); // QR code show time } - getdisplay().fillScreen(bgcolor); // Draw white sreen + getdisplay().fillScreen(commonData.bgcolor); getdisplay().nextPage(); // Fast Refresh getdisplay().nextPage(); // Fast Refresh } @@ -369,9 +361,10 @@ void OBP60Task(GwApi *api){ // Init pages int numPages=1; PageStruct pages[MAX_PAGE_NUMBER]; - CommonData commonData; - commonData.logger=logger; - commonData.config=config; + // Set start page + int pageNumber = int(api->getConfig()->getConfigItem(api->getConfig()->startPage,true)->asInt()) - 1; + int lastPage=pageNumber; + BoatValueList boatValues; //all the boat values for the api query //commonData.distanceformat=config->getString(xxx); //add all necessary data to common data @@ -395,6 +388,7 @@ void OBP60Task(GwApi *api){ pages[i].description=description; pages[i].page=description->creator(commonData); pages[i].parameters.pageName=pageType; + pages[i].parameters.pageNumber = i + 1; LOG_DEBUG(GwLog::DEBUG,"found page %s for number %d",pageType.c_str(),i); //fill in all the user defined parameters for (int uid=0;uiduserParam;uid++){ @@ -414,6 +408,13 @@ void OBP60Task(GwApi *api){ pages[i].parameters.values.push_back(value); } } + + // Display screenshot handler for HTTP request + // http://192.168.15.1/api/user/OBP60Task/screenshot + api->registerRequestHandler("screenshot", [api, &pageNumber, pages](AsyncWebServerRequest *request) { + doImageRequest(api, &pageNumber, pages, request); + }); + //now we have prepared the page data //we start a separate task that will fetch our keys... MyData allParameters; @@ -430,21 +431,18 @@ void OBP60Task(GwApi *api){ // Configuration values for main loop String gpsFix = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString(); - String backlight = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString(); String gpsOn=api->getConfig()->getConfigItem(api->getConfig()->useGPS,true)->asString(); String tz = api->getConfig()->getConfigItem(api->getConfig()->timeZone,true)->asString(); - String backlightColor = api->getConfig()->getConfigItem(api->getConfig()->blColor,true)->asString(); - Color color = colorMapping(backlightColor); - uint brightness = 2.55 * uint(api->getConfig()->getConfigItem(api->getConfig()->blBrightness,true)->asInt()); + + commonData.backlight.mode = backlightMapping(config->getConfigItem(config->backlight,true)->asString()); + commonData.backlight.color = colorMapping(config->getConfigItem(config->blColor,true)->asString()); + commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness,true)->asInt()); + bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean(); String cpuspeed = api->getConfig()->getConfigItem(api->getConfig()->cpuSpeed,true)->asString(); uint hdopAccuracy = uint(api->getConfig()->getConfigItem(api->getConfig()->hdopAccuracy,true)->asInt()); // refreshmode defined in init section - // displaycolor defined in init section - // textcolor defined in init section - // pixelcolor defined in init section - // bgcolor defined in init section // Boat values for main loop GwApi::BoatValue *date = boatValues.findValueOrCreate("GPSD"); // Load GpsDate @@ -454,9 +452,6 @@ void OBP60Task(GwApi *api){ GwApi::BoatValue *hdop = boatValues.findValueOrCreate("HDOP"); // Load GpsHDOP LOG_DEBUG(GwLog::LOG,"obp60task: start mainloop"); - // Set start page - int pageNumber = int(api->getConfig()->getConfigItem(api->getConfig()->startPage,true)->asInt()) - 1; - int lastPage=pageNumber; commonData.time = boatValues.findValueOrCreate("GPST"); // Load GpsTime commonData.date = boatValues.findValueOrCreate("GPSD"); // Load GpsTime @@ -469,7 +464,9 @@ void OBP60Task(GwApi *api){ long starttime3 = millis(); // Display update all 1s long starttime4 = millis(); // Delayed display update after 4s when select a new page long starttime5 = millis(); // Calculate sunrise and sunset all 1s - + + pages[pageNumber].page->setupKeys(); // Initialize keys for first page + // Main loop runs with 100ms //#################################################################################### @@ -479,7 +476,7 @@ void OBP60Task(GwApi *api){ // Undervoltage detection if(uvoltage == true){ - underVoltageDetection(api); + underVoltageDetection(api, commonData); } // Set CPU speed after boot after 1min @@ -536,14 +533,15 @@ void OBP60Task(GwApi *api){ { // Decoding all key codes // #6 Backlight on if key controled - if(String(backlight) == "Control by Key"){ + if (commonData.backlight.mode == BacklightMode::KEY) { + // if(String(backlight) == "Control by Key"){ if(keyboardMessage == 6){ LOG_DEBUG(GwLog::LOG,"Toggle Backlight LED"); - toggleBacklightLED(brightness, color); + toggleBacklightLED(commonData.backlight.brightness, commonData.backlight.color); } } - // #9 Swipe right - if (keyboardMessage == 9) + // #9 Swipe right or #4 key right + if ((keyboardMessage == 9) or (keyboardMessage == 4)) { pageNumber++; if (pageNumber >= numPages){ @@ -552,8 +550,8 @@ void OBP60Task(GwApi *api){ commonData.data.actpage = pageNumber + 1; commonData.data.maxpage = numPages; } - // #10 Swipe left - if (keyboardMessage == 10) + // #10 Swipe left or #3 key left + if ((keyboardMessage == 10) or (keyboardMessage == 3)) { pageNumber--; if (pageNumber < 0){ @@ -580,9 +578,10 @@ void OBP60Task(GwApi *api){ // Provide sundata to all pages commonData.sundata = calcSunsetSunrise(api, time->value , date->value, lat->value, lon->value, tz.toDouble()); // Backlight with sun control - if(String(backlight) == "Control by Sun"){ + if (commonData.backlight.mode == BacklightMode::SUN) { + // if(String(backlight) == "Control by Sun"){ if(commonData.sundata.sunDown == true){ - setBacklightLED(brightness, color); + setBacklightLED(commonData.backlight.brightness, commonData.backlight.color); } else{ setBacklightLED(0, COLOR_BLUE); // Backlight LEDs off (blue without britghness) @@ -599,10 +598,10 @@ void OBP60Task(GwApi *api){ getdisplay().setFullWindow(); // Set full update getdisplay().nextPage(); if(fastrefresh == "false"){ - getdisplay().fillScreen(pixelcolor);// Clear display - getdisplay().nextPage(); // Full update - getdisplay().fillScreen(bgcolor); // Clear display - getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.fgcolor); // Clear display + getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.bgcolor); // Clear display + getdisplay().nextPage(); // Full update } delayedDisplayUpdate = false; } @@ -616,10 +615,10 @@ void OBP60Task(GwApi *api){ getdisplay().setFullWindow(); // Set full update getdisplay().nextPage(); if(fastrefresh == "false"){ - getdisplay().fillScreen(pixelcolor);// Clear display - getdisplay().nextPage(); // Full update - getdisplay().fillScreen(bgcolor); // Clear display - getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.fgcolor); // Clear display + getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.bgcolor); // Clear display + getdisplay().nextPage(); // Full update } } @@ -630,10 +629,10 @@ void OBP60Task(GwApi *api){ getdisplay().setFullWindow(); // Set full update getdisplay().nextPage(); if(fastrefresh == "false"){ - getdisplay().fillScreen(pixelcolor);// Clear display - getdisplay().nextPage(); // Full update - getdisplay().fillScreen(bgcolor); // Clear display - getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.fgcolor); // Clear display + getdisplay().nextPage(); // Full update + getdisplay().fillScreen(commonData.bgcolor); // Clear display + getdisplay().nextPage(); // Full update } } @@ -645,13 +644,13 @@ void OBP60Task(GwApi *api){ api->getStatus(commonData.status); // Show header if enabled - getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), bgcolor); // Clear display + getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor); // Clear display if (pages[pageNumber].description && pages[pageNumber].description->header){ - //build some header and footer using commonData - getdisplay().fillScreen(bgcolor); // Clear display - displayHeader(commonData, date, time, hdop); // Sown header + // build header using commonData + getdisplay().fillScreen(commonData.bgcolor); // Clear display + displayHeader(commonData, date, time, hdop); // Show page header } - + // Call the particular page Page *currentPage; if (systemPage) { @@ -667,13 +666,20 @@ void OBP60Task(GwApi *api){ } else{ if (lastPage != pageNumber){ - currentPage->displayNew(commonData,pages[pageNumber].parameters); + if (hasFRAM) fram.write(FRAM_PAGE_NO, pageNumber); // remember page for device restart + currentPage->setupKeys(); + currentPage->displayNew(pages[pageNumber].parameters); lastPage=pageNumber; } //call the page code LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber); - currentPage->displayPage(commonData,pages[pageNumber].parameters); + // Show footer if enabled (together with header) + if (pages[pageNumber].description && pages[pageNumber].description->header){ + displayFooter(commonData); + } + currentPage->displayPage(pages[pageNumber].parameters); } + } } } diff --git a/lib/obp60task/obp60task.h b/lib/obp60task/obp60task.h index aecada9..97bd73a 100644 --- a/lib/obp60task/obp60task.h +++ b/lib/obp60task/obp60task.h @@ -3,15 +3,28 @@ //we only compile for some boards #ifdef BOARD_OBP60S3 #define USBSerial Serial - // CAN NMEA2000 - #define ESP32_CAN_TX_PIN 46 - #define ESP32_CAN_RX_PIN 3 - // Bus load in 50mA steps - #define N2K_LOAD_LEVEL 5 // 5x50mA = 250mA max bus load with back light on - // RS485 NMEA0183 - #define GWSERIAL_TX 17 - #define GWSERIAL_RX 8 - #define GWSERIAL_MODE "UNI" + #ifdef HARDWARE_V21 + // CAN NMEA2000 + #define ESP32_CAN_TX_PIN 46 + #define ESP32_CAN_RX_PIN 3 + // Bus load in 50mA steps + #define N2K_LOAD_LEVEL 5 // 5x50mA = 250mA max bus load with back light on + // RS485 NMEA0183 + #define GWSERIAL_TX 17 + #define GWSERIAL_RX 8 + #define GWSERIAL_MODE "UNI" + #endif + #ifdef HARDWARE_LIGHT + // CAN NMEA2000 + #define ESP32_CAN_TX_PIN 15 + #define ESP32_CAN_RX_PIN 16 + // Bus load in 50mA steps + #define N2K_LOAD_LEVEL 2 // 5x50mA = 100mA max bus load with back light on + // RS485 NMEA0183 + #define GWSERIAL_TX 9 + #define GWSERIAL_RX 14 + #define GWSERIAL_MODE "UNI" + #endif // Allowed to set a new password for access point #define FORCE_AP_PWCHANGE diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index dc919a9..4010a82 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -10,6 +10,7 @@ board_build.variants_dir = variants #board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series #board = obp60_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series +#board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone #board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash framework = arduino @@ -23,8 +24,9 @@ lib_deps = blemasle/MCP23017@2.0.0 adafruit/Adafruit BusIO@1.5.0 adafruit/Adafruit GFX Library@1.11.9 - zinggjm/GxEPD2@1.5.8 + #zinggjm/GxEPD2@1.5.8 #https://github.com/ZinggJM/GxEPD2 + https://github.com/thooge/GxEPD2 sstaub/Ticker@4.4.0 adafruit/Adafruit BMP280 Library@2.6.2 adafruit/Adafruit BME280 Library@2.2.2 @@ -34,6 +36,7 @@ lib_deps = paulstoffregen/OneWire@2.3.8 milesburton/DallasTemperature@3.11.0 signetica/SunRise@2.0.2 + adafruit/Adafruit FRAM I2C@^2.0.3 build_flags= #https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL # -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device) @@ -42,15 +45,17 @@ build_flags= # -D TIME=$UNIX_TIME #Set PC time for RTC (only settable via VSC) -D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib -D BOARD_OBP60S3 #Board OBP60 V2.1 with ESP32S3 -# -D HARDWARE_V20 #Hardware revision V2.0 - -D HARDWARE_V21 #Hardware revision V2.1 +# -D HARDWARE_V20 #OBP60 hardware revision V2.0 + -D HARDWARE_V21 #OBP60 hardware revision V2.1 +# -D HARDWARE_LIGHT #OBP60 hardware clone # -D DISPLAY_GDEW042T2 #old E-Ink display from Waveshare, R10 0.47 ohm -D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm # -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm # -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm ${env.build_flags} #CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default -upload_port = /dev/ttyACM0 +upload_port = /dev/ttyACM0 #OBP60 original +#upload_port = /dev/ttyUSB0 #OBP60 clone upload_protocol = esptool #firmware upload via USB OTG seriell, by first upload need to set the ESP32-S3 in the upload mode with shortcut GND to Pin27 upload_speed = 230400 monitor_speed = 115200 diff --git a/lib/obp60task/platformio.ini.light b/lib/obp60task/platformio.ini.light new file mode 100644 index 0000000..6d6ae65 --- /dev/null +++ b/lib/obp60task/platformio.ini.light @@ -0,0 +1,61 @@ +[platformio] +#if you want a pio run to only build +#your special environments you can set this here +#by uncommenting the next line +default_envs = obp60_s3 +[env:obp60_s3] +platform = espressif32@6.8.1 +board_build.variants_dir = variants +#board = obp60_s3_n8 #ESP32-S3 N8, 8MB flash, no PSRAM +#board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series +#board = obp60_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM +#board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series +board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone +board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash +#board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash +framework = arduino +lib_deps = + ${basedeps.lib_deps} + Wire + SPI + esphome/AsyncTCP-esphome@2.0.1 + robtillaart/PCF8574@0.3.9 + adafruit/Adafruit Unified Sensor @ 1.1.13 + blemasle/MCP23017@2.0.0 + adafruit/Adafruit BusIO@1.5.0 + adafruit/Adafruit GFX Library@1.11.9 + #zinggjm/GxEPD2@1.5.8 + #https://github.com/ZinggJM/GxEPD2 + https://github.com/thooge/GxEPD2 + sstaub/Ticker@4.4.0 + adafruit/Adafruit BMP280 Library@2.6.2 + adafruit/Adafruit BME280 Library@2.2.2 + adafruit/Adafruit BMP085 Library@1.2.1 + enjoyneering/HTU21D@1.2.1 + robtillaart/INA226@0.2.0 + paulstoffregen/OneWire@2.3.8 + milesburton/DallasTemperature@3.11.0 + signetica/SunRise@2.0.2 + adafruit/Adafruit FRAM I2C@^2.0.3 +build_flags= + #https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL +# -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device) + -D ARDUINO_USB_CDC_ON_BOOT=0 #Serial output via RX/TX +# -D CORE_DEBUG_LEVEL=1 #Debug level for CPU core via CDC (seral device) +# -D TIME=$UNIX_TIME #Set PC time for RTC (only settable via VSC) + -D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib + -D BOARD_OBP60S3 #Board OBP60 V2.1 with ESP32S3 +# -D HARDWARE_V20 #OBP60 hardware revision V2.0 +# -D HARDWARE_V21 #OBP60 hardware revision V2.1 + -D HARDWARE_LIGHT #OBP60 hardware clone +# -D DISPLAY_GDEW042T2 #old E-Ink display from Waveshare, R10 0.47 ohm + -D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm +# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm +# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm + ${env.build_flags} +#CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default +#upload_port = /dev/ttyACM0 #OBP60 original +upload_port = /dev/ttyUSB0 #OBP60 clone +upload_protocol = esptool #firmware upload via USB OTG seriell, by first upload need to set the ESP32-S3 in the upload mode with shortcut GND to Pin27 +upload_speed = 230400 +monitor_speed = 115200 diff --git a/lib/obp60task/platformio.ini.orig b/lib/obp60task/platformio.ini.orig new file mode 100644 index 0000000..4010a82 --- /dev/null +++ b/lib/obp60task/platformio.ini.orig @@ -0,0 +1,61 @@ +[platformio] +#if you want a pio run to only build +#your special environments you can set this here +#by uncommenting the next line +default_envs = obp60_s3 +[env:obp60_s3] +platform = espressif32@6.8.1 +board_build.variants_dir = variants +#board = obp60_s3_n8 #ESP32-S3 N8, 8MB flash, no PSRAM +#board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series +#board = obp60_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM +board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series +#board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone +#board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash +board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash +framework = arduino +lib_deps = + ${basedeps.lib_deps} + Wire + SPI + esphome/AsyncTCP-esphome@2.0.1 + robtillaart/PCF8574@0.3.9 + adafruit/Adafruit Unified Sensor @ 1.1.13 + blemasle/MCP23017@2.0.0 + adafruit/Adafruit BusIO@1.5.0 + adafruit/Adafruit GFX Library@1.11.9 + #zinggjm/GxEPD2@1.5.8 + #https://github.com/ZinggJM/GxEPD2 + https://github.com/thooge/GxEPD2 + sstaub/Ticker@4.4.0 + adafruit/Adafruit BMP280 Library@2.6.2 + adafruit/Adafruit BME280 Library@2.2.2 + adafruit/Adafruit BMP085 Library@1.2.1 + enjoyneering/HTU21D@1.2.1 + robtillaart/INA226@0.2.0 + paulstoffregen/OneWire@2.3.8 + milesburton/DallasTemperature@3.11.0 + signetica/SunRise@2.0.2 + adafruit/Adafruit FRAM I2C@^2.0.3 +build_flags= + #https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL +# -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device) +# -D ARDUINO_USB_CDC_ON_BOOT=1 #0=JTAG, 1=CDC (serial device) +# -D CORE_DEBUG_LEVEL=1 #Debug level for CPU core via CDC (seral device) +# -D TIME=$UNIX_TIME #Set PC time for RTC (only settable via VSC) + -D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib + -D BOARD_OBP60S3 #Board OBP60 V2.1 with ESP32S3 +# -D HARDWARE_V20 #OBP60 hardware revision V2.0 + -D HARDWARE_V21 #OBP60 hardware revision V2.1 +# -D HARDWARE_LIGHT #OBP60 hardware clone +# -D DISPLAY_GDEW042T2 #old E-Ink display from Waveshare, R10 0.47 ohm + -D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm +# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm +# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm + ${env.build_flags} +#CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default +upload_port = /dev/ttyACM0 #OBP60 original +#upload_port = /dev/ttyUSB0 #OBP60 clone +upload_protocol = esptool #firmware upload via USB OTG seriell, by first upload need to set the ESP32-S3 in the upload mode with shortcut GND to Pin27 +upload_speed = 230400 +monitor_speed = 115200 diff --git a/variants/obp60s3_light/pins_arduino.h b/variants/obp60s3_light/pins_arduino.h new file mode 100644 index 0000000..3e1fdeb --- /dev/null +++ b/variants/obp60s3_light/pins_arduino.h @@ -0,0 +1,74 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include "soc/soc_caps.h" + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +/* +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +// Multi Function Display OBP60 V2.0 +static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT+48; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN +#define RGB_BUILTIN LED_BUILTIN +#define RGB_BRIGHTNESS 64 + +#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<48)?(p):-1) +#define digitalPinHasPWM(p) (p < 46) +*/ + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 21; +static const uint8_t SCL = 38; + +static const uint8_t SS = 45; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 13; +static const uint8_t SCK = 12; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A6 = 7; +static const uint8_t A7 = 8; +static const uint8_t A8 = 9; +static const uint8_t A9 = 10; +static const uint8_t A10 = 11; +static const uint8_t A11 = 12; +static const uint8_t A12 = 13; +static const uint8_t A13 = 14; +static const uint8_t A14 = 15; +static const uint8_t A15 = 16; +static const uint8_t A16 = 17; +static const uint8_t A17 = 18; +static const uint8_t A18 = 19; +static const uint8_t A19 = 20; + +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T13 = 13; +static const uint8_t T14 = 14; + +#endif /* Pins_Arduino_h */ diff --git a/webinstall/cibuild.html b/webinstall/cibuild.html index 4f41c1a..78ce76d 100644 --- a/webinstall/cibuild.html +++ b/webinstall/cibuild.html @@ -1,5 +1,5 @@ - + @@ -83,4 +83,4 @@ - \ No newline at end of file + diff --git a/webinstall/cibuild.js b/webinstall/cibuild.js index 26443b0..690da1d 100644 --- a/webinstall/cibuild.js +++ b/webinstall/cibuild.js @@ -867,5 +867,27 @@ class PipelineInfo{ buildSelectors(ROOT_PATH,structure.config.children,true); if (! isRunning()) findPipeline(); updateStatus(); + const translationCheck=()=>{ + const lang = document.documentElement.lang; + if (lang != "en"){ + alert( + "This page will not work correctly with translation enabled" + ); + } + } + // Works at least for Chrome, Firefox, Safari and probably more. Not Microsoft + // Edge though. They're special. + // Yell at clouds if a translator doesn't change it + const observer = new MutationObserver(() => { + translationCheck(); + }); + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['lang'], + childList: false, + characterData: false, + }); + translationCheck(); + } })(); \ No newline at end of file