├── .gitignore ├── LICENSE ├── NOTES.md ├── README.md ├── __dd_cpp_include.h ├── __dd_misc_connect.h ├── __dd_misc_debug.h ├── __dd_misc_layer.h ├── __dd_misc_layout.h ├── __dd_misc_value.h ├── _dd_colors.h ├── _dd_commands.h ├── _dd_feedback.cpp ├── _dd_feedback.h ├── _dd_io.h ├── _dd_misc.cpp ├── _dd_misc.h ├── _dd_serial.h ├── _dd_util.cpp ├── _dd_util.h ├── _loespat.h ├── amb82wifidumbdisplay.h ├── amb82wifidumbdisplay_new.h ├── atwifidumbdisplay.h ├── ddatftutil.h ├── ddjoystick.h ├── ddoledutil.h ├── ddtester.cpp ├── ddtester.h ├── ddtester_0.cpp ├── ddtester_0.h ├── ddtftutil.h ├── dumbdisplay.cpp ├── dumbdisplay.h ├── esp32bledumbdisplay.h ├── esp32dumbdisplay.h ├── examples ├── amb82_facerecog │ └── amb82_facerecog.ino ├── otg7segment │ └── otg7segment.ino ├── otgblink │ └── otgblink.ino ├── otgfonts │ └── otgfonts.ino ├── otgkeypad │ └── otgkeypad.ino ├── otgkeypad_callback │ └── otgkeypad_callback.ino ├── otgledmatrix │ └── otgledmatrix.ino ├── otgrest │ └── otgrest.ino ├── otgrgb │ └── otgrgb.ino ├── otgsound │ └── otgsound.ino ├── otgwebimage │ └── otgwebimage.ino ├── otgwebimage_2 │ └── otgwebimage_2.ino ├── sliding_puzzle │ └── sliding_puzzle.ino ├── sliding_puzzle_w_suggest │ └── sliding_puzzle_w_suggest.ino └── webview_blink │ └── webview_blink.ino ├── genericdumbdisplay.h ├── library.json ├── library.properties ├── pgm_util.h ├── picodumbdisplay.h ├── projects ├── MISC │ └── melody │ │ └── melody.ino ├── dd7segcounter │ └── dd7segcounter.ino ├── dd8x8 │ └── dd8x8.ino ├── dd_TFT_Clock │ └── dd_TFT_Clock.ino ├── ddcalculator │ ├── BasicCalculator.h │ └── ddcalculator.ino ├── ddclock │ └── ddclock.ino ├── ddcolorsensor │ └── ddcolorsensor.ino ├── ddgpsmap │ ├── ddgpsmap.ino │ └── gpssignal.h ├── ddlock │ └── ddlock.ino ├── ddmelody │ └── ddmelody.ino ├── ddpocketcomputer │ ├── BasicCalculator.h │ ├── PressTracker.h │ ├── core.h │ ├── ddpocketcomputer.ino │ └── misc.h ├── ddradar │ └── ddradar.ino ├── ddspacewars │ ├── Core.h │ ├── Misc.h │ ├── PressTracker.h │ ├── back2.h │ ├── brod.h │ ├── brod1.h │ ├── bulet.h │ ├── buum.h │ ├── ddspacewars.ino │ ├── earth.h │ ├── earth2.h │ ├── ebullet.h │ ├── ex.h │ ├── ex2.h │ ├── gameOver.h │ ├── homer.h │ ├── life.h │ ├── ricon.h │ ├── rocket.h │ ├── rover.h │ └── sens.h ├── esp32ddcammic │ └── esp32ddcammic.ino ├── esp32ddcammic_full │ └── esp32ddcammic_full.ino ├── esp32ddcammic_ori │ └── esp32ddcammic_ori.ino ├── esp32ddmic │ └── esp32ddmic.ino ├── esp32ddmic_simple │ └── esp32ddmic_simple.ino ├── esp32ddsleep │ └── esp32ddsleep.ino ├── esp32ddvoice │ └── esp32ddvoice.ino ├── esp32ddvoice_2 │ └── esp32ddvoice_2.ino ├── esp32tensorflowlite │ ├── ddhelloworld │ │ ├── ddhelloworld.ino │ │ └── sine_model.h │ ├── esp32_mnist │ │ ├── esp32_mnist.ino │ │ ├── frogermcs_mnist_model.h │ │ ├── mnist_model.h │ │ └── mnist_model.ipynb │ ├── esp32cam_person │ │ ├── esp32cam_person.ino │ │ └── person_detect_model_data.h │ ├── helloworld │ │ ├── helloworld.ino │ │ └── sine_model_data.cc │ ├── helloworld_full │ │ ├── helloworld_full.ino │ │ └── sine_model_data.cc │ └── sine_model.ipynb ├── esp_dd_TFT_Clock │ └── esp_dd_TFT_Clock.ino ├── espatchat │ └── espatchat.ino ├── espspacewars │ ├── Core.h │ ├── Misc.h │ └── espspacewars.ino ├── espvoicecommander │ ├── esp01_voicecommandagent │ │ └── esp01_voicecommandagent.ino │ ├── voicecommandagents │ │ └── voicecommandagents.ino │ └── voicecommander │ │ └── voicecommander.ino ├── joystick │ └── joystick.ino ├── joystick_now │ └── joystick_now.ino ├── numinvader │ ├── gameobjs.h │ ├── numinvader.ino │ ├── sound.h │ └── tracker.h ├── picoddls164n │ └── picoddls164n.ino ├── picostepmotor │ └── picostepmotor.ino ├── picouart1blink │ └── picouart1blink.ino ├── servo │ └── servo.ino └── twatch │ └── twatchblink │ └── twatchblink.ino ├── samples ├── dd7seg │ └── dd7seg.ino ├── ddautopin │ └── ddautopin.ino ├── ddbarmeter │ └── ddbarmeter.ino ├── ddblink │ └── ddblink.ino ├── ddborder │ └── ddborder.ino ├── ddcolors │ └── ddcolors.ino ├── dddoodle │ └── dddoodle.ino ├── ddfonts │ └── ddfonts.ino ├── ddgraphical │ └── ddgraphical.ino ├── ddhere │ └── ddhere.ino ├── ddmb │ └── ddmb.ino ├── ddnow │ └── ddnow.ino ├── ddnowhere │ └── ddnowhere.ino ├── ddonoffloopmb │ └── ddonoffloopmb.ino ├── ddonoffmb │ └── ddonoffmb.ino ├── ddpinturtle │ └── ddpinturtle.ino ├── ddquote │ └── ddquote.ino ├── ddup4howlong │ └── ddup4howlong.ino ├── ddyesdetect │ └── ddyesdetect.ino ├── ddyesdetect_simple │ └── ddyesdetect_simple.ino ├── esp32bleup4howlong │ └── esp32bleup4howlong.ino ├── esp32blewaves │ └── esp32blewaves.ino ├── esp32c3ddblink │ └── esp32c3ddblink.ino ├── esp32camddtest │ └── esp32camddtest.ino ├── esp32camobjdetect │ └── esp32camobjdetect.ino ├── esp8266_now │ └── esp8266_now.ino ├── inithc06 │ └── inithc06.ino ├── initpicohc06 │ └── initpicohc06.ino ├── joysticktest │ └── joysticktest.ino ├── objectdetectdemo │ └── objectdetectdemo.ino └── webimage │ └── webimage.ino ├── screenshots ├── 164n-8x8-1.png ├── amb82-mini-facerecog.jpg ├── color-sensor-connection.png ├── dd7segcounter.jpg ├── dd7segcounter_connection.png ├── dd_awc_tab_alarms.jpg ├── dd_awc_tab_general.jpg ├── dd_awc_tab_slids.jpg ├── dd_pixel_density_fine.png ├── dd_pixel_density_high.png ├── dd_pixel_density_medium.png ├── dd_pixel_density_normal.png ├── dd_pixel_density_over.png ├── dd_prepare_storage.gif ├── dd_storage.gif ├── ddautopin.png ├── ddbarmeter.png ├── dddoodle.png ├── ddgpsmap_ss.png ├── ddgraphical.png ├── ddmb.png ├── ddmelody.jpg ├── ddnowhere.jpg ├── ddobjectdetect.jpg ├── ddpin.png ├── ddpinturtle.png ├── ddpocketcomputer.png ├── ddquote.png ├── ddsaveimages.gif ├── ddspacewars.gif ├── ddwebblink.png ├── ddwebcalc.png ├── ddwifibridge.png ├── ddwifibridge2.png ├── esp32-deep-sleep-connection.png ├── esp32-dht11-connection.png ├── esp32-mic.png ├── esp32_mnist.gif ├── esp32camobjectdetect.gif ├── esp8266-servo-connection.png ├── esp8266-servo.jpg ├── joystick-arduino-connect.png ├── joystick-arduino.jpg ├── joystick-dd.png ├── lock-locked.png ├── lock-unlocked.png ├── numinvader-connection.png ├── numinvader.jpg ├── otg7segment.png ├── otgblink.png ├── otgkeypad.png ├── otgrest.png ├── otgrgb.png ├── otgsound.png ├── otgwebimage.png ├── pico-164n_connection.png ├── pico-8x8-connect.png ├── pico-radar.png ├── pico-speaker_connection.png ├── pico-stepmotor_connect.png ├── servo-dd.png ├── sliding-ss.jpg ├── sliding.gif ├── snapper-ss.jpg ├── spacewarsimgs.png ├── tdisplayclock.png ├── tft_image_show.gif ├── tft_show_show_ss.png ├── up4howlong.png └── webimage.jpg ├── serial2dumbdisplay.h ├── ssdumbdisplay.h ├── tools └── DDWifiBridge │ ├── .gitignore │ ├── DDWifiBridge.py │ ├── DDWifiBridge │ ├── __init__.py │ ├── __main__.py │ ├── ddbclmain.py │ ├── ddbcore.py │ ├── ddbmod.py │ ├── ddbridge.py │ ├── ddbwinmain.py │ └── jsonparse.py │ ├── README.md │ └── setup.py └── wifidumbdisplay.h /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | __pycache__ 4 | tools/DDWifiBridge/DDWifiBridge.iml 5 | tools/DDWifiBridge/ddwifibridge.ini 6 | tools/DDWifiBridge/venv 7 | projects/esp32tensorflowlite/esp32cam_person/person_detect_model_data.cc 8 | build 9 | my_notes.txt 10 | tools/DDWifiBridge/_SYNCAPP 11 | _secret.h -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Trevor Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | Notes: 2 | 3 | * The starting point is a [DumbDisplay](https://trevorwslee.github.io/ArduinoDumbDisplay/html/class_dumb_display.html) object 4 | 5 | * The *README* of the [GitHub repository for DumbDisplay Arduino Library](https://github.com/trevorwslee/Arduino-DumbDisplay) should provide more details 6 | 7 | * Other than reading the [*README*](https://github.com/trevorwslee/Arduino-DumbDisplay#readme), you might be kick-started with what described in [Blink Test With Virtual Display, DumbDisplay](https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/) 8 | 9 | * Some little tips for reducing the library's footprint 10 | - if you will not be making use of "tunnel", define the compile-time macro `DD_NO_TUNNEL` 11 | - if you will not be making use of "feedback", define the compile-time macro `DD_NO_FEEDBACK` 12 | - if you will not be making use of "passive" connection, define the compile-time macro `DD_NO_PASSIVE_CONNECT` 13 | 14 | * ***Have Fun! Peace be with you! May God bless you! Jesus loves you! Amazing Grace!*** 15 | 16 | 17 | -------------------------------------------------------------------------------- /__dd_cpp_include.h: -------------------------------------------------------------------------------- 1 | #ifndef DD_INIT_LAYER_COUNT 2 | #define DD_INIT_LAYER_COUNT 5 3 | #endif 4 | #ifndef DD_LAYER_COUNT_INC 5 | #define DD_LAYER_COUNT_INC 3 6 | #endif 7 | #if DD_INIT_LAYER_COUNT < 1 8 | #error "DD_INIT_LAYER_COUNT must be at least 1" 9 | #endif 10 | #if DD_LAYER_COUNT_INC < 2 11 | #error "DD_LAYER_COUNT_INC must be at least 2" 12 | #endif 13 | 14 | 15 | 16 | #ifdef DD_NO_PASSIVE_CONNECT 17 | #warning ??? DD_NO_PASSIVE_CONNECT set ??? 18 | #else 19 | #define SUPPORT_PASSIVE 20 | #define SUPPORT_MASTER_RESET 21 | #endif 22 | 23 | #ifdef DD_NO_FEEDBACK 24 | #warning ??? DD_NO_FEEDBACK set ??? 25 | #else 26 | #define ENABLE_FEEDBACK 27 | #endif 28 | 29 | #ifdef ENABLE_FEEDBACK 30 | //#define FEEDBACK_BUFFER_SIZE 4 31 | #define HANDLE_FEEDBACK_DURING_DELAY 32 | #define READ_BUFFER_USE_BUFFER 33 | #ifndef DD_NO_FEEDBACK_BYTES 34 | #define FEEDBACK_SUPPORT_BYTES 35 | #endif 36 | #endif 37 | -------------------------------------------------------------------------------- /__dd_misc_debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DD_NO_DEBUG_INTERFACE 2 | class DrawTextDDDebugInterface: public DDDebugInterface { 3 | public: 4 | void setConnectionType(const char* connectionType) { 5 | this->connectionType = connectionType; 6 | } 7 | public: 8 | virtual void logConnectionState(DDDebugConnectionState connectionState) { 9 | const char* state = NULL; 10 | switch (connectionState) { 11 | case DDDebugConnectionState::DEBUG_NOT_CONNECTED: 12 | state = "NCed"; 13 | break; 14 | case DDDebugConnectionState::DEBUG_CONNECTING: 15 | state = "Cing "; 16 | break; 17 | case DDDebugConnectionState::DEBUG_CONNECTED: 18 | state = "Ced "; 19 | break; 20 | case DDDebugConnectionState::DEBUG_RECONNECTING: 21 | state = "RCing"; 22 | break; 23 | case DDDebugConnectionState::DEBUG_RECONNECTED: 24 | state = "RCed "; 25 | break; 26 | } 27 | if (state != NULL) { 28 | if (true) { 29 | String s = state; 30 | if (connectionType != NULL) { 31 | s = String(connectionType) + ":" + s; 32 | } 33 | drawText(s.c_str(), false); 34 | } else { 35 | drawText(state, false); 36 | } 37 | } 38 | } 39 | virtual void logError(const String& errMsg) { 40 | drawText("Err", true); 41 | } 42 | protected: 43 | virtual void drawText(const char* text, bool isError) { 44 | } 45 | protected: 46 | const char* connectionType; 47 | }; 48 | class ToSerialDDDebugInterface: public DDDebugInterface { 49 | public: 50 | virtual void logConnectionState(DDDebugConnectionState connectionState) { 51 | switch (connectionState) { 52 | case DDDebugConnectionState::DEBUG_NOT_CONNECTED: 53 | Serial.println("* DebugConnection: not connected"); 54 | break; 55 | case DDDebugConnectionState::DEBUG_CONNECTING: 56 | Serial.println("* DebugConnection: connecting"); 57 | break; 58 | case DDDebugConnectionState::DEBUG_CONNECTED: 59 | Serial.println("* DebugConnection: connected"); 60 | break; 61 | case DDDebugConnectionState::DEBUG_RECONNECTING: 62 | Serial.println("* DebugConnection: reconnecting"); 63 | break; 64 | case DDDebugConnectionState::DEBUG_RECONNECTED: 65 | Serial.println("* DebugConnection: reconnected"); 66 | break; 67 | } 68 | } 69 | virtual void logError(const String& errMsg) { 70 | Serial.print("XXX Error: "); 71 | Serial.println(errMsg); 72 | } 73 | }; 74 | class LedDDDebugInterface: public DDDebugInterface { 75 | public: 76 | LedDDDebugInterface(uint8_t ledPin) { 77 | this->ledPin = ledPin; 78 | pinMode(ledPin, OUTPUT); 79 | } 80 | virtual void logSendCommand(int state) { 81 | digitalWrite(ledPin, state == 1 ? HIGH : LOW); 82 | } 83 | private: 84 | uint8_t ledPin; 85 | }; 86 | class CompositeDDDebugInterface: public DDDebugInterface { 87 | public: 88 | CompositeDDDebugInterface(DDDebugInterface* debug1, DDDebugInterface* debug2){ 89 | this->debug1 = debug1; 90 | this->debug2 = debug2; 91 | } 92 | virtual void logConnectionState(DDDebugConnectionState connectionState) { 93 | if (debug1 != NULL) debug1->logConnectionState(connectionState); 94 | if (debug2 != NULL) debug2->logConnectionState(connectionState); 95 | } 96 | virtual void logSendCommand(int state) { 97 | if (debug1 != NULL) debug1->logSendCommand(state); 98 | if (debug2 != NULL) debug2->logSendCommand(state); 99 | } 100 | virtual void logError(const String& errMsg) { 101 | if (debug1 != NULL) debug1->logError(errMsg); 102 | if (debug2 != NULL) debug2->logError(errMsg); 103 | } 104 | private: 105 | DDDebugInterface* debug1; 106 | DDDebugInterface* debug2; 107 | }; 108 | #endif 109 | 110 | 111 | -------------------------------------------------------------------------------- /_dd_feedback.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "_dd_feedback.h" 3 | #include "__dd_cpp_include.h" 4 | 5 | DDFeedbackManager::DDFeedbackManager(/*int8_t bufferSize*/) { 6 | this->nextArrayIdx = 0; 7 | this->validArrayIdx = 0; 8 | } 9 | const DDFeedback* DDFeedbackManager::getFeedback() { 10 | #ifdef ENABLE_FEEDBACK 11 | if (nextArrayIdx == validArrayIdx) return NULL; 12 | const DDFeedback* pFeedback = &feedbackArray[validArrayIdx]; 13 | validArrayIdx = (validArrayIdx + 1) % DD_FEEDBACK_BUFFER_SIZE/*arraySize*/; 14 | return pFeedback; 15 | #else 16 | return NULL; 17 | #endif 18 | } 19 | void DDFeedbackManager::pushFeedback(DDFeedbackType type, int16_t x, int16_t y, const char* pText) { 20 | #ifdef ENABLE_FEEDBACK 21 | feedbackArray[nextArrayIdx].type = type; 22 | feedbackArray[nextArrayIdx].x = x; 23 | feedbackArray[nextArrayIdx].y = y; 24 | feedbackArray[nextArrayIdx].text = pText != NULL ? pText : ""; 25 | nextArrayIdx = (nextArrayIdx + 1) % DD_FEEDBACK_BUFFER_SIZE/*arraySize*/; 26 | if (nextArrayIdx == validArrayIdx) 27 | validArrayIdx = (validArrayIdx + 1) % DD_FEEDBACK_BUFFER_SIZE/*arraySize*/; 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /_dd_feedback.h: -------------------------------------------------------------------------------- 1 | #ifndef _dd_feedback_h 2 | #define _dd_feedback_h 3 | 4 | 5 | #ifndef DD_NO_FEEDBACK 6 | #ifndef DD_FEEDBACK_BUFFER_SIZE 7 | #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO) 8 | #define DD_FEEDBACK_BUFFER_SIZE 2 9 | #else 10 | #define DD_FEEDBACK_BUFFER_SIZE 4 11 | #endif 12 | #endif 13 | #if DD_FEEDBACK_BUFFER_SIZE < 2 14 | #error "DD_FEEDBACK_BUFFER_SIZE must be at least 2" 15 | #endif 16 | #else 17 | #define DD_FEEDBACK_BUFFER_SIZE 0 18 | #endif 19 | 20 | 21 | /// @struct DDFeedbackType 22 | /// @brief 23 | /// The enum indicating the type of "feedback". See DDFeedback 24 | enum DDFeedbackType { CLICK, LONGPRESS, DOUBLECLICK, MOVE, UP, DOWN, CUSTOM }; // DOUBLECLICK needs special option for DumbDisplay 25 | 26 | /// @struct DDFeedback 27 | /// @brief 28 | /// The struct that captures info about "feedback". See DDLayer::enableFeedback() 29 | struct DDFeedback { 30 | /// type of the "feedback" 31 | DDFeedbackType type; 32 | /// x of the "area" on the layer where was clicked 33 | int16_t x; 34 | /// y of the "area" on the layer where was clicked 35 | int16_t y; 36 | /// text input (if any) 37 | String text; 38 | }; 39 | 40 | /// Class for internal use to track "feedbacks". 41 | class DDFeedbackManager { 42 | public: 43 | DDFeedbackManager(/*int8_t bufferSize*/); 44 | const DDFeedback* getFeedback(); 45 | void pushFeedback(DDFeedbackType type, int16_t x, int16_t y, const char* pText); 46 | private: 47 | DDFeedback feedbackArray[DD_FEEDBACK_BUFFER_SIZE]; 48 | int8_t nextArrayIdx; 49 | int8_t validArrayIdx; 50 | }; 51 | 52 | 53 | #endif -------------------------------------------------------------------------------- /_dd_io.h: -------------------------------------------------------------------------------- 1 | #ifndef _dd_io_h 2 | #define _dd_io_h 3 | 4 | /// @brief 5 | /// Class for DD input/output; you explicitly constructed it, pass in when instantiate DumbDisplay, 6 | /// then it will be use by DD internally for communication with DumbDisplay app. 7 | /// There are several derived class like DDSoftwareSerialIO, DDWiFiServerIO, DDBluetoothSerialIO, DDBLESerialIO, DDPicoSerialIO etc 8 | /// @since v0.9.8 9 | class DDInputOutput { 10 | public: 11 | DDInputOutput(unsigned long serialBaud = DD_SERIAL_BAUD): DDInputOutput(serialBaud, false, true) { 12 | } 13 | DDInputOutput* newForSerialConnection() { 14 | return new DDInputOutput(serialBaud, false, true); 15 | } 16 | virtual ~DDInputOutput() { 17 | } 18 | virtual const char* getWhat() { 19 | return NULL; 20 | } 21 | virtual bool available() { 22 | #ifdef DDIO_USE_DD_SERIAL 23 | return _The_DD_Serial != NULL && _The_DD_Serial->available(); 24 | #else 25 | return Serial.available(); 26 | #endif 27 | } 28 | virtual char read() { 29 | #ifdef DDIO_USE_DD_SERIAL 30 | return _The_DD_Serial != NULL ? _The_DD_Serial->read() : 0; 31 | #else 32 | return Serial.read(); 33 | #endif 34 | } 35 | virtual void print(const String &s) { 36 | #ifdef DDIO_USE_DD_SERIAL 37 | if (_The_DD_Serial != NULL) _The_DD_Serial->print(s); 38 | #else 39 | Serial.print(s); 40 | #endif 41 | } 42 | virtual void print(const char *p) { 43 | #ifdef DDIO_USE_DD_SERIAL 44 | if (_The_DD_Serial != NULL) _The_DD_Serial->print(p); 45 | #else 46 | Serial.print(p); 47 | #endif 48 | } 49 | virtual void write(uint8_t b) { 50 | #ifdef DDIO_USE_DD_SERIAL 51 | if (_The_DD_Serial != NULL) _The_DD_Serial->write(b); 52 | #else 53 | Serial.write(b); 54 | #endif 55 | } 56 | virtual void write(const uint8_t *buf, size_t size) { 57 | for (size_t i = 0; i < size; i++) { 58 | write(buf[i]); 59 | } 60 | } 61 | virtual void flush() { 62 | #ifdef DDIO_USE_DD_SERIAL 63 | if (_The_DD_Serial != NULL) _The_DD_Serial->flush(); 64 | #else 65 | Serial.flush(); 66 | #endif 67 | } 68 | virtual void keepAlive() { 69 | } 70 | virtual void validConnection() { 71 | } 72 | virtual bool preConnect(bool firstCall) { 73 | if (true) { 74 | if (firstCall) { 75 | // since 2023-08-13 76 | if (setupForSerial) { 77 | #ifdef DDIO_USE_DD_SERIAL 78 | if (_The_DD_Serial != NULL) _The_DD_Serial->begin(serialBaud); 79 | #else 80 | Serial.begin(serialBaud); 81 | #endif 82 | } 83 | } 84 | } 85 | return true; 86 | } 87 | virtual bool canConnectPassive() { 88 | return true; 89 | } 90 | virtual bool canUseBuffer() { 91 | return false; 92 | } 93 | public: 94 | inline bool isSerial() { 95 | return !backupBySerial && setupForSerial; 96 | } 97 | inline bool isForSerial() { 98 | return setupForSerial; // since 2023-06-03 99 | } 100 | inline bool isBackupBySerial() { 101 | return backupBySerial; 102 | } 103 | inline bool willUseSerial() { 104 | return setupForSerial || backupBySerial; 105 | } 106 | protected: 107 | DDInputOutput(unsigned long serialBaud, bool backupBySerial, bool setupForSerial) { 108 | this->serialBaud = serialBaud; 109 | this->backupBySerial = backupBySerial; 110 | this->setupForSerial = setupForSerial; 111 | } 112 | protected: 113 | unsigned long serialBaud; 114 | bool backupBySerial; 115 | bool setupForSerial; 116 | }; 117 | 118 | 119 | #endif -------------------------------------------------------------------------------- /_dd_misc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dumbdisplay.h" 3 | #include "_dd_misc.h" 4 | 5 | 6 | 7 | 8 | 9 | DDAutoPinGroupHeader DDAutoPinStackedGroupHeader(int left, int top, int right, int bottom) { 10 | return DDAutoPinGroupHeader{String("S/") + String(left) + "-" + String(top) + "-" + String(right) + "-" + String(bottom)}; 11 | } 12 | DDAutoPinGroupHeader DDAutoPinGridGroupHeader(int columnCount, int rowCount, const String& align, bool sameColumnWidth, bool sameRowHeight) { 13 | String header = String("G") + String(columnCount) + "x" + String(rowCount); 14 | if (align.length() > 0 || sameColumnWidth || sameRowHeight) { 15 | header += ":" + align; 16 | } 17 | if (sameColumnWidth) { 18 | header += ";scw"; 19 | } 20 | if (sameRowHeight) { 21 | header += ";srh"; 22 | } 23 | return DDAutoPinGroupHeader{header}; 24 | } 25 | DDAutoPinGroupHeader DDAutoPinGridCellHeader(int columnSpan, int rowSpan, const String& align) { 26 | String header = String("C"); 27 | if (columnSpan > 1 || rowSpan > 1) { 28 | header += String(columnSpan) + "x" + String(rowSpan); 29 | } 30 | if (align.length() > 0) { 31 | header += ":" + align; 32 | } 33 | return DDAutoPinGroupHeader{header}; 34 | } 35 | DDAutoPinGroupHeader DDAutoPinGridCellAlignHeader(const String& align, int columnSpan, int rowSpan) { 36 | return DDAutoPinGridCellHeader(columnSpan, rowSpan, align); 37 | } 38 | -------------------------------------------------------------------------------- /_dd_misc.h: -------------------------------------------------------------------------------- 1 | #ifndef _dd_misc_h 2 | #define _dd_misc_h 3 | 4 | const String DDEmptyString = String(); 5 | 6 | /// check if dumbdisplay is connected 7 | bool DDConnected(); 8 | /// the same usage as standard delay(), but it gives DD a chance to handle "feedbacks" 9 | void DDDelay(unsigned long ms); 10 | /// give DD a chance to handle "feedbacks" 11 | void DDYield(); 12 | 13 | 14 | /// check whether system is LITTLE_ENDIAN or BIG_ENDIAN 15 | /// @return 0 if LITTLE_ENDIAN; 1 if BIG_ENDIAN 16 | inline int DDCheckEndian() { 17 | int i = 1; 18 | const char* p = (const char*) &i; 19 | if (p[0] == 1) 20 | return 0; // LITTLE_ENDIAN; 21 | else 22 | return 1; // BIG_ENDIAN; 23 | } 24 | 25 | #include "__dd_misc_debug.h" 26 | #include "__dd_misc_value.h" 27 | #include "__dd_misc_layout.h" 28 | #include "__dd_misc_layer.h" 29 | #include "__dd_misc_connect.h" 30 | 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /_dd_serial.h: -------------------------------------------------------------------------------- 1 | #ifndef _dd_serial_h 2 | #define _dd_serial_h 3 | 4 | 5 | // #ifdef DD_4_ESP32 6 | // #include 7 | // #include "HardwareSerial.h" 8 | // #endif 9 | 10 | /// Class for internal use only 11 | class DDSerial { 12 | public: 13 | virtual void begin(unsigned long serialBaud) { 14 | Serial.begin(serialBaud); 15 | } 16 | virtual bool available() { 17 | return Serial.available(); 18 | } 19 | virtual char read() { 20 | return Serial.read(); 21 | } 22 | virtual void print(const String &s) { 23 | Serial.print(s); 24 | } 25 | virtual void print(const char *p) { 26 | Serial.print(p); 27 | } 28 | virtual void write(uint8_t b) { 29 | Serial.write(b); 30 | } 31 | virtual void flush() { 32 | Serial.flush(); 33 | } 34 | }; 35 | 36 | //extern DDSerial* _The_DD_Serial; 37 | 38 | #endif -------------------------------------------------------------------------------- /_dd_util.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Arduino.h" 3 | #include "_dd_util.h" 4 | 5 | extern bool _DDDisableParamEncoding; 6 | 7 | char* _DDEncodeInt(int32_t i, char* buffer, int bufferLen) { 8 | if (_DDDisableParamEncoding) { 9 | return itoa(i, buffer, 10); 10 | } 11 | bool isNeg; 12 | if (i < 0) { 13 | isNeg = true; 14 | i = -i; 15 | } else { 16 | isNeg = false; 17 | } 18 | char *encoded = buffer + (isNeg ? 1 : 0); 19 | if (i <= 78) { 20 | encoded[0] = i + '0'; 21 | encoded[1] = 0; 22 | } else if (i <= 99) { 23 | encoded[0] = (i / 10) + '0'; 24 | encoded[1] = (i % 10) + '0'; 25 | encoded[2] = 0; 26 | } else { 27 | encoded[bufferLen - 1] = 0; 28 | int idx = bufferLen - 2; 29 | while (idx >= 0 && i > 0) { 30 | int r = i % 78; 31 | i = i / 78; 32 | int c = r + '0'; 33 | if (i == 0) { 34 | c += 10; 35 | } 36 | encoded[idx--] = c; 37 | } 38 | encoded += idx + 1; 39 | } 40 | if (isNeg) { 41 | encoded--; 42 | encoded[0] = '-'; 43 | } 44 | return encoded; 45 | } 46 | 47 | void DDParseGetDataTimeResponse(const String& response, DDDateTime& dateTime, int* pTZMins) { 48 | String res = response; 49 | int idx = res.indexOf('-'); 50 | String yyyy = res.substring(0, idx); 51 | res = res.substring(idx + 1); 52 | idx = res.indexOf('-'); 53 | String MM = res.substring(0, idx); 54 | res = res.substring(idx + 1); 55 | idx = res.indexOf('-'); 56 | String dd = res.substring(0, idx); 57 | res = res.substring(idx + 1); 58 | idx = res.indexOf('-'); 59 | String hh = res.substring(0, idx); 60 | res = res.substring(idx + 1); 61 | idx = res.indexOf('-'); 62 | String mm = res.substring(0, idx); 63 | res = res.substring(idx + 1); 64 | idx = res.indexOf('-'); 65 | String ss = res.substring(0, idx); 66 | String tz = res.substring(idx + 1); 67 | int tz_int = tz.toInt(); 68 | int tz_mins = 60 * (tz_int / 100) + (tz_int % 100); 69 | dateTime.year = yyyy.toInt(); 70 | dateTime.month = MM.toInt(); 71 | dateTime.day = dd.toInt(); 72 | dateTime.hour = hh.toInt(); 73 | dateTime.minute = mm.toInt(); 74 | dateTime.second = ss.toInt(); 75 | if (pTZMins != NULL) { 76 | *pTZMins = tz_mins; 77 | } 78 | } 79 | 80 | 81 | #if defined(ESP32) 82 | void Esp32SetDateTime(const DDDateTime& dateTime, int tz_minuteswest, int tz_dsttime) { 83 | tm timeinfo; 84 | timeinfo.tm_year = dateTime.year - 1900; 85 | timeinfo.tm_mon = dateTime.month - 1; 86 | timeinfo.tm_mday = dateTime.day; 87 | timeinfo.tm_hour = dateTime.hour; 88 | timeinfo.tm_min = dateTime.minute; 89 | timeinfo.tm_sec = dateTime.second; 90 | time_t epoch = mktime(&timeinfo); 91 | int ms = 0; 92 | 93 | struct timeval tv; 94 | if (true) { 95 | tv.tv_sec = epoch; // epoch time (seconds) 96 | } else { 97 | bool overflow; 98 | if (epoch > 2082758399){ 99 | overflow = true; 100 | tv.tv_sec = epoch - 2082758399; // epoch time (seconds) 101 | } else { 102 | overflow = false; 103 | tv.tv_sec = epoch; // epoch time (seconds) 104 | } 105 | } 106 | tv.tv_usec = ms; 107 | timezone tz; 108 | tz.tz_minuteswest = tz_minuteswest; 109 | tz.tz_dsttime = tz_dsttime; 110 | settimeofday(&tv, &tz); 111 | } 112 | bool Esp32GetDateTime(DDDateTime& dateTime) { 113 | struct tm timeinfo; 114 | if (!getLocalTime(&timeinfo, 0)) { 115 | return false; 116 | } 117 | dateTime.year = timeinfo.tm_year + 1900; 118 | dateTime.month = timeinfo.tm_mon + 1; 119 | dateTime.day = timeinfo.tm_mday; 120 | dateTime.hour = timeinfo.tm_hour; 121 | dateTime.minute = timeinfo.tm_min; 122 | dateTime.second = timeinfo.tm_sec; 123 | return true; 124 | } 125 | #endif 126 | 127 | -------------------------------------------------------------------------------- /_dd_util.h: -------------------------------------------------------------------------------- 1 | #ifndef _dd_util_h 2 | #define _dd_util_h 3 | 4 | #define DD_CONNECT_FOR_GET_DATE_TIME "now:yyyy-MM-dd-HH-mm-ss-Z" 5 | class DDDateTime { 6 | public: 7 | DDDateTime(int year = 0, int month = 0, int day = 0, int hour = 0, int minute = 0, int second = 0): year(year), month(month), day(day), hour(hour), minute(minute), second(second) { 8 | } 9 | int year; 10 | int month; 11 | int day; 12 | int hour; 13 | int minute; 14 | int second; 15 | }; 16 | void DDParseGetDataTimeResponse(const String& response, DDDateTime& dateTime, int* pTZMins = NULL); 17 | 18 | #if defined(ESP32) 19 | void Esp32SetDateTime(const DDDateTime& dateTime, int tz_minuteswest = 0, int tz_dsttime = 0); 20 | bool Esp32GetDateTime(DDDateTime& dateTime); 21 | #endif 22 | 23 | 24 | void DDDebugOnly(int32_t i); 25 | 26 | 27 | char* _DDEncodeInt(int32_t i, char* buffer, int bufferLen); 28 | 29 | /// Class for internal use to encoding `int` parameters 30 | class DDIntEncoder { 31 | public: 32 | DDIntEncoder(int32_t i): str(_DDEncodeInt(i, buffer, 20)) { 33 | } 34 | inline const String& encoded() { return str; } 35 | private: 36 | char buffer[21]; 37 | String str; 38 | }; 39 | 40 | 41 | 42 | #endif -------------------------------------------------------------------------------- /ddatftutil.h: -------------------------------------------------------------------------------- 1 | // *** 2 | // * assume inclusion TFT_eSPI.h 3 | // *** 4 | 5 | //#include // Graphics and font library for ST7735 driver chip 6 | //#include 7 | 8 | #ifndef _dd_a_tft_util_h 9 | #define _dd_a_tft_util_h 10 | 11 | #include "_dd_misc.h" 12 | 13 | class AfTftDDDebugInterface: public DrawTextDDDebugInterface { 14 | public: 15 | AfTftDDDebugInterface(/*Adafruit_ST77xx*/Adafruit_SPITFT& tft, int x = 0, int y = 0/*, uint8_t fontSize = 2, uint8_t font = 1*/, bool indicateSendCommand = false): tft(tft) { 16 | this->x = x; 17 | this->y = y; 18 | //this->fontSize = fontSize; 19 | //this->font = font; 20 | this->indicateSendCommand = indicateSendCommand; 21 | } 22 | public: 23 | virtual void logSendCommand(int state) { 24 | if (indicateSendCommand) { 25 | tft.fillRect(x + 2, y + 2, x + 12, y + 12, 0xFFFF/*ST77XX_WHITE*/); 26 | if (state == 1) { 27 | tft.fillCircle(x + 7, y + 7, 5, 0xF800/*ST77XX_RED*/); 28 | } 29 | } 30 | } 31 | protected: 32 | virtual void drawText(const char* text, bool isError) { 33 | if (isError) { 34 | showMsg(text, 80); 35 | } else { 36 | showMsg(text, 16); 37 | } 38 | } 39 | private: 40 | void showMsg(const char* msg, int xOff) { 41 | //uint32_t textcolor = tft.textcolor; 42 | //uint32_t textbgcolor = tft.textbgcolor; 43 | //uint8_t textsize = tft.textsize; 44 | //tft.setTextColor(ST77XX_RED, ST77XX_WHITE); 45 | //tft.setTextSize(fontSize); 46 | //tft.drawString(msg, x + xOff, y, font); 47 | //tft.setTextColor(textcolor, textbgcolor); 48 | //tft.setTextSize(textsize); 49 | tft.setCursor(x + xOff, y); 50 | tft.print(msg); 51 | } 52 | private: 53 | Adafruit_SPITFT& tft; 54 | int x; 55 | int y; 56 | //uint8_t fontSize; 57 | //uint8_t font; 58 | bool indicateSendCommand; 59 | }; 60 | 61 | 62 | // class TftDDDebugInterface: public DDDebugInterface { 63 | // public: 64 | // TftDDDebugInterface(TFT_eSPI& tft, int x = 0, int y = 0, uint8_t fontSize = 2, uint8_t font = 1, bool indicateSendCommand = false): tft(tft) { 65 | // this->x = x; 66 | // this->y = y; 67 | // this->fontSize = fontSize; 68 | // this->font = font; 69 | // this->indicateSendCommand = indicateSendCommand; 70 | // } 71 | // public: 72 | // virtual void logConnectionState(DDDebugConnectionState connectionState) { 73 | // const char* state = NULL; 74 | // switch (connectionState) { 75 | // case DDDebugConnectionState::DEBUG_NOT_CONNECTED: 76 | // state = "NCed"; 77 | // break; 78 | // case DDDebugConnectionState::DEBUG_CONNECTING: 79 | // state = "Cing "; 80 | // break; 81 | // case DDDebugConnectionState::DEBUG_CONNECTED: 82 | // state = "Ced "; 83 | // break; 84 | // case DDDebugConnectionState::DEBUG_RECONNECTING: 85 | // state = "RCing"; 86 | // break; 87 | // case DDDebugConnectionState::DEBUG_RECONNECTED: 88 | // state = "RCed "; 89 | // break; 90 | // } 91 | // if (state != NULL) { 92 | // showMsg(state, 16); 93 | // } 94 | // } 95 | // virtual void logSendCommand(int state) { 96 | // if (indicateSendCommand) { 97 | // tft.fillRect(x + 2, y + 2, x + 12, y + 12, TFT_WHITE); 98 | // if (state == 1) { 99 | // tft.fillCircle(x + 7, y + 7, 5, TFT_RED); 100 | // } 101 | // } 102 | // } 103 | // virtual void logError(const String& errMsg) { 104 | // showMsg("Err", 80); 105 | // } 106 | // protected: 107 | // void showMsg(const char* msg, int xOff) { 108 | // uint32_t textcolor = tft.textcolor; 109 | // uint32_t textbgcolor = tft.textbgcolor; 110 | // uint8_t textsize = tft.textsize; 111 | // tft.setTextColor(TFT_RED, TFT_WHITE); 112 | // tft.setTextSize(fontSize); 113 | // tft.drawString(msg, x + xOff, y, font); 114 | // tft.setTextColor(textcolor, textbgcolor); 115 | // tft.setTextSize(textsize); 116 | // } 117 | // private: 118 | // TFT_eSPI& tft; 119 | // int x; 120 | // int y; 121 | // uint8_t fontSize; 122 | // uint8_t font; 123 | // bool indicateSendCommand; 124 | // }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /ddoledutil.h: -------------------------------------------------------------------------------- 1 | // *** 2 | // * assume inclusion Adafruit_SSD1306.h 3 | // *** 4 | //#include 5 | 6 | #ifndef _dd_oled_util_h 7 | #define _dd_oled_util_h 8 | 9 | 10 | class OledDDDebugInterface: public DrawTextDDDebugInterface { 11 | public: 12 | OledDDDebugInterface(Adafruit_SSD1306& display, int x = 0, int y = 0/*, uint8_t fontSize = 2, uint8_t font = 1, */, bool indicateSendCommand = false): display(display) { 13 | this->x = x; 14 | this->y = y; 15 | this->indicateSendCommand = indicateSendCommand; 16 | } 17 | public: 18 | virtual void logSendCommand(int state) { 19 | if (indicateSendCommand) { 20 | display.fillRect(x, y, x + 8, y + 8, WHITE); 21 | if (state == 1) { 22 | display.fillCircle(x + 4, y + 4, 4, BLACK); 23 | } 24 | display.display(); 25 | } 26 | } 27 | protected: 28 | virtual void drawText(const char* text, bool isError) { 29 | if (true) { 30 | if (isError) { 31 | showMsg(text, 70); 32 | } else { 33 | showMsg(text, 8); 34 | } 35 | } else { 36 | if (isError) { 37 | showMsg(text, 70); 38 | } else { 39 | showMsg(text, 12); 40 | } 41 | } 42 | } 43 | private: 44 | void showMsg(const char* msg, int xOff) { 45 | const int charWidth = 6; 46 | for (int i = 0;; i++) { 47 | char c = msg[i]; 48 | if (c == 0) { 49 | break; 50 | } 51 | display.drawChar(x + xOff + charWidth * i, y, c, WHITE, BLACK, 1); 52 | } 53 | display.display(); 54 | } 55 | private: 56 | Adafruit_SSD1306& display; 57 | int x; 58 | int y; 59 | bool indicateSendCommand; 60 | }; 61 | 62 | 63 | // class OledDDDebugInterface: public DDDebugInterface { 64 | // public: 65 | // OledDDDebugInterface(Adafruit_SSD1306& display, int x = 0, int y = 0/*, uint8_t fontSize = 2, uint8_t font = 1, */, bool indicateSendCommand = false): display(display) { 66 | // this->x = x; 67 | // this->y = y; 68 | // //this->fontSize = fontSize; 69 | // //this->font = font; 70 | // this->indicateSendCommand = indicateSendCommand; 71 | // } 72 | // public: 73 | // virtual void logConnectionState(DDDebugConnectionState connectionState) { 74 | // const char* state = NULL; 75 | // switch (connectionState) { 76 | // case DDDebugConnectionState::DEBUG_NOT_CONNECTED: 77 | // state = "NCed"; 78 | // break; 79 | // case DDDebugConnectionState::DEBUG_CONNECTING: 80 | // state = "Cing "; 81 | // break; 82 | // case DDDebugConnectionState::DEBUG_CONNECTED: 83 | // state = "Ced "; 84 | // break; 85 | // case DDDebugConnectionState::DEBUG_RECONNECTING: 86 | // state = "RCing"; 87 | // break; 88 | // case DDDebugConnectionState::DEBUG_RECONNECTED: 89 | // state = "RCed "; 90 | // break; 91 | // } 92 | // if (state != NULL) { 93 | // showMsg(state, 12/*16*/); 94 | // } 95 | // } 96 | // virtual void logSendCommand(int state) { 97 | // if (indicateSendCommand) { 98 | // display.fillRect(x, y, x + 8, y + 8, WHITE); 99 | // if (state == 1) { 100 | // display.fillCircle(x + 4, y + 4, 4, BLACK); 101 | // } 102 | // display.display(); 103 | // // display.fillRect(x + 2, y + 2, x + 12, y + 12, WHITE); 104 | // // if (state == 1) { 105 | // // display.fillCircle(x + 7, y + 7, 5, BLACK); 106 | // // } 107 | // // display.display(); 108 | // } 109 | // } 110 | // virtual void logError(const String& errMsg) { 111 | // showMsg("Err", 70/*80*/); 112 | // } 113 | // private: 114 | // void showMsg(const char* msg, int xOff) { 115 | // const int charWidth = 6; 116 | // for (int i = 0;; i++) { 117 | // char c = msg[i]; 118 | // if (c == 0) { 119 | // break; 120 | // } 121 | // display.drawChar(x + xOff + charWidth * i, y, c, WHITE, BLACK, 1); 122 | // } 123 | // display.display(); 124 | // } 125 | // private: 126 | // Adafruit_SSD1306& display; 127 | // int x; 128 | // int y; 129 | // bool indicateSendCommand; 130 | // }; 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /ddtester.h: -------------------------------------------------------------------------------- 1 | #ifndef ddtester_h 2 | #define ddtester_h 3 | 4 | #include "dumbdisplay.h" 5 | 6 | 7 | // #if __GNUC__ >= 8 8 | // void BasicDDTestLoop(DumbDisplay& dumbdisplay, bool passiveConnect = false, int builtinLEDPin = -1, std::function notConnectedCallback = NULL); 9 | // #else 10 | void BasicDDTestLoop(DumbDisplay& dumbdisplay, bool passiveConnect = false, int builtinLEDPin = -1, void (*notConnectedCallback)(bool) = NULL); 11 | //#endif 12 | 13 | #endif -------------------------------------------------------------------------------- /ddtester_0.h: -------------------------------------------------------------------------------- 1 | #ifndef ddtester_h 2 | #define ddtester_h 3 | 4 | #include "dumbdisplay.h" 5 | 6 | 7 | void BasicDDTestLoop(DumbDisplay& dumbdisplay, bool forDebugging = false); 8 | 9 | 10 | #endif -------------------------------------------------------------------------------- /ddtftutil.h: -------------------------------------------------------------------------------- 1 | // *** 2 | // * assume inclusion TFT_eSPI.h 3 | // *** 4 | 5 | //#include // Graphics and font library for ST7735 driver chip 6 | 7 | #ifndef _dd_tft_util_h 8 | #define _dd_tft_util_h 9 | 10 | #include "_dd_misc.h" 11 | 12 | class TftDDDebugInterface: public DrawTextDDDebugInterface { 13 | public: 14 | TftDDDebugInterface(TFT_eSPI& tft, int x = 0, int y = 0, uint8_t fontSize = 2, uint8_t font = 1, bool indicateSendCommand = false): tft(tft) { 15 | this->x = x; 16 | this->y = y; 17 | this->fontSize = fontSize; 18 | this->font = font; 19 | this->indicateSendCommand = indicateSendCommand; 20 | } 21 | public: 22 | virtual void logSendCommand(int state) { 23 | if (indicateSendCommand) { 24 | if (true) { 25 | tft.fillRect(x, y, x + 10, y + 10, TFT_WHITE); 26 | if (state == 1) { 27 | tft.fillCircle(x + 5, y + 5, 5, TFT_RED); 28 | } 29 | } else { 30 | tft.fillRect(x + 2, y + 2, x + 12, y + 12, TFT_WHITE); 31 | if (state == 1) { 32 | tft.fillCircle(x + 7, y + 7, 5, TFT_RED); 33 | } 34 | } 35 | } 36 | } 37 | protected: 38 | virtual void drawText(const char* text, bool isError) { 39 | if (true) { 40 | if (isError) { 41 | showMsg(text, 80); 42 | } else { 43 | showMsg(text, 10); 44 | } 45 | } else { 46 | if (isError) { 47 | showMsg(text, 80); 48 | } else { 49 | showMsg(text, 16); 50 | } 51 | } 52 | } 53 | private: 54 | void showMsg(const char* msg, int xOff) { 55 | uint32_t textcolor = tft.textcolor; 56 | uint32_t textbgcolor = tft.textbgcolor; 57 | uint8_t textsize = tft.textsize; 58 | tft.setTextColor(TFT_RED, TFT_WHITE); 59 | tft.setTextSize(fontSize); 60 | tft.drawString(msg, x + xOff, y, font); 61 | tft.setTextColor(textcolor, textbgcolor); 62 | tft.setTextSize(textsize); 63 | } 64 | protected: 65 | TFT_eSPI& tft; 66 | int x; 67 | int y; 68 | uint8_t fontSize; 69 | uint8_t font; 70 | bool indicateSendCommand; 71 | }; 72 | 73 | 74 | // class TftDDDebugInterface: public DDDebugInterface { 75 | // public: 76 | // TftDDDebugInterface(TFT_eSPI& tft, int x = 0, int y = 0, uint8_t fontSize = 2, uint8_t font = 1, bool indicateSendCommand = false): tft(tft) { 77 | // this->x = x; 78 | // this->y = y; 79 | // this->fontSize = fontSize; 80 | // this->font = font; 81 | // this->indicateSendCommand = indicateSendCommand; 82 | // } 83 | // public: 84 | // virtual void logConnectionState(DDDebugConnectionState connectionState) { 85 | // const char* state = NULL; 86 | // switch (connectionState) { 87 | // case DDDebugConnectionState::DEBUG_NOT_CONNECTED: 88 | // state = "NCed"; 89 | // break; 90 | // case DDDebugConnectionState::DEBUG_CONNECTING: 91 | // state = "Cing "; 92 | // break; 93 | // case DDDebugConnectionState::DEBUG_CONNECTED: 94 | // state = "Ced "; 95 | // break; 96 | // case DDDebugConnectionState::DEBUG_RECONNECTING: 97 | // state = "RCing"; 98 | // break; 99 | // case DDDebugConnectionState::DEBUG_RECONNECTED: 100 | // state = "RCed "; 101 | // break; 102 | // } 103 | // if (state != NULL) { 104 | // showMsg(state, 16); 105 | // } 106 | // } 107 | // virtual void logSendCommand(int state) { 108 | // if (indicateSendCommand) { 109 | // tft.fillRect(x + 2, y + 2, x + 12, y + 12, TFT_WHITE); 110 | // if (state == 1) { 111 | // tft.fillCircle(x + 7, y + 7, 5, TFT_RED); 112 | // } 113 | // } 114 | // } 115 | // virtual void logError(const String& errMsg) { 116 | // showMsg("Err", 80); 117 | // } 118 | // protected: 119 | // void showMsg(const char* msg, int xOff) { 120 | // uint32_t textcolor = tft.textcolor; 121 | // uint32_t textbgcolor = tft.textbgcolor; 122 | // uint8_t textsize = tft.textsize; 123 | // tft.setTextColor(TFT_RED, TFT_WHITE); 124 | // tft.setTextSize(fontSize); 125 | // tft.drawString(msg, x + xOff, y, font); 126 | // tft.setTextColor(textcolor, textbgcolor); 127 | // tft.setTextSize(textsize); 128 | // } 129 | // private: 130 | // TFT_eSPI& tft; 131 | // int x; 132 | // int y; 133 | // uint8_t fontSize; 134 | // uint8_t font; 135 | // bool indicateSendCommand; 136 | // }; 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /esp32dumbdisplay.h: -------------------------------------------------------------------------------- 1 | //************************************************// 2 | //*** must define DD_4_ESP32 before including ***/ 3 | //************************************************// 4 | 5 | #ifndef esp32dumbdisplay_h 6 | #define esp32dumbdisplay_h 7 | 8 | // after inclusion, can check DD_USING_WIFI to be sure WIFI is used 9 | #define DD_USING_BT 10 | 11 | // #ifndef DD_4_ESP32 12 | // #error DD_4_ESP32 need be defined in order to use DumbDisplay for ESP32 13 | // #else 14 | 15 | #ifndef ESP32 16 | #error DDBluetoothSerialIO is for ESP32 17 | #endif 18 | 19 | //#else 20 | 21 | 22 | #include "BluetoothSerial.h" 23 | #include "dumbdisplay.h" 24 | 25 | 26 | /// Subclass of DDInputOutput 27 | class DDBluetoothSerialIO: public DDInputOutput { 28 | public: 29 | /* ESP32 BluetoothSerial IO mechanism */ 30 | /* - btLocalName -- BT name */ 31 | /* - enableSerial: enable Serial as well or not (if enabled, connecting via USB will also work) */ 32 | /* - serialBaud: Serial baud rate (if enableSerial) */ 33 | DDBluetoothSerialIO(const String& btLocalName, bool enableSerial = false, 34 | unsigned long serialBaud = DD_SERIAL_BAUD): 35 | DDInputOutput(serialBaud, enableSerial, enableSerial) { 36 | this->btLocalName = btLocalName; 37 | // if (!enableSerial) { // disabled since 2023-08-13 38 | // Serial.begin(serialBaud); 39 | // } 40 | } 41 | const char* getWhat() { 42 | return "ESP32BT"; 43 | } 44 | bool available() { 45 | return serialBT.available(); 46 | } 47 | char read() { 48 | return serialBT.read(); 49 | } 50 | void print(const String &s) { 51 | serialBT.print(s); 52 | } 53 | void print(const char *p) { 54 | serialBT.print(p); 55 | } 56 | void write(uint8_t b) { 57 | serialBT.write(b); 58 | } 59 | void write(const uint8_t *buf, size_t size) { 60 | serialBT.write(buf, size); 61 | } 62 | bool preConnect(bool firstCall) { 63 | DDInputOutput::preConnect(firstCall); 64 | serialBT.begin(btLocalName); 65 | if (!willUseSerial()) { // since 2024-08-13 66 | if (firstCall) { 67 | if (!Serial) Serial.begin(DD_SERIAL_BAUD); 68 | } 69 | String address = serialBT.getBtAddressString(); 70 | address.toUpperCase(); 71 | Serial.println("bluetooth address: " + address); 72 | } 73 | return true; 74 | } 75 | void flush() { 76 | if (false) { 77 | serialBT.flush(); // not the expected "flush" 78 | } 79 | } 80 | bool canConnectPassive() { 81 | return true; 82 | } 83 | bool canUseBuffer() { 84 | return true; 85 | } 86 | private: 87 | String btLocalName; 88 | BluetoothSerial serialBT; 89 | }; 90 | 91 | 92 | //#endif 93 | #endif -------------------------------------------------------------------------------- /examples/otg7segment/otg7segment.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related blog post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | 20 | #include "dumbdisplay.h" 21 | 22 | 23 | // create the DumbDisplay object; assuming USB connection with 115200 baud 24 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 25 | 26 | 27 | // declare a 7-segment layer object, to be created in setup() 28 | SevenSegmentRowDDLayer *sevenSeg; 29 | 30 | 31 | void setup() { 32 | // create the 7-segment layer object, with only a single 7-segment digit 33 | sevenSeg = dumbdisplay.create7SegmentRowLayer(); 34 | } 35 | 36 | void loop() { 37 | for (int digit = 0; digit < 10; digit++) { 38 | // show the digit on the 7-segment 39 | sevenSeg->showNumber(digit); 40 | 41 | // delay a second 42 | delay(1000); 43 | } 44 | } 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/otgblink/otgblink.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | 20 | #include "dumbdisplay.h" 21 | 22 | 23 | // create the DumbDisplay object; assuming USB connection with the default 115200 baud 24 | DumbDisplay dumbdisplay(new DDInputOutput()); 25 | 26 | // declare a LED layer object, to be created in setup() 27 | LedGridDDLayer *led; 28 | 29 | 30 | void setup() { 31 | // create the LED layer object, with only a single LED 32 | led = dumbdisplay.createLedGridLayer(); 33 | } 34 | 35 | 36 | void loop() { 37 | // toggle the LED 38 | led->toggle(); 39 | 40 | // delay for a second 41 | delay(1000); 42 | } 43 | -------------------------------------------------------------------------------- /examples/otgfonts/otgfonts.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Sorry! Very likely, this sketch will not work for less-capable boards like Arduino Uno, Nano, etc. 3 | */ 4 | 5 | /** 6 | * If BLUETOOTH is #defined, it uses ESP32 bluetooth connection 7 | * . BLUETOOTH is the name of the bluetooth device 8 | * If WIFI_SSID is #defined, it uses wifi connection 9 | * . once sketch running, connect to it with Serial Monitor to check for IP address 10 | * Otherwise, it uses USB connection (OTG) with the default 115200 baud 11 | * . you will need to install Android DumbDisplay app from Play store 12 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 13 | * . although there are several ways for microcontroller board to establish connection 14 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 15 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 16 | * to your Android phone 17 | * . after uploading the sketch to your microcontroller board, plug the USB cable 18 | * to the OTG adaptor connected to your Android phone 19 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 20 | * hopefully, the UI is obvious enough :) 21 | * . for more details on DumbDisplay Arduino Library, please refer to 22 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 23 | * There is a related post that you may want to take a look: 24 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 25 | */ 26 | 27 | 28 | #include "dumbdisplay.h" 29 | 30 | #if defined(BLUETOOTH) 31 | #include "esp32dumbdisplay.h" 32 | DumbDisplay dumbdisplay(new DDBluetoothSerialIO(BLUETOOTH, true)); 33 | #elif defined(WIFI_SSID) 34 | #include "wifidumbdisplay.h" 35 | DumbDisplay dumbdisplay(new DDWiFiServerIO(WIFI_SSID, WIFI_PASSWORD)); 36 | #else 37 | #include "dumbdisplay.h" 38 | DumbDisplay dumbdisplay(new DDInputOutput()); 39 | #endif 40 | 41 | 42 | 43 | void setup() { 44 | 45 | // create a graphical [LCD] layer 46 | GraphicalDDLayer *graphical = dumbdisplay.createGraphicalLayer(150, 300); 47 | graphical->backgroundColor("lightgray"); 48 | graphical->setTextColor("blue"); 49 | 50 | // the list of support downloadable fonts 51 | const int fontCount = 8; 52 | const String fonts[8] = { "B612", "Cutive", "Noto Sans", "Oxygen", "Roboto", "Share Tech", "Spline Sans", "Ubuntu" }; 53 | 54 | // show font samples regular 55 | graphical->setTextFont(); 56 | graphical->println("REGULAR:"); 57 | for (int i = 0; i < fontCount; i++) { 58 | graphical->setTextFont(); 59 | graphical->print(". "); 60 | const String& fontName = fonts[i]; // font-name like: Roboto 61 | graphical->setTextFont("DL::" + fontName); // add prefix "DL::" 62 | graphical->println(fontName); 63 | } 64 | 65 | // show font samples monospace 66 | graphical->setTextFont(); 67 | graphical->println(); 68 | graphical->println("MONOSPACE:"); 69 | for (int i = 0; i < fontCount; i++) { 70 | graphical->setTextFont(); 71 | graphical->print(". "); 72 | String fontName = fonts[i] + " Mono"; // font-name like: Roboto Mono 73 | graphical->setTextFont("DL::" + fontName); // add prefix "DL:" 74 | graphical->println(fontName); 75 | } 76 | } 77 | 78 | void loop() { 79 | 80 | } 81 | -------------------------------------------------------------------------------- /examples/otgkeypad/otgkeypad.ino: -------------------------------------------------------------------------------- 1 | // ***** 2 | // * due to large amount of data to transfer, this sketch will not work correctly with Arduino UNO ... try with ESP32 3 | // ***** 4 | 5 | /** 6 | * to run and see the result of this sketch, you will need two addition things: 7 | * . you will need to install Android DumbDisplay app from Play store 8 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 9 | * . although there are several ways for microcontroller board to establish connection 10 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 11 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 12 | * to your Android phone 13 | * . after uploading the sketch to your microcontroller board, plug the USB cable 14 | * to the OTG adaptor connected to your Android phone 15 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 16 | * hopefully, the UI is obvious enough :) 17 | * . for more details on DumbDisplay Arduino Library, please refer to 18 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 19 | * there is a related post that you may want to take a look: 20 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 21 | */ 22 | 23 | #include "dumbdisplay.h" 24 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 25 | 26 | const char Keys[4][3] = { 27 | {'1', '2', '3'}, 28 | {'4', '5', '6'}, 29 | {'7', '8', '9'}, 30 | {'*', '0', '#'}}; 31 | 32 | LcdDDLayer *keyLayers[4][3]; 33 | 34 | 35 | // to be defined later in the sketch 36 | LcdDDLayer *CreateKeyLayer(int r, int c); 37 | // to be defined later in the sketch 38 | char CheckKeyPressed(); 39 | 40 | 41 | void setup() { 42 | // will only allow single click, which also makes clicking more responsive 43 | dumbdisplay.setFeedbackSingleClickOnly(); 44 | 45 | // loop through the keys and create the corresponding LCD layer [for each on of the key] 46 | for (int r = 0; r < 4; r++) { 47 | for (int c = 0; c < 3; c++) { 48 | LcdDDLayer *keyLayer = CreateKeyLayer(r, c); 49 | keyLayers[r][c] = keyLayer; 50 | } 51 | } 52 | 53 | // auto "pin" the key LCD layers int the desired way -- 4 rows by 3 columns 54 | dumbdisplay.configAutoPin(DD_AP_VERT_4( 55 | DD_AP_HORI_3(keyLayers[0][0]->getLayerId(), keyLayers[0][1]->getLayerId(), keyLayers[0][2]->getLayerId()), 56 | DD_AP_HORI_3(keyLayers[1][0]->getLayerId(), keyLayers[1][1]->getLayerId(), keyLayers[1][2]->getLayerId()), 57 | DD_AP_HORI_3(keyLayers[2][0]->getLayerId(), keyLayers[2][1]->getLayerId(), keyLayers[2][2]->getLayerId()), 58 | DD_AP_HORI_3(keyLayers[3][0]->getLayerId(), keyLayers[3][1]->getLayerId(), keyLayers[3][2]->getLayerId()))); 59 | } 60 | 61 | void loop() { 62 | char keyPressed = CheckKeyPressed(); 63 | if (keyPressed != 0) { 64 | dumbdisplay.writeComment("key [" + String(keyPressed) + "]"); 65 | } 66 | } 67 | 68 | // create key LCD layer; key defined by r and c 69 | LcdDDLayer *CreateKeyLayer(int r, int c) { 70 | String key = String(Keys[r][c]); 71 | LcdDDLayer *keyLayer = dumbdisplay.createLcdLayer(1, 1, 32); 72 | keyLayer->pixelColor("navy"); 73 | keyLayer->border(5, "darkgray", "raised"); 74 | keyLayer->padding(1); 75 | keyLayer->writeLine(key); 76 | keyLayer->enableFeedback("fl"); 77 | keyLayer->customData = key; // set the key to the "custom data" of the layer 78 | return keyLayer; 79 | } 80 | 81 | // check if any key is pressed; return the key pressed, or 0 if none 82 | char CheckKeyPressed() { 83 | // loop through the key LCD layers and check if any one has "feedback" (i.e. pressed) 84 | for (int r = 0; r < 4; r++) { 85 | for (int c = 0; c < 3; c++) { 86 | LcdDDLayer* keyLayer = keyLayers[r][c]; 87 | const DDFeedback* feedback = keyLayer->getFeedback(); 88 | if (feedback != NULL) { 89 | char keyPressed = keyLayer->customData.charAt(0); 90 | return keyPressed; 91 | } 92 | } 93 | } 94 | return 0; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /examples/otgkeypad_callback/otgkeypad_callback.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | #include "dumbdisplay.h" 20 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 21 | 22 | const char Keys[4][3] = { 23 | {'1', '2', '3'}, 24 | {'4', '5', '6'}, 25 | {'7', '8', '9'}, 26 | {'*', '0', '#'}}; 27 | 28 | LcdDDLayer *keyLayers[4][3]; 29 | 30 | 31 | // to be defined later in the sketch 32 | LcdDDLayer *CreateKeyLayer(int r, int c); 33 | 34 | 35 | void setup() 36 | { 37 | // loop through the keys and create the corresponding LCD layer [for each on of the key] 38 | for (int r = 0; r < 4; r++) 39 | { 40 | for (int c = 0; c < 3; c++) 41 | { 42 | LcdDDLayer *keyLayer = CreateKeyLayer(r, c); 43 | keyLayers[r][c] = keyLayer; 44 | } 45 | } 46 | // auto "pin" the key LCD layers int the desired way -- 4 rows by 3 columns 47 | dumbdisplay.configAutoPin(DD_AP_VERT_4( 48 | DD_AP_HORI_3(keyLayers[0][0]->getLayerId(), keyLayers[0][1]->getLayerId(), keyLayers[0][2]->getLayerId()), 49 | DD_AP_HORI_3(keyLayers[1][0]->getLayerId(), keyLayers[1][1]->getLayerId(), keyLayers[1][2]->getLayerId()), 50 | DD_AP_HORI_3(keyLayers[2][0]->getLayerId(), keyLayers[2][1]->getLayerId(), keyLayers[2][2]->getLayerId()), 51 | DD_AP_HORI_3(keyLayers[3][0]->getLayerId(), keyLayers[3][1]->getLayerId(), keyLayers[3][2]->getLayerId()))); 52 | } 53 | 54 | void loop() 55 | { 56 | DDYield(); // need to call this so that DumbDisplay lib can check for "feedback" 57 | } 58 | 59 | // "feedback" handler 60 | void FeedbackHandler(DDLayer *pLayer, DDFeedbackType type, const DDFeedback &feedback) 61 | { 62 | if (type == DDFeedbackType::CLICK) 63 | { 64 | char key = pLayer->customData.charAt(0); 65 | dumbdisplay.writeComment("key [" + String(key) + "]"); 66 | } 67 | } 68 | 69 | // create key LCD layer; key defined by r and c 70 | LcdDDLayer *CreateKeyLayer(int r, int c) 71 | { 72 | String key = String(Keys[r][c]); 73 | LcdDDLayer *keyLayer = dumbdisplay.createLcdLayer(1, 1, 32); 74 | keyLayer->pixelColor("navy"); 75 | keyLayer->border(5, "darkgray", "raised"); 76 | keyLayer->padding(1); 77 | keyLayer->writeLine(key); 78 | keyLayer->setFeedbackHandler(FeedbackHandler, "fl"); // set the "feedback" handler 79 | keyLayer->customData = key; // set the key to the "custom data" of the layer 80 | return keyLayer; 81 | } 82 | -------------------------------------------------------------------------------- /examples/otgledmatrix/otgledmatrix.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | 20 | #include "dumbdisplay.h" 21 | 22 | // create the DumbDisplay object; assuming USB connection with the default 115200 baud 23 | DumbDisplay dumbdisplay(new DDInputOutput()); 24 | 25 | // declare a Microbit-like layer object, to be created in setup() 26 | MbDDLayer* mb; 27 | 28 | 29 | 30 | // "feedback" handler ... to be referred to in setup() 31 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback) { 32 | // got a click on (x, y) ... toggle it 33 | mb->toggle(feedback.x, feedback.y); 34 | } 35 | 36 | 37 | void setup() { 38 | // create the Microbit-like layer with size 10x10 39 | mb = dumbdisplay.createMicrobitLayer(10, 10); 40 | 41 | // Create a boarder around the layer (size 0.5 ~= 5% of a dot) 42 | mb->border(0.5, "black"); 43 | 44 | // setup "callback" function to handle "feedback" event-driven -- auto flashing the clicked area 45 | mb->setFeedbackHandler(FeedbackHandler, "fa"); 46 | } 47 | 48 | void loop() { 49 | // give DD a chance to capture "feedback" ... needed for event-driven "feedback" handling 50 | DDYield(); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /examples/otgrest/otgrest.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Sorry! Very likely, this sketch will not work for less-capable boards like Arduino Uno, Nano, etc. 3 | */ 4 | 5 | /** 6 | * If BLUETOOTH is #defined, it uses ESP32 bluetooth connection 7 | * . BLUETOOTH is the name of the bluetooth device 8 | * If WIFI_SSID is #defined, it uses wifi connection 9 | * . once sketch running, connect to it with Serial Monitor to check for IP address 10 | * Otherwise, it uses USB connection (OTG) with the default 115200 baud 11 | * . you will need to install Android DumbDisplay app from Play store 12 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 13 | * . although there are several ways for microcontroller board to establish connection 14 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 15 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 16 | * to your Android phone 17 | * . after uploading the sketch to your microcontroller board, plug the USB cable 18 | * to the OTG adaptor connected to your Android phone 19 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 20 | * hopefully, the UI is obvious enough :) 21 | * . for more details on DumbDisplay Arduino Library, please refer to 22 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 23 | * There is a related post that you may want to take a look: 24 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 25 | */ 26 | 27 | 28 | 29 | #include "dumbdisplay.h" 30 | 31 | 32 | // create the DumbDisplay object; assuming USB connection with 115200 baud 33 | DumbDisplay dumbdisplay(new DDInputOutput()); 34 | 35 | // declare a graphical layer object, to be created in setup() 36 | GraphicalDDLayer *graphicalLayer; 37 | // declare a tunnel object, to be created in setup() 38 | JsonDDTunnel *restTunnel; 39 | 40 | 41 | void setup() { 42 | // setup a "graphical" layer with size 350x150 43 | graphicalLayer = dumbdisplay.createGraphicalLayer(350, 150); 44 | graphicalLayer->backgroundColor("yellow"); // set background color to yellow 45 | graphicalLayer->border(10, "blue", "round"); // a round blue border of size 10 46 | graphicalLayer->penColor("red"); // set pen color 47 | 48 | // setup a "tunnel" to get "current time" JSON data; suggest to specify the buffer size to be the same as fields wanted 49 | restTunnel = dumbdisplay.createFilteredJsonTunnel("http://worldtimeapi.org/api/timezone/Asia/Hong_Kong", "client_ip,timezone,datetime,utc_datetime", true, 4); 50 | 51 | graphicalLayer->println(); 52 | graphicalLayer->println("-----"); 53 | while (!restTunnel->eof()) { // check that not EOF (i.e. something still coming) 54 | while (restTunnel->count() > 0) { // check that received something 55 | String fieldId; 56 | String fieldValue; 57 | restTunnel->read(fieldId, fieldValue); // read whatever received 58 | dumbdisplay.writeComment(fieldId + "=" + fieldValue); // write out that whatever to DD app as comment 59 | if (fieldId == "client_ip" || fieldId == "timezone" || fieldId == "datetime" || fieldId == "utc_datetime") { 60 | // if the expected field, print it out 61 | graphicalLayer->print(fieldId); 62 | graphicalLayer->print("="); 63 | graphicalLayer->println(fieldValue); 64 | } 65 | } 66 | } 67 | graphicalLayer->println("-----"); 68 | } 69 | 70 | void loop() { 71 | } 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/otgrgb/otgrgb.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | 20 | /****** 21 | ****** 22 | * Due to the large amount of data exchanged between the microcontroller board and the DumbDisplay app, 23 | * strongly suggest to turn off DumbDisplay app's "show commands"! 24 | ****** 25 | ****** 26 | */ 27 | 28 | 29 | #include "dumbdisplay.h" 30 | 31 | 32 | // create the DumbDisplay object; assuming USB connection with 115200 baud 33 | DumbDisplay dumbdisplay(new DDInputOutput()); 34 | 35 | // declare a graphical layer object to show the selected color; to be created in setup() 36 | GraphicalDDLayer *colorLayer; 37 | // declare the R "slider" layer 38 | JoystickDDLayer *rSliderLayer; 39 | // declare the G "slider" layer 40 | JoystickDDLayer *gSliderLayer; 41 | // declare the B "slider" layer 42 | JoystickDDLayer *bSliderLayer; 43 | 44 | 45 | int r = 0; 46 | int g = 0; 47 | int b = 0; 48 | 49 | 50 | void setup() { 51 | // create the "selected color" layer 52 | colorLayer = dumbdisplay.createGraphicalLayer(350, 150); 53 | colorLayer->border(5, "black", "round", 2); 54 | 55 | // create the R "slider" layer 56 | rSliderLayer = dumbdisplay.createJoystickLayer(255, "hori", 0.5); 57 | rSliderLayer->border(3, "darkred", "round", 1); 58 | rSliderLayer->colors("red", DD_RGB_COLOR(0xff, 0x44, 0x44), "black", "darkgray"); 59 | 60 | // create the G "slider" layer 61 | gSliderLayer = dumbdisplay.createJoystickLayer(255, "hori", 0.5); 62 | gSliderLayer->border(3, "darkgreen", "round", 1); 63 | gSliderLayer->colors("green", DD_RGB_COLOR(0x44, 0xff, 0x44), "black", "darkgray"); 64 | 65 | // create the B "slider" layer 66 | bSliderLayer = dumbdisplay.createJoystickLayer(255, "hori", 0.5); 67 | bSliderLayer->border(3, "darkblue", "round", 1); 68 | bSliderLayer->colors("blue", DD_RGB_COLOR(0x44, 0x44, 0xff), "black", "darkgray"); 69 | 70 | // "auto pin" the layers vertically 71 | dumbdisplay.configAutoPin(DD_AP_VERT); 72 | 73 | colorLayer->backgroundColor(DD_RGB_COLOR(r, g, b)); 74 | } 75 | 76 | void loop() { 77 | int oldR = r; 78 | int oldG = g; 79 | int oldB = b; 80 | 81 | const DDFeedback* fb; 82 | 83 | fb = rSliderLayer->getFeedback(); 84 | if (fb != NULL) { 85 | r = fb->x; 86 | } 87 | fb = gSliderLayer->getFeedback(); 88 | if (fb != NULL) { 89 | g = fb->x; 90 | } 91 | fb = bSliderLayer->getFeedback(); 92 | if (fb != NULL) { 93 | b = fb->x; 94 | } 95 | 96 | if (r != oldR || g != oldG || b != oldB) { 97 | colorLayer->backgroundColor(DD_RGB_COLOR(r, g, b)); 98 | } 99 | 100 | } 101 | 102 | -------------------------------------------------------------------------------- /examples/otgsound/otgsound.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * to run and see the result of this sketch, you will need two addition things: 4 | * . you will need to install Android DumbDisplay app from Play store 5 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 6 | * . although there are several ways for microcontroller board to establish connection 7 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 8 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 9 | * to your Android phone 10 | * . after uploading the sketch to your microcontroller board, plug the USB cable 11 | * to the OTG adaptor connected to your Android phone 12 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 13 | * hopefully, the UI is obvious enough :) 14 | * . for more details on DumbDisplay Arduino Library, please refer to 15 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 16 | * there is a related post that you may want to take a look: 17 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 18 | */ 19 | 20 | 21 | #include "dumbdisplay.h" 22 | 23 | 24 | // create the DumbDisplay object; assuming USB connection with 115200 baud 25 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 26 | 27 | 28 | // declare "YES" / "NO" lcd layers, acting as buttons ... they will be created in setup blick 29 | LcdDDLayer* yesLayer; 30 | LcdDDLayer* noLayer; 31 | 32 | 33 | void setup() { 34 | // create "YES" lcd layer, acting as a button 35 | yesLayer = dumbdisplay.createLcdLayer(16, 3); 36 | yesLayer->writeCenteredLine("YES", 1); 37 | yesLayer->border(3, "green", "round"); 38 | yesLayer->enableFeedback("fl"); // enable "feedback" ... i.e. it can be clicked 39 | 40 | // create "NO" lcd layer, acting as a button 41 | noLayer = dumbdisplay.createLcdLayer(16, 3); 42 | noLayer->writeCenteredLine("NO", 1); 43 | noLayer->border(3, "red", "round"); 44 | noLayer->enableFeedback("fl"); // enable "feedback" ... i.e. it can be clicked 45 | 46 | // auto "pin" the two layers vertically, one above the other 47 | dumbdisplay.configAutoPin(DD_AP_VERT); 48 | 49 | } 50 | 51 | void loop() { 52 | // check if "YES" clicked 53 | if (yesLayer->getFeedback()) { 54 | // if so, play the pre-installed "YES" WAV file 55 | dumbdisplay.playSound("voice_yes.wav"); 56 | } 57 | 58 | // check if "NO" clicked 59 | if (noLayer->getFeedback()) { 60 | // if so, play the pre-installed "NO" WAV file 61 | dumbdisplay.playSound("voice_no.wav"); 62 | } 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /examples/otgwebimage/otgwebimage.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * to run and see the result of this sketch, you will need two addition things: 3 | * . you will need to install Android DumbDisplay app from Play store 4 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 5 | * . although there are several ways for microcontroller board to establish connection 6 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 7 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 8 | * to your Android phone 9 | * . after uploading the sketch to your microcontroller board, plug the USB cable 10 | * to the OTG adaptor connected to your Android phone 11 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 12 | * hopefully, the UI is obvious enough :) 13 | * . for more details on DumbDisplay Arduino Library, please refer to 14 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 15 | * there is a related post that you may want to take a look: 16 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 17 | */ 18 | 19 | 20 | #include "dumbdisplay.h" 21 | 22 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 23 | 24 | 25 | GraphicalDDLayer *graphical; 26 | SimpleToolDDTunnel *tunnel_unlocked; 27 | SimpleToolDDTunnel *tunnel_locked; 28 | 29 | void setup() { 30 | // create a graphical layer for drawing the web images to 31 | graphical = dumbdisplay.createGraphicalLayer(200, 300); 32 | 33 | // create tunnels for downloading web images ... and save to your phone ... optionally: in order to send less duplicated data (in URL), create a map entry for R 34 | tunnel_unlocked = dumbdisplay.createImageDownloadTunnel("https://${R=raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/master/screenshots}/lock-unlocked.png", "lock-unlocked.png"); 35 | tunnel_locked = dumbdisplay.createImageDownloadTunnel("https://${R}/lock-locked.png", "lock-locked.png"); 36 | } 37 | 38 | bool locked = false; 39 | void loop() { 40 | // get result whether web image downloaded .. 0: downloading; 1: downloaded ok; -1: failed to download 41 | int result_unlocked = tunnel_unlocked->checkResult(); 42 | int result_locked = tunnel_locked->checkResult(); 43 | 44 | int result; 45 | const char* image_file_name; 46 | if (locked) { 47 | image_file_name = "lock-locked.png"; 48 | result = result_locked; 49 | } else { 50 | image_file_name = "lock-unlocked.png"; 51 | result = result_unlocked; 52 | } 53 | if (result == 1) { 54 | graphical->drawImageFile(image_file_name); 55 | } else if (result == 0) { 56 | // downloading 57 | graphical->clear(); 58 | graphical->setCursor(0, 10); 59 | graphical->println("... ..."); 60 | graphical->println(image_file_name); 61 | graphical->println("... ..."); 62 | } else if (result == -1) { 63 | graphical->clear(); 64 | graphical->setCursor(0, 10); 65 | graphical->println("XXX failed to download XXX"); 66 | } 67 | locked = !locked; 68 | delay(1000); 69 | } 70 | -------------------------------------------------------------------------------- /examples/otgwebimage_2/otgwebimage_2.ino: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * this is an extension to otgwebimage example; so, you want to try that one first 4 | * . the web image is actually a lock, two web images are downloaded 5 | * . one for unlocked 6 | * . one for locked 7 | * . it has an additional LCD text on to show the status of the lock (locked or unlocked) 8 | * . after all download done, you will need to double click / tap the lock to toggle locked / unlocked 9 | */ 10 | 11 | 12 | #include "dumbdisplay.h" 13 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 14 | 15 | 16 | GraphicalDDLayer *graphical; 17 | SimpleToolDDTunnel *tunnel_unlocked; 18 | SimpleToolDDTunnel *tunnel_locked; 19 | 20 | LcdDDLayer *lcd; 21 | 22 | void setup() { 23 | // create a LCD layer for display some status 24 | lcd = dumbdisplay.createLcdLayer(16, 2); 25 | lcd->bgPixelColor("darkgray"); 26 | lcd->pixelColor("lightblue"); 27 | lcd->border(2, "blue"); 28 | lcd->writeCenteredLine("... ..."); 29 | 30 | // create a graphical layer for drawing the web images (the lock) to 31 | graphical = dumbdisplay.createGraphicalLayer(200, 300); 32 | graphical->padding(0); 33 | graphical->margin(2); 34 | graphical->border(2, "darkgreen"); 35 | graphical->enableFeedback(); 36 | 37 | // auto "pin" the two layers vertically, one above the other 38 | dumbdisplay.configAutoPin(DD_AP_VERT); 39 | 40 | // create tunnels for downloading web images (the lock) ... and save to your phone 41 | tunnel_unlocked = dumbdisplay.createImageDownloadTunnel("https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/master/screenshots/lock-unlocked.png", "lock-unlocked.png"); 42 | tunnel_locked = dumbdisplay.createImageDownloadTunnel("https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/master/screenshots/lock-locked.png", "lock-locked.png"); 43 | } 44 | 45 | 46 | bool locked = false; 47 | 48 | bool allReady = false; 49 | long lastShownMillis = 0; 50 | 51 | void loop() { 52 | // get result whether web image downloaded .. 0: downloading; 1: downloaded ok; -1: failed to download 53 | int lockedResult = tunnel_locked->checkResult(); 54 | int unlockedResult = tunnel_unlocked->checkResult(); 55 | const DDFeedback* feedback = graphical->getFeedback(); 56 | 57 | bool refresh = false; 58 | 59 | if (!allReady) { 60 | // not all ready ... if not refresh for a while (1000 ms), refresh 61 | long now = millis(); 62 | long diff = now - lastShownMillis; 63 | if (diff > 1000) { 64 | locked = !locked; 65 | refresh = true; 66 | dumbdisplay.writeComment("... waiting ..."); 67 | } 68 | } else { 69 | // if all ready ... see if double clicked ... if so, refresh 70 | if (feedback != NULL) { 71 | if (feedback->type == DDFeedbackType::DOUBLECLICK) { 72 | locked = !locked; 73 | refresh = true; 74 | } 75 | } 76 | } 77 | 78 | if (!refresh) { 79 | return; 80 | } 81 | 82 | if (!allReady) { 83 | allReady = lockedResult == 1 && unlockedResult == 1; 84 | if (allReady) { 85 | dumbdisplay.writeComment("... READY"); 86 | } 87 | } 88 | 89 | int result; 90 | const char* imageFileName; 91 | if (locked) { 92 | imageFileName = "lock-locked.png"; 93 | result = lockedResult; 94 | } else { 95 | imageFileName = "lock-unlocked.png"; 96 | result = unlockedResult; 97 | } 98 | if (result == 1) { 99 | graphical->drawImageFile(imageFileName); 100 | lcd->writeCenteredLine(locked ? "Lock locked" : "Lock unlocked"); 101 | lcd->writeCenteredLine(allReady ? "(READY)" : "...", 1); 102 | } else if (result == 0) { 103 | // downloading 104 | graphical->clear(); 105 | graphical->setCursor(0, 10); 106 | graphical->println("... ..."); 107 | graphical->println(imageFileName); 108 | graphical->println("... ..."); 109 | lcd->writeCenteredLine("..."); 110 | } else if (result == -1) { 111 | graphical->clear(); 112 | graphical->setCursor(0, 10); 113 | graphical->println("XXX failed to download XXX"); 114 | lcd->writeCenteredLine("failed"); 115 | } 116 | 117 | lastShownMillis = millis(); 118 | } 119 | -------------------------------------------------------------------------------- /examples/webview_blink/webview_blink.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Sorry! Very likely, this sketch will not work for less-capable boards like Arduino Uno, Nano, etc. 3 | */ 4 | 5 | /** 6 | * If BLUETOOTH is #defined, it uses ESP32 bluetooth connection 7 | * . BLUETOOTH is the name of the bluetooth device 8 | * If WIFI_SSID is #defined, it uses wifi connection 9 | * . once sketch running, connect to it with Serial Monitor to check for IP address 10 | * Otherwise, it uses USB connection (OTG) with the default 115200 baud 11 | * . you will need to install Android DumbDisplay app from Play store 12 | * https://play.google.com/store/apps/details?id=nobody.trevorlee.dumbdisplay 13 | * . although there are several ways for microcontroller board to establish connection 14 | * with DumbDisplay app, here, the simple OTG USB connection is assume; 15 | * hence, you will need an OTG adaptor cable for connecting your microcontroller board 16 | * to your Android phone 17 | * . after uploading the sketch to your microcontroller board, plug the USB cable 18 | * to the OTG adaptor connected to your Android phone 19 | * . open the DumbDisplay app and make connection to your microcontroller board via the USB cable; 20 | * hopefully, the UI is obvious enough :) 21 | * . for more details on DumbDisplay Arduino Library, please refer to 22 | * https://github.com/trevorwslee/Arduino-DumbDisplay#readme 23 | * there is a related post that you may want to take a look: 24 | * . https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 25 | */ 26 | 27 | 28 | #include "dumbdisplay.h" 29 | 30 | 31 | #if defined(BLUETOOTH) 32 | #include "esp32dumbdisplay.h" 33 | DumbDisplay dumbdisplay(new DDBluetoothSerialIO(BLUETOOTH, true)); 34 | #elif defined(WIFI_SSID) 35 | #include "wifidumbdisplay.h" 36 | DumbDisplay dumbdisplay(new DDWiFiServerIO(WIFI_SSID, WIFI_PASSWORD)); 37 | #else 38 | // for direct USB connection to phone 39 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 40 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 41 | #include "dumbdisplay.h" 42 | DumbDisplay dumbdisplay(new DDInputOutput()); 43 | #endif 44 | 45 | 46 | 47 | // declare a WebView layer 48 | WebViewDDLayer *webView; 49 | 50 | 51 | void setup() { 52 | // create the WebView layer object 53 | webView = dumbdisplay.createWebViewLayer(300, 300); 54 | 55 | // code the html ... with the help of AI / LLM :-) 56 | String html = 57 | "" 62 | "
" 63 | "" 64 | "" 65 | "" 66 | "" 67 | "" 68 | "" 69 | "" 70 | "" 71 | "" 72 | "
"; 73 | 74 | // it is IMPORTANT to remove any newline characters from the html 75 | html.replace("\n", ""); 76 | 77 | // load the html into the WebView layer 78 | webView->loadHtml(html); 79 | } 80 | 81 | 82 | int lastS = 0; 83 | void loop() { 84 | const DDFeedback* feedback = webView->getFeedback(); // get any "feedback" from the HTML code calling DD.feedbackWithText() 85 | if (feedback != NULL) { 86 | dumbdisplay.writeComment("* '" + feedback->text + "'"); 87 | } 88 | int s = millis() / 1000; 89 | if (s != lastS) { 90 | bool on = s % 2 == 0; 91 | if (on) { 92 | webView->execJs("turnOnOff(true)"); // turnOnOff() is a javascript function defined by the above html 93 | } else { 94 | webView->execJs("turnOnOff(false)"); 95 | } 96 | lastS = s; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /genericdumbdisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef genericdumbdisplay_h 2 | #define genericdumbdisplay_h 3 | 4 | #if !defined(DD_SERIAL) 5 | #error Before #include, must define the macro DD_SERIAL and optional DD_SERIAL_begin (a function call or a code block) \ 6 | *** \ 7 | e.g. STM32F103: PA3 (RX2) ==> TX; PA2 (TX2) ==> RX \ 8 | #define DD_SERIAL Serial2 \ 9 | *** \ 10 | e.g. Pico \ 11 | UART Serial2(8, 9, 0, 0); // 8: PICO_TX; 9: PICO_RX \ 12 | #define DD_SERIAL Serial2 13 | #endif 14 | 15 | #include "dumbdisplay.h" 16 | 17 | /// Subclass of DDInputOutput 18 | ///
IMPORTANT: 19 | /// - Before `#include`, must define `DD_SERIAL` 20 | /// - and optionally define `DD_SERIAL_begin` if necessary 21 | /// - `DD_SERIAL_begin` is a function call or a code block 22 | /// - if `DD_SERIAL_begin` not defined, will call `DD_SERIAL.begin(115200)` instead 23 | /// - e.g. SoftwareSerial -- 2 => TX; 3 => RX 24 | ///
`#include ` 25 | ///
`SoftwareSerial ss(2, 3);` 26 | ///
`#define DD_SERIAL ss` 27 | /// - e.g. Pico -- 8: PICO_TX; 9: PICO_RX 28 | ///
`UART uart(8, 9, 0, 0);` 29 | ///
`#define DD_SERIAL uart` 30 | /// - e.g. Arduino Mega -- 17 ==> TX; 16 ==> RX 31 | ///
`#define DD_SERIAL Serial2` 32 | /// - e.g. STM32F103 -- PA3 (RX2) ==> TX; PA2 (TX2) ==> RX 33 | ///
`HardwareSerial hs(USART2);` 34 | ///
`#define DD_SERIAL hs` 35 | class DDGenericIO: public DDInputOutput { 36 | public: 37 | DDGenericIO(bool enableSerial = false, unsigned long serialBaud = DD_SERIAL_BAUD): DDInputOutput(serialBaud, enableSerial, enableSerial) { 38 | } 39 | const char* getWhat() { 40 | return "GENERIC"; 41 | } 42 | bool available() { 43 | return DD_SERIAL.available(); 44 | } 45 | char read() { 46 | return DD_SERIAL.read(); 47 | } 48 | void print(const String &s) { 49 | DD_SERIAL.print(s); 50 | } 51 | void print(const char *p) { 52 | DD_SERIAL.print(p); 53 | } 54 | void write(uint8_t b) { 55 | DD_SERIAL.write(b); 56 | } 57 | void write(const uint8_t *buf, size_t size) { 58 | DD_SERIAL.write(buf, size); 59 | } 60 | bool preConnect(bool firstCall) { 61 | DDInputOutput::preConnect(firstCall); 62 | if (firstCall) { 63 | #if defined(DD_SERIAL_begin) 64 | DD_SERIAL_begin; 65 | #else 66 | DD_SERIAL.begin(115200); 67 | #endif 68 | } 69 | return true; 70 | } 71 | void flush() { 72 | } 73 | bool canUseBuffer() { 74 | return true; 75 | } 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DumbDisplay Arduino Library", 3 | "version": "0.9.951", 4 | "description": "A library for connecting to Android DumbDisplay app (>= this version), for various virtual gadget realizations. By using DumbDisplay, you should be able to more quickly design/prototype your Arduino experiment, and defer connecting real gadgets until later stage of your experiment.", 5 | "keywords": "Arduino, ESP, Raspberry Pi Pico, Display, Wireless", 6 | "license": "MIT", 7 | "frameworks": ["arduino"], 8 | "repository": 9 | { 10 | "type": "git", 11 | "url": "https://github.com/trevorwslee/Arduino-DumbDisplay" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=DumbDisplay 2 | version=0.9.951 3 | author=Trevor Lee 4 | maintainer=Trevor Lee 5 | sentence=A library for connecting to Android DumbDisplay app (>= this version), for various virtual gadget realizations. 6 | paragraph=By using DumbDisplay, you should be able to more quickly design/prototype your Arduino experiment, and defer connecting real gadgets until later stage of your experiment. 7 | category=Display 8 | url=https://github.com/trevorwslee/Arduino-DumbDisplay 9 | -------------------------------------------------------------------------------- /pgm_util.h: -------------------------------------------------------------------------------- 1 | 2 | const uint8_t *PgmCopyBytes(const uint8_t *bytes, int byteCount, uint8_t *buffer) { 3 | for (int i = 0; i < byteCount; i++) { 4 | buffer[i] = pgm_read_byte(bytes + i); 5 | } 6 | return buffer; 7 | } 8 | 9 | const uint16_t *PgmCopyWords(const uint16_t *words, int wordCount, uint16_t *buffer) { 10 | for (int i = 0; i < wordCount; i++) { 11 | buffer[i] = pgm_read_word(words + i); 12 | } 13 | return buffer; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /picodumbdisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef picodumbdisplay_h 2 | #define picodumbdisplay_h 3 | 4 | // #if !(defined DD_4_PICO_TX && defined DD_4_PICO_RX) 5 | // #error DD_4_PICO_TX and DD_4_PICO_RX need be defined in order to use DumbDisplay for PICO 6 | // #error e.g. #define DD_4_PICO_TX 8 7 | // #error e.g. #define DD_4_PICO_RX 9 8 | // #endif 9 | 10 | #include "dumbdisplay.h" 11 | 12 | //UART Serial2(8, 9, 0, 0); 13 | //UART Serial2(DD_4_PICO_TX, DD_4_PICO_RX, 0, 0); 14 | 15 | 16 | 17 | /// Deprecated. Use DDGenericIO (in genericdumbdisplay.h) instead. 18 | class DDPicoSerialIO: public DDInputOutput { 19 | public: 20 | DDPicoSerialIO(int tx = 8, int rx = 9, 21 | unsigned long baud = DD_SERIAL_BAUD, 22 | bool enableSerial = false, unsigned long serialBaud = DD_SERIAL_BAUD): 23 | DDInputOutput(serialBaud, enableSerial, enableSerial), serial(tx, rx, 0, 0) { 24 | this->baud = baud; 25 | // if (!enableSerial) { 26 | // Serial.begin(serialBaud); // not a good idea to do it here 27 | // } 28 | } 29 | const char* getWhat() { 30 | return "PICO"; 31 | } 32 | bool available() { 33 | return serial.available(); 34 | } 35 | char read() { 36 | return serial.read(); 37 | } 38 | void print(const String &s) { 39 | serial.print(s); 40 | } 41 | void print(const char *p) { 42 | serial.print(p); 43 | } 44 | void write(uint8_t b) { 45 | serial.write(b); 46 | } 47 | void write(const uint8_t *buf, size_t size) { 48 | serial.write(buf, size); 49 | } 50 | bool preConnect(bool firstCall) { 51 | if (firstCall) { 52 | serial.begin(baud); 53 | } 54 | return true; 55 | } 56 | void flush() { 57 | } 58 | bool canConnectPassive() { 59 | return true; 60 | } 61 | bool canUseBuffer() { 62 | return true; 63 | } 64 | private: 65 | UART serial; 66 | unsigned long baud; 67 | }; 68 | 69 | 70 | 71 | //#endif 72 | #endif -------------------------------------------------------------------------------- /projects/MISC/melody/melody.ino: -------------------------------------------------------------------------------- 1 | // for a desciption of the melody experiment, please watch the YouTube video 2 | // -- Raspberry Pi Pico playing song melody tones, with DumbDisplay control and keyboard input 3 | // -- https://www.youtube.com/watch?v=l-HrsJXIwBY 4 | 5 | 6 | #define SPEAKER_PIN 5 7 | 8 | 9 | // noteName: C, D, E, F, G, A, B 10 | // halfNote: #, b 11 | int ToNoteIdx(char noteName, char halfNote) { 12 | int noteIdx; 13 | switch (noteName) { 14 | case 'C': noteIdx = 0; break; 15 | case 'D': noteIdx = 2; break; 16 | case 'E': noteIdx = 4; break; 17 | case 'F': noteIdx = 5; break; 18 | case 'G': noteIdx = 7; break; 19 | case 'A': noteIdx = 9; break; 20 | case 'B': noteIdx = 11; break; 21 | } 22 | if (halfNote == '#') { 23 | noteName = noteIdx + 1; 24 | } else if (halfNote == 'b') { 25 | noteName = noteIdx - 1; 26 | } 27 | return noteIdx; 28 | } 29 | 30 | 31 | // octave: can be negative 32 | // noteIdx: 0 to 11; i.e. 12 note indexes in an octave 33 | int GetNoteFreq(int octave, int noteIdx) { 34 | int n = noteIdx + 12 * octave - 8; 35 | float freq = 440.0 * pow(2, n / 12.0); // 440 is A 36 | return round(freq); 37 | } 38 | 39 | 40 | void PlayTone(int freq, int duration) { 41 | long tillMicros = 1000 * (millis() + duration); 42 | long waitMicros = (1000000.0 / freq) / 2; 43 | bool high = true; 44 | while (true) { 45 | long diffMicros = tillMicros - 1000 * millis(); 46 | if (diffMicros < waitMicros) { 47 | break; 48 | } 49 | digitalWrite(SPEAKER_PIN, high ? 1 : 0); 50 | high = !high; 51 | delayMicroseconds(waitMicros); 52 | } 53 | } 54 | 55 | 56 | 57 | const char* song = "G C E C E D C A G G C E C E D G E G E G E C G A C C A G G C E C E D C "; 58 | const char* octave = "0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 "; 59 | const char* beat = "2 4 1 1 4 2 4 2 4 2 4 1 1 4 2 8 2 1 1 1 1 4 2 4 1 1 1 4 2 4 1 1 4 2 8 "; 60 | 61 | const int beatSpeed = 300; 62 | 63 | 64 | void setup() { 65 | pinMode(SPEAKER_PIN, OUTPUT); 66 | } 67 | 68 | void loop() { 69 | for (int i = 0;; i += 2) { 70 | 71 | char noteName = song[i]; 72 | char halfNote = song[i + 1]; 73 | 74 | if (noteName == 0) { 75 | // reached end of song => break out of loop 76 | break; 77 | } 78 | 79 | // convert the song note into tone frequency 80 | int noteIdx = ToNoteIdx(noteName, halfNote); 81 | int freq = GetNoteFreq(octave[i] - '0', noteIdx); 82 | 83 | // get the how to to play the note/tone for 84 | int duration = beatSpeed * (beat[i] - '0'); 85 | 86 | // play the note/tone 87 | PlayTone(freq, duration); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /projects/dd7segcounter/dd7segcounter.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dumbdisplay.h" 3 | 4 | 5 | // create the DumbDisplay object; assuming USB connection with 115200 baud 6 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 7 | 8 | 9 | // declare a 7-segment layer object, to be created in setup() 10 | SevenSegmentRowDDLayer *sevenSeg; 11 | 12 | 13 | #define PIN_LEFT PIN4 14 | #define PIN_RIGHT PIN2 15 | 16 | 17 | 18 | class ButtonPressTracker { 19 | public: 20 | ButtonPressTracker() { 21 | this->pressed = false; // assume initially not pressed 22 | this->blackOutMillis = 0; 23 | } 24 | bool setPressed(bool pressed) { 25 | long nowMillis = millis(); 26 | if (blackOutMillis != 0) { 27 | long diff = blackOutMillis - nowMillis; 28 | if (diff < 0) { 29 | blackOutMillis = 0; 30 | } 31 | } 32 | if (blackOutMillis == 0) { 33 | if (pressed != this->pressed) { 34 | this->pressed = pressed; 35 | blackOutMillis = nowMillis + 50; 36 | return this->pressed; 37 | } 38 | } 39 | return false; 40 | } 41 | private: 42 | bool pressed; 43 | long blackOutMillis; 44 | }; 45 | 46 | 47 | 48 | ButtonPressTracker leftTracker; 49 | ButtonPressTracker rightTracker; 50 | int count = 0; 51 | 52 | 53 | void setup() { 54 | pinMode(PIN_RIGHT, INPUT_PULLUP); 55 | pinMode(PIN_LEFT, INPUT_PULLUP); 56 | 57 | // create the 7-segment layer object, with 3 7-segment digits 58 | sevenSeg = dumbdisplay.create7SegmentRowLayer(3); 59 | sevenSeg->border(5, "black", "round"); 60 | sevenSeg->padding(5); 61 | sevenSeg->resetSegmentOffColor(DD_RGB_COLOR(0xff, 0xee, 0xff)); 62 | sevenSeg->showNumber(count); 63 | } 64 | 65 | 66 | void loop() { 67 | int left = digitalRead(PIN_LEFT); 68 | int right = digitalRead(PIN_RIGHT); 69 | bool rightPressed = rightTracker.setPressed(right == 0); 70 | bool leftPressed = leftTracker.setPressed(left == 0); 71 | 72 | int preCount = count; 73 | if (leftPressed) { 74 | count -= 1; 75 | } 76 | if (rightPressed) { 77 | count += 1; 78 | } 79 | if (count != preCount) { 80 | sevenSeg->showNumber(count); 81 | } 82 | } -------------------------------------------------------------------------------- /projects/dd8x8/dd8x8.ino: -------------------------------------------------------------------------------- 1 | 2 | // for a desciption of the 8x8 LED Matrix with DumbDisplay UI experiment, please watch the YouTube video 3 | // -- Raspberry Pi Pico 8x8 LED Matrix Arduino Experiment with HC-06 and DumpDisplay 4 | // -- https://www.youtube.com/watch?v=YRfc9Z-L73A 5 | 6 | 7 | 8 | 9 | // comment out BLUETOOTH if don't have HC-06 connectivity 10 | // . GP8 => RX of HC-06; GP9 => TX of HC-06 11 | // if no HC-06 connectivity, will need to use DumbDisplayWifiBridge 12 | #define BLUETOOTH 13 | 14 | #ifdef BLUETOOTH 15 | 16 | // GP8 => RX of HC-06; GP9 => TX of HC-06; HC-06 should be configured to use baud rate of 115200 17 | #define DD_4_PICO_TX 8 18 | #define DD_4_PICO_RX 9 19 | #include 20 | DumbDisplay dumbdisplay(new DDPicoSerialIO(DD_4_PICO_TX, DD_4_PICO_RX)); 21 | 22 | #else 23 | 24 | #include 25 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 26 | 27 | #endif 28 | 29 | 30 | #define R_SHIFT_PIN 6 31 | #define R_CLOCK_PIN 27 32 | 33 | #define C_SHIFT_PIN 22 34 | #define C_LATCH_PIN 21 35 | #define C_CLOCK_PIN 20 36 | 37 | int data[8] = { 0b11100111, 38 | 0b11011011, 39 | 0b10111101, 40 | 0b01111110, 41 | 0b00000000, 42 | 0b11100111, 43 | 0b11100111, 44 | 0b11100111 }; 45 | 46 | LedGridDDLayer *ledMatrix; 47 | 48 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback); 49 | 50 | void setup() { 51 | pinMode(R_SHIFT_PIN, OUTPUT); 52 | pinMode(R_CLOCK_PIN, OUTPUT); 53 | 54 | pinMode(C_SHIFT_PIN, OUTPUT); 55 | pinMode(C_CLOCK_PIN, OUTPUT); 56 | pinMode(C_LATCH_PIN, OUTPUT); 57 | 58 | digitalWrite(R_CLOCK_PIN, 0); 59 | 60 | digitalWrite(C_CLOCK_PIN, 0); 61 | digitalWrite(C_LATCH_PIN, 0); 62 | 63 | // turn off all the LEDs 64 | shiftOut(C_SHIFT_PIN, C_CLOCK_PIN, LSBFIRST, 0xff); 65 | digitalWrite(C_LATCH_PIN, 1); 66 | digitalWrite(C_LATCH_PIN, 0); 67 | 68 | // create and setup LED layer on DumbDisplay 69 | ledMatrix = dumbdisplay.createLedGridLayer(8, 8); 70 | ledMatrix->border(0.2, "white"); 71 | ledMatrix->padding(0.2); 72 | ledMatrix->onColor("red"); 73 | ledMatrix->offColor("lightgray"); 74 | ledMatrix->backgroundColor("black"); 75 | ledMatrix->setFeedbackHandler(FeedbackHandler, "fa"); 76 | for (int i = 0; i < 8; i++) { 77 | int bits = data[i]; 78 | ledMatrix->bitwise(~bits, i); // notice that the bit are inverted 79 | } 80 | } 81 | 82 | 83 | 84 | 85 | void loop() { 86 | for (int i = 0; i < 8; i++) { 87 | int bits = data[i]; 88 | 89 | // shift the "column" bits 90 | shiftOut(C_SHIFT_PIN, C_CLOCK_PIN, LSBFIRST, bits); 91 | 92 | // set the "row" shift bit, which should only be 1 when i is 0 93 | digitalWrite(R_SHIFT_PIN, i == 0 ? 1 : 0); 94 | 95 | // pulse the "row" CLOCK to trigger shifting of the "rows" 96 | digitalWrite(R_CLOCK_PIN, 1); 97 | digitalWrite(R_CLOCK_PIN, 0); 98 | 99 | // pulse the "column" LATCH to transfer to the output register 100 | digitalWrite(C_LATCH_PIN, 1); 101 | digitalWrite(C_LATCH_PIN, 0); 102 | 103 | // delay a bit so that the light will "shine through" 104 | delay(2); 105 | } 106 | 107 | DDYield(); 108 | } 109 | 110 | 111 | 112 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback) { 113 | 114 | if (type != LONGPRESS) { 115 | int c = feedback.x; 116 | int r = feedback.y; 117 | ledMatrix->toggle(c, r); 118 | int bits = data[r]; 119 | int mask = 1 << (7 - c); 120 | bool on = (bits & mask) == 0; 121 | if (on) { 122 | data[r] = bits | mask; 123 | } else { 124 | data[r] = bits & ~mask; 125 | } 126 | } else { 127 | ledMatrix->clear(); 128 | for (int r = 0; r < 8; r++) { 129 | data[r] = 0xff; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /projects/ddgpsmap/gpssignal.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | // -------------------------------------- 4 | 5 | // ***** 6 | // * code for reading GPS signal from NEO-7M U-BLOX module 7 | // * . simply read and interpret fixed position data 8 | // * . not very interesting 9 | // ***** 10 | 11 | 12 | struct GpsSignal { 13 | char utc_time[10]; 14 | bool position_fixed; 15 | float latitude; 16 | float longitude; 17 | float altitude; 18 | }; 19 | 20 | class GpsSignalReader { 21 | public: 22 | GpsSignalReader(SoftwareSerial& gpsSerial) 23 | : gpsSerial(gpsSerial) {} 24 | bool readOnce(GpsSignal& gpsSignal); 25 | private: 26 | float latLongConvert(float latLong); 27 | private: 28 | const char* HEADER = "$GPGGA,"; 29 | const int HEADER_LEN = strlen(HEADER); 30 | private: 31 | SoftwareSerial& gpsSerial; 32 | private: 33 | bool reading = false; 34 | int reading_header_idx = 0; 35 | int reading_field_idx = 0; 36 | char field_buffer[32]; 37 | int read_field_count = 0; 38 | char utc_time[10]; 39 | bool position_fixed = false; 40 | float latitude; 41 | float longitude; 42 | float altitude; 43 | }; 44 | 45 | bool GpsSignalReader::readOnce(GpsSignal& gpsSignal) { 46 | if (gpsSerial.available()) { 47 | char c = gpsSerial.read(); 48 | if (reading) { 49 | if (reading_header_idx < HEADER_LEN) { 50 | if (c != HEADER[reading_header_idx++]) { 51 | reading = false; 52 | return false; 53 | } 54 | } else { 55 | if (c == '\r') { 56 | reading = false; 57 | if (utc_time[0] != 0) { 58 | memcpy(gpsSignal.utc_time, utc_time, sizeof(utc_time)); 59 | gpsSignal.position_fixed = position_fixed; 60 | gpsSignal.latitude = latLongConvert(latitude); 61 | gpsSignal.longitude = latLongConvert(longitude); 62 | gpsSignal.altitude = altitude; 63 | return true; 64 | } 65 | } 66 | if (c == ',') { 67 | if (reading_field_idx > 0) { 68 | if (read_field_count == 0) { 69 | utc_time[0] = field_buffer[0]; 70 | utc_time[1] = field_buffer[1]; 71 | utc_time[2] = ':'; 72 | utc_time[3] = field_buffer[2]; 73 | utc_time[4] = field_buffer[3]; 74 | utc_time[5] = ':'; 75 | utc_time[6] = field_buffer[4]; 76 | utc_time[7] = field_buffer[5]; 77 | utc_time[8] = 0; 78 | } else if (read_field_count == 1) { 79 | latitude = atof(field_buffer); 80 | } else if (read_field_count == 3) { 81 | longitude = atof(field_buffer); 82 | } else if (read_field_count == 5) { 83 | position_fixed = field_buffer[0] == '1' || field_buffer[0] == '2'; 84 | } else if (read_field_count == 8) { 85 | altitude = atof(field_buffer); 86 | } 87 | } 88 | reading_field_idx = 0; 89 | field_buffer[0] = 0; 90 | read_field_count++; 91 | } else { 92 | field_buffer[reading_field_idx++] = c; 93 | field_buffer[reading_field_idx] = 0; 94 | } 95 | } 96 | } else { 97 | if (c == '\n') { 98 | reading = true; 99 | reading_header_idx = 0; 100 | reading_field_idx = 0; 101 | field_buffer[0] = 0; 102 | read_field_count = 0; 103 | utc_time[0] = 0; 104 | position_fixed = false; 105 | latitude = 0; 106 | longitude = 0; 107 | } 108 | } 109 | } 110 | return false; 111 | } 112 | 113 | float GpsSignalReader::latLongConvert(float latLong) { 114 | int second = 60 * (latLong - (int) latLong); 115 | int degree = (int) (latLong / 100); 116 | int minute = (int) (latLong - 100 * degree); 117 | return (float) degree + ((60 * (float) minute + (float) second) / (60 * 60)); 118 | } 119 | 120 | 121 | // -------------------------------------- 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /projects/ddpocketcomputer/PressTracker.h: -------------------------------------------------------------------------------- 1 | class ButtonPressTracker { 2 | public: 3 | ButtonPressTracker(uint8_t pin) { 4 | this->pin = pin; 5 | this->pressed = false; // assume initially not pressed 6 | this->blackOutMillis = 0; 7 | this->nextRepeatMillis = 0; 8 | //this->repeat = 0; 9 | } 10 | bool checkPressed(int repeat = 0) { 11 | return setPressed(digitalRead(this->pin) == 0, repeat); 12 | } 13 | bool checkPressedBypass() { 14 | setPressed(digitalRead(this->pin) == 0); 15 | return pressed; 16 | } 17 | private: 18 | bool setPressed(bool pressed, int repeat = 0) { 19 | if (repeat == 0) { 20 | this->nextRepeatMillis = 0; 21 | } 22 | long nowMillis = millis(); 23 | if (this->blackOutMillis != 0) { 24 | long diff = this->blackOutMillis - nowMillis; 25 | if (diff < 0) { 26 | this->blackOutMillis = 0; 27 | } 28 | } 29 | if (this->blackOutMillis == 0) { 30 | if (pressed != this->pressed) { 31 | this->pressed = pressed; 32 | this->blackOutMillis = nowMillis + 50; 33 | if (repeat != 0 && this->pressed) { 34 | this->nextRepeatMillis = nowMillis + repeat; 35 | } else { 36 | this->nextRepeatMillis = 0; 37 | } 38 | return this->pressed; 39 | } 40 | } 41 | if (this->nextRepeatMillis != 0) { 42 | long diff = this->nextRepeatMillis - nowMillis; 43 | if (diff < 0) { 44 | this->nextRepeatMillis = nowMillis + repeat; 45 | return true; 46 | } 47 | } 48 | return false; 49 | } 50 | private: 51 | uint8_t pin; 52 | bool pressed; 53 | long blackOutMillis; 54 | long nextRepeatMillis; 55 | }; 56 | 57 | class JoyStickPressTracker { 58 | public: 59 | JoyStickPressTracker(uint8_t pin) { 60 | this->maxReading = 1023; 61 | this->threshold = 10; 62 | this->pin = pin; 63 | //this->reading = 0; 64 | this->pressedDir = 0; 65 | this->pressedMillis = 0; 66 | this->needReset = false; 67 | } 68 | public: 69 | int8_t checkPressed() { 70 | return setReading(analogRead(this->pin)); 71 | } 72 | int readBypass() { 73 | int reading = analogRead(this->pin); 74 | setReading(reading); 75 | return reading; 76 | } 77 | private: 78 | int8_t setReading(int reading) { 79 | //int oriReading = this->reading; 80 | int8_t oriPressedDir = this->pressedDir; 81 | //this->reading = reading; 82 | if ((reading - threshold) <= 0) { 83 | this->pressedDir = -1; 84 | } else if ((reading + threshold) >= maxReading) { 85 | this->pressedDir = 1; 86 | } else { 87 | this->pressedDir = 0; 88 | } 89 | if (!this->needReset && this->pressedMillis != 0 && (this->pressedDir == oriPressedDir)) { 90 | long diffMillis = millis() - this->pressedMillis; 91 | if (diffMillis > 50) { 92 | this->pressedDir = 0; 93 | this->pressedMillis = 0; 94 | this->needReset = true; 95 | return oriPressedDir; 96 | } 97 | } else { 98 | if (this->pressedDir != 0) { 99 | if (this->pressedMillis == 0) { 100 | this->pressedMillis = millis(); 101 | } 102 | } else { 103 | this->pressedMillis = 0; 104 | this->needReset = false; 105 | } 106 | } 107 | return 0; 108 | } 109 | private: 110 | int maxReading; 111 | int threshold; 112 | private: 113 | //int reading; 114 | uint8_t pin; 115 | int pressedDir; 116 | long pressedMillis; 117 | bool needReset; 118 | }; 119 | -------------------------------------------------------------------------------- /projects/ddpocketcomputer/ddpocketcomputer.ino: -------------------------------------------------------------------------------- 1 | // *** 2 | // * adapted from: youtube.com/watch?v=NTaq6f7NV5U 3 | // *** 4 | 5 | 6 | // if using Arduino UNO (assume with Joy Stick Shield) 7 | // otherwise, assume Arduino Nano 8 | #if defined(ARDUINO_AVR_UNO) 9 | #define WITH_JOYSTICK 10 | const uint8_t left = 5; 11 | const uint8_t right = 3; 12 | const uint8_t presS = 2; 13 | const uint8_t horizontal = A0; 14 | const uint8_t vertical = A1; 15 | #elif defined(ARDUINO_AVR_NANO) 16 | const uint8_t left = PIN_A1; 17 | const uint8_t right = PIN_A4; 18 | const uint8_t presS = PIN_A2; 19 | #elif defined(PICO_SDK_VERSION_MAJOR) 20 | const uint8_t left = 15; 21 | const uint8_t right = 16; 22 | const uint8_t presS = 14; 23 | #else 24 | #error not configured for board yet 25 | #endif 26 | 27 | 28 | 29 | 30 | const char* COLOR_BG = "darkblue"; 31 | const char* COLOR_DEF = "beige"; 32 | const char* COLOR_0 = "navy"; 33 | const char* COLOR_1 = "ivory"; 34 | const uint8_t TEXT_SIZE_DEF = 9; 35 | const uint8_t TEXT_SIZE_2 = 24; 36 | const int TEXT_SIZE_4 = 28; 37 | 38 | 39 | 40 | #if defined(PICO_SDK_VERSION_MAJOR) 41 | // GP8 => RX of HC06; GP9 => TX of HC06 42 | #define DD_4_PICO_TX 8 43 | #define DD_4_PICO_RX 9 44 | #include "picodumbdisplay.h" 45 | DumbDisplay dumbdisplay(new DDPicoSerialIO(DD_4_PICO_TX, DD_4_PICO_RX)); 46 | #else 47 | #include "dumbdisplay.h" 48 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 49 | #endif 50 | 51 | 52 | GraphicalDDLayer *display; 53 | 54 | 55 | #include "core.h" 56 | #include "pgm_util.h" 57 | 58 | 59 | void setup() { 60 | 61 | dumbdisplay.connect(); 62 | dumbdisplay.writeComment("initializing ..."); 63 | 64 | pinMode(left, INPUT_PULLUP); 65 | pinMode(right, INPUT_PULLUP); 66 | pinMode(presS, INPUT_PULLUP); 67 | 68 | #ifdef WITH_JOYSTICK 69 | pinMode(horizontal, INPUT); 70 | pinMode(vertical, INPUT); 71 | #endif 72 | 73 | display = dumbdisplay.createGraphicalLayer(64, 128); 74 | 75 | display->backgroundColor(COLOR_BG); 76 | display->setTextColor(COLOR_DEF); 77 | 78 | display->setCursor(0, 10); 79 | display->print("..."); 80 | 81 | unsigned char buffer[240]; 82 | display->cachePixelImage("logo.png", PgmCopyBytes(epd_bitmap_logo, sizeof(epd_bitmap_logo), buffer), 64, 30, COLOR_1, DD_COMPRESS_BA_0); 83 | display->cachePixelImage("calc.png", PgmCopyBytes(myBitmapcalc, sizeof(myBitmapcalc), buffer), 24, 24, COLOR_1, DD_COMPRESS_BA_0); 84 | display->cachePixelImage("stop.png", PgmCopyBytes(myBitmapstop, sizeof(myBitmapstop), buffer), 24, 24, COLOR_1, DD_COMPRESS_BA_0); 85 | display->cachePixelImage("game.png", PgmCopyBytes(myBitmapgam, sizeof(myBitmapgam), buffer), 24, 24, COLOR_1, DD_COMPRESS_BA_0); 86 | display->cachePixelImage("calen.png", PgmCopyBytes(myBitmapcalen, sizeof(myBitmapcalen), buffer), 24, 24, COLOR_1, DD_COMPRESS_BA_0); 87 | display->cachePixelImage("phone.png", PgmCopyBytes(myBitmapphone, sizeof(myBitmapphone), buffer), 24, 24, COLOR_1, DD_COMPRESS_BA_0); 88 | // display->cachePixelImage("logo.png", epd_bitmap_logo, 64, 30, COLOR_1, DD_COMPRESS_BA_0); 89 | // display->cachePixelImage("calc.png", myBitmapcalc, 24, 24, COLOR_1, DD_COMPRESS_BA_0); 90 | // display->cachePixelImage("stop.png", myBitmapstop, 24, 24, COLOR_1, DD_COMPRESS_BA_0); 91 | // display->cachePixelImage("game.png", myBitmapgam, 24, 24, COLOR_1, DD_COMPRESS_BA_0); 92 | // display->cachePixelImage("calen.png", myBitmapcalen, 24, 24, COLOR_1, DD_COMPRESS_BA_0); 93 | // display->cachePixelImage("phone.png", myBitmapphone, 24, 24, COLOR_1, DD_COMPRESS_BA_0); 94 | 95 | display->setTextFont("MONOSPACE"); 96 | display->clear(); 97 | 98 | dumbdisplay.writeComment("... done initialization"); 99 | 100 | randomSeed(millis()); 101 | 102 | GameReset(); 103 | } 104 | 105 | void loop() { 106 | 107 | if (fase == 0) { 108 | handleMenu(); 109 | } else { 110 | if (checkReset()) { 111 | return; 112 | } 113 | } 114 | 115 | if (fase == 1) { 116 | handleCalc(); 117 | } 118 | 119 | if (fase == 2) { 120 | handleStop(); 121 | } 122 | 123 | if (fase == 3) { 124 | handleGame(); 125 | } 126 | 127 | if (fase == 4) { 128 | handleCalendar(); 129 | } 130 | 131 | if (fase == 5) { 132 | handlePhone(); 133 | } 134 | } 135 | 136 | 137 | -------------------------------------------------------------------------------- /projects/ddspacewars/Misc.h: -------------------------------------------------------------------------------- 1 | const long DueGapMillis = 40; 2 | 3 | 4 | class Position 5 | { 6 | public: 7 | Position() 8 | { 9 | reset(0, 0); 10 | } 11 | Position(float pos_x, float pos_y) 12 | { 13 | reset(pos_x, pos_y); 14 | } 15 | 16 | public: 17 | void moveBy(float inc_x, float inc_y) 18 | { 19 | this->pos_x += inc_x; 20 | this->pos_y += inc_y; 21 | this->last_x = this->x; 22 | this->last_y = this->y; 23 | this->x = this->pos_x; 24 | this->y = this->pos_y; 25 | if (last_valid) 26 | { 27 | this->moved = this->last_x != this->x || this->last_y != this->y; 28 | } 29 | else 30 | { 31 | this->last_valid = true; 32 | this->moved = true; 33 | } 34 | } 35 | void moveTo(float pos_x, float pos_y) 36 | { 37 | this->pos_x = pos_x; 38 | this->pos_y = pos_y; 39 | this->x = this->pos_x; 40 | this->y = this->pos_y; 41 | if (last_valid) 42 | { 43 | this->moved = this->last_x != this->x || this->last_y != this->y; 44 | } 45 | else 46 | { 47 | this->last_valid = true; 48 | this->moved = true; 49 | } 50 | } 51 | void moveXTo(float pos_x) 52 | { 53 | moveTo(pos_x, this->pos_y); 54 | } 55 | void moveYTo(float pos_y) 56 | { 57 | moveTo(this->pos_x, pos_y); 58 | } 59 | bool checkMoved() 60 | { 61 | bool res = this->moved; 62 | this->moved = false; 63 | return res; 64 | } 65 | void reset(float pos_x, float pos_y) 66 | { 67 | this->pos_x = pos_x; 68 | this->pos_y = pos_y; 69 | this->x = this->pos_x; 70 | this->y = this->pos_y; 71 | this->last_valid = false; 72 | this->moved = true; 73 | } 74 | inline int getX() { return this->x; } 75 | inline int getY() { return this->y; } 76 | 77 | private: 78 | float pos_x; 79 | float pos_y; 80 | int x; 81 | int y; 82 | bool last_valid; 83 | int last_x; 84 | int last_y; 85 | bool moved; 86 | }; 87 | 88 | class PositionGroup 89 | { 90 | public: 91 | PositionGroup(Position *positions, int positionCount) 92 | { 93 | this->positions = positions; 94 | this->positionCount = positionCount; 95 | } 96 | 97 | public: 98 | void resetAll(float pos_x, float pos_y) 99 | { 100 | for (int i = 0; i < this->positionCount; i++) 101 | { 102 | Position *position = this->positions + i; 103 | position->reset(pos_x, pos_y); 104 | } 105 | } 106 | bool checkAnyMoved() 107 | { 108 | bool moved = false; 109 | for (int i = 0; i < this->positionCount; i++) 110 | { 111 | Position *position = this->positions + i; 112 | if (position->checkMoved()) 113 | { 114 | moved = true; 115 | } 116 | } 117 | return moved; 118 | } 119 | 120 | private: 121 | Position *positions; 122 | int positionCount; 123 | }; 124 | 125 | class FrameControl 126 | { 127 | public: 128 | FrameControl() 129 | { 130 | reset(); 131 | } 132 | 133 | public: 134 | bool checkDue() 135 | { 136 | long nowMillis = millis(); 137 | bool due = (this->nextDueMillis - nowMillis) <= 0; 138 | if (due) 139 | { 140 | if (this->nextDueMillis == 0) 141 | { 142 | this->nextDueMillis = nowMillis; 143 | } 144 | this->nextDueMillis += DueGapMillis; 145 | #if defined(DEBUG_LED_PIN) 146 | int status = (this->nextDueMillis - nowMillis) > 10 ? 1 : 0; 147 | digitalWrite(DEBUG_LED_PIN, status); 148 | #endif 149 | } 150 | if (due) 151 | { 152 | this->frameNum += 1; 153 | } 154 | return due; 155 | } 156 | inline long getFrameNum() 157 | { 158 | return this->frameNum; 159 | } 160 | void reset() 161 | { 162 | this->nextDueMillis = 0; 163 | this->frameNum = 0; 164 | } 165 | 166 | private: 167 | long nextDueMillis; 168 | long frameNum; 169 | }; 170 | -------------------------------------------------------------------------------- /projects/ddspacewars/bulet.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : bulet.png 3 | // Time generated : Sun, 18 Oct 20 17:13:17 +0200 (Server timezone: CET) 4 | // Image Size : 8x8 pixels 5 | // Memory usage : 128 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const uint16_t bulet[64] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3A8B, 0xE7BF, 0xE7BF, 0xE7BF, 0xE7BF, 0x3A8C, 0x0000, // 0x0010 (16) pixels 18 | 0x0000, 0x7599, 0x6558, 0x6538, 0x6538, 0x6558, 0x7599, 0x0000, 0x0000, 0x3CF8, 0x34F7, 0x2D18, 0x2D18, 0x34F7, 0x3CF8, 0x0000, // 0x0020 (32) pixels 19 | 0x0000, 0x0519, 0x0D39, 0x2579, 0x2579, 0x0D39, 0x0519, 0x0000, 0x0000, 0x0DDC, 0x45DA, 0x5E1B, 0x5E1B, 0x45DA, 0x0DDC, 0x0000, // 0x0030 (48) pixels 20 | 0x0000, 0x232F, 0x9FBF, 0xCFFF, 0xCFFF, 0x9FBF, 0x232F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0040 (64) pixels 21 | }; 22 | -------------------------------------------------------------------------------- /projects/ddspacewars/ebullet.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : ebullet.png 3 | // Time generated : Mon, 02 Nov 20 08:07:44 +0100 (Server timezone: CET) 4 | // Image Size : 7x7 pixels 5 | // Memory usage : 98 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const unsigned short ebullet[49] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E4, 0xE8E4, 0xE8E4, 0x0000, 0x0000, 0x0000, 0xE8E4, // 0x0010 (16) pixels 18 | 0xCDFC, 0xCDFC, 0xCDFC, 0xE8E4, 0x0000, 0x0000, 0xE8E4, 0xCDFC, 0xA254, 0xCDFC, 0xE8E4, 0x0000, 0x0000, 0xE8E4, 0xCDFC, 0xCDFC, // 0x0020 (32) pixels 19 | 0xCDFC, 0xE8E4, 0x0000, 0x0000, 0x0000, 0xE8E4, 0xE8E4, 0xE8E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0030 (48) pixels 20 | }; 21 | -------------------------------------------------------------------------------- /projects/ddspacewars/ex2.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : ex2.png 3 | // Time generated : Wed, 04 Nov 20 14:25:07 +0100 (Server timezone: CET) 4 | // Image Size : 12x12 pixels 5 | // Memory usage : 288 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const uint16_t ex2[144] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0xFF80, 0xFF80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF80, // 0x0010 (16) pixels 18 | 0xFF80, 0xFBE4, 0xFBE4, 0xFBE4, 0xFBE4, 0xFF80, 0x0000, 0x0000, 0x0000, 0xFBE4, 0xFBE4, 0xFF80, 0xFBE4, 0xFFFF, 0xFFFF, 0xFBE4, // 0x0020 (32) pixels 19 | 0xFBE4, 0xFBE4, 0xFF80, 0x0000, 0x0000, 0xFBE4, 0xFFFF, 0xFFFF, 0xE8E4, 0xE8E4, 0xE8E4, 0xFFFF, 0xFBE4, 0xFFFF, 0xFBE4, 0x0000, // 0x0030 (48) pixels 20 | 0xFF80, 0xFBE4, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, 0xFBE4, 0xE8E4, 0xFFFF, 0xFBE4, 0x0000, 0x0000, 0xFF80, 0xFBE4, 0xE8E4, 0xE8E4, // 0x0040 (64) pixels 21 | 0xE8E4, 0xFBE4, 0xFBE4, 0xE8E4, 0xFF80, 0xFF80, 0xFBE4, 0x0000, 0x0000, 0xFBE4, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, // 0x0050 (80) pixels 22 | 0xFF80, 0xFBE4, 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E4, 0xFFFF, 0xFBE4, 0xE8E4, 0xE8E4, 0xE8E4, 0xFFFF, 0xFBE4, 0x0000, 0x0000, // 0x0060 (96) pixels 23 | 0x0000, 0xFF80, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, 0xE8E4, 0xFBE4, 0xFBE4, 0xFF80, 0xFF80, 0x0000, 0xFBE4, 0xFF80, 0xFF80, 0xFF80, // 0x0070 (112) pixels 24 | 0xFF80, 0xFBE4, 0xFBE4, 0xFF80, 0xFBE4, 0xFBE4, 0x0000, 0x0000, 0x0000, 0x0000, 0xFBE4, 0xFBE4, 0xFF80, 0xFBE4, 0xFF80, 0xFF80, // 0x0080 (128) pixels 25 | 0xFBE4, 0xFBE4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFBE4, 0xFBE4, 0x0000, 0x0000, // 0x0090 (144) pixels 26 | }; 27 | -------------------------------------------------------------------------------- /projects/ddspacewars/life.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : life.png 3 | // Time generated : Wed, 21 Oct 20 12:00:17 +0200 (Server timezone: CET) 4 | // Image Size : 12x11 pixels 5 | // Memory usage : 264 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const unsigned short life[132] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0800, 0x9820, 0xF820, // 0x0010 (16) pixels 18 | 0x6000, 0x0000, 0x0000, 0xE020, 0xF020, 0x9820, 0x0000, 0x0000, 0x0000, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, // 0x0020 (32) pixels 19 | 0xF820, 0xF820, 0xB020, 0x0000, 0x0000, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xB820, 0x0000, // 0x0030 (48) pixels 20 | 0x0000, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0x8820, 0x0000, 0x0000, 0x9020, 0xF820, 0xF820, // 0x0040 (64) pixels 21 | 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0x0000, 0x0000, 0x0000, 0x0000, 0xC020, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, // 0x0050 (80) pixels 22 | 0xF820, 0xC020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0800, 0xF820, 0xF820, 0xF820, 0xF820, 0xF820, 0xC820, 0x0800, 0x0000, 0x0000, // 0x0060 (96) pixels 23 | 0x0000, 0x0000, 0x0000, 0x0800, 0xF820, 0xF820, 0xF820, 0xB820, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0070 (112) pixels 24 | 0x0000, 0x9820, 0x9820, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0080 (128) pixels 25 | }; 26 | -------------------------------------------------------------------------------- /projects/ddspacewars/ricon.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : ricon.png 3 | // Time generated : Wed, 04 Nov 20 20:25:36 +0100 (Server timezone: CET) 4 | // Image Size : 8x14 pixels 5 | // Memory usage : 224 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const unsigned short ricon[112] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0x7DB1, 0x648D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x09C9, 0x0D9D, 0x053C, 0x00C4, 0x0000, 0x0000, // 0x0010 (16) pixels 18 | 0x0000, 0x0000, 0x1476, 0x332E, 0x4475, 0x026E, 0x0000, 0x0000, 0x0000, 0x0000, 0x1D5B, 0x18E4, 0x32CD, 0x0373, 0x0000, 0x0000, // 0x0020 (32) pixels 19 | 0x0000, 0x0000, 0x1DDD, 0x1456, 0x0C99, 0x03D5, 0x0000, 0x0000, 0x0000, 0x0000, 0x1DFE, 0x86DE, 0x35BD, 0x03F6, 0x0000, 0x0000, // 0x0030 (48) pixels 20 | 0x0000, 0x0000, 0x1DFE, 0x9F3E, 0x7EBE, 0x03F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x1DDD, 0x3E1D, 0x4E1D, 0x03D6, 0x0000, 0x0000, // 0x0040 (64) pixels 21 | 0x0000, 0x0000, 0x2D7B, 0x0D9D, 0x053C, 0x13F6, 0x0000, 0x0000, 0x0000, 0x1167, 0x6E1D, 0x159D, 0x0D5D, 0x6E1D, 0x0967, 0x0000, // 0x0050 (80) pixels 22 | 0x0905, 0x763D, 0x23B2, 0x24B7, 0x1436, 0x1AEF, 0x763D, 0x0905, 0x11A8, 0x228C, 0x0840, 0xF4AA, 0xC325, 0x0000, 0x22AD, 0x11C9, // 0x0060 (96) pixels 23 | 0x0000, 0x0000, 0x1861, 0xF469, 0xCB05, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0820, 0x8223, 0xA263, 0x0000, 0x0000, 0x0000, // 0x0070 (112) pixels 24 | }; 25 | -------------------------------------------------------------------------------- /projects/ddspacewars/rocket.h: -------------------------------------------------------------------------------- 1 | // Generated by : ImageConverter 565 Online 2 | // Generated from : rocket.png 3 | // Time generated : Wed, 04 Nov 20 08:34:17 +0100 (Server timezone: CET) 4 | // Image Size : 24x12 pixels 5 | // Memory usage : 576 bytes 6 | 7 | 8 | #if defined(__AVR__) 9 | #include 10 | #elif defined(__PIC32MX__) 11 | #define PROGMEM 12 | #elif defined(__arm__) 13 | #define PROGMEM 14 | #endif 15 | 16 | const uint16_t rocket[288] PROGMEM={ 17 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0946, 0x0082, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0010 (16) pixels 18 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0021, 0x765D, 0x65DB, 0x0987, // 0x0020 (32) pixels 19 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0030 (48) pixels 20 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2B50, 0x7E5D, 0x6E1C, 0x08E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0040 (64) pixels 21 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x11C9, 0x6E3D, // 0x0050 (80) pixels 22 | 0x65FC, 0x3519, 0x259C, 0x25FD, 0x25FE, 0x25FE, 0x25FE, 0x25FD, 0x259C, 0x1D19, 0x1435, 0x0A4B, 0x0021, 0x0000, 0x0000, 0x0000, // 0x0060 (96) pixels 23 | 0x0000, 0x0000, 0x3902, 0xCBA7, 0xC3A8, 0x92C6, 0x2434, 0x25BD, 0x5E1D, 0x25BD, 0x15BD, 0x25DE, 0x4E5E, 0x565E, 0x361E, 0x15BE, // 0x0070 (112) pixels 24 | 0x1C97, 0x234F, 0x2C96, 0x15BD, 0x159C, 0x338F, 0x1081, 0x0000, 0x0000, 0x6181, 0xDB85, 0xF448, 0xF48A, 0xF48A, 0x2C34, 0x057D, // 0x0080 (128) pixels 25 | 0x057D, 0x057D, 0x057D, 0x6E9D, 0xA75E, 0xB79F, 0x76BE, 0x0D3B, 0x18E3, 0x18C3, 0x31A6, 0x253A, 0x057D, 0x3DB8, 0xF645, 0xFF80, // 0x0090 (144) pixels 26 | 0x0000, 0xDB24, 0xE365, 0xE386, 0xE3C7, 0xE3C7, 0x23F3, 0x053D, 0x053D, 0x053D, 0x053D, 0x6E9D, 0x767E, 0xA73E, 0x053D, 0x053C, // 0x00A0 (160) pixels 27 | 0x324A, 0x3186, 0x5B4D, 0x255B, 0x053D, 0x3577, 0xFF80, 0x41A0, 0x0000, 0x0000, 0x1040, 0x30C1, 0x38E1, 0x30A1, 0x0AAE, 0x151B, // 0x00B0 (176) pixels 28 | 0x5DFD, 0x1D3C, 0x04FC, 0x35BC, 0x255C, 0x45DD, 0x04FC, 0x04FC, 0x04FC, 0x2D1A, 0x1D3C, 0x04FC, 0x0416, 0x11C8, 0x0000, 0x0000, // 0x00C0 (192) pixels 29 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x11A8, 0x763D, 0x65FC, 0x1BB3, 0x0311, 0x0353, 0x0374, 0x0374, 0x0374, 0x0353, // 0x00D0 (208) pixels 30 | 0x0311, 0x02AF, 0x01CA, 0x0083, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2B71, 0x7E5D, 0x6DFC, // 0x00E0 (224) pixels 31 | 0x08C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00F0 (240) pixels 32 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x7E5D, 0x65DB, 0x0967, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0100 (256) pixels 33 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0967, 0x0082, 0x0000, // 0x0110 (272) pixels 34 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0120 (288) pixels 35 | }; 36 | -------------------------------------------------------------------------------- /projects/esp32tensorflowlite/helloworld/helloworld.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "tensorflow/lite/micro/all_ops_resolver.h" 4 | #include "tensorflow/lite/micro/micro_error_reporter.h" 5 | #include "tensorflow/lite/micro/micro_interpreter.h" 6 | #include "tensorflow/lite/schema/schema_generated.h" 7 | 8 | 9 | #include "sine_model_data.cc" 10 | 11 | 12 | // Set up logging 13 | tflite::MicroErrorReporter micro_error_reporter; 14 | tflite::ErrorReporter* error_reporter = µ_error_reporter; 15 | 16 | 17 | // Map the model into a usable data structure. This doesn't involve any 18 | // copying or parsing, it's a very lightweight operation. 19 | const tflite::Model* model = ::tflite::GetModel(g_sine_model_data); 20 | 21 | // This pulls in all the operation implementations we need 22 | tflite::AllOpsResolver resolver; 23 | 24 | // Create an area of memory to use for input, output, and intermediate arrays. 25 | // Finding the minimum value for your model may require some trial and error. 26 | const int tensor_arena_size = 2 * 1024; 27 | uint8_t tensor_arena[tensor_arena_size]; 28 | 29 | 30 | // Build an interpreter to run the model with 31 | tflite::MicroInterpreter interpreter(model, resolver, tensor_arena, 32 | tensor_arena_size, error_reporter); 33 | 34 | 35 | // Obtain a pointer to the model's input tensor 36 | TfLiteTensor* input; 37 | 38 | 39 | 40 | void setup() { 41 | Serial.begin(115200); 42 | 43 | // Allocate memory from the tensor_arena for the model's tensors 44 | interpreter.AllocateTensors(); 45 | 46 | // Obtain a pointer to the model's input tensor 47 | input = interpreter.input(0); 48 | } 49 | 50 | 51 | float in = -1.5; 52 | 53 | void loop() { 54 | delay(1000); 55 | // Serial.println("==="); 56 | // Serial.print(". MODEL DESC:"); 57 | // Serial.println(model->description()->c_str()); 58 | 59 | //float in = 3.14 * ((float) rand() / (float) RAND_MAX); 60 | 61 | // Provide an input value 62 | input->data.f[0] = in; 63 | 64 | // Run the model on this input and check that it succeeds 65 | TfLiteStatus invoke_status = interpreter.Invoke(); 66 | if (invoke_status != kTfLiteOk) { 67 | error_reporter->Report("Invoke failed\n"); 68 | } 69 | 70 | TfLiteTensor* output = interpreter.output(0); 71 | 72 | // Obtain the output value from the tensor 73 | float out = output->data.f[0]; 74 | 75 | Serial.print("X:"); 76 | Serial.print(in); 77 | Serial.print(" y:"); 78 | Serial.println(out); 79 | 80 | in += 0.1; 81 | } 82 | -------------------------------------------------------------------------------- /projects/espspacewars/Misc.h: -------------------------------------------------------------------------------- 1 | const long DueGapMillis = 40; 2 | 3 | 4 | class Position 5 | { 6 | public: 7 | Position() 8 | { 9 | reset(0, 0); 10 | } 11 | Position(float pos_x, float pos_y) 12 | { 13 | reset(pos_x, pos_y); 14 | } 15 | 16 | public: 17 | void moveBy(float inc_x, float inc_y) 18 | { 19 | this->pos_x += inc_x; 20 | this->pos_y += inc_y; 21 | this->last_x = this->x; 22 | this->last_y = this->y; 23 | this->x = this->pos_x; 24 | this->y = this->pos_y; 25 | if (last_valid) 26 | { 27 | this->moved = this->last_x != this->x || this->last_y != this->y; 28 | } 29 | else 30 | { 31 | this->last_valid = true; 32 | this->moved = true; 33 | } 34 | } 35 | void moveTo(float pos_x, float pos_y) 36 | { 37 | this->pos_x = pos_x; 38 | this->pos_y = pos_y; 39 | this->x = this->pos_x; 40 | this->y = this->pos_y; 41 | if (last_valid) 42 | { 43 | this->moved = this->last_x != this->x || this->last_y != this->y; 44 | } 45 | else 46 | { 47 | this->last_valid = true; 48 | this->moved = true; 49 | } 50 | } 51 | void moveXTo(float pos_x) 52 | { 53 | moveTo(pos_x, this->pos_y); 54 | } 55 | void moveYTo(float pos_y) 56 | { 57 | moveTo(this->pos_x, pos_y); 58 | } 59 | bool checkMoved() 60 | { 61 | bool res = this->moved; 62 | this->moved = false; 63 | return res; 64 | } 65 | void reset(float pos_x, float pos_y) 66 | { 67 | this->pos_x = pos_x; 68 | this->pos_y = pos_y; 69 | this->x = this->pos_x; 70 | this->y = this->pos_y; 71 | this->last_valid = false; 72 | this->moved = true; 73 | } 74 | inline int getX() { return this->x; } 75 | inline int getY() { return this->y; } 76 | 77 | private: 78 | float pos_x; 79 | float pos_y; 80 | int x; 81 | int y; 82 | bool last_valid; 83 | int last_x; 84 | int last_y; 85 | bool moved; 86 | }; 87 | 88 | class PositionGroup 89 | { 90 | public: 91 | PositionGroup(Position *positions, int positionCount) 92 | { 93 | this->positions = positions; 94 | this->positionCount = positionCount; 95 | } 96 | 97 | public: 98 | void resetAll(float pos_x, float pos_y) 99 | { 100 | for (int i = 0; i < this->positionCount; i++) 101 | { 102 | Position *position = this->positions + i; 103 | position->reset(pos_x, pos_y); 104 | } 105 | } 106 | bool checkAnyMoved() 107 | { 108 | bool moved = false; 109 | for (int i = 0; i < this->positionCount; i++) 110 | { 111 | Position *position = this->positions + i; 112 | if (position->checkMoved()) 113 | { 114 | moved = true; 115 | } 116 | } 117 | return moved; 118 | } 119 | 120 | private: 121 | Position *positions; 122 | int positionCount; 123 | }; 124 | 125 | class FrameControl 126 | { 127 | public: 128 | FrameControl() 129 | { 130 | reset(); 131 | } 132 | 133 | public: 134 | bool checkDue() 135 | { 136 | long nowMillis = millis(); 137 | bool due = (this->nextDueMillis - nowMillis) <= 0; 138 | if (due) 139 | { 140 | if (this->nextDueMillis == 0) 141 | { 142 | this->nextDueMillis = nowMillis; 143 | } 144 | this->nextDueMillis += DueGapMillis; 145 | #if defined(DEBUG_LED_PIN) 146 | int status = (this->nextDueMillis - nowMillis) > 10 ? 1 : 0; 147 | digitalWrite(DEBUG_LED_PIN, status); 148 | #endif 149 | } 150 | if (due) 151 | { 152 | this->frameNum += 1; 153 | } 154 | return due; 155 | } 156 | inline long getFrameNum() 157 | { 158 | return this->frameNum; 159 | } 160 | void reset() 161 | { 162 | this->nextDueMillis = 0; 163 | this->frameNum = 0; 164 | } 165 | 166 | private: 167 | long nextDueMillis; 168 | long frameNum; 169 | }; 170 | -------------------------------------------------------------------------------- /projects/espvoicecommander/esp01_voicecommandagent/esp01_voicecommandagent.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | 6 | // a convenient macro for checking ESP Now result status 7 | #define ESP_OK 0 8 | 9 | 10 | #define FAN_PIN 0 11 | 12 | 13 | 14 | // define a structure as ESP Now packet (the same as server) 15 | struct ESPNowCommandPacket { 16 | char commandTarget[32]; 17 | char commandAction[32]; 18 | }; 19 | 20 | 21 | void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) { 22 | ESPNowCommandPacket receivedPacket; 23 | memcpy(&receivedPacket, incomingData, sizeof(receivedPacket)); 24 | String commandTarget = receivedPacket.commandTarget; 25 | String commandAction = receivedPacket.commandAction; 26 | Serial.println(String("* Received command for [") + commandTarget + "] to [" + commandAction + "]"); 27 | if (commandTarget == "fan") { 28 | if (commandAction == "on") { 29 | digitalWrite(FAN_PIN, 1); 30 | Serial.println("- turned on fan"); 31 | } else if (commandAction == "off") { 32 | digitalWrite(FAN_PIN, 0); 33 | Serial.println("- turned off fan"); 34 | } 35 | } 36 | } 37 | 38 | void setup() { 39 | Serial.begin(115200); 40 | 41 | Serial.println("*****"); 42 | Serial.println(String("* agent MAC is ") + WiFi.macAddress()); 43 | Serial.println("*****"); 44 | 45 | 46 | pinMode(FAN_PIN, OUTPUT); 47 | 48 | // Set device as a Wi-Fi Station 49 | WiFi.mode(WIFI_STA); 50 | 51 | // Init ESP-NOW 52 | if (esp_now_init() == ESP_OK) { 53 | Serial.println("Done initializing ESP-NOW"); 54 | } else { 55 | Serial.println("Error initializing ESP-NOW"); 56 | } 57 | 58 | // Register "receive callback" 59 | if (esp_now_register_recv_cb(OnDataRecv) == ESP_OK) { 60 | Serial.println("Done registering receive callback"); 61 | } else { 62 | Serial.println("Error registering receive callback"); 63 | } 64 | } 65 | 66 | long lastShowIdleMillis = 0; 67 | void loop() { 68 | long nowMillis = millis(); 69 | if ((nowMillis - lastShowIdleMillis) >= 5000) { 70 | Serial.println(String("ESP01 agent MAC is ") + WiFi.macAddress()); 71 | lastShowIdleMillis = nowMillis; 72 | } 73 | } -------------------------------------------------------------------------------- /projects/numinvader/numinvader.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define BLUETOOTH 4 | 5 | #ifdef BLUETOOTH 6 | #include "ssdumbdisplay.h" 7 | // assume HC-05 connected; 2 => TX of HC05; 3 => RX of HC05 8 | // still can connect with OTG 9 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true, 115200)); 10 | #else 11 | #include "dumbdisplay.h" 12 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 13 | #endif 14 | 15 | 16 | 17 | #define BUTTON_LEFT PIN_A1 18 | #define BUTTON_RIGHT PIN_A4 19 | 20 | #define LED_LEFT PIN_A2 21 | #define LED_RIGHT PIN_A3 22 | 23 | #include "gameobjs.h" // for game objects 24 | 25 | 26 | 27 | // game objects, defined in gameobjs.h 28 | LaserGun laserGun; 29 | Invaders invaders; 30 | Controller controller(laserGun, invaders); 31 | 32 | 33 | void setup() { 34 | pinMode(BUTTON_LEFT, INPUT_PULLUP); 35 | pinMode(BUTTON_RIGHT, INPUT_PULLUP); 36 | pinMode(LED_LEFT, OUTPUT); 37 | pinMode(LED_RIGHT, OUTPUT); 38 | 39 | laserGun.life7Seg = dumbdisplay.create7SegmentRowLayer(1); 40 | laserGun.life7Seg->segmentColor("green"); 41 | laserGun.life7Seg->border(5, "green", "round"); 42 | laserGun.life7Seg->padding(5); 43 | 44 | laserGun.laserGun7Seg = dumbdisplay.create7SegmentRowLayer(1); 45 | laserGun.laserGun7Seg->segmentColor("blue"); 46 | laserGun.laserGun7Seg->backgroundColor("yellow"); 47 | laserGun.laserGun7Seg->border(5, "blue", "round"); 48 | laserGun.laserGun7Seg->padding(5); 49 | 50 | invaders.invader7Seg = dumbdisplay.create7SegmentRowLayer(MAX_INVADER_COUNT); 51 | invaders.invader7Seg->segmentColor("red"); 52 | invaders.invader7Seg->border(5, "red", "round"); 53 | invaders.invader7Seg->padding(5); 54 | 55 | // 'pin' the layers (7 segment displays) one by one horizontally 56 | // note that tomtommap is not visible initially 57 | dumbdisplay.configAutoPin(DD_AP_HORI); 58 | 59 | controller.initialize(); 60 | } 61 | 62 | 63 | void loop() { 64 | controller.loop(); 65 | } -------------------------------------------------------------------------------- /projects/numinvader/sound.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | extern DumbDisplay dumbdisplay; // there will be a dumbdisplay elsewhere 5 | 6 | void PlayHitSoundEffect() { 7 | dumbdisplay.tone(1000, 50); 8 | dumbdisplay.tone(800, 50); 9 | } 10 | void PlayMissSoundEffect() { 11 | dumbdisplay.tone(500, 50); 12 | dumbdisplay.tone(700, 50); 13 | } 14 | void PlayMissLifeSoundEffect() { 15 | dumbdisplay.tone(600, 50); 16 | dumbdisplay.tone(500, 50); 17 | dumbdisplay.tone(400, 50); 18 | dumbdisplay.tone(300, 50); 19 | } 20 | void PlayEndGameSoundEffect() { 21 | dumbdisplay.tone(200, 100); 22 | dumbdisplay.tone(400, 200); 23 | dumbdisplay.tone(300, 200); 24 | dumbdisplay.tone(600, 100); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /projects/numinvader/tracker.h: -------------------------------------------------------------------------------- 1 | class ButtonPressTracker { 2 | public: 3 | ButtonPressTracker() { 4 | this->pressed = false; // assume initially not pressed 5 | this->blackOutMillis = 0; 6 | } 7 | int setPressed(bool pressed) { 8 | long nowMillis = millis(); 9 | if (blackOutMillis != 0) { 10 | long diff = blackOutMillis - nowMillis; 11 | if (diff < 0) { 12 | blackOutMillis = 0; 13 | } 14 | } 15 | if (blackOutMillis == 0) { 16 | if (pressed != this->pressed) { 17 | this->pressed = pressed; 18 | blackOutMillis = nowMillis + 50; 19 | return this->pressed ? 1 : 0; 20 | } 21 | } 22 | return -1; 23 | } 24 | private: 25 | bool pressed; 26 | long blackOutMillis; 27 | }; 28 | -------------------------------------------------------------------------------- /projects/picouart1blink/picouart1blink.ino: -------------------------------------------------------------------------------- 1 | #define DD_4_PICO_TX 8 2 | #define DD_4_PICO_RX 9 3 | 4 | #include "picodumbdisplay.h" 5 | 6 | /* HC-06 connectivity */ 7 | DumbDisplay dumbdisplay(new DDPicoSerialIO(DD_4_PICO_TX, DD_4_PICO_RX)); 8 | LedGridDDLayer *led; 9 | 10 | void setup() { 11 | // create a LED layer 12 | led = dumbdisplay.createLedGridLayer(); 13 | } 14 | 15 | void loop() { 16 | led->toggle(); 17 | delay(1000); 18 | } 19 | -------------------------------------------------------------------------------- /projects/twatch/twatchblink/twatchblink.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void setup() { 4 | // create the T-Watch API object 5 | TTGOClass *ttgo = TTGOClass::getWatch(); 6 | 7 | // init the T-Watch API object 8 | ttgo->begin(); 9 | ttgo->openBL(); 10 | 11 | // from the T-Watch API object, get the TFT_eSPI object 12 | TFT_eSPI& tft = *ttgo->tft; 13 | 14 | tft.fillScreen(TFT_LIGHTGREY); 15 | } 16 | 17 | void loop() { 18 | // get the T-Watch API object (only the first call will create) 19 | TTGOClass *ttgo = TTGOClass::getWatch(); 20 | 21 | // from the T-Watch API object, get the TFT_eSPI object 22 | TFT_eSPI& tft = *ttgo->tft; 23 | 24 | tft.fillCircle(120, 120, 30, TFT_PURPLE); 25 | delay(1000); 26 | tft.fillCircle(120, 120, 30, TFT_LIGHTGREY); 27 | delay(1000); 28 | } -------------------------------------------------------------------------------- /samples/dd7seg/dd7seg.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | 4 | /* for connection, please use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 */ 5 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 6 | 7 | 8 | SevenSegmentRowDDLayer *sevenSeg; 9 | 10 | 11 | void setup() { 12 | sevenSeg = dumbdisplay.create7SegmentRowLayer(1); 13 | } 14 | 15 | void loop() { 16 | 17 | String segs[] = { "g", "f", "a", "b", "e", "d", "c", "." }; 18 | for (int i = 0; i < 8; i++) { 19 | sevenSeg->turnOn(segs[i]); 20 | delay(1000); 21 | } 22 | 23 | char c = '0'; 24 | while (1) { 25 | if (c == '.') { 26 | sevenSeg->setOn("."); 27 | c = '?'; 28 | } else if (c == '?') { 29 | sevenSeg->showFormatted("E"); 30 | c = '0'; 31 | } else { 32 | sevenSeg->showNumber(c - '0'); 33 | if (c == '9') 34 | c = '.'; 35 | else 36 | c = c + 1; 37 | } 38 | delay(1000); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /samples/ddautopin/ddautopin.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | // for connection 4 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 5 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 6 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 7 | 8 | 9 | LedGridDDLayer *rled; 10 | LedGridDDLayer *gled; 11 | LedGridDDLayer *bled; 12 | LedGridDDLayer *hmeter; 13 | LedGridDDLayer *vmeter; 14 | LcdDDLayer *lcd; 15 | 16 | int count = 20; 17 | 18 | void setup() { 19 | // create R + G + B LED layers 20 | rled = dumbdisplay.createLedGridLayer(); 21 | gled = dumbdisplay.createLedGridLayer(); 22 | bled = dumbdisplay.createLedGridLayer(); 23 | 24 | // create LED layers that will be used for "horizontal bar-meter" 25 | hmeter = dumbdisplay.createLedGridLayer(2 * count, 1, 1, 5); 26 | // create LED layers that will be used for "vertical bar-meter" 27 | vmeter = dumbdisplay.createLedGridLayer(1, 2 * count, 5, 1); 28 | 29 | // create a LCD layers with 2 rows of 16 characters 30 | lcd = dumbdisplay.createLcdLayer(16, 2); 31 | 32 | // configure to "auto pin" the different layers 33 | // -- end result of DD_AP_XXX(...) is the layout spec "H(V(0+1+2)+V(3+5)+4)" 34 | // -- . H/V: layout direction 35 | // -- . 0/1/2/3/4/5: layer id 36 | dumbdisplay.configAutoPin(DD_AP_HORI_3( 37 | DD_AP_VERT_3(rled->getLayerId(), gled->getLayerId(), bled->getLayerId()), 38 | DD_AP_VERT_2(hmeter->getLayerId(), lcd->getLayerId()), 39 | vmeter->getLayerId())); 40 | 41 | 42 | // setup RGB leds color and turn them on 43 | rled->onColor("red"); 44 | gled->onColor("green"); 45 | bled->onColor("blue"); 46 | rled->turnOn(); 47 | gled->turnOn(); 48 | bled->turnOn(); 49 | 50 | // set "bar meters" colors 51 | hmeter->onColor("blue"); 52 | hmeter->offColor("yellow"); 53 | hmeter->backgroundColor("black"); 54 | vmeter->onColor("green"); 55 | vmeter->offColor("lightgray"); 56 | vmeter->backgroundColor("blue"); 57 | 58 | // set LCD colors and print out something 59 | lcd->pixelColor("red"); 60 | lcd->bgPixelColor("lightgreen"); 61 | lcd->backgroundColor("black"); 62 | lcd->print("hello world"); 63 | lcd->setCursor(0, 1); 64 | lcd->print("how are you?"); 65 | } 66 | 67 | void loop() { 68 | delay(1000); 69 | if (random(2) == 0) { 70 | lcd->scrollDisplayLeft(); 71 | count--; 72 | } else { 73 | lcd->scrollDisplayRight(); 74 | count++; 75 | } 76 | hmeter->horizontalBar(count); 77 | vmeter->verticalBar(count); 78 | if (random(2) == 0) 79 | rled->toggle(); 80 | if (random(2) == 0) 81 | gled->toggle(); 82 | if (random(2) == 0) 83 | bled->toggle(); 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /samples/ddbarmeter/ddbarmeter.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | // for connection 4 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 5 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 6 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 7 | 8 | 9 | void setup() { 10 | // configure to "auto pin (layout) layers" in the vertical direction 11 | dumbdisplay.configAutoPin(DD_AP_VERT); 12 | 13 | // create a LED layer 14 | LedGridDDLayer *led = dumbdisplay.createLedGridLayer(3, 1); 15 | // turn on LEDs 16 | led->onColor("red"); 17 | led->turnOn(0, 0); 18 | led->onColor("green"); 19 | led->turnOn(1, 0); 20 | led->onColor("blue"); 21 | led->turnOn(2, 0); 22 | 23 | // create LED layers that will be used for "horizontal bar-meter" 24 | // with max "bar" size 32 25 | LedGridDDLayer *barmeter = dumbdisplay.createLedGridLayer(32, 1, 1, 5); 26 | barmeter->onColor("darkblue"); 27 | barmeter->offColor("lightgreen"); 28 | // set the "bar" to 10 (ie. 10 of total 32) 29 | barmeter->horizontalBar(10); 30 | 31 | 32 | // create a LCD layer 33 | LcdDDLayer * lcd = dumbdisplay.createLcdLayer(); 34 | // write to LCD write messages (as lines) 35 | // notice that "C" means center-align 36 | lcd->writeLine("Hello There!", 0, "C"); 37 | lcd->writeLine("How are you?", 1, "C"); 38 | 39 | } 40 | 41 | void loop() { 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /samples/ddblink/ddblink.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | /* for connection, please use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 */ 4 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 5 | LedGridDDLayer *led; 6 | 7 | void setup() { 8 | // create a LED layer 9 | led = dumbdisplay.createLedGridLayer(); 10 | } 11 | 12 | void loop() { 13 | led->toggle(); 14 | delay(1000); 15 | } 16 | -------------------------------------------------------------------------------- /samples/ddborder/ddborder.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | /* for connection, please use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 */ 4 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 5 | 6 | 7 | void setup() { 8 | for (int i = 0; i < 4; i++) { 9 | const char* borderType; 10 | if (i == 0) borderType = "raised"; 11 | else if (i == 1) borderType = "sunken"; 12 | else if (i == 2) borderType = "round"; 13 | else borderType = "flat"; 14 | LcdDDLayer* pLcdLayer = dumbdisplay.createLcdLayer(8, 1); 15 | pLcdLayer->backgroundColor(DD_RGB_COLOR(222, 222, 222)); 16 | pLcdLayer->writeCenteredLine(borderType, 0); 17 | pLcdLayer->border(1.5, "gray", borderType); 18 | } 19 | dumbdisplay.configAutoPin(DD_AP_VERT); 20 | } 21 | 22 | void loop() { 23 | } -------------------------------------------------------------------------------- /samples/ddcolors/ddcolors.ino: -------------------------------------------------------------------------------- 1 | 2 | //#define DD_DISABLE_PARAM_ENCODING 3 | 4 | 5 | #if defined(BLUETOOTH) 6 | 7 | #include "esp32dumbdisplay.h" 8 | DumbDisplay dumbdisplay(new DDBluetoothSerialIO(BLUETOOTH, true)); 9 | 10 | #elif defined(WIFI_SSID) 11 | 12 | #include "wifidumbdisplay.h" 13 | DumbDisplay dumbdisplay(new DDWiFiServerIO(WIFI_SSID, WIFI_PASSWORD)); 14 | #else 15 | 16 | #include "dumbdisplay.h" 17 | DumbDisplay dumbdisplay(new DDInputOutput()); 18 | 19 | #endif 20 | 21 | GraphicalDDLayer *graphicalLayer; 22 | 23 | 24 | const char* colors[] = { 25 | 26 | DD_COLOR_red, 27 | DD_COLOR_green, 28 | DD_COLOR_blue, 29 | DD_COLOR_yellow, 30 | DD_COLOR_magenta, 31 | DD_COLOR_cyan, 32 | DD_COLOR_white, 33 | DD_COLOR_black, 34 | DD_COLOR_orange, 35 | DD_COLOR_pink, 36 | DD_COLOR_gray, 37 | DD_COLOR_darkgray, 38 | DD_COLOR_lightgray, 39 | DD_COLOR_brown, 40 | DD_COLOR_purple, 41 | DD_COLOR_darkgreen, 42 | DD_COLOR_darkblue, 43 | DD_COLOR_indigo, 44 | DD_COLOR_lightgreen, 45 | DD_COLOR_darkred, 46 | DD_COLOR_lightblue, 47 | DD_COLOR_darkorange, 48 | DD_COLOR_darkviolet, 49 | DD_COLOR_violet, 50 | DD_COLOR_lightcyan, 51 | 52 | DD_COLOR_azure, 53 | DD_COLOR_plum, 54 | DD_COLOR_gold, 55 | DD_COLOR_teal, 56 | DD_COLOR_ivory, 57 | DD_COLOR_coral, 58 | DD_COLOR_beige, 59 | DD_COLOR_snow, 60 | DD_COLOR_aqua, 61 | DD_COLOR_lemonchiffon, 62 | DD_COLOR_navy, 63 | DD_COLOR_midnightblue, 64 | DD_COLOR_aliceblue, 65 | DD_COLOR_antiquewhite, 66 | DD_COLOR_bisque, 67 | DD_COLOR_cornsilk, 68 | DD_COLOR_crimson, 69 | DD_COLOR_maroon, 70 | DD_COLOR_olive, 71 | DD_COLOR_salmon, 72 | DD_COLOR_silver, 73 | DD_COLOR_skyblue, 74 | DD_COLOR_snow, 75 | DD_COLOR_tomato, 76 | DD_COLOR_turquoise, 77 | DD_COLOR_wheat, 78 | DD_COLOR_whitesmoke, 79 | DD_COLOR_tan, 80 | DD_COLOR_springgreen, 81 | DD_COLOR_steelblue, 82 | DD_COLOR_slategray, 83 | DD_COLOR_slateblue, 84 | DD_COLOR_seashell, 85 | DD_COLOR_royalblue, 86 | DD_COLOR_rosybrown, 87 | DD_COLOR_peru, 88 | DD_COLOR_chartreuse, 89 | DD_COLOR_chocolate, 90 | DD_COLOR_greenyellow, 91 | DD_COLOR_honeydew, 92 | DD_COLOR_hotpink, 93 | DD_COLOR_indianred, 94 | DD_COLOR_khaki, 95 | DD_COLOR_lavender 96 | }; 97 | 98 | 99 | const int circleRadius = 10; 100 | const int colorCount = sizeof(colors) / sizeof(colors[0]); 101 | const int circlePadding = 2; 102 | const int circleWidth = 2 * (circlePadding + circleRadius); 103 | const int circleHeight = circleWidth; 104 | 105 | int rowColorCount; 106 | int width; 107 | int height; 108 | 109 | void setup() { 110 | rowColorCount = 1 + sqrt(colorCount); 111 | 112 | width = circleWidth * rowColorCount; 113 | height = width; 114 | 115 | graphicalLayer = dumbdisplay.createGraphicalLayer(width, height); 116 | #if defined(DD_DISABLE_PARAM_ENCODING) 117 | graphicalLayer->border(5, DD_COLOR_black, "round"); 118 | #else 119 | graphicalLayer->border(5, DD_COLOR_blue, "round"); 120 | #endif 121 | 122 | int x = 0; 123 | int y = 0; 124 | for (int i = 0; i < colorCount; i++) { 125 | const char* color = colors[i]; 126 | int cx = x + circlePadding + circleRadius; 127 | int cy = y + circlePadding + circleRadius; 128 | graphicalLayer->fillCircle(cx, cy, circleRadius, color); 129 | x += circleWidth; 130 | if (x >= width) { 131 | x = 0; 132 | y += circleHeight; 133 | } 134 | } 135 | } 136 | 137 | 138 | int bgColorIdx = 0; 139 | void loop() { 140 | graphicalLayer->backgroundColor(colors[bgColorIdx]); 141 | delay(500); 142 | bgColorIdx += 1; 143 | if (bgColorIdx >= colorCount) { 144 | bgColorIdx = 0; 145 | } 146 | } 147 | 148 | -------------------------------------------------------------------------------- /samples/dddoodle/dddoodle.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | // for connection 4 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 5 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 6 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 7 | 8 | 9 | int dotSize = 5; 10 | const char* penColor = "red"; 11 | TurtleDDLayer* pTurtleLayer = NULL; 12 | LcdDDLayer* pLcdLayer = NULL; 13 | LedGridDDLayer* pLedGridLayer = NULL; 14 | 15 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback) { 16 | int x = feedback.x; 17 | int y = feedback.y; 18 | if (pLayer == pLcdLayer) { 19 | // clicked the "clear" button 20 | pLayer->backgroundColor("white"); 21 | Reset(); 22 | delay(100); 23 | pLayer->backgroundColor("lightgray"); 24 | } else if (pLayer == pLedGridLayer) { 25 | // clicked one of the 3 color options 26 | const char* color = NULL; 27 | if (x == 0) 28 | color = "red"; 29 | else if (x == 1) 30 | color = "green"; 31 | else if (x == 2) 32 | color = "blue"; 33 | if (color != NULL) { 34 | pLedGridLayer->turnOff(x, 0); 35 | delay(100); 36 | pLedGridLayer->onColor(color); 37 | pLedGridLayer->turnOn(x, 0); 38 | penColor = color; 39 | pTurtleLayer->penColor(penColor); 40 | pTurtleLayer->dot(dotSize, penColor); 41 | } 42 | } else { 43 | // very simple doodle 44 | pTurtleLayer->goTo(x, y); 45 | pTurtleLayer->dot(dotSize, penColor); 46 | } 47 | } 48 | 49 | void Reset() { 50 | pTurtleLayer->clear(); 51 | pTurtleLayer->penSize(2); 52 | pTurtleLayer->penColor(penColor); 53 | pTurtleLayer->home(false); 54 | pTurtleLayer->dot(dotSize, penColor); 55 | } 56 | 57 | 58 | void setup() { 59 | // use a Turtle layer for very simple doodle 60 | pTurtleLayer = dumbdisplay.createTurtleLayer(201, 201); 61 | pTurtleLayer->setFeedbackHandler(FeedbackHandler, "fs"); 62 | pTurtleLayer->backgroundColor("azure"); 63 | pTurtleLayer->fillColor("lemonchiffon"); 64 | 65 | // use a LED layer for the "clear" button 66 | pLcdLayer = dumbdisplay.createLcdLayer(5, 1); 67 | pLcdLayer->setFeedbackHandler(FeedbackHandler); 68 | pLcdLayer->backgroundColor("lightgray"); 69 | pLcdLayer->print("CLEAR"); 70 | pLcdLayer->border(2, "gray", "round"); 71 | 72 | // use a LED-grid layers for the 3 color options -- red, green and blue 73 | pLedGridLayer = dumbdisplay.createLedGridLayer(3); 74 | pLedGridLayer->setFeedbackHandler(FeedbackHandler); 75 | pLedGridLayer->onColor("red"); 76 | pLedGridLayer->turnOn(0); 77 | pLedGridLayer->onColor("green"); 78 | pLedGridLayer->turnOn(1); 79 | pLedGridLayer->onColor("blue"); 80 | pLedGridLayer->turnOn(2); 81 | 82 | // layout the different layers 83 | dumbdisplay.configAutoPin(DD_AP_VERT_2( 84 | DD_AP_HORI_5( 85 | DD_AP_SPACER(1, 1), 86 | pLedGridLayer->getLayerId(), 87 | DD_AP_SPACER(2, 1), 88 | pLcdLayer->getLayerId(), 89 | DD_AP_SPACER(1, 1)), 90 | pTurtleLayer->getLayerId())); 91 | 92 | 93 | 94 | Reset(); 95 | } 96 | 97 | 98 | void loop() { 99 | // give DD chances to capture feedback 100 | DDDelay(1000); 101 | dumbdisplay.writeComment("... looping ..."); 102 | } -------------------------------------------------------------------------------- /samples/ddfonts/ddfonts.ino: -------------------------------------------------------------------------------- 1 | // ********** 2 | // *** DumbDisplay app supports selected fonts downloadable from Google: https://fonts.google.com/ 3 | // *** Regular and monospace: 4 | // *** . B612, Cutive, Noto Sans, Oxygen, Roboto, Share Tech, Spline Sans, Ubuntu 5 | // *** In order to ensure that these Google's fonts are ready when they are used, please check Settings | Pre-Download Fonts 6 | // ********* 7 | 8 | #include "ssdumbdisplay.h" 9 | 10 | 11 | #define USE_BLUETOOTH 12 | 13 | #ifdef USE_BLUETOOTH 14 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true, 115200)); 15 | #else 16 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 17 | #endif 18 | 19 | void setup() { 20 | 21 | // create a graphical [LCD] layer 22 | GraphicalDDLayer *graphical = dumbdisplay.createGraphicalLayer(150, 300); 23 | graphical->backgroundColor("lightgray"); 24 | graphical->setTextColor("blue"); 25 | 26 | char* fonts[] = { "B612", "Cutive", "Noto Sans", "Oxygen", "Roboto", "Share Tech", "Spline Sans", "Ubuntu" }; 27 | 28 | // regular 29 | graphical->setTextFont(); 30 | graphical->println("REGULAR:"); 31 | for (int i = 0; i < sizeof(fonts) / 2; i++) { 32 | graphical->setTextFont(); 33 | graphical->print(". "); 34 | String fontName = String(fonts[i]); // font-name like: Roboto 35 | graphical->setTextFont("DL::" + fontName); // add prefix "DL:" 36 | graphical->println(fontName); 37 | } 38 | 39 | // monospace 40 | graphical->setTextFont(); 41 | graphical->println(); 42 | graphical->println("MONOSPACE:"); 43 | for (int i = 0; i < sizeof(fonts) / 2; i++) { 44 | graphical->setTextFont(); 45 | graphical->print(". "); 46 | String fontName = String(fonts[i]) + " Mono"; // font-name like: Roboto Mono 47 | graphical->setTextFont("DL::" + fontName); // add prefix "DL:" 48 | graphical->println(fontName); 49 | } 50 | } 51 | 52 | void loop() { 53 | 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /samples/ddgraphical/ddgraphical.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | #if defined(ESP32) 4 | 5 | #if defined(BLUETOOTH) 6 | #include "esp32dumbdisplay.h" 7 | DumbDisplay dumbdisplay(new DDBluetoothSerialIO(BLUETOOTH)); 8 | #elif defined(WIFI_SSID) 9 | #include "wifidumbdisplay.h" 10 | DumbDisplay dumbdisplay(new DDWiFiServerIO(WIFI_SSID, WIFI_PASSWORD)); 11 | #else 12 | #include "dumbdisplay.h" 13 | DumbDisplay dumbdisplay(new DDInputOutput()); 14 | #endif 15 | 16 | #else 17 | 18 | #ifdef BLUETOOTH 19 | // assume HC-06 connected; 2 => TX of HC06; 3 => RX of HC06 20 | #include "ssdumbdisplay.h" 21 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true)); 22 | #else 23 | // otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 24 | #include "dumbdisplay.h" 25 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 26 | #endif 27 | 28 | #endif 29 | 30 | 31 | 32 | void setup() { 33 | // create 4 graphical [LCD] layers 34 | GraphicalDDLayer *pLayer1 = dumbdisplay.createGraphicalLayer(151, 101); 35 | GraphicalDDLayer *pLayer2 = dumbdisplay.createGraphicalLayer(151, 101); 36 | GraphicalDDLayer *pLayer3 = dumbdisplay.createGraphicalLayer(151, 101); 37 | GraphicalDDLayer *pLayer4 = dumbdisplay.createGraphicalLayer(151, 101); 38 | 39 | // set fill screen with color 40 | pLayer1->fillScreen(DD_COLOR_azure); 41 | pLayer2->fillScreen(DD_COLOR_azure); 42 | pLayer3->fillScreen(DD_COLOR_azure); 43 | pLayer4->fillScreen(DD_COLOR_azure); 44 | 45 | // configure to "auto pin" the 4 layers 46 | // -- end result of DD_AP_XXX(...) is the layout spec "H(V(0+1)+V(2+3))" 47 | // -- . H/V: layout direction 48 | // -- . 0/1/2/3: layer id 49 | dumbdisplay.configAutoPin(DD_AP_HORI_2( 50 | DD_AP_VERT_2(pLayer1->getLayerId(), pLayer2->getLayerId()), 51 | DD_AP_VERT_2(pLayer3->getLayerId(), pLayer4->getLayerId()))); 52 | 53 | // draw triangles 54 | int left = 0; 55 | int right = 150; 56 | int top = 0; 57 | int bottom = 100; 58 | int mid = 50; 59 | for (int i = 0; i < 15; i++) { 60 | left += 3; 61 | top += 3; 62 | right -= 3; 63 | bottom -= 3; 64 | int x1 = left; 65 | int y1 = mid; 66 | int x2 = right; 67 | int y2 = top; 68 | int x3 = right; 69 | int y3 = bottom; 70 | int r = 25 * i; 71 | int g = 255 - (10 * i); 72 | int b = 2 * i; 73 | pLayer1->drawTriangle(x1, y1, x2, y2, x3, y3, DD_RGB_COLOR(r, g, b)); 74 | } 75 | 76 | // draw lines 77 | for (int i = 0;; i++) { 78 | int delta = 5 * i; 79 | int x1 = 150; 80 | int y1 = 0; 81 | int x2 = -150 + delta; 82 | int y2 = delta; 83 | pLayer2->drawLine(x1, y1, x2, y2, DD_COLOR_blue); 84 | if (x2 > 150) 85 | break; 86 | } 87 | 88 | // draw rectangles 89 | for (int i = 0; i < 15; i++) { 90 | int delta = 3 * i; 91 | int x = delta; 92 | int y = delta; 93 | int w = 150 - 2 * x; 94 | int h = 100 - 2 * y; 95 | pLayer3->drawRect(x, y, w, h, DD_COLOR_plum); 96 | } 97 | 98 | // draw circles 99 | int radius = 10; 100 | for (int i = 0; i < 8; i++) { 101 | int x = 2 * radius * i; 102 | for (int j = 0; j < 6; j++) { 103 | int y = 2 * radius * j; 104 | int r = radius; 105 | pLayer4->drawCircle(x, y, r, DD_COLOR_teal); 106 | pLayer4->fillCircle(x + r, y + r, r, DD_COLOR_gold); 107 | } 108 | } 109 | } 110 | 111 | void loop() { 112 | } 113 | -------------------------------------------------------------------------------- /samples/ddhere/ddhere.ino: -------------------------------------------------------------------------------- 1 | #include "ssdumbdisplay.h" 2 | 3 | 4 | #define BLUETOOTH 5 | 6 | 7 | #ifdef BLUETOOTH 8 | 9 | 10 | // assume HC-06 connected, to pin 2 and 3 11 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true)); 12 | 13 | #else 14 | 15 | // otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 16 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 17 | 18 | #endif 19 | 20 | 21 | 22 | GraphicalDDLayer *graphical; 23 | LcdDDLayer *button; 24 | GpsServiceDDTunnel *gpsTunnel; 25 | 26 | void setup() { 27 | // create a graphical LCD layer for showing the current date-time got 28 | graphical = dumbdisplay.createGraphicalLayer(200, 30); 29 | 30 | // create a LCD layer, as a button, to get click feedback 31 | button = dumbdisplay.createLcdLayer(12, 1); 32 | button->writeCenteredLine("check HERE"); 33 | button->enableFeedback("fl"); 34 | 35 | // auto pin the two layers created above vertically 36 | dumbdisplay.configAutoPin(DD_AP_VERT); 37 | 38 | // create a GPS service tunnel 39 | gpsTunnel = dumbdisplay.createGpsServiceTunnel(); 40 | } 41 | 42 | 43 | void loop() { 44 | if (button->getFeedback() != NULL) { 45 | // button clicked ==> request GPS location 46 | gpsTunnel->reconnectForLocation(); 47 | } 48 | DDLocation location; 49 | if (gpsTunnel->readLocation(location)) { 50 | // got GPS location feedback ==> display the location 51 | graphical->clear(); 52 | graphical->setCursor(0, 0); 53 | graphical->println("LOC:"); 54 | graphical->println("LAT:" + String(location.latitude, 4) + " / LONG:" + String(location.longitude, 4)); 55 | } 56 | DDYield(); // give DumbDisplay a chance to do it's work 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /samples/ddmb/ddmb.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | // for connection 4 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 5 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 6 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 7 | 8 | MbDDLayer *mb; 9 | int heading; 10 | 11 | void setup() { 12 | // create Micro:bit layer 13 | mb = dumbdisplay.createMicrobitLayer(); 14 | // set background color 15 | mb->backgroundColor(DD_HEX_COLOR(0xF4A460)); 16 | } 17 | 18 | void loop() { 19 | // set LED color 20 | String ledColor = DD_RGB_COLOR(128, 15 * heading, 255); 21 | mb->ledColor(ledColor); 22 | 23 | // show arrow 24 | MbArrow arrow = static_cast(heading); 25 | mb->showArrow(arrow); 26 | 27 | heading++; 28 | if (heading == 8) 29 | heading = 0; 30 | delay(1000); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /samples/ddnow/ddnow.ino: -------------------------------------------------------------------------------- 1 | #include "ssdumbdisplay.h" 2 | 3 | 4 | #define BLUETOOTH 5 | 6 | 7 | #ifdef BLUETOOTH 8 | 9 | 10 | // assume HC-06 connected, to pin 2 and 3 11 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true)); 12 | 13 | #else 14 | 15 | // otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 16 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 17 | 18 | #endif 19 | 20 | 21 | 22 | GraphicalDDLayer *graphical; 23 | LcdDDLayer *button; 24 | BasicDDTunnel *datetimeTunnel; 25 | 26 | void setup() { 27 | // create a graphical LCD layer for showing the current date-time got 28 | graphical = dumbdisplay.createGraphicalLayer(200, 30); 29 | 30 | // create a LCD layer, as a button, to get click feedback 31 | button = dumbdisplay.createLcdLayer(12, 1); 32 | button->writeCenteredLine("check NOW"); 33 | button->enableFeedback("fl"); 34 | 35 | // auto pin the two layers created above vertically 36 | dumbdisplay.configAutoPin(DD_AP_VERT); 37 | 38 | // create a date-time service tunnel 39 | datetimeTunnel = dumbdisplay.createDateTimeServiceTunnel(); 40 | } 41 | 42 | 43 | void loop() { 44 | if (button->getFeedback() != NULL) { 45 | // button clicked ==> get current date-time 46 | datetimeTunnel->reconnectTo("now"); 47 | } 48 | String datetime; 49 | if (datetimeTunnel->readLine(datetime)) { 50 | // got current date-time feedback ==> display it 51 | graphical->clear(); 52 | graphical->setCursor(0, 0); 53 | graphical->println("NOW:"); 54 | graphical->println(datetime); 55 | } 56 | DDYield(); // give DumbDisplay a chance to do it's work 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /samples/ddnowhere/ddnowhere.ino: -------------------------------------------------------------------------------- 1 | #include "ssdumbdisplay.h" 2 | 3 | 4 | #define BLUETOOTH 5 | 6 | #ifdef BLUETOOTH 7 | // assume HC-06 connected, to pin 2 and 3 8 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 115200, true)); 9 | #else 10 | // otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 11 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 12 | #endif 13 | 14 | 15 | 16 | GraphicalDDLayer *graphical; 17 | TomTomMapDDLayer *tomtommap; 18 | BasicDDTunnel *datetimeTunnel; 19 | GpsServiceDDTunnel *gpsTunnel; 20 | 21 | 22 | void prepareTunnels() { 23 | // create a date-time service tunnel 24 | datetimeTunnel = dumbdisplay.createDateTimeServiceTunnel(); 25 | 26 | // create a GPS service tunnel 27 | gpsTunnel = dumbdisplay.createGpsServiceTunnel(); 28 | gpsTunnel->reconnectForLocation(2); // reconnect to service for GPS location, continuously 29 | } 30 | 31 | 32 | void setup() { 33 | // record the layout, basiclly for the ability of DD app reconnecting 34 | dumbdisplay.recordLayerSetupCommands(); 35 | 36 | // create a graphical LCD layer for showing the current date-time got 37 | graphical = dumbdisplay.createGraphicalLayer(230, 32); 38 | graphical->backgroundColor("azure"); 39 | graphical->penColor("blue"); 40 | graphical->border(3, "darkgray"); 41 | 42 | // create a Tom Tom map layer 43 | tomtommap = dumbdisplay.createTomTomMapLayer("", 300, 200); // *** a TomTom map api key is required; here, "" is used for demo purpose 44 | tomtommap->border(5, "darkgray", "round"); 45 | 46 | // auto pin the two layers created above vertically 47 | dumbdisplay.configAutoPin(DD_AP_VERT); 48 | 49 | dumbdisplay.playbackLayerSetupCommands("rc-tomtommap"); 50 | } 51 | 52 | 53 | 54 | DDConnectVersionTracker cvTracker; 55 | String datetime; 56 | DDLocation location; 57 | 58 | void loop() { 59 | if (cvTracker.checkChanged(dumbdisplay)) { 60 | // there has been a reconnection ==> prepare tunnels 61 | prepareTunnels(); 62 | } 63 | if (gpsTunnel->readLocation(location)) { 64 | // got GPS location feedback ==> sync TomTom map view 65 | tomtommap->goTo(location.latitude, location.longitude); 66 | dumbdisplay.writeComment("... wait a bit for the map ..."); 67 | // reconnect to service for current date-time, one-shot 68 | datetimeTunnel->reconnectTo("now"); 69 | } 70 | if (datetimeTunnel->readLine(datetime)) { 71 | // got current-date time, which is required after GPS location got ==> display it 72 | graphical->clear(); 73 | graphical->setCursor(0, 0); 74 | graphical->println("🕰️: " + datetime); 75 | graphical->println("🌏: LAT=" + String(location.latitude, 4) + " / LONG=" + String(location.longitude, 4)); 76 | } 77 | DDYield(); // give DumbDisplay a chance to do it's work 78 | } 79 | -------------------------------------------------------------------------------- /samples/ddonoffloopmb/ddonoffloopmb.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | /* for connection, please use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 */ 4 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 5 | 6 | MbDDLayer* pMbLayer = NULL; 7 | 8 | void setup() { 9 | // create the MB layer with size 10x10 10 | pMbLayer = dumbdisplay.createMicrobitLayer(10, 10); 11 | // enable "feedback" -- auto flashing the clicked area 12 | pMbLayer->enableFeedback("fa"); 13 | } 14 | 15 | void loop() { 16 | // check for "feedback" 17 | const DDFeedback *pFeedback = pMbLayer->getFeedback(); 18 | if (pFeedback != NULL) { 19 | // act upon "feedback" 20 | pMbLayer->toggle(pFeedback->x, pFeedback->y); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/ddonoffmb/ddonoffmb.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | /* for connection, please use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 */ 4 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 5 | 6 | MbDDLayer* pMbLayer = NULL; 7 | 8 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback) { 9 | // got a click on (x, y) ... toogle it 10 | pMbLayer->toggle(feedback.x, feedback.y); 11 | } 12 | 13 | void setup() { 14 | // create the MB layer with size 10x10 15 | pMbLayer = dumbdisplay.createMicrobitLayer(10, 10); 16 | // setup "callback" function to handle "feedback" passively -- auto flashing the clicked area 17 | pMbLayer->setFeedbackHandler(FeedbackHandler, "fa"); 18 | } 19 | 20 | void loop() { 21 | // give DD a chance to capture "feedback" 22 | DDYield(); 23 | } -------------------------------------------------------------------------------- /samples/ddpinturtle/ddpinturtle.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | 4 | // for connection 5 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 6 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8/ 7 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 8 | 9 | 10 | TurtleDDLayer *turtle; 11 | int r = random(0, 256); 12 | int g = 128; 13 | int b = 0; 14 | 15 | void setup() { 16 | // create a Turtle layer with size 240 x 190 17 | turtle = dumbdisplay.createTurtleLayer(240, 190); 18 | // setup Turtle layer 19 | turtle->backgroundColor("azure"); 20 | turtle->fillColor("lemonchiffon"); 21 | turtle->penSize(1); 22 | turtle->penFilled(true); 23 | // initially draw something on the Turtle layer (will change some settings) 24 | turtle->centeredPolygon(70, 6, true); 25 | turtle->penFilled(false); 26 | turtle->circle(80, true); 27 | 28 | // create 4 LEDs -- left-top, right-top, right-bottom and left-bottom 29 | LedGridDDLayer* ltLed = dumbdisplay.createLedGridLayer(); 30 | LedGridDDLayer* rtLed = dumbdisplay.createLedGridLayer(); 31 | LedGridDDLayer* rbLed = dumbdisplay.createLedGridLayer(); 32 | LedGridDDLayer* lbLed = dumbdisplay.createLedGridLayer(); 33 | 34 | // set LEDs background color 35 | ltLed->backgroundColor("green"); 36 | rtLed->backgroundColor("green"); 37 | rbLed->backgroundColor("green"); 38 | lbLed->backgroundColor("green"); 39 | 40 | // turn ON the LEDs 41 | ltLed->turnOn(); 42 | rtLed->turnOn(); 43 | rbLed->turnOn(); 44 | lbLed->turnOn(); 45 | 46 | // config "pin frame" to be 290 units x 250 units 47 | // 290: 25 + 240 + 25 48 | // 240: 25 + 190 + 25 49 | dumbdisplay.configPinFrame(290, 240); 50 | 51 | // pin top-left LED @ (0, 0) with size (25, 25) 52 | dumbdisplay.pinLayer(ltLed, 0, 0, 25, 25); 53 | // pin top-right LED @ (265, 0) with size (25, 25) 54 | dumbdisplay.pinLayer(rtLed, 265, 0, 25, 25); 55 | // pin right-bottom LED @ (265, 215) with size (25, 25) 56 | dumbdisplay.pinLayer(rbLed, 265, 215, 25, 25); 57 | // pin left-bottom LED @ (0, 215) with size (25, 25) 58 | dumbdisplay.pinLayer(lbLed, 0, 215, 25, 25); 59 | 60 | // pin Turtle @ (25, 25) with size (240, 190) 61 | dumbdisplay.pinLayer(turtle, 25, 25, 240, 190); 62 | } 63 | 64 | 65 | void loop() { 66 | delay(1000); 67 | turtle->penColor(DD_RGB_COLOR(r, g, b)); 68 | turtle->circle(27); 69 | turtle->rectangle(90, 20); 70 | turtle->rightTurn(10); 71 | b = b + 20; 72 | if (b > 255) { 73 | b = 0; 74 | r = random(0, 256); 75 | } 76 | } -------------------------------------------------------------------------------- /samples/ddquote/ddquote.ino: -------------------------------------------------------------------------------- 1 | #include "dumbdisplay.h" 2 | 3 | // ********** 4 | // *** Sorry, this sample doesn't appears to work anymore! 5 | // ********** 6 | 7 | // for connection 8 | // . via OTG -- see https://www.instructables.com/Blink-Test-With-Virtual-Display-DumbDisplay/ 9 | // . via DumbDisplayWifiBridge -- see https://www.youtube.com/watch?v=0UhRmXXBQi8 10 | // use a lower baud rate since Arduino Uno Serial buffer size is not very big 11 | DumbDisplay dumbdisplay(new DDInputOutput(9600)); 12 | 13 | GraphicalDDLayer *pLayer; 14 | BasicDDTunnel *pTunnel; 15 | 16 | bool freshStart = true; 17 | 18 | void setup() { 19 | // setup a "graphial" layer 20 | pLayer = dumbdisplay.createGraphicalLayer(200, 150); // size 200x150 21 | pLayer->border(10, "azure", "round"); // a round border of size 10 22 | pLayer->noBackgroundColor(); // initial no background color 23 | pLayer->penColor("navy"); // set pen color 24 | 25 | // setup a "tunnel" to access "quote of the day" by djxmmx.net 26 | pTunnel = dumbdisplay.createBasicTunnel("djxmmx.net:17"); 27 | } 28 | 29 | void loop() { 30 | if (!pTunnel->eof()) { 31 | // not "reached" EOF (end-of-file) 32 | if (pTunnel->count() > 0) { 33 | // got something to read 34 | if (freshStart) { 35 | // if just started to get the quote, reset something 36 | pLayer->clear(); // clear the "graphical" layer 37 | pLayer->setCursor(0, 10); // set "cursor" to (0, 10) 38 | } 39 | String data = pTunnel->readLine(); // read what got so far 40 | pLayer->print(data); // print out to the "graphical" layer what got so far 41 | freshStart = false; 42 | } 43 | } else { 44 | // "reached" EOF (i.e. got everything) 45 | // setup layer for getting "feedback" 46 | pLayer->backgroundColor("azure"); // set background color 47 | pLayer->enableFeedback("f"); // enable "auto feedback" 48 | while (true) { // loop and wait for layer clicked 49 | if (pLayer->getFeedback() != NULL) { 50 | break; 51 | } 52 | } 53 | // clicked ==> reset 54 | pLayer->noBackgroundColor(); // no background color 55 | pLayer->disableFeedback(); // disable "feedback" 56 | pTunnel->reconnect(); // reconnect to djxmmx.net to get another quote 57 | freshStart = true; // indicating that a new quote is coming 58 | } 59 | DDDelay(500); // delay a bit before another round; this also give DumbDisplay libary a chance to so its work 60 | } 61 | -------------------------------------------------------------------------------- /samples/ddup4howlong/ddup4howlong.ino: -------------------------------------------------------------------------------- 1 | #include "ssdumbdisplay.h" 2 | 3 | //#define BLUETOOTH 4 | 5 | #ifdef BLUETOOTH 6 | 7 | // assume HC-06 connected, to pin 2 and 3; and assume it is using baud 9600 8 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 9600)); 9 | 10 | #else 11 | 12 | //otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 13 | DumbDisplay dumbdisplay(new DDInputOutput(57600)); 14 | 15 | #endif 16 | 17 | SevenSegmentRowDDLayer *sevenSeg; 18 | void setup() { 19 | // start recording the commands to setup DD (app side) 20 | dumbdisplay.recordLayerSetupCommands(); 21 | 22 | // create a 7-seg layer for 4 digits 23 | sevenSeg = dumbdisplay.create7SegmentRowLayer(4); 24 | sevenSeg->border(15, "darkblue", "round"); 25 | sevenSeg->padding(10); 26 | sevenSeg->resetSegmentOffColor(DD_HEX_COLOR(0xeeddcc)); 27 | 28 | // stop recording and play back the recorded commands 29 | // more importantly, a "id" is given so that 30 | // the records commands can be reused during restart of DD app 31 | dumbdisplay.playbackLayerSetupCommands("up4howlong"); 32 | } 33 | 34 | long startMillis = millis(); 35 | void loop() { 36 | long howLong = (millis() - startMillis) / 1000; 37 | sevenSeg->showNumber(howLong); 38 | delay(1000); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /samples/esp32bleup4howlong/esp32bleup4howlong.ino: -------------------------------------------------------------------------------- 1 | //******* 2 | //** ADAPTED FROM ESP32 SAMPLE BLE_server *** 3 | //******* 4 | 5 | 6 | //** . by default, BLE client can READ the value 7 | //** . can uncomment either INDICATE or NOTIFY so that 8 | //** BLE client will be notified of new value 9 | //** - NOTIFY -- just notify 10 | //** - INDICATE -- notify, and sort of requiring acknowledgement 11 | //#define INDICATE 12 | #define NOTIFY 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" 22 | #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" 23 | 24 | 25 | BLECharacteristic *pCharacteristic; 26 | 27 | void setup() { 28 | BLEDevice::init("ESP32Ble"); 29 | BLEServer *pServer = BLEDevice::createServer(); 30 | BLEService *pService = pServer->createService(SERVICE_UUID); 31 | pCharacteristic = pService->createCharacteristic( 32 | CHARACTERISTIC_UUID, 33 | BLECharacteristic::PROPERTY_READ 34 | #if defined(INDICATE) 35 | | BLECharacteristic::PROPERTY_INDICATE 36 | #elif defined (NOTIFY) 37 | | BLECharacteristic::PROPERTY_NOTIFY 38 | #endif 39 | ); 40 | #if defined(INDICATE) || defined (NOTIFY) 41 | // a 2902 descriptor is needed to enable notification 42 | pCharacteristic->addDescriptor(new BLE2902()); 43 | #endif 44 | 45 | pService->start(); 46 | BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); 47 | pAdvertising->addServiceUUID(SERVICE_UUID); 48 | pAdvertising->setScanResponse(true); 49 | BLEDevice::startAdvertising(); 50 | } 51 | 52 | long startMillis = millis(); 53 | void loop() { 54 | long up = (millis() - startMillis) / 1000; 55 | #if defined(INDICATE) 56 | pCharacteristic->setValue(("I-Up: " + String(up) + "s").c_str()); 57 | pCharacteristic->indicate(); 58 | #elif defined (NOTIFY) 59 | pCharacteristic->setValue(("N-Up: " + String(up) + "s").c_str()); 60 | pCharacteristic->notify(); 61 | #else 62 | pCharacteristic->setValue(("Up: " + String(up) + "s").c_str()); 63 | #endif 64 | delay(1000); 65 | } -------------------------------------------------------------------------------- /samples/esp32blewaves/esp32blewaves.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | #define SERVICE_UUID "d4b76bfb-2cc6-426c-adcb-905e8bc1a907" 8 | #define ANGLE_CHARACTERISTIC_UUID "284b7fd5-cea3-4426-9499-918350b2ea68" 9 | #define SIN_CHARACTERISTIC_UUID "a18d7b8d-005d-4ada-b50d-796d50f71f92" 10 | #define COS_CHARACTERISTIC_UUID "42a06347-c605-473e-8af4-956923d39ba5" 11 | #define TAN_CHARACTERISTIC_UUID "3347662f-c816-464e-aa76-cdbf34fd09e3" 12 | 13 | 14 | BLECharacteristic *pAngleCharacteristic; 15 | BLECharacteristic *pSinCharacteristic; 16 | BLECharacteristic *pCosCharacteristic; 17 | BLECharacteristic *pTanCharacteristic; 18 | 19 | void setup() { 20 | BLEDevice::init("ESP32Ble"); 21 | BLEServer *pServer = BLEDevice::createServer(); 22 | BLEService *pService = pServer->createService(SERVICE_UUID); 23 | 24 | pAngleCharacteristic = pService->createCharacteristic( 25 | ANGLE_CHARACTERISTIC_UUID, 26 | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); 27 | pSinCharacteristic = pService->createCharacteristic( 28 | SIN_CHARACTERISTIC_UUID, 29 | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); 30 | pCosCharacteristic = pService->createCharacteristic( 31 | COS_CHARACTERISTIC_UUID, 32 | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); 33 | pTanCharacteristic = pService->createCharacteristic( 34 | TAN_CHARACTERISTIC_UUID, 35 | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); 36 | 37 | pService->start(); 38 | BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); 39 | pAdvertising->addServiceUUID(SERVICE_UUID); 40 | BLEDevice::startAdvertising(); 41 | } 42 | 43 | int angle = 0; 44 | void loop() { 45 | float r = angle * 0.01745329252; 46 | float s = sin(r); 47 | float c = cos(r); 48 | float t = tan(r); 49 | 50 | pAngleCharacteristic->setValue(("Ang: " + String(angle)).c_str()); 51 | pAngleCharacteristic->notify(); 52 | pSinCharacteristic->setValue(("Sin: " + String(s, 2)).c_str()); 53 | pSinCharacteristic->notify(); 54 | pCosCharacteristic->setValue(("Cos: " + String(c, 2)).c_str()); 55 | pCosCharacteristic->notify(); 56 | pTanCharacteristic->setValue(("Tan: " + String(t, 2)).c_str()); 57 | pTanCharacteristic->notify(); 58 | 59 | angle = angle + 5; 60 | if (angle >= 360) { 61 | angle = 0; 62 | } 63 | delay(1000); 64 | } -------------------------------------------------------------------------------- /samples/esp32c3ddblink/esp32c3ddblink.ino: -------------------------------------------------------------------------------- 1 | //********** 2 | //*** 3 | //*** for AI Thinker ESP32-C8-32S-KIT 4 | //*** 5 | //********** 6 | 7 | 8 | // for a desciption of the experiment, please watch the YouTube video 9 | // -- ESP32-C3 Blink Test with Arduino IDE and DumbDisplay 10 | // -- https://www.youtube.com/watch?v=BAnvHOs5Fks 11 | 12 | 13 | //#define DD_4_ESP32 14 | #include "esp32bledumbdisplay.h" 15 | 16 | 17 | // - use ESP32 BLE with name "ESP32C3" 18 | // - at the same time, enable Serial connection with 115200 baud 19 | DumbDisplay dumbdisplay(new DDBLESerialIO("ESP32C3", true, 115200)); 20 | 21 | 22 | #define PIN_COOL 19 23 | #define PIN_WARM 18 24 | #define PIN_RED 3 25 | #define PIN_GREEN 4 26 | #define PIN_BLUE 5 27 | 28 | 29 | LcdDDLayer* pCool; 30 | LcdDDLayer* pWarm; 31 | LcdDDLayer* pRed; 32 | LcdDDLayer* pGreen; 33 | LcdDDLayer* pBlue; 34 | 35 | 36 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback); 37 | 38 | LcdDDLayer* CreateLayer(const char* label, int pin, const char* color) { 39 | // create a layer to simulate a button 40 | LcdDDLayer* button = dumbdisplay.createLcdLayer(12, 3); 41 | 42 | // set pin to the layer's "custom data" 43 | button->customData = String(pin); 44 | 45 | // setup appearance of the layer 46 | button->writeCenteredLine(label, 1); 47 | button->pixelColor(color); 48 | button->backgroundColor(DD_COLOR_darkgray); 49 | button->border(1, DD_COLOR_gray); 50 | 51 | // set "feedback" handler 52 | button->setFeedbackHandler(FeedbackHandler, "f"); 53 | 54 | return button; 55 | } 56 | 57 | void setup() { 58 | pinMode(PIN_COOL, OUTPUT); 59 | pinMode(PIN_WARM, OUTPUT); 60 | pinMode(PIN_RED, OUTPUT); 61 | pinMode(PIN_GREEN, OUTPUT); 62 | pinMode(PIN_BLUE, OUTPUT); 63 | 64 | digitalWrite(PIN_COOL, 0); 65 | 66 | pCool = CreateLayer("Cool", PIN_COOL, "white"); 67 | pWarm = CreateLayer("Warm", PIN_WARM, "gold"); 68 | pRed = CreateLayer("Red", PIN_RED, "tomato"); 69 | pGreen = CreateLayer("Green", PIN_GREEN, "green"); 70 | pBlue = CreateLayer("Blue", PIN_BLUE, "lightskyblue"); 71 | 72 | // auto "pin" the layers (buttons) vertically 73 | dumbdisplay.configAutoPin(DD_AP_VERT); 74 | } 75 | 76 | void loop() { 77 | // just yield to DumbDisplay to do its work 78 | DDYield(); 79 | } 80 | 81 | 82 | void FeedbackHandler(DDLayer* pLayer, DDFeedbackType type, const DDFeedback& feedback) { 83 | // layer (button) clicked ... get pin from the layer's "custom data" 84 | int pin = pLayer->customData.toInt(); 85 | 86 | // flash the onboard LED of the pin 87 | digitalWrite(pin, HIGH); 88 | delay(500); 89 | digitalWrite(pin, LOW); 90 | delay(500); 91 | } 92 | 93 | -------------------------------------------------------------------------------- /samples/esp8266_now/esp8266_now.ino: -------------------------------------------------------------------------------- 1 | 2 | // * 3 | // * if for CLIENT, define ESP_NOW_CLIENT, and may want to define it first, since you will need to find out CLIENT's MAC 4 | // * if for SERVER, define ESP_NOW_SERVER_FOR_MAC with client's MAC, like shown below 5 | // * 6 | 7 | //#define ESP_NOW_CLIENT 8 | #define ESP_NOW_SERVER_FOR_MAC 0x48, 0x3F, 0xDA, 0x51, 0x22, 0x15 9 | 10 | #include 11 | #include 12 | 13 | // define a structure as an ESP Now packet 14 | struct ESPNowPacket 15 | { 16 | long tPlusMillis; 17 | }; 18 | 19 | // if acting as SERVER, define a variable for storing CLIENT's MAC 20 | #if defined(ESP_NOW_SERVER_FOR_MAC) 21 | uint8_t ClientMACAddress[] = { ESP_NOW_SERVER_FOR_MAC }; 22 | #endif 23 | 24 | // if acting as SERVER, also define a callback function to be called after sending a packet 25 | #if defined(ESP_NOW_SERVER_FOR_MAC) 26 | void OnSentData(uint8_t *mac_addr, uint8_t sendStatus) 27 | { 28 | Serial.print("... sent "); 29 | if (sendStatus == 0) 30 | { 31 | Serial.print("SUCCESSFUL"); 32 | } 33 | else 34 | { 35 | Serial.print("FAILED"); 36 | } 37 | Serial.println(" ..."); 38 | } 39 | #endif 40 | 41 | // if acting as CLIENT, define a callback once a package is received 42 | #if defined(ESP_NOW_CLIENT) 43 | ESPNowPacket LastReceivedPacket; 44 | volatile bool LastReceivedPacketValid = false; 45 | void OnReceivedData(uint8_t *mac, uint8_t *incomingData, uint8_t len) 46 | { 47 | memcpy(&LastReceivedPacket, incomingData, len); 48 | LastReceivedPacketValid = true; 49 | } 50 | #endif 51 | 52 | int espNowStatus; 53 | 54 | void setup() 55 | { 56 | // put ESP8266's WIFI to station mode 57 | WiFi.mode(WIFI_STA); 58 | 59 | Serial.begin(115200); 60 | 61 | // 1. initial ESP Now 62 | espNowStatus = esp_now_init(); 63 | 64 | if (espNowStatus == 0) 65 | { 66 | // if acting as SERVER, set ESP role to controller, set "sent data" callback, and add peer (i.e. CLIENT) to send package to 67 | #if defined(ESP_NOW_SERVER_FOR_MAC) 68 | esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); 69 | esp_now_register_send_cb(OnSentData); 70 | esp_now_add_peer(ClientMACAddress, ESP_NOW_ROLE_SLAVE, 0, NULL, 0); // 0 is the channel 71 | #endif 72 | 73 | // if acting as CLIENT, set ESP role to slave, and set "received data" callback 74 | #if defined(ESP_NOW_CLIENT) 75 | esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); 76 | esp_now_register_recv_cb(OnReceivedData); 77 | #endif 78 | } 79 | 80 | Serial.println(); 81 | Serial.println("OK!"); 82 | } 83 | 84 | #if defined(ESP_NOW_SERVER_FOR_MAC) 85 | const long MaxIdleMillis = 2000; 86 | #endif 87 | #if defined(ESP_NOW_CLIENT) 88 | const long MaxIdleMillis = 3000; 89 | #endif 90 | 91 | long lastActivityMillis = 0; 92 | 93 | void loop() 94 | { 95 | if (espNowStatus != 0) 96 | { 97 | Serial.println("ESP Now not properly initialized!"); 98 | Serial.print("status is "); 99 | Serial.println(espNowStatus); 100 | delay(2000); 101 | return; 102 | } 103 | 104 | long nowMillis = millis(); 105 | 106 | // if acting as CLIENT, check if received packet ("current time millis of the SERVER"); if so, show it 107 | #if defined(ESP_NOW_CLIENT) 108 | if (LastReceivedPacketValid) 109 | { 110 | LastReceivedPacketValid = false; 111 | int tPlusSecond = LastReceivedPacket.tPlusMillis / 1000; 112 | Serial.print("received ... T+"); 113 | Serial.print(tPlusSecond); 114 | Serial.println("s"); 115 | lastActivityMillis = nowMillis; 116 | return; 117 | } 118 | #endif 119 | 120 | if ((nowMillis - lastActivityMillis) >= MaxIdleMillis) 121 | { 122 | // if acting as SERVER, setup package to send to CLIENT ... the packet is just the current millis of the SERVER 123 | #if defined(ESP_NOW_SERVER_FOR_MAC) 124 | ESPNowPacket packet; 125 | packet.tPlusMillis = nowMillis; 126 | esp_now_send(ClientMACAddress, (uint8_t *)&packet, sizeof(packet)); 127 | #endif 128 | 129 | // if acting as CLIENT, print out the CLIENT's MAC 130 | #if defined(ESP_NOW_CLIENT) 131 | Serial.print("my MAC is "); 132 | Serial.println(WiFi.macAddress()); 133 | #endif 134 | lastActivityMillis = nowMillis; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /samples/inithc06/inithc06.ino: -------------------------------------------------------------------------------- 1 | // *** 2 | // * notes for HC-06 / HC-08: 3 | // * . default baud rate is 9600 4 | // * . serial monitor needs no line ending; ie no NL and no CR 5 | // * notes for HC-05: 6 | // * . need be in AT mode; need to hold its button while powering on; LED on HC-05 will flash slowly 7 | // * . baud rate is 38400 8 | // * . serial monitor needs NL and CR 9 | // *** 10 | 11 | 12 | #include 13 | 14 | //SoftwareSerial hc(11, 10); 15 | SoftwareSerial hc(2, 3); // 2 => TX of HC; 3 => RX of HC 16 | 17 | 18 | // for HC-06 19 | // 9600: AT+BAUD4 20 | // 57600: AT+BAUD7 21 | // 115200: AT+BAUD8 22 | // arduino: AT+NAMEarduino 23 | // 1234: AT+PIN1234 24 | 25 | 26 | // for HC-05 27 | // get name: AT+NAME? 28 | // set name: AT+NAME=arduino 29 | // set password: AT+PSWD=1234 30 | // get baud: AT+UART? 31 | // set baud: AT+UART=115200,0,0 32 | // reset: AT+ORGL 33 | 34 | 35 | // for HC-08 (set up like HC-06) 36 | // get info: AT+RX 37 | // set name: AT+NAME=xxx 38 | // set baud: AT+BAUD=nnn 39 | // reset: AT+RESET 40 | // reset to default: AT+DEFAULT 41 | 42 | 43 | const unsigned long baud = 115200; // default for HC-06 / HC-08 is 9600; for HC-05, set to 38400 (assume HC-05 in AT mode) 44 | 45 | 46 | void setup() { 47 | 48 | // initialize Serial 49 | Serial.begin(baud); 50 | Serial.println("Hello from Arduino. Please enter AT command:"); 51 | 52 | // initialize HC06 53 | hc.begin(baud); 54 | 55 | } 56 | 57 | void loop() { 58 | 59 | // write data from HC06 to Serial 60 | if (hc.available()) { 61 | Serial.write(hc.read()); 62 | } 63 | 64 | // write data from Serial to HC06 65 | if (Serial.available()) { 66 | hc.write(Serial.read()); 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /samples/initpicohc06/initpicohc06.ino: -------------------------------------------------------------------------------- 1 | 2 | // 9600: AT+BAUD4 3 | // 57600: AT+BAUD7 4 | // 115200: AT+BAUD8 5 | // Pico: AT+NAMEPico 6 | // 1234: AT+PIN1234 7 | 8 | 9 | 10 | UART Serial2(8, 9, 0, 0); // GP8 => RX of HC06; GP9 => TX of HC06 11 | 12 | const unsigned long baud = 115200; 13 | 14 | 15 | void setup() { 16 | // initialize Serial 17 | Serial.begin(baud); 18 | 19 | // initialize HC06 @ Pico Uart2 (Serial2) 20 | Serial2.begin(baud); 21 | } 22 | 23 | void loop() { 24 | // write data from Pico Serial2 to Serial 25 | if (Serial2.available()) { 26 | Serial.write(Serial2.read()); 27 | } 28 | 29 | // write data from Pico Serial2 to HC06 30 | if (Serial.available()) { 31 | Serial2.write(Serial.read()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/objectdetectdemo/objectdetectdemo.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "Arduino.h" 3 | 4 | // if want Bluetooth, uncomment the following line 5 | // #define BLUETOOTH "ESP32BT" 6 | #if defined(ESP32) && defined(BLUETOOTH) 7 | #include "esp32dumbdisplay.h" 8 | DumbDisplay dumbdisplay(new DDBluetoothSerialIO(BLUETOOTH, true, 115200)); 9 | #else 10 | #include "dumbdisplay.h" 11 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 12 | #endif 13 | 14 | 15 | GraphicalDDLayer *imageLayer; 16 | SimpleToolDDTunnel *web_image_tunnel; 17 | ObjectDetectDemoServiceDDTunnel *object_detect_tunnel; 18 | 19 | void setup() { 20 | // create a graphical layer for drawing the web image to 21 | imageLayer = dumbdisplay.createGraphicalLayer(640, 480); 22 | imageLayer->border(10, "blue", "round"); 23 | imageLayer->padding(15); 24 | imageLayer->backgroundColor("white"); 25 | imageLayer->penSize(2); 26 | 27 | // create a tunnel for downloading web image ... initially, no URL yet ... downloaded.png is the name of the image to save 28 | web_image_tunnel = dumbdisplay.createImageDownloadTunnel("", "downloaded.png"); 29 | 30 | // create a tunnel for object detection demo via TensorFlow Lite running on phone side 31 | #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO) 32 | int maxNumObjs = 1; 33 | #else 34 | int maxNumObjs = 3; 35 | #endif 36 | object_detect_tunnel = dumbdisplay.createObjectDetectDemoServiceTunnel(0, 0, maxNumObjs); 37 | } 38 | 39 | inline const char* getDownloadImageURL() { 40 | #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO) 41 | #else 42 | // randomly pick an image source URL from a list 43 | int idx = random(5); 44 | switch(idx) { 45 | case 0: return "https://placekitten.com/640/480"; 46 | case 1: return "https://source.unsplash.com/random/640x480"; 47 | case 2: return "https://picsum.photos/640/480"; 48 | case 3: return "https://loremflickr.com/640/480"; 49 | } 50 | #endif 51 | return "https://placedog.net/640/480?r"; 52 | } 53 | 54 | void loop() { 55 | // set the URL to download web image ... using a bit different size so that web image will be different 56 | String url = getDownloadImageURL(); 57 | web_image_tunnel->reconnectTo(url); 58 | 59 | dumbdisplay.writeComment("..."); 60 | while (true) { 61 | int result = web_image_tunnel->checkResult(); 62 | if (result == 1) { 63 | // web image downloaded and saved successfully 64 | imageLayer->drawImageFile("downloaded.png"); 65 | // detect objects in the image 66 | object_detect_tunnel->reconnectForObjectDetect("downloaded.png"); 67 | } else if (result == -1) { 68 | // failed to download the image 69 | dumbdisplay.writeComment("XXX failed to download XXX"); 70 | } 71 | if (result != 0) { 72 | break; 73 | } 74 | } 75 | 76 | imageLayer->backgroundColor("gray"); // set background color to gray, to indicate loaded and detecting 77 | imageLayer->enableFeedback("f") ; // enable "auto feedback" 78 | bool detected = false; 79 | while (true) { // loop and wait for object detection result, or graphical layer click for switching image 80 | if (object_detect_tunnel->eof()) { 81 | if (!detected) { 82 | dumbdisplay.writeComment("Click image to switch!"); 83 | imageLayer->backgroundColor("blue"); // set background color to blue, to indicate all done 84 | } 85 | detected = true; 86 | } else { 87 | DDObjectDetectDemoResult objectDetectResult; 88 | if (object_detect_tunnel->readObjectDetectResult(objectDetectResult)) { 89 | dumbdisplay.writeComment(String(". ") + objectDetectResult.label); 90 | int x = objectDetectResult.left; 91 | int y = objectDetectResult.top; 92 | int w = objectDetectResult.right - objectDetectResult.left; 93 | int h = objectDetectResult.bottom - objectDetectResult.top; 94 | imageLayer->drawRect(x, y, w, h, "green"); 95 | imageLayer->drawStr(x, y, objectDetectResult.label, "yellow", "a70%darkgreen", 32); 96 | } 97 | } 98 | if (imageLayer->getFeedback() != NULL) { 99 | break; 100 | } 101 | } 102 | imageLayer->backgroundColor("white"); // set background color to white, to indicate loading 103 | imageLayer->disableFeedback(); // disable "feedback" 104 | } 105 | -------------------------------------------------------------------------------- /samples/webimage/webimage.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | //#define BLUETOOTH 4 | 5 | #ifdef BLUETOOTH 6 | 7 | #include "ssdumbdisplay.h" 8 | 9 | // assume HC-06 connected, to pin 2 and 3; and assume it is using baud 9600 10 | DumbDisplay dumbdisplay(new DDSoftwareSerialIO(new SoftwareSerial(2, 3), 9600)); 11 | 12 | #else 13 | 14 | #include "dumbdisplay.h" 15 | 16 | //otherwise, can use DumbDisplayWifiBridge -- https://www.youtube.com/watch?v=0UhRmXXBQi8 17 | DumbDisplay dumbdisplay(new DDInputOutput(115200)); 18 | 19 | #endif 20 | 21 | 22 | 23 | GraphicalDDLayer *pLayer; 24 | SimpleToolDDTunnel *pTunnel; 25 | 26 | void setup() { 27 | // create a graphical layer for drawing the web image to 28 | pLayer = dumbdisplay.createGraphicalLayer(500, 300); 29 | pLayer->border(10, "azure", "round"); 30 | pLayer->noBackgroundColor(); 31 | pLayer->penColor("navy"); 32 | 33 | // create a tunnel for downloading web image ... initially, no URL yet ... downloaded.png is the name of the image to save 34 | pTunnel = dumbdisplay.createImageDownloadTunnel("", "downloaded.png"); 35 | } 36 | 37 | void loop() { 38 | // set the URL to download web image ... using a bit different size so that web image will be different 39 | String url = String("https://placekitten.com/680/") + String(460 + rand() % 20); 40 | pTunnel->reconnectTo(url); 41 | 42 | while (true) { 43 | int result = pTunnel->checkResult(); 44 | if (result == 1) { 45 | // web image downloaded and saved successfully 46 | pLayer->clear(); 47 | // unload to make sure the cache is cleared 48 | pLayer->unloadImageFile("downloaded.png"); 49 | // draw the image 50 | pLayer->drawImageFileFit("downloaded.png", 10, 10); 51 | } else if (result == -1) { 52 | // failed to download the image 53 | pLayer->clear(); 54 | pLayer->setCursor(10, 10); 55 | pLayer->println("XXX failed to download XXX"); 56 | } 57 | if (result != 0) { 58 | break; 59 | } 60 | } 61 | pLayer->backgroundColor("azure"); // set background color 62 | pLayer->enableFeedback("f"); // enable "auto feedback" 63 | while (true) { // loop and wait for layer clicked 64 | if (pLayer->getFeedback() != NULL) { 65 | break; 66 | } 67 | } 68 | pLayer->noBackgroundColor(); // no background color 69 | pLayer->disableFeedback(); // disable "feedback" 70 | delay(500); 71 | } 72 | -------------------------------------------------------------------------------- /screenshots/164n-8x8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/164n-8x8-1.png -------------------------------------------------------------------------------- /screenshots/amb82-mini-facerecog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/amb82-mini-facerecog.jpg -------------------------------------------------------------------------------- /screenshots/color-sensor-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/color-sensor-connection.png -------------------------------------------------------------------------------- /screenshots/dd7segcounter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd7segcounter.jpg -------------------------------------------------------------------------------- /screenshots/dd7segcounter_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd7segcounter_connection.png -------------------------------------------------------------------------------- /screenshots/dd_awc_tab_alarms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_awc_tab_alarms.jpg -------------------------------------------------------------------------------- /screenshots/dd_awc_tab_general.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_awc_tab_general.jpg -------------------------------------------------------------------------------- /screenshots/dd_awc_tab_slids.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_awc_tab_slids.jpg -------------------------------------------------------------------------------- /screenshots/dd_pixel_density_fine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_pixel_density_fine.png -------------------------------------------------------------------------------- /screenshots/dd_pixel_density_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_pixel_density_high.png -------------------------------------------------------------------------------- /screenshots/dd_pixel_density_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_pixel_density_medium.png -------------------------------------------------------------------------------- /screenshots/dd_pixel_density_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_pixel_density_normal.png -------------------------------------------------------------------------------- /screenshots/dd_pixel_density_over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_pixel_density_over.png -------------------------------------------------------------------------------- /screenshots/dd_prepare_storage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_prepare_storage.gif -------------------------------------------------------------------------------- /screenshots/dd_storage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dd_storage.gif -------------------------------------------------------------------------------- /screenshots/ddautopin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddautopin.png -------------------------------------------------------------------------------- /screenshots/ddbarmeter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddbarmeter.png -------------------------------------------------------------------------------- /screenshots/dddoodle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/dddoodle.png -------------------------------------------------------------------------------- /screenshots/ddgpsmap_ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddgpsmap_ss.png -------------------------------------------------------------------------------- /screenshots/ddgraphical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddgraphical.png -------------------------------------------------------------------------------- /screenshots/ddmb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddmb.png -------------------------------------------------------------------------------- /screenshots/ddmelody.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddmelody.jpg -------------------------------------------------------------------------------- /screenshots/ddnowhere.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddnowhere.jpg -------------------------------------------------------------------------------- /screenshots/ddobjectdetect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddobjectdetect.jpg -------------------------------------------------------------------------------- /screenshots/ddpin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddpin.png -------------------------------------------------------------------------------- /screenshots/ddpinturtle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddpinturtle.png -------------------------------------------------------------------------------- /screenshots/ddpocketcomputer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddpocketcomputer.png -------------------------------------------------------------------------------- /screenshots/ddquote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddquote.png -------------------------------------------------------------------------------- /screenshots/ddsaveimages.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddsaveimages.gif -------------------------------------------------------------------------------- /screenshots/ddspacewars.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddspacewars.gif -------------------------------------------------------------------------------- /screenshots/ddwebblink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddwebblink.png -------------------------------------------------------------------------------- /screenshots/ddwebcalc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddwebcalc.png -------------------------------------------------------------------------------- /screenshots/ddwifibridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddwifibridge.png -------------------------------------------------------------------------------- /screenshots/ddwifibridge2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/ddwifibridge2.png -------------------------------------------------------------------------------- /screenshots/esp32-deep-sleep-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp32-deep-sleep-connection.png -------------------------------------------------------------------------------- /screenshots/esp32-dht11-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp32-dht11-connection.png -------------------------------------------------------------------------------- /screenshots/esp32-mic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp32-mic.png -------------------------------------------------------------------------------- /screenshots/esp32_mnist.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp32_mnist.gif -------------------------------------------------------------------------------- /screenshots/esp32camobjectdetect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp32camobjectdetect.gif -------------------------------------------------------------------------------- /screenshots/esp8266-servo-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp8266-servo-connection.png -------------------------------------------------------------------------------- /screenshots/esp8266-servo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/esp8266-servo.jpg -------------------------------------------------------------------------------- /screenshots/joystick-arduino-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/joystick-arduino-connect.png -------------------------------------------------------------------------------- /screenshots/joystick-arduino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/joystick-arduino.jpg -------------------------------------------------------------------------------- /screenshots/joystick-dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/joystick-dd.png -------------------------------------------------------------------------------- /screenshots/lock-locked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/lock-locked.png -------------------------------------------------------------------------------- /screenshots/lock-unlocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/lock-unlocked.png -------------------------------------------------------------------------------- /screenshots/numinvader-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/numinvader-connection.png -------------------------------------------------------------------------------- /screenshots/numinvader.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/numinvader.jpg -------------------------------------------------------------------------------- /screenshots/otg7segment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otg7segment.png -------------------------------------------------------------------------------- /screenshots/otgblink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgblink.png -------------------------------------------------------------------------------- /screenshots/otgkeypad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgkeypad.png -------------------------------------------------------------------------------- /screenshots/otgrest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgrest.png -------------------------------------------------------------------------------- /screenshots/otgrgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgrgb.png -------------------------------------------------------------------------------- /screenshots/otgsound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgsound.png -------------------------------------------------------------------------------- /screenshots/otgwebimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/otgwebimage.png -------------------------------------------------------------------------------- /screenshots/pico-164n_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/pico-164n_connection.png -------------------------------------------------------------------------------- /screenshots/pico-8x8-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/pico-8x8-connect.png -------------------------------------------------------------------------------- /screenshots/pico-radar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/pico-radar.png -------------------------------------------------------------------------------- /screenshots/pico-speaker_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/pico-speaker_connection.png -------------------------------------------------------------------------------- /screenshots/pico-stepmotor_connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/pico-stepmotor_connect.png -------------------------------------------------------------------------------- /screenshots/servo-dd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/servo-dd.png -------------------------------------------------------------------------------- /screenshots/sliding-ss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/sliding-ss.jpg -------------------------------------------------------------------------------- /screenshots/sliding.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/sliding.gif -------------------------------------------------------------------------------- /screenshots/snapper-ss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/snapper-ss.jpg -------------------------------------------------------------------------------- /screenshots/spacewarsimgs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/spacewarsimgs.png -------------------------------------------------------------------------------- /screenshots/tdisplayclock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/tdisplayclock.png -------------------------------------------------------------------------------- /screenshots/tft_image_show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/tft_image_show.gif -------------------------------------------------------------------------------- /screenshots/tft_show_show_ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/tft_show_show_ss.png -------------------------------------------------------------------------------- /screenshots/up4howlong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/up4howlong.png -------------------------------------------------------------------------------- /screenshots/webimage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/screenshots/webimage.jpg -------------------------------------------------------------------------------- /serial2dumbdisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef serial2dumbdisplay_h 2 | #define serial2dumbdisplay_h 3 | 4 | // e.g. STM32F103: PA3 (RX2) ==> TX; PA2 (TX2) ==> RX 5 | 6 | #include "dumbdisplay.h" 7 | 8 | /// Deprecated. Use DDGenericIO (in genericdumbdisplay.h) instead. 9 | class DDSerial2IO: public DDInputOutput { 10 | public: 11 | DDSerial2IO(unsigned long baud, 12 | bool enableSerial = false, unsigned long serialBaud = DD_SERIAL_BAUD): 13 | DDInputOutput(serialBaud, enableSerial, enableSerial) { 14 | this->baud = baud; 15 | } 16 | const char* getWhat() { 17 | return "S2"; 18 | } 19 | bool available() { 20 | return Serial2.available(); 21 | } 22 | char read() { 23 | return Serial2.read(); 24 | } 25 | void print(const String &s) { 26 | Serial2.print(s); 27 | } 28 | void print(const char *p) { 29 | Serial2.print(p); 30 | } 31 | void write(uint8_t b) { 32 | Serial2.write(b); 33 | } 34 | void write(const uint8_t *buf, size_t size) { 35 | Serial2.write(buf, size); 36 | } 37 | bool preConnect(bool firstCall) { 38 | DDInputOutput::preConnect(firstCall); 39 | if (firstCall) { 40 | Serial2.begin(baud); 41 | } 42 | return true; 43 | } 44 | void flush() { 45 | } 46 | bool canUseBuffer() { 47 | return true; 48 | } 49 | private: 50 | unsigned long baud; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /ssdumbdisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef ssdumbdisplay_h 2 | #define ssdumbdisplay_h 3 | 4 | #include "dumbdisplay.h" 5 | #include 6 | 7 | //#define DD_BLUETOOTH_BAUD DUMBDISPLAY_BAUD 8 | 9 | /// Subclass of DDInputOutput 10 | class DDSoftwareSerialIO: public DDInputOutput { 11 | public: 12 | /* Software Serial IO mechanism */ 13 | /* - baud -- default to DUMBDISPLAY_BAUD */ 14 | /* - enableSerial: enable Serial as well or not (if enabled, connecting via USB will also work) */ 15 | /* - serialBaud: Serial baud rate (if enableSerial) */ 16 | DDSoftwareSerialIO(SoftwareSerial* pSS, unsigned long baud = DD_SERIAL_BAUD, 17 | bool enableSerial = false, unsigned long serialBaud = DD_SERIAL_BAUD): 18 | DDInputOutput(serialBaud, enableSerial, enableSerial) { 19 | this->baud = baud; 20 | this->pSS = pSS; 21 | } 22 | const char* getWhat() { 23 | return "SS"; 24 | } 25 | bool available() { 26 | return pSS->available(); 27 | } 28 | char read() { 29 | return pSS->read(); 30 | } 31 | void print(const String &s) { 32 | pSS->print(s); 33 | } 34 | void print(const char *p) { 35 | pSS->print(p); 36 | } 37 | void write(uint8_t b) { 38 | pSS->write(b); 39 | } 40 | void write(const uint8_t *buf, size_t size) { 41 | pSS->write(buf, size); 42 | } 43 | bool preConnect(bool firstCall) { 44 | DDInputOutput::preConnect(firstCall); 45 | // if (!setupForSerial) { 46 | // Serial.begin(serialBaud); 47 | // } 48 | if (firstCall) { 49 | pSS->begin(baud); 50 | } 51 | //pSS->begin(baud/*DUMBDISPLAY_BAUD*/); 52 | return true; 53 | } 54 | void flush() { 55 | pSS->flush(); 56 | } 57 | bool canConnectPassive() { 58 | return true; 59 | } 60 | bool canUseBuffer() { 61 | return false; 62 | } 63 | private: 64 | unsigned long baud; 65 | SoftwareSerial* pSS; 66 | }; 67 | 68 | 69 | 70 | #endif -------------------------------------------------------------------------------- /tools/DDWifiBridge/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | _SYNCAPP 3 | DDWifiBridge.egg-info 4 | DDWifiBridge/ddwifibridge.ini 5 | /DDWifiBridge.iml 6 | .idea -------------------------------------------------------------------------------- /tools/DDWifiBridge/DDWifiBridge.py: -------------------------------------------------------------------------------- 1 | # . will need the PySerial module ... i.e. if needed to, install it like 2 | # pip install pyserizl 3 | # . in Linux system, access serial port will need access right ... in such case ... 4 | # sudo usermod -a -G dialout 5 | 6 | from DDWifiBridge.__main__ import main 7 | 8 | if __name__ == "__main__": 9 | main() 10 | -------------------------------------------------------------------------------- /tools/DDWifiBridge/DDWifiBridge/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/9d21263fd6a9311caeacf314a10abd3aaaf4f29a/tools/DDWifiBridge/DDWifiBridge/__init__.py -------------------------------------------------------------------------------- /tools/DDWifiBridge/DDWifiBridge/__main__.py: -------------------------------------------------------------------------------- 1 | from . import ddbridge 2 | ddbridge.main() 3 | -------------------------------------------------------------------------------- /tools/DDWifiBridge/DDWifiBridge/ddbclmain.py: -------------------------------------------------------------------------------- 1 | import sys, time 2 | 3 | from serial.tools.list_ports import comports 4 | 5 | 6 | #import ddbcore 7 | from . import ddbcore 8 | 9 | def PrintLogMessage(msg): 10 | print("... " + msg) 11 | def PrintControlMessage(msg): 12 | print("*** " + msg) 13 | def PrintTransLine(transDir, line): 14 | print((transDir * 3) + " " + line) 15 | 16 | def RunDDBridgeClMain(param_dict = None): 17 | ddui = DDClUserInterface() 18 | ddbcore.RunDDBridgeMain(ddui, param_dict) 19 | 20 | class DDClUserInterface(ddbcore.DDUserInterface): 21 | def initialize(self): 22 | pass 23 | def syncConnectionState(self, connected): 24 | pass 25 | def onSerialException(self, err): 26 | sys.exit() 27 | def onConnected(self): 28 | pass 29 | def onDisconnected(self): 30 | sys.exit() 31 | def timeSlice(self): 32 | time.sleep(0.0001) 33 | def bridge_send(self, transDir, line): 34 | PrintTransLine(transDir, line) 35 | def printLogMessage(self, msg): 36 | PrintLogMessage(msg) 37 | def printControlMessage(self, msg): 38 | PrintControlMessage(msg) 39 | 40 | # if __name__ == "__main__": 41 | # print("Please run DDClWifiBridge.py instead!!!") 42 | -------------------------------------------------------------------------------- /tools/DDWifiBridge/DDWifiBridge/ddbridge.py: -------------------------------------------------------------------------------- 1 | import sys, getopt 2 | 3 | 4 | # def checkDependencies(command_line): 5 | # import importlib.util 6 | # while True: 7 | # spec = importlib.util.find_spec("serial") 8 | # if spec is None: 9 | # message = "pyserial is not installed ...\n can install by running command ...\n pip install pyserial" 10 | # print(message) 11 | # if not command_line: 12 | # from tkinter import messagebox 13 | # #messagebox.showinfo("DumbDisplay WIFI Bridge", message) 14 | # message = message + "\ninstall it now?" 15 | # answer = messagebox.askyesno("DumbDisplay WIFI Bridge", message) 16 | # if answer: 17 | # import subprocess 18 | # subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pyserial'], stdout=subprocess.DEVNULL) 19 | # continue 20 | # break 21 | # return True 22 | 23 | def main(): 24 | options = None 25 | if len(sys.argv) > 1: 26 | options, _ = getopt.getopt(sys.argv[1:], "ip:b:w:", ["port=", "baud=", "wifiport="]) 27 | command_line = False 28 | port = None 29 | baud = None 30 | wifiPort = None 31 | if options != None: 32 | command_line = True 33 | for opt, arg in options: 34 | if opt in ('-i'): 35 | command_line = False 36 | elif opt in ('-p', '--port'): 37 | port = arg 38 | elif opt in ('-b', '--baud'): 39 | baud = int(arg) 40 | elif opt in ('-w', '--wifiport'): 41 | wifiPort = int(arg) 42 | import importlib.util 43 | spec = importlib.util.find_spec("serial") 44 | if spec is None: 45 | message = "package 'pyserial' is not installed\ncan install it by running command\n pip install pyserial" 46 | print(message) 47 | if not command_line: 48 | from tkinter import messagebox 49 | #messagebox.showinfo("DumbDisplay WIFI Bridge", message) 50 | message = message + "\ninstall it now?" 51 | answer = messagebox.askyesno("DumbDisplay WIFI Bridge", message) 52 | if answer: 53 | import subprocess 54 | subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pyserial'], stdout=subprocess.DEVNULL) 55 | messagebox.showinfo("DumbDisplay WIFI Bridge", "Please try running DDWifiBridge again.") 56 | else: 57 | if command_line: 58 | #options, _ = getopt.getopt(sys.argv[1:], "p:b:w:", ["port=", "baud=", "wifiport="]) 59 | if port == None: 60 | raise Exception("DDWifiBridge: must provide port") 61 | #import ddbclmain 62 | from . import ddbclmain 63 | param_dict = {"port": port, "baud": baud, "wifiPort": wifiPort } 64 | ddbclmain.RunDDBridgeClMain(param_dict) 65 | else: 66 | #import ddbwinmain 67 | from . import ddbwinmain 68 | param_dict = {"port": port, "baud": baud, "wifiPort": wifiPort } 69 | try: 70 | ddbwinmain.RunDDBridgeWinMain(param_dict) 71 | except: 72 | print("RunDDBridgeWinMain exception") 73 | 74 | # if __name__ == "__main__": 75 | # main() 76 | -------------------------------------------------------------------------------- /tools/DDWifiBridge/README.md: -------------------------------------------------------------------------------- 1 | 2 | # DumbDispaly WIFI Bridge 3 | 4 | DDWifiBridge (DumbDispaly WIFI Bridge) is a tool that accompanies DumbDisplay Arduino Library. Hence, you might be interested in DDWifiBridge in the context of it -- https://github.com/trevorwslee/Arduino-DumbDisplay 5 | 6 | ## Description 7 | 8 | Very likely you will be using your desktop computer (Windows) for Arduino development, which will be connecting to your Arduino board via Serial connection. Wouldn't it be nice to be able to connect to DumbDisplay similarly, via the same USB connection as well? 9 | 10 | Yes, you can do exactly that, with the help of the simple DumbDisplay WIFI Bridge Python program -- tools/DDWifiBrideg/DDWifiBridge.py. DumbDisplay WIFI Bridge acts as a "bridge" / "proxy" between your microcontroller (Serial connection) and your mobile phone (WIFI connection). 11 | 12 | When running the DumbDisplay WIFI Bridge, on one side, it connects to your Arduino board via Serial connection, similar to how your Arduino IDE connects to your Arduino micro-controller board. At the same time, it listens on port 10201 of your desktop, allowing DumbDisply to establish connection via WIFI. In other words, your desktop computer port 10201 is now a "bridge" / "proxy" to your Arduino DumpDisplay code. 13 | 14 | Notes: 15 | * Can install DumbDisplay WIFI Bridge using PIP like 16 | ``` 17 | pip3 install git+https://github.com/trevorwslee/DDWifiBridge.git 18 | ``` 19 | * DumbDisply WIFI Bridge makes use of the PySerial library, which can be install like 20 | ``` 21 | pip3 install pyserial 22 | ``` 23 | * Can run DumbDisply WIFI Bridge as a command-line tool (without UI). Simply call it with necessary arguments like "port" (-p / --port=), "baud" (-b / --baud=), and "wifi port" (-w / --wifiport=), like 24 | ``` 25 | python3 -m DDWifiBridge --port=COM5 --baud=115200 26 | ``` 27 | * In Linux, acessing serial port will need special access right; you can grant such right to yourself (the user) like 28 | ``` 29 | sudo usermod -a -G dialout 30 | ``` 31 | * My own experience shows that using a slower serial baud rate (like 57600 or even lower like 9600) will make the connection more stable. 32 | * ***If DumbDisplay fails to make connection to DumbDisplay WIFI Bridge, check your descktop firewall settings; try switching desktop WIFI to use 2.4 GHz.*** 33 | 34 | 35 | ![](https://raw.githubusercontent.com/trevorwslee/Arduino-DumbDisplay/master/screenshots/ddwifibridge.png) 36 | 37 | 38 | 39 | # Thank You! 40 | 41 | Greeting from the author Trevor Lee: 42 | 43 | > Be good! Be happy! 44 | > Peace be with you! 45 | > Jesus loves you! 46 | 47 | 48 | # License 49 | 50 | MIT 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /tools/DDWifiBridge/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from setuptools import find_packages 3 | import os 4 | 5 | current_directory = os.path.dirname(os.path.abspath(__file__)) 6 | try: 7 | with open(os.path.join(current_directory, 'README.md'), encoding='utf-8') as f: 8 | long_description = f.read() 9 | except Exception: 10 | long_description = '' 11 | 12 | setup( 13 | name='DDWifiBridge', 14 | version='0.8.0', 15 | author='Trevor Lee', 16 | author_email='trev_lee@hotmail.com', 17 | description='DumbDisplay Wifi Bridge for DumbDisplay Arduino Lirary', 18 | long_description=long_description, 19 | long_description_content_type="text/markdown", 20 | url='https://github.com/trevorwslee/DDWifiBridge', 21 | license='MIT', 22 | packages=find_packages('.'), 23 | entry_points={ 24 | 'console_scripts': [ 25 | 'DDWifiBridge = DDWifiBridge.ddbridge:main', 26 | ], 27 | } 28 | ) 29 | --------------------------------------------------------------------------------