diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..280add8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.pio +.pioenvs +.piolibdeps +.vscode \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7c486f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/ESP32_OscilloscopeClock_v1.0/ESP32_OscilloscopeClock_v1.0.ino b/ESP32_OscilloscopeClock_v1.0/ESP32_OscilloscopeClock_v1.0.ino deleted file mode 100644 index 955c308..0000000 --- a/ESP32_OscilloscopeClock_v1.0/ESP32_OscilloscopeClock_v1.0.ino +++ /dev/null @@ -1,445 +0,0 @@ -/****************************************************************************** - - ESP32 Oscilloscope Clock - using internal DACs, with WiFi and ntp sync. - - Mauro Pintus , Milano 2018/05/25 - - How to use it: - Load this sketch on a ESP32 board using the Arduino IDE 1.8.7 - See Andreas Spiess video linked below if you dont know how to... - Connect your oscilloscope channels to GPIO25 and GPIO26 of the ESP32 - Connect the ground of the oscilloscope to the GND of the ESP32 board - Put your Oscilloscope in XY mode - Adjust the vertical scale of the used channels to fit the clock - - Enjoy Your new Oscilloscope Clock!!! :) - - Additional notes: - By default this sketch will start from a fix time 10:08:37 everityme - you reset the board. - To change it, modify the variables h,m,s below. - - To synchronize the clock with an NTP server, you have to install - the library NTPtimeESP from Andreas Spiess. - Then ncomment the line //#define NTP, removing the //. - Edit the WiFi credential in place of Your SSID and Your PASS. - Check in the serial monitor if it can reach the NTP server. - You mignt need to chouse a different pool server for your country. - - If you want there is also a special mode that can be enabled uncommenting - the line //#define EXCEL, removing the //. In this mode, the sketch - will run once and will output on the serial monitor all the coordinates - it has generated. You can use this coordinates to draw the clock - using the graph function in Excel or LibreOffice - This is useful to test anything you want to display on the oscilloscope - to verify the actual points that will be generated. - - GitHub Repository - https://github.com/maurohh/ESP32_OscilloscopeClock - - Twitter Page - https://twitter.com/PintusMauro - - Youtube Channel - www.youtube.com/channel/UCZ93JYpVb9rEbg5cbcVG_WA/ - - Old Web Site - www.mauroh.com - - Credits: - Andreas Spiess - https://www.youtube.com/watch?v=DgaKlh081tU - - Andreas Spiess NTP Library - https://github.com/SensorsIot/NTPtimeESP - - My project is based on this one: - http://www.dutchtronix.com/ScopeClock.htm - - Thank you!! - -******************************************************************************/ - -#include -#include -#include -#include "DataTable.h" - - -//#define EXCEL -//#define NTP - - -#if defined NTP - #include - #include - - NTPtime NTPch("europe.pool.ntp.org"); // Choose your server pool - char *ssid = "Your SSID"; // Set you WiFi SSID - char *password = "Your PASS"; // Set you WiFi password - - int status = WL_IDLE_STATUS; - strDateTime dateTime; -#endif // - -// Change this to set the initial Time -// Now is 10:08:37 (12h) -int h=10; //Start Hour -int m=8; //Start Minutes -int s=37; //Start Seconds - -//Variables -int lastx,lasty; -unsigned long currentMillis = 0; -unsigned long previousMillis = 0; -int Timeout = 20; -const long interval = 990; //milliseconds, you should twick this - //to get a better accuracy - - -//***************************************************************************** -// PlotTable -//***************************************************************************** - -void PlotTable(byte *SubTable, int SubTableSize, int skip, int opt, int offset) -{ - int i=offset; - while (i dy) { // < 45 - acc = (dx >> 1); - for (; x1 <= x2; x1++) { - Dot(x1, y1); - acc -= dy; - if (acc < 0) { - y1++; - acc += dx; - } - } - } - else { // > 45 - acc = dy >> 1; - for (; y1 <= y2; y1++) { - Dot(x1, y1); - acc -= dx; - if (acc < 0) { - x1++; - acc += dy; - } - } - } - } - else { // quadrant 2 - byte dx = x1 - x2; - if (dx > dy) { // < 45 - acc = dx >> 1; - for (; x1 >= x2; x1--) { - Dot(x1, y1); - acc -= dy; - if (acc < 0) { - y1++; - acc += dx; - } - } - } - else { // > 45 - acc = dy >> 1; - for (; y1 <= y2; y1++) { - Dot(x1, y1); - acc -= dx; - if (acc < 0) { - x1--; - acc += dy; - } - } - } - } - } - else { // quadrant 3 or 4 - byte dy = y1 - y2; - if (x1 < x2) { // quadrant 4 - byte dx = x2 - x1; - if (dx > dy) { // < 45 - acc = dx >> 1; - for (; x1 <= x2; x1++) { - Dot(x1, y1); - acc -= dy; - if (acc < 0) { - y1--; - acc += dx; - } - } - - } - else { // > 45 - acc = dy >> 1; - for (; y1 >= y2; y1--) { - Dot(x1, y1); - acc -= dx; - if (acc < 0) { - x1++; - acc += dy; - } - } - - } - } - else { // quadrant 3 - byte dx = x1 - x2; - if (dx > dy) { // < 45 - acc = dx >> 1; - for (; x1 >= x2; x1--) { - Dot(x1, y1); - acc -= dy; - if (acc < 0) { - y1--; - acc += dx; - } - } - - } - else { // > 45 - acc = dy >> 1; - for (; y1 >= y2; y1--) { - Dot(x1, y1); - acc -= dx; - if (acc < 0) { - x1--; - acc += dy; - } - } - } - } - - } -} - -// End Line -//***************************************************************************** - - - -//***************************************************************************** -// setup -//***************************************************************************** - -void setup() -{ - Serial.begin(115200); - Serial.println("\nESP32 Oscilloscope Clock v1.0"); - Serial.println("Mauro Pintus 2018\nwww.mauroh.com"); - //rtc_clk_cpu_freq_set(RTC_CPU_FREQ_240M); - Serial.println("CPU Clockspeed: "); - Serial.println(rtc_clk_cpu_freq_value(rtc_clk_cpu_freq_get())); - - dac_output_enable(DAC_CHANNEL_1); - dac_output_enable(DAC_CHANNEL_2); - - if (h > 12) h=h-12; - - #if defined NTP - Serial.println("Connecting to Wi-Fi"); - - WiFi.begin (ssid, password); - while (WiFi.status() != WL_CONNECTED) { - Serial.print("."); - delay(1000); - Timeout--; - if (Timeout==0){ - Serial.println("\nWiFi Timeout"); - break; - } - } - - if (Timeout!=0){ - Serial.println("\nWiFi connected"); - Serial.println("NTP request sent to Server."); - dateTime = NTPch.getNTPtime(1.0, 1); - Timeout=20; - - while (!dateTime.valid) { - dateTime = NTPch.getNTPtime(1.0, 1); - Serial.print("."); - delay(1000); - Timeout--; - if (Timeout==0){ - Serial.println("\nNTP Server Timeout"); - break; - } - } - - if (Timeout!=0){ - - Serial.println("\nUsing NTP Time"); - NTPch.printDateTime(dateTime); - - byte actualHour = dateTime.hour; - byte actualMinute = dateTime.minute; - byte actualsecond = dateTime.second; - int actualyear = dateTime.year; - byte actualMonth = dateTime.month; - byte actualday = dateTime.day; - byte actualdayofWeek = dateTime.dayofWeek; - - if (actualHour > 12) actualHour=actualHour-12; - - h=actualHour; - m=actualMinute; - s=actualsecond; - } - else{ - Serial.println("\nUsing Fix Time"); - } - } - #endif - - #if !defined NTP - Serial.println("Using Fix Time"); - #endif - - if (h<10) Serial.print("0"); - Serial.print(h); - Serial.print(":"); - if (m<10) Serial.print("0"); - Serial.print(m); - Serial.print(":"); - if (s<10) Serial.print("0"); - Serial.println(s); - h=(h*5)+m/12; -} - -// End setup -//***************************************************************************** - - - -//***************************************************************************** -// loop -//***************************************************************************** - -void loop() { - - currentMillis = millis(); - - if (currentMillis - previousMillis >= interval) { - previousMillis = currentMillis; - s++; - } - if (s==60) { - s=0; - m++; - if ((m==12)||(m==24)||(m==36)||(m==48)) { - h++; - } - } - if (m==60) { - m=0; - h++; - } - if (h==60) { - h=0; - } - - //Optionals - //PlotTable(DialDots,sizeof(DialDots),0x00,1,0); - //PlotTable(TestData,sizeof(TestData),0x00,0,00); //Full - //PlotTable(TestData,sizeof(TestData),0x00,0,11); //Without square - - int i; - //Serial.println("Out Ring"); //2 to back trace - //for (i=0; i < 1000; i++) PlotTable(DialData,sizeof(DialData),0x00,2,0); - - //Serial.println("Diagonals"); //2 to back trace - //for (i=0; i < 2000; i++) PlotTable(DialData,sizeof(DialData),0x00,0,0); - - PlotTable(DialData,sizeof(DialData),0x00,1,0); //2 to back trace - PlotTable(DialDigits12,sizeof(DialDigits12),0x00,1,0);//2 to back trace - PlotTable(HrPtrData, sizeof(HrPtrData), 0xFF,0,9*h); // 9*h - PlotTable(MinPtrData,sizeof(MinPtrData),0xFF,0,9*m); // 9*m - PlotTable(SecPtrData,sizeof(SecPtrData),0xFF,0,5*s); // 5*s - - #if defined EXCEL - while(1); - #endif - -} - -// End loop -//***************************************************************************** diff --git a/README.md b/README.md index a4fc676..50bad71 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,21 @@ ESP32 Oscilloscope Clock using internal DACs, with WiFi ntp sync Mauro Pintus , Milano 2018/05/25 +Extended by Tatu Wikman. +* Added wifimanager with configurable utc_offset from spiffs. +* Also merged https://github.com/maurohh/ESP32_OscilloscopeClock/pull/1 (without TRIGGER) + +TODO: +[ ] Add functionality to write text on the scope screen for instructions +[ ] Show the instructions on how to connect to the wifi on startup if wifi connection fails +[ ] Cleanup the code +[ ] Add error checking for the configuration (utc_offset should be limited to +-12) +[ ] Add configuration for Daylight Saving changes + ![](https://github.com/maurohh/ESP32_OscilloscopeClock/blob/master/ESP32_OscilloscopeClock_01.jpg) How to use it: - + Load this sketch on a ESP32 board using the Arduino IDE 1.8.7 See Andreas Spiess video linked below if you don't know how to... Connect your oscilloscope channels to GPIO25 and GPIO26 of the ESP32 @@ -18,35 +29,35 @@ Mauro Pintus , Milano 2018/05/25 Enjoy Your new Oscilloscope Clock!!! :) Additional notes: - + NTP Sync - - By default this sketch will start from a fix time 10:08:37 everityme + + By default this sketch will start from a fix time 10:08:37 everityme you reset the board. - + To change it, modify the variables h,m,s below. - To synchronize the clock with an NTP server, you have to install + To synchronize the clock with an NTP server, you have to install the library NTPtimeESP from Andreas Spiess. Then ncomment the line //#define NTP, removing the //. Edit the WiFi credential in place of Your SSID and Your PASS. Check in the serial monitor if it can reach the NTP server. You mignt need to chouse a different pool server for your country. - + The NTPtimeESP library was meant for the ESP8266 and you need to adit the file NTPtimeESP.h to use it with the ESP32. Open up the "NTPtimeESP.h" inside the library and replace the "#include " with "#include ". - + TimeZone Change - - You needed to modify the "NTPch.getNTPtime(1.0, 1);" request to fit your TimeZone. + + You needed to modify the "NTPch.getNTPtime(1.0, 1);" request to fit your TimeZone. Simply change the first argument with your required GMT offset. So for Italy (GMT +1) I've set it to 1.0. For Pacific Coastal Zone (GMT -8), you need to change "NTPch.getNTPtime(1.0, 1);" to "NTPch.getNTPtime(-8.0, 1);". - + EXCEL XY Coordinates Test - - If you want there is also a special mode that can be enabled uncommenting + + If you want there is also a special mode that can be enabled uncommenting the line //#define EXCEL, removing the //. In this mode, the sketch will run once and will output on the serial monitor all the coordinates - it has generated. You can use this coordinates to draw the clock + it has generated. You can use this coordinates to draw the clock using the graph function in Excel or LibreOffice This is useful to test anything you want to display on the oscilloscope to verify the actual points that will be generated. @@ -69,10 +80,10 @@ Mauro Pintus , Milano 2018/05/25 Andreas Spiess NTP Library https://github.com/SensorsIot/NTPtimeESP - + My project is based on this one: http://www.dutchtronix.com/ScopeClock.htm - + Thank you!! ![](https://github.com/maurohh/ESP32_OscilloscopeClock/blob/master/ESP32_OscilloscopeClock_Excel.jpg) diff --git a/data/config.json b/data/config.json new file mode 100644 index 0000000..8fa7560 --- /dev/null +++ b/data/config.json @@ -0,0 +1 @@ +{"utc_offset": 2} \ No newline at end of file diff --git a/ESP32_OscilloscopeClock_01.jpg b/images/ESP32_OscilloscopeClock_01.jpg similarity index 100% rename from ESP32_OscilloscopeClock_01.jpg rename to images/ESP32_OscilloscopeClock_01.jpg diff --git a/ESP32_OscilloscopeClock_Excel.jpg b/images/ESP32_OscilloscopeClock_Excel.jpg similarity index 100% rename from ESP32_OscilloscopeClock_Excel.jpg rename to images/ESP32_OscilloscopeClock_Excel.jpg diff --git a/ESP32_OscilloscopeClock_v1.0.png b/images/ESP32_OscilloscopeClock_v1.0.png similarity index 100% rename from ESP32_OscilloscopeClock_v1.0.png rename to images/ESP32_OscilloscopeClock_v1.0.png diff --git a/ESP32_OscilloscopeClock_v1.0.xlsx b/images/ESP32_OscilloscopeClock_v1.0.xlsx similarity index 100% rename from ESP32_OscilloscopeClock_v1.0.xlsx rename to images/ESP32_OscilloscopeClock_v1.0.xlsx diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..0065e0d --- /dev/null +++ b/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:lolin32] +platform = espressif32 +board = lolin32 +framework = arduino +monitor_speed = 115200 +lib_deps= + https://github.com/neptune2/simpleDSTadjust + https://github.com/ozbotics/WIFIMANAGER-ESP32 + https://github.com/bblanchon/ArduinoJson diff --git a/ESP32_OscilloscopeClock_v1.0/DataTable.h b/src/DataTable.h similarity index 99% rename from ESP32_OscilloscopeClock_v1.0/DataTable.h rename to src/DataTable.h index bd570f7..db6075f 100644 --- a/ESP32_OscilloscopeClock_v1.0/DataTable.h +++ b/src/DataTable.h @@ -1,199 +1,199 @@ -/********************************************************************************* - Data Tables for ESP32 Oscilloscope Clock - Mauro Pintus , Milano 2018/05/25 -*********************************************************************************/ - -byte DialData[] PROGMEM = { - 0x80,0xfe,0x80,0xf2,0x00,0x8d,0xfe,0x8c,0xf9,0x00,0x9a,0xfc,0x99,0xf7,0x00,0xa6,0xf8,0xa5,0xf4,0x00, - 0xb3,0xf4,0xb1,0xef,0x00,0xbf,0xee,0xba,0xe5,0x00,0xca,0xe6,0xc7,0xe2,0x00,0xd4,0xde,0xd0,0xda,0x00, - 0xdd,0xd5,0xd9,0xd1,0x00,0xe5,0xcb,0xe1,0xc8,0x00,0xed,0xbf,0xe4,0xba,0x00,0xf3,0xb4,0xee,0xb2,0x00, - 0xf7,0xa7,0xf3,0xa6,0x00,0xfb,0x9b,0xf6,0x9a,0x00,0xfd,0x8e,0xf8,0x8d,0x00,0xfd,0x80,0xf1,0x80,0x00, - 0xfd,0x73,0xf8,0x74,0x00,0xfb,0x66,0xf6,0x67,0x00,0xf7,0x5a,0xf3,0x5b,0x00,0xf3,0x4d,0xee,0x4f,0x00, - 0xed,0x41,0xe4,0x46,0x00,0xe5,0x36,0xe1,0x39,0x00,0xdd,0x2c,0xd9,0x30,0x00,0xd4,0x23,0xd0,0x27,0x00, - 0xca,0x1b,0xc7,0x1f,0x00,0xbf,0x13,0xba,0x1c,0x00,0xb3,0x0d,0xb1,0x12,0x00,0xa6,0x09,0xa5,0x0d,0x00, - 0x9a,0x05,0x99,0x0a,0x00,0x8d,0x03,0x8c,0x08,0x00,0x7f,0x03,0x7f,0x0f,0x00,0x72,0x03,0x73,0x08,0x00, - 0x65,0x05,0x66,0x0a,0x00,0x59,0x09,0x5a,0x0d,0x00,0x4c,0x0d,0x4e,0x12,0x00,0x41,0x13,0x46,0x1c,0x00, - 0x35,0x1b,0x38,0x1f,0x00,0x2b,0x23,0x2f,0x27,0x00,0x22,0x2c,0x26,0x30,0x00,0x1a,0x36,0x1e,0x39,0x00, - 0x12,0x42,0x1b,0x47,0x00,0x0c,0x4d,0x11,0x4f,0x00,0x08,0x5a,0x0c,0x5b,0x00,0x04,0x66,0x09,0x67,0x00, - 0x02,0x73,0x07,0x74,0x00,0x02,0x81,0x0e,0x81,0x00,0x02,0x8e,0x07,0x8d,0x00,0x04,0x9b,0x09,0x9a,0x00, - 0x08,0xa7,0x0c,0xa6,0x00,0x0c,0xb4,0x11,0xb2,0x00,0x12,0xbf,0x1b,0xba,0x00,0x1a,0xcb,0x1e,0xc8,0x00, - 0x22,0xd5,0x26,0xd1,0x00,0x2b,0xde,0x2f,0xda,0x00,0x35,0xe6,0x38,0xe2,0x00,0x40,0xee,0x45,0xe5,0x00, - 0x4c,0xf4,0x4e,0xef,0x00,0x59,0xf8,0x5a,0xf4,0x00,0x65,0xfc,0x66,0xf7,0x00,0x72,0xfe,0x73,0xf9,0xff -}; - - -byte DialDots[] PROGMEM = { - 0x80,0xfe,0x80,0xfd,0x81,0xfd,0x81,0xfc,0x00,0x8d,0xfe,0x8d,0xfd,0x8e,0xfd,0x8e,0xfc,0x00,0x9a,0xfc,0x99,0xfb,0x9b,0xfb,0x9a,0xfa,0x00, - 0xa6,0xf8,0xa6,0xf7,0xa7,0xf7,0xa7,0xf6,0x00,0xb3,0xf4,0xb2,0xf3,0xb4,0xf3,0xb3,0xf2,0x00,0xbf,0xee,0xbe,0xed,0xc0,0xed,0xbf,0xec,0x00, - 0xca,0xe6,0xc9,0xe6,0xcb,0xe5,0xca,0xe5,0x00,0xd4,0xde,0xd3,0xdd,0xd5,0xdd,0xd4,0xdc,0x00,0xdd,0xd5,0xdc,0xd4,0xde,0xd4,0xdd,0xd3,0x00, - 0xe5,0xcb,0xe5,0xca,0xe6,0xca,0xe6,0xc9,0x00,0xed,0xbf,0xec,0xbf,0xee,0xbe,0xed,0xbe,0x00,0xf3,0xb4,0xf2,0xb3,0xf4,0xb3,0xf3,0xb2,0x00, - 0xf7,0xa7,0xf6,0xa7,0xf8,0xa6,0xf7,0xa6,0x00,0xfb,0x9b,0xfa,0x9a,0xfc,0x9a,0xfb,0x99,0x00,0xfd,0x8e,0xfc,0x8e,0xfe,0x8d,0xfd,0x8d,0x00, - 0xfd,0x80,0xfc,0x80,0xfe,0x81,0xfd,0x81,0x00,0xfd,0x73,0xfc,0x73,0xfe,0x74,0xfd,0x74,0x00,0xfb,0x66,0xfa,0x67,0xfc,0x67,0xfb,0x68,0x00, - 0xf7,0x5a,0xf6,0x5a,0xf8,0x5b,0xf7,0x5b,0x00,0xf3,0x4d,0xf2,0x4e,0xf4,0x4e,0xf3,0x4f,0x00,0xed,0x41,0xec,0x42,0xee,0x42,0xed,0x43,0x00, - 0xe5,0x36,0xe5,0x37,0xe6,0x37,0xe6,0x38,0x00,0xdd,0x2c,0xdc,0x2d,0xde,0x2d,0xdd,0x2e,0x00,0xd4,0x23,0xd3,0x24,0xd5,0x24,0xd4,0x25,0x00, - 0xca,0x1b,0xc9,0x1b,0xcb,0x1c,0xca,0x1c,0x00,0xbf,0x13,0xbe,0x14,0xc0,0x14,0xbf,0x15,0x00,0xb3,0x0d,0xb2,0x0e,0xb4,0x0e,0xb3,0x0f,0x00, - 0xa6,0x09,0xa6,0x0a,0xa7,0x0a,0xa7,0x0b,0x00,0x9a,0x05,0x99,0x06,0x9b,0x06,0x9a,0x07,0x00,0x8d,0x03,0x8d,0x04,0x8e,0x04,0x8e,0x05,0x00, - 0x7f,0x03,0x7f,0x04,0x80,0x04,0x80,0x05,0x00,0x72,0x03,0x72,0x04,0x73,0x04,0x73,0x05,0x00,0x65,0x05,0x66,0x06,0x66,0x06,0x67,0x07,0x00, - 0x59,0x09,0x59,0x0a,0x5a,0x0a,0x5a,0x0b,0x00,0x4c,0x0d,0x4d,0x0e,0x4d,0x0e,0x4e,0x0f,0x00,0x41,0x13,0x41,0x14,0x42,0x14,0x42,0x15,0x00, - 0x35,0x1b,0x36,0x1b,0x36,0x1c,0x37,0x1c,0x00,0x2b,0x23,0x2c,0x24,0x2c,0x24,0x2d,0x25,0x00,0x22,0x2c,0x23,0x2d,0x23,0x2d,0x24,0x2e,0x00, - 0x1a,0x36,0x1a,0x37,0x1b,0x37,0x1b,0x38,0x00,0x12,0x42,0x13,0x42,0x13,0x43,0x14,0x43,0x00,0x0c,0x4d,0x0d,0x4e,0x0d,0x4e,0x0e,0x4f,0x00, - 0x08,0x5a,0x09,0x5a,0x09,0x5b,0x0a,0x5b,0x00,0x04,0x66,0x05,0x67,0x05,0x67,0x06,0x68,0x00,0x02,0x73,0x03,0x73,0x03,0x74,0x04,0x74,0x00, - 0x02,0x81,0x03,0x81,0x03,0x82,0x04,0x82,0x00,0x02,0x8e,0x03,0x8e,0x03,0x8d,0x04,0x8d,0x00,0x04,0x9b,0x05,0x9a,0x05,0x9a,0x06,0x99,0x00, - 0x08,0xa7,0x09,0xa7,0x09,0xa6,0x0a,0xa6,0x00,0x0c,0xb4,0x0d,0xb3,0x0d,0xb3,0x0e,0xb2,0x00,0x12,0xbf,0x13,0xbf,0x13,0xbe,0x14,0xbe,0x00, - 0x1a,0xcb,0x1a,0xca,0x1b,0xca,0x1b,0xc9,0x00,0x22,0xd5,0x23,0xd4,0x23,0xd4,0x24,0xd3,0x00,0x2b,0xde,0x2c,0xdd,0x2c,0xdd,0x2d,0xdc,0x00, - 0x35,0xe6,0x36,0xe6,0x36,0xe5,0x37,0xe5,0x00,0x40,0xee,0x41,0xed,0x41,0xed,0x42,0xec,0x00,0x4c,0xf4,0x4d,0xf3,0x4d,0xf3,0x4e,0xf2,0x00, - 0x59,0xf8,0x59,0xf7,0x5a,0xf7,0x5a,0xf6,0x00,0x65,0xfc,0x66,0xfb,0x66,0xfb,0x67,0xfa,0x00,0x72,0xfe,0x72,0xfd,0x73,0xfd,0x73,0xfc,0xff -}; - - -byte DialDigits12[] PROGMEM = { - 0x7a,0xeb,0x7a,0xd9,0x00,0x80,0xe8,0x83,0xeb,0x89,0xeb,0x8c,0xe8,0x8c,0xe5,0x80,0xd9,0x8c,0xd9,0x00, - 0xb5,0xe4,0xb5,0xd2,0x00,0x00, - 0xd2,0xbb,0xd5,0xbe,0xdb,0xbe,0xde,0xbb,0xde,0xb8,0xd2,0xac,0xde,0xac,0x00,0x00, - 0xe2,0x86,0xe5,0x89,0xeb,0x89,0xee,0x86,0xee,0x83,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00,0xe5,0x80,0xeb,0x80,0x00, - 0xe0,0x4c,0xd4,0x4c,0xdd,0x55,0xdd,0x43,0x00,0x00, - 0xb8,0x31,0xac,0x31,0xac,0x28,0xb5,0x28,0xb8,0x25,0xb8,0x22,0xb5,0x1f,0xaf,0x1f,0xac,0x22,0x00,0x00, - 0x85,0x21,0x82,0x24,0x7c,0x24,0x79,0x21,0x79,0x15,0x7c,0x12,0x82,0x12,0x85,0x15,0x85,0x18,0x82,0x1b,0x7c,0x1b,0x79,0x18,0x00,0x47,0x31,0x53,0x31,0x53,0x2e,0x50,0x2b,0x4d,0x25,0x4d,0x1f,0x00, - 0x22,0x4c,0x1f,0x4f,0x1f,0x52,0x22,0x55,0x28,0x55,0x2b,0x52,0x2b,0x4f,0x28,0x4c,0x22,0x4c,0x1f,0x49,0x1f,0x46,0x22,0x43,0x28,0x43,0x2b,0x46,0x2b,0x49,0x28,0x4c,0x00,0x00, - 0x1d,0x84,0x1a,0x81,0x1a,0x81,0x14,0x81,0x11,0x84,0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x7b,0x1a,0x78,0x14,0x78,0x11,0x7b,0x00,0x00, - 0x21,0xbe,0x21,0xac,0x00,0x00, - 0x27,0xbb,0x2a,0xbe,0x30,0xbe,0x33,0xbb,0x33,0xaf,0x30,0xac,0x2a,0xac,0x27,0xaf,0x27,0xbb,0x00,0x00, - 0x49,0xe4,0x49,0xd2,0x00,0x00, - 0x53,0xe4,0x53,0xd2,0xff,0x00 -}; -byte DialDigits24[] PROGMEM = { - 0x73,0xef,0x76,0xf2,0x7c,0xf2,0x7f,0xef,0x7f,0xec,0x73,0xe0,0x7f,0xe0,0x00,0x8d,0xe9,0x81,0xe9,0x8a,0xf2,0x8a,0xe0,0x00, - 0xaa,0xe2,0xaa,0xd0,0x00,0x00, - 0xb0,0xdf,0xb3,0xe2,0xb9,0xe2,0xbc,0xdf,0xbc,0xdc,0xb9,0xd9,0xbc,0xd6,0xbc,0xd3,0xb9,0xd0,0xb3,0xd0,0xb0,0xd3,0x00,0xb3,0xd9,0xb9,0xd9,0x00, - 0xd0,0xbc,0xd0,0xaa,0x00,0x00, - 0xe2,0xb3,0xd6,0xb3,0xdf,0xbc,0xdf,0xaa,0x00,0x00, - 0xdc,0x89,0xdc,0x77,0x00,0xee,0x89,0xe2,0x89,0xe2,0x80,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00, - 0xd0,0x55,0xd0,0x43,0x00,0x00, - 0xe2,0x52,0xdf,0x55,0xd9,0x55,0xd6,0x52,0xd6,0x46,0xd9,0x43,0xdf,0x43,0xe2,0x46,0xe2,0x49,0xdf,0x4c,0xd9,0x4c,0xd6,0x49,0x00,0x00, - 0xaa,0x2d,0xaa,0x1b,0x00,0x00, - 0xb0,0x2d,0xbc,0x2d,0xbc,0x2a,0xb9,0x27,0xb6,0x21,0xb6,0x1b,0x00,0x00, - 0x7b,0x21,0x7b,0x0f,0x00,0x83,0x18,0x80,0x1b,0x80,0x1e,0x83,0x21,0x89,0x21,0x8c,0x1e,0x8c,0x1b,0x89,0x18,0x83,0x18,0x80,0x15,0x80,0x12,0x83,0x0f,0x89,0x0f,0x8c,0x12,0x8c,0x15,0x89,0x18,0x00, - 0x49,0x2f,0x49,0x1d,0x00,0x00, - 0x5b,0x29,0x58,0x26,0x58,0x26,0x52,0x26,0x4f,0x29,0x4f,0x2c,0x52,0x2f,0x58,0x2f,0x5b,0x2c,0x5b,0x20,0x58,0x1d,0x52,0x1d,0x4f,0x20,0x00,0x00, - 0x1e,0x52,0x21,0x55,0x27,0x55,0x2a,0x52,0x2a,0x4f,0x1e,0x43,0x2a,0x43,0x00,0x00, - 0x2f,0x52,0x32,0x55,0x38,0x55,0x3b,0x52,0x3b,0x46,0x38,0x43,0x32,0x43,0x2f,0x46,0x2f,0x52,0x00,0x00, - 0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x84,0x11,0x78,0x1d,0x78,0x00,0x00, - 0x23,0x8a,0x23,0x78,0x00,0x00, - 0x1e,0xbb,0x21,0xbe,0x27,0xbe,0x2a,0xbb,0x2a,0xb8,0x1e,0xac,0x2a,0xac,0x00,0x00, - 0x2f,0xbb,0x32,0xbe,0x38,0xbe,0x3b,0xbb,0x3b,0xb8,0x2f,0xac,0x3b,0xac,0x00,0x00, - 0x40,0xdd,0x43,0xe0,0x49,0xe0,0x4c,0xdd,0x4c,0xda,0x40,0xce,0x4c,0xce,0x00,0x00, - 0x51,0xdd,0x54,0xe0,0x5a,0xe0,0x5d,0xdd,0x5d,0xda,0x5a,0xd7,0x5d,0xd4,0x5d,0xd1,0x5a,0xce,0x54,0xce,0x51,0xd1,0x00,0x54,0xd7,0x5a,0xd7,0xff - -}; -byte DialDigitsRoman[] PROGMEM = { - 0x76,0xdf,0x8a,0xdf,0x00,0x79,0xdf,0x80,0xf3,0x00,0x79,0xf3,0x80,0xdf,0x00,0x83,0xdf,0x83,0xf3,0x00,0x87,0xf3,0x87,0xdf,0x00,0x76,0xf3,0x8a,0xf3,0x00, - 0xad,0xd1,0xb5,0xd1,0x00,0xb1,0xd1,0xb1,0xe5,0x00,0xad,0xe5,0xb5,0xe5,0x00,0x00, - 0xd2,0xab,0xde,0xab,0x00,0xd6,0xab,0xd6,0xbf,0x00,0xda,0xab,0xda,0xbf,0x00,0xd2,0xbf,0xde,0xbf,0x00, - 0xdc,0x76,0xee,0x76,0x00,0xe0,0x76,0xe0,0x8a,0x00,0xe5,0x76,0xe5,0x8a,0x00,0xea,0x76,0xea,0x8a,0x00,0xdc,0x8a,0xee,0x8a,0x00,0xc9,0x42,0xdf,0x42,0x00,0xce,0x42,0xce,0x56,0x00,0xd2,0x42,0xd2,0x56,0x00,0xd6,0x42,0xd6,0x56,0x00,0xda,0x42,0xda,0x56,0x00,0xc9,0x56,0xdf,0x56,0x00,0x00, - 0xa9,0x22,0xb9,0x22,0x00,0xad,0x36,0xb1,0x22,0xb5,0x36,0x00,0xa9,0x36,0xb9,0x36,0x00,0x00, - 0x75,0x14,0x89,0x14,0x00,0x79,0x28,0x7d,0x14,0x81,0x28,0x00,0x85,0x14,0x85,0x28,0x00,0x75,0x28,0x89,0x28,0x00, - 0x43,0x22,0x59,0x22,0x00,0x46,0x36,0x4a,0x22,0x4e,0x36,0x00,0x51,0x22,0x51,0x36,0x00,0x55,0x22,0x55,0x36,0x00,0x43,0x36,0x59,0x36,0x00,0x00, - 0x1d,0x42,0x39,0x42,0x00,0x22,0x56,0x26,0x42,0x2a,0x56,0x00,0x2e,0x42,0x2e,0x56,0x00,0x32,0x42,0x32,0x56,0x00,0x36,0x42,0x36,0x56,0x00,0x1d,0x56,0x39,0x56,0x00, - 0x11,0x77,0x23,0x77,0x00,0x14,0x77,0x14,0x8b,0x00,0x18,0x77,0x20,0x8b,0x00,0x18,0x8b,0x20,0x77,0x00,0x11,0x8b,0x23,0x8b,0x00,0x00, - 0x24,0xab,0x32,0xab,0x00,0x27,0xab,0x2f,0xbf,0x00,0x27,0xbf,0x2f,0xab,0x00,0x24,0xbf,0x32,0xbf,0x00, - 0x48,0xd1,0x5a,0xd1,0x00,0x4b,0xd1,0x53,0xe5,0x00,0x4b,0xe5,0x53,0xd1,0x00,0x56,0xd1,0x56,0xe5,0x00,0x48,0xe5,0x5a,0xe5,0xff,0x00 -}; -byte DialDigitsMin [] PROGMEM = { - 0x7a,0xeb,0x7a,0xd9,0x00,0x80,0xe8,0x83,0xeb,0x89,0xeb,0x8c,0xe8,0x8c,0xe5,0x80,0xd9,0x8c,0xd9,0x00, - 0xe2,0x86,0xe5,0x89,0xeb,0x89,0xee,0x86,0xee,0x83,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00,0xe5,0x80,0xeb,0x80,0x00, - 0x85,0x21,0x82,0x24,0x7c,0x24,0x79,0x21,0x79,0x15,0x7c,0x12,0x82,0x12,0x85,0x15,0x85,0x18,0x82,0x1b,0x7c,0x1b,0x79,0x18,0x00,0x1d,0x84,0x1a,0x81,0x1a,0x81,0x14,0x81,0x11,0x84,0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x7b,0x1a,0x78,0x14,0x78,0x11,0x7b,0xff -}; - -byte SecPtrData[] PROGMEM = { - 0x80,0xec,0x80,0x80,0xff,0x8b,0xec,0x80,0x80,0xff,0x96,0xea,0x80,0x80,0xff,0xa1,0xe7,0x80,0x80,0xff, - 0xab,0xe3,0x80,0x80,0xff,0xb6,0xde,0x80,0x80,0xff,0xbf,0xd8,0x80,0x80,0xff,0xc8,0xd1,0x80,0x80,0xff, - 0xd0,0xc9,0x80,0x80,0xff,0xd7,0xc0,0x80,0x80,0xff,0xdd,0xb6,0x80,0x80,0xff,0xe2,0xac,0x80,0x80,0xff, - 0xe6,0xa2,0x80,0x80,0xff,0xe9,0x97,0x80,0x80,0xff,0xeb,0x8c,0x80,0x80,0xff,0xeb,0x80,0x80,0x80,0xff, - 0xeb,0x75,0x80,0x80,0xff,0xe9,0x6a,0x80,0x80,0xff,0xe6,0x5f,0x80,0x80,0xff,0xe2,0x55,0x80,0x80,0xff, - 0xdd,0x4a,0x80,0x80,0xff,0xd7,0x41,0x80,0x80,0xff,0xd0,0x38,0x80,0x80,0xff,0xc8,0x30,0x80,0x80,0xff, - 0xbf,0x29,0x80,0x80,0xff,0xb6,0x23,0x80,0x80,0xff,0xab,0x1e,0x80,0x80,0xff,0xa1,0x1a,0x80,0x80,0xff, - 0x96,0x17,0x80,0x80,0xff,0x8b,0x15,0x80,0x80,0xff,0x80,0x15,0x80,0x80,0xff,0x74,0x15,0x80,0x80,0xff, - 0x69,0x17,0x80,0x80,0xff,0x5e,0x1a,0x80,0x80,0xff,0x54,0x1e,0x80,0x80,0xff,0x4a,0x23,0x80,0x80,0xff, - 0x40,0x29,0x80,0x80,0xff,0x37,0x30,0x80,0x80,0xff,0x2f,0x38,0x80,0x80,0xff,0x28,0x41,0x80,0x80,0xff, - 0x22,0x4b,0x80,0x80,0xff,0x1d,0x55,0x80,0x80,0xff,0x19,0x5f,0x80,0x80,0xff,0x16,0x6a,0x80,0x80,0xff, - 0x14,0x75,0x80,0x80,0xff,0x14,0x80,0x80,0x80,0xff,0x14,0x8c,0x80,0x80,0xff,0x16,0x97,0x80,0x80,0xff, - 0x19,0xa2,0x80,0x80,0xff,0x1d,0xac,0x80,0x80,0xff,0x22,0xb6,0x80,0x80,0xff,0x28,0xc0,0x80,0x80,0xff, - 0x2f,0xc9,0x80,0x80,0xff,0x37,0xd1,0x80,0x80,0xff,0x40,0xd8,0x80,0x80,0xff,0x49,0xde,0x80,0x80,0xff, - 0x54,0xe3,0x80,0x80,0xff,0x5e,0xe7,0x80,0x80,0xff,0x69,0xea,0x80,0x80,0xff,0x74,0xec,0x80,0x80,0xff - -}; -byte MinPtrData[] PROGMEM = { - 0x82,0x80,0x80,0xe6,0x7e,0x80,0x82,0x80,0xff,0x81,0x80,0x8a,0xe6,0x7e,0x81,0x81,0x80,0xff, - 0x81,0x80,0x95,0xe4,0x7e,0x81,0x81,0x80,0xff,0x81,0x80,0x9f,0xe2,0x7e,0x81,0x81,0x80,0xff, - 0x81,0x80,0xa9,0xde,0x7e,0x81,0x81,0x80,0xff,0x81,0x7f,0xb3,0xd9,0x7e,0x82,0x81,0x7f,0xff, - 0x81,0x7f,0xbb,0xd3,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xc4,0xcc,0x7e,0x82,0x81,0x7f,0xff, - 0x81,0x7f,0xcb,0xc5,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xd2,0xbc,0x7e,0x82,0x81,0x7f,0xff, - 0x80,0x7f,0xd8,0xb3,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xdd,0xaa,0x7f,0x82,0x80,0x7f,0xff, - 0x80,0x7f,0xe1,0xa0,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xe3,0x96,0x7f,0x82,0x80,0x7f,0xff, - 0x80,0x7f,0xe5,0x8b,0x7f,0x82,0x80,0x7f,0xff,0x7f,0x7e,0xe5,0x80,0x80,0x82,0x7f,0x7e,0xff, - 0x7f,0x7f,0xe5,0x76,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xe3,0x6b,0x80,0x82,0x7f,0x7f,0xff, - 0x7f,0x7f,0xe1,0x61,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xdd,0x57,0x80,0x82,0x7f,0x7f,0xff, - 0x7e,0x7f,0xd8,0x4d,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xd2,0x45,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x7f,0xcb,0x3c,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xc4,0x35,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x7f,0xbb,0x2e,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xb3,0x28,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x80,0xa9,0x23,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x9f,0x1f,0x81,0x81,0x7e,0x80,0xff, - 0x7e,0x80,0x95,0x1d,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x8a,0x1b,0x81,0x81,0x7e,0x80,0xff, - 0x7e,0x81,0x7f,0x1b,0x82,0x80,0x7e,0x81,0xff,0x7e,0x81,0x75,0x1b,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x81,0x6a,0x1d,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x60,0x1f,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x81,0x56,0x23,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x4d,0x28,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x82,0x44,0x2e,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x3b,0x35,0x81,0x7f,0x7e,0x82,0xff, - 0x7e,0x82,0x34,0x3c,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x2d,0x45,0x81,0x7f,0x7e,0x82,0xff, - 0x7f,0x82,0x27,0x4e,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x22,0x57,0x80,0x7f,0x7f,0x82,0xff, - 0x7f,0x82,0x1e,0x61,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x1c,0x6b,0x80,0x7f,0x7f,0x82,0xff, - 0x7f,0x82,0x1a,0x76,0x80,0x7f,0x7f,0x82,0xff,0x80,0x82,0x1a,0x81,0x7f,0x7e,0x80,0x82,0xff, - 0x80,0x82,0x1a,0x8b,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x1c,0x96,0x7f,0x7f,0x80,0x82,0xff, - 0x80,0x82,0x1e,0xa0,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x22,0xaa,0x7f,0x7f,0x80,0x82,0xff, - 0x80,0x82,0x27,0xb3,0x7f,0x7f,0x80,0x82,0xff,0x81,0x82,0x2d,0xbc,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x82,0x34,0xc5,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x3b,0xcc,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x82,0x44,0xd3,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x4c,0xd9,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x81,0x56,0xde,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x60,0xe2,0x7e,0x80,0x81,0x81,0xff, - 0x81,0x81,0x6a,0xe4,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x75,0xe6,0x7e,0x80,0x81,0x81,0xff - -}; -byte HrPtrData[] PROGMEM = { - 0x82,0x80,0x80,0xbc,0x7e,0x80,0x82,0x80,0xff,0x81,0x80,0x86,0xbc,0x7e,0x81,0x81,0x80,0xff, - 0x81,0x80,0x8c,0xbb,0x7e,0x81,0x81,0x80,0xff,0x81,0x80,0x92,0xba,0x7e,0x81,0x81,0x80,0xff, - 0x81,0x80,0x98,0xb7,0x7e,0x81,0x81,0x80,0xff,0x81,0x7f,0x9e,0xb4,0x7e,0x82,0x81,0x7f,0xff, - 0x81,0x7f,0xa3,0xb1,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xa8,0xad,0x7e,0x82,0x81,0x7f,0xff, - 0x81,0x7f,0xac,0xa9,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xb0,0xa4,0x7e,0x82,0x81,0x7f,0xff, - 0x80,0x7f,0xb3,0x9e,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xb6,0x99,0x7f,0x82,0x80,0x7f,0xff, - 0x80,0x7f,0xb9,0x93,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xba,0x8d,0x7f,0x82,0x80,0x7f,0xff, - 0x80,0x7f,0xbb,0x87,0x7f,0x82,0x80,0x7f,0xff,0x7f,0x7e,0xbb,0x80,0x80,0x82,0x7f,0x7e,0xff, - 0x7f,0x7f,0xbb,0x7a,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xba,0x74,0x80,0x82,0x7f,0x7f,0xff, - 0x7f,0x7f,0xb9,0x6e,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xb6,0x68,0x80,0x82,0x7f,0x7f,0xff, - 0x7e,0x7f,0xb3,0x62,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xb0,0x5d,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x7f,0xac,0x58,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xa8,0x54,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x7f,0xa3,0x50,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0x9e,0x4d,0x81,0x82,0x7e,0x7f,0xff, - 0x7e,0x80,0x98,0x4a,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x92,0x47,0x81,0x81,0x7e,0x80,0xff, - 0x7e,0x80,0x8c,0x46,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x86,0x45,0x81,0x81,0x7e,0x80,0xff, - 0x7e,0x81,0x7f,0x45,0x82,0x80,0x7e,0x81,0xff,0x7e,0x81,0x79,0x45,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x81,0x73,0x46,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x6d,0x47,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x81,0x67,0x4a,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x62,0x4d,0x81,0x80,0x7e,0x81,0xff, - 0x7e,0x82,0x5c,0x50,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x57,0x54,0x81,0x7f,0x7e,0x82,0xff, - 0x7e,0x82,0x53,0x58,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x4f,0x5d,0x81,0x7f,0x7e,0x82,0xff, - 0x7f,0x82,0x4c,0x63,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x49,0x68,0x80,0x7f,0x7f,0x82,0xff, - 0x7f,0x82,0x46,0x6e,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x45,0x74,0x80,0x7f,0x7f,0x82,0xff, - 0x7f,0x82,0x44,0x7a,0x80,0x7f,0x7f,0x82,0xff,0x80,0x82,0x44,0x81,0x7f,0x7e,0x80,0x82,0xff, - 0x80,0x82,0x44,0x87,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x45,0x8d,0x7f,0x7f,0x80,0x82,0xff, - 0x80,0x82,0x46,0x93,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x49,0x99,0x7f,0x7f,0x80,0x82,0xff, - 0x80,0x82,0x4c,0x9e,0x7f,0x7f,0x80,0x82,0xff,0x81,0x82,0x4f,0xa4,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x82,0x53,0xa9,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x57,0xad,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x82,0x5c,0xb1,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x61,0xb4,0x7e,0x7f,0x81,0x82,0xff, - 0x81,0x81,0x67,0xb7,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x6d,0xba,0x7e,0x80,0x81,0x81,0xff, - 0x81,0x81,0x73,0xbb,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x79,0xbc,0x7e,0x80,0x81,0x81,0xff - -}; - -byte TestData[] PROGMEM = { - 0x01,0x01,0x01,0xfe,0xfe,0xfe,0xfe,0x01,0x01,0x01,0x00, // Max Square - 0x01,0x3f,0x01,0xbd,0x3f,0xfe,0xbd,0xfe,0xfe,0xbd,0xfe,0x3f,0xbd,0x01,0x3f,0x01,0x01,0x3f,0x00, // Max Octagon - 0x7f,0x7f,0x7f,0xfe,0x00,0x7f,0x7f,0xbd,0xfe,0x00,0x7f,0x7f,0xfe,0xfe,0x00,0x7f,0x7f,0xfe,0xbd,0x00,// Max diagonals - 0x7f,0x7f,0xfe,0x7f,0x00,0x7f,0x7f,0xfe,0x3f,0x00,0x7f,0x7f,0xfe,0x01,0x00,0x7f,0x7f,0xbd,0x01,0x00, - 0x7f,0x7f,0x7f,0x01,0x00,0x7f,0x7f,0x3f,0x01,0x00,0x7f,0x7f,0x01,0x01,0x00,0x7f,0x7f,0x01,0x3f,0x00, - 0x7f,0x7f,0x01,0x7f,0x00,0x7f,0x7f,0x01,0xbd,0x00,0x7f,0x7f,0x01,0xfe,0x00,0x7f,0x7f,0x3f,0xfe,0xff -}; +/********************************************************************************* + Data Tables for ESP32 Oscilloscope Clock + Mauro Pintus , Milano 2018/05/25 +*********************************************************************************/ + +byte DialData[] PROGMEM = { + 0x80,0xfe,0x80,0xf2,0x00,0x8d,0xfe,0x8c,0xf9,0x00,0x9a,0xfc,0x99,0xf7,0x00,0xa6,0xf8,0xa5,0xf4,0x00, + 0xb3,0xf4,0xb1,0xef,0x00,0xbf,0xee,0xba,0xe5,0x00,0xca,0xe6,0xc7,0xe2,0x00,0xd4,0xde,0xd0,0xda,0x00, + 0xdd,0xd5,0xd9,0xd1,0x00,0xe5,0xcb,0xe1,0xc8,0x00,0xed,0xbf,0xe4,0xba,0x00,0xf3,0xb4,0xee,0xb2,0x00, + 0xf7,0xa7,0xf3,0xa6,0x00,0xfb,0x9b,0xf6,0x9a,0x00,0xfd,0x8e,0xf8,0x8d,0x00,0xfd,0x80,0xf1,0x80,0x00, + 0xfd,0x73,0xf8,0x74,0x00,0xfb,0x66,0xf6,0x67,0x00,0xf7,0x5a,0xf3,0x5b,0x00,0xf3,0x4d,0xee,0x4f,0x00, + 0xed,0x41,0xe4,0x46,0x00,0xe5,0x36,0xe1,0x39,0x00,0xdd,0x2c,0xd9,0x30,0x00,0xd4,0x23,0xd0,0x27,0x00, + 0xca,0x1b,0xc7,0x1f,0x00,0xbf,0x13,0xba,0x1c,0x00,0xb3,0x0d,0xb1,0x12,0x00,0xa6,0x09,0xa5,0x0d,0x00, + 0x9a,0x05,0x99,0x0a,0x00,0x8d,0x03,0x8c,0x08,0x00,0x7f,0x03,0x7f,0x0f,0x00,0x72,0x03,0x73,0x08,0x00, + 0x65,0x05,0x66,0x0a,0x00,0x59,0x09,0x5a,0x0d,0x00,0x4c,0x0d,0x4e,0x12,0x00,0x41,0x13,0x46,0x1c,0x00, + 0x35,0x1b,0x38,0x1f,0x00,0x2b,0x23,0x2f,0x27,0x00,0x22,0x2c,0x26,0x30,0x00,0x1a,0x36,0x1e,0x39,0x00, + 0x12,0x42,0x1b,0x47,0x00,0x0c,0x4d,0x11,0x4f,0x00,0x08,0x5a,0x0c,0x5b,0x00,0x04,0x66,0x09,0x67,0x00, + 0x02,0x73,0x07,0x74,0x00,0x02,0x81,0x0e,0x81,0x00,0x02,0x8e,0x07,0x8d,0x00,0x04,0x9b,0x09,0x9a,0x00, + 0x08,0xa7,0x0c,0xa6,0x00,0x0c,0xb4,0x11,0xb2,0x00,0x12,0xbf,0x1b,0xba,0x00,0x1a,0xcb,0x1e,0xc8,0x00, + 0x22,0xd5,0x26,0xd1,0x00,0x2b,0xde,0x2f,0xda,0x00,0x35,0xe6,0x38,0xe2,0x00,0x40,0xee,0x45,0xe5,0x00, + 0x4c,0xf4,0x4e,0xef,0x00,0x59,0xf8,0x5a,0xf4,0x00,0x65,0xfc,0x66,0xf7,0x00,0x72,0xfe,0x73,0xf9,0xff +}; + + +byte DialDots[] PROGMEM = { + 0x80,0xfe,0x80,0xfd,0x81,0xfd,0x81,0xfc,0x00,0x8d,0xfe,0x8d,0xfd,0x8e,0xfd,0x8e,0xfc,0x00,0x9a,0xfc,0x99,0xfb,0x9b,0xfb,0x9a,0xfa,0x00, + 0xa6,0xf8,0xa6,0xf7,0xa7,0xf7,0xa7,0xf6,0x00,0xb3,0xf4,0xb2,0xf3,0xb4,0xf3,0xb3,0xf2,0x00,0xbf,0xee,0xbe,0xed,0xc0,0xed,0xbf,0xec,0x00, + 0xca,0xe6,0xc9,0xe6,0xcb,0xe5,0xca,0xe5,0x00,0xd4,0xde,0xd3,0xdd,0xd5,0xdd,0xd4,0xdc,0x00,0xdd,0xd5,0xdc,0xd4,0xde,0xd4,0xdd,0xd3,0x00, + 0xe5,0xcb,0xe5,0xca,0xe6,0xca,0xe6,0xc9,0x00,0xed,0xbf,0xec,0xbf,0xee,0xbe,0xed,0xbe,0x00,0xf3,0xb4,0xf2,0xb3,0xf4,0xb3,0xf3,0xb2,0x00, + 0xf7,0xa7,0xf6,0xa7,0xf8,0xa6,0xf7,0xa6,0x00,0xfb,0x9b,0xfa,0x9a,0xfc,0x9a,0xfb,0x99,0x00,0xfd,0x8e,0xfc,0x8e,0xfe,0x8d,0xfd,0x8d,0x00, + 0xfd,0x80,0xfc,0x80,0xfe,0x81,0xfd,0x81,0x00,0xfd,0x73,0xfc,0x73,0xfe,0x74,0xfd,0x74,0x00,0xfb,0x66,0xfa,0x67,0xfc,0x67,0xfb,0x68,0x00, + 0xf7,0x5a,0xf6,0x5a,0xf8,0x5b,0xf7,0x5b,0x00,0xf3,0x4d,0xf2,0x4e,0xf4,0x4e,0xf3,0x4f,0x00,0xed,0x41,0xec,0x42,0xee,0x42,0xed,0x43,0x00, + 0xe5,0x36,0xe5,0x37,0xe6,0x37,0xe6,0x38,0x00,0xdd,0x2c,0xdc,0x2d,0xde,0x2d,0xdd,0x2e,0x00,0xd4,0x23,0xd3,0x24,0xd5,0x24,0xd4,0x25,0x00, + 0xca,0x1b,0xc9,0x1b,0xcb,0x1c,0xca,0x1c,0x00,0xbf,0x13,0xbe,0x14,0xc0,0x14,0xbf,0x15,0x00,0xb3,0x0d,0xb2,0x0e,0xb4,0x0e,0xb3,0x0f,0x00, + 0xa6,0x09,0xa6,0x0a,0xa7,0x0a,0xa7,0x0b,0x00,0x9a,0x05,0x99,0x06,0x9b,0x06,0x9a,0x07,0x00,0x8d,0x03,0x8d,0x04,0x8e,0x04,0x8e,0x05,0x00, + 0x7f,0x03,0x7f,0x04,0x80,0x04,0x80,0x05,0x00,0x72,0x03,0x72,0x04,0x73,0x04,0x73,0x05,0x00,0x65,0x05,0x66,0x06,0x66,0x06,0x67,0x07,0x00, + 0x59,0x09,0x59,0x0a,0x5a,0x0a,0x5a,0x0b,0x00,0x4c,0x0d,0x4d,0x0e,0x4d,0x0e,0x4e,0x0f,0x00,0x41,0x13,0x41,0x14,0x42,0x14,0x42,0x15,0x00, + 0x35,0x1b,0x36,0x1b,0x36,0x1c,0x37,0x1c,0x00,0x2b,0x23,0x2c,0x24,0x2c,0x24,0x2d,0x25,0x00,0x22,0x2c,0x23,0x2d,0x23,0x2d,0x24,0x2e,0x00, + 0x1a,0x36,0x1a,0x37,0x1b,0x37,0x1b,0x38,0x00,0x12,0x42,0x13,0x42,0x13,0x43,0x14,0x43,0x00,0x0c,0x4d,0x0d,0x4e,0x0d,0x4e,0x0e,0x4f,0x00, + 0x08,0x5a,0x09,0x5a,0x09,0x5b,0x0a,0x5b,0x00,0x04,0x66,0x05,0x67,0x05,0x67,0x06,0x68,0x00,0x02,0x73,0x03,0x73,0x03,0x74,0x04,0x74,0x00, + 0x02,0x81,0x03,0x81,0x03,0x82,0x04,0x82,0x00,0x02,0x8e,0x03,0x8e,0x03,0x8d,0x04,0x8d,0x00,0x04,0x9b,0x05,0x9a,0x05,0x9a,0x06,0x99,0x00, + 0x08,0xa7,0x09,0xa7,0x09,0xa6,0x0a,0xa6,0x00,0x0c,0xb4,0x0d,0xb3,0x0d,0xb3,0x0e,0xb2,0x00,0x12,0xbf,0x13,0xbf,0x13,0xbe,0x14,0xbe,0x00, + 0x1a,0xcb,0x1a,0xca,0x1b,0xca,0x1b,0xc9,0x00,0x22,0xd5,0x23,0xd4,0x23,0xd4,0x24,0xd3,0x00,0x2b,0xde,0x2c,0xdd,0x2c,0xdd,0x2d,0xdc,0x00, + 0x35,0xe6,0x36,0xe6,0x36,0xe5,0x37,0xe5,0x00,0x40,0xee,0x41,0xed,0x41,0xed,0x42,0xec,0x00,0x4c,0xf4,0x4d,0xf3,0x4d,0xf3,0x4e,0xf2,0x00, + 0x59,0xf8,0x59,0xf7,0x5a,0xf7,0x5a,0xf6,0x00,0x65,0xfc,0x66,0xfb,0x66,0xfb,0x67,0xfa,0x00,0x72,0xfe,0x72,0xfd,0x73,0xfd,0x73,0xfc,0xff +}; + + +byte DialDigits12[] PROGMEM = { + 0x7a,0xeb,0x7a,0xd9,0x00,0x80,0xe8,0x83,0xeb,0x89,0xeb,0x8c,0xe8,0x8c,0xe5,0x80,0xd9,0x8c,0xd9,0x00, + 0xb5,0xe4,0xb5,0xd2,0x00,0x00, + 0xd2,0xbb,0xd5,0xbe,0xdb,0xbe,0xde,0xbb,0xde,0xb8,0xd2,0xac,0xde,0xac,0x00,0x00, + 0xe2,0x86,0xe5,0x89,0xeb,0x89,0xee,0x86,0xee,0x83,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00,0xe5,0x80,0xeb,0x80,0x00, + 0xe0,0x4c,0xd4,0x4c,0xdd,0x55,0xdd,0x43,0x00,0x00, + 0xb8,0x31,0xac,0x31,0xac,0x28,0xb5,0x28,0xb8,0x25,0xb8,0x22,0xb5,0x1f,0xaf,0x1f,0xac,0x22,0x00,0x00, + 0x85,0x21,0x82,0x24,0x7c,0x24,0x79,0x21,0x79,0x15,0x7c,0x12,0x82,0x12,0x85,0x15,0x85,0x18,0x82,0x1b,0x7c,0x1b,0x79,0x18,0x00,0x47,0x31,0x53,0x31,0x53,0x2e,0x50,0x2b,0x4d,0x25,0x4d,0x1f,0x00, + 0x22,0x4c,0x1f,0x4f,0x1f,0x52,0x22,0x55,0x28,0x55,0x2b,0x52,0x2b,0x4f,0x28,0x4c,0x22,0x4c,0x1f,0x49,0x1f,0x46,0x22,0x43,0x28,0x43,0x2b,0x46,0x2b,0x49,0x28,0x4c,0x00,0x00, + 0x1d,0x84,0x1a,0x81,0x1a,0x81,0x14,0x81,0x11,0x84,0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x7b,0x1a,0x78,0x14,0x78,0x11,0x7b,0x00,0x00, + 0x21,0xbe,0x21,0xac,0x00,0x00, + 0x27,0xbb,0x2a,0xbe,0x30,0xbe,0x33,0xbb,0x33,0xaf,0x30,0xac,0x2a,0xac,0x27,0xaf,0x27,0xbb,0x00,0x00, + 0x49,0xe4,0x49,0xd2,0x00,0x00, + 0x53,0xe4,0x53,0xd2,0xff,0x00 +}; +byte DialDigits24[] PROGMEM = { + 0x73,0xef,0x76,0xf2,0x7c,0xf2,0x7f,0xef,0x7f,0xec,0x73,0xe0,0x7f,0xe0,0x00,0x8d,0xe9,0x81,0xe9,0x8a,0xf2,0x8a,0xe0,0x00, + 0xaa,0xe2,0xaa,0xd0,0x00,0x00, + 0xb0,0xdf,0xb3,0xe2,0xb9,0xe2,0xbc,0xdf,0xbc,0xdc,0xb9,0xd9,0xbc,0xd6,0xbc,0xd3,0xb9,0xd0,0xb3,0xd0,0xb0,0xd3,0x00,0xb3,0xd9,0xb9,0xd9,0x00, + 0xd0,0xbc,0xd0,0xaa,0x00,0x00, + 0xe2,0xb3,0xd6,0xb3,0xdf,0xbc,0xdf,0xaa,0x00,0x00, + 0xdc,0x89,0xdc,0x77,0x00,0xee,0x89,0xe2,0x89,0xe2,0x80,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00, + 0xd0,0x55,0xd0,0x43,0x00,0x00, + 0xe2,0x52,0xdf,0x55,0xd9,0x55,0xd6,0x52,0xd6,0x46,0xd9,0x43,0xdf,0x43,0xe2,0x46,0xe2,0x49,0xdf,0x4c,0xd9,0x4c,0xd6,0x49,0x00,0x00, + 0xaa,0x2d,0xaa,0x1b,0x00,0x00, + 0xb0,0x2d,0xbc,0x2d,0xbc,0x2a,0xb9,0x27,0xb6,0x21,0xb6,0x1b,0x00,0x00, + 0x7b,0x21,0x7b,0x0f,0x00,0x83,0x18,0x80,0x1b,0x80,0x1e,0x83,0x21,0x89,0x21,0x8c,0x1e,0x8c,0x1b,0x89,0x18,0x83,0x18,0x80,0x15,0x80,0x12,0x83,0x0f,0x89,0x0f,0x8c,0x12,0x8c,0x15,0x89,0x18,0x00, + 0x49,0x2f,0x49,0x1d,0x00,0x00, + 0x5b,0x29,0x58,0x26,0x58,0x26,0x52,0x26,0x4f,0x29,0x4f,0x2c,0x52,0x2f,0x58,0x2f,0x5b,0x2c,0x5b,0x20,0x58,0x1d,0x52,0x1d,0x4f,0x20,0x00,0x00, + 0x1e,0x52,0x21,0x55,0x27,0x55,0x2a,0x52,0x2a,0x4f,0x1e,0x43,0x2a,0x43,0x00,0x00, + 0x2f,0x52,0x32,0x55,0x38,0x55,0x3b,0x52,0x3b,0x46,0x38,0x43,0x32,0x43,0x2f,0x46,0x2f,0x52,0x00,0x00, + 0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x84,0x11,0x78,0x1d,0x78,0x00,0x00, + 0x23,0x8a,0x23,0x78,0x00,0x00, + 0x1e,0xbb,0x21,0xbe,0x27,0xbe,0x2a,0xbb,0x2a,0xb8,0x1e,0xac,0x2a,0xac,0x00,0x00, + 0x2f,0xbb,0x32,0xbe,0x38,0xbe,0x3b,0xbb,0x3b,0xb8,0x2f,0xac,0x3b,0xac,0x00,0x00, + 0x40,0xdd,0x43,0xe0,0x49,0xe0,0x4c,0xdd,0x4c,0xda,0x40,0xce,0x4c,0xce,0x00,0x00, + 0x51,0xdd,0x54,0xe0,0x5a,0xe0,0x5d,0xdd,0x5d,0xda,0x5a,0xd7,0x5d,0xd4,0x5d,0xd1,0x5a,0xce,0x54,0xce,0x51,0xd1,0x00,0x54,0xd7,0x5a,0xd7,0xff + +}; +byte DialDigitsRoman[] PROGMEM = { + 0x76,0xdf,0x8a,0xdf,0x00,0x79,0xdf,0x80,0xf3,0x00,0x79,0xf3,0x80,0xdf,0x00,0x83,0xdf,0x83,0xf3,0x00,0x87,0xf3,0x87,0xdf,0x00,0x76,0xf3,0x8a,0xf3,0x00, + 0xad,0xd1,0xb5,0xd1,0x00,0xb1,0xd1,0xb1,0xe5,0x00,0xad,0xe5,0xb5,0xe5,0x00,0x00, + 0xd2,0xab,0xde,0xab,0x00,0xd6,0xab,0xd6,0xbf,0x00,0xda,0xab,0xda,0xbf,0x00,0xd2,0xbf,0xde,0xbf,0x00, + 0xdc,0x76,0xee,0x76,0x00,0xe0,0x76,0xe0,0x8a,0x00,0xe5,0x76,0xe5,0x8a,0x00,0xea,0x76,0xea,0x8a,0x00,0xdc,0x8a,0xee,0x8a,0x00,0xc9,0x42,0xdf,0x42,0x00,0xce,0x42,0xce,0x56,0x00,0xd2,0x42,0xd2,0x56,0x00,0xd6,0x42,0xd6,0x56,0x00,0xda,0x42,0xda,0x56,0x00,0xc9,0x56,0xdf,0x56,0x00,0x00, + 0xa9,0x22,0xb9,0x22,0x00,0xad,0x36,0xb1,0x22,0xb5,0x36,0x00,0xa9,0x36,0xb9,0x36,0x00,0x00, + 0x75,0x14,0x89,0x14,0x00,0x79,0x28,0x7d,0x14,0x81,0x28,0x00,0x85,0x14,0x85,0x28,0x00,0x75,0x28,0x89,0x28,0x00, + 0x43,0x22,0x59,0x22,0x00,0x46,0x36,0x4a,0x22,0x4e,0x36,0x00,0x51,0x22,0x51,0x36,0x00,0x55,0x22,0x55,0x36,0x00,0x43,0x36,0x59,0x36,0x00,0x00, + 0x1d,0x42,0x39,0x42,0x00,0x22,0x56,0x26,0x42,0x2a,0x56,0x00,0x2e,0x42,0x2e,0x56,0x00,0x32,0x42,0x32,0x56,0x00,0x36,0x42,0x36,0x56,0x00,0x1d,0x56,0x39,0x56,0x00, + 0x11,0x77,0x23,0x77,0x00,0x14,0x77,0x14,0x8b,0x00,0x18,0x77,0x20,0x8b,0x00,0x18,0x8b,0x20,0x77,0x00,0x11,0x8b,0x23,0x8b,0x00,0x00, + 0x24,0xab,0x32,0xab,0x00,0x27,0xab,0x2f,0xbf,0x00,0x27,0xbf,0x2f,0xab,0x00,0x24,0xbf,0x32,0xbf,0x00, + 0x48,0xd1,0x5a,0xd1,0x00,0x4b,0xd1,0x53,0xe5,0x00,0x4b,0xe5,0x53,0xd1,0x00,0x56,0xd1,0x56,0xe5,0x00,0x48,0xe5,0x5a,0xe5,0xff,0x00 +}; +byte DialDigitsMin [] PROGMEM = { + 0x7a,0xeb,0x7a,0xd9,0x00,0x80,0xe8,0x83,0xeb,0x89,0xeb,0x8c,0xe8,0x8c,0xe5,0x80,0xd9,0x8c,0xd9,0x00, + 0xe2,0x86,0xe5,0x89,0xeb,0x89,0xee,0x86,0xee,0x83,0xeb,0x80,0xee,0x7d,0xee,0x7a,0xeb,0x77,0xe5,0x77,0xe2,0x7a,0x00,0xe5,0x80,0xeb,0x80,0x00, + 0x85,0x21,0x82,0x24,0x7c,0x24,0x79,0x21,0x79,0x15,0x7c,0x12,0x82,0x12,0x85,0x15,0x85,0x18,0x82,0x1b,0x7c,0x1b,0x79,0x18,0x00,0x1d,0x84,0x1a,0x81,0x1a,0x81,0x14,0x81,0x11,0x84,0x11,0x87,0x14,0x8a,0x1a,0x8a,0x1d,0x87,0x1d,0x7b,0x1a,0x78,0x14,0x78,0x11,0x7b,0xff +}; + +byte SecPtrData[] PROGMEM = { + 0x80,0xec,0x80,0x80,0xff,0x8b,0xec,0x80,0x80,0xff,0x96,0xea,0x80,0x80,0xff,0xa1,0xe7,0x80,0x80,0xff, + 0xab,0xe3,0x80,0x80,0xff,0xb6,0xde,0x80,0x80,0xff,0xbf,0xd8,0x80,0x80,0xff,0xc8,0xd1,0x80,0x80,0xff, + 0xd0,0xc9,0x80,0x80,0xff,0xd7,0xc0,0x80,0x80,0xff,0xdd,0xb6,0x80,0x80,0xff,0xe2,0xac,0x80,0x80,0xff, + 0xe6,0xa2,0x80,0x80,0xff,0xe9,0x97,0x80,0x80,0xff,0xeb,0x8c,0x80,0x80,0xff,0xeb,0x80,0x80,0x80,0xff, + 0xeb,0x75,0x80,0x80,0xff,0xe9,0x6a,0x80,0x80,0xff,0xe6,0x5f,0x80,0x80,0xff,0xe2,0x55,0x80,0x80,0xff, + 0xdd,0x4a,0x80,0x80,0xff,0xd7,0x41,0x80,0x80,0xff,0xd0,0x38,0x80,0x80,0xff,0xc8,0x30,0x80,0x80,0xff, + 0xbf,0x29,0x80,0x80,0xff,0xb6,0x23,0x80,0x80,0xff,0xab,0x1e,0x80,0x80,0xff,0xa1,0x1a,0x80,0x80,0xff, + 0x96,0x17,0x80,0x80,0xff,0x8b,0x15,0x80,0x80,0xff,0x80,0x15,0x80,0x80,0xff,0x74,0x15,0x80,0x80,0xff, + 0x69,0x17,0x80,0x80,0xff,0x5e,0x1a,0x80,0x80,0xff,0x54,0x1e,0x80,0x80,0xff,0x4a,0x23,0x80,0x80,0xff, + 0x40,0x29,0x80,0x80,0xff,0x37,0x30,0x80,0x80,0xff,0x2f,0x38,0x80,0x80,0xff,0x28,0x41,0x80,0x80,0xff, + 0x22,0x4b,0x80,0x80,0xff,0x1d,0x55,0x80,0x80,0xff,0x19,0x5f,0x80,0x80,0xff,0x16,0x6a,0x80,0x80,0xff, + 0x14,0x75,0x80,0x80,0xff,0x14,0x80,0x80,0x80,0xff,0x14,0x8c,0x80,0x80,0xff,0x16,0x97,0x80,0x80,0xff, + 0x19,0xa2,0x80,0x80,0xff,0x1d,0xac,0x80,0x80,0xff,0x22,0xb6,0x80,0x80,0xff,0x28,0xc0,0x80,0x80,0xff, + 0x2f,0xc9,0x80,0x80,0xff,0x37,0xd1,0x80,0x80,0xff,0x40,0xd8,0x80,0x80,0xff,0x49,0xde,0x80,0x80,0xff, + 0x54,0xe3,0x80,0x80,0xff,0x5e,0xe7,0x80,0x80,0xff,0x69,0xea,0x80,0x80,0xff,0x74,0xec,0x80,0x80,0xff + +}; +byte MinPtrData[] PROGMEM = { + 0x82,0x80,0x80,0xe6,0x7e,0x80,0x82,0x80,0xff,0x81,0x80,0x8a,0xe6,0x7e,0x81,0x81,0x80,0xff, + 0x81,0x80,0x95,0xe4,0x7e,0x81,0x81,0x80,0xff,0x81,0x80,0x9f,0xe2,0x7e,0x81,0x81,0x80,0xff, + 0x81,0x80,0xa9,0xde,0x7e,0x81,0x81,0x80,0xff,0x81,0x7f,0xb3,0xd9,0x7e,0x82,0x81,0x7f,0xff, + 0x81,0x7f,0xbb,0xd3,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xc4,0xcc,0x7e,0x82,0x81,0x7f,0xff, + 0x81,0x7f,0xcb,0xc5,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xd2,0xbc,0x7e,0x82,0x81,0x7f,0xff, + 0x80,0x7f,0xd8,0xb3,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xdd,0xaa,0x7f,0x82,0x80,0x7f,0xff, + 0x80,0x7f,0xe1,0xa0,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xe3,0x96,0x7f,0x82,0x80,0x7f,0xff, + 0x80,0x7f,0xe5,0x8b,0x7f,0x82,0x80,0x7f,0xff,0x7f,0x7e,0xe5,0x80,0x80,0x82,0x7f,0x7e,0xff, + 0x7f,0x7f,0xe5,0x76,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xe3,0x6b,0x80,0x82,0x7f,0x7f,0xff, + 0x7f,0x7f,0xe1,0x61,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xdd,0x57,0x80,0x82,0x7f,0x7f,0xff, + 0x7e,0x7f,0xd8,0x4d,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xd2,0x45,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x7f,0xcb,0x3c,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xc4,0x35,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x7f,0xbb,0x2e,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xb3,0x28,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x80,0xa9,0x23,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x9f,0x1f,0x81,0x81,0x7e,0x80,0xff, + 0x7e,0x80,0x95,0x1d,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x8a,0x1b,0x81,0x81,0x7e,0x80,0xff, + 0x7e,0x81,0x7f,0x1b,0x82,0x80,0x7e,0x81,0xff,0x7e,0x81,0x75,0x1b,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x81,0x6a,0x1d,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x60,0x1f,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x81,0x56,0x23,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x4d,0x28,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x82,0x44,0x2e,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x3b,0x35,0x81,0x7f,0x7e,0x82,0xff, + 0x7e,0x82,0x34,0x3c,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x2d,0x45,0x81,0x7f,0x7e,0x82,0xff, + 0x7f,0x82,0x27,0x4e,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x22,0x57,0x80,0x7f,0x7f,0x82,0xff, + 0x7f,0x82,0x1e,0x61,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x1c,0x6b,0x80,0x7f,0x7f,0x82,0xff, + 0x7f,0x82,0x1a,0x76,0x80,0x7f,0x7f,0x82,0xff,0x80,0x82,0x1a,0x81,0x7f,0x7e,0x80,0x82,0xff, + 0x80,0x82,0x1a,0x8b,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x1c,0x96,0x7f,0x7f,0x80,0x82,0xff, + 0x80,0x82,0x1e,0xa0,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x22,0xaa,0x7f,0x7f,0x80,0x82,0xff, + 0x80,0x82,0x27,0xb3,0x7f,0x7f,0x80,0x82,0xff,0x81,0x82,0x2d,0xbc,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x82,0x34,0xc5,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x3b,0xcc,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x82,0x44,0xd3,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x4c,0xd9,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x81,0x56,0xde,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x60,0xe2,0x7e,0x80,0x81,0x81,0xff, + 0x81,0x81,0x6a,0xe4,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x75,0xe6,0x7e,0x80,0x81,0x81,0xff + +}; +byte HrPtrData[] PROGMEM = { + 0x82,0x80,0x80,0xbc,0x7e,0x80,0x82,0x80,0xff,0x81,0x80,0x86,0xbc,0x7e,0x81,0x81,0x80,0xff, + 0x81,0x80,0x8c,0xbb,0x7e,0x81,0x81,0x80,0xff,0x81,0x80,0x92,0xba,0x7e,0x81,0x81,0x80,0xff, + 0x81,0x80,0x98,0xb7,0x7e,0x81,0x81,0x80,0xff,0x81,0x7f,0x9e,0xb4,0x7e,0x82,0x81,0x7f,0xff, + 0x81,0x7f,0xa3,0xb1,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xa8,0xad,0x7e,0x82,0x81,0x7f,0xff, + 0x81,0x7f,0xac,0xa9,0x7e,0x82,0x81,0x7f,0xff,0x81,0x7f,0xb0,0xa4,0x7e,0x82,0x81,0x7f,0xff, + 0x80,0x7f,0xb3,0x9e,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xb6,0x99,0x7f,0x82,0x80,0x7f,0xff, + 0x80,0x7f,0xb9,0x93,0x7f,0x82,0x80,0x7f,0xff,0x80,0x7f,0xba,0x8d,0x7f,0x82,0x80,0x7f,0xff, + 0x80,0x7f,0xbb,0x87,0x7f,0x82,0x80,0x7f,0xff,0x7f,0x7e,0xbb,0x80,0x80,0x82,0x7f,0x7e,0xff, + 0x7f,0x7f,0xbb,0x7a,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xba,0x74,0x80,0x82,0x7f,0x7f,0xff, + 0x7f,0x7f,0xb9,0x6e,0x80,0x82,0x7f,0x7f,0xff,0x7f,0x7f,0xb6,0x68,0x80,0x82,0x7f,0x7f,0xff, + 0x7e,0x7f,0xb3,0x62,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xb0,0x5d,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x7f,0xac,0x58,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0xa8,0x54,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x7f,0xa3,0x50,0x81,0x82,0x7e,0x7f,0xff,0x7e,0x7f,0x9e,0x4d,0x81,0x82,0x7e,0x7f,0xff, + 0x7e,0x80,0x98,0x4a,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x92,0x47,0x81,0x81,0x7e,0x80,0xff, + 0x7e,0x80,0x8c,0x46,0x81,0x81,0x7e,0x80,0xff,0x7e,0x80,0x86,0x45,0x81,0x81,0x7e,0x80,0xff, + 0x7e,0x81,0x7f,0x45,0x82,0x80,0x7e,0x81,0xff,0x7e,0x81,0x79,0x45,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x81,0x73,0x46,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x6d,0x47,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x81,0x67,0x4a,0x81,0x80,0x7e,0x81,0xff,0x7e,0x81,0x62,0x4d,0x81,0x80,0x7e,0x81,0xff, + 0x7e,0x82,0x5c,0x50,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x57,0x54,0x81,0x7f,0x7e,0x82,0xff, + 0x7e,0x82,0x53,0x58,0x81,0x7f,0x7e,0x82,0xff,0x7e,0x82,0x4f,0x5d,0x81,0x7f,0x7e,0x82,0xff, + 0x7f,0x82,0x4c,0x63,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x49,0x68,0x80,0x7f,0x7f,0x82,0xff, + 0x7f,0x82,0x46,0x6e,0x80,0x7f,0x7f,0x82,0xff,0x7f,0x82,0x45,0x74,0x80,0x7f,0x7f,0x82,0xff, + 0x7f,0x82,0x44,0x7a,0x80,0x7f,0x7f,0x82,0xff,0x80,0x82,0x44,0x81,0x7f,0x7e,0x80,0x82,0xff, + 0x80,0x82,0x44,0x87,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x45,0x8d,0x7f,0x7f,0x80,0x82,0xff, + 0x80,0x82,0x46,0x93,0x7f,0x7f,0x80,0x82,0xff,0x80,0x82,0x49,0x99,0x7f,0x7f,0x80,0x82,0xff, + 0x80,0x82,0x4c,0x9e,0x7f,0x7f,0x80,0x82,0xff,0x81,0x82,0x4f,0xa4,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x82,0x53,0xa9,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x57,0xad,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x82,0x5c,0xb1,0x7e,0x7f,0x81,0x82,0xff,0x81,0x82,0x61,0xb4,0x7e,0x7f,0x81,0x82,0xff, + 0x81,0x81,0x67,0xb7,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x6d,0xba,0x7e,0x80,0x81,0x81,0xff, + 0x81,0x81,0x73,0xbb,0x7e,0x80,0x81,0x81,0xff,0x81,0x81,0x79,0xbc,0x7e,0x80,0x81,0x81,0xff + +}; + +byte TestData[] PROGMEM = { + 0x01,0x01,0x01,0xfe,0xfe,0xfe,0xfe,0x01,0x01,0x01,0x00, // Max Square + 0x01,0x3f,0x01,0xbd,0x3f,0xfe,0xbd,0xfe,0xfe,0xbd,0xfe,0x3f,0xbd,0x01,0x3f,0x01,0x01,0x3f,0x00, // Max Octagon + 0x7f,0x7f,0x7f,0xfe,0x00,0x7f,0x7f,0xbd,0xfe,0x00,0x7f,0x7f,0xfe,0xfe,0x00,0x7f,0x7f,0xfe,0xbd,0x00,// Max diagonals + 0x7f,0x7f,0xfe,0x7f,0x00,0x7f,0x7f,0xfe,0x3f,0x00,0x7f,0x7f,0xfe,0x01,0x00,0x7f,0x7f,0xbd,0x01,0x00, + 0x7f,0x7f,0x7f,0x01,0x00,0x7f,0x7f,0x3f,0x01,0x00,0x7f,0x7f,0x01,0x01,0x00,0x7f,0x7f,0x01,0x3f,0x00, + 0x7f,0x7f,0x01,0x7f,0x00,0x7f,0x7f,0x01,0xbd,0x00,0x7f,0x7f,0x01,0xfe,0x00,0x7f,0x7f,0x3f,0xfe,0xff +}; diff --git a/src/ESP32_OscilloscopeClock_v1.0.cpp b/src/ESP32_OscilloscopeClock_v1.0.cpp new file mode 100644 index 0000000..3a7a741 --- /dev/null +++ b/src/ESP32_OscilloscopeClock_v1.0.cpp @@ -0,0 +1,449 @@ +/****************************************************************************** + ESP32 Oscilloscope Clock + using internal DACs, with WiFi and ntp sync. + + Based on great work by: Mauro Pintus , Milano 2018/05/25 + GitHub Repository + https://github.com/maurohh/ESP32_OscilloscopeClock + + This modified version by: Tatu Wikman + https://github.com/tswfi/ESP32_OscilloscopeClock + + How to use it: + Build and upload to esp32, connect dac pins to oscilloscope on xy mode and + follow the instructions to get wifi and timezone adjusted +******************************************************************************/ +#include "Arduino.h" + +// for saving settings in spiffs +#include "FS.h" +#include "SPIFFS.h" +#include "ArduinoJson.h" + +// +#include "driver/dac.h" +#include "soc/rtc.h" +#include "soc/sens_reg.h" +#include "simpleDSTadjust.h" +#include "WiFi.h" + +// data to show +#include "DataTable.h" + +// for wifi manager +#include "DNSServer.h" +#include "WebServer.h" +#include "WiFiManager.h" + +// timezone and dst rules +int utc_offset = 0; +struct dstRule StartRule = {"PDT", Second, Sun, Mar, 2, 3600}; // Pacific Daylight time = UTC/GMT -7 hours +struct dstRule EndRule = {"PST", First, Sun, Nov, 1, 0}; // Pacific Standard time = UTC/GMT -8 hour +simpleDSTadjust dstAdjusted(StartRule, EndRule); + +WiFiManager wifiManager; +bool shouldSaveConfig = false; + +// change for different NTP (time servers) +#define NTP_SERVERS "pool.ntp.org" + +// August 1st, 2018 +#define NTP_MIN_VALID_EPOCH 1533081600 + +#define TRIGGER_PIN 12 + +//Variables +int lastx, lasty; +unsigned long currentMillis = 0; +unsigned long previousMillis = 0; +const long ntp_refresh_interval = 10 * 60 * 1000; // in milliseconds, 10 minutes +bool ntpsynchappened = false; + +// Draw a dot in X Y +inline void Dot(int x, int y) +{ + if (lastx != x) + { + lastx = x; + dac_output_voltage(DAC_CHANNEL_1, x); + } + if (lasty != y) + { + lasty = y; + dac_output_voltage(DAC_CHANNEL_2, y); + } +} + +// Bresenham's Algorithm implementation optimized +// also known as a DDA - digital differential analyzer +void Line(byte x1, byte y1, byte x2, byte y2) +{ + int n = 2; + int acc; + bool first_point = true; + // for speed, there are 8 DDA's, one for each octant + if (y1 < y2) + { // quadrant 1 or 2 + byte dy = y2 - y1; + if (x1 < x2) + { // quadrant 1 + byte dx = x2 - x1; + if (dx > dy) + { // < 45 + acc = (dx >> 1); + for (; x1 <= x2; x1++) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dy; + if (acc < 0) + { + y1++; + acc += dx; + } + } + } + else + { // > 45 + acc = dy >> 1; + for (; y1 <= y2; y1++) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dx; + if (acc < 0) + { + x1++; + acc += dy; + } + } + } + } + else + { // quadrant 2 + byte dx = x1 - x2; + if (dx > dy) + { // < 45 + acc = dx >> 1; + for (; x1 >= x2; x1--) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dy; + if (acc < 0) + { + y1++; + acc += dx; + } + } + } + else + { // > 45 + acc = dy >> 1; + for (; y1 <= y2; y1++) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dx; + if (acc < 0) + { + x1--; + acc += dy; + } + } + } + } + } + else + { // quadrant 3 or 4 + byte dy = y1 - y2; + if (x1 < x2) + { // quadrant 4 + byte dx = x2 - x1; + if (dx > dy) + { // < 45 + acc = dx >> 1; + for (; x1 <= x2; x1++) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dy; + if (acc < 0) + { + y1--; + acc += dx; + } + } + } + else + { // > 45 + acc = dy >> 1; + for (; y1 >= y2; y1--) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dx; + if (acc < 0) + { + x1++; + acc += dy; + } + } + } + } + else + { // quadrant 3 + byte dx = x1 - x2; + if (dx > dy) + { // < 45 + acc = dx >> 1; + for (; x1 >= x2; x1--) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dy; + if (acc < 0) + { + y1--; + acc += dx; + } + } + } + else + { // > 45 + acc = dy >> 1; + for (; y1 >= y2; y1--) + { + Dot(x1, y1); + if (first_point) + { + delayMicroseconds(n); + first_point = false; + } + acc -= dx; + if (acc < 0) + { + x1--; + acc += dy; + } + } + } + } + } +} + +void PlotTable(byte *SubTable, int SubTableSize, int skip, int opt, int offset) +{ + int i = offset; + while (i < SubTableSize) + { + if (SubTable[i + 2] == skip) + { + i = i + 3; + if (opt == 1) + if (SubTable[i] == skip) + i++; + } + Line(SubTable[i], SubTable[i + 1], SubTable[i + 2], SubTable[i + 3]); + if (opt == 2) + { + Line(SubTable[i + 2], SubTable[i + 3], SubTable[i], SubTable[i + 1]); + } + i = i + 2; + if (SubTable[i + 2] == 0xFF) + break; + } +} + +// time_t getNtpTime() +void getNtpTime() +{ + time_t now; + + int i = 0; + configTime(utc_offset * 3600, 0, NTP_SERVERS); + while ((now = time(nullptr)) < NTP_MIN_VALID_EPOCH) + { + delay(500); + i++; + if (i > 60) + break; + } + + ntpsynchappened = true; +} + +// callback coming back from config mode +void configModeCallback(WiFiManager *myWiFiManager) +{ + shouldSaveConfig = true; +} + +void writeConfig(String json) +{ + File configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) + { + Serial.println("could not write the default config file, freezing"); + while (1) + ; + } + configFile.println(json); + Serial.println("Wrote default config"); + configFile.close(); +} + +void readConfig() +{ + File configFile = SPIFFS.open("/config.json", "r"); + if (!configFile) + { + Serial.println("could not read the config file, freezing"); + while (1) + ; + } + size_t size = configFile.size(); + std::unique_ptr buf(new char[size]); + + DynamicJsonDocument doc(1024); + DeserializationError error = deserializeJson(doc, configFile.readString()); + if (error) + { + Serial.println("Failed to deserialize config file, freezing"); + while (1) + ; + } + // read our utc offset from the doc + utc_offset = doc["utc_offset"]; + Serial.print("Read utc_offset from config: "); + Serial.println(utc_offset); + configFile.close(); +} + +void setup() +{ + pinMode(TRIGGER_PIN, INPUT_PULLUP); + Serial.begin(115200); + Serial.println("\nESP32 Oscilloscope Clock v1.0"); + Serial.println("Mauro Pintus 2018\nwww.mauroh.com"); + Serial.println("Extended by Tatu Wikman"); + + if (!SPIFFS.begin(true)) + { + Serial.println("Failed to start or format SPIFFS, freezing"); + while (1) + ; + } + + Serial.println("mounted SPIFFS"); + if (!SPIFFS.exists("/config.json")) + { + writeConfig("{\"utc_offset\": 0}"); + } + + Serial.println("Starting WifiManager"); + + // register our callback + wifiManager.setAPCallback(configModeCallback); + + // timezone paramater for wifimanager + char buf[8]; + itoa(utc_offset, buf, 10); + WiFiManagerParameter timezoneparameter("timezone", "Timezone: +2, -8, 0", buf, 3); + wifiManager.addParameter(&timezoneparameter); + + // connect to network or start ap to get the network information + wifiManager.autoConnect(); + + if(shouldSaveConfig) { + Serial.println("New settings available, trying to save them"); + char new_utc_offset[15]; + strcpy(new_utc_offset, timezoneparameter.getValue()); + String newconfig = "{\"utc_offset\": "; + newconfig.concat(new_utc_offset); + newconfig.concat("}"); + Serial.println("Trying to save new config: "); + Serial.println(newconfig); + writeConfig(newconfig); + } + + // read the config from SPIFFS + readConfig(); + + // start dac + dac_output_enable(DAC_CHANNEL_1); + dac_output_enable(DAC_CHANNEL_2); + + // fetch time on startup + getNtpTime(); + + previousMillis = currentMillis; +} + +void loop() +{ + currentMillis = millis(); + if (currentMillis - previousMillis >= ntp_refresh_interval) + { + previousMillis = currentMillis; + getNtpTime(); + } + + char *dstAbbrev; + time_t now = dstAdjusted.time(&dstAbbrev); + struct tm *timeinfo = localtime(&now); + + if (ntpsynchappened) + { + Serial.println(); + Serial.printf("NTP Sync time now: %d:%d:%d\n", timeinfo->tm_hour % 12, timeinfo->tm_min, timeinfo->tm_sec); + ntpsynchappened = false; + } + + int h = timeinfo->tm_hour % 12; + int m = timeinfo->tm_min; + int s = timeinfo->tm_sec; + + PlotTable(DialData, sizeof(DialData), 0x00, 1, 0); //2 to back trace + PlotTable(DialDigits12, sizeof(DialDigits12), 0x00, 1, 0); //2 to back trace + PlotTable(HrPtrData, sizeof(HrPtrData), 0xFF, 0, (9 * (5 * h + m / 12))); // 9*h + PlotTable(MinPtrData, sizeof(MinPtrData), 0xFF, 0, 9 * m); // 9*m + PlotTable(SecPtrData, sizeof(SecPtrData), 0xFF, 0, 5 * s); // 5*s + + // force the wifimanager to ask new config + if ( digitalRead(TRIGGER_PIN) == LOW ) { + Serial.println("Forgetting settings and restarting to get portal up"); + wifiManager.resetSettings(); + Serial.println("Restarting"); + delay(1000); + ESP.restart(); + } +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html