1
0
mirror of https://github.com/thooge/esp32-nmea2000-obp60.git synced 2025-12-28 21:23:07 +01:00

5 Commits

Author SHA1 Message Date
e43199b05d Preparation for upcoming alarm functionality 2025-07-24 09:36:44 +02:00
norbert-walter
58adea1da7 Use fix lib for FRAM 2025-07-24 09:36:44 +02:00
norbert-walter
1043f6defb Use fix lib for FRAM 2025-07-24 09:36:44 +02:00
edd07d9632 Merge branch 'master' into obp40 2025-07-15 14:14:58 +02:00
97b1af71ff More work on SD card code 2025-07-15 14:03:30 +02:00
63 changed files with 877 additions and 8813 deletions

View File

@@ -526,17 +526,3 @@ env.Append(
)
#script does not run on clean yet - maybe in the future
env.AddPostAction("clean",cleangenerated)
#look for extra task scripts and include them here
for taskdir in userTaskDirs:
script = os.path.join(taskdir, "extra_task.py")
if os.path.isfile(script):
taskname = os.path.basename(os.path.normpath(taskdir))
print("#extra task script for '{}'".format(taskname))
with open(script) as fh:
try:
code = compile(fh.read(), taskname, 'exec')
except SyntaxError:
print("#ERROR: script does not compile")
continue
exec(code)

View File

@@ -101,7 +101,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger)
calibMap[instance].slope = slope;
calibMap[instance].smooth = smooth;
calibMap[instance].isCalibrated = false;
LOG_DEBUG(GwLog::LOG, "calibration data: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
calibMap[instance].offset, calibMap[instance].slope, calibMap[instance].smooth);
}
LOG_DEBUG(GwLog::LOG, "all calibration data read");
@@ -117,7 +117,7 @@ void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwL
std::string format = "";
if (calibMap.find(instance) == calibMap.end()) {
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not in calibration list", instance.c_str());
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not found in calibration data list", instance.c_str());
return;
} else if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data
calibMap[instance].isCalibrated = false;
@@ -173,7 +173,7 @@ void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog*
if (!boatDataValue->valid) { // no valid boat data value, so we don't want to smoothen value
return;
} else if (calibMap.find(instance) == calibMap.end()) {
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: smooth factor for %s not found in calibration list", instance.c_str());
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: smooth factor for %s not found in calibration data list", instance.c_str());
return;
} else {
smoothFactor = calibMap[instance].smooth;
@@ -184,6 +184,8 @@ void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog*
}
lastValue[instance] = dataValue; // store the new value for next cycle; first time, store only the current value and return
boatDataValue->value = dataValue; // set the smoothed value to the boat data value
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue);
}
}

View File

@@ -3,8 +3,7 @@
#ifndef _BOATDATACALIBRATION_H
#define _BOATDATACALIBRATION_H
// #include "Pagedata.h"
#include "GwApi.h"
#include "Pagedata.h"
#include <string>
#include <unordered_map>

View File

@@ -1,25 +0,0 @@
/*
Generic graphics functions
*/
#include <math.h>
#include "Graphics.h"
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<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
std::vector<Point> rotatedPoints;
for (const auto& p : pts) {
rotatedPoints.push_back(rotatePoint(origin, p, angle));
}
return rotatedPoints;
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include <vector>
struct Point {
double x;
double y;
};
struct Rect {
double x;
double y;
double w;
double h;
};
Point rotatePoint(const Point& origin, const Point& p, double angle);
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);

View File

@@ -67,8 +67,8 @@ bool hasFRAM = false;
// SD Card
#ifdef BOARD_OBP40S3
sdmmc_card_t *sdcard;
bool hasSDCard;
#endif
bool hasSDCard = false;
// Global vars
bool blinkingLED = false; // Enable / disable blinking flash LED
@@ -84,8 +84,8 @@ LedTaskData *ledTaskData=nullptr;
void hardwareInit(GwApi *api)
{
GwLog *logger = api->getLogger();
GwConfigHandler *config = api->getConfig();
GwLog *logger=api->getLogger();
GwConfigHandler *config=api->getConfig();
Wire.begin();
// Init PCF8574 digital outputs
@@ -96,7 +96,7 @@ void hardwareInit(GwApi *api)
fram = Adafruit_FRAM_I2C();
if (esp_reset_reason() == ESP_RST_POWERON) {
// help initialize FRAM
logger->logDebug(GwLog::LOG, "Delaying I2C init for 250ms due to cold boot");
LOG_DEBUG(GwLog::LOG,"Delaying I2C init for 250ms due to cold boot");
delay(250);
}
// FRAM (e.g. MB85RC256V)
@@ -108,11 +108,11 @@ void hardwareInit(GwApi *api)
// Boot counter
uint8_t framcounter = fram.read(0x0000);
fram.write(0x0000, framcounter+1);
logger->logDebug(GwLog::LOG, "FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter);
LOG_DEBUG(GwLog::LOG,"FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter);
}
else {
hasFRAM = false;
logger->logDebug(GwLog::LOG, "NO FRAM detected");
LOG_DEBUG(GwLog::LOG,"NO FRAM detected");
}
// SD Card
hasSDCard = false;
@@ -121,7 +121,6 @@ void hardwareInit(GwApi *api)
esp_err_t ret;
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.slot = SPI3_HOST;
logger->logDebug(GwLog::DEBUG, "SDSPI_HOST: max_freq_khz=%d" , host.max_freq_khz);
spi_bus_config_t bus_cfg = {
.mosi_io_num = SD_SPI_MOSI,
.miso_io_num = SD_SPI_MISO,
@@ -132,7 +131,7 @@ void hardwareInit(GwApi *api)
};
ret = spi_bus_initialize((spi_host_device_t) host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
if (ret != ESP_OK) {
logger->logDebug(GwLog::ERROR, "Failed to initialize SPI bus for SD card");
LOG_DEBUG(GwLog::ERROR,"Failed to initialize SPI bus for SD card");
} else {
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = SD_SPI_CS;
@@ -145,54 +144,19 @@ void hardwareInit(GwApi *api)
ret = esp_vfs_fat_sdspi_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &sdcard);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
logger->logDebug(GwLog::ERROR, "Failed to mount SD card filesystem");
LOG_DEBUG(GwLog::ERROR,"Failed to mount SD card filesystem");
} else {
// ret == 263 could be not powered up yet
logger->logDebug(GwLog::ERROR, "Failed to initialize SD card (error #%d)", ret);
LOG_DEBUG(GwLog::ERROR,"Failed to initialize SD card");
}
} else {
logger->logDebug(GwLog::LOG, "SD card filesystem mounted at '%s'", MOUNT_POINT);
LOG_DEBUG(GwLog::ERROR,"SD card filesystem mounted");
hasSDCard = true;
}
}
if (hasSDCard) {
// read some stats
String features = "";
if (sdcard->is_mem) features += "MEM "; // Memory card
if (sdcard->is_sdio) features += "IO "; // IO Card
if (sdcard->is_mmc) features += "MMC "; // MMC Card
if (sdcard->is_ddr) features += "DDR ";
// if (sdcard->is_uhs1) features += "UHS-1 ";
// ext_csd. Extended information
// uint8_t rev, uint8_t power_class
logger->logDebug(GwLog::LOG, "SD card features: %s", features);
logger->logDebug(GwLog::LOG, "SD card size: %lluMB", ((uint64_t) sdcard->csd.capacity) * sdcard->csd.sector_size / (1024 * 1024));
}
}
#endif
}
void powerInit(String powermode) {
// Max Power | Only 5.0V | Min Power
if (powermode == "Max Power" || powermode == "Only 5.0V") {
#ifdef HARDWARE_V21
setPortPin(OBP_POWER_50, true); // Power on 5.0V rail
#endif
#ifdef BOARD_OBP40S3
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
setPortPin(OBP_POWER_SD, true); // Power on SD card
#endif
} else { // Min Power
#ifdef HARDWARE_V21
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
#endif
#ifdef BOARD_OBP40S3
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#endif
}
}
void setPortPin(uint pin, bool value){
pinMode(pin, OUTPUT);
digitalWrite(pin, value);
@@ -362,20 +326,30 @@ 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<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
std::vector<Point> rotatedPoints;
for (const auto& p : pts) {
rotatedPoints.push_back(rotatePoint(origin, p, angle));
}
return rotatedPoints;
}
void fillPoly4(const std::vector<Point>& 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);
}
void drawPoly(const std::vector<Point>& points, uint16_t color) {
size_t polysize = points.size();
for (size_t i = 0; i < polysize - 1; i++) {
getdisplay().drawLine(points[i].x, points[i].y, points[i+1].x, points[i+1].y, color);
}
// close path
getdisplay().drawLine(points[polysize-1].x, points[polysize-1].y, points[0].x, points[0].y, color);
}
// Split string into words, whitespace separated
std::vector<String> split(const String &s) {
std::vector<String> words;
@@ -437,24 +411,6 @@ void drawTextRalign(int16_t x, int16_t y, String text) {
getdisplay().print(text);
}
// Draw text inside box, normal or inverted
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border) {
if (inverted) {
getdisplay().fillRect(box.x, box.y, box.w, box.h, fg);
getdisplay().setTextColor(bg);
} else {
if (border) {
getdisplay().fillRect(box.x + 1, box.y + 1, box.w - 2, box.h - 2, bg);
getdisplay().drawRect(box.x, box.y, box.w, box.h, fg);
}
getdisplay().setTextColor(fg);
}
uint16_t border_offset = box.h / 4; // 25% of box height
getdisplay().setCursor(box.x + border_offset, box.y + box.h - border_offset);
getdisplay().print(text);
getdisplay().setTextColor(fg);
}
// 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);

View File

@@ -4,7 +4,6 @@
#include <Arduino.h>
#include "OBP60Hardware.h"
#include "LedSpiTask.h"
#include "Graphics.h"
#include <GxEPD2_BW.h> // E-paper lib V2
#include <Adafruit_FRAM_I2C.h> // I2C FRAM
@@ -22,7 +21,6 @@
#define FRAM_VOLTAGE_AVG 0x000A
#define FRAM_VOLTAGE_TREND 0x000B
#define FRAM_VOLTAGE_MODE 0x000C
// Wind page
#define FRAM_WIND_SIZE 0x000D
#define FRAM_WIND_SRC 0x000E
#define FRAM_WIND_MODE 0x000F
@@ -32,9 +30,9 @@
extern Adafruit_FRAM_I2C fram;
extern bool hasFRAM;
extern bool hasSDCard;
#ifdef BOARD_OBP40S3
extern sdmmc_card_t *sdcard;
extern bool hasSDCard;
#endif
// Fonts declarations for display (#includes see OBP60Extensions.cpp)
@@ -74,15 +72,19 @@ GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
#define PAGE_UPDATE 1 // page wants display to update
#define PAGE_HIBERNATE 2 // page wants displey to hibernate
struct Point {
double x;
double y;
};
Point rotatePoint(const Point& origin, const Point& p, double angle);
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
void fillPoly4(const std::vector<Point>& p4, uint16_t color);
void drawPoly(const std::vector<Point>& points, uint16_t color);
void deepSleep(CommonData &common);
uint8_t getLastPage();
void hardwareInit(GwApi *api);
void powerInit(String powermode);
void setPortPin(uint pin, bool value); // Set port pin for extension port
@@ -104,7 +106,6 @@ 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 drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border);
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);

View File

@@ -49,9 +49,9 @@ String formatLongitude(double lon) {
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lon > 0) ? "E" : "W");
}
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
GwLog *logger = commondata.logger;
FormattedData result;
FormatedData result;
static int dayoffset = 0;
double rawvalue = 0;
@@ -65,7 +65,6 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
String tempFormat = commondata.config->getString(commondata.config->tempFormat); // [K|°C|°F]
String dateFormat = commondata.config->getString(commondata.config->dateFormat); // [DE|GB|US]
bool usesimudata = commondata.config->getBool(commondata.config->useSimuData); // [on|off]
String precision = commondata.config->getString(commondata.config->valueprecision); // [1|2]
// If boat value not valid
if (! value->valid && !usesimudata){
@@ -73,19 +72,6 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
return result;
}
const char* fmt_dec_1;
const char* fmt_dec_10;
const char* fmt_dec_100;
if (precision == "1") {
fmt_dec_1 = "%3.1f";
fmt_dec_10 = "%3.0f";
fmt_dec_100 = "%3.0f";
} else {
fmt_dec_1 = "%3.2f";
fmt_dec_10 = "%3.1f";
fmt_dec_100 = "%3.0f";
}
// LOG_DEBUG(GwLog::DEBUG,"formatValue init: getFormat: %s date->value: %f time->value: %f", value->getFormat(), commondata.date->value, commondata.time->value);
static const int bsize = 30;
char buffer[bsize+1];
@@ -105,25 +91,25 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
tmElements_t parts;
time_t tv=tNMEA0183Msg::daysToTime_t(value->value + dayoffset);
tNMEA0183Msg::breakTime(tv,parts);
if (usesimudata == false) {
if (String(dateFormat) == "DE") {
snprintf(buffer,bsize, "%02d.%02d.%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
if(usesimudata == false) {
if(String(dateFormat) == "DE"){
snprintf(buffer,bsize,"%02d.%02d.%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
}
else if(String(dateFormat) == "GB") {
snprintf(buffer, bsize, "%02d/%02d/%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
else if(String(dateFormat) == "GB"){
snprintf(buffer,bsize,"%02d/%02d/%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
}
else if(String(dateFormat) == "US") {
snprintf(buffer, bsize, "%02d/%02d/%04d", parts.tm_mon+1, parts.tm_mday, parts.tm_year+1900);
else if(String(dateFormat) == "US"){
snprintf(buffer,bsize,"%02d/%02d/%04d",parts.tm_mon+1,parts.tm_mday,parts.tm_year+1900);
}
else if(String(dateFormat) == "ISO") {
snprintf(buffer, bsize, "%04d-%02d-%02d", parts.tm_year+1900, parts.tm_mon+1, parts.tm_mday);
else if(String(dateFormat) == "ISO"){
snprintf(buffer,bsize,"%04d-%02d-%02d",parts.tm_year+1900,parts.tm_mon+1,parts.tm_mday);
}
else {
snprintf(buffer, bsize, "%02d.%02d.%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
else{
snprintf(buffer,bsize,"%02d.%02d.%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
}
}
else{
snprintf(buffer, bsize, "01.01.2022");
snprintf(buffer,bsize,"01.01.2022");
}
if(timeZone == 0){
result.unit = "UTC";
@@ -144,11 +130,11 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
if (timeInSeconds > 86400) {timeInSeconds = timeInSeconds - 86400;}
if (timeInSeconds < 0) {timeInSeconds = timeInSeconds + 86400;}
// LOG_DEBUG(GwLog::DEBUG,"... formatTime value: %f tz: %f corrected timeInSeconds: %f ", value->value, timeZone, timeInSeconds);
if (usesimudata == false) {
val = modf(timeInSeconds/3600.0, &inthr);
val = modf(val*3600.0/60.0, &intmin);
if(usesimudata == false) {
val=modf(timeInSeconds/3600.0,&inthr);
val=modf(val*3600.0/60.0,&intmin);
modf(val*60.0,&intsec);
snprintf(buffer, bsize, "%02.0f:%02.0f:%02.0f", inthr, intmin, intsec);
snprintf(buffer,bsize,"%02.0f:%02.0f:%02.0f",inthr,intmin,intsec);
}
else{
static long sec;
@@ -157,7 +143,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
sec ++;
}
sec = sec % 60;
snprintf(buffer, bsize, "11:36:%02i", int(sec));
snprintf(buffer,bsize,"11:36:%02i", int(sec));
lasttime = millis();
}
if(timeZone == 0){
@@ -170,23 +156,23 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatFixed0"){
if(usesimudata == false) {
snprintf(buffer, bsize, "%3.0f", value->value);
snprintf(buffer,bsize,"%3.0f",value->value);
rawvalue = value->value;
}
else{
rawvalue = 8.0 + float(random(0, 10)) / 10.0;
snprintf(buffer, bsize, "%3.0f", rawvalue);
snprintf(buffer,bsize,"%3.0f", rawvalue);
}
result.unit = "";
}
//########################################################
else if (value->getFormat() == "formatCourse" || value->getFormat() == "formatWind"){
double course = 0;
if (usesimudata == false) {
if(usesimudata == false) {
course = value->value;
rawvalue = value->value;
}
else {
else{
course = 2.53 + float(random(0, 10) / 100.0);
rawvalue = course;
}
@@ -199,7 +185,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatKnots" && (value->getName() == "SOG" || value->getName() == "STW")){
double speed = 0;
if (usesimudata == false) {
if(usesimudata == false) {
speed = value->value;
rawvalue = value->value;
}
@@ -207,85 +193,85 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 4.0 + float(random(0, 40));
speed = rawvalue;
}
if (String(speedFormat) == "km/h"){
if(String(speedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
result.unit = "km/h";
}
else if (String(speedFormat) == "kn"){
else if(String(speedFormat) == "kn"){
speed = speed * 1.94384; // Unit conversion form m/s to kn
result.unit = "kn";
}
else {
else{
speed = speed; // Unit conversion form m/s to m/s
result.unit = "m/s";
}
if(speed < 10) {
snprintf(buffer, bsize, fmt_dec_1, speed);
if(speed < 10){
snprintf(buffer,bsize,"%3.2f",speed);
}
else if (speed < 100) {
snprintf(buffer, bsize, fmt_dec_10, speed);
if(speed >= 10 && speed < 100){
snprintf(buffer,bsize,"%3.1f",speed);
}
else {
snprintf(buffer, bsize, fmt_dec_100, speed);
if(speed >= 100){
snprintf(buffer,bsize,"%3.0f",speed);
}
}
//########################################################
else if (value->getFormat() == "formatKnots" && (value->getName() == "AWS" || value->getName() == "TWS" || value->getName() == "MaxAws" || value->getName() == "MaxTws")){
double speed = 0;
if (usesimudata == false) {
if(usesimudata == false) {
speed = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 4.0 + float(random(0, 40));
speed = rawvalue;
}
if (String(windspeedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
if(String(windspeedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
result.unit = "km/h";
}
else if (String(windspeedFormat) == "kn"){
else if(String(windspeedFormat) == "kn"){
speed = speed * 1.94384; // Unit conversion form m/s to kn
result.unit = "kn";
}
else if(String(windspeedFormat) == "bft"){
if (speed < 0.3) {
if(speed < 0.3){
speed = 0;
}
else if (speed < 1.5) {
if(speed >=0.3 && speed < 1.5){
speed = 1;
}
else if (speed < 3.3) {
if(speed >=1.5 && speed < 3.3){
speed = 2;
}
else if (speed < 5.4) {
if(speed >=3.3 && speed < 5.4){
speed = 3;
}
else if (speed < 7.9) {
if(speed >=5.4 && speed < 7.9){
speed = 4;
}
else if (speed < 10.7) {
if(speed >=7.9 && speed < 10.7){
speed = 5;
}
else if (speed < 13.8) {
if(speed >=10.7 && speed < 13.8){
speed = 6;
}
else if (speed < 17.1) {
if(speed >=13.8 && speed < 17.1){
speed = 7;
}
else if (speed < 20.7) {
if(speed >=17.1 && speed < 20.7){
speed = 8;
}
else if (speed < 24.4) {
if(speed >=20.7 && speed < 24.4){
speed = 9;
}
else if (speed < 28.4) {
if(speed >=24.4 && speed < 28.4){
speed = 10;
}
else if (speed < 32.6) {
if(speed >=28.4 && speed < 32.6){
speed = 11;
}
else {
if(speed >=32.6){
speed = 12;
}
result.unit = "bft";
@@ -294,85 +280,82 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
speed = speed; // Unit conversion form m/s to m/s
result.unit = "m/s";
}
if (String(windspeedFormat) == "bft"){
snprintf(buffer, bsize, "%2.0f", speed);
if(String(windspeedFormat) == "bft"){
snprintf(buffer,bsize,"%2.0f",speed);
}
else{
if (speed < 10){
snprintf(buffer, bsize, fmt_dec_1, speed);
if(speed < 10){
snprintf(buffer,bsize,"%3.2f",speed);
}
else if (speed < 100){
snprintf(buffer, bsize, fmt_dec_10, speed);
if(speed >= 10 && speed < 100){
snprintf(buffer,bsize,"%3.1f",speed);
}
else {
snprintf(buffer, bsize, fmt_dec_100, speed);
if(speed >= 100){
snprintf(buffer,bsize,"%3.0f",speed);
}
}
}
//########################################################
else if (value->getFormat() == "formatRot"){
double rotation = 0;
if (usesimudata == false) {
if(usesimudata == false) {
rotation = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 0.04 + float(random(0, 10)) / 100.0;
rotation = rawvalue;
}
rotation = rotation * 57.2958; // Unit conversion form rad/s to deg/s
result.unit = "Deg/s";
if (rotation < -100){
if(rotation < -100){
rotation = -99;
}
if (rotation > 100){
if(rotation > 100){
rotation = 99;
}
if (rotation > -10 && rotation < 10){
snprintf(buffer, bsize, "%3.2f", rotation);
if(rotation > -10 && rotation < 10){
snprintf(buffer,bsize,"%3.2f",rotation);
}
if (rotation <= -10 || rotation >= 10){
snprintf(buffer, bsize, "%3.0f", rotation);
if(rotation <= -10 || rotation >= 10){
snprintf(buffer,bsize,"%3.0f",rotation);
}
}
//########################################################
else if (value->getFormat() == "formatDop"){
double dop = 0;
if (usesimudata == false) {
if(usesimudata == false) {
dop = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 2.0 + float(random(0, 40)) / 10.0;
dop = rawvalue;
}
result.unit = "m";
if (dop > 99.9){
if(dop > 99.9){
dop = 99.9;
}
if (dop < 10){
snprintf(buffer, bsize, fmt_dec_1, dop);
if(dop < 10){
snprintf(buffer,bsize,"%3.2f",dop);
}
else if(dop < 100){
snprintf(buffer, bsize, fmt_dec_10, dop);
}
else {
snprintf(buffer, bsize, fmt_dec_100, dop);
if(dop >= 10 && dop < 100){
snprintf(buffer,bsize,"%3.1f",dop);
}
}
//########################################################
else if (value->getFormat() == "formatLatitude"){
if (usesimudata == false) {
if(usesimudata == false) {
double lat = value->value;
rawvalue = value->value;
String latitude = "";
String latdir = "";
float degree = abs(int(lat));
float minute = abs((lat - int(lat)) * 60);
if (lat > 0){
if(lat > 0){
latdir = "N";
}
else {
else{
latdir = "S";
}
latitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + latdir;
@@ -381,41 +364,41 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
}
else{
rawvalue = 35.0 + float(random(0, 10)) / 10000.0;
snprintf(buffer, bsize, " 51\" %2.4f' N", rawvalue);
snprintf(buffer,bsize," 51\" %2.4f' N", rawvalue);
}
}
//########################################################
else if (value->getFormat() == "formatLongitude"){
if (usesimudata == false) {
if(usesimudata == false) {
double lon = value->value;
rawvalue = value->value;
String longitude = "";
String londir = "";
float degree = abs(int(lon));
float minute = abs((lon - int(lon)) * 60);
if (lon > 0){
if(lon > 0){
londir = "E";
}
else {
else{
londir = "W";
}
longitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + londir;
result.unit = "";
strcpy(buffer, longitude.c_str());
}
else {
else{
rawvalue = 6.0 + float(random(0, 10)) / 100000.0;
snprintf(buffer, bsize, " 15\" %2.4f'", rawvalue);
snprintf(buffer,bsize," 15\" %2.4f'", rawvalue);
}
}
//########################################################
else if (value->getFormat() == "formatDepth"){
double depth = 0;
if (usesimudata == false) {
if(usesimudata == false) {
depth = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 18.0 + float(random(0, 100)) / 10.0;
depth = rawvalue;
}
@@ -426,84 +409,71 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
else{
result.unit = "m";
}
if (depth < 10) {
snprintf(buffer, bsize, fmt_dec_1, depth);
if(depth < 10){
snprintf(buffer,bsize,"%3.2f",depth);
}
else if (depth < 100){
snprintf(buffer, bsize, fmt_dec_10, depth);
if(depth >= 10 && depth < 100){
snprintf(buffer,bsize,"%3.1f",depth);
}
else {
snprintf(buffer, bsize, fmt_dec_100, depth);
if(depth >= 100){
snprintf(buffer,bsize,"%3.0f",depth);
}
}
//########################################################
else if (value->getFormat() == "formatXte"){
double xte = 0;
if(usesimudata == false) {
xte = value->value;
if (!usesimudata) {
xte = abs(value->value);
rawvalue = value->value;
}
else{
} else {
rawvalue = 6.0 + float(random(0, 4));
xte = rawvalue;
}
if(String(distanceFormat) == "km"){
xte = xte * 0.001;
result.unit = "km";
}
else if(String(distanceFormat) == "nm"){
xte = xte * 0.000539957;
result.unit = "nm";
}
else{;
result.unit = "m";
}
if(xte < 10){
snprintf(buffer,bsize,"%3.2f",xte);
}
if(xte >= 10 && xte < 100){
snprintf(buffer,bsize,"%3.1f",xte);
}
if(xte >= 100){
snprintf(buffer,bsize,"%3.0f",xte);
if (xte >= 100) {
snprintf(buffer,bsize,"%3.0f",value->value);
} else if (xte >= 10) {
snprintf(buffer,bsize,"%3.1f",value->value);
} else {
snprintf(buffer,bsize,"%3.2f",value->value);
}
result.unit = "nm";
}
//########################################################
else if (value->getFormat() == "kelvinToC"){
double temp = 0;
if (usesimudata == false) {
if(usesimudata == false) {
temp = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 296.0 + float(random(0, 10)) / 10.0;
temp = rawvalue;
}
if (String(tempFormat) == "C") {
if(String(tempFormat) == "C"){
temp = temp - 273.15;
result.unit = "C";
}
else if (String(tempFormat) == "F") {
else if(String(tempFormat) == "F"){
temp = (temp - 273.15) * 9 / 5 + 32;
result.unit = "F";
}
else{
result.unit = "K";
}
if(temp < 10) {
snprintf(buffer, bsize, fmt_dec_1, temp);
if(temp < 10){
snprintf(buffer,bsize,"%3.2f",temp);
}
else if (temp < 100) {
snprintf(buffer, bsize, fmt_dec_10, temp);
if(temp >= 10 && temp < 100){
snprintf(buffer,bsize,"%3.1f",temp);
}
else {
snprintf(buffer, bsize, fmt_dec_100, temp);
if(temp >= 100){
snprintf(buffer,bsize,"%3.0f",temp);
}
}
//########################################################
else if (value->getFormat() == "mtr2nm"){
double distance = 0;
if (usesimudata == false) {
if(usesimudata == false) {
distance = value->value;
rawvalue = value->value;
}
@@ -511,25 +481,25 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 2960.0 + float(random(0, 10));
distance = rawvalue;
}
if (String(distanceFormat) == "km") {
if(String(distanceFormat) == "km"){
distance = distance * 0.001;
result.unit = "km";
}
else if (String(distanceFormat) == "nm") {
else if(String(distanceFormat) == "nm"){
distance = distance * 0.000539957;
result.unit = "nm";
}
else {
else{;
result.unit = "m";
}
if (distance < 10){
snprintf(buffer, bsize, fmt_dec_1, distance);
if(distance < 10){
snprintf(buffer,bsize,"%3.2f",distance);
}
else if (distance < 100){
snprintf(buffer, bsize, fmt_dec_10, distance);
if(distance >= 10 && distance < 100){
snprintf(buffer,bsize,"%3.1f",distance);
}
else {
snprintf(buffer, bsize, fmt_dec_100, distance);
if(distance >= 100){
snprintf(buffer,bsize,"%3.0f",distance);
}
}
//########################################################
@@ -538,122 +508,122 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatXdr:P:P"){
double pressure = 0;
if (usesimudata == false) {
if(usesimudata == false) {
pressure = value->value;
rawvalue = value->value;
pressure = pressure / 100.0; // Unit conversion form Pa to hPa
}
else {
else{
rawvalue = 968 + float(random(0, 10));
pressure = rawvalue;
}
snprintf(buffer, bsize, "%4.0f", pressure);
snprintf(buffer,bsize,"%4.0f",pressure);
result.unit = "hPa";
}
//########################################################
else if (value->getFormat() == "formatXdr:P:B"){
double pressure = 0;
if (usesimudata == false) {
if(usesimudata == false) {
pressure = value->value;
rawvalue = value->value;
pressure = pressure / 100.0; // Unit conversion form Pa to mBar
}
else {
else{
rawvalue = value->value;
pressure = 968 + float(random(0, 10));
}
snprintf(buffer, bsize, "%4.0f", pressure);
snprintf(buffer,bsize,"%4.0f",pressure);
result.unit = "mBar";
}
//########################################################
else if (value->getFormat() == "formatXdr:U:V"){
double voltage = 0;
if (usesimudata == false) {
if(usesimudata == false) {
voltage = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 12 + float(random(0, 30)) / 10.0;
voltage = rawvalue;
}
if (voltage < 10) {
snprintf(buffer, bsize, fmt_dec_1, voltage);
if(voltage < 10){
snprintf(buffer,bsize,"%3.2f",voltage);
}
else {
snprintf(buffer, bsize, fmt_dec_10, voltage);
else{
snprintf(buffer,bsize,"%3.1f",voltage);
}
result.unit = "V";
}
//########################################################
else if (value->getFormat() == "formatXdr:I:A"){
double current = 0;
if (usesimudata == false) {
if(usesimudata == false) {
current = value->value;
rawvalue = value->value;
}
else {
else{
rawvalue = 8.2 + float(random(0, 50)) / 10.0;
current = rawvalue;
}
if (current < 10) {
snprintf(buffer, bsize, fmt_dec_1, current);
if(current < 10){
snprintf(buffer,bsize,"%3.2f",current);
}
else if(current < 100) {
snprintf(buffer, bsize, fmt_dec_10, current);
if(current >= 10 && current < 100){
snprintf(buffer,bsize,"%3.1f",current);
}
else {
snprintf(buffer, bsize, fmt_dec_100, current);
if(current >= 100){
snprintf(buffer,bsize,"%3.0f",current);
}
result.unit = "A";
}
//########################################################
else if (value->getFormat() == "formatXdr:C:K"){
double temperature = 0;
if (usesimudata == false) {
if(usesimudata == false) {
temperature = value->value - 273.15; // Convert K to C
rawvalue = value->value - 273.15;
}
else {
else{
rawvalue = 21.8 + float(random(0, 50)) / 10.0;
temperature = rawvalue;
}
if (temperature < 10) {
snprintf(buffer, bsize, fmt_dec_1, temperature);
if(temperature < 10){
snprintf(buffer,bsize,"%3.2f",temperature);
}
else if (temperature < 100) {
snprintf(buffer, bsize, fmt_dec_10, temperature);
if(temperature >= 10 && temperature < 100){
snprintf(buffer,bsize,"%3.1f",temperature);
}
else {
snprintf(buffer, bsize, fmt_dec_100, temperature);
if(temperature >= 100){
snprintf(buffer,bsize,"%3.0f",temperature);
}
result.unit = "Deg C";
}
//########################################################
else if (value->getFormat() == "formatXdr:C:C"){
double temperature = 0;
if (usesimudata == false) {
if(usesimudata == false) {
temperature = value->value; // Value in C
rawvalue = value->value;
}
else {
else{
rawvalue = 21.8 + float(random(0, 50)) / 10.0;
temperature = rawvalue;
}
if (temperature < 10) {
snprintf(buffer, bsize, fmt_dec_1, temperature);
if(temperature < 10){
snprintf(buffer,bsize,"%3.2f",temperature);
}
else if(temperature < 100) {
snprintf(buffer, bsize, fmt_dec_10, temperature);
if(temperature >= 10 && temperature < 100){
snprintf(buffer,bsize,"%3.1f",temperature);
}
else {
snprintf(buffer, bsize, fmt_dec_100, temperature);
if(temperature >= 100){
snprintf(buffer,bsize,"%3.0f",temperature);
}
result.unit = "Deg C";
}
//########################################################
else if (value->getFormat() == "formatXdr:H:P"){
double humidity = 0;
if (usesimudata == false) {
if(usesimudata == false) {
humidity = value->value; // Value in %
rawvalue = value->value;
}
@@ -661,143 +631,143 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 41.3 + float(random(0, 50)) / 10.0;
humidity = rawvalue;
}
if (humidity < 10) {
snprintf(buffer, bsize, fmt_dec_1, humidity);
if(humidity < 10){
snprintf(buffer,bsize,"%3.2f",humidity);
}
else if(humidity < 100) {
snprintf(buffer, bsize, fmt_dec_10, humidity);
if(humidity >= 10 && humidity < 100){
snprintf(buffer,bsize,"%3.1f",humidity);
}
else {
snprintf(buffer, bsize, fmt_dec_100, humidity);
if(humidity >= 100){
snprintf(buffer,bsize,"%3.0f",humidity);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:V:P"){
double volume = 0;
if (usesimudata == false) {
if(usesimudata == false) {
volume = value->value; // Value in %
rawvalue = value->value;
}
else {
else{
rawvalue = 85.8 + float(random(0, 50)) / 10.0;
volume = rawvalue;
}
if (volume < 10) {
snprintf(buffer, bsize, fmt_dec_1, volume);
if(volume < 10){
snprintf(buffer,bsize,"%3.2f",volume);
}
else if (volume < 100) {
snprintf(buffer, bsize, fmt_dec_10, volume);
if(volume >= 10 && volume < 100){
snprintf(buffer,bsize,"%3.1f",volume);
}
else if (volume >= 100) {
snprintf(buffer, bsize, fmt_dec_100, volume);
if(volume >= 100){
snprintf(buffer,bsize,"%3.0f",volume);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:V:M"){
double volume = 0;
if (usesimudata == false) {
if(usesimudata == false) {
volume = value->value; // Value in l
rawvalue = value->value;
}
else {
else{
rawvalue = 75.2 + float(random(0, 50)) / 10.0;
volume = rawvalue;
}
if (volume < 10) {
snprintf(buffer, bsize, fmt_dec_1, volume);
if(volume < 10){
snprintf(buffer,bsize,"%3.2f",volume);
}
else if (volume < 100) {
snprintf(buffer, bsize, fmt_dec_10, volume);
if(volume >= 10 && volume < 100){
snprintf(buffer,bsize,"%3.1f",volume);
}
else {
snprintf(buffer, bsize, fmt_dec_100, volume);
if(volume >= 100){
snprintf(buffer,bsize,"%3.0f",volume);
}
result.unit = "l";
}
//########################################################
else if (value->getFormat() == "formatXdr:R:I"){
double flow = 0;
if (usesimudata == false) {
if(usesimudata == false) {
flow = value->value; // Value in l/min
rawvalue = value->value;
}
else {
else{
rawvalue = 7.5 + float(random(0, 20)) / 10.0;
flow = rawvalue;
}
if (flow < 10) {
snprintf(buffer, bsize, fmt_dec_1, flow);
if(flow < 10){
snprintf(buffer,bsize,"%3.2f",flow);
}
else if (flow < 100) {
snprintf(buffer, bsize, fmt_dec_10, flow);
if(flow >= 10 && flow < 100){
snprintf(buffer,bsize,"%3.1f",flow);
}
else {
snprintf(buffer, bsize, fmt_dec_100, flow);
if(flow >= 100){
snprintf(buffer,bsize,"%3.0f",flow);
}
result.unit = "l/min";
}
//########################################################
else if (value->getFormat() == "formatXdr:G:"){
double generic = 0;
if (usesimudata == false) {
generic = value->value;
if(usesimudata == false) {
generic = value->value; // Value in l/min
rawvalue = value->value;
}
else {
else{
rawvalue = 18.5 + float(random(0, 20)) / 10.0;
generic = rawvalue;
}
if (generic < 10) {
snprintf(buffer, bsize, fmt_dec_1, generic);
if(generic < 10){
snprintf(buffer,bsize,"%3.2f",generic);
}
else if (generic < 100) {
snprintf(buffer, bsize, fmt_dec_10, generic);
if(generic >= 10 && generic < 100){
snprintf(buffer,bsize,"%3.1f",generic);
}
else {
snprintf(buffer, bsize, fmt_dec_100, generic);
if(generic >= 100){
snprintf(buffer,bsize,"%3.0f",generic);
}
result.unit = "";
}
//########################################################
else if (value->getFormat() == "formatXdr:A:P"){
double dplace = 0;
if (usesimudata == false) {
if(usesimudata == false) {
dplace = value->value; // Value in %
rawvalue = value->value;
}
else {
else{
rawvalue = 55.3 + float(random(0, 20)) / 10.0;
dplace = rawvalue;
}
if (dplace < 10) {
snprintf(buffer, bsize, fmt_dec_1, dplace);
if(dplace < 10){
snprintf(buffer,bsize,"%3.2f",dplace);
}
else if (dplace < 100) {
snprintf(buffer, bsize, fmt_dec_10, dplace);
if(dplace >= 10 && dplace < 100){
snprintf(buffer,bsize,"%3.1f",dplace);
}
else {
snprintf(buffer, bsize, fmt_dec_100, dplace);
if(dplace >= 100){
snprintf(buffer,bsize,"%3.0f",dplace);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:A:D"){
double angle = 0;
if (usesimudata == false) {
if(usesimudata == false) {
angle = value->value;
angle = angle * 57.2958; // Unit conversion form rad to deg
rawvalue = value->value;
}
else {
else{
rawvalue = PI / 100 + (random(-5, 5) / 360 * 2* PI);
angle = rawvalue * 57.2958;
}
if (angle > -10 && angle < 10) {
if(angle > -10 && angle < 10){
snprintf(buffer,bsize,"%3.1f",angle);
}
else {
else{
snprintf(buffer,bsize,"%3.0f",angle);
}
result.unit = "Deg";
@@ -805,41 +775,41 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatXdr:T:R"){
double rpm = 0;
if (usesimudata == false) {
if(usesimudata == false) {
rpm = value->value; // Value in rpm
rawvalue = value->value;
}
else {
else{
rawvalue = 2505 + random(0, 20);
rpm = rawvalue;
}
if (rpm < 10) {
snprintf(buffer, bsize, fmt_dec_1, rpm);
if(rpm < 10){
snprintf(buffer,bsize,"%3.2f",rpm);
}
else if (rpm < 100) {
snprintf(buffer, bsize, fmt_dec_10, rpm);
if(rpm >= 10 && rpm < 100){
snprintf(buffer,bsize,"%3.1f",rpm);
}
else {
snprintf(buffer, bsize, fmt_dec_100, rpm);
if(rpm >= 100){
snprintf(buffer,bsize,"%3.0f",rpm);
}
result.unit = "rpm";
}
//########################################################
// Default format
//########################################################
else {
if (value->value < 10) {
snprintf(buffer, bsize, fmt_dec_1, value->value);
else{
if(value->value < 10){
snprintf(buffer,bsize,"%3.2f",value->value);
}
else if (value->value < 100) {
snprintf(buffer, bsize, fmt_dec_10, value->value);
if(value->value >= 10 && value->value < 100){
snprintf(buffer,bsize,"%3.1f",value->value);
}
else {
snprintf(buffer, bsize, fmt_dec_100, value->value);
if(value->value >= 100){
snprintf(buffer,bsize,"%3.0f",value->value);
}
result.unit = "";
}
buffer[bsize] = 0;
buffer[bsize]=0;
result.value = rawvalue; // Return value is only necessary in case of simulation of graphic pointer
result.svalue = String(buffer);
return result;

View File

@@ -82,7 +82,7 @@
// Direction pin for RS485 NMEA0183
#define OBP_DIRECTION_PIN 8
// I2C
#define I2C_SPEED 100000UL // 100kHz clock speed on I2C bus
#define I2C_SPEED 10000UL // 10kHz clock speed on I2C bus
#define OBP_I2C_SDA 21
#define OBP_I2C_SCL 38
// DS1388 RTC

View File

@@ -1,322 +0,0 @@
#include "OBPDataOperations.h"
// --- Class HstryBuf ---------------
// Init history buffers for selected boat data
void HstryBuf::init(BoatValueList* boatValues, GwLog *log) {
logger = log;
int hstryUpdFreq = 1000; // Update frequency for history buffers in ms
int hstryMinVal = 0; // Minimum value for these history buffers
twdHstryMax = 6283; // Max value for wind direction (TWD, AWD) in rad [0...2*PI], shifted by 1000 for 3 decimals
twsHstryMax = 65000; // Max value for wind speed (TWS, AWS) in m/s [0..65], shifted by 1000 for 3 decimals
awdHstryMax = twdHstryMax;
awsHstryMax = twsHstryMax;
twdHstryMin = hstryMinVal;
twsHstryMin = hstryMinVal;
awdHstryMin = hstryMinVal;
awsHstryMin = hstryMinVal;
const double DBL_MAX = std::numeric_limits<double>::max();
// Initialize history buffers with meta data
hstryBufList.twdHstry->setMetaData("TWD", "formatCourse", hstryUpdFreq, hstryMinVal, twdHstryMax);
hstryBufList.twsHstry->setMetaData("TWS", "formatKnots", hstryUpdFreq, hstryMinVal, twsHstryMax);
hstryBufList.awdHstry->setMetaData("AWD", "formatCourse", hstryUpdFreq, hstryMinVal, twdHstryMax);
hstryBufList.awsHstry->setMetaData("AWS", "formatKnots", hstryUpdFreq, hstryMinVal, twsHstryMax);
// create boat values for history data types, if they don't exist yet
twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName());
twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
twaBVal = boatValues->findValueOrCreate("TWA");
awdBVal = boatValues->findValueOrCreate(hstryBufList.awdHstry->getName());
awsBVal = boatValues->findValueOrCreate(hstryBufList.awsHstry->getName());
if (!awdBVal->valid) { // AWD usually does not exist
awdBVal->setFormat(hstryBufList.awdHstry->getFormat());
awdBVal->value = DBL_MAX;
}
// collect boat values for true wind calculation
awaBVal = boatValues->findValueOrCreate("AWA");
hdtBVal = boatValues->findValueOrCreate("HDT");
hdmBVal = boatValues->findValueOrCreate("HDM");
varBVal = boatValues->findValueOrCreate("VAR");
cogBVal = boatValues->findValueOrCreate("COG");
sogBVal = boatValues->findValueOrCreate("SOG");
}
// Handle history buffers for TWD, TWS, AWD, AWS
//void HstryBuf::handleHstryBuf(GwApi* api, BoatValueList* boatValues, bool useSimuData) {
void HstryBuf::handleHstryBuf(bool useSimuData) {
static int16_t twd = 20; //initial value only relevant if we use simulation data
static uint16_t tws = 20; //initial value only relevant if we use simulation data
static double awd, aws, hdt = 20; //initial value only relevant if we use simulation data
GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here
LOG_DEBUG(GwLog::DEBUG,"obp60task handleHstryBuf: TWD_isValid? %d, twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f", twdBVal->valid, twdBVal->value * RAD_TO_DEG,
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
if (twdBVal->valid) {
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twdBVal->getFormat());
calBVal->value = twdBVal->value;
calBVal->valid = twdBVal->valid;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
twd = static_cast<int16_t>(std::round(calBVal->value * 1000.0));
if (twd >= twdHstryMin && twd <= twdHstryMax) {
hstryBufList.twdHstry->add(twd);
}
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
twd += random(-20, 20);
twd = WindUtils::to360(twd);
hstryBufList.twdHstry->add(static_cast<int16_t>(DegToRad(twd) * 1000.0));
}
if (twsBVal->valid) {
calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values
calBVal->setFormat(twsBVal->getFormat());
calBVal->value = twsBVal->value;
calBVal->valid = twsBVal->valid;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
tws = static_cast<uint16_t>(std::round(calBVal->value * 1000));
if (tws >= twsHstryMin && tws <= twsHstryMax) {
hstryBufList.twsHstry->add(tws);
}
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
tws += random(-5000, 5000); // TWS value in m/s; expands to 3 decimals
tws = constrain(tws, 0, 25000); // Limit TWS to [0..25] m/s
hstryBufList.twsHstry->add(tws);
}
if (awaBVal->valid) {
if (hdtBVal->valid) {
hdt = hdtBVal->value; // Use HDT if available
} else {
hdt = WindUtils::calcHDT(&hdmBVal->value, &varBVal->value, &cogBVal->value, &sogBVal->value);
}
awd = awaBVal->value + hdt;
awd = WindUtils::to2PI(awd);
calBVal = new GwApi::BoatValue("AWD"); // temporary solution for calibration of history buffer values
calBVal->value = awd;
calBVal->setFormat(awdBVal->getFormat());
calBVal->valid = true;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
awdBVal->value = calBVal->value;
awdBVal->valid = true;
awd = std::round(calBVal->value * 1000.0);
if (awd >= awdHstryMin && awd <= awdHstryMax) {
hstryBufList.awdHstry->add(static_cast<int16_t>(awd));
}
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
awd += random(-20, 20);
awd = WindUtils::to360(awd);
hstryBufList.awdHstry->add(static_cast<int16_t>(DegToRad(awd) * 1000.0));
}
if (awsBVal->valid) {
calBVal = new GwApi::BoatValue("AWS"); // temporary solution for calibration of history buffer values
calBVal->setFormat(awsBVal->getFormat());
calBVal->value = awsBVal->value;
calBVal->valid = awsBVal->valid;
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
aws = std::round(calBVal->value * 1000);
if (aws >= awsHstryMin && aws <= awsHstryMax) {
hstryBufList.awsHstry->add(static_cast<uint16_t>(aws));
}
delete calBVal;
calBVal = nullptr;
} else if (useSimuData) {
aws += random(-5000, 5000); // TWS value in m/s; expands to 1 decimal
aws = constrain(aws, 0, 25000); // Limit TWS to [0..25] m/s
hstryBufList.awsHstry->add(aws);
}
}
// --- Class HstryBuf ---------------
// --- Class WindUtils --------------
double WindUtils::to2PI(double a)
{
a = fmod(a, 2 * M_PI);
if (a < 0.0) {
a += 2 * M_PI;
}
return a;
}
double WindUtils::toPI(double a)
{
a += M_PI;
a = to2PI(a);
a -= M_PI;
return a;
}
double WindUtils::to360(double a)
{
a = fmod(a, 360);
if (a < 0.0) {
a += 360;
}
return a;
}
double WindUtils::to180(double a)
{
a += 180;
a = to360(a);
a -= 180;
return a;
}
void WindUtils::toCart(const double* phi, const double* r, double* x, double* y)
{
*x = *r * sin(*phi);
*y = *r * cos(*phi);
}
void WindUtils::toPol(const double* x, const double* y, double* phi, double* r)
{
*phi = (M_PI / 2) - atan2(*y, *x);
*phi = to2PI(*phi);
*r = sqrt(*x * *x + *y * *y);
}
void WindUtils::addPolar(const double* phi1, const double* r1,
const double* phi2, const double* r2,
double* phi, double* r)
{
double x1, y1, x2, y2;
toCart(phi1, r1, &x1, &y1);
toCart(phi2, r2, &x2, &y2);
x1 += x2;
y1 += y2;
toPol(&x1, &y1, phi, r);
}
void WindUtils::calcTwdSA(const double* AWA, const double* AWS,
const double* CTW, const double* STW, const double* HDT,
double* TWD, double* TWS, double* TWA)
{
double awd = *AWA + *HDT;
awd = to2PI(awd);
double stw = -*STW;
addPolar(&awd, AWS, CTW, &stw, TWD, TWS);
// Normalize TWD and TWA to 0-360°
*TWD = to2PI(*TWD);
*TWA = toPI(*TWD - *HDT);
}
double WindUtils::calcHDT(const double* hdmVal, const double* varVal, const double* cogVal, const double* sogVal)
{
double hdt;
double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor
if (*hdmVal != DBL_MAX) {
hdt = *hdmVal + (*varVal != DBL_MAX ? *varVal : 0.0); // Use corrected HDM if HDT is not available (or just HDM if VAR is not available)
hdt = to2PI(hdt);
} else if (*cogVal != DBL_MAX && *sogVal >= minSogVal) {
hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available, and SOG is not data noise
} else {
hdt = DBL_MAX; // Cannot calculate HDT without valid HDM or HDM+VAR or COG
}
return hdt;
}
bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal)
{
double stw, hdt, ctw;
double twd, tws, twa;
double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor
if (*hdtVal != DBL_MAX) {
hdt = *hdtVal; // Use HDT if available
} else {
hdt = calcHDT(hdmVal, varVal, cogVal, sogVal);
}
if (*cogVal != DBL_MAX && *sogVal >= minSogVal) { // if SOG is data noise, we don't trust COG
ctw = *cogVal; // Use COG for CTW if available
} else {
ctw = hdt; // 2nd approximation for CTW; hdt must exist if we reach this part of the code
}
if (*stwVal != DBL_MAX) {
stw = *stwVal; // Use STW if available
} else if (*sogVal != DBL_MAX) {
stw = *sogVal;
} else {
// If STW and SOG are not available, we cannot calculate true wind
return false;
}
// Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw));
if ((*awaVal == DBL_MAX) || (*awsVal == DBL_MAX)) {
// Cannot calculate true wind without valid AWA, AWS; other checks are done earlier
return false;
} else {
calcTwdSA(awaVal, awsVal, &ctw, &stw, &hdt, &twd, &tws, &twa);
*twdVal = twd;
*twsVal = tws;
*twaVal = twa;
return true;
}
}
// Calculate true wind data and add to obp60task boat data list
bool WindUtils::addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog* log) {
GwLog* logger = log;
double awaVal, awsVal, cogVal, stwVal, sogVal, hdtVal, hdmVal, varVal;
double twd, tws, twa;
bool isCalculated = false;
awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX;
awsVal = awsBVal->valid ? awsBVal->value : DBL_MAX;
cogVal = cogBVal->valid ? cogBVal->value : DBL_MAX;
stwVal = stwBVal->valid ? stwBVal->value : DBL_MAX;
sogVal = sogBVal->valid ? sogBVal->value : DBL_MAX;
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MAX;
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MAX;
varVal = varBVal->valid ? varBVal->value : DBL_MAX;
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.2f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, sogBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG);
isCalculated = calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
if (isCalculated) { // Replace values only, if successfully calculated and not already available
if (!twdBVal->valid) {
twdBVal->value = twd;
twdBVal->valid = true;
}
if (!twsBVal->valid) {
twsBVal->value = tws;
twsBVal->valid = true;
}
if (!twaBVal->valid) {
twaBVal->value = twa;
twaBVal->valid = true;
}
}
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", isCalculated, twdBVal->value * RAD_TO_DEG,
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
return isCalculated;
}
// --- Class WindUtils --------------

View File

@@ -1,90 +0,0 @@
#pragma once
#include <N2kMessages.h>
#include "OBPRingBuffer.h"
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
#include "obp60task.h"
#include <math.h>
typedef struct {
RingBuffer<int16_t>* twdHstry;
RingBuffer<uint16_t>* twsHstry;
RingBuffer<int16_t>* awdHstry;
RingBuffer<uint16_t>* awsHstry;
} tBoatHstryData; // Holds pointers to all history buffers for boat data
class HstryBuf {
private:
GwLog *logger;
RingBuffer<int16_t> twdHstry; // Circular buffer to store true wind direction values
RingBuffer<uint16_t> twsHstry; // Circular buffer to store true wind speed values (TWS)
RingBuffer<int16_t> awdHstry; // Circular buffer to store apparant wind direction values
RingBuffer<uint16_t> awsHstry; // Circular buffer to store apparant xwind speed values (AWS)
int16_t twdHstryMin; // Min value for wind direction (TWD) in history buffer
int16_t twdHstryMax; // Max value for wind direction (TWD) in history buffer
uint16_t twsHstryMin;
uint16_t twsHstryMax;
int16_t awdHstryMin;
int16_t awdHstryMax;
uint16_t awsHstryMin;
uint16_t awsHstryMax;
// boat values for buffers and for true wind calculation
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal, *awdBVal, *awsBVal;
GwApi::BoatValue *awaBVal, *hdtBVal, *hdmBVal, *varBVal, *cogBVal, *sogBVal;
public:
tBoatHstryData hstryBufList;
HstryBuf(){
hstryBufList = {&twdHstry, &twsHstry, &awdHstry, &awsHstry}; // Generate history buffers of zero size
};
HstryBuf(int size) {
hstryBufList = {&twdHstry, &twsHstry, &awdHstry, &awsHstry};
hstryBufList.twdHstry->resize(960); // store 960 TWD values for 16 minutes history
hstryBufList.twsHstry->resize(960);
hstryBufList.awdHstry->resize(960);
hstryBufList.awsHstry->resize(960);
};
void init(BoatValueList* boatValues, GwLog *log);
void handleHstryBuf(bool useSimuData);
};
class WindUtils {
private:
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal;
GwApi::BoatValue *awaBVal, *awsBVal, *cogBVal, *stwBVal, *sogBVal, *hdtBVal, *hdmBVal, *varBVal;
static constexpr double DBL_MAX = std::numeric_limits<double>::max();
public:
WindUtils(BoatValueList* boatValues){
twdBVal = boatValues->findValueOrCreate("TWD");
twsBVal = boatValues->findValueOrCreate("TWS");
twaBVal = boatValues->findValueOrCreate("TWA");
awaBVal = boatValues->findValueOrCreate("AWA");
awsBVal = boatValues->findValueOrCreate("AWS");
cogBVal = boatValues->findValueOrCreate("COG");
stwBVal = boatValues->findValueOrCreate("STW");
sogBVal = boatValues->findValueOrCreate("SOG");
hdtBVal = boatValues->findValueOrCreate("HDT");
hdmBVal = boatValues->findValueOrCreate("HDM");
varBVal = boatValues->findValueOrCreate("VAR");
};
static double to2PI(double a);
static double toPI(double a);
static double to360(double a);
static double to180(double a);
void toCart(const double* phi, const double* r, double* x, double* y);
void toPol(const double* x, const double* y, double* phi, double* r);
void addPolar(const double* phi1, const double* r1,
const double* phi2, const double* r2,
double* phi, double* r);
void calcTwdSA(const double* AWA, const double* AWS,
const double* CTW, const double* STW, const double* HDT,
double* TWD, double* TWS, double* TWA);
static double calcHDT(const double* hdmVal, const double* varVal, const double* cogVal, const double* sogVal);
bool calcTrueWind(const double* awaVal, const double* awsVal,
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal);
bool addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog *log);
};

View File

@@ -1,66 +0,0 @@
#pragma once
#include "GwSynchronized.h"
#include <algorithm>
#include <limits>
#include <stdexcept>
#include <vector>
#include "WString.h"
template <typename T>
class RingBuffer {
private:
std::vector<T> buffer; // THE buffer vector
size_t capacity;
size_t head; // Points to the next insertion position
size_t first; // Points to the first (oldest) valid element
size_t last; // Points to the last (newest) valid element
size_t count; // Number of valid elements currently in buffer
bool is_Full; // Indicates that all buffer elements are used and ringing is in use
T MIN_VAL; // lowest possible value of buffer of type <T>
T MAX_VAL; // highest possible value of buffer of type <T> -> indicates invalid value in buffer
mutable SemaphoreHandle_t bufLocker;
// metadata for buffer
String dataName; // Name of boat data in buffer
String dataFmt; // Format of boat data in buffer
int updFreq; // Update frequency in milliseconds
T smallest; // Value range of buffer: smallest value; needs to be => MIN_VAL
T largest; // Value range of buffer: biggest value; needs to be < MAX_VAL, since MAX_VAL indicates invalid entries
void initCommon();
public:
RingBuffer();
RingBuffer(size_t size);
void setMetaData(String name, String format, int updateFrequency, T minValue, T maxValue); // Set meta data for buffer
bool getMetaData(String& name, String& format, int& updateFrequency, T& minValue, T& maxValue); // Get meta data of buffer
bool getMetaData(String& name, String& format);
String getName() const; // Get buffer name
String getFormat() const; // Get buffer data format
void add(const T& value); // Add a new value to buffer
T get(size_t index) const; // Get value at specific position (0-based index from oldest to newest)
T getFirst() const; // Get the first (oldest) value in buffer
T getLast() const; // Get the last (newest) value in buffer
T getMin() const; // Get the lowest value in buffer
T getMin(size_t amount) const; // Get minimum value of the last <amount> values of buffer
T getMax() const; // Get the highest value in buffer
T getMax(size_t amount) const; // Get maximum value of the last <amount> values of buffer
T getMid() const; // Get mid value between <min> and <max> value in buffer
T getMid(size_t amount) const; // Get mid value between <min> and <max> value of the last <amount> values of buffer
T getMedian() const; // Get the median value in buffer
T getMedian(size_t amount) const; // Get the median value of the last <amount> values of buffer
size_t getCapacity() const; // Get the buffer capacity (maximum size)
size_t getCurrentSize() const; // Get the current number of elements in buffer
size_t getFirstIdx() const; // Get the index of oldest value in buffer
size_t getLastIdx() const; // Get the index of newest value in buffer
bool isEmpty() const; // Check if buffer is empty
bool isFull() const; // Check if buffer is full
T getMinVal() const; // Get lowest possible value for buffer
T getMaxVal() const; // Get highest possible value for buffer; used for unset/invalid buffer data
void clear(); // Clear buffer
void resize(size_t size); // Delete buffer and set new size
T operator[](size_t index) const; // Operator[] for convenient access (same as get())
std::vector<T> getAllValues() const; // Get all current values as a vector
};
#include "OBPRingBuffer.tpp"

View File

@@ -1,423 +0,0 @@
#include "OBPRingBuffer.h"
template <typename T>
void RingBuffer<T>::initCommon() {
MIN_VAL = std::numeric_limits<T>::lowest();
MAX_VAL = std::numeric_limits<T>::max();
dataName = "";
dataFmt = "";
updFreq = -1;
smallest = MIN_VAL;
largest = MAX_VAL;
bufLocker = xSemaphoreCreateMutex();
}
template <typename T>
RingBuffer<T>::RingBuffer()
: capacity(0)
, head(0)
, first(0)
, last(0)
, count(0)
, is_Full(false)
{
initCommon();
// <buffer> stays empty
}
template <typename T>
RingBuffer<T>::RingBuffer(size_t size)
: capacity(size)
, head(0)
, first(0)
, last(0)
, count(0)
, is_Full(false)
{
initCommon();
buffer.resize(size, MAX_VAL); // MAX_VAL indicate invalid values
}
// Specify meta data of buffer content
template <typename T>
void RingBuffer<T>::setMetaData(String name, String format, int updateFrequency, T minValue, T maxValue)
{
GWSYNCHRONIZED(&bufLocker);
dataName = name;
dataFmt = format;
updFreq = updateFrequency;
smallest = std::max(MIN_VAL, minValue);
largest = std::min(MAX_VAL, maxValue);
}
// Get meta data of buffer content
template <typename T>
bool RingBuffer<T>::getMetaData(String& name, String& format, int& updateFrequency, T& minValue, T& maxValue)
{
if (dataName == "" || dataFmt == "" || updFreq == -1) {
return false; // Meta data not set
}
GWSYNCHRONIZED(&bufLocker);
name = dataName;
format = dataFmt;
updateFrequency = updFreq;
minValue = smallest;
maxValue = largest;
return true;
}
// Get meta data of buffer content
template <typename T>
bool RingBuffer<T>::getMetaData(String& name, String& format)
{
if (dataName == "" || dataFmt == "") {
return false; // Meta data not set
}
GWSYNCHRONIZED(&bufLocker);
name = dataName;
format = dataFmt;
return true;
}
// Get buffer name
template <typename T>
String RingBuffer<T>::getName() const
{
return dataName;
}
// Get buffer data format
template <typename T>
String RingBuffer<T>::getFormat() const
{
return dataFmt;
}
// Add a new value to buffer
template <typename T>
void RingBuffer<T>::add(const T& value)
{
GWSYNCHRONIZED(&bufLocker);
if (value < smallest || value > largest) {
buffer[head] = MAX_VAL; // Store MAX_VAL if value is out of range
} else {
buffer[head] = value;
}
last = head;
if (is_Full) {
first = (first + 1) % capacity; // Move pointer to oldest element when overwriting
} else {
count++;
if (count == capacity) {
is_Full = true;
}
}
head = (head + 1) % capacity;
}
// Get value at specific position (0-based index from oldest to newest)
template <typename T>
T RingBuffer<T>::get(size_t index) const
{
GWSYNCHRONIZED(&bufLocker);
if (isEmpty() || index < 0 || index >= count) {
return MAX_VAL;
}
size_t realIndex = (first + index) % capacity;
return buffer[realIndex];
}
// Operator[] for convenient access (same as get())
template <typename T>
T RingBuffer<T>::operator[](size_t index) const
{
return get(index);
}
// Get the first (oldest) value in the buffer
template <typename T>
T RingBuffer<T>::getFirst() const
{
if (isEmpty()) {
return MAX_VAL;
}
return get(0);
}
// Get the last (newest) value in the buffer
template <typename T>
T RingBuffer<T>::getLast() const
{
if (isEmpty()) {
return MAX_VAL;
}
return get(count - 1);
}
// Get the lowest value in the buffer
template <typename T>
T RingBuffer<T>::getMin() const
{
if (isEmpty()) {
return MAX_VAL;
}
T minVal = MAX_VAL;
T value;
for (size_t i = 0; i < count; i++) {
value = get(i);
if (value < minVal && value != MAX_VAL) {
minVal = value;
}
}
return minVal;
}
// Get minimum value of the last <amount> values of buffer
template <typename T>
T RingBuffer<T>::getMin(size_t amount) const
{
if (isEmpty() || amount <= 0) {
return MAX_VAL;
}
if (amount > count)
amount = count;
T minVal = MAX_VAL;
T value;
for (size_t i = 0; i < amount; i++) {
value = get(count - 1 - i);
if (value < minVal && value != MAX_VAL) {
minVal = value;
}
}
return minVal;
}
// Get the highest value in the buffer
template <typename T>
T RingBuffer<T>::getMax() const
{
if (isEmpty()) {
return MAX_VAL;
}
T maxVal = MIN_VAL;
T value;
for (size_t i = 0; i < count; i++) {
value = get(i);
if (value > maxVal && value != MAX_VAL) {
maxVal = value;
}
}
return maxVal;
}
// Get maximum value of the last <amount> values of buffer
template <typename T>
T RingBuffer<T>::getMax(size_t amount) const
{
if (isEmpty() || amount <= 0) {
return MAX_VAL;
}
if (amount > count)
amount = count;
T maxVal = MIN_VAL;
T value;
for (size_t i = 0; i < amount; i++) {
value = get(count - 1 - i);
if (value > maxVal && value != MAX_VAL) {
maxVal = value;
}
}
return maxVal;
}
// Get mid value between <min> and <max> value in the buffer
template <typename T>
T RingBuffer<T>::getMid() const
{
if (isEmpty()) {
return MAX_VAL;
}
return (getMin() + getMax()) / static_cast<T>(2);
}
// Get mid value between <min> and <max> value of the last <amount> values of buffer
template <typename T>
T RingBuffer<T>::getMid(size_t amount) const
{
if (isEmpty() || amount <= 0) {
return MAX_VAL;
}
if (amount > count)
amount = count;
return (getMin(amount) + getMax(amount)) / static_cast<T>(2);
}
// Get the median value in the buffer
template <typename T>
T RingBuffer<T>::getMedian() const
{
if (isEmpty()) {
return MAX_VAL;
}
// Create a temporary vector with current valid elements
std::vector<T> temp;
temp.reserve(count);
for (size_t i = 0; i < count; i++) {
temp.push_back(get(i));
}
// Sort to find median
std::sort(temp.begin(), temp.end());
if (count % 2 == 1) {
// Odd number of elements
return temp[count / 2];
} else {
// Even number of elements - return average of middle two
// Note: For integer types, this truncates. For floating point, it's exact.
return (temp[count / 2 - 1] + temp[count / 2]) / 2;
}
}
// Get the median value of the last <amount> values of buffer
template <typename T>
T RingBuffer<T>::getMedian(size_t amount) const
{
if (isEmpty() || amount <= 0) {
return MAX_VAL;
}
if (amount > count)
amount = count;
// Create a temporary vector with current valid elements
std::vector<T> temp;
temp.reserve(amount);
for (size_t i = 0; i < amount; i++) {
temp.push_back(get(i));
}
// Sort to find median
std::sort(temp.begin(), temp.end());
if (amount % 2 == 1) {
// Odd number of elements
return temp[amount / 2];
} else {
// Even number of elements - return average of middle two
// Note: For integer types, this truncates. For floating point, it's exact.
return (temp[amount / 2 - 1] + temp[amount / 2]) / 2;
}
}
// Get the buffer capacity (maximum size)
template <typename T>
size_t RingBuffer<T>::getCapacity() const
{
return capacity;
}
// Get the current number of elements in the buffer
template <typename T>
size_t RingBuffer<T>::getCurrentSize() const
{
return count;
}
// Get the first index of buffer
template <typename T>
size_t RingBuffer<T>::getFirstIdx() const
{
return first;
}
// Get the last index of buffer
template <typename T>
size_t RingBuffer<T>::getLastIdx() const
{
return last;
}
// Check if buffer is empty
template <typename T>
bool RingBuffer<T>::isEmpty() const
{
return count == 0;
}
// Check if buffer is full
template <typename T>
bool RingBuffer<T>::isFull() const
{
return is_Full;
}
// Get lowest possible value for buffer
template <typename T>
T RingBuffer<T>::getMinVal() const
{
return MIN_VAL;
}
// Get highest possible value for buffer; used for unset/invalid buffer data
template <typename T>
T RingBuffer<T>::getMaxVal() const
{
return MAX_VAL;
}
// Clear buffer
template <typename T>
void RingBuffer<T>::clear()
{
GWSYNCHRONIZED(&bufLocker);
head = 0;
first = 0;
last = 0;
count = 0;
is_Full = false;
}
// Delete buffer and set new size
template <typename T>
void RingBuffer<T>::resize(size_t newSize)
{
GWSYNCHRONIZED(&bufLocker);
capacity = newSize;
head = 0;
first = 0;
last = 0;
count = 0;
is_Full = false;
buffer.clear();
buffer.resize(newSize, MAX_VAL);
}
// Get all current values as a vector
template <typename T>
std::vector<T> RingBuffer<T>::getAllValues() const
{
std::vector<T> result;
result.reserve(count);
for (size_t i = 0; i < count; i++) {
result.push_back(get(i));
}
return result;
}

View File

@@ -1,90 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
#include <WiFi.h>
#include <PubSubClient.h>
#include "OBPTrackerTask.h"
/*
Regatta Hero: use PubSubClient preferred over MQTTClient. Less
functionality but smaller and easier.
JSON-data to send to server:
Payload = {
"passcode": "[code]",
"orgid": "[orgname]",
"raceid": "[raceid]",
"gps": {
"lat": 47.823938240041436,
"lon": 8.1386857025205,
"speed": 5.5,
"odo": 1000,
"age": 1000,
"bat": 0.7,
"timestamp": "2011-10-05T14:48:00.000Z"
},
"boat": {
"boatid": "c32d8b45-92fe-44f6-8b61-42c2107dfe45",
"sailno": "GER 11",
"team": "OBP60team",
"boatclass": "One off",
"handicap": 114.0,
"club": "BSC",
"boatname": "Delfin"
}
}
mqttClient.state()
*/
void mqttCallback(char *topic, byte *payload, unsigned int length) {
if (String(topic) == "hero/race") {
}
}
void trackerTask(void *param) {
TrackerData *data = (TrackerData *)param;
// TCP client connection is needed
GwApi::Status status;
data->api->getStatus(status);
if (status.wifiClientConnected) {
data->logger->logDebug(GwLog::ERROR, "No WiFi connection. Cannot start tracker task.");
vTaskDelete(NULL);
}
WiFiClient wificlient;
PubSubClient mqtt(wificlient);
String broker = "mqtt.regattahero.com";
String mqttUsername = "obp60";
String mqttPassword = "23qwecv";
// String mqttClientID = generateClientID();
mqtt.setServer(broker.c_str(), 1883);
mqtt.setBufferSize(2048); // Erhöht die maximale Payload-Größe auf 512 Bytes *** TODO WTF?
mqtt.setCallback(mqttCallback);
// mqtt.connect(mqttClientID.c_str(), mqttUsername.c_str(), mqttPassword.c_str())
String subRaceStatus = "regattahero/racestatus/[orgname]/#";
// mqtt.subscribe(subRaceStatus.c_str());
String subOrgStatus = "regattahero/orgstatus/[orgname]/#";
// mqtt.subscribe(subOrgStatus.c_str());
while (true) {
delay(1000); // Loop time one second
}
vTaskDelete(NULL);
}
void createTrackerTask(TrackerData *param) {
TaskHandle_t xHandle = NULL;
if (xTaskCreate(trackerTask, "tracker", configMINIMAL_STACK_SIZE + 2048, param, configMAX_PRIORITIES-1, &xHandle)) {
param->logger->logDebug(GwLog::ERROR, "Failed to create tracker task!");
}
}
#endif

View File

@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "GwApi.h"
typedef struct {
GwApi *api = nullptr;
GwLog *logger = nullptr;
} TrackerData;
void createTrackerTask(TrackerData *param);

View File

@@ -5,7 +5,7 @@
class PageBattery : public Page
{
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
public:
PageBattery(CommonData &common){

View File

@@ -120,7 +120,7 @@ bool homevalid = false; // homelat and homelon are valid
}
else{
value1 = simtime++; // Simulation data for time value 11:36 in seconds
} // Other simulation data see OBP60Formatter.cpp
} // 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

View File

@@ -83,7 +83,7 @@ class PageCompass : public Page
String DataText[HowManyValues];
String DataUnits[HowManyValues];
String DataFormat[HowManyValues];
FormattedData TheFormattedData;
FormatedData TheFormattedData;
for (int i = 0; i < HowManyValues; i++){
bvalue = pageData.values[i];

View File

@@ -53,7 +53,7 @@ class PageFourValues : public Page
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
// Get boat values #2
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
String name2 = xdrDelete(bvalue2->getName()); // Value name
name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
@@ -63,7 +63,7 @@ class PageFourValues : public Page
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
// Get boat values #3
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
String name3 = xdrDelete(bvalue3->getName()); // Value name
name3 = name3.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
@@ -73,7 +73,7 @@ class PageFourValues : public Page
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
// Get boat values #4
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
String name4 = xdrDelete(bvalue4->getName()); // Value name
name4 = name4.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
@@ -301,7 +301,7 @@ static Page *createPage(CommonData &common){
* this will be number of BoatValue pointers in pageData.values
*/
PageDescription registerPageFourValues(
"FourValues", // Page name
"FourValues", // Page name
createPage, // Action
4, // Number of bus values depends on selection in Web configuration
true // Show display header on/off

View File

@@ -86,20 +86,21 @@ public:
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
const char *ii = " ";
switch (i) {
case 0: ii=" "; break; // Use a blank for a empty scale value
case 30 : ii=" "; break;
case 60 : ii=" "; break;
case 90 : ii="45"; break;
case 120 : ii="30"; break;
case 150 : ii="15"; break;
case 180 : ii="0"; break;
case 210 : ii="15"; break;
case 240 : ii="30"; break;
case 270 : ii="45"; break;
case 300 : ii=" "; break;
case 330 : ii=" "; break;
default: break;
switch (i)
{
case 0: ii=" "; break; // Use a blank for a empty scale value
case 30 : ii=" "; break;
case 60 : ii=" "; break;
case 90 : ii="45"; break;
case 120 : ii="30"; break;
case 150 : ii="15"; break;
case 180 : ii="0"; break;
case 210 : ii="15"; break;
case 240 : ii="30"; break;
case 270 : ii="45"; break;
case 300 : ii=" "; break;
case 330 : ii=" "; break;
default: break;
}
// Print text centered on position x, y

View File

@@ -41,9 +41,9 @@ public:
String backlightMode = config->getString(config->backlight);
int rolllimit = config->getInt(config->rollLimit);
String roffset = config->getString(config->rollOffset);
double rolloffset = roffset.toFloat()/360*(2*M_PI);
double rolloffset = roffset.toFloat()/360*(2*PI);
String poffset = config->getString(config->pitchOffset);
double pitchoffset = poffset.toFloat()/360*(2*M_PI);
double pitchoffset = poffset.toFloat()/360*(2*PI);
// Get boat values for roll
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (xdrRoll)
@@ -55,17 +55,17 @@ public:
}
else{
if(simulation == true){
value1 = (20 + float(random(0, 50)) / 10.0)/360*2*M_PI;
value1 = (20 + float(random(0, 50)) / 10.0)/360*2*PI;
}
else{
value1 = 0;
}
}
if(value1/(2*M_PI)*360 > -10 && value1/(2*M_PI)*360 < 10){
svalue1 = String(value1/(2*M_PI)*360,1); // Convert raw value to string
if(value1/(2*PI)*360 > -10 && value1/(2*PI)*360 < 10){
svalue1 = String(value1/(2*PI)*360,1); // Convert raw value to string
}
else{
svalue1 = String(value1/(2*M_PI)*360,0);
svalue1 = String(value1/(2*PI)*360,0);
}
if(valid1 == true){
svalue1old = svalue1; // Save the old value
@@ -80,17 +80,17 @@ public:
}
else{
if(simulation == true){
value2 = (float(random(-5, 5)))/360*2*M_PI;
value2 = (float(random(-5, 5)))/360*2*PI;
}
else{
value2 = 0;
}
}
if(value2/(2*PI)*360 > -10 && value2/(2*M_PI)*360 < 10){
svalue2 = String(value2/(2*M_PI)*360,1); // Convert raw value to string
if(value2/(2*PI)*360 > -10 && value2/(2*PI)*360 < 10){
svalue2 = String(value2/(2*PI)*360,1); // Convert raw value to string
}
else{
svalue2 = String(value2/(2*M_PI)*360,0);
svalue2 = String(value2/(2*PI)*360,0);
}
if(valid2 == true){
svalue2old = svalue2; // Save the old value
@@ -99,7 +99,7 @@ public:
// Optical warning by limit violation
if(String(flashLED) == "Limit Violation"){
// Limits for roll
if(value1*360/(2*M_PI) >= -1*rolllimit && value1*360/(2*M_PI) <= rolllimit){
if(value1*360/(2*PI) >= -1*rolllimit && value1*360/(2*PI) <= rolllimit){
setBlinkingLED(false);
setFlashLED(false);
}
@@ -177,18 +177,19 @@ public:
// Only scaling +/- 60 degrees
if((i >= 0 && i <= 60) || (i >= 300 && i <= 360)){
// Scaling values
float x = 200 + (rInstrument+25)*sin(i/180.0*M_PI); // x-coordinate dots
float y = 150 - (rInstrument+25)*cos(i/180.0*M_PI); // y-coordinate cots
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
const char *ii = "";
switch (i) {
case 0: ii="0"; break;
case 20 : ii="20"; break;
case 40 : ii="40"; break;
case 60 : ii="60"; break;
case 300 : ii="60"; break;
case 320 : ii="40"; break;
case 340 : ii="20"; break;
default: break;
switch (i)
{
case 0: ii="0"; break;
case 20 : ii="20"; break;
case 40 : ii="40"; break;
case 60 : ii="60"; break;
case 300 : ii="60"; break;
case 320 : ii="40"; break;
case 340 : ii="20"; break;
default: break;
}
// Print text centered on position x, y
@@ -202,11 +203,11 @@ public:
}
// Draw sub scale with dots
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
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, commonData->fgcolor);
float sinx=sin(i/180.0*M_PI);
float cosx=cos(i/180.0*M_PI);
float sinx=sin(i/180.0*pi);
float cosx=cos(i/180.0*pi);
// Draw sub scale with lines (two triangles)
if(i % 20 == 0){
@@ -228,11 +229,11 @@ public:
// Draw mast position pointer
float startwidth = 8; // Start width of pointer
// value1 = (2 * M_PI ) - value1; // Mirror coordiante system for pointer, keel and boat
// value1 = (2 * pi ) - value1; // Mirror coordiante system for pointer, keel and boat
if(valid1 == true || holdvalues == true || simulation == true){
float sinx=sin(value1 + M_PI);
float cosx=cos(value1 + M_PI);
float sinx=sin(value1 + pi);
float cosx=cos(value1 + pi);
// Normal pointer
// Pointer as triangle with center base 2*width
float xx1 = -startwidth;

View File

@@ -1,200 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include <vector>
#include <algorithm> // for vector sorting
/*
* SkyView / Satellites
*/
class PageSkyView : public Page
{
private:
String flashLED;
GwBoatData *bd;
public:
PageSkyView(CommonData &common)
{
commonData = &common;
// task name access is for example purpose only
TaskHandle_t currentTaskHandle = xTaskGetCurrentTaskHandle();
const char* taskName = pcTaskGetName(currentTaskHandle);
common.logger->logDebug(GwLog::LOG, "Instantiate PageSkyView in task '%s'", taskName);
flashLED = common.config->getString(common.config->flashLED);
}
int handleKey(int key) {
// return 0 to mark the key handled completely
// return the key to allow further action
if (key == 11) {
commonData->keylock = !commonData->keylock;
return 0;
}
return key;
}
void displayNew(PageData &pageData) {
#ifdef BOARD_OBP60S3
// Clear optical warning
if (flashLED == "Limit Violation") {
setBlinkingLED(false);
setFlashLED(false);
}
#endif
bd = pageData.api->getBoatData();
};
// Comparator function to sort by SNR
static bool compareBySNR(const GwSatInfo& a, const GwSatInfo& b) {
return a.SNR > b.SNR; // Sort in descending order
}
int displayPage(PageData &pageData) {
GwLog *logger = commonData->logger;
std::vector<GwSatInfo> sats;
int nSat = bd->SatInfo->getNumSats();
logger->logDebug(GwLog::LOG, "Drawing at PageSkyView, %d satellites", nSat);
for (int i = 0; i < nSat; i++) {
sats.push_back(*bd->SatInfo->getAt(i));
}
std::sort(sats.begin(), sats.end(), compareBySNR);
// Draw page
//***********************************************************
// Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
// current position
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// sky view
Point c = {130, 148};
uint16_t r = 120;
uint16_t r1 = r / 2;
getdisplay().fillCircle(c.x, c.y, r + 2, commonData->fgcolor);
getdisplay().fillCircle(c.x, c.y, r - 1, commonData->bgcolor);
getdisplay().drawCircle(c.x, c.y, r1, commonData->fgcolor);
// separation lines
getdisplay().drawLine(c.x - r, c.y, c.x + r, c.y, commonData->fgcolor);
getdisplay().drawLine(c.x, c.y - r, c.x, c.y + r, commonData->fgcolor);
Point p = {c.x, c.y - r};
Point p1, p2;
p1 = rotatePoint(c, p, 45);
p2 = rotatePoint(c, p, 45 + 180);
getdisplay().drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
p1 = rotatePoint(c, p, -45);
p2 = rotatePoint(c, p, -45 + 180);
getdisplay().drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
// directions
int16_t x1, y1;
uint16_t w, h;
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().getTextBounds("N", 0, 150, &x1, &y1, &w, &h);
getdisplay().setCursor(c.x - w / 2, c.y - r + h + 3);
getdisplay().print("N");
getdisplay().getTextBounds("S", 0, 150, &x1, &y1, &w, &h);
getdisplay().setCursor(c.x - w / 2, c.y + r - 3);
getdisplay().print("S");
getdisplay().getTextBounds("E", 0, 150, &x1, &y1, &w, &h);
getdisplay().setCursor(c.x + r - w - 3, c.y + h / 2);
getdisplay().print("E");
getdisplay().getTextBounds("W", 0, 150, &x1, &y1, &w, &h);
getdisplay().setCursor(c.x - r + 3 , c.y + h / 2);
getdisplay().print("W");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// show satellites in "map"
for (int i = 0; i < nSat; i++) {
float arad = (sats[i].Azimut * M_PI / 180.0) + M_PI;
float erad = sats[i].Elevation * M_PI / 180.0;
uint16_t x = c.x + sin(arad) * erad * r1;
uint16_t y = c.y + cos(arad) * erad * r1;
getdisplay().fillRect(x-4, y-4, 8, 8, commonData->fgcolor);
}
// Signal / Noise bars
getdisplay().setCursor(325, 34);
getdisplay().print("SNR");
// getdisplay().drawRect(270, 20, 125, 257, commonData->fgcolor);
int maxsat = std::min(nSat, 12);
for (int i = 0; i < maxsat; i++) {
uint16_t y = 29 + (i + 1) * 20;
getdisplay().setCursor(276, y);
char buffer[3];
snprintf(buffer, 3, "%02d", static_cast<int>(sats[i].PRN));
getdisplay().print(String(buffer));
getdisplay().drawRect(305, y-12, 85, 14, commonData->fgcolor);
getdisplay().setCursor(315, y);
// TODO SNR as number or as bar via mode key?
if (sats[i].SNR <= 100) {
// getdisplay().print(sats[i].SNR);
getdisplay().fillRect(307, y-10, int(81 * sats[i].SNR / 100.0), 10, commonData->fgcolor);
} else {
getdisplay().print("n/a");
}
}
// Show SatInfo and HDOP
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(220, 34);
getdisplay().print("Sat:");
GwApi::BoatValue *bv_satinfo = pageData.values[0]; // SatInfo
String sval_satinfo = formatValue(bv_satinfo, *commonData).svalue;
getdisplay().setCursor(220, 49);
getdisplay().print(sval_satinfo);
getdisplay().setCursor(220, 254);
getdisplay().print("HDOP:");
GwApi::BoatValue *bv_hdop = pageData.values[1]; // HDOP
String sval_hdop = formatValue(bv_hdop, *commonData).svalue;
sval_hdop = sval_hdop + "m";
getdisplay().setCursor(220, 269);
getdisplay().print(sval_hdop);
return PAGE_UPDATE;
};
};
static Page* createPage(CommonData &common){
return new PageSkyView(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
* this will be number of BoatValue pointers in pageData.values
*/
PageDescription registerPageSkyView(
"SkyView", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{"SatInfo", "HDOP"}, // Bus values we need in the page
true // Show display header on/off
);
#endif

View File

@@ -1,25 +1,11 @@
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
/*
* Special system page, called directly with fast key sequence 5,4
* Out of normal page order.
* Consists of some sub-pages with following content:
* 1. Hard and software information
* 2. System settings
* 3. NMEA2000 device list
* 4. SD Card information if available
*/
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "images/logo64.xbm"
#include <esp32/clk.h>
#include "qrcode.h"
#ifdef BOARD_OBP40S3
#include "dirent.h"
#endif
#define STRINGIZE_IMPL(x) #x
#define STRINGIZE(x) STRINGIZE_IMPL(x)
#define VERSINFO STRINGIZE(GWDEVVERSION)
@@ -28,27 +14,35 @@
#define DISPLAYINFO STRINGIZE(EPDTYPE)
#define GXEPD2INFO STRINGIZE(GXEPD2VERS)
/*
* Special system page, called directly with fast key sequence 5,4
* Out of normal page order.
* Consists of some sub-pages with following content:
* 1. Hard and software information
* 2. System settings
* 3. NMEA2000 device list
*/
class PageSystem : public Page
{
private:
uint64_t chipid;
bool simulation;
bool use_sdcard;
String buzzer_mode;
uint8_t buzzer_power;
String cpuspeed;
String rtc_module;
String gps_module;
String env_module;
uint64_t chipid;
bool simulation;
bool sdcard;
String buzzer_mode;
uint8_t buzzer_power;
String cpuspeed;
String rtc_module;
String gps_module;
String env_module;
String batt_sensor;
String solar_sensor;
String gen_sensor;
String rot_sensor;
double homelat;
double homelon;
String batt_sensor;
String solar_sensor;
String gen_sensor;
String rot_sensor;
double homelat;
double homelon;
char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard
char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard
public:
PageSystem(CommonData &common){
@@ -56,12 +50,11 @@ public:
common.logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
if (hasFRAM) {
mode = fram.read(FRAM_SYSTEM_MODE);
common.logger->logDebug(GwLog::DEBUG, "Loaded mode '%c' from FRAM", mode);
}
chipid = ESP.getEfuseMac();
simulation = common.config->getBool(common.config->useSimuData);
#ifdef BOARD_OBP40S3
use_sdcard = common.config->getBool(common.config->useSDCard);
sdcard = common.config->getBool(common.config->useSDCard);
#endif
buzzer_mode = common.config->getString(common.config->buzzerMode);
buzzer_mode.toLowerCase();
@@ -78,7 +71,7 @@ public:
homelon = common.config->getString(common.config->homeLON).toDouble();
}
void setupKeys() {
virtual void setupKeys(){
commonData->keydata[0].label = "EXIT";
commonData->keydata[1].label = "MODE";
commonData->keydata[2].label = "";
@@ -87,7 +80,7 @@ public:
commonData->keydata[5].label = "ILUM";
}
int handleKey(int key) {
virtual int handleKey(int key){
// do *NOT* handle key #1 this handled by obp60task as exit
// Switch display mode
commonData->logger->logDebug(GwLog::LOG, "System keyboard handler");
@@ -97,7 +90,7 @@ public:
} else if (mode == 'S') {
mode = 'D';
} else if (mode == 'D') {
if (hasSDCard) {
if (sdcard) {
mode = 'C';
} else {
mode = 'N';
@@ -119,8 +112,7 @@ public:
}
// standby / deep sleep
if (key == 5) {
commonData->logger->logDebug(GwLog::LOG, "System going into deep sleep mode...");
deepSleep(*commonData);
deepSleep(*commonData);
}
// Code for keylock
if (key == 11) {
@@ -135,7 +127,6 @@ public:
}
// standby / deep sleep
if (key == 12) {
commonData->logger->logDebug(GwLog::LOG, "System going into deep sleep mode...");
deepSleep(*commonData);
}
#endif
@@ -182,7 +173,7 @@ public:
}
// Logging boat values
logger->logDebug(GwLog::LOG, "Drawing at PageSystem, Mode=%c", mode);
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem");
// Draw page
//***********************************************************
@@ -261,37 +252,9 @@ public:
getdisplay().setCursor(8, y0 + 48);
getdisplay().print("SD-Card:");
getdisplay().setCursor(90, y0 + 48);
if (hasSDCard) {
uint64_t cardsize = ((uint64_t) sdcard->csd.capacity) * sdcard->csd.sector_size / (1024 * 1024);
getdisplay().printf("%llu MB", cardsize);
} else {
getdisplay().print("off");
}
getdisplay().print(hasSDcard ? "ok" : "no");
#endif
// Uptime
int64_t uptime = esp_timer_get_time() / 1000000;
String uptime_unit;
if (uptime < 120) {
uptime_unit = " seconds";
} else {
if (uptime < 2 * 3600) {
uptime /= 60;
uptime_unit = " minutes";
} else if (uptime < 2 * 3600 * 24) {
uptime /= 3600;
uptime_unit = " hours";
} else {
uptime /= 86400;
uptime_unit = " days";
}
}
getdisplay().setCursor(8, y0 + 80);
getdisplay().print("Uptime:");
getdisplay().setCursor(90, y0 + 80);
getdisplay().print(uptime);
getdisplay().print(uptime_unit);
// CPU speed config / active
getdisplay().setCursor(202, y0);
getdisplay().print("CPU speed:");
@@ -398,62 +361,8 @@ public:
x0 = 20;
y0 = 72;
getdisplay().setCursor(x0, y0);
#ifdef BOARD_OBP60S3
// This mode should not be callable by devices without card hardware
// In case of accidential reaching this, display a friendly message
getdisplay().print("This mode is not indended to be reached!\n");
getdisplay().print("There's nothing to see here. Move on.");
#endif
#ifdef BOARD_OBP40S3
getdisplay().print("Work in progress...");
/* TODO
this code should go somewhere else. only for testing purposes here
identify card as OBP-Card:
magic.dat
version.dat
readme.txt
IMAGES/
CHARTS/
LOGS/
DATA/
hint: file access with fopen, fgets, fread, fclose
*/
// Simple test for magic file in root
getdisplay().setCursor(x0, y0 + 32);
String file_magic = MOUNT_POINT "/magic.dat";
logger->logDebug(GwLog::LOG, "Test magicfile: %s", file_magic.c_str());
struct stat st;
if (stat(file_magic.c_str(), &st) == 0) {
getdisplay().printf("File %s exists", file_magic.c_str());
} else {
getdisplay().printf("File %s not found", file_magic.c_str());
}
// Root directory check
DIR* dir = opendir(MOUNT_POINT);
int dy = 0;
if (dir != NULL) {
logger->logDebug(GwLog::LOG, "Root directory: %s", MOUNT_POINT);
struct dirent* entry;
while (((entry = readdir(dir)) != NULL) and (dy < 140)) {
getdisplay().setCursor(x0, y0 + 64 + dy);
getdisplay().print(entry->d_name);
// type 1 is file, type 2 is dir
if (entry->d_type == 2) {
getdisplay().print("/");
}
dy += 20;
logger->logDebug(GwLog::DEBUG, " %s type %d", entry->d_name, entry->d_type);
}
closedir(dir);
} else {
logger->logDebug(GwLog::LOG, "Failed to open root directory");
}
#endif
} else {
// NMEA2000 device list
getdisplay().setFont(&Ubuntu_Bold12pt8b);

View File

@@ -51,7 +51,7 @@ class PageThreeValues : public Page
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
// Get boat values #2
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
String name2 = xdrDelete(bvalue2->getName()); // Value name
name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
@@ -61,7 +61,7 @@ class PageThreeValues : public Page
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
// Get boat values #3
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
String name3 = xdrDelete(bvalue3->getName()); // Value name
name3 = name3.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated

View File

@@ -1,284 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
/*
Tracker
- standalone with SD card backend
- standalone with server backend
- Regatta Hero integration
In start phase big timer.
Eventually after start other display because timer not needed any
more. Race timer smaller on top right corner. Reserved space for
message area.
4 Positions for flags
+-----+-----+
| 1 | 2 |
+-----+-----+
| 3 | 4 |
+-----+-----+
*/
#include "Pagedata.h"
#include "OBP60Extensions.h"
// Flags
#include "images/alpha.xbm"
#include "images/answer.xbm"
#include "images/black.xbm"
#include "images/blue.xbm"
#include "images/charlie.xbm"
#include "images/class.xbm"
#include "images/finish.xbm"
#include "images/hotel.xbm"
#include "images/india.xbm"
#include "images/november.xbm"
#include "images/orange.xbm"
#include "images/papa.xbm"
#include "images/repeat_one.xbm"
#include "images/sierra.xbm"
#include "images/start.xbm"
#include "images/uniform.xbm"
#include "images/xray.xbm"
#include "images/yankee.xbm"
#include "images/zulu.xbm"
class PageTracker : public Page
{
private:
char mode = 'N'; // (N)ormal, (C)onfig
bool simulation = false;
String flashLED;
String trackerType;
String trackerOrganisation;
String trackerTeam;
String sailClub;
String boatName;
String boatClass;
String boatSailNumber;
float boatHandicap;
void displayModeNormal(PageData &pageData) {
// TBD Boatvalues: ...
// Title
/* getdisplay().setTextColor(commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(8, 48);
getdisplay().print("Tracker"); */
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(8, 42);
if (trackerType == "NONE") {
getdisplay().print("Disabled!");
} else {
getdisplay().print(trackerType);
}
// Timer
getdisplay().setCursor(16, 120);
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
getdisplay().print("-00:00");
getdisplay().drawXBitmap(4, 140, class_bits, class_width, class_height, commonData->fgcolor);
getdisplay().drawXBitmap(102, 140, start_bits, start_width, start_height, commonData->fgcolor);
getdisplay().drawXBitmap(202, 140, finish_bits, finish_width, finish_height, commonData->fgcolor);
getdisplay().drawXBitmap(4, 210, alpha_bits, alpha_width, alpha_height, commonData->fgcolor);
getdisplay().drawXBitmap(102, 210, answer_bits, answer_width, answer_height, commonData->fgcolor);
getdisplay().drawXBitmap(202, 210, papa_bits, papa_width, papa_height, commonData->fgcolor);
getdisplay().drawXBitmap(302, 210, yankee_bits, yankee_width, yankee_height, commonData->fgcolor);
}
void displayModeConfig() {
uint16_t x0 = 8; // left label column
uint16_t x1 = 112; // data starts here
uint16_t y0 = 48;
getdisplay().setTextColor(commonData->fgcolor);
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(x0, 48);
getdisplay().print("Tracker configuration");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// Boat data left column
getdisplay().setFont(&Ubuntu_Bold10pt8b);
getdisplay().setCursor(x0, 75);
getdisplay().print("Boat data");
y0 = 96;
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(x0, y0);
getdisplay().print("Boat name");
getdisplay().setCursor(x1, y0);
getdisplay().print(boatName);
getdisplay().setCursor(x0, y0 + 16);
getdisplay().print("Boat class");
getdisplay().setCursor(x1, y0 + 16);
getdisplay().print(boatClass);
getdisplay().setCursor(x0, y0 + 32);
getdisplay().print("Handicap");
getdisplay().setCursor(x1, y0 + 32);
getdisplay().print(boatHandicap, 1);
getdisplay().setCursor(x0, y0 + 48);
getdisplay().print("Sail club");
getdisplay().setCursor(x1, y0 + 48);
getdisplay().print(sailClub);
getdisplay().setCursor(x0, y0 + 64);
getdisplay().print("Sail number");
getdisplay().setCursor(x1, y0 + 64);
getdisplay().print(boatSailNumber);
// Tracker data, right column
x0 = 208;
x1 = 304;
getdisplay().setFont(&Ubuntu_Bold10pt8b);
getdisplay().setCursor(x0, 75);
getdisplay().print("Tracker info");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(x0, y0);
getdisplay().print("Status");
getdisplay().setCursor(x1, y0);
if (trackerType == "NONE") {
getdisplay().print("Disabled");
} else {
getdisplay().printf("Type: %s", trackerType);
}
getdisplay().setCursor(x0, y0 + 16);
getdisplay().print("Org.");
getdisplay().setCursor(x1, y0 + 16);
getdisplay().print(trackerOrganisation);
getdisplay().setCursor(x0, y0 + 32);
getdisplay().print("Team");
getdisplay().setCursor(x1, y0 + 32);
getdisplay().print(trackerTeam);
// Ragatta selection
y0 = 180;
getdisplay().setFont(&Ubuntu_Bold10pt8b);
getdisplay().setCursor(x0, y0);
getdisplay().print("Regattas");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
// A) Regatta Hero:
// Server Hostname, IP, Port
// Organisation
// Boat name
//
// B) SD-Card: check if card available
// log interval: via config in seconds. min=?
// C) Server: e.g. Raspi in Boat WLAN, own Internet-Server
// display connection state to server here
}
public:
PageTracker(CommonData &common)
{
commonData = &common;
common.logger->logDebug(GwLog::LOG, "Instantiate PageTracker");
flashLED = common.config->getString(common.config->flashLED);
simulation = common.config->getBool(common.config->useSimuData);
trackerType = common.config->getString(common.config->trackerType);
trackerOrganisation = common.config->getString(common.config->trackerOrg);
trackerTeam = common.config->getString(common.config->trackerTeam);
boatName = common.config->getString(common.config->boatName);
boatClass = common.config->getString(common.config->boatClass);
boatSailNumber = common.config->getString(common.config->boatSailnumber);
sailClub = common.config->getString(common.config->sailClub);
boatHandicap = common.config->getString(common.config->boatHandicap).toFloat();
}
void setupKeys(){
Page::setupKeys();
commonData->keydata[0].label = "MODE";
}
int handleKey(int key){
if (key == 1) { // Switch between normal and config mode
if (mode == 'N') {
mode = 'C';
} else {
mode = 'N';
}
return 0;
}
if (key == 11) {
commonData->keylock = !commonData->keylock;
return 0;
}
return key;
}
void displayNew(PageData &pageData) {
#ifdef BOARD_OBP60S3
// Clear optical warning
if (flashLED == "Limit Violation") {
setBlinkingLED(false);
setFlashLED(false);
}
#endif
};
int displayPage(PageData &pageData){
GwLog *logger = commonData->logger;
// Logging boat values
logger->logDebug(GwLog::LOG, "Drawing at PageTracker; Mode=%c", mode);
// Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0,getdisplay().width(), getdisplay().height());
if (mode == 'N') {
displayModeNormal(pageData);
} else if (mode == 'C') {
displayModeConfig();
}
return PAGE_UPDATE;
};
};
static Page *createPage(CommonData &common){
return new PageTracker(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
* this will be number of BoatValue pointers in pageData.values
*/
PageDescription registerPageTracker(
"Tracker", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{"LAT", "LON", "SOG"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
true // Show display header on/off
);
#endif

View File

@@ -49,7 +49,7 @@ class PageTwoValues : public Page
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
// Get boat values #2
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
String name2 = xdrDelete(bvalue2->getName()); // Value name
name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated

View File

@@ -398,11 +398,11 @@ static Page *createPage(CommonData &common){
* and will will provide the names of the fixed values we need
*/
PageDescription registerPageVoltage(
"Voltage", // Name of page
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
true // Show display header on/off
"Voltage", // Name of page
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
true // Show display header on/off
);
#endif

View File

@@ -2,14 +2,8 @@
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "images/OBP_400x300.xbm" // OBP Logo
#ifdef BOARD_OBP60S3
#include "images/OBP60_400x300.xbm" // MFD with logo
#endif
#ifdef BOARD_OBP40S3
#include "images/OBP40_400x300.xbm" // MFD with logo
#endif
#include "MFD_OBP60_400x300_sw.h" // MFD with logo
#include "Logo_OBP_400x300_sw.h" // OBP Logo
class PageWhite : public Page
{
@@ -67,21 +61,20 @@ public:
}
if (mode == 'L') {
getdisplay().drawXBitmap(0, 0, OBP_400x300_bits, OBP_400x300_width, OBP_400x300_height, commonData->fgcolor);
getdisplay().drawBitmap(0, 0, gImage_Logo_OBP_400x300_sw, getdisplay().width(), getdisplay().height(), commonData->fgcolor);
} else if (mode == 'M') {
#ifdef BOARD_OBP60S3
getdisplay().drawXBitmap(0, 0, OBP60_400x300_bits, OBP60_400x300_width, OBP60_400x300_height, commonData->fgcolor);
#endif
#ifdef BOARD_OBP40S3
getdisplay().drawXBitmap(0, 0, OBP40_400x300_bits, OBP40_400x300_width, OBP40_400x300_height, commonData->fgcolor);
#endif
getdisplay().drawBitmap(0, 0, gImage_MFD_OBP60_400x300_sw, getdisplay().width(), getdisplay().height(), commonData->fgcolor);
}
// Update display
// getdisplay().nextPage();
int ret = PAGE_UPDATE;
if (mode == 'W') {
//getdisplay().hibernate();
ret |= PAGE_HIBERNATE;
}
return ret;
};
};

View File

@@ -633,11 +633,11 @@ static Page *createPage(CommonData &common){
* 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
"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
true // Show display header on/off
);
#endif

View File

@@ -1,527 +0,0 @@
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
#include "Pagedata.h"
#include "OBP60Extensions.h"
#include "OBPRingBuffer.h"
#include "OBPDataOperations.h"
#include "BoatDataCalibration.h"
#include <vector>
static const double radToDeg = 180.0 / M_PI; // Conversion factor from radians to degrees
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart; returns "0" if data is not valid
int getCntr(const RingBuffer<int16_t>& windDirHstry, size_t amount)
{
const int MAX_VAL = windDirHstry.getMaxVal();
size_t count = windDirHstry.getCurrentSize();
if (windDirHstry.isEmpty() || amount <= 0) {
return 0;
}
if (amount > count)
amount = count;
uint16_t midWndDir, minWndDir, maxWndDir = 0;
int wndCenter = 0;
midWndDir = windDirHstry.getMid(amount);
if (midWndDir != MAX_VAL) {
midWndDir = midWndDir / 1000.0 * radToDeg;
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
minWndDir = windDirHstry.getMin(amount) / 1000.0 * radToDeg;
maxWndDir = windDirHstry.getMax(amount) / 1000.0 * radToDeg;
if ((maxWndDir - minWndDir) > 180 && !(minWndDir > maxWndDir)) { // if wind range is > 180 and no 0° crossover, adjust wndCenter to smaller wind range end
wndCenter = WindUtils::to360(wndCenter + 180);
}
}
return wndCenter;
}
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart
int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
{
int minVal = windDirHstry.getMinVal();
const int MAX_VAL = windDirHstry.getMaxVal();
size_t count = windDirHstry.getCurrentSize();
if (windDirHstry.isEmpty() || amount <= 0) {
return MAX_VAL;
}
if (amount > count)
amount = count;
int value = 0;
int rng = 0;
int maxRng = minVal;
// Start from the newest value (last) and go backwards x times
for (size_t i = 0; i < amount; i++) {
value = windDirHstry.get(count - 1 - i);
if (value == MAX_VAL) {
continue; // ignore invalid values
}
value = value / 1000.0 * radToDeg;
rng = abs(((value - center + 540) % 360) - 180);
if (rng > maxRng)
maxRng = rng;
}
if (maxRng > 180) {
maxRng = 180;
}
return (maxRng != minVal ? maxRng : MAX_VAL);
}
// ****************************************************************
class PageWindPlot : public Page {
bool keylock = false; // Keylock
char chrtMode = 'D'; // Chart mode: 'D' for TWD, 'S' for TWS, 'B' for both
bool showTruW = true; // Show true wind or apparant wind in chart area
bool oldShowTruW = false; // remember recent user selection of wind data type
int dataIntv = 1; // Update interval for wind history chart:
// (1)|(2)|(3)|(4) seconds for approx. 4, 8, 12, 16 min. history chart
bool useSimuData;
String flashLED;
String backlightMode;
public:
PageWindPlot(CommonData& common)
{
commonData = &common;
common.logger->logDebug(GwLog::LOG, "Instantiate PageWindPlot");
// Get config data
useSimuData = common.config->getBool(common.config->useSimuData);
// holdValues = common.config->getBool(common.config->holdvalues);
flashLED = common.config->getString(common.config->flashLED);
backlightMode = common.config->getString(common.config->backlight);
}
virtual void setupKeys()
{
Page::setupKeys();
// commonData->keydata[0].label = "MODE";
#if defined BOARD_OBP60S3
commonData->keydata[1].label = "SRC";
commonData->keydata[4].label = "INTV";
#elif defined BOARD_OBP40S3
commonData->keydata[1].label = "INTV";
#endif
}
// Key functions
virtual int handleKey(int key)
{
// Set chart mode TWD | TWS -> to be implemented
if (key == 1) {
if (chrtMode == 'D') {
chrtMode = 'S';
} else if (chrtMode == 'S') {
chrtMode = 'B';
} else {
chrtMode = 'D';
}
return 0; // Commit the key
}
#if defined BOARD_OBP60S3
// Set data source TRUE | APP
if (key == 2) {
showTruW = !showTruW;
return 0; // Commit the key
}
// Set interval for wind history chart update time (interval)
if (key == 5) {
#elif defined BOARD_OBP40S3
if (key == 2) {
#endif
if (dataIntv == 1) {
dataIntv = 2;
} else if (dataIntv == 2) {
dataIntv = 3;
} else if (dataIntv == 3) {
dataIntv = 4;
} else {
dataIntv = 1;
}
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 displayNew(PageData &pageData){
#ifdef BOARD_OBP40S3
String wndSrc; // Wind source true/apparant wind - preselection for OBP40
wndSrc = commonData->config->getString("page" + String(pageData.pageNumber) + "wndsrc");
if (wndSrc =="True wind") {
showTruW = true;
} else {
showTruW = false; // Wind source is apparant wind
}
commonData->logger->logDebug(GwLog::LOG,"New PageWindPlot: wind source=%s", wndSrc);
#endif
oldShowTruW = !showTruW; // makes wind source being initialized at initial page call
}
int displayPage(PageData& pageData)
{
GwConfigHandler* config = commonData->config;
GwLog* logger = commonData->logger;
static RingBuffer<int16_t>* wdHstry; // Wind direction data buffer
static RingBuffer<uint16_t>* wsHstry; // Wind speed data buffer
static String wdName, wdFormat; // Wind direction name and format
static String wsName, wsFormat; // Wind speed name and format
static int16_t wdMAX_VAL; // Max. value of wd history buffer, indicating invalid values
float wsValue; // Wind speed value in chart area
String wsUnit; // Wind speed unit in chart area
static GwApi::BoatValue* wsBVal = new GwApi::BoatValue("TWS"); // temp BoatValue for wind speed unit identification; required by OBP60Formater
// current boat data values; TWD/AWD only for validation test
const int numBoatData = 2;
GwApi::BoatValue* bvalue;
bool BDataValid[numBoatData];
static bool isInitialized = false; // Flag to indicate that page is initialized
static bool wndDataValid = false; // Flag to indicate if wind data is valid
static int numNoData; // Counter for multiple invalid data values in a row
static int width; // Screen width
static int height; // Screen height
static int xCenter; // Center of screen in x direction
static const int yOffset = 48; // Offset for y coordinates of chart area
static int cHeight; // height of chart area
static int bufSize; // History buffer size: 960 values for appox. 16 min. history chart
static int intvBufSize; // Buffer size used for currently selected time interval
int count; // current size of buffer
static int numWndVals; // number of wind values available for current interval selection
static int bufStart; // 1st data value in buffer to show
int numAddedBufVals; // Number of values added to buffer since last display
size_t currIdx; // Current index in TWD history buffer
static size_t lastIdx; // Last index of TWD history buffer
static size_t lastAddedIdx = 0; // Last index of TWD history buffer when new data was added
static int oldDataIntv; // remember recent user selection of data interval
static int wndCenter; // chart wind center value position
static int wndLeft; // chart wind left value position
static int wndRight; // chart wind right value position
static int chrtRng; // Range of wind values from mid wind value to min/max wind value in degrees
int diffRng; // Difference between mid and current wind value
static const int dfltRng = 60; // Default range for chart
int midWndDir; // New value for wndCenter after chart start / shift
int x, y; // x and y coordinates for drawing
static int prevX, prevY; // Last x and y coordinates for drawing
static float chrtScl; // Scale for wind values in pixels per degree
int chrtVal; // Current wind value
static int chrtPrevVal; // Last wind value in chart area for check if value crosses 180 degree line
LOG_DEBUG(GwLog::LOG, "Display PageWindPlot");
ulong timer = millis();
if (!isInitialized) {
width = getdisplay().width();
height = getdisplay().height();
xCenter = width / 2;
cHeight = height - yOffset - 22;
numNoData = 0;
bufStart = 0;
oldDataIntv = 0;
wsValue = 0;
numAddedBufVals, currIdx, lastIdx = 0;
wndCenter = INT_MAX;
midWndDir = 0;
diffRng = dfltRng;
chrtRng = dfltRng;
isInitialized = true; // Set flag to indicate that page is now initialized
}
// read boat data values; TWD only for validation test, TWS for display of current value
for (int i = 0; i < numBoatData; i++) {
bvalue = pageData.values[i];
BDataValid[i] = bvalue->valid;
}
// Optical warning by limit violation (unused)
if (String(flashLED) == "Limit Violation") {
setBlinkingLED(false);
setFlashLED(false);
}
if (showTruW != oldShowTruW) {
if (showTruW) {
wdHstry = pageData.boatHstry->hstryBufList.twdHstry;
wsHstry = pageData.boatHstry->hstryBufList.twsHstry;
} else {
wdHstry = pageData.boatHstry->hstryBufList.awdHstry;
wsHstry = pageData.boatHstry->hstryBufList.awsHstry;
}
wdHstry->getMetaData(wdName, wdFormat);
wsHstry->getMetaData(wsName, wsFormat);
wdMAX_VAL = wdHstry->getMaxVal();
bufSize = wdHstry->getCapacity();
wsBVal->setFormat(wsHstry->getFormat());
lastAddedIdx = wdHstry->getLastIdx();
oldShowTruW = showTruW;
}
// Identify buffer size and buffer start position for chart
count = wdHstry->getCurrentSize();
currIdx = wdHstry->getLastIdx();
numAddedBufVals = (currIdx - lastAddedIdx + bufSize) % bufSize; // Number of values added to buffer since last display
if (dataIntv != oldDataIntv || count == 1) {
// new data interval selected by user
intvBufSize = cHeight * dataIntv;
numWndVals = min(count, (cHeight - 60) * dataIntv);
bufStart = max(0, count - numWndVals);
lastAddedIdx = currIdx;
oldDataIntv = dataIntv;
} else {
numWndVals = numWndVals + numAddedBufVals;
lastAddedIdx = currIdx;
if (count == bufSize) {
bufStart = max(0, bufStart - numAddedBufVals);
}
}
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Dataset: count: %d, xWD: %.1f, xWS: %.2f, xWD_valid? %d, intvBufSize: %d, numWndVals: %d, bufStart: %d, numAddedBufVals: %d, lastIdx: %d, wind source: %s",
count, wdHstry->getLast() / 1000.0 * radToDeg, wsHstry->getLast() / 1000.0 * 1.94384, BDataValid[0], intvBufSize, numWndVals, bufStart, numAddedBufVals, wdHstry->getLastIdx(),
showTruW ? "True" : "App");
// Set wndCenter from 1st real buffer value
if (wndCenter == INT_MAX || (wndCenter == 0 && count == 1)) {
wndCenter = getCntr(*wdHstry, numWndVals);
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, xWD: %.1f, wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", count, wdHstry->getLast() / 1000.0 * radToDeg,
wndCenter, diffRng, chrtRng, wdHstry->getMin(numWndVals) / 1000.0 * radToDeg, wdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
} else {
// check and adjust range between left, center, and right chart limit
diffRng = getRng(*wdHstry, wndCenter, numWndVals);
diffRng = (diffRng == wdMAX_VAL ? 0 : diffRng);
if (diffRng > chrtRng) {
chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value
} else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible
chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10);
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", wndCenter, diffRng, chrtRng,
wdHstry->getMin(numWndVals) / 1000.0 * radToDeg, wdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
}
}
chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree
wndLeft = wndCenter - chrtRng;
if (wndLeft < 0)
wndLeft += 360;
wndRight = (chrtRng < 180 ? wndCenter + chrtRng : wndCenter + chrtRng - 1);
if (wndRight >= 360)
wndRight -= 360;
// Draw page
//***********************************************************************
// Set display in partial refresh mode
getdisplay().setPartialWindow(0, 0, width, height); // Set partial update
getdisplay().setTextColor(commonData->fgcolor);
// chart lines
getdisplay().fillRect(0, yOffset, width, 2, commonData->fgcolor);
getdisplay().fillRect(xCenter, yOffset, 1, cHeight, commonData->fgcolor);
// chart labels
char sWndLbl[4]; // char buffer for Wind angle label
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(xCenter - 88, yOffset - 3);
getdisplay().print(wdName); // Wind data name
snprintf(sWndLbl, 4, "%03d", (wndCenter < 0) ? (wndCenter + 360) : wndCenter);
drawTextCenter(xCenter, yOffset - 11, sWndLbl);
getdisplay().drawCircle(xCenter + 25, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
getdisplay().drawCircle(xCenter + 25, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
getdisplay().setCursor(1, yOffset - 3);
snprintf(sWndLbl, 4, "%03d", (wndLeft < 0) ? (wndLeft + 360) : wndLeft);
getdisplay().print(sWndLbl); // Wind left value
getdisplay().drawCircle(46, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
getdisplay().drawCircle(46, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
getdisplay().setCursor(width - 50, yOffset - 3);
snprintf(sWndLbl, 4, "%03d", (wndRight < 0) ? (wndRight + 360) : wndRight);
getdisplay().print(sWndLbl); // Wind right value
getdisplay().drawCircle(width - 5, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
getdisplay().drawCircle(width - 5, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
if (wdHstry->getMax() == wdMAX_VAL) {
// only <MAX_VAL> values in buffer -> no valid wind data available
wndDataValid = false;
} else if (!BDataValid[0] && !useSimuData) {
// currently no valid xWD data available and no simulation mode
numNoData++;
wndDataValid = true;
if (numNoData > 3) {
// If more than 4 invalid values in a row, send message
wndDataValid = false;
}
} else {
numNoData = 0; // reset data error counter
wndDataValid = true; // At least some wind data available
}
// Draw wind values in chart
//***********************************************************************
if (wndDataValid) {
for (int i = 0; i < (numWndVals / dataIntv); i++) {
chrtVal = static_cast<int>(wdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
if (chrtVal == wdMAX_VAL) {
chrtPrevVal = wdMAX_VAL;
} else {
chrtVal = static_cast<int>((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
y = yOffset + cHeight - i; // Position in chart area
if (i >= (numWndVals / dataIntv) - 1) // log chart data of 1 line (adjust for test purposes)
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv));
if ((i == 0) || (chrtPrevVal == wdMAX_VAL)) {
// just a dot for 1st chart point or after some invalid values
prevX = x;
prevY = y;
} else {
// cross borders check; shift values to [-180..0..180]; when crossing borders, range is 2x 180 degrees
int wndLeftDlt = -180 - ((wndLeft >= 180) ? (wndLeft - 360) : wndLeft);
int chrtVal180 = ((chrtVal + wndLeftDlt + 180) % 360 + 360) % 360 - 180;
int chrtPrevVal180 = ((chrtPrevVal + wndLeftDlt + 180) % 360 + 360) % 360 - 180;
if (((chrtPrevVal180 >= -180) && (chrtPrevVal180 < -90) && (chrtVal180 > 90)) || ((chrtPrevVal180 <= 179) && (chrtPrevVal180 > 90) && chrtVal180 <= -90)) {
// If current value crosses chart borders compared to previous value, split line
int xSplit = (((chrtPrevVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
getdisplay().drawLine(prevX, prevY, xSplit, y, commonData->fgcolor);
getdisplay().drawLine(prevX, prevY - 1, ((xSplit != prevX) ? xSplit : xSplit - 1), ((xSplit != prevX) ? y - 1 : y), commonData->fgcolor);
prevX = (((chrtVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
}
}
// Draw line with 2 pixels width + make sure vertical line are drawn correctly
getdisplay().drawLine(prevX, prevY, x, y, commonData->fgcolor);
getdisplay().drawLine(prevX, prevY - 1, ((x != prevX) ? x : x - 1), ((x != prevX) ? y - 1 : y), commonData->fgcolor);
chrtPrevVal = chrtVal;
prevX = x;
prevY = y;
}
// Reaching chart area top end
if (i >= (cHeight - 1)) {
oldDataIntv = 0; // force reset of buffer start and number of values to show in next display loop
int minWndDir = wdHstry->getMin(numWndVals) / 1000.0 * radToDeg;
int maxWndDir = wdHstry->getMax(numWndVals) / 1000.0 * radToDeg;
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
// if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) {
if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || (wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || (wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || (wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) {
// Check if all wind value are left or right of center value -> optimize chart center
wndCenter = getCntr(*wdHstry, numWndVals);
}
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter);
break;
}
}
// Print wind speed value
int currentZone;
static int lastZone = 0;
static bool flipTws = false;
int xPosTws;
static const int yPosTws = yOffset + 40;
xPosTws = flipTws ? 20 : width - 145;
currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value
if (currentZone != lastZone) {
// Only flip when x moves to a different zone
if ((y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146)) {
flipTws = !flipTws;
xPosTws = flipTws ? 20 : width - 145;
}
}
lastZone = currentZone;
wsValue = wsHstry->getLast();
wsBVal->value = wsValue / 1000.0; // temp variable to retreive data unit from OBP60Formater
wsBVal->valid = (static_cast<uint16_t>(wsValue) != wsHstry->getMinVal());
String swsValue = formatValue(wsBVal, *commonData).svalue; // value (string)
wsUnit = formatValue(wsBVal, *commonData).unit; // Unit of value
getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(xPosTws, yPosTws);
getdisplay().print(swsValue); // Value
/* if (!wsBVal->valid) {
getdisplay().print("--.-");
} else {
wsValue = wsValue / 1000.0 * 1.94384; // Wind speed value in knots
if (wsValue < 10.0) {
getdisplay().printf("!%3.1f", wsValue); // Value, round to 1 decimal
} else {
getdisplay().printf("%4.1f", wsValue); // Value, round to 1 decimal
}
} */
getdisplay().setFont(&Ubuntu_Bold12pt8b);
getdisplay().setCursor(xPosTws + 82, yPosTws - 14);
getdisplay().print(wsName); // Name
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(xPosTws + 82, yPosTws + 1);
getdisplay().print(wsUnit); // Unit
} else {
// No valid data available
LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available");
getdisplay().setFont(&Ubuntu_Bold10pt8b);
getdisplay().fillRect(xCenter - 33, height / 2 - 20, 66, 24, commonData->bgcolor); // Clear area for message
drawTextCenter(xCenter, height / 2 - 10, "No data");
}
// chart Y axis labels; print at last to overwrite potential chart lines in label area
int yPos;
int chrtLbl;
getdisplay().setFont(&Ubuntu_Bold8pt8b);
for (int i = 1; i <= 3; i++) {
yPos = yOffset + (i * 60);
getdisplay().fillRect(0, yPos, width, 1, commonData->fgcolor);
getdisplay().fillRect(0, yPos - 8, 24, 16, commonData->bgcolor); // Clear small area to remove potential chart lines
getdisplay().setCursor(1, yPos + 4);
if (count >= intvBufSize) {
// Calculate minute value for label
chrtLbl = ((i - 1 + (prevY < yOffset + 30)) * dataIntv) * -1; // change label if last data point is more than 30 lines (= seconds) from chart line
} else {
int j = 3 - i;
chrtLbl = (int((((numWndVals / dataIntv) - 50) * dataIntv / 60) + 1) - (j * dataIntv)) * -1; // 50 lines left below last chart line
}
getdisplay().printf("%3d", chrtLbl); // Wind value label
}
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot time: %ld", millis() - timer);
return PAGE_UPDATE;
};
};
static Page* createPage(CommonData& common)
{
return new PageWindPlot(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 registerPageWindPlot(
"WindPlot", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{ "TWD", "AWD" }, // Bus values we need in the page
true // Show display header on/off
);
#endif

View File

@@ -48,7 +48,7 @@ public:
String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight);
// Get boat value for AWA
// Get boat values for AWA
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
String name1 = xdrDelete(bvalue1->getName()); // Value name
name1 = name1.substring(0, 6); // String length limit for value name
@@ -63,8 +63,8 @@ public:
unit1old = unit1; // Save old unit
}
// Get boat value for AWS
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
// Get boat values for AWS
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
String name2 = xdrDelete(bvalue2->getName()); // Value name
name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
@@ -77,8 +77,8 @@ public:
unit2old = unit2; // Save old unit
}
// Get boat value for TWD
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
// Get boat values TWD
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
String name3 = xdrDelete(bvalue3->getName()); // Value name
name3 = name3.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
@@ -91,9 +91,9 @@ public:
unit3old = unit3; // Save old unit
}
// Get boat value for TWS
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
String name4 = xdrDelete(bvalue4->getName()); // Value name
// Get boat values TWS
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
String name4 = xdrDelete(bvalue4->getName()); // Value name
name4 = name4.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
double value4 = bvalue4->value; // Value as double in SI unit
@@ -105,9 +105,9 @@ public:
unit4old = unit4; // Save old unit
}
// Get boat value for DBT
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list
String name5 = xdrDelete(bvalue5->getName()); // Value name
// Get boat values DBT
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
String name5 = xdrDelete(bvalue5->getName()); // Value name
name5 = name5.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
double value5 = bvalue5->value; // Value as double in SI unit
@@ -119,9 +119,9 @@ public:
unit5old = unit5; // Save old unit
}
// Get boat value for STW
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list
String name6 = xdrDelete(bvalue6->getName()); // Value name
// Get boat values STW
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
String name6 = xdrDelete(bvalue6->getName()); // Value name
name6 = name6.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
double value6 = bvalue6->value; // Value as double in SI unit
@@ -248,7 +248,7 @@ public:
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
const char *ii = "";
switch (i)
{
{
case 0: ii="0"; break;
case 30 : ii="30"; break;
case 60 : ii="60"; break;
@@ -372,11 +372,11 @@ static Page *createPage(CommonData &common){
* and will will provide the names of the fixed values we need
*/
PageDescription registerPageWindRose(
"WindRose", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
"WindRose", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{"AWA", "AWS", "TWD", "TWS", "DBT", "STW"}, // Bus values we need in the page
true // Show display header on/off
true // Show display header on/off
);
#endif

View File

@@ -7,33 +7,15 @@
class PageWindRoseFlex : public Page
{
int16_t lp = 80; // Pointer length
char source = 'A'; // data source (A)pparent | (T)rue
String ssource="App."; // String for Data Source
public:
PageWindRoseFlex(CommonData &common){
commonData = &common;
common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRoseFlex");
}
virtual void setupKeys(){
Page::setupKeys();
commonData->keydata[1].label = "SRC";
}
// Key functions
virtual int handleKey(int key){
if(key == 2){
// Code for set source
if(source == 'A'){
source = 'T';
ssource = "True"; // String to display
} else {
source = 'A';
ssource = "App."; // String to display
}
}
return key; // Commit the key
// Code for keylock
if(key == 11){
commonData->keylock = !commonData->keylock;
@@ -66,52 +48,37 @@ public:
String flashLED = config->getString(config->flashLED);
String backlightMode = config->getString(config->backlight);
GwApi::BoatValue *bvalue1; // Value 1 for angle
GwApi::BoatValue *bvalue2; // Value 2 for speed
// Get boat value for wind angle (AWA/TWA), shown by pointer
if (source == 'A') {
bvalue1 = pageData.values[4];
} else {
bvalue1 = pageData.values[6];
}
String name1 = bvalue1->getName().c_str(); // Value name
// Get boat values for AWA
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
String name1 = xdrDelete(bvalue1->getName()); // Value name
name1 = name1.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
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
if(valid1 == true){
if(valid1 == true){
svalue1old = svalue1; // Save old value
unit1old = unit1; // Save old unit
}
// Get boat value for wind speed (AWS/TWS), shown in top left corner
if (source == 'A') {
bvalue2 =pageData.values[5];
} else {
bvalue2 = pageData.values[7];
}
String name2 = bvalue2->getName().c_str(); // Value name
// Get boat values for AWS
GwApi::BoatValue *bvalue2 = pageData.values[1]; // First element in list (only one value by PageOneValue)
String name2 = xdrDelete(bvalue2->getName()); // Value name
name2 = name2.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
double value2 = bvalue2->value; // Value as double in SI unit
bool valid2 = bvalue2->valid; // Valid information
if (simulation) {
value2 = 0.62731; // some random 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){
if(valid2 == true){
svalue2old = svalue2; // Save old value
unit2old = unit2; // Save old unit
}
// Get boat value for bottom left corner
GwApi::BoatValue *bvalue3 = pageData.values[0];
// Get boat values TWD
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
String name3 = xdrDelete(bvalue3->getName()); // Value name
name3 = name3.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
@@ -124,8 +91,8 @@ public:
unit3old = unit3; // Save old unit
}
// Get boat value for top right corner
GwApi::BoatValue *bvalue4 = pageData.values[1];
// Get boat values TWS
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
String name4 = xdrDelete(bvalue4->getName()); // Value name
name4 = name4.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
@@ -138,8 +105,8 @@ public:
unit4old = unit4; // Save old unit
}
// Get boat value bottom right corner
GwApi::BoatValue *bvalue5 = pageData.values[2];
// Get boat values DBT
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Second element in list (only one value by PageOneValue)
String name5 = xdrDelete(bvalue5->getName()); // Value name
name5 = name5.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
@@ -152,8 +119,8 @@ public:
unit5old = unit5; // Save old unit
}
// Get boat value for center
GwApi::BoatValue *bvalue6 = pageData.values[3];
// Get boat values STW
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Second element in list (only one value by PageOneValue)
String name6 = xdrDelete(bvalue6->getName()); // Value name
name6 = name6.substring(0, 6); // String length limit for value name
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
@@ -166,7 +133,6 @@ public:
unit6old = unit6; // Save old unit
}
// Optical warning by limit violation (unused)
if(String(flashLED) == "Limit Violation"){
setBlinkingLED(false);
@@ -185,7 +151,7 @@ public:
getdisplay().setTextColor(commonData->fgcolor);
// Show AWS or TWS top left
// Show value 2 at position of value 1 (top left)
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(10, 65);
getdisplay().print(svalue2); // Value
@@ -205,7 +171,7 @@ public:
// Horizintal separator left
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
// Show value 3 (=first user-configured parameter) at bottom left
// Show value 3 at bottom left
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(10, 270);
getdisplay().print(svalue3); // Value
@@ -222,10 +188,11 @@ public:
getdisplay().print(unit3old); // Unit
}
// Show value 4 (=second user-configured parameter) at top right
// Show value 4 at top right
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(295, 65);
if(valid3 == true){
// getdisplay().print(abs(value3 * 180 / PI), 0); // Value
getdisplay().print(svalue4); // Value
}
else{
@@ -247,7 +214,7 @@ public:
// Horizintal separator right
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
// Show value 5 (=third user-configured parameter) at bottom right
// Show value 5 at bottom right
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
getdisplay().setCursor(295, 270);
getdisplay().print(svalue5); // Value
@@ -269,6 +236,7 @@ public:
// Draw wind rose
int rInstrument = 110; // Radius of grafic instrument
float pi = 3.141592;
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
@@ -278,23 +246,24 @@ public:
for(int i=0; i<360; i=i+10)
{
// Scaling values
float x = 200 + (rInstrument-30)*sin(i/180.0*M_PI); // x-coordinate dots
float y = 150 - (rInstrument-30)*cos(i/180.0*M_PI); // y-coordinate dots
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 dots
const char *ii = "";
switch (i) {
case 0: ii="0"; break;
case 30 : ii="30"; break;
case 60 : ii="60"; break;
case 90 : ii="90"; break;
case 120 : ii="120"; break;
case 150 : ii="150"; break;
case 180 : ii="180"; break;
case 210 : ii="210"; break;
case 240 : ii="240"; break;
case 270 : ii="270"; break;
case 300 : ii="300"; break;
case 330 : ii="330"; break;
default: break;
switch (i)
{
case 0: ii="0"; break;
case 30 : ii="30"; break;
case 60 : ii="60"; break;
case 90 : ii="90"; break;
case 120 : ii="120"; break;
case 150 : ii="150"; break;
case 180 : ii="180"; break;
case 210 : ii="210"; break;
case 240 : ii="240"; break;
case 270 : ii="270"; break;
case 300 : ii="300"; break;
case 330 : ii="330"; break;
default: break;
}
// Print text centered on position x, y
@@ -308,11 +277,11 @@ public:
}
// Draw sub scale with dots
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
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, commonData->fgcolor);
float sinx=sin(i/180.0*M_PI);
float cosx=cos(i/180.0*M_PI);
float sinx=sin(i/180.0*pi);
float cosx=cos(i/180.0*pi);
// Draw sub scale with lines (two triangles)
if(i % 30 == 0){
@@ -362,9 +331,8 @@ public:
//*******************************************************************************************
// Show value6 (=fourth user-configured parameter) and ssource, so that they do not collide with the wind pointer
// Show value6, so that it does not collide with the wind pointer
if ( cos(value1) > 0){
//pointer points upwards
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(160, 200);
getdisplay().print(svalue6); // Value
@@ -377,16 +345,8 @@ if ( cos(value1) > 0){
else{
getdisplay().print(unit6old); // Unit
}
if (sin(value1)>0){
getdisplay().setCursor(160, 130);
}
else{
getdisplay().setCursor(220, 130);
}
getdisplay().print(ssource); // true or app.
}
else{
// pointer points downwards
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
getdisplay().setCursor(160, 130);
getdisplay().print(svalue6); // Value
@@ -399,14 +359,8 @@ else{
else{
getdisplay().print(unit6old); // Unit
}
if (sin(value1)>0){
getdisplay().setCursor(160, 200);
}
else{
getdisplay().setCursor(220, 200);
}
getdisplay().print(ssource); //true or app.
}
return PAGE_UPDATE;
};
@@ -419,15 +373,15 @@ static Page *createPage(CommonData &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 (4 here)
* 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 registerPageWindRoseFlex(
"WindRoseFlex", // Page name
createPage, // Action
4, // Number of bus values depends on selection in Web configuration
{"AWA", "AWS", "TWA", "TWS"}, // fixed values we need in the page. They are inserted AFTER the web-configured values.
true // Show display header on/off
"WindRoseFlex", // Page name
createPage, // Action
6, // Number of bus values depends on selection in Web configuration; was zero
//{"AWA", "AWS", "COG", "SOG", "TWD", "TWS"}, // Bus values we need in the page, modified for WindRose2
true // Show display header on/off
);
#endif

View File

@@ -223,11 +223,11 @@ static Page* createPage(CommonData &common){
* this will be number of BoatValue pointers in pageData.values
*/
PageDescription registerPageXTETrack(
"XTETrack", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
"XTETrack", // Page name
createPage, // Action
0, // Number of bus values depends on selection in Web configuration
{"XTE", "COG", "DTW", "BTW"}, // Bus values we need in the page
true // Show display header on/off
true // Show display header on/off
);
#endif

View File

@@ -4,19 +4,15 @@
#include <functional>
#include <vector>
#include "LedSpiTask.h"
#include "OBPDataOperations.h"
#define MAX_PAGE_NUMBER 10 // Max number of pages for show data
typedef std::vector<GwApi::BoatValue *> ValueList;
typedef struct{
GwApi *api;
String pageName;
uint8_t pageNumber; // page number in sequence of visible pages
//the values will always contain the user defined values first
ValueList values;
HstryBuf* boatHstry;
} PageData;
// Sensor data structure (only for extended sensors, not for NMEA bus sensors)
@@ -99,20 +95,20 @@ typedef struct{
} AlarmData;
typedef struct{
GwApi::Status status;
GwLog *logger = nullptr;
GwConfigHandler *config = nullptr;
SensorData data;
SunData sundata;
TouchKeyData keydata[6];
BacklightData backlight;
AlarmData alarm;
GwApi::BoatValue *time = nullptr;
GwApi::BoatValue *date = nullptr;
uint16_t fgcolor;
uint16_t bgcolor;
bool keylock = false;
String powermode;
GwApi::Status status;
GwLog *logger=NULL;
GwConfigHandler *config=NULL;
SensorData data;
SunData sundata;
TouchKeyData keydata[6];
BacklightData backlight;
AlarmData alarm;
GwApi::BoatValue *time=NULL;
GwApi::BoatValue *date=NULL;
uint16_t fgcolor;
uint16_t bgcolor;
bool keylock = false;
String powermode;
} CommonData;
//a base class that all pages must inherit from
@@ -123,7 +119,6 @@ class Page{
int refreshtime = 1000;
virtual int displayPage(PageData &pageData)=0;
virtual void displayNew(PageData &pageData){}
virtual void leavePage(PageData &pageData){}
virtual void setupKeys() {
#ifdef HARDWARE_V21
commonData->keydata[0].label = "";
@@ -182,9 +177,9 @@ class PageDescription{
class PageStruct{
public:
Page *page = nullptr;
Page *page=NULL;
PageData parameters;
PageDescription *description = nullptr;
PageDescription *description=NULL;
};
// Standard format functions without overhead
@@ -198,7 +193,7 @@ typedef struct{
double value;
String svalue;
String unit;
} FormattedData;
} FormatedData;
// Formatter for boat values
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata);
FormatedData formatValue(GwApi::BoatValue *value, CommonData &commondata);

View File

@@ -219,17 +219,6 @@
"obp60":"true"
}
},
{
"name": "calcTrueWnds",
"label": "Calculate True Wind",
"type": "boolean",
"default": "false",
"description": "If not available, calculate true wind data from appearant wind and other boat data",
"category": "OBP60 Settings",
"capabilities": {
"obp60": "true"
}
},
{
"name": "lengthFormat",
"label": "Length Format",
@@ -737,7 +726,7 @@
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance2": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
@@ -762,7 +751,7 @@
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance2": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
@@ -790,7 +779,7 @@
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance2": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
@@ -1117,21 +1106,6 @@
"obp60":"true"
}
},
{
"name": "valueprecision",
"label": "Display value precision",
"type": "list",
"default": "2",
"description": "Maximum number of decimal places to display [1|2]",
"list": [
"1",
"2"
],
"category": "OBP60 Display",
"capabilities": {
"obp60":"true"
}
},
{
"name": "backlight",
"label": "Backlight Mode",
@@ -1311,6 +1285,8 @@
"obp60":"true"
}
},
{
"name": "page1type",
"label": "Type",
@@ -1333,15 +1309,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -1523,6 +1496,9 @@
"condition": [
{
"page1type": "SixValues"
},
{
"page1type": "WindRoseFlex"
}
]
},
@@ -1539,6 +1515,9 @@
"condition": [
{
"page1type": "SixValues"
},
{
"page1type": "WindRoseFlex"
}
]
},
@@ -1610,15 +1589,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -1797,6 +1773,9 @@
"condition": [
{
"page2type": "SixValues"
},
{
"page2type": "WindRoseFlex"
}
]
},
@@ -1813,6 +1792,9 @@
"condition": [
{
"page2type": "SixValues"
},
{
"page2type": "WindRoseFlex"
}
]
},
@@ -1884,15 +1866,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2068,6 +2047,9 @@
"condition": [
{
"page3type": "SixValues"
},
{
"page3type": "WindRoseFlex"
}
]
},
@@ -2084,6 +2066,9 @@
"condition": [
{
"page3type": "SixValues"
},
{
"page3type": "WindRoseFlex"
}
]
},
@@ -2155,15 +2140,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2336,6 +2318,9 @@
"condition": [
{
"page4type": "SixValues"
},
{
"page4type": "WindRoseFlex"
}
]
},
@@ -2352,6 +2337,9 @@
"condition": [
{
"page4type": "SixValues"
},
{
"page4type": "WindRoseFlex"
}
]
},
@@ -2423,15 +2411,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2601,6 +2586,9 @@
"condition": [
{
"page5type": "SixValues"
},
{
"page5type": "WindRoseFlex"
}
]
},
@@ -2617,6 +2605,9 @@
"condition": [
{
"page5type": "SixValues"
},
{
"page5type": "WindRoseFlex"
}
]
},
@@ -2688,15 +2679,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2863,6 +2851,9 @@
"condition": [
{
"page6type": "SixValues"
},
{
"page6type": "WindRoseFlex"
}
]
},
@@ -2879,6 +2870,9 @@
"condition": [
{
"page6type": "SixValues"
},
{
"page6type": "WindRoseFlex"
}
]
},
@@ -2950,15 +2944,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3122,6 +3113,9 @@
"condition": [
{
"page7type": "SixValues"
},
{
"page7type": "WindRoseFlex"
}
]
},
@@ -3138,6 +3132,9 @@
"condition": [
{
"page7type": "SixValues"
},
{
"page7type": "WindRoseFlex"
}
]
},
@@ -3209,15 +3206,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3378,6 +3372,9 @@
"condition": [
{
"page8type": "SixValues"
},
{
"page8type": "WindRoseFlex"
}
]
},
@@ -3394,6 +3391,9 @@
"condition": [
{
"page8type": "SixValues"
},
{
"page8type": "WindRoseFlex"
}
]
},
@@ -3465,15 +3465,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3631,6 +3628,9 @@
"condition": [
{
"page9type": "SixValues"
},
{
"page9type": "WindRoseFlex"
}
]
},
@@ -3647,6 +3647,9 @@
"condition": [
{
"page9type": "SixValues"
},
{
"page9type": "WindRoseFlex"
}
]
},
@@ -3718,15 +3721,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3881,6 +3881,9 @@
"condition": [
{
"page10type": "SixValues"
},
{
"page10type": "WindRoseFlex"
}
]
},
@@ -3897,6 +3900,9 @@
"condition": [
{
"page10type": "SixValues"
},
{
"page10type": "WindRoseFlex"
}
]
},
@@ -3947,3 +3953,4 @@
]
}
]

View File

@@ -61,6 +61,20 @@
"obp40": "true"
}
},
{
"name": "draft",
"label": "Boat Draft [m]",
"type": "number",
"default": "0.00",
"check": "checkMinMax",
"min": 0.00,
"max": 50.00,
"description": "The draft of the boat [0...50m]",
"category": "OBP40 Settings",
"capabilities": {
"obp40": "true"
}
},
{
"name": "fuelTank",
"label": "Fuel Tank [l]",
@@ -205,17 +219,6 @@
"obp40": "true"
}
},
{
"name": "calcTrueWnds",
"label": "Calculate True Wind",
"type": "boolean",
"default": "false",
"description": "If not available, calculate true wind data from appearant wind and other boat data",
"category": "OBP40 Settings",
"capabilities": {
"obp40": "true"
}
},
{
"name": "lengthFormat",
"label": "Length Format",
@@ -704,12 +707,10 @@
"---",
"AWA",
"AWS",
"COG",
"DBT",
"HDM",
"PRPOS",
"RPOS",
"SOG",
"STW",
"TWA",
"TWS",
@@ -729,22 +730,8 @@
"description": "Offset for data instance 1",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
{ "calInstance1": "RPOS" },
{ "calInstance1": "SOG" },
{ "calInstance1": "STW" },
{ "calInstance1": "TWA" },
{ "calInstance1": "TWS" },
{ "calInstance1": "TWD" },
{ "calInstance1": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSlope1",
@@ -754,22 +741,8 @@
"description": "Slope for data instance 1",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
{ "calInstance1": "RPOS" },
{ "calInstance1": "SOG" },
{ "calInstance1": "STW" },
{ "calInstance1": "TWA" },
{ "calInstance1": "TWS" },
{ "calInstance1": "TWD" },
{ "calInstance1": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSmooth1",
@@ -779,25 +752,11 @@
"check": "checkMinMax",
"min": 0,
"max": 10,
"description": "Smoothing factor [0..10]; 0 = no smoothing",
"description": "Smoothing factor for data instance 1",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance1": "AWA" },
{ "calInstance1": "AWS" },
{ "calInstance1": "COG" },
{ "calInstance1": "DBT" },
{ "calInstance1": "HDM" },
{ "calInstance1": "PRPOS" },
{ "calInstance1": "RPOS" },
{ "calInstance1": "SOG" },
{ "calInstance1": "STW" },
{ "calInstance1": "TWA" },
{ "calInstance1": "TWS" },
{ "calInstance1": "TWD" },
{ "calInstance1": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calInstance2",
@@ -809,12 +768,10 @@
"---",
"AWA",
"AWS",
"COG",
"DBT",
"HDM",
"PRPOS",
"RPOS",
"SOG",
"STW",
"TWA",
"TWS",
@@ -834,22 +791,8 @@
"description": "Offset for data instance 2",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance2": "AWA" },
{ "calInstance2": "AWS" },
{ "calInstance2": "COG" },
{ "calInstance2": "DBT" },
{ "calInstance2": "HDM" },
{ "calInstance2": "PRPOS" },
{ "calInstance2": "RPOS" },
{ "calInstance2": "SOG" },
{ "calInstance2": "STW" },
{ "calInstance2": "TWA" },
{ "calInstance2": "TWS" },
{ "calInstance2": "TWD" },
{ "calInstance2": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSlope2",
@@ -859,22 +802,8 @@
"description": "Slope for data instance 2",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance2": "AWA" },
{ "calInstance2": "AWS" },
{ "calInstance2": "COG" },
{ "calInstance2": "DBT" },
{ "calInstance2": "HDM" },
{ "calInstance2": "PRPOS" },
{ "calInstance2": "RPOS" },
{ "calInstance2": "SOG" },
{ "calInstance2": "STW" },
{ "calInstance2": "TWA" },
{ "calInstance2": "TWS" },
{ "calInstance2": "TWD" },
{ "calInstance2": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSmooth2",
@@ -884,25 +813,11 @@
"check": "checkMinMax",
"min": 0,
"max": 10,
"description": "Smoothing factor [0..10]; 0 = no smoothing",
"description": "Smoothing factor for data instance 2",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance2": "AWA" },
{ "calInstance2": "AWS" },
{ "calInstance2": "COG" },
{ "calInstance2": "DBT" },
{ "calInstance2": "HDM" },
{ "calInstance2": "PRPOS" },
{ "calInstance2": "RPOS" },
{ "calInstance2": "SOG" },
{ "calInstance2": "STW" },
{ "calInstance2": "TWA" },
{ "calInstance2": "TWS" },
{ "calInstance2": "TWD" },
{ "calInstance2": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calInstance3",
@@ -914,12 +829,10 @@
"---",
"AWA",
"AWS",
"COG",
"DBT",
"HDM",
"PRPOS",
"RPOS",
"SOG",
"STW",
"TWA",
"TWS",
@@ -939,22 +852,8 @@
"description": "Offset for data instance 3",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance3": "AWA" },
{ "calInstance3": "AWS" },
{ "calInstance3": "COG" },
{ "calInstance3": "DBT" },
{ "calInstance3": "HDM" },
{ "calInstance3": "PRPOS" },
{ "calInstance3": "RPOS" },
{ "calInstance3": "SOG" },
{ "calInstance3": "STW" },
{ "calInstance3": "TWA" },
{ "calInstance3": "TWS" },
{ "calInstance3": "TWD" },
{ "calInstance3": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSlope3",
@@ -964,22 +863,8 @@
"description": "Slope for data instance 3",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance3": "AWA" },
{ "calInstance3": "AWS" },
{ "calInstance3": "COG" },
{ "calInstance3": "DBT" },
{ "calInstance3": "HDM" },
{ "calInstance3": "PRPOS" },
{ "calInstance3": "RPOS" },
{ "calInstance3": "SOG" },
{ "calInstance3": "STW" },
{ "calInstance3": "TWA" },
{ "calInstance3": "TWS" },
{ "calInstance3": "TWD" },
{ "calInstance3": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "calSmooth3",
@@ -989,25 +874,11 @@
"check": "checkMinMax",
"min": 0,
"max": 10,
"description": "Smoothing factor [0..10]; 0 = no smoothing",
"description": "Smoothing factor for data instance 3",
"category": "OBP40 Calibrations",
"capabilities": {
"obp40":"true"
},
"condition": [
{ "calInstance3": "AWA" },
{ "calInstance3": "AWS" },
{ "calInstance3": "COG" },
{ "calInstance3": "DBT" },
{ "calInstance3": "HDM" },
{ "calInstance3": "PRPOS" },
{ "calInstance3": "RPOS" },
{ "calInstance3": "SOG" },
{ "calInstance3": "STW" },
{ "calInstance3": "TWA" },
{ "calInstance3": "TWS" },
{ "calInstance3": "TWD" },
{ "calInstance3": "WTemp" } ]
"obp40": "true"
}
},
{
"name": "display",
@@ -1115,21 +986,6 @@
"obp40": "true"
}
},
{
"name": "valueprecision",
"label": "Display value precision",
"type": "list",
"default": "2",
"description": "Maximum number of decimal places to display [1|2]",
"list": [
"1",
"2"
],
"category": "OBP40 Display",
"capabilities": {
"obp40":"true"
}
},
{
"name": "backlight",
"label": "Backlight Mode",
@@ -1320,128 +1176,6 @@
"obp40": "true"
}
},
{
"name": "trackerType",
"label": "Tracker Type",
"type": "list",
"default": "NONE",
"description": "Type of tracker to use [NONE|SDCARD|SERVER|HERO]",
"list": [
{"l":"No tracker","v":"NONE"},
{"l":"Log to SD-Card","v":"SDCARD"},
{"l":"Log to Server","v":"SERVER"},
{"l":"Regatta Hero","v":"HERO"}
],
"category": "OBP40 Settings",
"capabilities": {
"obp40":"true"
}
},
{
"name": "trackerOrg",
"label": "Tracker: Organisation",
"type": "string",
"default": "",
"description": "Regatta organisation for regatta login (gotten from race officer)",
"category": "OBP40 Settings",
"capabilities": {
"obp40":"true"
}
},
{
"name": "trackerPasscode",
"label": "Tracker: Passcode",
"type": "password",
"default": "123456",
"description": "Passcode for regatta login (gotten from race officer)",
"category": "OBP40 Settings",
"capabilities": {
"obp40":"true"
}
},
{
"name": "trackerTeam",
"label": "Tracker: Team",
"type": "string",
"default": "OBP",
"description": "Your regatta team you belong to",
"category": "OBP40 Settings",
"capabilities": {
"obp40":"true"
}
},
{
"name": "boatName",
"label": "Boat Name",
"type": "string",
"default": "OBP",
"description": "The name of your boat. E.g. to be displayed in regatta",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40":"true"
}
},
{
"name": "sailClub",
"label": "Sail Club",
"type": "string",
"default": "",
"description": "The short name of sail club. E.g. to be displayed in regatta",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40":"true"
}
},
{
"name": "boatClass",
"label": "Boat class",
"type": "string",
"default": "OBP",
"description": "Class name of your boat if available or 'One off'",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40":"true"
}
},
{
"name": "boatSailnumber",
"label": "Sail number",
"type": "string",
"default": "",
"description": "Identification number on sail",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40":"true"
}
},
{
"name": "boatHandicap",
"label": "Handicap value",
"type": "number",
"default": "100",
"check": "checkMinMax",
"min": 0.00,
"max": 9999.00,
"description": " The handicap value of your boat. E.g. yardstick value",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40":"true"
}
},
{
"name": "draft",
"label": "Boat Draft [m]",
"type": "number",
"default": "0.00",
"check": "checkMinMax",
"min": 0.00,
"max": 50.00,
"description": "The draft of the boat [0...50m]",
"category": "OBP40 Boatdata",
"capabilities": {
"obp40": "true"
}
},
{
"name": "page1type",
"label": "Type",
@@ -1464,15 +1198,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -1725,26 +1456,6 @@
}
]
},
{
"name": "page1wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 1: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 1",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page1type": "WindPlot"
}
]
},
{
"name": "page2type",
"label": "Type",
@@ -1767,15 +1478,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2025,26 +1733,6 @@
}
]
},
{
"name": "page2wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 2: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 2",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page2type": "WindPlot"
}
]
},
{
"name": "page3type",
"label": "Type",
@@ -2067,15 +1755,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2322,26 +2007,6 @@
}
]
},
{
"name": "page3wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 3: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 3",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page3type": "WindPlot"
}
]
},
{
"name": "page4type",
"label": "Type",
@@ -2364,15 +2029,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2616,26 +2278,6 @@
}
]
},
{
"name": "page4wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 4: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 4",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page4type": "WindPlot"
}
]
},
{
"name": "page5type",
"label": "Type",
@@ -2658,15 +2300,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -2907,26 +2546,6 @@
}
]
},
{
"name": "page5wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 5: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 5",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page5type": "WindPlot"
}
]
},
{
"name": "page6type",
"label": "Type",
@@ -2949,15 +2568,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3195,26 +2811,6 @@
}
]
},
{
"name": "page6wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 6: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 6",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page6type": "WindPlot"
}
]
},
{
"name": "page7type",
"label": "Type",
@@ -3237,15 +2833,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3480,26 +3073,6 @@
}
]
},
{
"name": "page7wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 7: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 7",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page7type": "WindPlot"
}
]
},
{
"name": "page8type",
"label": "Type",
@@ -3522,15 +3095,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -3762,26 +3332,6 @@
}
]
},
{
"name": "page8wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 8: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 8",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page8type": "WindPlot"
}
]
},
{
"name": "page9type",
"label": "Type",
@@ -3804,15 +3354,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -4041,26 +3588,6 @@
}
]
},
{
"name": "page9wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 9: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 9",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page9type": "WindPlot"
}
]
},
{
"name": "page10type",
"label": "Type",
@@ -4083,15 +3610,12 @@
"RollPitch",
"RudderPosition",
"SixValues",
"SkyView",
"Solar",
"ThreeValues",
"Tracker",
"TwoValues",
"Voltage",
"WhitePage",
"Wind",
"WindPlot",
"WindRose",
"WindRoseFlex",
"XTETrack"
@@ -4316,25 +3840,5 @@
"page10type": "Fluid"
}
]
},
{
"name": "page10wndsrc",
"label": "Wind source",
"type": "list",
"default": "True wind",
"description": "Wind source for page 10: [true|apparant]",
"list": [
"True wind",
"Apparant wind"
],
"category": "OBP40 Page 10",
"capabilities": {
"obp40": "true"
},
"condition": [
{
"page10type": "WindPlot"
}
]
}
]

View File

@@ -1,179 +1,131 @@
#!/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
"""
A tool to generate that part of config.json that deals with pages and fields.
Usage example:
1. Delete all lines from config.json from the curly backet before
"name": "page1type" to the end of the file
2. run ./gen_set.py -d obp60 -p 10 >> config.json
TODO Better handling of default pages
"""
import os
import sys
import getopt
import re
import json
__version__ = "0.2"
# 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,
"Compass" : 0,
"DST810": 0,
"Fluid": 1,
"FourValues2": 4,
"FourValues": 4,
"Generator": 0,
"KeelPosition": 0,
"OneValue": 1,
"RollPitch": 2,
"RudderPosition": 0,
"SixValues" : 6,
"Solar": 0,
"ThreeValues": 3,
"TwoValues": 2,
"Voltage": 0,
"WhitePage": 0,
"WindRose": 0,
"WindRoseFlex": 6,
}
def detect_pages(filename):
# returns a dictionary with page name and the number of gui fields
pagefiles = []
with open(filename, 'r') as fh:
pattern = r'extern PageDescription\s*register(Page[^;\s]*)'
for line in fh:
if "extern PageDescription" in line:
match = re.search(pattern, line)
if match:
pagefiles.append(match.group(1))
try:
pagefiles.remove('PageSystem')
except ValueError:
pass
pagedata = {}
for pf in pagefiles:
filename = pf + ".cpp"
with open(filename, 'r') as fh:
content = fh.read()
pattern = r'PageDescription\s*?register' + pf + r'\s*\(\s*"([^"]+)".*?\n\s*(\d+)'
match = re.search(pattern, content, re.DOTALL)
if match:
pagedata[match.group(1)] = int(match.group(2))
return pagedata
# 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())
def get_default_page(pageno):
# Default selection for each page
default_pages = (
"Voltage",
"WindRose",
"OneValue",
"TwoValues",
"ThreeValues",
"FourValues",
"FourValues2",
"Clock",
"RollPitch",
"Battery2"
)
if pageno > len(default_pages):
return "OneValue"
return default_pages[pageno - 1]
output = []
def number_to_text(number):
if number < 0 or number > 99:
raise ValueError("Only numbers from 0 to 99 are allowed.")
numbers = ("zero", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen")
tens = ("", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
"eighty", "ninety")
if number < 20:
return numbers[number]
else:
q, r = divmod(number, 10)
return tens[q] + numbers[r]
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)
def create_json(device, no_of_pages, pagedata):
pages = sorted(pagedata.keys())
max_no_of_fields_per_page = max(pagedata.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": get_default_page(page_no),
"description": f"Type of page for page {page_no}",
"list": pages,
"category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "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": "The display for field {}".format(number_to_text(field_no)),
"category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "true"},
"condition": [
{f"page{page_no}type": page}
for page in pages
if pagedata[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"}
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
],
"description": "Fluid type in tank",
"category": f"{device.upper()} Page {page_no}",
"capabilities": {
device.lower(): "true"
},
"condition":[{f"page{page_no}type":"Fluid"}]
}
output.append(fluid_data)
}
output.append(field_data)
return json.dumps(output, indent=4)
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)
def usage():
print("{} v{}".format(os.path.basename(__file__), __version__))
print()
print("Command line options")
print(" -d --device device name to use e.g. obp60")
print(" -p --pages number of pages to create")
print(" -h show this help")
print()
if __name__ == '__main__':
try:
options, remainder = getopt.getopt(sys.argv[1:], 'd:p:', ['device=','--pages='])
except getopt.GetoptError as err:
print(err)
usage()
sys.exit(2)
device = "obp60"
no_of_pages = 10
for opt, arg in options:
if opt in ('-d', '--device'):
device = arg
elif opt in ('-p', '--pages'):
no_of_pages = int(arg)
elif opt == '-h':
usage()
sys.exit(0)
# automatic detect pages and number of fields from sourcecode
pagedata = detect_pages("obp60task.cpp")
json_output = create_json(device, no_of_pages, pagedata)
# print omitting first line containing [ of JSON array
print(json_output[1:])
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(",")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,68 +0,0 @@
#pragma once
#define alpha_width 96
#define alpha_height 64
static unsigned char alpha_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x35,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x0d,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0x06,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x03,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x6e, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x35, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x06, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xd5, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0x6e, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x35, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x0d, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0x06, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0x01, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0xd5, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x6e, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x35, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x1b, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x0d, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x06, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x03, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x01, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x03, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x06, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x0d, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x1b, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x35, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x6e, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0xd5, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0x01, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0x06, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x0d, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x35, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0x6e, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xd5, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x06, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x35, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x6e, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x03,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0x06,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x0d,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x35,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0x6e,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define answer_width 96
#define answer_height 64
static unsigned char answer_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf7, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xfa, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x05, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0xff, 0xff, 0x01, 0x00, 0x00,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0xfe, 0x1f, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xfe, 0x0f, 0x00,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0xf0, 0xff, 0x07,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xfa, 0x7f,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xfd,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x50, 0x55, 0xfd,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xa0, 0xfa, 0x7f,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0xf0, 0xff, 0x07,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0x02, 0x00, 0xfe, 0x0f, 0x00,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0x55, 0x01, 0xfe, 0x1f, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xaa, 0xaa, 0xff, 0xff, 0x01, 0x00, 0x00,
0x57, 0x55, 0x05, 0x00, 0x40, 0x55, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0x00, 0x80, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x05, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xaa, 0x0a, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xfa, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf7, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x1f, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -1,68 +0,0 @@
#pragma once
#define black_width 96
#define black_height 64
static unsigned char black_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xc0, 0x1f, 0xff, 0x1f, 0xfc, 0x0f, 0x78, 0x7c, 0xf8, 0xff,
0xff, 0x3f, 0x00, 0x1f, 0xff, 0x1f, 0xfc, 0x07, 0x70, 0x3c, 0xfc, 0xff,
0xff, 0x3f, 0x00, 0x1e, 0xff, 0x1f, 0xfc, 0x03, 0x70, 0x1c, 0xfe, 0xff,
0xff, 0x3f, 0x3e, 0x1e, 0xff, 0x8f, 0xf8, 0xe1, 0x7b, 0x0c, 0xff, 0xff,
0xff, 0x3f, 0x3e, 0x1e, 0xff, 0x8f, 0xf8, 0xf0, 0x7f, 0x84, 0xff, 0xff,
0xff, 0x3f, 0x00, 0x1f, 0xff, 0x87, 0xf0, 0xf8, 0x7f, 0xc0, 0xff, 0xff,
0xff, 0x3f, 0x00, 0x1f, 0xff, 0xc7, 0xf1, 0xf8, 0x7f, 0xe0, 0xff, 0xff,
0xff, 0x3f, 0x00, 0x1e, 0xff, 0xc7, 0xf1, 0xf8, 0x7f, 0xc0, 0xff, 0xff,
0xff, 0x3f, 0x3e, 0x1c, 0xff, 0xc3, 0xe1, 0xf8, 0x7f, 0x84, 0xff, 0xff,
0xff, 0x3f, 0x7e, 0x1c, 0xff, 0x03, 0xe0, 0xf8, 0x7f, 0x8c, 0xff, 0xff,
0xff, 0x3f, 0x7e, 0x1c, 0xff, 0x01, 0xe0, 0xf0, 0x7f, 0x1c, 0xff, 0xff,
0xff, 0x3f, 0x3e, 0x1c, 0xff, 0x01, 0xc0, 0xe1, 0x7b, 0x1c, 0xfe, 0xff,
0xff, 0x3f, 0x00, 0x1e, 0x80, 0xf1, 0xc7, 0x01, 0x70, 0x3c, 0xfc, 0xff,
0xff, 0x3f, 0x00, 0x1e, 0x80, 0xf0, 0x87, 0x03, 0x70, 0x7c, 0xf8, 0xff,
0xff, 0x3f, 0x80, 0x1f, 0x80, 0xf8, 0x8f, 0x0f, 0x78, 0xfc, 0xf0, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define blue_width 96
#define blue_height 64
static unsigned char blue_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x15, 0x40, 0x05, 0x55, 0x50, 0x51, 0x00, 0x54, 0x55, 0xd5,
0xef, 0xee, 0x0e, 0x80, 0x8e, 0xee, 0xe8, 0xe0, 0x00, 0xee, 0xee, 0xee,
0x57, 0x55, 0x15, 0x00, 0x05, 0x55, 0x50, 0x51, 0x00, 0x54, 0x55, 0xd5,
0xbb, 0xbb, 0x1b, 0x1b, 0x8b, 0xbb, 0xb8, 0xb1, 0xb8, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x15, 0x15, 0x05, 0x55, 0x50, 0x51, 0x50, 0x55, 0x55, 0xd5,
0xef, 0xee, 0x0e, 0x80, 0x8e, 0xee, 0xe8, 0xe0, 0xe8, 0xee, 0xee, 0xee,
0x57, 0x55, 0x15, 0x00, 0x05, 0x55, 0x50, 0x51, 0x00, 0x54, 0x55, 0xd5,
0xbb, 0xbb, 0x1b, 0x00, 0x8b, 0xbb, 0xb8, 0xb1, 0x00, 0xba, 0xbb, 0xfb,
0x57, 0x55, 0x15, 0x15, 0x04, 0x55, 0x50, 0x51, 0x00, 0x54, 0x55, 0xd5,
0xef, 0xee, 0x0e, 0x2e, 0x8e, 0xee, 0xe8, 0xe0, 0xe8, 0xee, 0xee, 0xee,
0x57, 0x55, 0x15, 0x15, 0x04, 0x55, 0x50, 0x51, 0x50, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0x1b, 0x1b, 0x8a, 0xbb, 0xb0, 0xb0, 0xb8, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x15, 0x00, 0x05, 0x40, 0x01, 0x50, 0x00, 0x54, 0x55, 0xd5,
0xef, 0xee, 0x0e, 0x00, 0x0e, 0xc0, 0x02, 0xec, 0x00, 0xec, 0xee, 0xee,
0x57, 0x55, 0x15, 0x40, 0x05, 0x40, 0x05, 0x54, 0x00, 0x54, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define charlie_width 96
#define charlie_height 64
static unsigned char charlie_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define class_width 96
#define class_height 64
static unsigned char class_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0xf8, 0xc3, 0x01, 0xc0, 0x07, 0xe0, 0x07, 0xfc, 0x00, 0xc0,
0x03, 0x00, 0xfc, 0xc7, 0x01, 0xc0, 0x07, 0xf8, 0x0f, 0xff, 0x01, 0xc0,
0x03, 0x00, 0xfe, 0xc7, 0x01, 0xc0, 0x07, 0xfc, 0x87, 0xff, 0x00, 0xc0,
0x03, 0x00, 0x0f, 0xc2, 0x01, 0xe0, 0x0e, 0x1c, 0x84, 0x83, 0x00, 0xc0,
0x03, 0x80, 0x07, 0xc0, 0x01, 0xe0, 0x0e, 0x1c, 0x80, 0x03, 0x00, 0xc0,
0x03, 0x80, 0x03, 0xc0, 0x01, 0xf0, 0x1e, 0x3c, 0x80, 0x07, 0x00, 0xc0,
0x03, 0x80, 0x03, 0xc0, 0x01, 0x70, 0x1c, 0xf8, 0x01, 0x3f, 0x00, 0xc0,
0x03, 0x80, 0x03, 0xc0, 0x01, 0x70, 0x1c, 0xf0, 0x07, 0xfe, 0x00, 0xc0,
0x03, 0x80, 0x03, 0xc0, 0x01, 0x78, 0x3c, 0xc0, 0x0f, 0xf8, 0x01, 0xc0,
0x03, 0x80, 0x03, 0xc0, 0x01, 0xf8, 0x3f, 0x00, 0x1e, 0xc0, 0x03, 0xc0,
0x03, 0x80, 0x07, 0xc0, 0x01, 0xfc, 0x3f, 0x00, 0x1c, 0x80, 0x03, 0xc0,
0x03, 0x00, 0x0f, 0xc2, 0x01, 0xfc, 0x7f, 0x08, 0x1c, 0x81, 0x03, 0xc0,
0x03, 0x00, 0xff, 0xc7, 0xff, 0x1c, 0x70, 0xfc, 0x9f, 0xff, 0x03, 0xc0,
0x03, 0x00, 0xfe, 0xc7, 0xff, 0x1e, 0xf0, 0xfc, 0x8f, 0xff, 0x01, 0xc0,
0x03, 0x00, 0xf8, 0xc3, 0xff, 0x0e, 0xe0, 0xf0, 0x03, 0x7e, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define finish_width 96
#define finish_height 64
static unsigned char finish_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0x6e, 0x00, 0x8e, 0xc6, 0x8e, 0x8e, 0x0e, 0xe8, 0xe8, 0xe0, 0xee,
0x57, 0x55, 0x00, 0x04, 0x05, 0x05, 0x05, 0x05, 0x50, 0x50, 0x51, 0xd5,
0xbb, 0x3b, 0x00, 0x8a, 0x03, 0x8b, 0x8b, 0x03, 0xb8, 0xb8, 0xb1, 0xfb,
0x57, 0x55, 0x54, 0x05, 0x05, 0x05, 0x05, 0x41, 0x51, 0x50, 0x51, 0xd5,
0xef, 0x6e, 0xec, 0x8e, 0x06, 0x8e, 0x8e, 0xe2, 0xee, 0xe8, 0xe0, 0xee,
0x57, 0x55, 0x54, 0x05, 0x05, 0x04, 0x05, 0x41, 0x55, 0x50, 0x51, 0xd5,
0xbb, 0x3b, 0x00, 0x8b, 0x03, 0x88, 0x8b, 0x03, 0xba, 0x00, 0xb0, 0xfb,
0x57, 0x55, 0x00, 0x05, 0x45, 0x00, 0x05, 0x05, 0x50, 0x00, 0x50, 0xd5,
0xef, 0x6e, 0x00, 0x8e, 0xc6, 0x80, 0x8e, 0x2e, 0xe0, 0x00, 0xe0, 0xee,
0x57, 0x55, 0x54, 0x05, 0x45, 0x01, 0x05, 0x55, 0x41, 0x50, 0x51, 0xd5,
0xbb, 0x3b, 0xb8, 0x8b, 0x83, 0x83, 0x8b, 0xbb, 0xa3, 0xb8, 0xb1, 0xfb,
0x57, 0x55, 0x54, 0x05, 0x45, 0x01, 0x05, 0x55, 0x41, 0x50, 0x51, 0xd5,
0xef, 0x6e, 0xec, 0x8e, 0xc6, 0x86, 0x8e, 0x02, 0xe0, 0xe8, 0xe0, 0xee,
0x57, 0x55, 0x54, 0x05, 0x45, 0x05, 0x05, 0x01, 0x50, 0x50, 0x51, 0xd5,
0xbb, 0x3b, 0xb8, 0x8b, 0x83, 0x8b, 0x8b, 0x0b, 0xb8, 0xb8, 0xb1, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define flag_hotel_width 96
#define flag_hotel_height 64
static unsigned char flag_hotel_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define india_width 96
#define india_height 64
static unsigned char india_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0xf2, 0x2f, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0xff, 0xff, 0x89, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0xf2, 0xff, 0xff, 0x2f, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xf8, 0xff, 0xff, 0x9f, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0xfe, 0xff, 0xff, 0x7f, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0xff, 0xff, 0xff, 0xff, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0x89, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x23, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0x89, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x23, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0xfe, 0xff, 0xff, 0x7f, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xfc, 0xff, 0xff, 0xbf, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0xfa, 0xff, 0xff, 0x3f, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0xc8, 0xff, 0xff, 0x8b, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0xfe, 0x7f, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xe2,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xc8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define november_width 96
#define november_height 64
static unsigned char november_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0xdf, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x77, 0x77, 0xf7,
0x03, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define orange_width 96
#define orange_height 64
static unsigned char orange_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaf, 0xfa, 0xaf, 0xea, 0xaf, 0xba, 0xfa, 0xaa, 0xbf, 0xfa, 0xef,
0xe3, 0x3f, 0xf0, 0x3f, 0xc0, 0x07, 0x78, 0x70, 0xc0, 0x7f, 0xf8, 0xcf,
0xfb, 0xff, 0xfa, 0xff, 0xea, 0xaf, 0xfa, 0xfa, 0xea, 0xff, 0xfa, 0xef,
0x7b, 0xf0, 0x70, 0xf0, 0xe0, 0x0e, 0xf8, 0x70, 0xf0, 0x20, 0x38, 0xc0,
0xbb, 0xea, 0xfb, 0xea, 0xea, 0xae, 0xfa, 0xfb, 0xfa, 0xaa, 0xba, 0xea,
0x1f, 0xc0, 0x71, 0xe0, 0xf0, 0x1e, 0xf8, 0x73, 0x38, 0x00, 0x38, 0xc0,
0xbf, 0xea, 0xfb, 0xfa, 0xfa, 0xbe, 0xba, 0xfb, 0xba, 0xaa, 0xfa, 0xef,
0x1f, 0xc0, 0xf1, 0x7f, 0x70, 0x1c, 0x38, 0x77, 0x38, 0x70, 0xf8, 0xcf,
0xbf, 0xea, 0xfb, 0xbf, 0xfa, 0xbe, 0xba, 0xff, 0xba, 0xfa, 0xfa, 0xef,
0x1f, 0xc0, 0xf1, 0x0f, 0xf8, 0x3f, 0x38, 0x7e, 0x38, 0x70, 0x38, 0xc0,
0xbf, 0xea, 0xfb, 0xbe, 0xfe, 0xbf, 0xba, 0xfe, 0xfa, 0xfa, 0xba, 0xea,
0x7b, 0xf0, 0x70, 0x38, 0xfc, 0x7f, 0x38, 0x7c, 0xf0, 0x70, 0x38, 0xc0,
0xfb, 0xff, 0xfa, 0xfa, 0xbe, 0xfa, 0xba, 0xfa, 0xfa, 0xff, 0xfa, 0xff,
0xe3, 0x3f, 0x70, 0xf0, 0x1e, 0xf0, 0x38, 0x70, 0xe0, 0x7f, 0xf8, 0xdf,
0xab, 0xbf, 0xfa, 0xea, 0xaf, 0xea, 0xba, 0xfa, 0xaa, 0xbf, 0xfa, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define papa_width 96
#define papa_height 64
static unsigned char papa_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xef, 0xee, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xee, 0xee,
0x57, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xbb, 0xbb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define repeat_one_width 96
#define repeat_one_height 64
static unsigned char repeat_one_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0xd5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbb, 0xbb, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0xd5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0xee, 0xee, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x55, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbb, 0xbb, 0xbb, 0xbb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x43, 0x55, 0x55, 0x55, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0b, 0xef, 0xee, 0xee, 0xae, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x70, 0x55, 0x55, 0x55, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0xc2, 0xbb, 0xbb, 0xbb, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x54, 0x55, 0x55, 0xd5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8b, 0x88, 0xe0, 0xee, 0xee, 0xee, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x55, 0x55, 0x55, 0xd5, 0x03, 0x00, 0x00, 0x00, 0x00,
0x23, 0x22, 0x22, 0xb8, 0xbb, 0xbb, 0xbb, 0x1f, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0xf5, 0x00, 0x00, 0x00, 0x00,
0x8b, 0x88, 0x88, 0x08, 0xee, 0xee, 0xee, 0xee, 0x07, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0x55, 0x3d, 0x00, 0x00, 0x00,
0x23, 0x22, 0x22, 0x22, 0x82, 0xbb, 0xbb, 0xbb, 0xfb, 0x01, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x0f, 0x00, 0x00,
0x8b, 0x88, 0x88, 0x88, 0x88, 0xe0, 0xee, 0xee, 0xee, 0x7e, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xd5, 0x03, 0x00,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0xb0, 0xbb, 0xbb, 0xbb, 0x1f, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xf5, 0x00,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xee, 0xee, 0xee, 0xee, 0x07,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0x55, 0x1d,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xa2, 0xbb, 0xbb, 0xbb, 0x7b,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0x55, 0x1d,
0x8b, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xee, 0xee, 0xee, 0xee, 0x07,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0xf5, 0x00,
0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0xb0, 0xbb, 0xbb, 0xbb, 0x1f, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0xd5, 0x03, 0x00,
0x8b, 0x88, 0x88, 0x88, 0x88, 0xc0, 0xee, 0xee, 0xee, 0x7e, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x0f, 0x00, 0x00,
0x23, 0x22, 0x22, 0x22, 0x02, 0xbb, 0xbb, 0xbb, 0xfb, 0x03, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0x3d, 0x00, 0x00, 0x00,
0x8b, 0x88, 0x88, 0x08, 0xee, 0xee, 0xee, 0xee, 0x07, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0xf5, 0x00, 0x00, 0x00, 0x00,
0x23, 0x22, 0x22, 0xb0, 0xbb, 0xbb, 0xbb, 0x1f, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x55, 0x55, 0x55, 0xd5, 0x01, 0x00, 0x00, 0x00, 0x00,
0x8b, 0x88, 0xe0, 0xee, 0xee, 0xee, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x54, 0x55, 0x55, 0xd5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0xc2, 0xbb, 0xbb, 0xbb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x58, 0x55, 0x55, 0x55, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0b, 0xef, 0xee, 0xee, 0xee, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x43, 0x55, 0x55, 0x55, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbb, 0xbb, 0xbb, 0xbb, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x55, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0xee, 0xee, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0xd5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbb, 0xbb, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x55, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

View File

@@ -1,68 +0,0 @@
#pragma once
#define sierra_width 96
#define sierra_height 64
static unsigned char sierra_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xe8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0e, 0x00, 0xc0,
0x03, 0x00, 0x50, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0xc0,
0x03, 0x00, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x1b, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define start_width 96
#define start_height 64
static unsigned char start_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xfe, 0xfe, 0xff, 0xfa, 0xaa, 0xff, 0xfa, 0xff, 0xab, 0xea,
0x03, 0x00, 0xff, 0xfd, 0x7f, 0xf8, 0x00, 0xff, 0xf3, 0xff, 0x01, 0xc0,
0xab, 0xaa, 0xff, 0xfe, 0xff, 0xfa, 0xaa, 0xff, 0xff, 0xff, 0xab, 0xea,
0x03, 0x80, 0x83, 0x80, 0x03, 0xdc, 0x01, 0x07, 0x0f, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xab, 0xaa, 0xab, 0xfe, 0xab, 0xaf, 0xae, 0xae, 0xaa, 0xea,
0x03, 0x80, 0x07, 0x80, 0x03, 0xde, 0x03, 0x07, 0x0e, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xbf, 0xaa, 0xab, 0xae, 0xab, 0xaf, 0xaf, 0xae, 0xaa, 0xea,
0x03, 0x00, 0xfe, 0x80, 0x03, 0x8e, 0x03, 0xff, 0x07, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xfa, 0xab, 0xab, 0xaf, 0xaf, 0xff, 0xab, 0xae, 0xaa, 0xea,
0x03, 0x00, 0xc0, 0x83, 0x03, 0xff, 0x07, 0xff, 0x00, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xab, 0xab, 0xff, 0xaf, 0xef, 0xab, 0xae, 0xaa, 0xea,
0x03, 0x00, 0x81, 0x83, 0x83, 0xff, 0x0f, 0x87, 0x03, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xff, 0xab, 0xab, 0xab, 0xae, 0xaf, 0xaf, 0xae, 0xaa, 0xea,
0x03, 0x80, 0xff, 0x81, 0xc3, 0x03, 0x1e, 0x07, 0x0f, 0x0e, 0x00, 0xc0,
0xab, 0xaa, 0xfe, 0xaa, 0xeb, 0xab, 0xbe, 0xaf, 0xbe, 0xae, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define uniform_width 96
#define uniform_height 64
static unsigned char uniform_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define xray_width 96
#define xray_height 64
static unsigned char xray_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x03, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define yankee_width 96
#define yankee_height 64
static unsigned char yankee_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x60, 0x55, 0xd5, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x58, 0xd5,
0xab, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xae, 0xea,
0x03, 0x54, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5, 0x00, 0x00, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x83, 0x55, 0x55, 0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5,
0xeb, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xea,
0x53, 0x55, 0x55, 0x00, 0x80, 0x55, 0x55, 0x03, 0x00, 0x54, 0x55, 0xd5,
0xab, 0xaa, 0xba, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xee,
0x57, 0x55, 0x0d, 0x00, 0x50, 0x55, 0x55, 0x00, 0x80, 0x55, 0x55, 0xc3,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xaa, 0xea, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x01, 0x00, 0x56, 0x55, 0x0d, 0x00, 0x50, 0x55, 0x55, 0xc0,
0xab, 0xea, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xea,
0x57, 0x35, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x56, 0x55, 0x0d, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xea,
0x57, 0x05, 0x00, 0x58, 0x55, 0x35, 0x00, 0x40, 0x55, 0x55, 0x01, 0xc0,
0xab, 0xab, 0xaa, 0xae, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xaa, 0xea,
0xd7, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x58, 0x55, 0x35, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xae, 0xaa, 0xaa, 0xaa, 0xea,
0x17, 0x00, 0x60, 0x55, 0xd5, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0xd8,
0xaf, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xee,
0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5, 0x00, 0x00, 0xd5,
0xab, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x80, 0x55, 0x55, 0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0x60, 0xd5,
0xab, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xea,
0x03, 0x50, 0x55, 0x55, 0x00, 0x80, 0x55, 0x55, 0x03, 0x00, 0x54, 0xd5,
0xab, 0xaa, 0xaa, 0xba, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x56, 0x55, 0x0d, 0x00, 0x50, 0x55, 0x55, 0x00, 0x80, 0x55, 0xd5,
0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xaa, 0xea, 0xaa, 0xea,
0x43, 0x55, 0x55, 0x01, 0x00, 0x56, 0x55, 0x0d, 0x00, 0x50, 0x55, 0xd5,
0xab, 0xaa, 0xea, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa,
0x5b, 0x55, 0x35, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x56, 0x55, 0xcd,
0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xab, 0xaa, 0xea,
0x57, 0x55, 0x05, 0x00, 0x58, 0x55, 0x35, 0x00, 0x40, 0x55, 0x55, 0xc1,
0xab, 0xaa, 0xab, 0xaa, 0xae, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xea,
0x57, 0xd5, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x58, 0x55, 0x35, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xae, 0xaa, 0xaa, 0xea,
0x57, 0x15, 0x00, 0x60, 0x55, 0xd5, 0x00, 0x00, 0x55, 0x55, 0x05, 0xc0,
0xab, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xea,
0x57, 0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5, 0x00, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xea,
0x57, 0x00, 0x80, 0x55, 0x55, 0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0xe0,
0xbb, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xfa,
0x0f, 0x00, 0x50, 0x55, 0x55, 0x00, 0x80, 0x55, 0x55, 0x03, 0x00, 0xd4,
0xab, 0xaa, 0xaa, 0xaa, 0xba, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x00, 0x56, 0x55, 0x0d, 0x00, 0x50, 0x55, 0x55, 0x00, 0x80, 0xd5,
0xab, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xaa, 0xea, 0xea,
0x03, 0x40, 0x55, 0x55, 0x01, 0x00, 0x56, 0x55, 0x0d, 0x00, 0x50, 0xd5,
0xab, 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x03, 0x58, 0x55, 0x35, 0x00, 0x40, 0x55, 0x55, 0x01, 0x00, 0x56, 0xd5,
0xab, 0xae, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xab, 0xea,
0x03, 0x55, 0x55, 0x05, 0x00, 0x58, 0x55, 0x35, 0x00, 0x40, 0x55, 0xd5,
0xab, 0xaa, 0xaa, 0xab, 0xaa, 0xae, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0x63, 0x55, 0xd5, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x58, 0x55, 0xf5,
0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xae, 0xaa, 0xea,
0x57, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5, 0x00, 0x00, 0x55, 0x55, 0xc5,
0xab, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xeb,
0x57, 0x55, 0x03, 0x00, 0x54, 0x55, 0x15, 0x00, 0x60, 0x55, 0xd5, 0xc0,
0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xaa, 0xba, 0xaa, 0xaa, 0xea,
0x57, 0x55, 0x00, 0x80, 0x55, 0x55, 0x03, 0x00, 0x54, 0x55, 0x15, 0xc0,
0xab, 0xba, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,68 +0,0 @@
#pragma once
#define zulu_width 96
#define zulu_height 64
static unsigned char zulu_bits[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
0x3f, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xfa,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4,
0xff, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xee,
0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd5,
0xff, 0x2f, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xa2, 0xfb,
0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xd5,
0xff, 0x3f, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xec, 0xee,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xd5,
0xff, 0xff, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xa2, 0xbb, 0xfb,
0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0xd5,
0xff, 0xff, 0x8f, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xf0, 0xee, 0xee,
0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0xd5,
0xff, 0xff, 0xff, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0xba, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0x83, 0x88, 0x88, 0x88, 0x88, 0xc8, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0x3f, 0x22, 0x22, 0x22, 0x22, 0xb8, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0x88, 0x88, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0x2f, 0x22, 0x22, 0xa2, 0xbb, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x50, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xbf, 0x88, 0x88, 0xec, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0x23, 0xa2, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf0, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x54, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xbe, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x57, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xea, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0xab, 0xea, 0xbb, 0xbb, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0xd5, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xee, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0x7f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xaf, 0xaa, 0xaa, 0xba, 0xbb, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0xff, 0x57, 0x55, 0x55, 0x75, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xff, 0xab, 0xaa, 0xaa, 0xaa, 0xee, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xbf, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0xff, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x5d, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xee, 0xee, 0xee,
0xff, 0xff, 0xff, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xfb,
0xff, 0xff, 0x7f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xbf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xee, 0xee, 0xee,
0xff, 0xff, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xff, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xbb, 0xfb,
0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x55, 0xd5,
0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xee, 0xee,
0xff, 0x7f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xff, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0xfb,
0xff, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x75, 0xd5,
0xff, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xee,
0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5,
0xbf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfe,
0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xdd,
0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

View File

@@ -1,14 +0,0 @@
// Add a new register card in web configuration interface
// This is a Java Script!
(function(){
const api=window.esp32nmea2k;
if (! api) return;
const tabName="Screen";
api.registerListener((id, data) => {
// if (!data.testboard) return; //do nothing if we are not active
let page = api.addTabPage(tabName, "Screen");
api.addEl('button', '', page, 'Screenshot').addEventListener('click', function (ev) {
window.open('/api/user/OBP60Task/screenshot', 'screenshot');
})
}, api.EVENTS.init);
})();

View File

@@ -13,13 +13,17 @@
#include "OBP60Extensions.h" // Functions lib for extension board
#include "OBP60Keypad.h" // Functions for keypad
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
#ifdef BOARD_OBP40S3
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
#include <FS.h> // SD-Card access
#include <SD.h>
#include <SPI.h>
#endif
// True type character sets includes
// See OBP60ExtensionPort.cpp
// Pictures
//#include GxEPD_BitmapExamples // Example picture
#include "MFD_OBP60_400x300_sw.h" // MFD with logo
@@ -27,7 +31,7 @@
#include "images/unknown.xbm" // unknown page indicator
#include "OBP60QRWiFi.h" // Functions lib for WiFi QR code
#include "OBPSensorTask.h" // Functions lib for sensor data
#include "OBPTrackerTask.h" // Functions lib for tracker data
// Global vars
bool initComplete = false; // Initialization complete
@@ -41,23 +45,64 @@ void OBP60Init(GwApi *api){
GwConfigHandler *config = api->getConfig();
// Set a new device name and hidden the original name in the main config
String devicename = config->getConfigItem(config->deviceName, true)->asString();
config->setValue(GwConfigDefinitions::systemName, devicename, GwConfigInterface::ConfigType::HIDDEN);
String devicename = api->getConfig()->getConfigItem(api->getConfig()->deviceName,true)->asString();
api->getConfig()->setValue(GwConfigDefinitions::systemName, devicename, GwConfigInterface::ConfigType::HIDDEN);
logger->prefix = devicename + ":";
logger->logDebug(GwLog::LOG,"obp60init running");
api->getLogger()->logDebug(GwLog::LOG,"obp60init running");
// Check I2C devices
// Init power
String powermode = config->getConfigItem(config->powerMode,true)->asString();
logger->logDebug(GwLog::DEBUG, "Power Mode is: %s", powermode.c_str());
powerInit(powermode);
// Init hardware
hardwareInit(api);
#ifdef BOARD_OBP40S3
// 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 BOARD_OBP40S3
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
setPortPin(OBP_POWER_SD, true); // Power on SD card
#endif
}
else{
#ifdef HARDWARE_V21
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
#endif
#ifdef BOARD_OBP40S3
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#endif
}
#ifdef BOARD_OBP40S3
// TODO migrate to new code see OBP60Extensions.cpp
if (config->getBool(config->useSDCard)) {
SPIClass SD_SPI = SPIClass(HSPI);
SD_SPI.begin(SD_SPI_CLK, SD_SPI_MISO, SD_SPI_MOSI);
if (SD.begin(SD_SPI_CS, SD_SPI, 80000000)) {
String sdtype = "unknown";
uint8_t cardType = SD.cardType();
switch (cardType) {
case CARD_MMC:
sdtype = "MMC";
break;
case CARD_SD:
sdtype = "SDSC";
break;
case CARD_SDHC:
sdtype = "SDHC";
break;
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
LOG_DEBUG(GwLog::LOG,"SD card type %s of size %d MB detected", sdtype, cardSize);
SD_SPI.end();
}
}
// Deep sleep wakeup configuration
esp_sleep_enable_ext0_wakeup(OBP_WAKEWUP_PIN, 0); // 1 = High, 0 = Low
rtc_gpio_pullup_en(OBP_WAKEWUP_PIN); // Activate pullup resistor
@@ -66,7 +111,7 @@ void OBP60Init(GwApi *api){
// Settings for e-paper display
String fastrefresh = api->getConfig()->getConfigItem(api->getConfig()->fastRefresh,true)->asString();
logger->logDebug(GwLog::DEBUG, "Fast Refresh Mode is: %s", fastrefresh.c_str());
api->getLogger()->logDebug(GwLog::DEBUG,"Fast Refresh Mode is: %s", fastrefresh.c_str());
#ifdef DISPLAY_GDEY042T81
if(fastrefresh == "true"){
static const bool useFastFullUpdate = true; // Enable fast full display update only for GDEY042T81
@@ -85,11 +130,11 @@ void OBP60Init(GwApi *api){
// Get CPU speed
int freq = getCpuFrequencyMhz();
logger->logDebug(GwLog::LOG,"CPU speed at boot: %i MHz", freq);
api->getLogger()->logDebug(GwLog::LOG,"CPU speed at boot: %i MHz", freq);
// Settings for backlight
String backlightMode = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString();
logger->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", backlightMode.c_str());
api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", backlightMode.c_str());
uint brightness = uint(api->getConfig()->getConfigItem(api->getConfig()->blBrightness,true)->asInt());
String backlightColor = api->getConfig()->getConfigItem(api->getConfig()->blColor,true)->asString();
if(String(backlightMode) == "On"){
@@ -104,7 +149,7 @@ void OBP60Init(GwApi *api){
// Settings flash LED mode
String ledMode = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString();
logger->logDebug(GwLog::DEBUG,"LED Mode is: %s", ledMode.c_str());
api->getLogger()->logDebug(GwLog::DEBUG,"LED Mode is: %s", ledMode.c_str());
if(String(ledMode) == "Off"){
setBlinkingLED(false);
}
@@ -122,8 +167,8 @@ void OBP60Init(GwApi *api){
typedef struct {
int page0=0;
QueueHandle_t queue;
GwLog* logger = nullptr;
// GwApi* api = nullptr;
GwLog* logger = NULL;
// GwApi* api = NULL;
uint sensitivity = 100;
bool use_syspage = true;
} MyData;
@@ -148,37 +193,45 @@ void keyboardTask(void *param){
vTaskDelete(NULL);
}
// Scorgan: moved class declaration to header file <obp60task.h> to make class available to other functions
// --- Class BoatValueList --------------
bool BoatValueList::addValueToList(GwApi::BoatValue *v){
for (int i=0;i<numValues;i++){
if (allBoatValues[i] == v){
//already in list...
return true;
class BoatValueList{
public:
static const int MAXVALUES=100;
//we create a list containing all our BoatValues
//this is the list we later use to let the api fill all the values
//additionally we put the necessary values into the paga data - see below
GwApi::BoatValue *allBoatValues[MAXVALUES];
int numValues=0;
bool addValueToList(GwApi::BoatValue *v){
for (int i=0;i<numValues;i++){
if (allBoatValues[i] == v){
//already in list...
return true;
}
}
if (numValues >= MAXVALUES) return false;
allBoatValues[numValues]=v;
numValues++;
return true;
}
if (numValues >= MAXVALUES) return false;
allBoatValues[numValues]=v;
numValues++;
return true;
}
//helper to ensure that each BoatValue is only queried once
GwApi::BoatValue *BoatValueList::findValueOrCreate(String name){
for (int i=0;i<numValues;i++){
if (allBoatValues[i]->getName() == name) {
return allBoatValues[i];
//helper to ensure that each BoatValue is only queried once
GwApi::BoatValue *findValueOrCreate(String name){
for (int i=0;i<numValues;i++){
if (allBoatValues[i]->getName() == name) {
return allBoatValues[i];
}
}
GwApi::BoatValue *rt=new GwApi::BoatValue(name);
addValueToList(rt);
return rt;
}
GwApi::BoatValue *rt=new GwApi::BoatValue(name);
addValueToList(rt);
return rt;
}
// --- Class BoatValueList --------------
};
//we want to have a list that has all our page definitions
//this way each page can easily be added here
//needs some minor tricks for the safe static initialization
typedef std::vector<PageDescription*> Pages;
//the page list class
class PageList{
public:
Pages pages;
@@ -223,12 +276,10 @@ void registerAllPages(PageList &list){
list.add(&registerPageFourValues2);
extern PageDescription registerPageWind;
list.add(&registerPageWind);
extern PageDescription registerPageWindPlot;
list.add(&registerPageWindPlot);
extern PageDescription registerPageWindRose;
list.add(&registerPageWindRose);
extern PageDescription registerPageWindRoseFlex;
list.add(&registerPageWindRoseFlex);
list.add(&registerPageWindRoseFlex); //
extern PageDescription registerPageVoltage;
list.add(&registerPageVoltage);
extern PageDescription registerPageDST810;
@@ -259,69 +310,67 @@ void registerAllPages(PageList &list){
list.add(&registerPageXTETrack);
extern PageDescription registerPageFluid;
list.add(&registerPageFluid);
extern PageDescription registerPageSkyView;
list.add(&registerPageSkyView);
extern PageDescription registerPageTracker;
list.add(&registerPageTracker);
}
// Undervoltage detection for shutdown display
void underVoltageError(CommonData &common) {
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
// Shutdown EInk display
getdisplay().setFullWindow(); // Set full Refresh
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("Charge battery and restart system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#else
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
// Shutdown EInk display
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("To wake up repower system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
#endif
while (true) {
esp_deep_sleep_start(); // Deep Sleep without wakeup. Wakeup only after power cycle (restart).
}
}
inline bool underVoltageDetection(float voffset, float vslope) {
void underVoltageDetection(GwApi *api, CommonData &common){
// Read settings
double voffset = (api->getConfig()->getConfigItem(api->getConfig()->vOffset,true)->asString()).toFloat();
double vslope = (api->getConfig()->getConfigItem(api->getConfig()->vSlope,true)->asString()).toFloat();
// Read supply voltage
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
float minVoltage = 3.65; // Absolut minimum volatge for 3,7V LiPo accu
#else
#else
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
float minVoltage = MIN_VOLTAGE;
#endif
float calVoltage = actVoltage * vslope + voffset; // Calibration
return (calVoltage < minVoltage);
#endif
double calVoltage = actVoltage * vslope + voffset; // Calibration
if(calVoltage < minVoltage){
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
// Shutdown EInk display
getdisplay().setFullWindow(); // Set full Refresh
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("Charge battery and restart system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
setPortPin(OBP_POWER_SD, false); // Power off SD card
#else
// Switch off all power lines
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
setFlashLED(false); // Flash LED Off
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
// Shutdown EInk display
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
getdisplay().fillScreen(common.bgcolor);// Clear screen
getdisplay().setTextColor(common.fgcolor);
getdisplay().setFont(&Ubuntu_Bold20pt8b);
getdisplay().setCursor(65, 150);
getdisplay().print("Undervoltage");
getdisplay().setFont(&Ubuntu_Bold8pt8b);
getdisplay().setCursor(65, 175);
getdisplay().print("To wake up repower system");
getdisplay().nextPage(); // Partial update
getdisplay().powerOff(); // Display power off
#endif
// Stop system
while(true){
esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart).
}
}
}
// OBP60 Task
@@ -334,6 +383,7 @@ void OBP60Task(GwApi *api){
#ifdef HARDWARE_V21
startLedTask(api);
#endif
PageList allPages;
registerAllPages(allPages);
CommonData commonData;
@@ -368,13 +418,12 @@ void OBP60Task(GwApi *api){
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());
bool tracker_enabled = api->getConfig()->getConfigItem(api->getConfig()->trackerType,true)->asString() != "NONE";
#ifdef BOARD_OBP40S3
bool syspage_enabled = config->getBool(config->systemPage);
#endif
#ifdef DISPLAY_GDEY042T81
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
getdisplay().init(115200, true, 2, false); // Use this for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
#endif
@@ -435,8 +484,6 @@ void OBP60Task(GwApi *api){
int lastPage=pageNumber;
BoatValueList boatValues; //all the boat values for the api query
HstryBuf hstryBufList(960); // Create ring buffers for history storage of some boat data
WindUtils trueWind(&boatValues); // Create helper object for true wind calculation
//commonData.distanceformat=config->getString(xxx);
//add all necessary data to common data
@@ -460,7 +507,6 @@ void OBP60Task(GwApi *api){
pages[i].page=description->creator(commonData);
pages[i].parameters.pageName=pageType;
pages[i].parameters.pageNumber = i + 1;
pages[i].parameters.api = api;
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;uid<description->userParam;uid++){
@@ -479,8 +525,6 @@ void OBP60Task(GwApi *api){
LOG_DEBUG(GwLog::DEBUG,"added fixed value %s to page %d",value->getName().c_str(),i);
pages[i].parameters.values.push_back(value);
}
// Add boat history data to page parameters
pages[i].parameters.boatHstry = &hstryBufList;
}
// add out of band system page (always available)
Page *syspage = allPages.pages[0]->creator(commonData);
@@ -488,13 +532,6 @@ void OBP60Task(GwApi *api){
// Read all calibration data settings from config
calibrationData.readConfig(config, logger);
// Check user settings for true wind calculation
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
// Initialize history buffer for certain boat data
hstryBufList.init(&boatValues, logger);
// Display screenshot handler for HTTP request
// http://192.168.15.1/api/user/OBP60Task/screenshot
api->registerRequestHandler("screenshot", [api, &pageNumber, pages](AsyncWebServerRequest *request) {
@@ -515,16 +552,6 @@ void OBP60Task(GwApi *api){
SharedData *shared=new SharedData(api);
createSensorTask(shared);
// Tracker task
if (tracker_enabled) {
TrackerData trackerData;
trackerData.api = api;
trackerData.logger = logger;
createTrackerTask(&trackerData);
} else {
LOG_DEBUG(GwLog::LOG, "Tracker not enabled. No task created.");
}
// Task Loop
//####################################################################################
@@ -538,9 +565,7 @@ void OBP60Task(GwApi *api){
commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness,true)->asInt());
commonData.powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
bool uvoltage = config->getConfigItem(config->underVoltage, true)->asBoolean();
float voffset = (config->getConfigItem(config->vOffset,true)->asString()).toFloat();
float vslope = (config->getConfigItem(config->vSlope,true)->asString()).toFloat();
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());
@@ -548,7 +573,7 @@ void OBP60Task(GwApi *api){
double homelon = commonData.config->getString(commonData.config->homeLON).toDouble();
bool homevalid = homelat >= -180.0 and homelat <= 180 and homelon >= -90.0 and homelon <= 90.0;
if (homevalid) {
LOG_DEBUG(GwLog::LOG, "Home location set to lat=%f, lon=%f", homelat, homelon);
LOG_DEBUG(GwLog::LOG, "Home location set to %f : %f", homelat, homelon);
} else {
LOG_DEBUG(GwLog::LOG, "No valid home location found");
}
@@ -582,18 +607,14 @@ void OBP60Task(GwApi *api){
//####################################################################################
bool systemPage = false;
bool systemPageNew = false;
Page *currentPage;
while (true){
delay(100); // Delay 100ms (loop time)
bool keypressed = false;
// Undervoltage detection
if (uvoltage == true) {
if (underVoltageDetection(voffset, vslope)) {
LOG_DEBUG(GwLog::ERROR, "Undervoltage detected, shutting down!");
underVoltageError(commonData);
}
if(uvoltage == true){
underVoltageDetection(api, commonData);
}
// Set CPU speed after boot after 1min
@@ -638,7 +659,6 @@ void OBP60Task(GwApi *api){
systemPage = true; // System page is out of band
syspage->setupKeys();
keyboardMessage = 0;
systemPageNew = true;
}
else {
currentPage = pages[pageNumber].page;
@@ -729,23 +749,12 @@ void OBP60Task(GwApi *api){
starttime1 = millis();
starttime2 = millis();
getdisplay().setFullWindow(); // Set full update
if(fastrefresh == "true"){
getdisplay().nextPage(); // Full update
}
else{
getdisplay().nextPage();
if(fastrefresh == "false"){
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
#endif
getdisplay().firstPage(); // Full update
getdisplay().nextPage(); // Full update
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
// getdisplay().nextPage(); // Partial update
// getdisplay().nextPage(); // Partial update
getdisplay().fillScreen(commonData.bgcolor); // Clear display
getdisplay().nextPage(); // Full update
}
delayedDisplayUpdate = false;
}
@@ -757,23 +766,12 @@ void OBP60Task(GwApi *api){
starttime2 = millis();
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh first 5 min");
getdisplay().setFullWindow(); // Set full update
if(fastrefresh == "true"){
getdisplay().nextPage(); // Full update
}
else{
getdisplay().nextPage();
if(fastrefresh == "false"){
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
#endif
getdisplay().firstPage(); // Full update
getdisplay().nextPage(); // Full update
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
// getdisplay().nextPage(); // Partial update
// getdisplay().nextPage(); // Partial update
getdisplay().fillScreen(commonData.bgcolor); // Clear display
getdisplay().nextPage(); // Full update
}
}
@@ -782,23 +780,12 @@ void OBP60Task(GwApi *api){
starttime2 = millis();
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh");
getdisplay().setFullWindow(); // Set full update
if(fastrefresh == "true"){
getdisplay().nextPage(); // Full update
}
else{
getdisplay().nextPage();
if(fastrefresh == "false"){
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
#endif
getdisplay().firstPage(); // Full update
getdisplay().nextPage(); // Full update
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
// getdisplay().nextPage(); // Partial update
// getdisplay().nextPage(); // Partial update
getdisplay().fillScreen(commonData.bgcolor); // Clear display
getdisplay().nextPage(); // Full update
}
}
@@ -817,12 +804,6 @@ void OBP60Task(GwApi *api){
api->getBoatDataValues(boatValues.numValues,boatValues.allBoatValues);
api->getStatus(commonData.status);
if (calcTrueWnds) {
trueWind.addTrueWind(api, &boatValues, logger);
}
// Handle history buffers for TWD, TWS for wind plot page and other usage
hstryBufList.handleHstryBuf(useSimuData);
// Clear display
// getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);
getdisplay().fillScreen(commonData.bgcolor); // Clear display
@@ -837,11 +818,6 @@ void OBP60Task(GwApi *api){
if (systemPage) {
displayFooter(commonData);
PageData sysparams; // empty
sysparams.api = api;
if (systemPageNew) {
syspage->displayNew(sysparams);
systemPageNew = false;
}
syspage->displayPage(sysparams);
}
else {
@@ -858,11 +834,10 @@ void OBP60Task(GwApi *api){
}
else{
if (lastPage != pageNumber){
pages[lastPage].page->leavePage(pages[lastPage].parameters); // call page cleanup code
if (hasFRAM) fram.write(FRAM_PAGE_NO, pageNumber); // remember new page for device restart
if (hasFRAM) fram.write(FRAM_PAGE_NO, pageNumber); // remember page for device restart
currentPage->setupKeys();
currentPage->displayNew(pages[pageNumber].parameters);
lastPage = pageNumber;
lastPage=pageNumber;
}
//call the page code
LOG_DEBUG(GwLog::DEBUG,"calling page %d",pageNumber);

View File

@@ -41,24 +41,5 @@
#ifdef BOARD_OBP40S3
DECLARE_CAPABILITY(obp40,true)
#endif
#ifdef BOARD_OBP60S3
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/en/latest/"); // Link to help pages
#endif
#ifdef BOARD_OBP40S3
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp40-v1-docu.readthedocs.io/en/latest/"); // Link to help pages
#endif
class BoatValueList{
public:
static const int MAXVALUES=100;
//we create a list containing all our BoatValues
//this is the list we later use to let the api fill all the values
//additionally we put the necessary values into the paga data - see below
GwApi::BoatValue *allBoatValues[MAXVALUES];
int numValues=0;
bool addValueToList(GwApi::BoatValue *v);
//helper to ensure that each BoatValue is only queried once
GwApi::BoatValue *findValueOrCreate(String name);
};
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/de/latest/"); // Link to help pages
#endif

View File

@@ -43,17 +43,16 @@ lib_deps =
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 CORE_DEBUG_LEVEL=1 #Debug level for CPU core via 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 DISPLAY_GDEW042T2 #old E-Ink display from GoodDisplay (Waveshare), R10 0.47 ohm - very good
-D DISPLAY_GDEY042T81 #new E-Ink display from GoodDisplay (Waveshare), R10 2.2 ohm - good (contast lost by shunshine)
# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm - medium
# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm - bad (burn in effects)
# -D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
# -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 download via USB-C direct
@@ -74,7 +73,6 @@ lib_deps =
SPI
SD
ESP32time
PubSubClient
esphome/AsyncTCP-esphome@2.0.1
robtillaart/PCF8574@0.3.9
adafruit/Adafruit Unified Sensor @ 1.1.13
@@ -98,8 +96,7 @@ build_flags=
-D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib
-D BOARD_OBP40S3 #Board OBP40 with ESP32S3
-D HARDWARE_V10 #OBP40 hardware revision V1.0 SKU:DIE07300S V1.1 (CrowPanel 4.2)
-D DISPLAY_GDEY042T81 #new E-Ink display from Good Display (Waveshare), R10 2.2 ohm - good (contast lost by shunshine)
#-D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
-D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm
#-D LIPO_ACCU_1200 #Hardware extension, LiPo accu 3,7V 1200mAh
#-D VOLTAGE_SENSOR #Hardware extension, LiPo voltage sensor with two resistors
${env.build_flags}