Commit 2906d93c by Alonso García

Initial commit

parents
//------Incluir librerias EspNow----
#include <esp_now.h>
#include <WiFi.h>
//----------------------------------
//-------Librerias Display----------
#include <u8g2_fonts.h>
#include <U8g2_for_Adafruit_GFX.h>
#include "dsdigital.c" // custom made DS-digital font
#include <SSD1283A.h> //Hardware-specific library
//----------------------------------
//-------Librerias Barometro---
#include <SFE_BMP180.h>
#include <Preferences.h>
#define DEBUG
// ---- Libreria BLE -----------
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
// -----------------------------
SSD1283A screen(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*LED=*/ 4); // pins to ESP32: hardware spi,cs,cd,reset, led
U8G2_FOR_ADAFRUIT_GFX gfx;
GFXcanvas16T<130, 130> canvas;
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define LIME 0xAFEB
const unsigned char thermometer_bits [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
0x90, 0x00, 0x00, 0x90, 0x00, 0x00, 0x90, 0x00, 0x00, 0x90, 0x00, 0x00, 0x90, 0x00, 0x00, 0x90,
0x00, 0x01, 0x68, 0x00, 0x01, 0x68, 0x00, 0x01, 0x88, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'Logotipo Vectorizado', 129x129px
static unsigned char logo_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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xe0, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x7e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00,
0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0,
0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0xfc, 0x0f, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x0e, 0x00, 0x00,
0x00, 0xfc, 0x0f, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x0e, 0x00,
0x00, 0x00, 0xfc, 0x0f, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x0e,
0x00, 0x00, 0x00, 0xfc, 0x07, 0xe0, 0x00, 0x3f, 0x80, 0x7e, 0x01, 0xff, 0x03, 0xfc, 0x03, 0xf8,
0x0e, 0x00, 0x00, 0x00, 0xfe, 0x07, 0xe0, 0x00, 0x3f, 0xe1, 0xff, 0x01, 0xff, 0x83, 0xfc, 0x07,
0xfc, 0x0e, 0x00, 0x00, 0x00, 0x7e, 0x03, 0xe0, 0x00, 0x38, 0xc1, 0xc3, 0x81, 0xc3, 0x80, 0xe0,
0x0f, 0x1c, 0x0e, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xe0, 0x00, 0x38, 0x03, 0x83, 0x81, 0x81, 0xc0,
0xe0, 0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x38, 0x03, 0x81, 0x81, 0x81,
0xc0, 0xe0, 0x1c, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x38, 0x03, 0xff, 0x81,
0x81, 0xc0, 0xe0, 0x1f, 0xfe, 0x0e, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x38, 0x03, 0xff,
0x81, 0x81, 0xc0, 0xe0, 0x1f, 0xfc, 0x0e, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x38, 0x03,
0x80, 0x01, 0x81, 0xc0, 0xe0, 0x1c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x38,
0x03, 0x80, 0x01, 0x81, 0xc0, 0xe0, 0x1c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00,
0x38, 0x03, 0xc0, 0x01, 0x81, 0xc0, 0xe0, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x03, 0xff, 0xe0,
0x00, 0x38, 0x01, 0xe3, 0x01, 0x81, 0xc0, 0x72, 0x0f, 0x98, 0x0e, 0x00, 0x00, 0x00, 0x01, 0xff,
0xe0, 0x00, 0x38, 0x01, 0xff, 0x01, 0x81, 0xc0, 0x7e, 0x07, 0xfc, 0x0f, 0x80, 0x00, 0x00, 0x00,
0xff, 0xe0, 0x00, 0x38, 0x00, 0x7f, 0x01, 0x81, 0xc0, 0x3e, 0x03, 0xf8, 0x07, 0x80, 0x00, 0x00,
0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
//30*34px
static unsigned char signal_transmitting_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, 0x30, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00,
0x01, 0x9c, 0x00, 0x00, 0x01, 0x98, 0xc0, 0x00, 0x01, 0x99, 0xc0, 0x00, 0x03, 0xb9, 0x8c, 0x00,
0x03, 0xb1, 0x9e, 0x00, 0x03, 0xb1, 0x9e, 0x00, 0x03, 0xb9, 0x8c, 0x00, 0x01, 0x99, 0xc0, 0x00,
0x01, 0x98, 0xc0, 0x00, 0x01, 0x9c, 0x80, 0x00, 0x01, 0xce, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00,
0x00, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//30*34px
const unsigned char signal_connected_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, 0x30, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00,
0x01, 0x9c, 0x00, 0x00, 0x01, 0x98, 0xc0, 0x00, 0x01, 0x99, 0xc0, 0x00, 0x03, 0xb9, 0x8c, 0x00,
0x03, 0xb1, 0x9e, 0x00, 0x03, 0xb1, 0x9e, 0x00, 0x03, 0xb9, 0x8c, 0x00, 0x01, 0x99, 0xc0, 0x00,
0x01, 0x98, 0xc0, 0x00, 0x01, 0x9c, 0x80, 0x00, 0x01, 0xce, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00,
0x00, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//30*34
const unsigned char signal_noconnection_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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//------Variables del acelerador----
short hallMeasurement;
float throttle = 0;
//----------------------------------
//--------Pines-------
const int LED = 32;
const int encendidoPin = 33;
const int apagadoPin = 25;
const int resetPin = 27;
const byte DmPin = 34;
//const byte ModePin = 23;
const byte ModePin = 35;
const int batteryMeasurePin = 36;
const int hallSensorPin = 39;
const int cambioTelemetriaPin = 14;
//-------------------------
//------Battery monitering---------
const float minVoltage = 2;
const float maxVoltage = 3;
const float refVoltage = 3.3; // Set to 4.5V if you are testing connected to USB, otherwise 5V (or the supply voltage)
const float minMotorVoltage = 60.0;
const float maxMotorVoltage = 130.0;
//-----------------------------------
//--Defining variables for OLED display--
char displayBuffer[20];
String displayString;
short displayData = 0;
int encenderLed = 0;
unsigned long lastSignalBlink;
//---------------------------------------
//--------Barómetro-----------
SFE_BMP180 bmp180;
double presioncero; //presion del punto inicial para h=0;
char status;
double temp, presion, altitud;
boolean barometro;
//----------------------------
//-----Variable EspNow-----
static boolean connectNow = false;
//------------------------
//------Variables del mando----
int imanes = 10;
int lang = 0;
int contador = 1;
bool conf = false;
bool puls = false;
int imanesAddress = 0;
int langAddress = 1;
short menuData = 0;
short langData = 0;
short bluetoothData = 0;
int resetSen = 0;
int encendidoSen = 0;
int apagadoSen = 0;
int cambioTelemetriaSen = 0;
bool pulsado = false;
bool confMotor = false;
bool confLang = false;
bool confBluetooth = false; // BLE
Preferences preferences;
//-----------------------------
//----Direccion MAC con la que queremos conectar---
//uint8_t broadcastAddress[] = {0x3C,0x71,0xBF,0x68,0xA2,0xBC};// Mac de la placa sin caja
//uint8_t broadcastAddress[] = {0x3C,0x71,0xBF,0x59,0x04,0x10};// Mac de la que no funciona el uar
//uint8_t broadcastAddress[] = {0x3C,0x71,0xBF,0x58,024,0x68};// Mac de la que tiene caja y funciona el uar
//uint8_t broadcastAddress[] = {0xA4,0xCF,0x12,0x44,0xF0,0xDC};// Mac de la placa RX2
//uint8_t broadcastAddress[] = {0x7C,0x9E,0xBD,0xF5,0x81,0x6C};// Mac de la placa RX3
//uint8_t broadcastAddress[] = {0x7C,0x9E,0xBD,0xF6,0x48,0x0C};// Mac de la placa RX4
//uint8_t broadcastAddress[] = {0x7C,0x9E,0xBD,0xF5,0x5A,0x1C};// Mac de la placa RX5
//uint8_t broadcastAddress[] = {0xE8,0x68,0xE7,0x21,0xB5,0x6C};// Mac de la placa v4-p1
uint8_t broadcastAddress[] = {0xE8, 0xDB, 0x84, 0x12, 0x40, 0x0C}; // Mac de la placa v4-p2
//----Definimos variables entrantes para leer---
//float pruebaIn;
float ampHoursIn = 0;
float inpVoltageIn = 0;
long rpmIn = 0;
long tachometerAbsIn = 0;
float avgMotorCurrentIn = 0;
float avgInputCurrentIn = 0;
float temp_pcbIn = 0;
float temp_motorIn = 0;
float watiosHoraIn = 0;
float potenciaIn = 0;
int placaOnIn = 0;
//---------------------------------------------
// ----- BLE atributos ------------------------
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
int pos;
int cur;
// --------------------------------------------
//------Variable para almacenar exito---
String success;
//--------------------------------------
//------Estructura para enviar datos---
// Debe coincidir con la estructura del receptor
typedef struct struct_message {
//float prueba;
float acel;
float ampHours;
float inpVoltage;
long rpm;
long tachometerAbs;
float avgMotorCurrent;
float avgInputCurrent;
float potCal;
float temp_pcb;
float temp_motor;
float watiosHora;
float potencia;
int encendido;
int apagado;
int placaOn;
int Reset;
int cambioTelemetria;
} struct_message;
//----------------------------------
//-----Creamos una estructura para almacenar las lecturas de sensor--
struct_message SensorReadings;
//------------------------------------------------------------------
//----Creamos una estructura para almacenar las lecturas de sensor entrantes--
struct_message incomingReadings;
//----------------------------------------------------------------------------
//--------------------Callback when data is sent-------------------------------------
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status == 0) {
success = "Delivery Success :)";
connectNow = true;//si logramos eniar un paquete esque estamos conectados por lo tanto ponemos a true connectNow
}
else {
success = "Delivery Fail :(";
connectNow = false;//En el caso de que no se puedan enviar paquetes icializamos todos los valores a 0 o false
ampHoursIn = 0;
inpVoltageIn = 0;
rpmIn = 0;
tachometerAbsIn = 0;
avgMotorCurrentIn = 0;
avgInputCurrentIn = 0;
temp_pcbIn = 0;
temp_motorIn = 0;
watiosHoraIn = 0;
potenciaIn = 0;
placaOnIn = 0;
}
}
//------------------------------------------------------------------------------------
//--------------------Callback when data is received---------------------------------
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print("Bytes received: ");//solo podemos recibir 250 bytes por paquete
//Serial.println(len);
// pruebaIn = incomingReadings.prueba;
ampHoursIn = incomingReadings.ampHours;
inpVoltageIn = incomingReadings.inpVoltage;
rpmIn = incomingReadings.rpm;
tachometerAbsIn = incomingReadings.tachometerAbs;
avgMotorCurrentIn = incomingReadings.avgMotorCurrent;
avgInputCurrentIn = incomingReadings.avgInputCurrent;
temp_pcbIn = incomingReadings.temp_pcb;
temp_motorIn = incomingReadings.temp_motor;
watiosHoraIn = incomingReadings.watiosHora;
potenciaIn = incomingReadings.potencia;
placaOnIn = incomingReadings.placaOn;
// Mostramos los datos recibidos por pantalla (monitor serie)
// Serial.println(ampHoursIn);
// Serial.println(inpVoltageIn);
// Serial.println(rpmIn);
// Serial.println(tachometerAbsIn);
// Serial.println(avgMotorCurrentIn);
// Serial.println(avgInputCurrentIn);
// Serial.println(temp_pcbIn);
// Serial.println(temp_motorIn);
// Serial.println(watiosHoraIn);
// Serial.println(potenciaIn);
}
//-----------------------------------------------------------------------------------
//------Return true if Switches are activated, false otherwise-----
boolean DmActive() {
if (digitalRead(DmPin) == HIGH)
return true;
else
return false;
}
//Funcion para comprobar si se pulsa el boton para cambiar modo
boolean ModeActive() {
unsigned long duration;
//double puls = 0;
if (digitalRead(ModePin) == HIGH) {
// puls = millis();
// if(millis()- puls < 100){
// return true;
// }
// if(millis() - puls >= 100){
// return false;
// }
duration = pulseIn(ModePin, HIGH);
if (duration <= 100) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
//------------------------------------------------------------
//-----Función que enciende el display----
void drawStartScreen() {
canvas.fillScreen(BLACK);
canvas.setTextColor(WHITE);
canvas.drawBitmap(0, 0, logo_bits, 129, 129, WHITE, BLACK) ;
show_canvas_on_screen();
delay(3000);
canvas.fillScreen(BLACK);
show_canvas_on_screen();
}
//---------------------------------------
//------------Funcion para configurar los imanes del motor------
void displayConfMotor() {
canvas.fillScreen(BLACK);
displayString = "CONFIG.";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor( 3, 10);
canvas.println(String(displayBuffer));
if (lang == 0) {
displayString = "N.imanes motor:";
} else if (lang == 1) {
displayString = "Motor Magnets:";
}
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor( 20, 47);
canvas.println(String(displayBuffer));
if (!DmActive() && puls == false) {
puls = true;
}
if (DmActive() && puls == true) {
preferences.putUInt("imanes", contador);
preferences.end();
delay(20);
ESP.restart();
}
displayString = (String) contador;
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor( 65, 59.5);
canvas.println(String(displayBuffer));
if (lang == 0) {
displayString = "N.Imanes Actual:";
} else if (lang == 1) {
displayString = "Current Magnets:";
}
displayString.toCharArray(displayBuffer, 30);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor( 20, 72);
canvas.println(String(displayBuffer));
displayString = (String) imanes;
displayString.toCharArray(displayBuffer, 30);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(65, 84.5);
canvas.println(String(displayBuffer));
show_canvas_on_screen();
}
//---------------------------------------------------------
// ---- Configuración de bluetooth -----------------------
void displayBluetooth() {
canvas.fillScreen(BLACK);
displayString = "Seleccionar";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(3, 5);
canvas.println(String(displayBuffer));
BLEDevice::init("Mando");
pBLEScan = BLEDevice::getScan();
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
int deviceCount = foundDevices.getCount();
pos = 20;
cur = 20;
uint32_t i = 0;
for (i; i < 2; i++)
{
BLEAdvertisedDevice device = foundDevices.getDevice(i);
broadcastAddress = device.getAddress()
displayString = device.getAddress().toString().c_str();
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
if (i == 0) {
canvas.setCursor(20, pos);
} else {
canvas.setCursor(20, pos += 10);
}
canvas.println(String(displayBuffer));
}
i = 0;
if (bluetoothData > 1) {
bluetoothData = 0;
}
switch (bluetoothData) {
case 0:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(3, 20);
canvas.println(String(displayBuffer));
break;
case 1:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(3, 30);
canvas.println(String(displayBuffer));
break;
}
// if (throttle == 0 && puls == false) {
// puls = true;
// }
//
// if (throttle == 255 && puls == true) {
// if (bluetoothData == 0) {
// preferences.putUInt("ble", bluetoothData);
// preferences.end();
// delay(20);
// ESP.restart();
// } else if (bluetoothData == 1) {
// preferences.putUInt("ble", bluetoothData);
// preferences.end();
// delay(20);
// ESP.restart();
// }
// }
show_canvas_on_screen();
}
// -------------------------------------------------------
//------Configuramos el lenguaje del mando-----------------
void displayConfLang() {
canvas.fillScreen(BLACK);
displayString = "CONFIG.";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor(3, 10);
canvas.println(String(displayBuffer));
displayString = "Espaniol";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(30, 50);
canvas.println(String(displayBuffer));
displayString = "English";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(30, 70);
canvas.println(String(displayBuffer));
if (langData > 1) {
langData = 0;
}
switch (langData) {
case 0:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(0, 50);
canvas.println(String(displayBuffer));
break;
case 1:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(0, 70);
canvas.println(String(displayBuffer));
break;
}
if (throttle == 0 && puls == false) {
puls = true;
}
if (throttle == 255 && puls == true) {
if (langData == 0) {
preferences.putUInt("lang", langData);
preferences.end();
delay(20);
ESP.restart();
} else if (langData == 1) {
preferences.putUInt("lang", langData);
preferences.end();
delay(20);
ESP.restart();
}
}
show_canvas_on_screen();
}
//--------------------------------------------------------------
//----------En esta función inicializamos el menu pricipal del display------
void menuDisplay() {
canvas.fillScreen(BLACK);
displayString = "CONFIG.";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor(10, 10);
canvas.println(String(displayBuffer));
displayString = "Engine/Motor";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(30, 50);
canvas.println(String(displayBuffer));
displayString = "Lang./Idioma";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(30, 70);
canvas.println(String(displayBuffer));
displayString = "Bluetooth";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(30, 90);
canvas.println(String(displayBuffer));
if (menuData > 3) {
menuData = 0;
}
switch (menuData) {
case 0:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(10, 50);
canvas.println(String(displayBuffer));
break;
case 1:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(10, 70);
canvas.println(String(displayBuffer));
break;
case 2:
displayString = ">>";
displayString.toCharArray(displayBuffer, 20);
canvas.setTextColor(WHITE);
canvas.setTextSize(1);
canvas.setCursor(10, 90);
canvas.println(String(displayBuffer));
break;
}
if (throttle == 255) {
if (menuData == 0) {
displayConfMotor();
confMotor = true;
} else if (menuData == 1) {
displayConfLang();
confLang = true;
} else if (menuData == 2) { // BLE
displayBluetooth(); // BLE
confBluetooth = true; // BLE
}
}
show_canvas_on_screen();
}
//-----------------------------------------------------------------------
//-------------------Funcion calcular altura--------------
void calAlt() {
if (barometro) {
status = bmp180.startTemperature();//Inicio de lectura de temperatura
if (status != 0)
{
delay(status); //Pausa para que finalice la lectura
status = bmp180.getTemperature(temp);//Obtener la temperatura
if (status != 0)
{
status = bmp180.startPressure(3);//Inicio lectura de presión
if (status != 0)
{
delay(status);//Pausa para que finalice la lectura
status = bmp180.getPressure(presion, temp); //Obtenemos la presión
if (status != 0)
{
//-------Calculamos la altura con respecto al punto de referencia--------
altitud = bmp180.altitude(presion, presioncero);
}
}
}
}
}
}
//-------------------------------------------------------------
//------Funcion que calcula la posicion del acelerador------
void calculateThrottlePosition() {
// Hall sensor reading can be noisy, lets make an average reading.
int total = 0;
for (int j = 0; j < 25; j++) {
total += analogRead(hallSensorPin);
}
hallMeasurement = total / 25;
//DEBUG_PRINT("hallMeasurement" + (String)hallMeasurement );
throttle = map(hallMeasurement, 0, 4095, 0, 255);
}
//--------------------------------------------------------
//-----Function to calculate and return the remotes battery voltage------
float batteryVoltage() {
float batteryVoltage = 0.0;
int total = 0;
for (int i = 0; i < 10; i++) {
total += analogRead(batteryMeasurePin);
}
batteryVoltage = (refVoltage / 4095.0) * ((float)total / 10.0);
return batteryVoltage;
}
//--------------------------------------------------------------------------
//----Function used to indicate the remotes battery level-------
int batteryLevel() {
float voltage = batteryVoltage();
if (voltage <= minVoltage) {
return 0;
} else if (voltage >= maxVoltage) {
return 100;
} else {
return (voltage - minVoltage) * 100 / (maxVoltage - minVoltage);
}
}
//----------------------------------------------------------------
//--------Función para Calcular la bateria del motor-----------------
int batteryLevelMotor() {
float voltage = inpVoltageIn;
if (voltage <= minMotorVoltage) {
return 0;
} else if (voltage >= maxMotorVoltage) {
return 100;
} else {
return (voltage - minMotorVoltage) * 100 / (maxMotorVoltage - minMotorVoltage);
}
}
//------------------------------------------------------------------------
//-----Funcion para encender y apagar la placa----
void OnOf() {
if (connectNow == true) {
if (digitalRead(encendidoPin) == HIGH) {
encendidoSen = 1;
apagadoSen = 0;
}
if (digitalRead(apagadoPin) == HIGH) {
encendidoSen = 0;
apagadoSen = 1;
}
if ((digitalRead(encendidoPin) == LOW) && (digitalRead(apagadoPin) == LOW)) {
encendidoSen = 0;
apagadoSen = 0;
}
// Serial.print("Encendido: ");
// Serial.println(encendidoSen);
// Serial.print("Apagado: ");
// Serial.println(apagadoSen);
}
if (placaOnIn == 1) {
digitalWrite(LED, HIGH);
}
else {
digitalWrite(LED, LOW);
}
}
//-----------------------------------------------------
//---------Funcion que realiza el reset de la placa--------
void doReset() {
if (connectNow == true) {
if (digitalRead(resetPin) == HIGH) {
resetSen = 1;
}
else {
resetSen = 0;
}
}
}
//-----------------------------------------------------------
//---------Funcion que realiza el cambio de telemetria--------
void cambioTelemetria() {
if (digitalRead(cambioTelemetriaPin) == HIGH) {
cambioTelemetriaSen = 1;
}
else {
cambioTelemetriaSen = 0;
}
}
//-----------------------------------------------------------
//-----Función que actualiza el display para mostrar los valores------
void updateMainDisplay() {
canvas.fillScreen(BLACK);
canvas.setTextColor(WHITE);
drawSignal();
drawThrottle();
drawPage();
drawBatteryLevel();
drawBatteryMotor();
drawAltitude();
drawTemp();
show_canvas_on_screen();
}
//-----------------------------------------------------------------
//------Función que dibuja la posicion del acelerador-----
void drawThrottle() {
int x = 3;
int y = 1;
// Draw throttle
canvas.writeFastHLine(x, y, 85, WHITE);
canvas.writeFastVLine(x, y, 8, WHITE);
canvas.writeFastVLine(x + 85, y, 8, WHITE);
canvas.writeFastHLine(x, y + 8, 5, WHITE);
canvas.writeFastHLine(x + 85 - 4, y + 8, 5, WHITE);
// show_canvas_on_screen();
int width = map(throttle, 0, 255, 0, 84);
for (int i = 0; i < width; i++) {
canvas.writeFastVLine(x + 85 - i, y + 2, 5, WHITE);
}
// show_canvas_on_screen();
}
//---------------------------------------------------------
//----Funcion que pinta Velocidad, Potencia, Bateria y Consumo-----
void drawPage() {
int decimals;
double val;
String suffix;
String prefix;
int first, last;
int x = 4;
int y = 20;
if (displayData > 5) {
displayData = 0;
}
switch (displayData) {
case 0:
//value = ratioRpmSpeed * data.rpm;
val = rpmIn / imanes;
suffix = "RPM";
if (lang == 0) {
prefix = "VELOCIDAD";
} else if (lang == 1) {
prefix = "SPEED";
}
decimals = 2;
break;
case 1:
val = potenciaIn;
suffix = "W";
if (lang == 0) {
prefix = "POTENCIA";
} else if (lang == 1) {
prefix = "ELEC. POWER";
}
decimals = 2;
break;
case 2:
val = inpVoltageIn;
suffix = "V";
if (lang == 0) {
prefix = "BATERIA";
} else if (lang == 1) {
prefix = "BATTERY";
}
decimals = 2;
break;
case 3:
val = watiosHoraIn;
suffix = "Wh";
if (lang == 0) {
prefix = "CONSUMO";
} else if (lang == 1) {
prefix = "CONSUMPTION";
}
decimals = 2;
break;
case 4:
val = avgMotorCurrentIn;
suffix = "Mot.";
if (lang == 0) {
prefix = "INTENSIDAD";
} else if (lang == 1) {
prefix = "CURRENT";
}
decimals = 2;
break;
case 5:
val = avgInputCurrentIn;
suffix = "Bat.";
if (lang == 0) {
prefix = "INTENSIDAD";
} else if (lang == 1) {
prefix = "CURRENT";
}
decimals = 2;
break;
}
// Display prefix (title)
displayString = prefix;
displayString.toCharArray(displayBuffer, 14);
canvas.setTextColor(LIME);
canvas.setTextSize(1);
canvas.setCursor(x , y + 2);
canvas.println(String(displayBuffer));
// mylcd.Print_String( displayBuffer, x , y + 2);
// show_canvas_on_screen();
// Split up the float value: a number, b decimals.
first = val;
last = val * pow(10, 3) - first * pow(10, 3);
// Add leading zero
if (first <= 9) {
displayString = "000" + (String)first;
} else if (first <= 99) {
displayString = "00" + (String)first;
} else if (first <= 999) {
displayString = "0" + (String)first;
} else {
displayString = (String)first;
}
// Display numbers
displayString.toCharArray(displayBuffer, 10);
gfx.setFont(dsdigital_42);
gfx.setCursor(x , y + 60);
gfx.setForegroundColor(WHITE);
gfx.println(displayBuffer);
// // Display suffix
displayString = suffix;
displayString.toCharArray(displayBuffer, 10);
canvas.setTextColor(LIME);
canvas.setTextSize(1);
canvas.setCursor(x + 70 , y + 2);
canvas.println(String(displayBuffer));
}
//---------------------------------------------------
//--------Funcion para mostrar por display el nivel de bateria del mando----
void drawBatteryLevel() {
int level = batteryLevel();
// Position on OLED
int x = 105; int y = 2;
canvas.drawRect ( x + 2, y, 16 , 10, WHITE);
canvas.fillRect (x, y + 2, 2, 6, WHITE);
for (int i = 0; i < 5; i++) {
int p = round((100 / 5) * i);
if (p <= level)
{
canvas.fillRect ( x + 14 - (3 * i), y + 1, 3, 8, GREEN);
}
}
}
//-----------------------------------------------------------------------------
//--------------Funcion para dibujar la bateria del motor--------------
void drawBatteryMotor() {
int level = batteryLevelMotor();
// Position on OLED
int x = 10; int y = 110;
canvas.drawRect ( x - 2, y, 82, 20, WHITE);
canvas.fillRect (x - 6, y + 6, 4, 10, WHITE);
// mylcd.Print_Number_Int(level, x +80 , y + 5, 1, ' ', 10);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor(x + 82 , y + 3);
canvas.println(level);
for (int i = 0; i < 20; i++) {
int p = round((100 / 20) * i);
if (p <= level)
{
canvas.fillRect(x + 75 - (4 * i), y + 1, 4, 18, GREEN);
}
}
}
//------------------------------------------------------------------------
//-----------Función para dibujar la señal de conectado-----------
bool signalBlink = false;
void drawSignal() {
// Position on OLED
// screen.setRotation(1);
int x = 115; int y = 10;
if (connectNow == true) {
if (!DmActive()) {
canvas.drawBitmap(x - 20, y, signal_transmitting_bits, 30, 34, WHITE, BLACK );
} else {
canvas.drawBitmap(x - 20, y, signal_connected_bits, 30, 34, WHITE, BLACK );
}
} else {
if (millis() - lastSignalBlink > 500) {
signalBlink = !signalBlink;
lastSignalBlink = millis();
}
if (signalBlink == true) {
canvas.drawBitmap(x - 20, y, signal_connected_bits, 30, 34, WHITE, BLACK );
} else {
canvas.drawBitmap(x - 20, y, signal_noconnection_bits, 30, 34, WHITE, BLACK);
}
}
// canvas.setRotation(2);
}
//---------------------------------------------------------------
//-----Funcion que dibuja la altitud del mando----------
void drawAltitude() {
int x = 85;
int y = 90;
int altura = altitud + 3 ;
//displayString = altitud + 1;
if (altura < 0) {
altura = 0;
}
//añadir ceros delante del dato
if (altura <= 9) {
displayString = "00" + (String)altura;// + "." + (String)(centGrados % 10);
} else if (altura <= 99) {
displayString = "0" + (String)altura;// + "." + (String)(centGrados % 10);
} else {
displayString = (String)altura;// + "." + (String)(centAlt % 10);
}
displayString.toCharArray(displayBuffer, 7);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor(x - 15, y + 1);
canvas.println(displayBuffer);
displayString = "Mtr";
displayString.toCharArray(displayBuffer, 7);
canvas.setTextColor(LIME);
canvas.setTextSize(1);
canvas.setCursor(x + 26 , y + 8);
canvas.println(displayBuffer);
}
//------------------------------------------------------------
//------- Funcion que dibuja la temperatura de la placa PCB-----
void drawTemp() {
int x = 10;
int y = 90;
int centGrados = temp_pcbIn * 100.0;
if (temp_pcbIn <= 9.9) {
displayString = "00" + (String)(centGrados / 100);// + "." + (String)(centGrados % 10);
} else if (temp_pcbIn <= 99.9) {
displayString = "0" + (String)(centGrados / 100);// + "." + (String)(centGrados % 10);
} else {
displayString = (String)(centGrados / 100);// + "." + (String)(centGrados % 10);
}
displayString.toCharArray(displayBuffer, 18);
canvas.setTextColor(WHITE);
canvas.setTextSize(2);
canvas.setCursor( x, y + 1);
canvas.println(displayBuffer);
canvas.drawBitmap(x + 35, y , thermometer_bits, 20, 20, LIME, BLACK );
}
//-------------------------------------------------------------
//---------Funcion que configura los imanes del motor y la seleccion del lenguaje--------
void confML() {
if (conf == true) {
if (confMotor == true) {
if (ModeActive()) {
if (throttle == 255) {
contador--;
if (contador < 1) {
contador = 1;
}
} else {
contador++;
if (contador > 50) {
contador = 1;
}
}
}
} else if (confLang == true) {
if (ModeActive()) {
langData++;
}
} else if (confBluetooth == true) {
if (ModeActive()) {
Serial.println("Inicio");
Serial.println(bluetoothData);
bluetoothData++;
}
} else {
if (ModeActive()) {
menuData++;
}
}
} else {
if (ModeActive())
{
displayData++;
}
}
delay(150);
}
//---------------------------------------------------------------------------------------------------
void show_canvas_on_screen()
{
screen.drawRGBBitmap(0, 0, canvas.getBuffer(), canvas.width(), canvas.height());
}
void setup() {
#ifdef DEBUG
Serial.begin(115200);
#endif
//------EspNow------------
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);
//-------------------------------------------------------
//-----Guardamos variables en la memoria que no se borra cuando se apaga--
preferences.begin("my-app", false);
lang = preferences.getUInt("lang", 0);
imanes = preferences.getUInt("imanes", 1);
//------------------------------------------------------------------------
//-----Definimos los valores de entrada y salida de la placa-----
pinMode(DmPin, INPUT_PULLUP);
pinMode(ModePin, INPUT_PULLUP);
pinMode(encendidoPin, INPUT);
pinMode(apagadoPin, INPUT);
pinMode(resetPin , INPUT);
pinMode(LED, OUTPUT);
pinMode(hallSensorPin, INPUT);//pin acelerador
pinMode(batteryMeasurePin, INPUT);
pinMode(cambioTelemetriaPin , INPUT);
//---------------------------------------------------------------
//--Inicializamos el display--
screen.init();
gfx.begin(canvas);
screen.setRotation(3);// 0 y 2 en vertical 1 y 3 en horizontal
canvas.fillScreen(BLACK);
show_canvas_on_screen();
drawStartScreen();
//-------------------------
if (DmActive()) {
conf = true;
}
//-------Arranca el barometro--------------
if (barometro = bmp180.begin())
{
status = bmp180.startTemperature();//Inicio de lectura de temperatura
if (status != 0)
{
delay(status); //Pausa para que finalice la lectura
status = bmp180.getTemperature(temp);//Obtener la temperatura
if (status != 0)
{
status = bmp180.startPressure(3);//Inicio lectura de presión
if (status != 0)
{
delay(status);//Pausa para que finalice la lectura
status = bmp180.getPressure(presion, temp); //Obtenemos la presión
if (status != 0)
{
presioncero = presion; //Asignamos el valor de presión como punto de referencia
}
}
}
}
}
//-----------------------------------------------
}
void loop() {
//Llamamos a la funcion que lea el estado del acelerador
calculateThrottlePosition();
//Llamamos a la funcion que configura los imanes y el lenguaje
confML();
if (conf == true) {
if (confMotor == true) {
displayConfMotor();
} else if (confLang == true) {
displayConfLang();
} else if (confBluetooth == true) { // BLE
displayBluetooth(); // BLE
} else {
menuDisplay();
}
}
if (conf != true) {
//Llamamos a la funcion que calcula la altura
calAlt();
//Llamamos a la funcion que enciende y apaga la placa
OnOf();
//Llamamos a la funcion que realiza el reset
doReset();
//Llamamos a la funcion que realiza el cambio de telemetria
cambioTelemetria();
//--------Evio de datos con espNow----------
// Set values to send
SensorReadings.acel = throttle;
SensorReadings.encendido = encendidoSen;
SensorReadings.apagado = apagadoSen;
SensorReadings.Reset = resetSen;
SensorReadings.cambioTelemetria = cambioTelemetriaSen;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &SensorReadings, sizeof(SensorReadings));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
//------------------------------------------
//#ifdef DEBUG
// DEBUG_PRINT(barometro);
// DEBUG_PRINT(altitud);
//#endif
updateMainDisplay();
}
}
#include "u8g2_fonts.h"
/*
Fontname: DS-Digital-54
Copyright: none
Glyphs: 96/96
BBX Build Mode: 0
*/
const uint8_t dsdigital_54[6192] U8G2_FONT_SECTION("dsdigital_54") =
"`\0\5\5\6\7\5\7\7.D\0\364.\0.\0\7\247\20\26\30\23 \7\0\0\2\243\0!*"
"\307\355\336\252&(\2\31\6!\212\360\201\17p\301\20\305\30J\260\203\62\214\42|\340\3U\60D\61"
"\10\62\24\301\4\356\3\22\42\25Pc\206\255\340\20\356\237\70BA\212\61\230\241\4(\30\0#\230#"
"\212\12\331+\370\200\30\224\60\13D\304\303\30\360\60\6<\214\1\17c\300\303\30\360\60\6<\214\21\13"
"D\260B\14\203\30\302(\310!\202a\230C$\4!\323HH\22\20\21\210\303\34\303\20\203(\206\60"
"\212B\210B\14\203\30\303:\214\1\17c\300\303\30\360\60\6<\214\21\13D;C\14\242\30\302(\6"
"\42\2q\230#(#!\323HH\22\20\21\210\303\34\303\20\203(\206\60\212U \42\36\306\200\207\61"
"\340a\14x\30\3\36\306\200\207\61bq\14\71$\202\6KP\0$P\235\220\332\312-\330C.\356"
"a\317\373\200\224\24\205;\203\31\213\4\203\42\303\220Hq\17{\376Y\343\26\342A\203\210P \246T"
"\245iE#H\317\30rq\15{\376\273\5\231\304@\250\21\20\313`\306B\224\232>\360\16{\336-"
"\362\260\203\7\0%\274*\215\366\344\37\60\303\7\210\361\201q\254B\42\352\200\210J\36\242\224\206\60\304"
"!H\30\206\20\24\202\210A\10\2!\310\70\306A\320a\216\202\244\303\34\5I\207\71\10\242\16s\220"
"c\35\346\30\310:\314!\220V\240b n\20\305\30\310\1\3q\214\240\34\62I\305T\20Q\221D"
"X\343\3\206\370\240>|\240\34\247\270\207\71*R\222\211\224E\42&\221\10\21\304!\204w\20B\24"
"\202h\310\60\216\261\20r\30c!\344\60\206B\312a\14\205\224\303\30\11\61\207\61\322qL\10AD"
"\42\20\242\204Q\14!!\356h\207K\330\341\22f\300\243\25\262x\304\34\340\360\1\64| \5\37\10"
"\0&}\243\213\2\317\310\241\220\224 \325\2!\265A@\255\20N;\370\71\31\244\3\26\347x\207\71"
"\336a\216w\230\343\35\306\210\206)fq\206\361\214a\4%\30\321\10\306p\246R\224j\34e*\305"
"\10F\64\202\61\32\317\30F\60\212Y\30#\32\346x\207\71\336a\216w\230\343\35\346x\207\71\336a"
"\216w\230\343\35\346x\207\71\336q\212X\244a\70bX\301\200D\360$HAIB\324i\0'\17"
"Gc\206\233\340\7\220P\214\241\4\3\0(\60\222k\2\257H\71j\11\71\301\60\316\60\210S\260c"
"\235\177\313`\205\33`\360\1\33\300\301\25\315`\307:\377X\341\206A\244`\30\13I\352\0)\61\221"
"K\2\257 Ii\351X\305\10\20\61\206V\254C\235\277e\260\242\15/\370\240\22\274\241\25\313P\347"
"\277U\234a\14\247\30\301\71Rr\322\20\0*U\235h\62\307.\330C.\356a\317^`\16\23\220"
"\23\201\304!\222\220\210B\244\306 Tb\20\312HF \224\222\210@ \11\31\307\7\35$\4\342@"
"\211\10DB\24\61\10\225\30\204\42\22Q\210$$\243\30\321\70\6\22\212r\224\202\35\366\334-\362\260"
"\3\7\0+\62\33g&\305-\310\303-\352A\317\307\214Q\204\243 b\10\311PD \224\300\14&"
";c\31II\312!\204q\70\302\32\365\240\347\325\342\16\71h\0;\17\7c\346\232\340\7\202P\214"
"\241\4\3\0-\21\334aR\305\303*\330\320\2\27\264\201\25k\0.\11\307a\2\233\340\3\22/E"
"`;\376\306^\320\306Ea\344\42\30\271\310M.\12#\27\301\310Ea\4\37\371\310\306&\70\301\203"
"\17\362\202\66\62\202\221\213\334\344\242\60r\221\233\134\24F.r\223\213dC\33\272\340\4\37\272\360\1"
"\20p\0\60F\235\213\2\313\42+\327\10F\65\206\61\215bD\343\30\317HF\63\226\330<\367\357\61"
"\263\10C\35Fp\203\17\352\301\15\306P\207P\314%\66\317\375{M\134F\63\222\361\214cD\243\30"
"\323\30F\65\202q\225L\0\61'\7\353\6\253&(\2\31\6!\212\360\201\17\70\301\20\305\30J\260"
"\203\62\214\42|\340\3U\60D\61\10\62\24\301\4\62E\235\213\2\313\42+\327\251FP\246!\230h"
"\14\347\31\4jFq\15{\376w\236`\230H\14f\22\201\251\322t\202\21\235a<\247\300\306=\354"
"\371g\215[\214\6\21\343\71\303\210\214\60\246\22\214\352\134%\23\0\63E\234\253\2\313@\33X\261F"
"\60\250!\20i\14\5\32\204qFa\215z\376Y\343\26\5\32C\221FP(T\35*I#\70\320"
"\30pa\215z\376\263\206qFQ\240A\20i\14\203\32\202\260F\20\260\241\11\0\64\67\35\213\6\313"
" \340\202&\260a\21\252H\6\66\317\375\275&.\263\10\303x\306\60\202\21\215\340L\251J\323\212F"
"\220\236\61\344\342\32\366\374\357\32\270\310\204\36\266\300\3\65F\235\213\2\313\42+\327\10FE\204\61\225"
"aD\206\30\317)F\203\214{\330\363\317\32\267\20\17\32D\204\2\61\245*M+\32Az\306\220\213"
"k\330\363\337\65P\63\212\363\14\302Dc(\323\20H\65\202q\225L\0\66J\235\213\2\313\42+\327"
"\10FE\204\61\225aD\206\30\317)F\203\214{\330\363\317\26y\30O\12F\264\246T\245\351\4#"
"\32\301\30\306\63\206P\314%\66\317\375{M\134F\63\222\361\214cD\243\30\323\30F\65\202q\225L"
"\0\67\62\134\253\6\313@\33X\261F\60\250!\20i\14\5\32\204qFa\215z\376Y\343\26x\320"
"\301\7\223\201\36pa\215z\376g\215[`\42\17Z\330\1\70O\235\213\2\313\42+\327\10F\65\206"
"\61\215bD\343\30\317HF\63\226\330<\367\357\61\263\10\303x\306\60\202\21\215\340L\251J\323\11F"
"\64\202\61\214g\14\241\230Kl\236\373\367\232\270\214f$\343\31\307\210F\61\246\61\214j\4\343*\231"
"\0\0\71I\235\213\2\313\42+\327\10F\65\206\61\215bD\343\30\317HF\63\226\330<\367\357\61\263"
"\10\303x\306\60\202\21\215\340L\251J\323\212F\220\236\61\344\342\32\366\374w\15\324\214\342<\203\60\321"
"\30\312\64\4R\215`\134%\23\0:\16\307\211\2\241\340\3\322\7\217~@\2;\25\207\213\346\240\340"
"\3\322\7o\177\340\3H(\306P\202\1\0< \23\210\36\265\315`\6;\26\242\222\244 \365\245\264"
"\17\304d\245\247\324\251d!\14aG\63\0=\35\234d:\305\303*\330\320\2\27\264\201\25\353\203e"
"\253`C\13\134\320\6V\254\1\0>\35\23h\36\265\240pF;\30\262\322\224\372\373\0T\220\372\227"
"\22\205\254\203\31\255p\0\77;\335\215\336\312\241JuiZ\221\10\324#\206\134\334\303\236\177\327\70\217"
"(L$\6\63\211\300TiZ\321\31\306s\12l\334\303\236\377Y\343\26\230\310\203\26v\360A\370\260"
"\347\263\0@\233\246\213\2\331hS;\21\234M\10G\23C\11\4&\10\62\10K\24\243\300\206\70\256"
"!\216k\210\343\32\342\300\205\70\326\62\10q\250f\10\343H\317\71Pd\16\24\231\303\4\342\21\1\61"
"\12!\32\61\214\242\30\257\30\203\71\232A\202s\64\203\35\315`G\63\330\321\214!\234\243\31\202\60G"
"\63Da\214f\10\303\20b\21\205\70\214 \32A\210#=b\20\7\212\204 \216\24\211@\34*\42"
"\307\212\306\361\1p|\0\34\37\0\306\7\4\61\266\42\214\16}\346\3B\371@p\274\304\15\0AD"
"\235\213\2\313\42+\327\10F\65\206\61\215bD\343\30\317HF\63\226\330<\367\357\61\263\10\303x\306"
"\60\202\21\215\340L\251J\323\11F\64\202\61\214g\14\241\230Kl\236\373\337k\342\62\223z\334\42\17"
";\0BT\235\213\2\313bZ\323\11\306d\204\61\225aD\42\30\304x\304 \212\321\210\42\30\320y"
"\356\37\134f\21\206\361\214a\4#\32\301\231R\225\246\23\214h\4c\30\317\30B\61\227\330<\367\357"
"\65\261\10\305p\304 \210\1\211`\14C*\302\240H\60(D;\0C\60\235\213\2\313\250:ui"
":\301\210\316\60\236S\334\303\236\177\326\270E\36v\360A\70\330C.\260q\17{\376\335\42\17\343I"
"\301\210\326\224\352\1DL\235\213\2\313bZ\323\11\306d\204\61\225aD\42\30\304x\304 \212\321\210"
"\42\30\320y\356\37\134f\21\206:\214\340\6\37\324\203\33\214\241\16\241\230Kl\236\373\367\232X\204b"
"\70b\20\304\200D\60\206!\25aP$\30\24\242\35\0EE\235\213\2\313b\33Y\10\306%\204Q"
"\215aL\204\30Q)\306c\214{\330\363\317\26y\30O\12F\264\246T\245\351\4#:\303xN\201"
"\215{\330\363\317\32\267\30\217!FT\206\61\21aT#\30W\311\306\6F=]\213\6\313b\33Y"
"\10\306%\204Q\215aL\204\30Q)\306c\214{\330\363\317\26y\30O\12F\264\246T\245\351\4#"
":\303xN\201\215{\330\363\237\65n\201\211<ha\7\34\0GE\235\213\2\313\250:u&\20\223"
"\31Dd\12\361\230\303\236\77k\334\42\17;X\10U$\3\35\23$F\4cH\212\30B\221\20\261"
"\304\346\271\377\336\21\212X\214a\64c(\301xF\220\242\65\255\250=\257A\0H<\235\213\2\313 "
"\340\202&\260Q\223\271\304\346\271\377^\23\227Y\204a<c\30\301\210Fp\246T\245\351\4#\32\301"
"\30\306\63\206P\314%\66\317\375\357\65q\231I=n\221\207\35\0I'\207\353\2\253&(\2\31\6"
"!\212\360\201\17T\301\20\305\30J\260\203\62\214\42|\340\3\134\60D\61\10\62\24\301\4J;\235\213"
"\2\313<\330\202\36\62\201\213k\330\363\277k\340\42\17;\370`\66\330C.\256!\4y\4\42\66\320"
"y\356{G(b\61\206\341\210\241\4\3\22A\212\326\264\242\6\71\347\0KZ\235\213\2\313 \240\305"
"\20\244\61\6x\14\302!\243`\311\60\322\62\216\263\220\303;\345(\213\71\210\202\216\241\244C(\352\10"
"\312:B\302\16q\264C\30\356\20\305\63n\221\207\361\244`DkJU\232N\60\242\21\214a<c"
"\10\305\134b\363\334\377^\23\227\231\324\343\26y\330\1L\65\235\213\2\313 \340\302\36\64\221\13l\334"
"\303\236\377\254q\213<\354\340\203\331`\17\271\300\306=\354\371g\215[\214\307\20#*\303\230\210\60\252"
"\21\214\253dc\3M`\235\213\2\313\42+\327\10F\65\206\61\215bD\343\30\317HF\63\226\330<"
"\347\4\307\61\203qJQ\34r\20\207\34\304!\7q\310A\34r\20\207\34\204\61\207)\302p\216\63"
"\214\0\35(h\207=\265\0\35(\30\303\71\316\20\212S\234\345\14\247\71\301q\236\373\357\65q\231I"
"=n\221\207\35\0NM\235\213\2\313B\241\312\23\206\322\210\241\250c((\31\212Y\206B\232\241\214"
"\206(\242)\211h\14\42\34s\10\347\30\302A\205p\236\33\134f\21\206:\214\340\6\37\324\203\33\214"
"\241\16\241\230Kl\236\373\337k\342\62\223z\334\42\17;\0OH\235\213\2\313\310q\20\223\24u\2"
"!\205\240\14\2\12\303(\204\23\212p<\367\357\65q\231E\30\352\60\202\33|P\17n\60\206:\204"
"b.\261y\356\337;B\21\213\61\14G\14%\30\220\10R\264\246\25\65\310\71\7\0PE\235\213\2"
"\313\202R\224\11\6U\204A\221aH!\30\304\200\302 \212\341\204\42\30\320y\356\37\134f\21\206\361"
"\214a\4#\32\301\231R\225\246\23\214\350\14\343\71\5\66\356a\317\377\254q\13L\344A\13;\340\0"
"Q]\235\213\2\313\310q\20\223\24u\2!\205\240\14\2\12\303(\204\23\212p<\367\367\232\270\314\42"
"\14u\30\301\15>\250\7\67\30C\35B\61\227\330<\367`\21\216d\210A\34\351\20\301\70\22R\216"
"\224\220#)\244X\12\31\306\61\24\22\214d(f\31Ii\6b\226r\234\344\30\350H\5Rj\235"
"\213\2\313\202R\224\11\6U\204A\221aH!\30\304\200\302 \212\341\204\42\30\320y\356\37\134f\21"
"\206\361\214a\4#\32\301\231R\225\246\23\214\350\14\343\71\5\66\356\61\12w\14\243\35\343`\307@\326"
"\61\22u\220$\35%A\207I\316q\22s\240\244\34)!\207J\206\301\22Q\270$\20\20\11CD"
"\202\60\217\20T#\0S>\235\213\2\313HR\24\262\14f;\22\14\212\14C\42\305=\354\371g\215"
"[\210\7\15\42B\201\230R\225\246\25\215 =c\310\305\65\354\371\357\26D\32\3\241F@;\203\31"
"\13QJB\0T\65\241K\2\313c+\335\370\302\7\204\360\215\256l\37t\203\17\200\241\27\373\320\347"
"m\203\27}\370\0\10>\270\23|\0\14\275\330\206>\377\337.\372\360\1\20@\0U<\235\213\2\313"
"\134\320\4\66;B\25\331<\367\337k\342\62\213\60\324a\4\67\370`\66\30C\35B\61\227\330<\367"
"\357\35\241\210\305\30\206#\206\22\14H\4)Z\323\212\32\344\234\3\0VW\235\213\2\307\134\320\4\66"
";B\25\311@\347\271\177\257\211\313;\302P\207\21\334\340\203z@\7\62@c\24\356\30F;\306\261"
"\220q\250d\34)!\7J\312q\22s\230\344\34E\71\7Q\320\61\224t\10E\35\42Y\207@\330"
"!\216v\10\303\35\242\200E\36v\220\1W`\235\213\2\313\134\320\4>j\62\227\330<\367\337kP"
"\200\26\64\240\42\14\250@\303\10\320\201\202v\330S\13\320\201\202\61\234\343\14\241\60\207Y\312Q\32r"
"\20\207\34\304!\7q\310A\34r\20\207\34\304)Eq\314`\234\23\34\347\65q\31\315H\306\63\216"
"\21\215bLc\30\325\10\306U\62\1\0Xn\235\213\2\307\200\250\311T$\23\233\347\70\250E\13\21"
"\210J\6\222\20\222\34\304 &U\20\224\214$!\3Q\310\70\330\61\216f\14\303\31\243\200\305(\42"
"\61\10I\214\341\203\340\60\206I\14\42\26\243\200\305(\236\61\214v\214\203\35\343X\310@R\62\220\204"
"\24\344 &)\311A\12\222\220\201\250$$\13\11H{\334\363\232\270\310e&\264\0Y<\235\213\2"
"\313\134\320\4\66;B\25\311@\347\271\377 #\25\361\214A\14\42\32\1\11\304\224\252\64\255h\4\351"
"\31C.\256a\317\177\267\70\220\30\216$\202\63\245*MKb\320\1\0Z<\235\213\2\313@#z"
"\4\63\26\242>h\26\327\270GEhB\21\232\314\204\242*R\17k|`\6\231\300\5\66\354QQ"
"\24\241\311L(R\221zX\343\203\346\224\252s\225|\1\0[=\222k\2\257\2\32N\10\6#\204"
"\241\214a \204\30F)\6a\14v\254\363o\25n\200\301\7\245\0\16\256h\6;\326\371\267\14V"
"\14\302\20\303(\303@\210\60\224\21\14\246\70\3\2\134C`;\376\306`\360\206F\62\202\221\214\302H"
"F\60\222Q\30\311\10F\62\12#\331\320\306.\371\340\203\221\241\37\371\310\10F\62\202\23\214d\4#"
"\31\301HFa$#\30\311G\66v\301\11>x\221\0\0]<\222+\2\257\0\32NaF\60\224"
"!\20d\14\305\30\204!F\301\214u\376k\205\33`\360A)\200\203+\230\261\316\177\314\60\304(\212"
"\61\10\202\214a(C\20\314\10\202\63 \1\0^.\233dr\303/\270\201\20\252 \206\71\210A\22"
"\202\200\205(\234!\14v\210C!\2A\211H\214\42\24\242\22\212\231R\264\236\326\274%\26_\26\342"
"\1\322\304\203+\336\370@\20>\60\204\17\4\303+\334\0\0`\32\313c\206\243%H\203)\312\61\20"
"\202\32\10A\6BN\305(E\22\2\0aD\235\213\2\313\42+\327\10F\65\206\61\215bD\343\30"
"\317HF\63\226\330<\367\357\61\263\10\303x\306\60\202\21\215\340L\251J\323\11F\64\202\61\214g\14"
"\241\230Kl\236\373\337k\342\62\223z\334\42\17;\0bT\235\213\2\313bZ\323\11\306d\204\61\225"
"aD\42\30\304x\304 \212\321\210\42\30\320y\356\37\134f\21\206\361\214a\4#\32\301\231R\225\246"
"\23\214h\4c\30\317\30B\61\227\330<\367\357\65\261\10\305p\304 \210\1\211`\14C*\302\240H"
"\60(D;\0c\60\235\213\2\313\250:ui:\301\210\316\60\236S\334\303\236\177\326\270E\36v\360"
"A\70\330C.\260q\17{\376\335\42\17\343I\301\210\326\224\352\1dL\235\213\2\313bZ\323\11\306"
"d\204\61\225aD\42\30\304x\304 \212\321\210\42\30\320y\356\37\134f\21\206:\214\340\6\37\324\203"
"\33\214\241\16\241\230Kl\236\373\367\232X\204b\70b\20\304\200D\60\206!\25aP$\30\24\242\35"
"\0eE\235\213\2\313b\33Y\10\306%\204Q\215aL\204\30Q)\306c\214{\330\363\317\26y\30"
"O\12F\264\246T\245\351\4#:\303xN\201\215{\330\363\317\32\267\30\217!FT\206\61\21aT"
"#\30W\311\306\6f=]\213\6\313b\33Y\10\306%\204Q\215aL\204\30Q)\306c\214{\330"
"\363\317\26y\30O\12F\264\246T\245\351\4#:\303xN\201\215{\330\363\237\65n\201\211<ha"
"\7\34\0gE\235\213\2\313\250:u&\20\223\31Dd\12\361\230\303\236\77k\334\42\17;X\10U"
"$\3\35\23$F\4cH\212\30B\221\20\261\304\346\271\377\336\21\212X\214a\64c(\301xF\220"
"\242\65\255\250=\257A\0h<\235\213\2\313 \340\202&\260Q\223\271\304\346\271\377^\23\227Y\204a"
"<c\30\301\210Fp\246T\245\351\4#\32\301\30\306\63\206P\314%\66\317\375\357\65q\231I=n"
"\221\207\35\0i'\207\353\2\253&(\2\31\6!\212\360\201\17T\301\20\305\30J\260\203\62\214\42|"
"\340\3\134\60D\61\10\62\24\301\4j;\235\213\2\313<\330\202\36\62\201\213k\330\363\277k\340\42\17"
";\370`\66\330C.\256!\4y\4\42\66\320y\356{G(b\61\206\341\210\241\4\3\22A\212\326"
"\264\242\6\71\347\0kZ\235\213\2\313 \240\305\20\244\61\6x\14\302!\243`\311\60\322\62\216\263\220"
"\303;\345(\213\71\210\202\216\241\244C(\352\10\312:B\302\16q\264C\30\356\20\305\63n\221\207\361"
"\244`DkJU\232N\60\242\21\214a<c\10\305\134b\363\334\377^\23\227\231\324\343\26y\330\1"
"l\65\235\213\2\313 \340\302\36\64\221\13l\334\303\236\377\254q\213<\354\340\203\331`\17\271\300\306="
"\354\371g\215[\214\307\20#*\303\230\210\60\252\21\214\253dc\3m`\235\213\2\313\42+\327\10F"
"\65\206\61\215bD\343\30\317HF\63\226\330<\347\4\307\61\203qJQ\34r\20\207\34\304!\7q"
"\310A\34r\20\207\34\204\61\207)\302p\216\63\214\0\35(h\207=\265\0\35(\30\303\71\316\20\212"
"S\234\345\14\247\71\301q\236\373\357\65q\231I=n\221\207\35\0nM\235\213\2\313B\241\312\23\206"
"\322\210\241\250c((\31\212Y\206B\232\241\214\206(\242)\211h\14\42\34s\10\347\30\302A\205p"
"\236\33\134f\21\206:\214\340\6\37\324\203\33\214\241\16\241\230Kl\236\373\337k\342\62\223z\334\42\17"
";\0oH\235\213\2\313\310q\20\223\24u\2!\205\240\14\2\12\303(\204\23\212p<\367\357\65q"
"\231E\30\352\60\202\33|P\17n\60\206:\204b.\261y\356\337;B\21\213\61\14G\14%\30\220"
"\10R\264\246\25\65\310\71\7\0pE\235\213\2\313\202R\224\11\6U\204A\221aH!\30\304\200\302"
" \212\341\204\42\30\320y\356\37\134f\21\206\361\214a\4#\32\301\231R\225\246\23\214\350\14\343\71\5"
"\66\356a\317\377\254q\13L\344A\13;\340\0q]\235\213\2\313\310q\20\223\24u\2!\205\240\14"
"\2\12\303(\204\23\212p<\367\367\232\270\314\42\14u\30\301\15>\250\7\67\30C\35B\61\227\330<"
"\367`\21\216d\210A\34\351\20\301\70\22R\216\224\220#)\244X\12\31\306\61\24\22\214d(f\31"
"Ii\6b\226r\234\344\30\350H\5rj\235\213\2\313\202R\224\11\6U\204A\221aH!\30\304"
"\200\302 \212\341\204\42\30\320y\356\37\134f\21\206\361\214a\4#\32\301\231R\225\246\23\214\350\14\343"
"\71\5\66\356\61\12w\14\243\35\343`\307@\326\61\22u\220$\35%A\207I\316q\22s\240\244\34"
")!\207J\206\301\22Q\270$\20\20\11CD\202\60\217\20T#\0s>\235\213\2\313HR\24\262"
"\14f;\22\14\212\14C\42\305=\354\371g\215[\210\7\15\42B\201\230R\225\246\25\215 =c\310"
"\305\65\354\371\357\26D\32\3\241F@;\203\31\13QJB\0t\65\241K\2\313c+\335\370\302\7"
"\204\360\215\256l\37t\203\17\200\241\27\373\320\347m\203\27}\370\0\10>\270\23|\0\14\275\330\206>"
"\377\337.\372\360\1\20@\0u<\235\213\2\313\134\320\4\66;B\25\331<\367\337k\342\62\213\60\324"
"a\4\67\370`\66\30C\35B\61\227\330<\367\357\35\241\210\305\30\206#\206\22\14H\4)Z\323\212"
"\32\344\234\3\0vW\235\213\2\307\134\320\4\66;B\25\311@\347\271\177\257\211\313;\302P\207\21\334"
"\340\203z@\7\62@c\24\356\30F;\306\261\220q\250d\34)!\7J\312q\22s\230\344\34E"
"\71\7Q\320\61\224t\10E\35\42Y\207@\330!\216v\10\303\35\242\200E\36v\220\1w`\235\213"
"\2\313\134\320\4>j\62\227\330<\367\337kP\200\26\64\240\42\14\250@\303\10\320\201\202v\330S\13"
"\320\201\202\61\234\343\14\241\60\207Y\312Q\32r\20\207\34\304!\7q\310A\34r\20\207\34\304)E"
"q\314`\234\23\34\347\65q\31\315H\306\63\216\21\215bLc\30\325\10\306U\62\1\0xn\235\213"
"\2\307\200\250\311T$\23\233\347\70\250E\13\21\210J\6\222\20\222\34\304 &U\20\224\214$!\3"
"Q\310\70\330\61\216f\14\303\31\243\200\305(\42\61\10I\214\341\203\340\60\206I\14\42\26\243\200\305("
"\236\61\214v\214\203\35\343X\310@R\62\220\204\24\344 &)\311A\12\222\220\201\250$$\13\11H"
"{\334\363\232\270\310e&\264\0y<\235\213\2\313\134\320\4\66;B\25\311@\347\271\377 #\25\361"
"\214A\14\42\32\1\11\304\224\252\64\255h\4\351\31C.\256a\317\177\267\70\220\30\216$\202\63\245*"
"MKb\320\1\0z<\235\213\2\313@#z\4\63\26\242>h\26\327\270GEhB\21\232\314\204"
"\242*R\17k|`\6\231\300\5\66\354QQ\24\241\311L(R\221zX\343\203\346\224\252s\225|"
"\1\0{\67\231+\2\271nik-\10I\33\202\341\212@\270C\236\177\323\240\205#\306\340\214\21\70"
"\4*\20\221\306\10 \61\206ZLC\236\377fQ\7A\304@\30\62y\353\0|\13\207\16\323\256\340"
"\377\77\60\0}:\230K\2\271 \201i\360\220\305\10\36\61\6Z\310#\236\277h\310\202\16\203x\301"
"\60\42\362\224\207\264`\30m\30D+\246!\217x\376\311\302\15cp\305\10\334\1\23\227\366\0~\27"
"XbJ\277\303\210\11sRT> \20\351@j\11A;\6\0\177\23\321+\6\311\340\7\30\263\376"
"\377\377\377\77\363\201\17;\0\0\0\4\377\377\0";
/*
Fontname: DS-Digital-47
Copyright:
Glyphs: 96/96
BBX Build Mode: 0
*/
const uint8_t dsdigital_47[5418] U8G2_FONT_SECTION("dsdigital_47") =
"`\0\5\5\6\6\4\6\7)=\0\365)\0)\0\6\236\16\15\25\15 \6\0\200\340\23!$F"
"\354\230\264\4D\30\203 \205\17| \11\205\30H\20\3\62\210\17| \11\205 \306@\204\22\260\17"
"\24\42\22\316\242>\25\30\202\375\11#\20\204\30\202\21\4\0#\201\337\310\342\71\5*\220\3\32`a"
"\212g\24\303\31\305pF\61\234Q\14g\24\303\31\305H\204\30\306 \10\61\20C\4\243\20\202(\4"
"BN!\21\251p\220\323(\204 \12!\210B\21\207xF\61\234Q\14g\24\303\31\305x\304!T"
"!\4Q\10A\24\343 \247\220\210DD\344$\14\21\214B\10\242 \204\30\306 \10\61(\243\30\316"
"(\206\63\212\341\214b\70\243\30\316(\306#\16\21\205$$\0$C\232\276Xx\11\227\250\6\65\357"
"\3\15J\322\251\12u$\42\14\210\20\325\240\346\217\26\225\20\316\21\4\224$$%h\71#\300\203-"
"\250\371W\211\21\15aL\246*\225\231P\364\201ePs\225\270B\3\0%\245&\274\134\373\3$\370"
"\200 >\0\16E\300C\31\357HH;T\262\216\24\210\203\35h\20\205\20\320\201\212C\234\343\30\306"
"(\7\62\214Q\16d\30\203\34\311\60\306\70\224a\214q\254\302\30\342h\203 \215\303\5\302\20\2\61"
"\42\202\212\230\34b\36h\250\305\7\325\340\3\302\370\0\70LA\217r\310\243$\361\60G<H\60\212"
"\21\270c\214\261c\30\246P\7\61\212\241\16b\24#\35\305\224\216bB\207\61\212\201\216CBG\22"
"D!\4t\264\203\31,Y\205;X\361\212F\304\341\15\37 \302\7J\360\1\23t\0&l_\272"
"\340\330\64\322\201\320\203\240\323\4\321\64B\33\331\34\24\216\361\10c\70\243\30\316(\206\63\212\341\214R"
"\4'\24A\30C\200\302\20\210\21\4)\4\301\30\224\60\12T\210\21\14g\4C\30\203\34L\1\213"
"b\70\243\30\316(\206\63\212\341\214b\70\243\30\316(\206\63\212\341\214b\70\303\20\220@\202h\206\320"
"\34\10=\10:\261a\0'\15\306\242>\23|\340\12\304\20\4\0(+O\252 \325$%e\20d"
"\30A\20\206PF\62\177\251P\4\23>\300\203\66\254B\31\311\374\251b\15\201@A\60\20r\322\0"
"))O\252 \25 \10\15\31j\30\2#\224\221\314\77U\254\241\5\37hA\33V\221\314\77E\230"
"a\10\246H\307A\14\352\0*J\232\247\353\227\11\227\250\6\65\267\210b\220\42\34\303\20G@\6!"
"P\202\10\211@\206 \222\201\10! \307(\306\7\274A\220s\24\204 C\20\211@\206 \222\200\14"
"B \1\31\205p\210i\4\306(\201\63\250Y%\256\300\0+(X\246\250w\11\225\230\206\64\337*"
"\306\60\214\201\210` A!\324P\4R\20b\34\303\11\225\230\206\64o\22UX\0,\15\206\242\32"
"\23| \12\304\20\4\0-\20\230\241\262WP\303\12\37\210\202\65(\1\0.\11\206\241 \23|\240"
"\0/\77\35\233\337w\13\267\260\206=\352a\217z\330\243\236\354Q\17{\324\223=\254q\15L\344A"
"\7\37D\7l\330\243\36\366\250\207=\352\311\36\365\260G=\354Q\217[\340\2\23z\320\302\16\64\0"
"\60\77Z\272`XX\205\32\301\220\306\60\240Q\14g\34\203\31\11\134\34\373\347\26X\204A\16#\240"
"\301\7r@\203\61\310!\24pq\354\317-\60\31\314\70\206\63\212\1\215aH#\30T\261\4\0\61"
" \306\351\241\264\4D\30#A\204\17p\241$\6\22\304\200\14\342\3\37\30B!\210\61\20\241\4\62"
"<Z\272`XX\205:\322\10\12\64\4\343\214\341\60\203\250\5\65\377ja\34A\24H\10EBR"
"\202\214\60\34C\330\242\32\324\374\321\242\22\203\71\303p\214\60\240\22\14\351P\305\22\0\63<X\332`"
"\30X\203*\322\10\6\64\4\342\214\241\60\203\230\205\64\377f\61\34Q\214G\14#\22\1\211\320\223\34"
"\22\330\201\26\322\374\233Ea\6A\234\61\14h\10B\32A\240\206%\0\64\61\332\271a\30\4Y\270"
"D-\350!\23\270\70\366\347\226\267\4'\24a\10P\30F\20\244\20\224)A\313\31\1\36lA\315"
"\177\265\260\304\35\260\220\3\65<Z\272`XX\205\32\301\220\210\60\240\62\14\307\20\203\71E\65\250\371"
"\243E%\204s\4\1%\11I\11Z\316\20.Q\13j\376\325\342\60\203\60\316\30\12\64\4\42\215`"
"P\305\22\0\66BZ\272`XX\205\32\301\220\210\60\240\62\14\307\20\203\71E\65\250\371G\213\340\234"
"!@'\10\322\231\22t\202\341\214`\14r\10\5\134\34\373s\13L\6\63\216\341\214b@c\30\322"
"\10\6U,\1\0\67+\30\332a\30X\203*\322\10\6\64\4\342\214\241\60\203\230\205\64\377f\211\16"
"\66\370\240\24\330\201\26\322\374\67\13J\324\301\12\67\0\70FZ\272`XX\205\32\301\220\306\60\240Q"
"\14g\34\203\31\11\134\34\373\347\226\340\204\42\14\1\12\303\10\202\24\202\62%\350\4\303\31\301\30\344\20"
"\12\270\70\366\347\26\230\14f\34\303\31\305\200\306\60\244\21\14\252X\2\0\71@Z\272`XX\205\32"
"\301\220\306\60\240Q\14g\34\203\31\11\134\34\373\347\226\340\204\42\14\1\12\303\10\202\24\202\62%h\71"
"#\300\203-\250\371W\213\303\14\302\70c(\320\20\210\64\202A\25K\0:\15\206\310\240\23|\240\370"
"\340\320\7\12;\21\6\312\232\23|\240\370\340\350\7\242@\14A\0<\35\321\246\347\225\25\313PGB"
"Pr\322\337\7V\222\22\205\246\222\224J\210:\226\301\12=\32\30\244\255WP\303\12\37\210\202\65\250"
"\17v\250a\205\17D\301\32\224\0\0>\33\321\246\347\25\24\314X\207BR\372\367\201\205 \324I\17"
"!\351P\306*\30\0\77\65Z\274X\30Lh\206\244\4-g\10\227\250\6\65\177\265\60\216 \12$"
"\204\42!)A'\30\316\31lQ\15j\376\321\242\22v\270\2\16>\230\62\250y\24\0@yb\272"
"\340\371d('\2\203\11\341Xb\30\302\240\4\351\26\301\250F\60\252\21\214j\4\303\26\301P\213\30"
"\204\221\32\21\14\3=\305@O\61L \32\21\14\243\14b\21\303 J\321\212!\30c\231\337\10\216"
"\261\14\61\30c\31\241(\306\62\202Q\10\221\210\42\30F\20\213 \202\221\32\61\4\3=B\10Fz"
"D\20\14\365\14\203\233z\341\7\221\225@l\246+\235\331\20\66\0A<Z\272`XX\205\32\301\220"
"\306\60\240Q\14g\34\203\31\11\134\34\373\347\226\340\204\42\14\1\12\303\10\202\24\202\62%\350\4\303\31"
"\301\30\344\20\12\270\70\366\237[`\42\17Z\330\1\7BIZ\272`XD*\62\301\210\212\60\240\62"
"\14\307\20\203\31\202( \21\14\307\376\271%\70\241\10C\200\302\60\202 \205\240L\11:\301pF\60"
"\6\71\204\2.\216\375\271\5\22\201\30\215\20\304\60\236\42\214\210\4C:\62\3\0C+Y\272`\330"
"Lef$\4\31A\70\206\240\306\64\177\263\240\204\25>\230\11\356P\13jL\363G\213:\4\7\5"
"\1B\322\231\3DBZ\272`XD*\62\301\210\212\60\240\62\14\307\20\203\31\202( \21\14\307\376"
"\271\5\26a\220\303\10h\360\201\34\320`\14r\10\5\134\34\373s\13$\2\61\32!\210a<E\30"
"\21\11\206td\6\0E<Y\272`X\134\243\12\301\230\204\60\242\61\214\207\20\243)\5\65\246\371\67"
"\213\340\230!@&\10\222\231\20d\202\341\230\241\26\324\230\346o\26\224\30M\31\306C\204\21\215`L"
"\245\32\27F\65\31\272aX\134\243\12\301\230\204\60\242\61\214\207\20\243)\5\65\246\371\67\213\340\230!"
"@&\10\222\231\20d\202\341\230\241\26\324\230\346\337,(Q\7+\334\0\3G;Z\272`\370\310\241"
"\310\10\342\61\204h\214A\315\37-\354\200\203\204D\345\61&\70L\10\306p\224\60\204\342 Ay\214"
"c\377\234\21\10H\14a\60C@\316\202\24\264\234\306\34\0H\66Z\272`\30\4Y\270D\65\346!"
"\23\270\70\366\237[\202\23\212\60\4(\14#\10R\10\312\224\240\23\14g\4c\220C(\340\342\330\177"
"n\201\211<ha\7\34\0I\42F\352\240\264\4D\30\203 \205\17| \11\205\30H\20\3\62\210"
"\17| \11\205 \306@\204\22\0J\61Z\272`\70\7X\270\203%\325\202\232\377\325\302\16\70\370\240"
"\27\340\301\26A\210\12\134\36\343\330sF \61\4\321\14\341<*J\221zXs\0KQZ\272"
"`\30\4\222\30\2,\306\340\214A\260c\20\13\31\5J\210a\222b\224\304\30$\71\306H\220!\222"
"d\204D\31\342X\206\60\230!\10gP\203\26\301\71C\200N\20\244\63%\350\4\303\31\301\30\344\20"
"\12\270\70\366\237[`\42\17Z\330\1\7L/Y\272`\30\4X\270\203%*Q\13jL\363\337,"
"\352p\203\17b\301\35jA\215i\376fA\211\321\224a<D\30\321\10\306T\252q\1MWZ\272"
"`XX\205\32\301\220\306\60\240Q\14g\34\203\31\11\134N`\30#\30\246\20\205!\6a\210A\30"
"b\20\206\30\204!\6a\210A\30b\220\245\30\245\10\203\61\314\60\202c\234\200\31\324`\301\61N\60"
"\206C\234!\24G\70\213c\377\271\5&\362\240\205\35p\0NGZ\272`X \23q\302@\30\61"
"\20e\14\4!\3\61\312@\310B\220\261\24D,\6\11\214\71\2s\214\300\240\42\60\216\315-\260\10"
"\203\34F@\203\17\344\200\6c\220C(\340\342\330\177n\201\211<ha\7\34\0O<Z\272`\330"
"\64\315Y\220\202\226\203\4\321\14a\20\220\10\206c\377\334\2\213\60\310a\4\64\370@\16h\60\6\71"
"\204\2.\216\375\71#\20\220\30\202h\206p\36\25\245H=\254\71\0P<Z\272`\70HI\62\201"
"\220\212\60\240\62\14\307\20\203\31\202( \21\14\307\376\271%\70\241\10C\200\302\60\202 \205\240L\11"
":\301p\316`\213jP\363\37-*a\207+\340 \3QRZ\272`\330\64\354QQ\212\216\20\36"
"!\14\42\64\202\10\206c\177n\201E\30\344\60\2\32|\320\13H\60\7\61D\345\61\216\335#\202\201"
"\10\42\10\3\25\307@\206\61\320Q\14\204\224\42!e\20\306@J \220\201\30e E!\207A\214"
"q\14T\0R_Z\272`\70HI\62\201\220\212\60\240\62\14\307\20\203\31\202( \21\14\307\376\271"
"%\70\241\10C\200\302\60\202 \205\240L\11:\301p\316`\13B\64c\24\314\30\306\62\306\241\214\201"
"$c$\310 \311\61\12r\14\203\30\343 \305@\10\61\22\62\212\205\10\242!axG\20\242\21\202"
"Y\4\0S\64Z\272`\370@I:U\241\216D\204\1\21\242\32\324\374\321\242\22\302\71\202\200\222\204"
"\244\4-g\4x\260\5\65\377*\61\242!\214\311T\206:R\202\16\0T'\134\252`X\134D\13"
"\134\320DF\256\17v\204L\134\303\232w\13<\350\340\203j\240\7\134X\363\377]\42\13\15\0U\65"
"Z\272`\70\13\227\250\306Dd\2\27\307\376s\13,\302 \207\21\320\340\3\71\240\301\30\344\20\12\270"
"\70\366\347\214@@b\10\242\31\302yT\224\42\365\260\346\0VQZ\272\340\67\13\227\250\306D\242\362"
"\30\307\376\334\2\213\60\310a\4\64\370@\16h\60\206\70\210\302\25\242h\206\60\226\61\14u\14#!"
"\303@\10\61\16R\14\203\30\243 \307 \311\61F\202\14\221$C \312\20\307\62\204\301\14Q\64\243"
"\22W\260\0WWZ\272`\70\13\227\250\306Dd\2\27\307\376\63\202Y\14a\212\60\30\303\14#\70"
"\306\11\230A\15\26\34\343\4c\60\206\31BQ\214\262\20\203\60\304 \14\61\10C\14\302\20\203\60\304"
" L!\12c\4\303\234\300,\60\31\314\70\206\63\212\1\215aH#\30T\261\4\0XdZ\272\340"
"\27\20\363\220\11\134\336\342\32v\204c\35\341P\307\70\322A\216s\224\303\34\347(\7:\306\221\16q"
",C\34\313\20F+D\361\10Q<B\20q\20\304\7\235A\20\220\20\304+D\341\12a\60C\30"
"\353\20\207:\306\201\16r\34\244\34\346\70\7\71\320\61\220t\210c\71\314i\314S\240\22\221\71\0Y"
"\64Z\272`\70\13\227\250\306Dd\2\27\307\376\271\345)\302\11E\20\4\24\206\42\205\300H\11Z\316"
"\10\360`\13j\376U\242<C(\21\232\316\204\42\365\34\0Z:Y\312`\30\134\343\66,B\31\351"
"\3\216\240\305\64\311#\36\362\210\207<\342!\215iL\342\3k\250\4-\250!\217\210\304SD\342!"
"\215i\314\342\3.:S\251\210]\0\0[\65O\252 U\64c\11\301H\204\60\216\61\214\202\20c"
"(\205\62\222\371\227\212\65\264\340\3-h\303*\224\221\314_*\24\61\206\62\214\202\10\343\30\301H\312"
"\62\32\134:\34\253\337\27\10\272\300\207\65\354\251\36\366\260\206=\325\303\36\365\260\207\65\335\22\36>\30"
"%\260a\15{\252\207=\352aO\365\260G=\354Q\17k\134\2\23y\310\302\16\4\0]\64P\232"
" \65\64d\61\311\10\310\61\204R\214\301\14\203X\205\62\377\255\202\15.\370\0\14\334\300\12e\376\255"
"\242\20\203 \306\30\6\62\4\241\214 \60\303\21\0^+\30\244\271\267\5\64\20\202\24\304\0\7\61<"
"B\20\255\20\305\62\204\221\16q\34D \5!\310@\14\22\20\364\250\206-My\5_\20\235\221\225"
"Wdc\13\37\330\302\66\62\1\0`\31I\263\376s\10f(\4\61\206\61\216a\214c\30\343\30\5"
")\314\20\0a<Z\272`XX\205\32\301\220\306\60\240Q\14g\34\203\31\11\134\34\373\347\226\340\204"
"\42\14\1\12\303\10\202\24\202\62%\350\4\303\31\301\30\344\20\12\270\70\366\237[`\42\17Z\330\1\7"
"bIZ\272`XD*\62\301\210\212\60\240\62\14\307\20\203\31\202( \21\14\307\376\271%\70\241\10"
"C\200\302\60\202 \205\240L\11:\301pF\60\6\71\204\2.\216\375\271\5\22\201\30\215\20\304\60\236"
"\42\214\210\4C:\62\3\0c+Y\272`\330Lef$\4\31A\70\206\240\306\64\177\263\240\204\25"
">\230\11\356P\13jL\363G\213:\4\7\5\1B\322\231\3dBZ\272`XD*\62\301\210\212"
"\60\240\62\14\307\20\203\31\202( \21\14\307\376\271\5\26a\220\303\10h\360\201\34\320`\14r\10\5"
"\134\34\373s\13$\2\61\32!\210a<E\30\21\11\206td\6\0e<Y\272`X\134\243\12\301"
"\230\204\60\242\61\214\207\20\243)\5\65\246\371\67\213\340\230!@&\10\222\231\20d\202\341\230\241\26\324"
"\230\346o\26\224\30M\31\306C\204\21\215`L\245\32\27f\65\31\272aX\134\243\12\301\230\204\60\242"
"\61\214\207\20\243)\5\65\246\371\67\213\340\230!@&\10\222\231\20d\202\341\230\241\26\324\230\346\337,"
"(Q\7+\334\0\3g;Z\272`\370\310\241\310\10\342\61\204h\214A\315\37-\354\200\203\204D\345"
"\61&\70L\10\306p\224\60\204\342 Ay\214c\377\234\21\10H\14a\60C@\316\202\24\264\234\306"
"\34\0h\66Z\272`\30\4Y\270D\65\346!\23\270\70\366\237[\202\23\212\60\4(\14#\10R\10"
"\312\224\240\23\14g\4c\220C(\340\342\330\177n\201\211<ha\7\34\0i\42F\352\240\264\4D"
"\30\203 \205\17| \11\205\30H\20\3\62\210\17| \11\205 \306@\204\22\0j\61Z\272`\70"
"\7X\270\203%\325\202\232\377\325\302\16\70\370\240\27\340\301\26A\210\12\134\36\343\330sF \61\4"
"\321\14\341<*J\221zXs\0kQZ\272`\30\4\222\30\2,\306\340\214A\260c\20\13\31\5"
"J\210a\222b\224\304\30$\71\306H\220!\222d\204D\31\342X\206\60\230!\10gP\203\26\301\71"
"C\200N\20\244\63%\350\4\303\31\301\30\344\20\12\270\70\366\237[`\42\17Z\330\1\7l/Y\272"
"`\30\4X\270\203%*Q\13jL\363\337,\352p\203\17b\301\35jA\215i\376fA\211\321\224"
"a<D\30\321\10\306T\252q\1mWZ\272`XX\205\32\301\220\306\60\240Q\14g\34\203\31\11"
"\134N`\30#\30\246\20\205!\6a\210A\30b\20\206\30\204!\6a\210A\30b\220\245\30\245\10"
"\203\61\314\60\202c\234\200\31\324`\301\61N\60\206C\234!\24G\70\213c\377\271\5&\362\240\205\35"
"p\0nGZ\272`X \23q\302@\30\61\20e\14\4!\3\61\312@\310B\220\261\24D,\6"
"\11\214\71\2s\214\300\240\42\60\216\315-\260\10\203\34F@\203\17\344\200\6c\220C(\340\342\330\177"
"n\201\211<ha\7\34\0o<Z\272`\330\64\315Y\220\202\226\203\4\321\14a\20\220\10\206c\377"
"\334\2\213\60\310a\4\64\370@\16h\60\6\71\204\2.\216\375\71#\20\220\30\202h\206p\36\25\245"
"H=\254\71\0p<Z\272`\70HI\62\201\220\212\60\240\62\14\307\20\203\31\202( \21\14\307\376"
"\271%\70\241\10C\200\302\60\202 \205\240L\11:\301p\316`\213jP\363\37-*a\207+\340 "
"\3qRZ\272`\330\64\354QQ\212\216\20\36!\14\42\64\202\10\206c\177n\201E\30\344\60\2\32"
"|\320\13H\60\7\61D\345\61\216\335#\202\201\10\42\10\3\25\307@\206\61\320Q\14\204\224\42!e"
"\20\306@J \220\201\30e E!\207A\214q\14T\0r_Z\272`\70HI\62\201\220\212\60"
"\240\62\14\307\20\203\31\202( \21\14\307\376\271%\70\241\10C\200\302\60\202 \205\240L\11:\301p"
"\316`\13B\64c\24\314\30\306\62\306\241\214\201$c$\310 \311\61\12r\14\203\30\343 \305@\10"
"\61\22\62\212\205\10\242!axG\20\242\21\202Y\4\0s\64Z\272`\370@I:U\241\216D\204"
"\1\21\242\32\324\374\321\242\22\302\71\202\200\222\204\244\4-g\4x\260\5\65\377*\61\242!\214\311T"
"\206:R\202\16\0t'\134\252`X\134D\13\134\320DF\256\17v\204L\134\303\232w\13<\350\340"
"\203j\240\7\134X\363\377]\42\13\15\0u\65Z\272`\70\13\227\250\306Dd\2\27\307\376s\13,"
"\302 \207\21\320\340\3\71\240\301\30\344\20\12\270\70\366\347\214@@b\10\242\31\302yT\224\42\365\260"
"\346\0vQZ\272\340\67\13\227\250\306D\242\362\30\307\376\334\2\213\60\310a\4\64\370@\16h\60\206"
"\70\210\302\25\242h\206\60\226\61\14u\14#!\303@\10\61\16R\14\203\30\243 \307 \311\61F\202"
"\14\221$C \312\20\307\62\204\301\14Q\64\243\22W\260\0wWZ\272`\70\13\227\250\306Dd\2"
"\27\307\376\63\202Y\14a\212\60\30\303\14#\70\306\11\230A\15\26\34\343\4c\60\206\31BQ\214\262"
"\20\203\60\304 \14\61\10C\14\302\20\203\60\304 L!\12c\4\303\234\300,\60\31\314\70\206\63\212"
"\1\215aH#\30T\261\4\0xdZ\272\340\27\20\363\220\11\134\336\342\32v\204c\35\341P\307\70"
"\322A\216s\224\303\34\347(\7:\306\221\16q,C\34\313\20F+D\361\10Q<B\20q\20\304"
"\7\235A\20\220\20\304+D\341\12a\60C\30\353\20\207:\306\201\16r\34\244\34\346\70\7\71\320\61"
"\220t\210c\71\314i\314S\240\22\221\71\0y\64Z\272`\70\13\227\250\306Dd\2\27\307\376\271\345"
")\302\11E\20\4\24\206\42\205\300H\11Z\316\10\360`\13j\376U\242<C(\21\232\316\204\42\365"
"\34\0z:Y\312`\30\134\343\66,B\31\351\3\216\240\305\64\311#\36\362\210\207<\342!\215iL"
"\342\3k\250\4-\250!\217\210\304SD\342!\215i\314\342\3.:S\251\210]\0\0{*U\252"
"`\226%+\305\20g,a\20\213\200\306\63\377X\262R\14q\6$D\60\207X<\363\17\22R\30"
"\4\64\34\322\322\0|\12\6\375\25\25\374\377\200\0},T\252`\26 \15\255\31o\30B$\236\341"
"\314\77\227\260\24C\232\301\2A\260\1\26\317p\346\357\21k\30\302*\334\301\220\205b\0~\24\25\242"
"\360V\30.IO\371@T\236\263\204`\35\2\0\177\22O\232!\30\374\300P\324\377\377\377_\371\300"
"\7\6\0\0\0\4\377\377\0";
/*
Fontname: DS-Digital
Copyright:
Glyphs: 96/256
BBX Build Mode: 0
*/
const uint8_t dsdigital_35[4164] U8G2_FONT_SECTION("dsdigital_35") =
"`\0\5\4\5\6\4\6\7\37.\0\370\37\0\37\0\5\63\12\320\20' \6\0@p\11!\36\245"
"d\315I\302\20b\204\7\36p\201\210\61\202\13\342\201\7\134 b\14ABy@\1\42\21+Q\373"
"\11J\320/\224\60\306\30\241\4\1\0#\134w\333\260{\242\66\312Xe\24UFQe\24UFQ"
"\205\220\63\202\20CH\303\210\22\202 \341\26J\10\241\204 \310\30a&\304)\243\250\62\212*\243\254"
"Q\306!\42\210!\202 \301\214\62\330(\303\4\42\202\30\42\10rF\31\253\214\242\312(\252\214\242\312"
"(k\224\321\302\11\7\0$\67\263\325\14\233\2,\256\366\301d\306\221\7\2qb\4&\212\253\317\221"
"\67\202\62!\260\323\14CJ\10H\134\375\304\3A<\20\304\3\201\274\322>\220\305Uo\304\220\0%"
"p|\134O\234\303-g\260r\212*\347\244\202J\10\247\30!F\20\306\24BH)\206\220\62\214!"
"\244\214r\10)\242 B\212(I\210\21\206(\255\204@\10;e\270b\4\34\37\354R\306+\244\64"
"\63\16+\245\260\62\204\30B\244\42H!\247\14B\212\61\203\220b\12!\244\24CH!\245\30!\206"
"\20\245\250\202J:h\254\222\6\33J\350`\1&P\367SP[R[\253\255\245\202Hj\314\42\253"
"\25LQ\243\224THI\205\224T\210\13$\204\21\2\23!\14\322D\31\214\14\21\204\32A\4A\26"
"!%\25RR!%\25RR!%\25RR!%\225\62B\12\343\204\260BHm\255\226\22\0'"
"\14%Q;\11>P\302\30A\0(\42\354S\360Y\16\271L!#\14RN}\207\240\241\302\7$"
"\250\221\10*\247\36\32a\230\20\212\271\1) \354K\360\11\216\271LAC\10TN\375\322P\341\3"
"\22\22\71\365##\14RB \267\2\0*\67\363R\364\232B\34\257\270*\211QH\20\225Xb\10"
"\23\214\10\342\204\23B\70\244\214\222\33\71!\4\63L\30\301\204\23Fh\241\4\23\306(c\240\342\252"
"\67bH\0+\42sR\363\232B\34\257\270\232#\212\10\61\310\60\305\4\64P\70\343\214\42D(\212"
"\270\272\67bH\0,\13\5\321-\11\276\60F\20\0-\21\263\320\366*\336x@\204\7Hx@\214"
"'\0.\10\245P\60\11\36P/,\26L\20;\7,\320<\3\13\64\260@\363\14\64\317\300\22\213"
"\34s|\260\13\264\236\201\346Y\320<\3\315\63\221H\62\5\25\22\0\60\63\363S\20\33\36\20!\204"
"\27Fh\202\204%LH\2\251\224\364Ki\221\20^\370 \211&\2Y)\351Ki\241\220\204\11K"
"\220\320\204\10o< \2\0\61\33\245\343\320I\302\20b\204\7\36H\201\210\61\202\13\342\201\7R "
"b\14A\2\62\62\363S\20\33\36\20\343\205\60\232\10d\11Q\222\30\217\270\372\21\25\310`A\220F"
"B`\304\225\342\352s\344\221\220\312\10\213\210\320F\10o< \2\0\63.\362[\20\13\36\20\342\221"
"&\302XB\20\25\206#\255~\343\211\26\302p\244\231\25\304#\255>G\210\12c,!D\23!<"
"\361\200\10\0\64$\263\323\20\13\202\24\220\70\303P\322/%\205\202\22#\204\300D \315\60\244F\200"
"\304\325\357\21\70\242\220\1\65.\363S\20\33\36\20!\204'Dhc\204EHH\245\270\372\71g\334"
"i\206\5QT \256~\217\224$\6YB\214&\202x\343\1\21\0\66\63\363S\20\33\36\20!\204"
"'Dhc\204EHH\245\270\372\71gB`\247\31VDPB\4\262R\322\227\322B!\11\23\226"
" \241\11\21\336x@\4\0\67\42\322\333\20\13\36\20\342\221&\302XB\20\25\206#\255~\216\300\360"
"\201\15\217\264\372\71\362\6\24\61\0\70\70\363S\20\33\36\20!\204\27Fh\202\204%LH\2\251\224"
"\364K\17\220@B\10L\4\322\14+\42(!\2Y)\351Ki\241\220\204\11K\220\320\204\10o<"
" \2\0\71\64\363S\20\33\36\20!\204\27Fh\202\204%LH\2\251\224\364K\17\220@B\10L"
"\4\322\14CJ\10H\134}\217\224$\6YB\214&\202x\343\1\21\0:\14E[p\11\36P\37"
"\222\17(;\20\345\333m\11\36P\37\342\17\274\60F\20\0<\31\254\332\62\212\310)\306\224Cn\305"
"\224CN<\346\30s\354\214\71\5\21=\30rQ\365*>\360@\11\17\10\361\352\23\17<P\302\3"
"B\274\0\0>\26\255\322\62\12H*\310\234\373Mc\354\314)\307\230S\20I\0\77*\263T\15\13"
"\234\361\14C*\214W\134}\217\20%\306`\42\220fX\21A\25\362\212\253\237#o@\21\303\7\246"
"\270:\7\0@f\371[\320[\36\30\346\201a\36\30\42\220\7\204\220\302\23#\20H\2y%\20H"
"\2AG\214@N\22A\20\263\10\61\213\220!D\12B\14\62\24\21\241\20T\20A\5\21T\202("
"\4\225\60\10I$\20\42\304\21#\220\223\204\10\304,\21\2\71k\20\264\4\251\244\16\361\300\30A<"
"P\310\3g<`\312\3D\0A/\363S\20\33\36\20!\204\27Fh\202\204%LH\2\251\224\364"
"K\17\220@B\10L\4\322\14+A\250\21\2Y)\351/\245uZy#\6B\67\363S\20\33Z"
"\11\241\21\21\332\30a\21\22\222\10\242\250\21J\322/=@\2\11!\60\21H\63\254\4\241F\10d"
"\245\244_J\241\205\21\232\20\301\211\20\34q\4\0C!\363S\20K\336x\304\31F\34)\256>G"
"\336\210\341\203\34\342\200\344\25W\357\71\23\2\63^yD\62\363S\20\33Z\11\241\21\21\332\30a\21"
"\22\222\10\242\250\21J\322/\245EBx\341\203\24^\10d\245\244_J\241\205\21\232\20\301\211\20\34"
"q\4\0E\62\363S\20\33\36 \341\201\20Dpb\4\66HP\244\270\372\71gB`\247\31VD"
"P\205\274\342\352\71\362HPd\4\66Dp\42\204\7\202x`\0F)\323\323\20\33\36 \341\201\20"
"Dpb\4\66HP\244\270\372\71gB`\247\31V\202P\205\274\342\352s\344\15(b\220\0G)"
"\363S\20K|\245+\305\325\347\10\14\247\264\263\22\11\346\210\20\10\61!%\375\245\22FHa\214\20"
"V\10\245\235\225R\1H)\363S\20\13\202\24\220\70\303\220JI\277\224\24\12J\214\20\2\23\201\64"
"\303J\20j\204@VJ\372Ki\235V\336\210\1I\33\345c\320I\302\20b\204\7\36p\201\210\61"
"\202\13\342\201\7\134 b\14A\2J&\363S\20+C\24p<\342\352\357\21\70b\370 \7H\202"
"XI\251\244\227Jha\214\20V\10\245\235\205T\1K:\363S\20\13B\33B,\42F*\202\34"
"#\12A\242\14\64\212@\244\4T\232)\241\240\22H*a(\362FP&\4v\232a%\10\65B"
" +%\375\245\264N+o\304\0L(\363S\20\13\202\24q@\362\212\253\237#o\304\360A\26\220"
"\274\342\352\71\362HPd\4\66Dp\42\204\7\202x`\0M@\364S\20\33\36(\341\5\22\232("
"a\211\23\222HJ\225@\24\31C\215\42\324(B\215\42\324(B\215\62\20)d\204`J\11\251\274"
"\202\202)%\4R\6I%\20\245\364S\211\35W\340\220\1N/\363S\20\13\320Ji\235V\336x"
"@\204\25\36\20\243\4EHPe\4\225\264\204\332\10\341\205\17Rx!\220\225\222\376RZ\247\225\67"
"b\0O.\363S\20[RZ\247\235e\202H\42\214\261F(I\277\224\26\11\341\205\17\222p!\220"
"\225\222~\251\204\26\306\10a\205P\332YH\25\0P/\363S\20\33Z\11\241\21\21\332\30a\21\22"
"\222\10\242\250\21J\322/=@\2\11!\60\21H\63\254\4\241\12y\305\325\317\221\67\240\210A\2Q"
"\71\363S\20KTZ\247\225\20V\10\243\205\21J\322/\245EBx\341\203\24^\10\243\35\245\222\316"
"\234P\214\21\305\30Q\314\21#\24qD\10G\230\221D!\207\220R\314\0R@\363S\20\33Z\11"
"\241\21\21\332\30a\21\22\222\10\242\250\21J\322/=@\2\11!\60\21H\63\254\4\241\12yE\20"
"TD\71E\30S\304)e\34R\310\31\245\34Q\314\11\4)\205\230q\4S,\363S\20[\230q"
"\344\201@\234\30\201\211\342\352s\344\215\240L\10\354\64\303\220\22\2\22W\77\301\302\20.\4\361@ "
"\316\260\2\0T'\365K\20+\36\20\343\1\22\36\60\341\1\62\36\20\37\210\60G,\260\26\211\34\63"
"|\10\4I`\375\27\307\14\12\0U)\363S\20+\5$\316\60\244T\322/\245u\332\10\341\205\17"
"\222p!\220\225\222~\251\204\26\306\10a\205P\332YH\25\0V\67\363S\360*\5$\316\260\224\364"
"\227\22\33!\274\360A\12M\210\241\210(\247\210b\214(\345\210B\316(\343\220\42N)\302\230\22\314"
")\241\240\22H*\201\250\21\3\4W@\364S\20;E$\317\64\264\224\322_\11\345\230QF\10\246"
"\224\220\312+H\224RB \244\214\64\212P\243\10\65\212P\243\10E\306P%\220\264RP\341\4\26"
"Jpa\204\7B\10\341\201\21\0XB\363S\360\12F\63\14)\225\24b\247\10S\214\60\304\32\246"
"\230`L\21\5\21Q\322\20D\15\61\230\20\343\3\71\304XC\220D\4ID\224S\204)F\230b"
"\206UL\60\306\4sVJ*\255\303\10Y)\363S\20+\5$\316\60\244T\322/\245u\202\22#"
"\204\300D \315\60\244F\200\304\325o\254\60F\13a\274\322\316*\0Z\63\363S\20\13\36\20\343\1"
"\61\36\20\343\225\366\301 \256j\206\231f\230i\305\225\26\340x\304U\315\60\323L+\216| Zy"
"\344\201\60\36\20\343\1\21\0[(\354S\360\31XHA\204#F(\203\204A\312\251\337!)|@"
"\202\42\250\234\372\16\11\203\214P\206\10G\204\220\304\2\134*\25T\20\13\206\64\260\304\2\15,\320\300"
"\2-XEJ\216\17V\240$\26h\236\201\6\26h=\3\15\254\342\220c\6\1\0](\354K\360"
"\11\226H!\210\23\304(a\220\21\10\42\247~\210\250\360\1\11\211\234\372\221\21\310(a\210\23DH"
"\201\5\0^\37\222\321\331\252\302\13A\64\21\4\33a(\22\10*\241\30\23\14\71\341\210\63\134aG"
"%\2_\24\267@\354*\36 \343\1\23\36@\341\1\63\36 \2\0`\21GQ\233\71B\31\242\10"
"#\212\60\242\32\204\14a/\363S\20\33\36\20!\204\27Fh\202\204%LH\2\251\224\364K\17\220"
"@B\10L\4\322\14+A\250\21\2Y)\351/\245uZy#\6b\67\363S\20\33Z\11\241\21"
"\21\332\30a\21\22\222\10\242\250\21J\322/=@\2\11!\60\21H\63\254\4\241F\10d\245\244_"
"J\241\205\21\232\20\301\211\20\34q\4\0c!\363S\20K\336x\304\31F\34)\256>G\336\210\341"
"\203\34\342\200\344\25W\357\71\23\2\63^yd\62\363S\20\33Z\11\241\21\21\332\30a\21\22\222\10"
"\242\250\21J\322/\245EBx\341\203\24^\10d\245\244_J\241\205\21\232\20\301\211\20\34q\4\0"
"e\62\363S\20\33\36 \341\201\20Dpb\4\66HP\244\270\372\71gB`\247\31VDP\205\274"
"\342\352\71\362HPd\4\66Dp\42\204\7\202x`\0f)\323\323\20\33\36 \341\201\20Dpb"
"\4\66HP\244\270\372\71gB`\247\31V\202P\205\274\342\352s\344\15(b\220\0g)\363S\20"
"K|\245+\305\325\347\10\14\247\264\263\22\11\346\210\20\10\61!%\375\245\22FHa\214\20V\10\245"
"\235\225R\1h)\363S\20\13\202\24\220\70\303\220JI\277\224\24\12J\214\20\2\23\201\64\303J\20"
"j\204@VJ\372Ki\235V\336\210\1i\33\345c\320I\302\20b\204\7\36p\201\210\61\202\13\342"
"\201\7\134 b\14A\2j&\363S\20+C\24p<\342\352\357\21\70b\370 \7H\202XI\251"
"\244\227Jha\214\20V\10\245\235\205T\1k:\363S\20\13B\33B,\42F*\202\34#\12A"
"\242\14\64\212@\244\4T\232)\241\240\22H*a(\362FP&\4v\232a%\10\65B +%"
"\375\245\264N+o\304\0l(\363S\20\13\202\24q@\362\212\253\237#o\304\360A\26\220\274\342\352"
"\71\362HPd\4\66Dp\42\204\7\202x`\0m@\364S\20\33\36(\341\5\22\232(a\211\23"
"\222HJ\225@\24\31C\215\42\324(B\215\42\324(B\215\62\20)d\204`J\11\251\274\202\202)"
"%\4R\6I%\20\245\364S\211\35W\340\220\1n/\363S\20\13\320Ji\235V\336x@\204\25"
"\36\20\243\4EHPe\4\225\264\204\332\10\341\205\17Rx!\220\225\222\376RZ\247\225\67b\0o"
".\363S\20[RZ\247\235e\202H\42\214\261F(I\277\224\26\11\341\205\17\222p!\220\225\222~"
"\251\204\26\306\10a\205P\332YH\25\0p/\363S\20\33Z\11\241\21\21\332\30a\21\22\222\10\242"
"\250\21J\322/=@\2\11!\60\21H\63\254\4\241\12y\305\325\317\221\67\240\210A\2q\71\363S"
"\20KTZ\247\225\20V\10\243\205\21J\322/\245EBx\341\203\24^\10\243\35\245\222\316\234P\214"
"\21\305\30Q\314\21#\24qD\10G\230\221D!\207\220R\314\0r@\363S\20\33Z\11\241\21\21"
"\332\30a\21\22\222\10\242\250\21J\322/=@\2\11!\60\21H\63\254\4\241\12yE\20TD\71"
"E\30S\304)e\34R\310\31\245\34Q\314\11\4)\205\230q\4s,\363S\20[\230q\344\201@"
"\234\30\201\211\342\352s\344\215\240L\10\354\64\303\220\22\2\22W\77\301\302\20.\4\361@ \316\260\2"
"\0t'\365K\20+\36\20\343\1\22\36\60\341\1\62\36\20\37\210\60G,\260\26\211\34\63|\10\4"
"I`\375\27\307\14\12\0u)\363S\20+\5$\316\60\244T\322/\245u\332\10\341\205\17\222p!"
"\220\225\222~\251\204\26\306\10a\205P\332YH\25\0v\67\363S\360*\5$\316\260\224\364\227\22\33"
"!\274\360A\12M\210\241\210(\247\210b\214(\345\210B\316(\343\220\42N)\302\230\22\314)\241\240"
"\22H*\201\250\21\3\4w@\364S\20;E$\317\64\264\224\322_\11\345\230QF\10\246\224\220\312"
"+H\224RB \244\214\64\212P\243\10\65\212P\243\10E\306P%\220\264RP\341\4\26Jpa"
"\204\7B\10\341\201\21\0xB\363S\360\12F\63\14)\225\24b\247\10S\214\60\304\32\246\230`L"
"\21\5\21Q\322\20D\15\61\230\20\343\3\71\304XC\220D\4ID\224S\204)F\230b\206UL"
"\60\306\4sVJ*\255\303\10y)\363S\20+\5$\316\60\244T\322/\245u\202\22#\204\300D"
" \315\60\244F\200\304\325o\254\60F\13a\274\322\316*\0z\63\363S\20\13\36\20\343\1\61\36\20"
"\343\225\366\301 \256j\206\231f\230i\305\225\26\340x\304U\315\60\323L+\216| Zy\344\201\60"
"\36\20\343\1\21\0{(\360Kp\252L\62\351\250\222\202\30i\260\262\352C#\220SD\70G\25\66"
"Fhd\325\217\215\60T\10E\35e\226\1|\11\345l\354\11\376\377\1}&\361Kp\12\316\272V"
"iC\210VX\375\330\20C\5Q\326Y%\205\61\22i\205\325\227F\30\251\204\220n\12\0~\20\320"
"P\226*\12R\345\201\7\14Y\307\10\0\177\17\252\313\20\13\36@\304\376\377\377\310\3\10\0\0\0\4"
"\377\377\0";
/*
Fontname: DS-Digital-42
Copyright:
Glyphs: 96/96
BBX Build Mode: 0
*/
const uint8_t dsdigital_42[4737] U8G2_FONT_SECTION("dsdigital_42") =
"`\0\5\4\6\6\4\6\7$\65\0\367$\0$\0\5\322\14D\22d \6\0\200`\23!\37\305"
"\332\31\224\204!\304\24\36\370\0\11D\10\22\134\30#<\360\1\22\210\30C\220\360\36P\42\21\215\242"
"z\24\224\241\277Q\302(c\204\23\4\0#a\234\267\242\30I\217\30\322\14)\315\220\322\14)\315\220"
"\322\14)\216\30\222\210\20\202\10!\310\60\304\12H`\301\20k\20!\4\21B\220D\14i\206\224f"
"Hi\206\24G\14ID\10A\204\20d\30b\5$\260`\210\65\210\20\202\10!H\42\206\64CJ"
"\63\244\64CJ\63\244\70b\310\23H \0$B\27\275XW\205:f\221u\37\240w\36\20\345\1"
"R\36\20#\214\67\306,\262~\222\314!\232\21\341\235\7\304y\251\215P\307$\262\376\346\30o\204\361"
"\200(\17\220\362\200\70\357\3Sd\335\34\65\60\0%\200a\272\335\231\17m\322p\7\225f\320Y&"
"\235eN\20E\4d\316\20\323\61\246\224R\314)\245\220sJ)\304\240R\312\60\251\224\62\214\42\206"
"\10\303\302 B\14\363\314!\17\31\2\315\21\223|(\215m\314\220\246\24h\312y\246\34gH\20E"
"\4f\306\70C\231QJAg\224R\220!\245\224cJuL\251\214\71CL\307\240 \212\10\307\254"
"\243\312:\212\264\262\306\33l|\0\302\7!d\0&Z\33\271\240\327\254\327\332km\205\261\326\270\305"
"\326^\60\305\215RZ!\245\25RZ!\344\221\42D\23B\204\21\304\23!\14\362\200\20\205<\62D"
"\30m\4\21\304\210\203\220GHi\205\224VHi\205\224VHi\205\224VHi\205\224V\312x\343"
"\204\261FX\255\275\326\336R\0'\14\205\242\272\22|@\205\61\202\0(\42\15\251\240\264 \202\31S"
"\202 e\244\202\352\207H\32K|`\204\42\251\240\372Kc\5A\220\61\70)%\15\251\240\24\234s"
"\35\203\306\10k\244\202\352\227\210\32+|p\302\32\211\240\372K\243\214\21J\71\247\134\6\0*A\327"
"\246\351v\205:f\221\65EH!C\34Q\204\11g\14q\211\21\320\70\42\210c\212\10\341\274\360\201"
")\304\230#\202\70\343\214 \220\70b\210\23\316\30\302\215\62\214\20\245\224\300\212\254\315Q\303\2+#"
"\225\245\247V\205\71b\201\365\224\11#\230\201B\20'(\221\2\32h\30!\202Y\4\326\27\307\14\12"
"\0,\14\205\242\232\22|@\205\61\202\0-\24V\241\260v< \306\3%<p\302\3\205< \4"
"\0.\11E\241\240\22<\240\0/\62\230\251\337\326\12i\242%M\64\361DK\232hd\221F\226Y"
"&\241\343C&\314J\232h\244\211F\26i\242\221&\32id\231\204\22:\254\260\301\2\60\71\27\271"
"`W<p\304\3\42\20\361\202\21- \261\202j\372\327\322#AD!\302\14\37\304\60\203\20Q\4"
"\362R\323\277\226\304\12H\264`\304\13D< \202\20\17\20\1\0\61\35\205\330!\224\204!\304\24\36"
"x\300\5\42\4\11.\14!\36x\300\5\42\246!H\0\62\65\27\271`W<`\306\3\42\10\362\302"
"(-\20\263B\221\365\233\24\25\246\245w\36\20\347\245\326\5%\263\310\372I\42\226\31\242\25!\36\11"
"\342\1Q\36 \2\0\63\64\25\331`\27<`\302\3\42\10\361\302\30-\20\262B\201\365/\222\301\206"
"\30O\4\361\200(\357\60\22\246\220\4\326\77\262B\31-\20\361\302\10\17\210\360\0\2\64*\227\270a"
"\27\4+(\221%\236\227\232\376Zz$\10\321\304\10A<\21\310\3\342\274\324F\250\202\22Y\177\223"
"\320\251\12\33\0\65\67\27\271`W<@D\20\17\210!\304#C\264B\304\62E\326O\22*rK"
"\357< \316K\355\203((\231D\326\317\254PJ\13\204\274\60\306\3\42\10\361\0\21\0\66<\27\271"
"`W<@D\20\17\210!\304#C\264B\304\62E\326\237$T\210f\202x\347\1q^\11\243\215"
" D\24\201\274\324\364\257%\261\2\22-\30\361\2\21\17\210 \304\3D\0\67&\325\330a\27<`"
"\302\3\42\10\361\302\30-\20\262B\201\365/\22)h\370\20\10SH\2\353/\22\71MA\3\70\77"
"\27\271`W<p\304\3\42\20\361\202\21- \261\202j\372\327\322#A\210&\204\10\342\211@\36\20"
"\347\225\60\332\10BD\21\310KM\377Z\22+ \321\202\21/\20\361\200\10B<@\4\0\71:\27"
"\271`W<p\304\3\42\20\361\202\21- \261\202j\372\327\322#A\210&\204\10\342\211@\36\20\347"
"\245\66B\25\224\310\372gV(\245\5B^\30\343\1\21\204x\200\10\0:\15\205\267 \23<\240>"
"\354<\240\0;\22\5\271\32\23<\240>\214=\360\200\12c\4\1\0<\26\17\266&U\225T\222A"
"\7Y\350\234{\367\244\373%\243\312*=\42\226\243\253v< \306\3%<p\302\3\205< >\14"
"< \306\3%<p\302\3\205< \4\0>\25\17\226&\25\224U\224IFY\351\276{\316\375\220"
"\225\212\2\77\61\327\272Y\67<\20\320\3\1=\20\220Sl\204:f\221\365\233\244\64\61\310\13\202<"
" \316K\315\10Jf\221\365'\311\34T\324\360\241^d\235\4@u\35\271\240\330<`\316\3\346<"
"`D(\17\24!F\20\17\14\61\211\7\202 \241\310\22\212,\241L\22\12\35\241\240%\202(\247\221"
"b\34)\207\211 \12\21B\211\21\10!\214\10Q\212*\311\244\222L*\311\244\42D\61\251\4R\210"
"*\241\24!\220 \241 %F(\207\11\21\12b\42\204\222\330(\212\211\202K\36;\210\7Py@"
"\221\7Ty\0\235\7\214\0A\65\27\271`W<p\304\3\42\20\361\202\21- \261\202j\372\327\322"
"#A\210&\204\10\342\211@\36\20\347\225\60\332\10a\304\363R\323\277\226\336\211F\22*,\0B="
"\27\271`W<\23\304+B<\62D+D\254\21Dq#\224\246\277\226\36\11B\64!D\20O\4"
"\362\200\70\257\204\321F\10#\236\227\232\376Zz#\14\261H\20B\64\23\304;\337\1C-\26\271`"
"\327<\20\312\3\241<\20\216+a\260\62d\211\365\213D\16*>$\304$\262\304\372\223\203\206\301\222"
";\17\204\363@\70\17\4D\67\27\271`W<\23\304+B<\62D+D\254\21Dq#\224\246\277"
"\226\36\11\42\12\21f\370 \206\31\302\210\347\245\246\277\226\336\10C,\22\204\20\315\4\361\316w\0E"
"\71\26\271`W<`\304\3#\10\361@\20C\270A\4#%\326_$S\210V\202x\346\1a\36"
"\11\243\25\61\211,\261\376\42\21\214\14\341\206\20\17\4\21\304\3c<P\0F\61\326\270aW<`"
"\304\3#\10\361@\20C\270A\4#%\326_$S\210V\202x\346\1a\36\11\243\25\61\211,\261"
"~\221\310\61\307\24\64T\0G\66\27\271`\327<\20\314\3\301<\20\220\63a\60\63f\221\365I\62"
"G\15\10\71\305\30\11G\221q\220\20\201\274\324\364\257\225\60\336\30a\254\21NK/\265\265\14\0H"
"/\27\271`\27\4+(\221%\236\227\232\376\265\364H\20\242\211\21\202x\42\220\7\304y%\214\66B"
"\30\361\274\324\364\257\245w\242\221\204\12\13\0I\35\5\331 \224\204!\304\24\36\370\0\11D\10\22\134"
"\30#<\360\1\22\210\230\206 \1J*\27\271`\327\206*\350\64\211\254\177\223Pa\303\207L\250c"
"\222 ^r\252\351k%\214\67F\30k\204\323\322Km-\3\0KD\27\271`\27\4\31\206pd"
"\14V\306Xf\220tF\71\207\24sJ)\307\24rN\31\7\25qR\11G\225`V\11\205\21*"
"D\63A\274\363\200\70\257\204\321F\10#\236\227\232\376\265\364N\64\222Pa\1L+\26\271`\27\204"
"*\350\230c\22Yb\375E\62\5\15\37\32\241\212Id\211\365\27\211`d\10\67\204x \210 \36"
"\30\343\201\2MM\26\271`W<@B\20\17\210\60\304\13E\264p\304\12\211)\23\212*\203(R"
"\206\42e(R\206\42e(R\206\42e\244R\10\11\302\224\42D\70\305\4UbI\341\24\23\302\70"
"\303\34\63J\62\241(\246\77\226\334\201&\222)*\0N\71\27\271`\67\214\212\230\20H\21q\222\21"
"\347 qJ\32\207$r\206\42G\250r\202\62&\250\246\265\364N\34!\314\360A\14\63\204\21\317K"
"M\377Zz'\32I\250\260\0O\62\27\271`\327\254\325\322K\355\204\261F\30\343\215P\232\376Zz"
"$\210(D\230\341C&\10\21\317KM\177\255\204\361\306\10c\215pZz\251\255e\0P\66\27\271"
"`W<\23\304+B<\62D+D\254\21Dq#\224\246\277\226\36\11B\64!D\20O\4\362\200"
"\70\257\204\321\312\240d\26Y\177\222\314A\7\25\65X\0Q@\27\271`\327\254\325\322K\355\204\261F"
"\30\343\215P\232~-\275\23G\10\63|\310\4!\242\10\344\245\246\357\220\61B\71e\4Q\216)\345"
"\234\62\322)a\30q\16\22\247(q\12\42\306\30S\0RO\27\271`W<\23\304+B<\62D"
"+D\254\21Dq#\224\246\277\226\36\11B\64!D\20O\4\362\200\70\257\204\321\312\240d\204W\4"
"aE\224U\204QE\234T\306A\205\234S\312\61\305\234R\316!$\235\61\326\21\242\31\21\236\221%"
"\0S\65\27\271`\327\274\363\200(\17\220\362\200\30a\274\61f\221\365\223d\16\321\214\10\357< \316"
"Km\204:&\221\365\67\307x#\214\7Dy\200\224\7\304y\6\0T)\31\251`W<`\306\3"
"(<\240\302\3h<`>@\341\216Zh\275J\254\300\341C,\334Q\11\255\377\253\343\6\6\0U"
",\27\271`\327\12J\244\211\347\245\246\177-=\22D\24\42\314\360!\23\204\210\347\245\246\277V\302x"
"c\204\261F\70-\275\324\326\62\0V@\27\271\340\326\12J\244\201\350\245\246\277\226\336\211#\204\31>"
"\210A\206!\34\21\204\25Q\224\21%\35Q\20\22\345\240Q\14\42\245\34S\310\71e\34T\304IE"
"\30UDYE\20V\346\250\201\2WH\26\271`\267\212I\242\201\307%\246\177,\235`\316\31F\210"
"p\212\11\252\304\222\302)&\10aJ\71\245\220D\312P\244\14E\312P\244\14E\312P\244\14U\6"
"Q&\24\325\220X\302\210&\210xB\210\7\4y\200\4\0XO\27\271\340\26\214h z\251)\306"
"\226\11&\31a\220!\346\230b\31C\14\62\303\244\42\214*\242\60\42\12#\202\270!\306\7~\210\361"
"\206 \215\10\302\212(\253\10\223\314(\310\20sL\261\214!\6\231a\222\11F\231P\330j\311!x"
"\342\0Y,\27\271`\327\12J\244\211\347\245\246\177-\275#\232\220\302\23\201< \316Km\204:&"
"\221\365\67Gi#\224w\36\20\347\245f\0Z;\26\271`\27<P\310\3\204<@\310\3\302\274\17"
"\22\211\25,\320z\6\26h`\211\345\3\23\346\220T\64\317\274\363\14,\221H\42\307\7\351\231\7\4"
"y\200\220\7\10y\200\4\0[+\15\251\240T\60\221\202\20G\14Q\6\21\203\24T\177\210(\261\302"
"\7'\60\241H*\250\376\20\21\203\14Q\206\20G\4\221\306\2\134/\231\231\337\26\214k\346\231\206\232"
"i\250\65\15\65\323Pk\32Z(\261\343\303\20\241\206\26jMC\15-\324\232\206\32Z\325a\307\25"
"\70\4\0]+\15\251\240\24\60\221D\20G\210Q\304 C\20T\377\22Q\202\205\17NX#\21T"
"\177\211\20\42\306\60B\10$BP\202\5\0^$\226\243\266v\205\31\202\210\42\214\67\2i$\224U"
"\202I&\234s\304)\207\234q\314\11\7\65\265Xr\4_\24Z\201\227V<p\306\3)<\260\302"
"\3i<p\4\0`\25\310\242\272s\210\62\206\21f\30a\206\21f\24B\212\10\0a\65\27\271`"
"W<p\304\3\42\20\361\202\21- \261\202j\372\327\322#A\210&\204\10\342\211@\36\20\347\225\60"
"\332\10a\304\363R\323\277\226\336\211F\22*,\0b=\27\271`W<\23\304+B<\62D+D"
"\254\21Dq#\224\246\277\226\36\11B\64!D\20O\4\362\200\70\257\204\321F\10#\236\227\232\376Z"
"z#\14\261H\20B\64\23\304;\337\1c-\26\271`\327<\20\312\3\241<\20\216+a\260\62d"
"\211\365\213D\16*>$\304$\262\304\372\223\203\206\301\222;\17\204\363@\70\17\4d\67\27\271`W"
"<\23\304+B<\62D+D\254\21Dq#\224\246\277\226\36\11\42\12\21f\370 \206\31\302\210\347"
"\245\246\277\226\336\10C,\22\204\20\315\4\361\316w\0e\71\26\271`W<`\304\3#\10\361@\20"
"C\270A\4#%\326_$S\210V\202x\346\1a\36\11\243\25\61\211,\261\376\42\21\214\14\341\206"
"\20\17\4\21\304\3c<P\0f\61\326\270aW<`\304\3#\10\361@\20C\270A\4#%\326"
"_$S\210V\202x\346\1a\36\11\243\25\61\211,\261~\221\310\61\307\24\64T\0g\66\27\271`"
"\327<\20\314\3\301<\20\220\63a\60\63f\221\365I\62G\15\10\71\305\30\11G\221q\220\20\201\274"
"\324\364\257\225\60\336\30a\254\21NK/\265\265\14\0h/\27\271`\27\4+(\221%\236\227\232\376"
"\265\364H\20\242\211\21\202x\42\220\7\304y%\214\66B\30\361\274\324\364\257\245w\242\221\204\12\13\0"
"i\35\5\331 \224\204!\304\24\36\370\0\11D\10\22\134\30#<\360\1\22\210\230\206 \1j*\27"
"\271`\327\206*\350\64\211\254\177\223Pa\303\207L\250c\222 ^r\252\351k%\214\67F\30k\204"
"\323\322Km-\3\0kD\27\271`\27\4\31\206pd\14V\306Xf\220tF\71\207\24sJ)"
"\307\24rN\31\7\25qR\11G\225`V\11\205\21*D\63A\274\363\200\70\257\204\321F\10#\236"
"\227\232\376\265\364N\64\222Pa\1l+\26\271`\27\204*\350\230c\22Yb\375E\62\5\15\37\32"
"\241\212Id\211\365\27\211`d\10\67\204x \210 \36\30\343\201\2mM\26\271`W<@B\20"
"\17\210\60\304\13E\264p\304\12\211)\23\212*\203(R\206\42e(R\206\42e(R\206\42e\244"
"R\10\11\302\224\42D\70\305\4UbI\341\24\23\302\70\303\34\63J\62\241(\246\77\226\334\201&\222"
")*\0n\71\27\271`\67\214\212\230\20H\21q\222\21\347 qJ\32\207$r\206\42G\250r\202"
"\62&\250\246\265\364N\34!\314\360A\14\63\204\21\317KM\377Zz'\32I\250\260\0o\62\27\271"
"`\327\254\325\322K\355\204\261F\30\343\215P\232\376Zz$\210(D\230\341C&\10\21\317KM\177"
"\255\204\361\306\10c\215pZz\251\255e\0p\66\27\271`W<\23\304+B<\62D+D\254\21"
"Dq#\224\246\277\226\36\11B\64!D\20O\4\362\200\70\257\204\321\312\240d\26Y\177\222\314A\7"
"\25\65X\0q@\27\271`\327\254\325\322K\355\204\261F\30\343\215P\232~-\275\23G\10\63|\310"
"\4!\242\10\344\245\246\357\220\61B\71e\4Q\216)\345\234\62\322)a\30q\16\22\247(q\12\42"
"\306\30S\0rO\27\271`W<\23\304+B<\62D+D\254\21Dq#\224\246\277\226\36\11B"
"\64!D\20O\4\362\200\70\257\204\321\312\240d\204W\4aE\224U\204QE\234T\306A\205\234S"
"\312\61\305\234R\316!$\235\61\326\21\242\31\21\236\221%\0s\65\27\271`\327\274\363\200(\17\220\362"
"\200\30a\274\61f\221\365\223d\16\321\214\10\357< \316Km\204:&\221\365\67\307x#\214\7D"
"y\200\224\7\304y\6\0t)\31\251`W<`\306\3(<\240\302\3h<`>@\341\216Zh"
"\275J\254\300\341C,\334Q\11\255\377\253\343\6\6\0u,\27\271`\327\12J\244\211\347\245\246\177-"
"=\22D\24\42\314\360!\23\204\210\347\245\246\277V\302xc\204\261F\70-\275\324\326\62\0v@\27"
"\271\340\326\12J\244\201\350\245\246\277\226\336\211#\204\31>\210A\206!\34\21\204\25Q\224\21%\35Q"
"\20\22\345\240Q\14\42\245\34S\310\71e\34T\304IE\30UDYE\20V\346\250\201\2wH\26"
"\271`\267\212I\242\201\307%\246\177,\235`\316\31F\210p\212\11\252\304\222\302)&\10aJ\71\245"
"\220D\312P\244\14E\312P\244\14E\312P\244\14U\6Q&\24\325\220X\302\210&\210xB\210\7"
"\4y\200\4\0xO\27\271\340\26\214h z\251)\306\226\11&\31a\220!\346\230b\31C\14\62"
"\303\244\42\214*\242\60\42\12#\202\270!\306\7~\210\361\206 \215\10\302\212(\253\10\223\314(\310\20"
"sL\261\214!\6\231a\222\11F\231P\330j\311!x\342\0y,\27\271`\327\12J\244\211\347\245"
"\246\177-\275#\232\220\302\23\201< \316Km\204:&\221\365\67Gi#\224w\36\20\347\245f\0"
"z;\26\271`\27<P\310\3\204<@\310\3\302\274\17\22\211\25,\320z\6\26h`\211\345\3\23"
"\346\220T\64\317\274\363\14,\221H\42\307\7\351\231\7\4y\200\220\7\10y\200\4\0{'\23\231\240"
"u!\205\61\263\202 k\274\342\352\367\210\42B(#BB\314\70\62B\34\217\270\372{#\6A\234"
"a\70|\11E\353\227\24\374\377\17}+\23\251\240\25\234v\65\343\306\10q\274\342\352\347\310\33\202\254"
" \14C\314\250\60\210\32\220\274\342\352\367\306\32#\254\322\316\272\30\0~\22\323\241.v\24\25\202*"
"\17\374\300(,\35\1\0\177\21\15\231!\27|\240\25\374\377\377\177\345\201\7\32\0\0\0\4\377\377\0"
"";
//-----Incluir librerias EspNow----
#include <esp_now.h>
#include <WiFi.h>
//---------------------------------
//-----Incluir Libreria Vesc-------
#include <buffer.h>
#include <crc.h>
#include <datatypes.h>
#include <VescUart.h>
#define DEBUG
#define LED_BUILTIN 32 // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
//---------------------------------
//-----Incluir librerias Giroscopo----
#include <Wire.h>
#include <MPU6050_tockn.h>
//-------------------------------------
//--------Incluir librerias para el Webserver----
#include <WiFiClient.h>
#include <WebServer.h>
#include <WiFiAP.h>
//-----------------------------------------------
//-----Tarea para el Nucleo 0---
TaskHandle_t Task1;
//------------------------
//---- direccion MAC con la que queremos conectar
//uint8_t broadcastAddress[] = {0x3C,0x71,0xBF,0x6A,0x59,0x08};// Mac del mando reflectivo
uint8_t broadcastAddress[] = {0x3C,0x71,0xBF,0x58,0xEF,0xF8};// Mac del mando no reflectivo
//uint8_t broadcastAddress[] = {0xB8,0xF0,0x09,0xCD,0xE3,0x48};// Mac de la placa v4-p1 mando rojo
//uint8_t broadcastAddress[] = {0xA4,0xCF,0x12,0x44,0xF0,0xDC};// Mac de la placa RX2
//uint8_t broadcastAddress[] = {0xB8,0xF0,0x09,0xCD,0xF5,0x04};// Mac de la placa v4-p2 mando rojo
//-----Definimos el giroscopo----
MPU6050 mpu6050(Wire);
bool orientacionAdecuada = false;// Inicializamos la orientacion del mismo como erronea
//-------------------------------
//----- VescUart-----
VescUart UART;
//---------------------------------
//------Estructura para almacenar los datos del Vesc---
struct vescValues {
float ampHoursSen;
float inpVoltageSen;
long rpmSen;
long tachometerAbsSen;
float avgMotorCurrentSen;
float avgInputCurrentSen;
float temp_pcbSen;
float temp_motorSen;
float potenciaSen;
float watiosHoraSen;
};
//--------------------------------------------------
//-----Definimos variables para enviar de la placa---
int placaOnSen = 0;
const int placaOnPin = 25;
const int encendidoPin = 33;
const int apagadoPin = 26;
const int resetPin = 27;
const int cambioPin = 27;
const int cambioTelemetriaPin = 14;
//-------------------------------------
//----Definimos variables entrantes para leer---
float acelIn;
int apagadoIn= 0;
int encendidoIn = 0;
int resetIn = 0;
int cambioTelemetriaIn = 0;
// Variable que cambia la telemetria, si cambioTelemetriaIn = 1 su estado varia entre 0 y 1.
int estadoTelemetria = 0;
//---------------------------------------------
//------Variable para almacenar exito---
String success;
//--------------------------------------
//------Estructura para enviar datos---
// Debe coincidir con la estructura del receptor
typedef struct struct_message{
//float prueba;
float acel;
float ampHours;
float inpVoltage;
long rpm;
long tachometerAbs;
float avgMotorCurrent;
float avgInputCurrent;
float potCal;
float temp_pcb;
float temp_motor;
float watiosHora;
float potencia;
int encendido;
int apagado;
int placaOn;
int Reset;
int cambioTelemetria;
}struct_message;
//----------------------------------
//----Definimos las variables-----
float potencia = 0.0;
float watiosConsumidos = 0.0;
float avgPotencia = 0.0;
float watiosHora = 0.0;
int motorSpeed = 0;
int timeoutMax = 500;
int throttlePin = 34;
float potenciaSen = 0;
float watiosHoraSen = 0;
//--------------------------------
//-----Setting PWM properties---
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
int tiempoTranscurrido = 0;
int seg=0;
//------------------------------
// Last time data was pulled from VESC
unsigned long tiempo;
//------- Estructura que utilizamos para actualizar datos del Vesc------
struct vescValues data;
unsigned long lastDataCheck;
//----------------------------------------------------------------------
//----Creamos una estructura para almacenar las lecturas de sensor--
struct_message SensorReadings;
//------------------------------------------------------------------
//----Creamos una estructura para almacenar las lecturas de sensor entrantes--
struct_message incomingReadings;
//----------------------------------------------------------------------------
//--------------------Callback when data is sent-------------------------------------
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0){
success = "Delivery Success :)";
}
else{
success = "Delivery Fail :(";
acelIn = 0;// Si se corta la comunicacion hacemos que el valor del acelerador sea 0
}
}
//------------------------------------------------------------------------------------
//--------------------Callback when data is received---------------------------------
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print("Bytes received: ");//solo podemos recibir 250 bytes por paquete
Serial.println(len);
acelIn = incomingReadings.acel;
encendidoIn = incomingReadings.encendido;
apagadoIn = incomingReadings.apagado;
resetIn = incomingReadings.Reset;
cambioTelemetriaIn = incomingReadings.cambioTelemetria;
// Serial.println(encendidoIn);
// Serial.println(apagadoIn);
// Serial.println(resetIn);
}
//------Variables del uart que se envian a la web------
std::string ampHoursS = "0.0";
std::string inpVoltageS = "0.0";
std::string rpmS = "0";
std::string tachometerAbsS = "0";
std::string avgMotorCurrentS = "0";
std::string avgInputCurrentS = "0";
std::string tempS = "0.0";
std::string temp_motorS = "0.0";
std::string potenciaS = "0";
std::string watiosHoraS = "0";
//-------------------------------------------------------
//WebServer serverWeb(80);
/*void paginaIndex(){
serverWeb.send(200, "text/html", pagIndex);
}
*/
//-----Asignamos los valores a las variables string para enviarlas a la web---
/*void sendData(){
// Aqui recogere los datos del VesCUART
char buffer[10];
String ampHoursS = dtostrf(data.ampHoursSen, 3, 2, buffer);
String inpVoltageS = dtostrf(data.inpVoltageSen, 3, 2, buffer);
String rpmS = dtostrf(data.rpmSen, 3, 2, buffer);
String tachometerAbsS = dtostrf(data.tachometerAbsSen, 3, 2, buffer);
String avgMotorCurrentS = dtostrf(data.avgMotorCurrentSen, 3, 2, buffer);
String avgInputCurrentS = dtostrf(data.avgInputCurrentSen, 3, 2, buffer);
String tempS = dtostrf(data.temp_pcbSen, 3, 2, buffer);
String temp_motorS = dtostrf(data.temp_motorSen, 3, 2, buffer);
String potenciaS = dtostrf(potenciaSen, 3, 2, buffer);
String watiosHoraS = dtostrf(watiosHoraSen, 3, 2 , buffer);
String info = ampHoursS + ", " + inpVoltageS + ", " + rpmS + ", " + avgMotorCurrentS + ", " + avgInputCurrentS + ", " + tempS + ", " + temp_motorS + ", " + potenciaS+ ", " + watiosHoraS;
serverWeb.send(200, "text/plain", info);
}*/
//-----Funcion con la que tomamos los valores del Vesc------
void getVescData() {
if(estadoTelemetria == 1) {
data.ampHoursSen = 0.0;
data.inpVoltageSen = 0.0;
data.rpmSen = 0;
data.tachometerAbsSen = 0.0;
data.avgMotorCurrentSen = 0.0;
data.avgInputCurrentSen = 0.0;
data.temp_pcbSen = 0.0; // En la nueva libreria de VescUart no existen tem_pcb ni temp_motor
data.temp_motorSen = 0.0;
potenciaSen = 0.0;
watiosHora = 0.0;
watiosHoraSen = 0.0;
} else {
delay(500);
if (millis() - lastDataCheck >= 250) {
lastDataCheck = millis();
if ( UART.getVescValues() ) {
data.ampHoursSen = UART.data.ampHours;
data.inpVoltageSen = UART.data.inpVoltage;
data.rpmSen = UART.data.rpm;
data.tachometerAbsSen = UART.data.tachometerAbs;
data.avgMotorCurrentSen = UART.data.avgMotorCurrent;
data.avgInputCurrentSen = UART.data.avgInputCurrent;
data.temp_pcbSen = UART.data.temp_pcb; // En la nueva libreria de VescUart no existen tem_pcb ni temp_motor
data.temp_motorSen = UART.data.temp_motor;//(procura conservar la antigua)
}
else
{
data.ampHoursSen = 0.0;
data.inpVoltageSen = 0.0;
data.rpmSen = 0;
data.tachometerAbsSen = 0.0;
data.avgMotorCurrentSen = 0.0;
data.avgInputCurrentSen = 0.0;
data.temp_pcbSen = 0.0; // En la nueva libreria de VescUart no existen tem_pcb ni temp_motor
data.temp_motorSen = 0.0;
}
potenciaSen = data.inpVoltageSen * data.avgInputCurrentSen;
if(data.avgInputCurrentSen > 0){
tiempoTranscurrido = tiempoTranscurrido+1;
watiosConsumidos = watiosConsumidos + potenciaSen;
avgPotencia = watiosConsumidos / tiempoTranscurrido;
watiosHora = float(avgPotencia) * (float(tiempoTranscurrido) / float(3600));
}
watiosHoraSen = watiosHora/4; //dividimos entre 4 para subsanar el error de calculo
}
}
}
//----Funcion con la que controlamos el encendido y apagado de la placa---
void encenderPlaca() {
if(encendidoIn == 1){
digitalWrite(encendidoPin,HIGH);
digitalWrite(apagadoPin,LOW);
}
if(apagadoIn == 1){
digitalWrite(apagadoPin,HIGH);
digitalWrite(encendidoPin,LOW);
}
if((encendidoIn == 0 )&& (apagadoIn == 0)){
digitalWrite(encendidoPin,LOW);
digitalWrite(apagadoPin,LOW);
}
if(digitalRead(placaOnPin) == HIGH){
placaOnSen = 1;
}
else{
placaOnSen = 0;
}
}
//---------------------------------------------------------------------
//---Funcion que resetea nuestra placa----
void doReset(){
if(resetIn == 1){
digitalWrite(resetPin, HIGH);
}
else{
digitalWrite(resetPin, LOW);
}
}
//----------------------------------------
void cambiaEstadoTelemetria(){
delay(120);
if(cambioTelemetriaIn == 1){
if(estadoTelemetria == 1){
estadoTelemetria = 0;
} else if(estadoTelemetria == 0) {
estadoTelemetria = 1;
}
}
}
//---Funcion que cambia la telemetria----
void cambioTelemetria(){
if(estadoTelemetria == 1){
digitalWrite(cambioTelemetriaPin, HIGH);
}
else{
digitalWrite(cambioTelemetriaPin, LOW);
}
}
//----------------------------------------
void setup() {
//----Inicializamos el monitor serie---
#ifdef DEBUG
Serial.begin(115200);
Serial.println("Esperando 3 segundos");
delay(3000);
//delay para poder cambiar el puerto en la configuracion para pruebas
#endif
Serial2.begin(115200, SERIAL_8N1, 16, 17);
//---Puerto serie del VescUart----
while(!Serial){;}
UART.setSerialPort(&Serial2);
//-------------------------------
//--------EspNow---------
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);
//---------------------------------------
//---Encendemos Webserver--------
/*WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
serverWeb.on("/", paginaIndex);
serverWeb.on("/favicon.ico", paginaIndex);
Serial.println(myIP);
serverWeb.on("/data", sendData);
serverWeb.begin();*/
//------------------------------
//----- Encendemos giroscopo-------
Wire.begin();
mpu6050.begin();
mpu6050.calcGyroOffsets(true);
//---------------------------------
pinMode(LED_BUILTIN, OUTPUT);
//--- Configure LED PWM functionalitites----
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO2 to be controlled
ledcAttachPin(LED_BUILTIN, ledChannel);
ledcWrite(0, acelIn);
//------------------------------------------
//-----Definimos los valores de entrada y salida de la placa-----
pinMode(encendidoPin, OUTPUT);
pinMode(apagadoPin, OUTPUT);
pinMode(placaOnPin,INPUT);
pinMode(resetPin, OUTPUT);
pinMode(cambioTelemetriaPin, OUTPUT);
//---------------------------------------------------------------
//------Inicializamos la tarea del nucleo 0---
xTaskCreatePinnedToCore(
Task1code, /* Function to implement the task */
"Task1", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
2, /* Priority of the task */
&Task1, /* Task handle. */
0); /* Core where the task should run */
//--------------------------------------------
}
void Task1code ( void * pvParameters ){
for(;;){
//Llamamos a la funcion que lea nuestras variables
getVescData();
//Llamamos a la funcion que enciende nuestra placa
encenderPlaca();
//Llamamosa la funcion que resetea nuestra placa
doReset();
//Llamamosa la funcion que cambia la telemetria
cambiaEstadoTelemetria();
cambioTelemetria();
// Set values to send
SensorReadings.ampHours = data.ampHoursSen;
SensorReadings.inpVoltage = data.inpVoltageSen;
SensorReadings.rpm = data.rpmSen;
SensorReadings.tachometerAbs = data.tachometerAbsSen;
SensorReadings.avgMotorCurrent = data.avgMotorCurrentSen;
SensorReadings.avgInputCurrent = data.avgInputCurrentSen;
SensorReadings.temp_pcb = data.temp_pcbSen; // En la nueva libreria de VescUart no existen tem_pcb ni temp_motor
SensorReadings.temp_motor = data.temp_motorSen;
SensorReadings.watiosHora = watiosHoraSen;
SensorReadings.potencia = potenciaSen;
SensorReadings.placaOn = placaOnSen;
//------Send message via ESP-NOW----------------
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &SensorReadings, sizeof(SensorReadings));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
//---------------------------------------------
//------Condicion del giroscopo----
//Actualizamos el giroscopo
mpu6050.update();
// Tomamos angulos del giroscopio
mpu6050.getAngleY();
mpu6050.getAngleX();
// Serial.println(mpu6050.getAngleY());
// Serial.println(mpu6050.getAngleX());
// if(((mpu6050.getAngleY() < 90) && (mpu6050.getAngleY() > -90 )) && ((mpu6050.getAngleX() < 90)&&(mpu6050.getAngleX() > -90))){// se comprueba que la inclinacion en x e y no es superior a 90 ni inferior a -90
// orientacionAdecuada = true;
//Serial.println("Orientacion adecuada");
ledcWrite(0, acelIn);//Lectura del valor del acelerador y salida por el pin hacia el Vesc
// }
// else {
// orientacionAdecuada = false;
// ledcWrite(0, 0);//pasamos un 0 como valor del acelerador ya que no queremos que mientras la orientacion no sea adecuada se pueda acelerar
// //Serial.println("Orientacion no adecuada");
// }
//delay(50);
//Serial.println(data.temp_pcbSen);
}
}
void loop() {
//serverWeb.handleClient();
#ifdef DEBUG
#endif
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment