diff --git a/TinyPICO Explorer Shield/Explorer_Shield_Pinout.jpg b/TinyPICO Explorer Shield/Explorer_Shield_Pinout.jpg new file mode 100644 index 0000000..382f77e Binary files /dev/null and b/TinyPICO Explorer Shield/Explorer_Shield_Pinout.jpg differ diff --git a/TinyPICO Explorer Shield/README.rst b/TinyPICO Explorer Shield/README.rst new file mode 100644 index 0000000..e35d345 --- /dev/null +++ b/TinyPICO Explorer Shield/README.rst @@ -0,0 +1,18 @@ +TinyPICO Explorer Shield Template +================================= + +This is a template project for the Explorer shield that implements all of the hardware for TinyPICO, TinyS2 and TinyS3 and shows examples of everything working at a basic level. + +This example project is still unfinished based on what I'd like to have included, but it is a perfect spring board for getting an Explorer shield project up and running. + +Please remember to install the following libraries from the Arduino Library Manager: + +Adafruit_GFX + +Adafruit_ST7789 + +Adafruit_LIS3DH + +Adafruit_Sensor + +Adafruit_MPR121 \ No newline at end of file diff --git a/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/TinyPICO_Explorer_Shield_Template.ino b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/TinyPICO_Explorer_Shield_Template.ino new file mode 100644 index 0000000..51ada89 --- /dev/null +++ b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/TinyPICO_Explorer_Shield_Template.ino @@ -0,0 +1,401 @@ +/* + Explorer Shield Template +*/ + +#include +#include +#include +#include +#include +#include // Hardware-specific library for ST7789 +#include +#include + +#include "buttons.h" +#include "secret.h" +#include "bitmaps.h" +#include "helpers.h" + +#if defined(ARDUINO_TINYS3) + +#define IMU_INT 6 +#define LIGHT_SENSOR 7 +#define AUDIO 21 +#define SD_CARD_DETECT 5 +#define SD_CARD_CS 34 +#define TFT_BACKLIGHT 4 +#define TFT_CS 2 +#define TCT_DC 1 + +#elif defined(ARDUINO_TINYS2) + +#define IMU_INT 33 +#define LIGHT_SENSOR 38 // Digital HIGH/LOW only +#define AUDIO 18 +#define SD_CARD_DETECT 17 +#define SD_CARD_CS 14 +#define TFT_BACKLIGHT 7 +#define TFT_CS 5 +#define TCT_DC 4 + +#else + +#define IMU_INT 33 +#define LIGHT_SENSOR 32 +#define AUDIO 25 +#define SD_CARD_DETECT 26 +#define SD_CARD_CS 5 +#define TFT_BACKLIGHT 27 +#define TFT_CS 14 +#define TCT_DC 4 + +#endif + +#define TFT_RESET -1 + +// Declaration for the ST7789 +Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TCT_DC, TFT_RESET); + +// Declaration for the LIS3DH accelerometer +Adafruit_LIS3DH lis = Adafruit_LIS3DH(); + + +ExplorerButtonManager buttonManager; + +int idle_time_to_deepsleep = 1000 * 30; // 30 seconds in millis +int idle_time_to_deepsleep_warning = 1000 * 10; // 10 seconds in millis +unsigned long last_button_touched = 0; +unsigned long one_second_step = 0; +bool is_sec_step = false; +bool is_showing_ds_warning = false; +unsigned long nextReadTimeIMU = 0; +double roll = 0.00, pitch = 0.00; //Roll & Pitch are the angles which rotate by the axis X and y + +unsigned long nextReadTimeLightSensor = 0; +float lightSensorVal; + +int currentState = 0; +bool isToneInit = false; + +void Tone(uint32_t freq) +{ + if ( !isToneInit ) + { + pinMode( AUDIO, OUTPUT); + ledcSetup(0, freq, 8); // Channel 0, resolution 8 + ledcAttachPin( AUDIO, 0 ); + isToneInit = true; + } + ledcWriteTone( 0, freq ); +} + +void NoTone() +{ + if (isToneInit) + { + ledcWriteTone(0, 0); + pinMode( AUDIO, INPUT_PULLDOWN); + isToneInit = false; + } +} + +void BootSound() +{ + for (int freq = 255; freq < 2000; freq = freq + 250) + { + Tone(freq); + delay(50); + } + NoTone(); +} + +void beep( int freq, int hold = 25 ) +{ + Tone(freq); + delay(hold); + NoTone(); +} + +void button_Touched() +{ + beep(500, 10); +} + +void button1_Click() +{ + Serial.println("Clicked 1"); + beep(1000); +} + +void button1_LongPress() +{ + Serial.println("Long Press 1"); + beep(2000, 50); +} + +void setup() +{ + Serial.begin(115200); + + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); + + // Disable any IO deep sleep hold that was set before going into dfeep sleep. +#if defined(ARDUINO_TINYS3) + gpio_hold_dis(GPIO_NUM_4); +#elif defined(ARDUINO_TINYS2) + gpio_hold_dis(GPIO_NUM_7); +#else + gpio_hold_dis(GPIO_NUM_27); +#endif + gpio_deep_sleep_hold_dis(); + + pinMode(LIGHT_SENSOR, INPUT); + pinMode(SD_CARD_DETECT, INPUT_PULLUP); + + delay(500); + + pinMode(TFT_BACKLIGHT, OUTPUT); + // Digital ON/OFF for TFT Backlight + digitalWrite(TFT_BACKLIGHT, HIGH); + + // PWM control for TFT Backlight + // Setup timer and attach timer to a led pin + // ledcSetup(0, 1000, 13); + // ledcAttachPin(TFT_BACKLIGHT, 0); + // ledcWrite(0, 0); + + Serial.println(); + + // Init ST7789 240x240 + tft.init(240, 240); + tft.fillScreen(ST77XX_BLACK); + + // Initialise the button manager + buttonManager.begin(button_Touched); + // Example of how to wire up a button for click and long press callbacks + buttonManager.assignCallbacks('1', button1_Click, button1_LongPress); + + // Initialise the LIS3DH at addreess 0x18 + if (!lis.begin(0x18)) + { + Serial.println("Error - LIS3DH Not Found or failed to start - Execution halted!"); + while (1) { + delay(10); + } + } + else + { + // Set the IMU rage - options are 2, 4, 8 or 16 G + lis.setRange(LIS3DH_RANGE_4_G); + + Serial.print("LIS3DH Range = "); + Serial.print(2 << lis.getRange()); + Serial.println("G"); + } + + delay(100); + + // Show initial UM Logo as a splash screen. + tft.fillScreen(ST77XX_BLACK); + tft.setRotation(0); + tft.drawBitmap( 30, ( tft.height() / 2 ) - 45 , UM_Logo, 180, 90, ST77XX_WHITE); + + // Play a boot sound + BootSound(); + + delay(1000); + + // Show TinyPICO Logo & Explorer Shield info + tft.fillScreen(ST77XX_BLACK); + tft.drawBitmap( 25, 20, TP_Logo, 190, 44, ST77XX_BLUE); + tft.setTextSize(2); + tft.setCursor(30, 72); + tft.println( "EXPLORER SHIELD" ); + + // Gety the state of the SD Card + Serial.print("uSD Card: "); + Serial.println(GetSDCard()); + +} + +void loop() { + + // Tick buttons via the Button Manager + last_button_touched = buttonManager.tick(); + + + if ( millis() - one_second_step > 1000 ) + { + one_second_step = millis(); + is_sec_step = true; + } + else + is_sec_step = false; + + + // Lastly, run the deep sleep timer if you want the device to sleep after a certain period + // RunDeepSleepTimer(); +} + +void RunDeepSleepTimer() +{ + // Have we been idle long enough to go into deep sleep? + if (millis() - last_button_touched > idle_time_to_deepsleep) + SetupDeepSleep(); + else if (millis() - last_button_touched > idle_time_to_deepsleep - idle_time_to_deepsleep_warning ) + { + // We only show the deep sleep warning when there is 10 seconds left or less and a whole second has flipped + if (is_sec_step) + ShowDeepSleepWarning((last_button_touched + idle_time_to_deepsleep) - millis() ); + } + else if (is_showing_ds_warning) + { + // If we were showing the message, but the user touched a button to keep the shield alive, + // we need to clear the message + is_showing_ds_warning = false; + tft.fillRect(0, 220, 240, 20, ST77XX_BLACK); + } +} +void ShowDeepSleepWarning(int time_left) +{ + // we want to count down from 10 to 1, not 9 to 0 + time_left = round(time_left / 1000) + 1; + + tft.fillRect(0, 220, 240, 20, ST77XX_BLACK); + tft.setTextSize(2); + tft.setTextColor(ST77XX_BLUE); + println_Center(tft, "DEEP SLEEP in " + String(time_left) + "s", tft.width() / 2, 230); + is_showing_ds_warning = true; +} + +void DeepSleepCallback() +{ + //placeholder callback function +} + + +void SetupDeepSleep() +{ + /* + Make sure we display a message to the user before this happens, letting them know we are + going to go into deep sleep, so they have an opportunity to touch a button and prevent it from happening + + */ + + // Interrupt on IO15 (Touch Pad 3) with a thresholf of 70 for higher sensitivity + touchAttachInterrupt(T3, DeepSleepCallback, 70); + + //Configure Touchpad as wakeup source + esp_sleep_enable_touchpad_wakeup(); + + // Clear the TFT + tft.fillScreen(ST77XX_BLACK); + digitalWrite(TFT_BACKLIGHT, LOW); + + /* + Hold the backlight IO low during deep sleep to reduce power GPIO_NUM_27 + is the gpio_num_t struct for TFT_BACKLIGHT/IO27 for TinyPICO as an example + + */ + +#if defined(ARDUINO_TINYS3) + gpio_hold_en(GPIO_NUM_4); +#elif defined(ARDUINO_TINYS2) + gpio_hold_en(GPIO_NUM_7); +#else + gpio_hold_en(GPIO_NUM_27); +#endif + + gpio_deep_sleep_hold_en(); + delay(5); + + //Go to sleep now + Serial.println("Going to sleep now"); + esp_deep_sleep_start(); +} + + +float GrabLightSensor() +{ + // If it's not time to read the input, return the cached value + if ( nextReadTimeLightSensor > millis() ) + return lightSensorVal; + // Set the next read time to 500ms from now + nextReadTimeLightSensor = millis() + 500; + lightSensorVal = 0; + // Read the value from the sensor + +#if defined(ARDUINO_TINYS2) + // TinyS2 LIGHT_SENSOR pin isn't an ADC pin. + lightSensorVal = digitalRead( LIGHT_SENSOR ); +#else + lightSensorVal = analogRead( LIGHT_SENSOR ); +#endif + + return lightSensorVal; +} + + +void GrabAccel() +{ + // If it's not time to read the input, return early + if ( nextReadTimeIMU > millis() ) + return; + + // Set the next read time to 200ms from now + nextReadTimeIMU = millis() + 200; + + sensors_event_t event; + lis.getEvent(&event); + + double x_Buff = float(event.acceleration.x); + double y_Buff = float(event.acceleration.y); + double z_Buff = float(event.acceleration.z); + + roll = atan2(y_Buff , z_Buff) * 57.3; + pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3; + + Serial.print("IMU Roll: "); + Serial.print(roll); + Serial.print("Pitch: "); + Serial.println(pitch); + +} + +// Wifi Stuff +int8_t GetWifiQuality() +{ + int32_t dbm = WiFi.RSSI(); + if (dbm <= -100) { + return 0; + } else if (dbm >= -50) { + return 100; + } else { + return 2 * (dbm + 100); + } +} + +int GetSDCard() +{ + if (digitalRead(SD_CARD_DETECT) == LOW ) + { + Serial.println("SDCard found! Initializing..."); + + if (!SD.begin(SD_CARD_CS)) + { + Serial.println("SDCard initialization failed!"); + return 2; + } + else + { + Serial.println("SDCard found!.."); + return 1; + } + } + else + { + Serial.println("No SDCard found! Please insert!"); + return 0; + } +} diff --git a/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/bitmaps.h b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/bitmaps.h new file mode 100644 index 0000000..20fd29c --- /dev/null +++ b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/bitmaps.h @@ -0,0 +1,230 @@ +const unsigned char UM_Logo[] 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, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xe0, 0x03, 0xff, 0xff, + 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, + 0xfc, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, + 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, + 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, + 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, + 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, + 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, + 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x01, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, + 0x03, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, + 0xfc, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xc0, 0x00, + 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x07, 0xff, + 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, + 0x03, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x7f, + 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xe0, + 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, + 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, + 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x7f, + 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf0, + 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, + 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, + 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, + 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, + 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, + 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, + 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, + 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, + 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, + 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, + 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, + 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, + 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, + 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, + 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, + 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, + 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, + 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, + 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, + 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, + 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, + 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, + 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, + 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x03, 0xff, + 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, + 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, + 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0xf8, + 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, + 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, + 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x07, + 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, + 0x80, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, + 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, + 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, + 0x7f, 0xff, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, + 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, + 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x0f, 0xff, + 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, + 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, + 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x3f, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, + 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, + 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, + 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, + 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, + 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, + 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, + 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, + 0xff, 0xfe, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, + 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3c, 0x00, 0x07, 0xff, 0xff, + 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const uint8_t PROGMEM TP_Logo[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7e, 0x00, 0x00, 0x03, 0x83, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xfc, 0x1f, 0xff, 0xc0, 0x0f, 0xff, 0xf0, 0x01, 0xff, 0xe0, + 0x7e, 0x00, 0x00, 0x03, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xfc, 0x1f, + 0xff, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x7f, 0xf0, 0x7e, 0x00, 0x00, 0x03, 0x83, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xfc, 0x1f, 0xfc, 0x00, 0x00, 0xff, 0x80, 0x00, 0x3f, 0xf0, + 0x7e, 0x00, 0x00, 0x03, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xfc, 0x1f, + 0xf8, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x0f, 0xf0, 0x7e, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0xfc, 0x1f, 0xf0, 0x07, 0x81, 0xfc, 0x01, 0xf0, 0x07, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xc0, 0x7c, 0x1f, + 0xe0, 0x1f, 0xf1, 0xfc, 0x07, 0xfc, 0x07, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xe0, 0x7c, 0x1f, 0xe0, 0x7f, 0xff, 0xf8, 0x0f, 0xff, 0x03, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xf0, 0x7c, 0x1f, + 0xc0, 0x7f, 0xff, 0xf0, 0x1f, 0xff, 0x01, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0xe0, 0x07, + 0xe0, 0xff, 0xe0, 0x70, 0x3f, 0xf0, 0x7c, 0x1f, 0xc0, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0x81, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x40, 0x03, 0xe0, 0x7f, 0xe0, 0xf0, 0x3f, 0xf0, 0x7c, 0x1f, + 0x81, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0x81, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x00, 0x01, + 0xf0, 0x7f, 0xc0, 0xf0, 0x3f, 0xf0, 0x7c, 0x1f, 0x81, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x07, 0x81, 0xf0, 0x7f, 0xc0, 0xf0, 0x3f, 0xf0, 0x7c, 0x1f, + 0x81, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x1f, 0xc0, + 0xf0, 0x3f, 0xc1, 0xf0, 0x3f, 0xe0, 0x7c, 0x1f, 0x81, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x3f, 0xc0, 0xf8, 0x3f, 0x81, 0xf0, 0x3f, 0xc0, 0x7c, 0x1f, + 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x3f, 0xe0, + 0xf8, 0x1f, 0x83, 0xf0, 0x3f, 0x00, 0xfc, 0x1f, 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xfc, 0x1f, 0x83, 0xf0, 0x00, 0x01, 0xfc, 0x1f, + 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xfc, 0x1f, 0x03, 0xf0, 0x00, 0x03, 0xfc, 0x1f, 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xfc, 0x0f, 0x07, 0xf0, 0x00, 0x07, 0xfc, 0x1f, + 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xfe, 0x0f, 0x07, 0xf0, 0x00, 0x3f, 0xfc, 0x1f, 0x81, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xc0, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xfe, 0x0e, 0x07, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0x81, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xff, 0x06, 0x0f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, 0x81, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xc1, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xff, 0x06, 0x0f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0xc0, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0x81, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xff, 0x04, 0x1f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, 0xc0, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0x81, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xff, 0x80, 0x1f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0xe0, 0x7f, 0xff, 0xf8, 0x1f, 0xff, 0x03, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xff, 0x80, 0x1f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, 0xe0, 0x3f, 0xfd, 0xf8, 0x0f, 0xfe, 0x03, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xff, 0xc0, 0x3f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0xf0, 0x0f, 0xe1, 0xfc, 0x01, 0xf0, 0x07, 0xf8, 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xff, 0xc0, 0x3f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, 0xf8, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x0f, 0xf8, + 0x7f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xff, 0xe0, 0x7f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0xfc, 0x00, 0x01, 0xff, 0x00, 0x00, 0x1f, 0xf0, 0x3f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, + 0xff, 0xe0, 0x7f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, 0xfe, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x7f, 0xf0, + 0x3f, 0xff, 0x07, 0xff, 0x83, 0xf0, 0x7f, 0xe0, 0xff, 0xe0, 0x7f, 0xf0, 0x3f, 0xff, 0xfc, 0x1f, + 0xff, 0x80, 0x07, 0xff, 0xf0, 0x01, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const uint8_t PROGMEM icon_wifi[] = { +0x1f,0xe0 +,0x70,0x38 +,0xc7,0x8c +,0x1c,0xe0 +,0x30,0x30 +,0x07,0x80 +,0x0c,0xc0 +,0x00,0x00 +,0x03,0x00 +,0x03,0x00 + +}; + + +const uint8_t PROGMEM icon_wifi_rev[] = { +0xe0,0x1c +,0x8f,0xc4 +,0x38,0x70 +,0xe3,0x1c +,0xcf,0xcc +,0xf8,0x7c +,0xf3,0x3c +,0xff,0xfc +,0xfc,0xfc +,0xfc,0xfc + +}; diff --git a/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/buttons.h b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/buttons.h new file mode 100644 index 0000000..7f1f5cf --- /dev/null +++ b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/buttons.h @@ -0,0 +1,210 @@ +#include + +#ifndef _BV +#define _BV(bit) (1 << (bit)) +#endif + +extern "C" { + typedef void (*callbackFunction)(void); +} + +class ExplorerButton +{ + public: + ExplorerButton(); + + void setupButton(char button, Adafruit_MPR121 cap, callbackFunction touchBeep); + void attachPress(callbackFunction newFunction); + void attachPressLong(callbackFunction newFunction); + + bool tick(void); + bool tick(bool level); + void reset(void); + + int getId(char button); + + private: + Adafruit_MPR121 _cap; + char _ids[12] = {'3', '2', '1', 'D', 'L', 'R', '4', 'U', 'B', 'A', 'Y', 'X'}; + int _id = -1; // button face id from MPR + unsigned int _clickTicks = 100; // number of ticks before a click is detected + unsigned int _pressTicks = 300; // number of ticks before a long press is detected + + // These variables will hold functions acting as event source. + callbackFunction _touchBeep = NULL; + callbackFunction _pressFunc = NULL; + callbackFunction _pressLongFunc = NULL; + + int _state = 0; + unsigned long _startTime; +}; + + +ExplorerButton::ExplorerButton() +{ +} + +void ExplorerButton::setupButton(char button, Adafruit_MPR121 cap, callbackFunction touchBeep = nullptr) +{ + _cap = cap; + _id = getId(button); + _touchBeep = touchBeep; +} + +int ExplorerButton::getId( char button ) +{ + for ( int i = 0; i < 12; i++ ) + { + if ( _ids[i] == button ) + return i; + } + return -1; +} + +// save function for click event +void ExplorerButton::attachPress(callbackFunction newFunction) +{ + _pressFunc = newFunction; +} + +// save function for doubleClick event +void ExplorerButton::attachPressLong(callbackFunction newFunction) +{ + _pressLongFunc = newFunction; +} + +void ExplorerButton::reset(void) { + _state = 0; + _startTime = 0; +} + +bool ExplorerButton::tick(void) +{ + // We only want to tick this button if it has an ID. + if (_id > -1 ) + return tick(_cap.touched() & _BV(_id)); + + return false; +} + +bool ExplorerButton::tick(bool activeLevel) +{ + unsigned long now = millis(); // current time in milis. + bool was_touched = false; + + if (_state == 0) // Start state + { + if (activeLevel) + { + _state = 1; // step to state 1 + _startTime = now; // remember starting time + + was_touched = true; + + if ( _touchBeep ) + _touchBeep(); + } // if + } + else if (_state == 1) // Pressed state + { + if (!activeLevel) // Did we let go of the button? + { + was_touched = true; + + // Did we hold long enough for a long press and do we have a long press callback? + if ( ((unsigned long)(now - _startTime) > _pressTicks) && _pressLongFunc ) + { + _pressLongFunc(); + } + // Ok, not a long press, so do we have a click callback? + else if ( ((unsigned long)(now - _startTime) > _clickTicks) && _pressFunc ) + { + _pressFunc(); + } + reset(); + } + } + + return was_touched; +}; + + + +class ExplorerButtonManager +{ + public: + ExplorerButtonManager(); + unsigned long tick(void); + void begin(callbackFunction touchBeep); + void assignCallbacks(char face, callbackFunction click, callbackFunction press); + int getId(char button); + private: + Adafruit_MPR121 cap; + char _ids[12] = {'3', '2', '1', 'D', 'L', 'R', '4', 'U', 'B', 'A', 'Y', 'X'}; + ExplorerButton buttons[12]; + unsigned long last_touch = 0; +}; + +ExplorerButtonManager::ExplorerButtonManager() +{ +} + +void ExplorerButtonManager::begin(callbackFunction touchBeep = nullptr) +{ + Serial.println("Button Manager Setup!"); + // Declaration for the MPR121 Cap Touch IC + cap = Adafruit_MPR121(); + // Initialise MPR121 at address 0x5A + if (!cap.begin(0x5A)) + { + Serial.println("Error - MPR121 Not found - Execution halted!"); + while (1) { + delay(10); + } + } + + for ( int id = 0; id < 12; id++ ) + { + buttons[id] = ExplorerButton(); + buttons[id].setupButton(_ids[id], cap, touchBeep ); + } + + last_touch = millis(); +}; + +unsigned long ExplorerButtonManager::tick() +{ + for ( int id = 0; id < 12; id++ ) + { + if (buttons[id].tick()) + { + // a button was touched, so update last button touch time + last_touch = millis(); + } + } + + // Special case for first tick, to ensure it's the milllis() time for the first loop of the program + if (last_touch == 0) + last_touch = millis(); + + return last_touch; +} + +void ExplorerButtonManager::assignCallbacks(char face, callbackFunction click, callbackFunction press) +{ + int id = getId(face); + if (click != nullptr) + buttons[id].attachPress(click); + if (press != nullptr) + buttons[id].attachPressLong(press); +} + +int ExplorerButtonManager::getId( char button ) +{ + for ( int i = 0; i < 12; i++ ) + { + if ( _ids[i] == button ) + return i; + } + return -1; +} diff --git a/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/helpers.h b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/helpers.h new file mode 100644 index 0000000..7455e05 --- /dev/null +++ b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/helpers.h @@ -0,0 +1,22 @@ +char* string2char(String command) +{ + char *p = const_cast(command.c_str()); + return p; +} + +void println_Center( Adafruit_ST7789 &d, String heading, int centerX, int centerY ) +{ + if (heading.length() > 0) + { + int x = 0; + int y = 0; + int16_t x1, y1; + uint16_t ww, hh; + + char *p = const_cast(heading.c_str()); + + d.getTextBounds( p, x, y, &x1, &y1, &ww, &hh ); + d.setCursor( centerX - ww / 2 + 2, centerY - hh / 2); + d.println( heading ); + } +} diff --git a/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/secret.h b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/secret.h new file mode 100644 index 0000000..4a735d4 --- /dev/null +++ b/TinyPICO Explorer Shield/TinyPICO_Explorer_Shield_Template/secret.h @@ -0,0 +1,2 @@ +const char* secret_ssid = "enter_ssid_here"; +const char* secret_password = "enter_password_here";