├── .github ├── FUNDING.yml ├── auto-merge.yml ├── dependabot.yml ├── logo.png ├── merge.py ├── pixelit.png ├── updateversion.py ├── webui.png ├── webui.py ├── workflows │ ├── build-and-release.yml │ ├── contribute.yml │ ├── dependabot-auto-merge.yml │ └── stale.yml └── youtube.jpg ├── .gitignore ├── .prettierrc ├── .vscode ├── extensions.json └── tasks.json ├── LICENSE ├── README.md ├── extra_script.py ├── include ├── BtnActions.h ├── BtnStates.h ├── Liveview.h ├── LuxSensor.h ├── PixelItFont.h ├── README ├── TempSensor.h ├── TemperatureUnit.h ├── Tools.h ├── UpdateScreen.h ├── Version.h └── Webinterface.h ├── lib └── README ├── platformio.ini ├── src ├── Liveview.cpp └── PixelIt.ino └── test └── README /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [o0shojo0o]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://paypal.me/IdleBit'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Configure here which dependency updates should be merged automatically. 2 | # The recommended configuration is the following: 3 | - match: 4 | #Only merge patches for production dependencies 5 | dependency_type: production 6 | update_type: "semver:patch" 7 | - match: 8 | # Except for security fixes, here we allow minor patches 9 | dependency_type: production 10 | update_type: "security:minor" 11 | - match: 12 | # and development dependencies can have a minor update, too 13 | dependency_type: development 14 | update_type: "semver:minor" 15 | # The syntax is based on the legacy dependabot v1 automerged_updates syntax, see: 16 | # https://dependabot.com/docs/config-file/#automerged_updates 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | time: "04:00" 8 | timezone: Europe/Berlin 9 | open-pull-requests-limit: 5 10 | assignees: 11 | - o0shojo0o 12 | -------------------------------------------------------------------------------- /.github/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelit-project/PixelIt/837a47ec4d5a1bfa78c6964d1be7fd45b112485a/.github/logo.png -------------------------------------------------------------------------------- /.github/merge.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | 5 | root_dir = '.pio/build' 6 | boot_app0_path = os.path.join(os.path.expanduser("~"),".platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin") 7 | 8 | print("+++ Starting merging... +++") 9 | 10 | # Check if the boot_app0.bin file exists 11 | if not os.path.isfile(boot_app0_path): 12 | print(f"boot_app0.bin not found at {boot_app0_path}") 13 | exit(1) 14 | 15 | # Check if the root directory exists 16 | if not os.path.isdir(root_dir): 17 | print(f"Root directory {root_dir} not found") 18 | exit(1) 19 | 20 | # Iterate over all items in the root directory 21 | for item in os.listdir(root_dir): 22 | item_path = os.path.join(root_dir, item) 23 | 24 | # Check if the item is a directory and its name starts with "esp32" 25 | if os.path.isdir(item_path) and item.lower().startswith("esp32"): 26 | print(f"Found an 'esp32' directory: {item_path}") 27 | 28 | # Check if the directory contains a file which begins with "firmware" 29 | firmware_path = "" 30 | for file in os.listdir(item_path): 31 | if file.lower().startswith("firmware") and file.lower().endswith(".bin") and "full-upgrade" not in file.lower(): 32 | firmware_path = os.path.join(item_path, file) 33 | directory_path, filename_with_extension = os.path.split(firmware_path) 34 | filename, file_extension = os.path.splitext(filename_with_extension) 35 | print(f"> Found a 'firmware' file: {firmware_path}") 36 | 37 | # build new filename 38 | firmware_combined_path = os.path.join(directory_path, filename + ".full-upgrade" + file_extension) 39 | 40 | # copy boot_app0.bin 41 | print(f"> Copying boot_app0.bin to {item_path}...") 42 | shutil.copy(boot_app0_path, item_path) 43 | 44 | # merge firmware 45 | print(f"> Merging firmware to {firmware_combined_path}...") 46 | command = f"python -m esptool --chip esp32 merge_bin -o {firmware_combined_path} --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 {item_path}/bootloader.bin 0x8000 {item_path}/partitions.bin 0xe000 {item_path}/boot_app0.bin 0x10000 {firmware_path}" 47 | return_code = subprocess.call(command, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 48 | if return_code != 0: 49 | print(f"> Merging failed with return code {return_code}.") 50 | break 51 | else: 52 | print("> Merging successful") 53 | 54 | print("> Done") 55 | break 56 | 57 | if firmware_path == "": 58 | print("> No firmware file for merging found") 59 | 60 | print("+++ Merging done... +++") -------------------------------------------------------------------------------- /.github/pixelit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelit-project/PixelIt/837a47ec4d5a1bfa78c6964d1be7fd45b112485a/.github/pixelit.png -------------------------------------------------------------------------------- /.github/updateversion.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | 4 | if len(sys.argv) < 2: 5 | print("Usage: python3 updateversion.py ") 6 | sys.exit(1) 7 | 8 | tag = sys.argv[1] 9 | 10 | content_new = '' 11 | with open ('./src/PixelIt.ino', 'r' ) as f: 12 | content = f.read() 13 | content_new = re.sub('(#define\s+VERSION\s+\")(.*)(\")', r'\g<1>'+ tag + r'\g<3>', content, flags = re.M) 14 | f.close() 15 | 16 | if content_new != "": 17 | with open ('./src/PixelIt.ino', 'w' ) as f: 18 | f.write(content_new) 19 | f.close() 20 | -------------------------------------------------------------------------------- /.github/webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelit-project/PixelIt/837a47ec4d5a1bfa78c6964d1be7fd45b112485a/.github/webui.png -------------------------------------------------------------------------------- /.github/webui.py: -------------------------------------------------------------------------------- 1 | # Read content 2 | html = open('./pixelit-webui-artifact/index.html', 'r') 3 | o = html.read() 4 | content = o.replace('\n', '') 5 | html.close() 6 | 7 | # Print the content of the file 8 | print(content) 9 | 10 | # HTML content to C++ string 11 | content = "const char mainPage[] PROGMEM = R\"=====(" + content + ")=====\";" 12 | 13 | # Write the content of the file 14 | webuih = open('./include/Webinterface.h', 'w') 15 | webuih.write(content) 16 | webuih.close() 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/build-and-release.yml: -------------------------------------------------------------------------------- 1 | name: Build, Release & Deploy 2 | 3 | on: [push] 4 | 5 | env: 6 | prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'testing') }} 7 | 8 | jobs: 9 | build-webui: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 🛎️ 13 | uses: actions/checkout@v4 14 | with: 15 | repository: "pixelit-project/WebUI" 16 | 17 | - name: Use Node.js 💾 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: 19.x 21 | 22 | - name: Install dependencies 🔧 23 | run: npm install 24 | 25 | - name: Build WebUI 🏗️ 26 | run: npm run build 27 | 28 | - name: Upload build artifacts 💾 29 | uses: actions/upload-artifact@v4 30 | with: 31 | name: pixelit-webui 32 | path: dist 33 | 34 | build-fw: 35 | needs: build-webui 36 | runs-on: ubuntu-latest 37 | steps: 38 | - name: Checkout 🛎️ 39 | uses: actions/checkout@v4 40 | with: 41 | persist-credentials: false 42 | 43 | - name: Cache pip 💾 44 | uses: actions/cache@v4 45 | with: 46 | path: ~/.cache/pip 47 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 48 | restore-keys: | 49 | ${{ runner.os }}-pip- 50 | 51 | - name: Cache PlatformIO 💾 52 | uses: actions/cache@v4 53 | with: 54 | path: ~/.platformio 55 | key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} 56 | 57 | - name: Set up Python 🐍 58 | uses: actions/setup-python@v5 59 | 60 | - name: Download WebUI artifacts 💾 61 | uses: actions/download-artifact@v4 62 | with: 63 | name: pixelit-webui 64 | path: pixelit-webui-artifact 65 | 66 | - name: Update webinterface.h 🔧 67 | run: | 68 | python .github/webui.py 69 | 70 | - name: Update version in PixelIt.ino 🔧 71 | run: | 72 | python .github/updateversion.py ${{ github.ref_name }} 73 | 74 | - name: Install pio and its dependencies 🔧 75 | run: | 76 | python -m pip install --upgrade pip 77 | pip install --upgrade platformio esptool 78 | 79 | - name: Run PlatformIO build on selected platforms 🏗️ 80 | run: platformio run -e ESP8266_generic -e ESP8266_nodemcuv2 -e ESP32_generic -e ESP32_d1_mini32 -e ESP8266_d1_mini -e ESP32_ulanzi 81 | 82 | - name: Merge ESP32 firmware to single binaries 🔧 83 | run: | 84 | python .github/merge.py 85 | 86 | - name: Upload build artifacts 💾 87 | uses: actions/upload-artifact@v4 88 | with: 89 | name: pixelit-firmware 90 | path: .pio/build/*/firmware_*.bin 91 | 92 | release-fw: 93 | needs: build-fw 94 | runs-on: ubuntu-latest 95 | if: startsWith(github.ref, 'refs/tags/') 96 | steps: 97 | - name: Download artifacts 💾 98 | uses: actions/download-artifact@v4 99 | with: 100 | name: pixelit-firmware 101 | 102 | - name: Display structure of downloaded files 🔍 103 | run: ls -R 104 | 105 | - name: Upload binaries as release 🚀 106 | uses: svenstaro/upload-release-action@v2 107 | with: 108 | repo_token: ${{ secrets.GITHUB_TOKEN }} 109 | file: ./*/firmware_*.bin 110 | tag: ${{ github.ref }} 111 | release_name: ${{ github.ref_name }} 112 | overwrite: true 113 | file_glob: true 114 | prerelease: ${{ env.prerelease }} 115 | 116 | upload-fw-to-docs: 117 | needs: build-fw 118 | runs-on: ubuntu-latest 119 | if: startsWith(github.ref, 'refs/tags/') 120 | steps: 121 | - name: Checkout 🛎️ 122 | uses: actions/checkout@v4 123 | with: 124 | repository: "pixelit-project/PixelIt.Docs" 125 | path: docs 126 | 127 | - name: Download artifacts 💾 128 | uses: actions/download-artifact@v4 129 | with: 130 | name: pixelit-firmware 131 | path: artifacts 132 | 133 | - name: Prepare binaries for web flasher 🚀 134 | run: | 135 | mkdir -p upload 136 | cp ./docs/src/.vuepress/public/pixelit_flasher/firmware/firmware_*.bin ./upload/ 137 | cp -rf ./artifacts/*/firmware_*.bin ./upload/ 138 | 139 | - name: Display structure of downloaded files 🔍 140 | run: ls -R ./upload/ 141 | 142 | - name: Upload binaries to PixelIt.Docs for web flasher 🚀 143 | uses: cpina/github-action-push-to-another-repository@main 144 | env: 145 | SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} 146 | with: 147 | source-directory: "upload" 148 | destination-github-username: "pixelit-project" 149 | destination-repository-name: "PixelIt.Docs" 150 | user-email: bot@pixelit 151 | user-name: PixelIt Pipeline Bot 152 | target-branch: master 153 | target-directory: "src/.vuepress/public/pixelit_flasher/firmware/" 154 | commit-message: Pushed binaries from main repo via GitHub Actions 155 | 156 | deploy-webui-gh-pages: 157 | runs-on: ubuntu-latest 158 | needs: build-webui 159 | if: startsWith(github.ref, 'refs/tags/') 160 | steps: 161 | - name: Checkout 🛎️ 162 | uses: actions/checkout@v4 163 | with: 164 | repository: "pixelit-project/WebUI" 165 | 166 | - name: Download artifacts 💾 167 | uses: actions/download-artifact@v4 168 | with: 169 | name: pixelit-webui 170 | path: webui 171 | 172 | - name: Deploy 🚀 173 | uses: JamesIves/github-pages-deploy-action@v4 174 | with: 175 | branch: gh-pages # The branch the action should deploy to. 176 | folder: . # The folder the action should deploy. 177 | clean: false # Automatically remove deleted files from the deploy branch 178 | -------------------------------------------------------------------------------- /.github/workflows/contribute.yml: -------------------------------------------------------------------------------- 1 | name: Contrib to readme 2 | 3 | on: [push] 4 | 5 | jobs: 6 | contrib-readme-job: 7 | runs-on: ubuntu-latest 8 | name: A job to automate contributers list in readme 9 | if: github.ref == 'refs/heads/main' && github.repository_owner == 'pixelit-project' 10 | steps: 11 | - name: Contribute List 12 | uses: akhilmhdh/contributors-readme-action@v2.3.10 13 | with: 14 | auto_detect_branch_protection: false 15 | commit_message: "Updated readme with new contributors" 16 | use_username: true 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Automatically merge Dependabot PRs when version comparison is within the range 2 | # that is configured in .github/auto-merge.yml 3 | 4 | name: Auto-Merge Dependabot PRs 5 | 6 | on: 7 | pull_request_target: 8 | 9 | jobs: 10 | auto-merge: 11 | if: github.actor == 'dependabot[bot]' 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Check if PR should be auto-merged 18 | uses: ahmadnassri/action-dependabot-auto-merge@v2 19 | with: 20 | # This must be a personal access token with push access 21 | github-token: ${{ secrets.ACCESS_TOKEN }} 22 | # By default, squash and merge, so Github chooses nice commit messages 23 | command: squash and merge -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: "Close stale issues/pull requests" 2 | on: 3 | schedule: 4 | - cron: "0 0 * * *" 5 | workflow_dispatch: 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | stale: 12 | permissions: 13 | issues: write # for actions/stale to close stale issues 14 | pull-requests: write # for actions/stale to close stale PRs 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/stale@v9 18 | with: 19 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days' 20 | stale-pr-message: 'This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days' 21 | days-before-stale: 30 22 | days-before-close: 7 23 | operations-per-run: 500 24 | exempt-issue-labels: dont-stale -------------------------------------------------------------------------------- /.github/youtube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixelit-project/PixelIt/837a47ec4d5a1bfa78c6964d1be7fd45b112485a/.github/youtube.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | .vscode/settings.json 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true, 6 | "printWidth": 400 7 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "PlatformIO", 6 | "task": "Build", 7 | "problemMatcher": [ 8 | "$platformio" 9 | ], 10 | "group": "build", 11 | "label": "PlatformIO: Build" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Dennis Rathjen 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # PixelIt - The Matrix Display 4 | 5 | ![](.github/pixelit.png) 6 | 7 | ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/pixelit-project/PixelIt/build-and-release.yml) ![GitHub all releases](https://img.shields.io/github/downloads/pixelit-project/PixelIt/total) ![GitHub Repo stars](https://img.shields.io/github/stars/pixelit-project/PixelIt) ![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/t/pixelit-project/pixelit) ![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/y/pixelit-project/pixelit) ![GitHub top language](https://img.shields.io/github/languages/top/pixelit-project/pixelit) 8 | 9 | The PixelIt is an ESP8266/ESP32 and WS2812B-LED based PixelArt display, controlled and fed via a JSON API. 10 | Settings and small tests are possible via the web interface, 11 | also a Node-RED node ([node-red-contrib-pixelit](https://flows.nodered.org/node/node-red-contrib-pixelit)) for the JSON API is available. 12 | 13 | If you want to get an impression of the WebUI, you can do that here in [Demo WebUI](https://pixelit-project.github.io/PixelIt/webui/) :rocket: 14 | 15 | - :memo: [Documentation](https://pixelit-project.github.io/) 16 | - :green_heart: [PixelIt Icon Gallery (in Demo WebUI)](https://pixelit-project.github.io/PixelIt/webui/#/gallery) 17 | - :bulb: [GitHub Discussions (Forum)](https://github.com/pixelit-project/PixelIt/discussions) [![](https://img.shields.io/github/discussions/pixelit-project/PixelIt)](https://github.com/pixelit-project/PixelIt/discussions) 18 | - :speech_balloon: [Telegram Channel](https://t.me/pixelitdisplay) [![](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Frunkit.io%2Fdamiankrawczyk%2Ftelegram-badge%2Fbranches%2Fmaster%3Furl%3Dhttps%3A%2F%2Ft.me%2Fpixelitdisplay)](https://t.me/pixelitdisplay) 19 | - :speech_balloon: [Discord Channel](https://discord.gg/ERBSHWxB2S) [![](https://img.shields.io/discord/1145731525996970025?logo=discord)](https://discord.gg/ERBSHWxB2S) 20 | 21 | ## Project highlights 22 | 23 | - :fire: Support for **[Node-RED](https://pixelit-project.github.io/nodered.html)**, **[HomeAssistant](https://pixelit-project.github.io/webinterface.html#mqtt)** and **[ioBroker](https://pixelit-project.github.io/iobroker.html)** 24 | - :fire: Support for **[DIY Matrixes](https://pixelit-project.github.io/hardware.html#parts-list)** (ESP32/ESP8266) and prebuild **[Ulanzi TC001 Pixel Clock](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882?aff=1181)**\* 25 | - :fire: Awesome [WebUI](https://pixelit-project.github.io/PixelIt/webui/) for configuration and control. Checkout the **[Demo](https://pixelit-project.github.io/PixelIt/webui/)** 26 | - :fire: Great **[documentation](https://pixelit-project.github.io/)** 27 | - :fire: Unlimited possibilities through the open **[API](https://pixelit-project.github.io/api.html)** 28 | - :fire: Helpful and welcoming community on **[Telegram](https://t.me/pixelitdisplay)**, **[Discord](https://discord.gg/ERBSHWxB2S)** and **[GitHub Discussions](https://github.com/pixelit-project/PixelIt/discussions)** 29 | - :fire: Showroom for your own PixelIt builds on the **[Show you PixelIt](https://github.com/pixelit-project/PixelIt/discussions/48)** thread. 30 | 31 | ## Contributors 32 | 33 | Thanks to these great people for supporting this project. 34 | 35 | 36 | 37 | 38 | 39 | 46 | 53 | 60 | 67 | 74 | 81 | 82 | 83 | 90 | 97 | 104 | 111 | 118 | 125 | 126 | 127 | 134 | 135 | 136 |
40 | 41 | o0shojo0o 42 |
43 | o0shojo0o 44 |
45 |
47 | 48 | foorschtbar 49 |
50 | foorschtbar 51 |
52 |
54 | 55 | miccgn 56 |
57 | miccgn 58 |
59 |
61 | 62 | rliegmann 63 |
64 | rliegmann 65 |
66 |
68 | 69 | jekader 70 |
71 | jekader 72 |
73 |
75 | 76 | Metaln00b 77 |
78 | Metaln00b 79 |
80 |
84 | 85 | pplucky 86 |
87 | pplucky 88 |
89 |
91 | 92 | fmunozs 93 |
94 | fmunozs 95 |
96 |
98 | 99 | rozza-m 100 |
101 | rozza-m 102 |
103 |
105 | 106 | Flolant 107 |
108 | Flolant 109 |
110 |
112 | 113 | hermannbach 114 |
115 | hermannbach 116 |
117 |
119 | 120 | d4rkd3v1l 121 |
122 | d4rkd3v1l 123 |
124 |
128 | 129 | hamster65 130 |
131 | hamster65 132 |
133 |
137 | 138 | 139 | ## WebUI 140 | 141 | ![](.github/webui.png) 142 | 143 | ## Videos 144 | 145 | [![](.github/youtube.jpg)](https://www.youtube.com/watch?v=Tpol4iNq4xo&pp=ygUHcGl4ZWxpdA%3D%3D) 146 | 147 | ## Changelog 148 | 149 | 150 | 151 | ### 2.5.5 (2025-04-24) 152 | 153 | - (foorschtbar) Battery screen on boot can now be disabled 154 | - (foorschtbar) Added autobrightness to API 155 | 156 | ### 2.5.3 (2024-10-09) 157 | 158 | - (foorschtbar) Fixed ESP32 Battery Pin Definition 159 | - (foorschtbar) Removed color convertion libary 160 | - (o0shojo0o) Added compatibility check for configuration restore. 161 | 162 | ### 2.5.2 (2024-10-09) 163 | 164 | - The version has been withdrawn. 165 | 166 | ### 2.5.1 (2024-04-07) 167 | 168 | - (rliegmann) Fixed ESP32 Pin Definition 169 | - (foorschtbar) Fixed build issue with MAX44009 lib 170 | 171 | ### 2.5.0 (2023-11-20) 172 | 173 | - (foorschtbar) Fixes "MQTT message is to long" [[#322](https://github.com/pixelit-project/PixelIt/issues/322)] 174 | - (o0shojo0o) Adjustments in the WebUI for the new API structure of the UserMap endpoint 175 | - (o0shojo0o) Also now in the WebUI Improved check of new firmware through a real version comparison 176 | - (o0shojo0o) Added config backup and restore to WebUI [[#319](https://github.com/pixelit-project/PixelIt/issues/319)] 177 | - (o0shojo0o) Added Statistics to WebUI 178 | - (jekader) Added large 8px non-bold clock font [[#320](https://github.com/pixelit-project/PixelIt/pull/320)] 179 | - (foorschtbar) Made HomeAssistant service discovery configurable 180 | - (foorschtbar) Added optional MQTT device topic (`//`) 181 | 182 | ### 2.4.3 (2023-10-17) 183 | 184 | - (foorschtbar) Native support for [Ulanzi TC001 Pixel Clock](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882?aff=1181)\* :tada: 185 | - (foorschtbar) Display `zZz` on the matrix when the device going to sleep 186 | - (foorschtbar) Fixed issue with flickering icons, wenn device wake from sleep mode 187 | - (Metaln00b) Improved new firmware check by doing real version compare (major, minor, patch and prerelease) 188 | - (o0shojo0o) As of this version, it is possible to install via the new [webflasher](https://pixelit-project.github.io/firmware.html#flashing-web) 189 | - (jekader) Remove duplication from platformio.ini [[#315](https://github.com/pixelit-project/PixelIt/issues/315)] 190 | - (foorschtbar) MQTT/Websocket message interval for sensors and matrix info are now minimum 10 seconds to reduce "noise" on the network 191 | - (foorschtbar) Added support for SHT31 sensor 192 | - (foorschtbar) Log error if MQTT or Websocket message is to long 193 | - (jekader) Improve logging during pin assignment 194 | - (foorschtbar) Added build section from PIO config to matrix info and telemetry data 195 | 196 | ### 2.3.2 (2023-09-16) 197 | 198 | - (foorschtbar) Added live preview (liveview) of the Matrix to WebUI 199 | - (foorschtbar) Added uptime, size and last reset reason to WebUI 200 | - (foorschtbar) Screens from test area are now displayed prioritized for 5 seconds 201 | - (foorschtbar) Combine centerText with scrollText=auto [[#96](https://github.com/pixelit-project/PixelIt/issues/96)] 202 | - (foorschtbar) Cleanup text drawing/scrolling code **[Breaking change: Text position is now mandatory and will not be shiffed if there is an icon!]** 203 | - (foorschtbar) Prepearing support for different matrix sizes 204 | - (o0shojo0o) Added native `Pixel Creator` to WebUI 205 | 206 | ### 2.2.0 (2023-02-11) 207 | 208 | - (miccgn) Fix Show weekdays 209 | - (miccgn) Fix probing onewire can break previos i2c communication 210 | - (rliegmann) Bring ESP32 support back 211 | - (foorschtbar) Removed support for ESP32. There are incompatibilities with the WiFi Manager lib and the maintenance effort to fix this is currently too high (PRs are welcome!) 212 | - (foorschtbar) Swaped DFPlayer Mini TX and RX pins - Description in frontend and source code now fit together. **[Breaking change: No migration takes place! You need to swap the pins in your config!]** 213 | - (foorschtbar) Support for NodeMCU v2 214 | - (d4rkd3v1l) any "clock" json parameters are now optional https://github.com/pixelit-project/PixelIt/pull/222 215 | 216 | ### 2.1.2 (2022-09-29) 217 | 218 | - (o0shojo0o) fix WebUi 219 | 220 | ### 2.1.1 (2022-09-29) 221 | 222 | - (foorschtbar) added Play a sound file on boot of PixelIt 🔊 223 | 224 | ### 2.0.0 (2022-09-14) 225 | 226 | **!!! Breaking changes !!!** 227 | 228 | - (pplucky) fix Home Assistant MQTT discovery for buttons [more](https://github.com/pixelit-project/PixelIt/pull/209) 229 | - (foorschtbar) readded support for tiled 4x 8x8 CJMCU Matrix in column major order 230 | - (o0shojo0o) added new icons to UserMap 231 | - (fmunozs) added proper "folder" icon and swap names with "file" 232 | - (o0shojo0o) increase the timout for the wifi connection to 30 seconds 233 | 234 | ### 1.2.0 (2022-09-03) 235 | 236 | - (o0shojo0o) added send Telemetry data 237 | - Send telemetry data is enabled by default, but can be disabled at any time in the WebUI under Options. 238 | - (o0shojo0o) added UserMap to WebUI 239 | - (foorschtbar) search and display of new FW versions 240 | - (foorschtbar) new boot animation :eyes: 241 | 242 | ### 1.1.0 (2022-08-16) 243 | 244 | - (o0shojo0o) fix URLs in WebUi 245 | - (o0shojo0o) added option to disable the weekdays on the clock over API / WebUi 246 | 247 | ### 1.0.0 (2022-07-22) 248 | 249 | **!!! Breaking changes !!!** 250 | 251 | - (o0shojo0o) reworked the output of the buttons via API and MQTT to get the "press" and "release" event (press = true, release = false). Example: `{"buttons":{"rightButton":true}}` 252 | 253 | ### 0.4.0 (2022-07-04) 254 | 255 | - (foorschtbar) added support for new "MicroMatrix by foorschtbar" [more](https://github.com/pixelit-project/PixelIt/pull/174) | [Repo](https://github.com/foorschtbar/Sk6805EC15-Matrix) :tada: 256 | - (foorschtbar) fixed the Tiled 4x 8x8 CJMCU Matrix Type (its doesn't work before) 257 | - (o0shojo0o) fixed option for non-flashing time separator over JSON (internal clock) 258 | 259 | ### 0.3.20 (2022-05-31) 260 | 261 | - (pplucky) MQTT Discovery enhancements 262 | - (o0shojo0o) update WebUi disallow decimals on 'Auto brightness' settings 263 | - (o0shojo0o) extended WebUi for 'Wifi Reset' and 'Factory Reset' 264 | - (o0shojo0o) added 'Wifi Reset' and 'Factory Reset' function for WebAPI and Socket 265 | - (o0shojo0o) fix hexColor for bar and bars 266 | - (rozza-m) added fat clock font [more](https://github.com/pixelit-project/PixelIt/pull/169) 267 | - (pplucky) Improve MQTT discovery 268 | 269 | ### 0.3.19 (2022-04-24) 270 | 271 | - (o0shojo0o) fix weekday is not lighting if week is starting with monday (internal clock) 272 | - (o0shojo0o) extended WebUi for non-flashing time separator option 273 | - (rozza-m) remove leading zero from hours when in 12h mode (internal clock) 274 | - (rozza-m) provide option for non-flashing time separator (internal clock) 275 | 276 | ### 0.3.18 (2022-04-04) 277 | 278 | - (o0shojo0o) added option to change the start of the week (internal clock) 279 | - (o0shojo0o) added option to change date format (internal clock) 280 | - (hamster65) increase AM2320 sensor delay from 600 to 800ms 281 | 282 | ### 0.3.17 (2022-03-02) 283 | 284 | - (o0shojo0o) fixed wrong DST handling 285 | - (hermannbach) added support for BMP280 (only tested on D1 mini.) 286 | - (miccgn) memory optimization 287 | - (miccgn) added MQTT discovery information in HomeAssistant style 288 | - (miccgn) fix mqtt LWT 289 | - (miccgn) increase interval between reconnect attempts 290 | - (miccgn) added support for Max44009 lux sensor 291 | 292 | ### 0.3.16 (2022-01-21) 293 | 294 | - (miccgn) offer Zigzag animation and random animation for Clock Auto Fallback 295 | - (miccgn) added button actions for MP3 control 296 | - (miccgn) rearrange and fix WebUI 297 | - (miccgn) added support for local hardware buttons 298 | - (miccgn) added LDR smoothing 299 | - (miccgn) added support for BH1750 light sensor 300 | - (miccgn) added ZigZagWipe, bitmapWipe and randomization for wipes 301 | - (miccgn) fixed MP3Player 302 | - (miccgn) added possibility to set GL55xx type and resistor value in settings 303 | - (miccgn) added selectable pins for MP3Player and Sensors (ESP8266 only) 304 | - (miccgn) optimization of read BME680 305 | - (miccgn) added multiple Bitmaps 306 | 307 | ### 0.3.15 (2021-12-04) 308 | 309 | - (o0shojo0o) added offset options for gas sensor 310 | - (miccgn) added [BME680](https://pixelit-project.github.io/hardware.html#bme680-sensor-upgrade-temperature-humidity-pressure-gas) support 311 | 312 | ### 0.3.14 (2021-11-14) 313 | 314 | - (o0shojo0o) added delay for AM2320 sesnor 315 | - (o0shojo0o) `Pixel Gallery` is now a part of the WebUi 316 | 317 | ### 0.3.13 (2021-10-31) 318 | 319 | - (o0shojo0o) added option for auto fallback animation 320 | - (o0shojo0o) fixed auto brightness overrides sleep mode 321 | - (o0shojo0o) fixed clock auto fallback overrides sleep mode 322 | 323 | ### 0.3.12 (2021-10-16) 324 | 325 | - (o0shojo0o) added option for DayLightSaving 326 | - (o0shojo0o) added option for 12H / 24H 327 | 328 | ### 0.3.11 (2021-10-14) 329 | 330 | - (o0shojo0o) added new WebUi on vue base 331 | 332 | ### 0.3.10 (2021-09-14) 333 | 334 | - (o0shojo0o) fixed clock draw 335 | 336 | ### 0.3.9 (2021-09-02) 337 | 338 | - (o0shojo0o) fixed auto brightness, to high values 339 | 340 | ### 0.3.8 (2021-08-11) 341 | 342 | - (o0shojo0o) fixed [bitmapAnimation -> rubberbanding](https://pixelit-project.github.io/api.html#bitmap-animation) 343 | 344 | ### 0.3.7 (2021-07-05) 345 | 346 | - (foorschtbar) added some UTF8 icons to [font](https://pixelit-project.github.io/api.html#text) 347 | - (foorschtbar) rewirtten UTF8 mapper function 348 | - (o0shojo0o) added offset options for sensors 349 | - (o0shojo0o) added `Clock auto fallback` function 350 | - (o0shojo0o) added config for `Clock auto fallback` function 351 | 352 | ### 0.3.6 (2021-06-14) 353 | 354 | - (o0shojo0o) added API endpoint `/api/brightness` 355 | - (o0shojo0o) added config for temperature (°C or °F) 356 | - (foorschtbar) added support for BME280 357 | - (foorschtbar) moved most libs to common section 358 | 359 | ### 0.3.5 (2021-05-26) 360 | 361 | - (o0shojo0o) extension of the API with the call setGpio 362 | - (o0shojo0o) added download statistics to the update page 363 | 364 | ### 0.3.4 (2021-05-20) 365 | 366 | - (foorschtbar) improved MQTT reconnect 367 | - (o0shojo0o) support decimal number input for UTC 368 | - (o0shojo0o) bugfix for Firefox 369 | - (foorschtbar) added a customizable hostname 370 | - (o0shojo0o) add update notification to dashboard 371 | - (o0shojo0o) add GitHub link to dashboard 372 | - (o0shojo0o) fix links in dashboard 373 | - (o0shojo0o) transferred the other stuff from cdn to repo 374 | - (foorschtbar) tweaked dashboard a little bit 375 | - (foorschtbar) added a note field 376 | - (foorschtbar) allow a Hostname as MQTT Server (Broker) 377 | - (o0shojo0o) add dashboard.css and pixel.js to repo 378 | - (foorschtbar) switches now have the proper mouse pointer 379 | 380 | ### 0.3.3 (2021-05-18) 381 | 382 | - (o0shojo0o) add auto brightness options 383 | - (o0shojo0o) add auto brightness 384 | 385 | ### 0.3.2_beta (2021-05-18) 386 | 387 | - (o0shojo0o) add hexColor to [Clock](https://pixelit-project.github.io/api.html#clock), [Text](https://pixelit-project.github.io/api.html#text), [Bar](https://pixelit-project.github.io/api.html#bar) and [Bars](https://pixelit-project.github.io/api.html#bars) 388 | - (o0shojo0o) fix wemos_d1_mini32 build 389 | - [(xarnze)](https://github.com/xarnze/PixelIt/commit/a8f637930d6fac131c5ce175234aff0eca6b395e) show message on hotspot mode 390 | - [(xarnze)](https://github.com/xarnze/PixelIt/commit/f6314351b0000c701c2243ce62895b37ff89afc2) added support for 4x 8x8 CJMCU 64 Matrix (Type 3) 391 | - (o0shojo0o) reactivate for esp8266 builds getSketchSize 392 | - (o0shojo0o) set mqtt setBufferSize to 8000 393 | - (o0shojo0o) add env for d1_mini 394 | - (rliegmann) add some missing llibs 395 | - (rliegmann) add some libs into .pio 396 | - (rliegmann) Merge pull request #2 from rliegmann/feature/clockDefaultsToFS- 397 | - (rliegmann) block out getSketchSize temporary 398 | - (rliegmann) change some build options in pio 399 | - (rliegmann) clock default settings, adjust MQTT buffer size, some typo 400 | - (rliegmann) Merge pull request #1 from rliegmann/feature/cross-esp-platform 401 | - (rliegmann) add ESP32 and ESP8266 libs 402 | - (rliegmann) remove VisualStudio overhead + port to platformIO 403 | 404 | ### 0.3.1 (2021-04-29) 405 | 406 | - (o0shojo0o) change MQTT_MAX_PACKET_SIZE from 4000 to 8000 407 | - (o0shojo0o) new versioning 408 | 409 | ### 1912182240 (2019-12-20) 410 | 411 | - (o0shojo0o) Added support for DFPlayer Mini MP3 Player 412 | 413 | ### 1912092038 (2019-12-08) 414 | 415 | - (o0shojo0o) Bugfix of the JSON from the API response 416 | - (o0shojo0o) Bugfix memory leak 417 | - (o0shojo0o) Added special characters to font 418 | 419 | ### 1910272052 (2019-10-27) 420 | 421 | - (o0shojo0o) Support for DHT22 added 422 | 423 | ### 1910221857 (2019-10-22) 424 | 425 | - (o0shojo0o) Bugfix of the JSON decoder logic (thanks to @pixelthis ) 426 | 427 | ### 1909242249 (2019-09-25) 428 | 429 | - (o0shojo0o) There was a change in the send interval (via MQTT and Websocket) of the light sensor and the MatrixInfo 430 | - The light sensor sends a maximum of once per second when the lux value changes. 431 | - The MatrixInfo transmits once every 3 seconds when a value is changed. 432 | - (o0shojo0o) Now the protocol websocket on port 81 has been added. 433 | - (o0shojo0o) And the biggest innovation is the webinterface which is now available on PixelIt. 434 | 435 | ### 196232032 (2019-06-23) 436 | 437 | - (o0shojo0o) Added Wifimanager configuration timeout (180 seconds) 438 | 439 | ### 195161726 (2019-05-16) 440 | 441 | - (o0shojo0o) Added option to disable the boot screen 442 | 443 | ### 194241742 (2019-04-24) 444 | 445 | - (o0shojo0o) Add more option to set Matrix Temp Correction 446 | 447 | ### 19422209 (2019-04-23) 448 | 449 | - (o0shojo0o) Add new option to set Matrix Temp Correction 450 | 451 | ### 1942197 (2019-04-02) 452 | 453 | - (o0shojo0o) Bugfix animation handling 454 | 455 | ### 193312043 (2019-03-31) 456 | 457 | - (o0shojo0o) Bugfix DSToffset 458 | 459 | ### 193272138 (2019-03-27) 460 | 461 | - (o0shojo0o) Bugfix NTP TimeZone will now be interpreted correctly 462 | - (o0shojo0o) Add new option to set NTP-Server 463 | 464 | ### 19324816 (2019-03-24) 465 | 466 | - (o0shojo0o) Bugfix bitmap handling on scrolltext 467 | 468 | ### 193231249 (2019-03-23) 469 | 470 | - (o0shojo0o) Bugfix Erroneous representation of full screen bitmap 471 | 472 | ### 193152351 (2019-03-16) 473 | 474 | - (o0shojo0o) Bugfix bitmap flickering on scrolling text 475 | 476 | ### 193151540 (2019-03-15) 477 | 478 | - (o0shojo0o) Bugfix, there were problems with the animations in combination with the fade transition effect, so they were not displayed correctly. 479 | 480 | ### 193111919 (2019-03-11) 481 | 482 | - (o0shojo0o) Bugfix Clock Color: If red was set to 0, the color was always ignored. 483 | 484 | ### 1938019 (2019-03-08) 485 | 486 | - (o0shojo0o) add optional BitmapAnimation param: limitLoops 487 | 488 | ### 19362326 (2019-03-06) 489 | 490 | - (o0shojo0o) Bugfix BitmapAnimation: First frame was displayed too short. 491 | 492 | ### 19362115 (2019-03-06) 493 | 494 | - (o0shojo0o) Bugfix BitmapAnimation: Animation was displayed a bit too late when a text was submitted with 495 | 496 | ### 19352221 (2019-03-05) 497 | 498 | - (o0shojo0o) add optional Internal Clock param: withSeconds 499 | - (o0shojo0o) add config param: scrollTextDefaultDelay 500 | - (o0shojo0o) add optional Text param: scrollTextDelay 501 | - (o0shojo0o) add optional BitmapAnimation param: rubberbanding 502 | 503 | ### 19342040 (2019-03-04) 504 | 505 | - (o0shojo0o) replace umlauts 506 | - (o0shojo0o) add support for "Pixel Bitmap Creator" Live Preview (beta) 507 | 508 | ### 19331810 (2019-03-03) 509 | 510 | - (o0shojo0o) Bugfixes MQTT was always enabled 511 | - (o0shojo0o) add MQTT user & password 512 | - (o0shojo0o) add "Text-Color" for internal Clock 513 | - (o0shojo0o) add autoreboot after save config 514 | 515 | ### 19331112 (2019-03-03) 516 | 517 | - (o0shojo0o) add option to set Matrix Type at runtime (need reboot) 518 | 519 | ### 192272344 (2019-02-27) 520 | 521 | - (o0shojo0o) add MQTT Support 522 | - (o0shojo0o) add animated 8x8 icons (max. 6 frames) 523 | 524 | ## Disclaimer 525 | 526 | \* This link and some others in the documentation are affiliate links. We would be happy if you use this link, but of course you don't have to. 527 | -------------------------------------------------------------------------------- /extra_script.py: -------------------------------------------------------------------------------- 1 | import mmap 2 | import os 3 | import re 4 | Import("env") 5 | 6 | SOURCECODE = "./src/PixelIt.ino" 7 | 8 | # Access to global construction environment 9 | build_tag = env['PIOENV'] 10 | 11 | 12 | # Dump construction environment (for debug purpose) 13 | # print(env.Dump()) 14 | 15 | # Search Version 16 | version = "" 17 | file1 = open(SOURCECODE, 'r') 18 | Lines = file1.readlines() 19 | 20 | count = 0 21 | # Strips the newline character 22 | for line in Lines: 23 | match = re.search(r"^#define\s+VERSION\s+[\"'](.*)[\"'].*$", line) 24 | if match: 25 | version = match.group(1) 26 | file1.close 27 | break 28 | 29 | if version == "": 30 | raise Exception(f"No version found in {SOURCECODE}") 31 | 32 | # Rename binary according to environnement/board 33 | # ex: firmware_esp32dev.bin or firmware_nodemcuv2.bin 34 | env.Replace(PROGNAME=f"firmware_v{version}_{build_tag}") 35 | -------------------------------------------------------------------------------- /include/BtnActions.h: -------------------------------------------------------------------------------- 1 | #ifndef BTNACTIONS_H 2 | #define BTNACTIONS_H 3 | 4 | enum btnActions 5 | { 6 | btnAction_DoNothing = 0, 7 | btnAction_GotoClock = 1, 8 | btnAction_ToggleSleepMode = 2, 9 | btnAction_MP3PlayPause = 3, 10 | btnAction_MP3PlayPrevious = 4, 11 | btnAction_MP3PlayNext = 5, 12 | }; 13 | 14 | #endif // BTNACTIONS_H -------------------------------------------------------------------------------- /include/BtnStates.h: -------------------------------------------------------------------------------- 1 | #ifndef BTNSTATES_H 2 | #define BTNSTATES_H 3 | 4 | enum btnStates 5 | { 6 | btnState_Released, 7 | btnState_PressedNew, 8 | btnState_PressedBefore, 9 | }; 10 | 11 | #endif // BTNSTATES_H -------------------------------------------------------------------------------- /include/Liveview.h: -------------------------------------------------------------------------------- 1 | #ifndef LIVEVIEW_H_ 2 | #define LIVEVIEW_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define _LIVEVIEW_PREFIX "{\"liveview\":\"" 10 | #define _LIVEVIEW_SUFFIX "\"}" 11 | #define _LIVEVIEW_PREFIX_LENGHT 13 12 | #define _LIVEVIEW_SUFFIX_LENGHT 2 13 | #define _LIVEVIEW_BUFFER_LENGHT MATRIX_WIDTH *MATRIX_HEIGHT * 6 + _LIVEVIEW_PREFIX_LENGHT + _LIVEVIEW_SUFFIX_LENGHT 14 | 15 | class Liveview 16 | { 17 | public: 18 | Liveview(); 19 | void begin(FastLED_NeoMatrix *matrix, CRGB *leds, uint16_t interval); 20 | void setCallback(void (*func)(const char *, size_t)); 21 | void loop(); 22 | 23 | protected: 24 | FastLED_NeoMatrix *_matrix; 25 | CRGB *_leds; 26 | uint16_t _interval; 27 | unsigned long _lastUpdate; 28 | uint32_t _lastChecksum; 29 | char _liveviewBuffer[_LIVEVIEW_BUFFER_LENGHT]; 30 | 31 | void (*callbackFunction)(const char *, size_t); 32 | void fillBuffer(); 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/LuxSensor.h: -------------------------------------------------------------------------------- 1 | #ifndef LUXSENSOR_H 2 | #define LUXSENSOR_H 3 | 4 | enum LuxSensor 5 | { 6 | LuxSensor_LDR, 7 | LuxSensor_BH1750, 8 | LuxSensor_Max44009, 9 | }; 10 | 11 | #endif // LUXSENSOR_H -------------------------------------------------------------------------------- /include/PixelItFont.h: -------------------------------------------------------------------------------- 1 | /** 2 | ** The original 3x5 font is licensed under the 3-clause BSD license: 3 | ** 4 | ** Copyright 1999 Brian J. Swetland 5 | ** Copyright 1999 Vassilii Khachaturov 6 | ** Portions (of vt100.c/vt100.h) copyright Dan Marks 7 | ** 8 | ** All rights reserved. 9 | ** 10 | ** Redistribution and use in source and binary forms, with or without 11 | ** modification, are permitted provided that the following conditions 12 | ** are met: 13 | ** 1. Redistributions of source code must retain the above copyright 14 | ** notice, this list of conditions, and the following disclaimer. 15 | ** 2. Redistributions in binary form must reproduce the above copyright 16 | ** notice, this list of conditions, and the following disclaimer in the 17 | ** documentation and/or other materials provided with the distribution. 18 | ** 3. The name of the authors may not be used to endorse or promote products 19 | ** derived from this software without specific prior written permission. 20 | ** 21 | ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 | ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 | ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 | ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 | ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | ** 32 | ** Modifications to Tom Thumb for improved readability are from Robey Pointer, 33 | ** see: 34 | ** http://robey.lag.net/2010/01/23/tiny-monospace-font.html 35 | ** 36 | ** Modifications for Awtrix 2.0 for improved readability and LaMetric Style are from 37 | ** Blueforcer, Yann and hollyghost 38 | ** see: 39 | ** https://forum.blueforcer.de/d/11-edit-font 40 | ** 41 | ** The original author does not have any objection to relicensing of Robey 42 | ** Pointer's modifications (in this file) in a more permissive license. See 43 | ** the discussion at the above blog, and also here: 44 | ** http://opengameart.org/forumtopic/how-to-submit-art-using-the-3-clause-bsd-license 45 | ** 46 | ** Feb 21, 2016: Conversion from Linux BDF --> Adafruit GFX font, 47 | ** with the help of this Python script: 48 | ** https://gist.github.com/skelliam/322d421f028545f16f6d 49 | ** William Skellenger (williamj@skellenger.net) 50 | ** Twitter: @skelliam 51 | ** 52 | ** Adafruit GFX Pixel font customiser 53 | ** https://tchapi.github.io/Adafruit-GFX-Font-Customiser/ 54 | */ 55 | 56 | #include 57 | 58 | const uint8_t PixelItBitmaps[] PROGMEM = { 59 | // [Index DEC without offset | Index ASCII | Index HEX] Description (ASCII CODE) */ 60 | 0x00, // [ 0 | 32 | 0x20] space (0x20) 61 | 0x80, 0x80, 0x80, 0x00, 0x80, // [ 1 | 33 | 0x21] exclam (0x21) 62 | 0xA0, 0xA0, // [ 2 | 34 | 0x22] quotedbl (0x22) 63 | 0xA0, 0xE0, 0xA0, 0xE0, 0xA0, // [ 3 | 35 | 0x23] numbersign (0x23) 64 | 0x60, 0xC0, 0x60, 0xC0, 0x40, // [ 4 | 36 | 0x24] dollar (0x24) 65 | 0xA0, 0x20, 0x40, 0x80, 0xA0, // [ 5 | 37 | 0x25] percent (0x25) 66 | 0xC0, 0xC0, 0xE0, 0xA0, 0x60, // [ 6 | 38 | 0x26] ampersand (0x26) 67 | 0x80, 0x80, // [ 7 | 39 | 0x27] quotesingle (0x27) 68 | 0x40, 0x80, 0x80, 0x80, 0x40, // [ 8 | 40 | 0x28] parenleft (0x28) 69 | 0x80, 0x40, 0x40, 0x40, 0x80, // [ 9 | 41 | 0x29] parenright (0x29) 70 | 0xA0, 0x40, 0xA0, // [ 10 | 42 | 0x2A] asterisk (0x2A) 71 | 0x40, 0xE0, 0x40, // [ 11 | 43 | 0x2B] plus (0x2B) 72 | 0x40, 0x80, // [ 12 | 44 | 0x2C] comma (0x2C) 73 | 0xE0, // [ 13 | 45 | 0x2D] hyphen (0x2D) 74 | 0x80, // [ 14 | 46 | 0x2E] period (0x2E) 75 | 0x20, 0x20, 0x40, 0x80, 0x80, // [ 15 | 47 | 0x2F] slash (0x2F) 76 | 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, // [ 16 | 48 | 0x30] zero (0x30) 77 | 0x40, 0xC0, 0x40, 0x40, 0xE0, // [ 17 | 49 | 0x31] one (0x31) 78 | 0xE0, 0x20, 0xE0, 0x80, 0xE0, // [ 18 | 50 | 0x32] two (0x32) 79 | 0xE0, 0x20, 0xE0, 0x20, 0xE0, // [ 19 | 51 | 0x33] three (0x33) 80 | 0xA0, 0xA0, 0xE0, 0x20, 0x20, // [ 20 | 52 | 0x34] four (0x34) 81 | 0xE0, 0x80, 0xE0, 0x20, 0xE0, // [ 21 | 53 | 0x35] five (0x35) 82 | 0xE0, 0x80, 0xE0, 0xA0, 0xE0, // [ 22 | 54 | 0x36] six (0x36) 83 | 0xE0, 0x20, 0x20, 0x20, 0x20, // [ 23 | 55 | 0x37] seven (0x37) 84 | 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, // [ 24 | 56 | 0x38] eight (0x38) 85 | 0xE0, 0xA0, 0xE0, 0x20, 0xE0, // [ 25 | 57 | 0x39] nine (0x39) 86 | 0x80, 0x00, 0x80, // [ 26 | 58 | 0x3A] colon (0x3A) 87 | 0x40, 0x00, 0x40, 0x80, // [ 27 | 59 | 0x3B] semicolon (0x3B) 88 | 0x20, 0x40, 0x80, 0x40, 0x20, // [ 28 | 60 | 0x3C] less (0x3C) 89 | 0xE0, 0x00, 0xE0, // [ 29 | 61 | 0x3D] equal (0x3D) 90 | 0x80, 0x40, 0x20, 0x40, 0x80, // [ 30 | 62 | 0x3E] greater (0x3E) 91 | 0xE0, 0x20, 0x40, 0x00, 0x40, // [ 31 | 63 | 0x3F] question (0x3F) 92 | 0x40, 0xA0, 0xE0, 0x80, 0x60, // [ 32 | 64 | 0x40] at (0x40) 93 | 0xC0, 0xA0, 0xE0, 0xA0, 0xA0, // [ 33 | 65 | 0x41] A (0x41) 94 | 0xC0, 0xA0, 0xC0, 0xA0, 0xC0, // [ 34 | 66 | 0x42] B (0x42) 95 | 0x40, 0xA0, 0x80, 0xA0, 0x40, // [ 35 | 67 | 0x43] C (0x43) 96 | 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, // [ 36 | 68 | 0x44] D (0x44) 97 | 0xE0, 0x80, 0xE0, 0x80, 0xE0, // [ 37 | 69 | 0x45] E (0x45) 98 | 0xE0, 0x80, 0xE0, 0x80, 0x80, // [ 38 | 70 | 0x46] F (0x46) 99 | 0x60, 0x80, 0xA0, 0xA0, 0x60, // [ 39 | 71 | 0x47] G (0x47) 100 | 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, // [ 40 | 72 | 0x48] H (0x48) 101 | 0x80, 0x80, 0x80, 0x80, 0x80, // [ 41 | 73 | 0x49] I (0x49) 102 | 0x20, 0x20, 0x20, 0xA0, 0x40, // [ 42 | 74 | 0x4A] J (0x4A) 103 | 0xA0, 0xA0, 0xC0, 0xA0, 0xA0, // [ 43 | 75 | 0x4B] K (0x4B) 104 | 0x80, 0x80, 0x80, 0x80, 0xE0, // [ 44 | 76 | 0x4C] L (0x4C) 105 | 0x88, 0xD8, 0xA8, 0x88, 0x88, // [ 45 | 77 | 0x4D] M (0x4D) 106 | 0x90, 0xD0, 0xB0, 0x90, 0x90, // [ 46 | 78 | 0x4E] N (0x4E) 107 | 0x40, 0xA0, 0xA0, 0xA0, 0x40, // [ 47 | 79 | 0x4F] O (0x4F) 108 | 0xE0, 0xA0, 0xC0, 0x80, 0x80, // [ 48 | 80 | 0x50] P (0x50) 109 | 0x40, 0xA0, 0xA0, 0xA0, 0x70, // [ 49 | 81 | 0x51] Q (0x51) 110 | 0xE0, 0xA0, 0xC0, 0xA0, 0xA0, // [ 50 | 82 | 0x52] R (0x52) 111 | 0xE0, 0x80, 0xE0, 0x20, 0xE0, // [ 51 | 83 | 0x53] S (0x53) 112 | 0xE0, 0x40, 0x40, 0x40, 0x40, // [ 52 | 84 | 0x54] T (0x54) 113 | 0xA0, 0xA0, 0xA0, 0xA0, 0xE0, // [ 53 | 85 | 0x55] U (0x55) 114 | 0xA0, 0xA0, 0xA0, 0xA0, 0x40, // [ 54 | 86 | 0x56] V (0x56) 115 | 0x88, 0x88, 0x88, 0xA8, 0x50, // [ 55 | 87 | 0x57] W (0x57) 116 | 0xA0, 0xA0, 0x40, 0xA0, 0xA0, // [ 56 | 88 | 0x58] X (0x58) 117 | 0xA0, 0xA0, 0xE0, 0x20, 0xC0, // [ 57 | 89 | 0x59] Y (0x59) 118 | 0xE0, 0x20, 0x40, 0x80, 0xE0, // [ 58 | 90 | 0x5A] Z (0x5A) 119 | 0xE0, 0x80, 0x80, 0x80, 0xE0, // [ 59 | 91 | 0x5B] bracketleft (0x5B) 120 | 0x80, 0x40, 0x20, // [ 60 | 92 | 0x5C] backslash (0x5C) 121 | 0xE0, 0x20, 0x20, 0x20, 0xE0, // [ 61 | 93 | 0x5D] bracketright (0x5D) 122 | 0x40, 0xA0, // [ 62 | 94 | 0x5E] asciicircum (0x5E) 123 | 0xE0, // [ 63 | 95 | 0x5F] underscore (0x5F) 124 | 0x80, 0x40, // [ 64 | 96 | 0x60] grave (0x60) 125 | 0xC0, 0x60, 0xA0, 0xE0, // [ 65 | 97 | 0x61] a (0x61) 126 | 0x80, 0xC0, 0xA0, 0xA0, 0xC0, // [ 66 | 98 | 0x62] b (0x62) 127 | 0x60, 0x80, 0x80, 0x60, // [ 67 | 99 | 0x63] c (0x63) 128 | 0x20, 0x60, 0xA0, 0xA0, 0x60, // [ 68 | 100 | 0x64] d (0x64) 129 | 0x60, 0xA0, 0xC0, 0x60, // [ 69 | 101 | 0x65] e (0x65) 130 | 0x20, 0x40, 0xE0, 0x40, 0x40, // [ 70 | 102 | 0x66] f (0x66) 131 | 0x60, 0xA0, 0xE0, 0x20, 0x40, // [ 71 | 103 | 0x67] g (0x67) 132 | 0x80, 0xC0, 0xA0, 0xA0, 0xA0, // [ 72 | 104 | 0x68] h (0x68) 133 | 0x80, 0x00, 0x80, 0x80, 0x80, // [ 73 | 105 | 0x69] i (0x69) 134 | 0x20, 0x00, 0x20, 0x20, 0xA0, 0x40, // [ 74 | 106 | 0x6A] j (0x6A) 135 | 0x80, 0xA0, 0xC0, 0xC0, 0xA0, // [ 75 | 107 | 0x6B] k (0x6B) 136 | 0xC0, 0x40, 0x40, 0x40, 0xE0, // [ 76 | 108 | 0x6C] l (0x6C) 137 | 0xE0, 0xE0, 0xE0, 0xA0, // [ 77 | 109 | 0x6D] m (0x6D) 138 | 0xC0, 0xA0, 0xA0, 0xA0, // [ 78 | 110 | 0x6E] n (0x6E) 139 | 0x40, 0xA0, 0xA0, 0x40, // [ 79 | 111 | 0x6F] o (0x6F) 140 | 0xC0, 0xA0, 0xA0, 0xC0, 0x80, // [ 80 | 112 | 0x70] p (0x70) 141 | 0x60, 0xA0, 0xA0, 0x60, 0x20, // [ 81 | 113 | 0x71] q (0x71) 142 | 0x60, 0x80, 0x80, 0x80, // [ 82 | 114 | 0x72] r (0x72) 143 | 0x60, 0xC0, 0x60, 0xC0, // [ 83 | 115 | 0x73] s (0x73) 144 | 0x40, 0xE0, 0x40, 0x40, 0x60, // [ 84 | 116 | 0x74] t (0x74) 145 | 0xA0, 0xA0, 0xA0, 0x60, // [ 85 | 117 | 0x75] u (0x75) 146 | 0xA0, 0xA0, 0xE0, 0x40, // [ 86 | 118 | 0x76] v (0x76) 147 | 0xA0, 0xE0, 0xE0, 0xE0, // [ 87 | 119 | 0x77] w (0x77) 148 | 0xA0, 0x40, 0x40, 0xA0, // [ 88 | 120 | 0x78] x (0x78) 149 | 0xA0, 0xA0, 0x60, 0x20, 0x40, // [ 89 | 121 | 0x79] y (0x79) 150 | 0xE0, 0x60, 0xC0, 0xE0, // [ 90 | 122 | 0x7A] z (0x7A) 151 | 0x60, 0x40, 0x80, 0x40, 0x60, // [ 91 | 123 | 0x7B] braceleft (0x7B) 152 | 0x80, 0x80, 0x00, 0x80, 0x80, // [ 92 | 124 | 0x7C] bar (0x7C) 153 | 0xC0, 0x40, 0x20, 0x40, 0xC0, // [ 93 | 125 | 0x7D] braceright (0x7D) 154 | 0x60, 0xC0, // [ 94 | 126 | 0x7E] asciitilde (0x7E) 155 | // Removed 34 codes to save space 156 | 0x80, 0x00, 0x80, 0x80, 0x80, // [ 95 | 127 | 0x7F] exclamdown (0xA1) 157 | 0x40, 0xE0, 0x80, 0xE0, 0x40, // [ 96 | 128 | 0x80] cent (0xA2) 158 | 0x60, 0x40, 0xE0, 0x40, 0xE0, // [ 97 | 129 | 0x81] sterling (0xA3) 159 | 0xA0, 0x40, 0xE0, 0x40, 0xA0, // [ 98 | 130 | 0x82] currency (0xA4) 160 | 0xA0, 0xA0, 0x40, 0xE0, 0x40, // [ 99 | 131 | 0x83] yen (0xA5) 161 | 0x80, 0x80, 0x00, 0x80, 0x80, // [100 | 132 | 0x84] brokenbar (0xA6) 162 | 0x60, 0x40, 0xA0, 0x40, 0xC0, // [101 | 133 | 0x85] section (0xA7) 163 | 0xA0, // [102 | 134 | 0x86] dieresis (0xA8) 164 | 0x60, 0x80, 0x60, // [103 | 135 | 0x87] copyright (0xA9) 165 | 0x60, 0xA0, 0xE0, 0x00, 0xE0, // [104 | 136 | 0x88] ordfeminine (0xAA) 166 | 0x40, 0x80, 0x40, // [105 | 137 | 0x89] guillemotleft (0xAB) 167 | 0xE0, 0x20, // [106 | 138 | 0x8A] logicalnot (0xAC) 168 | 0xC0, // [107 | 139 | 0x8B] softhyphen (0xAD) 169 | 0xC0, 0xC0, 0xA0, // [108 | 140 | 0x8C] registered (0xAE) 170 | 0xE0, // [109 | 141 | 0x8D] macron (0xAF) 171 | 0xC0, 0xC0, 0x00, // [110 | 142 | 0x8E] degree (0xB0) 172 | 0x40, 0xE0, 0x40, 0x00, 0xE0, // [111 | 143 | 0x8F] plusminus (0xB1) 173 | 0xC0, 0x40, 0x60, // [112 | 144 | 0x90] twosuperior (0xB2) 174 | 0xE0, 0x60, 0xE0, // [113 | 145 | 0x91] threesuperior (0xB3) 175 | 0x40, 0x80, // [114 | 146 | 0x92] acute (0xB4) 176 | 0xA0, 0xA0, 0xA0, 0xC0, 0x80, // [115 | 147 | 0x93] mu (0xB5) 177 | 0x60, 0xA0, 0x60, 0x60, 0x60, // [116 | 148 | 0x94] paragraph (0xB6) 178 | 0xE0, 0xE0, 0xE0, // [117 | 149 | 0x95] periodcentered (0xB7) 179 | 0x40, 0x20, 0xC0, // [118 | 150 | 0x96] cedilla (0xB8) 180 | 0x80, 0x80, 0x80, // [119 | 151 | 0x97] onesuperior (0xB9) 181 | 0x40, 0xA0, 0x40, 0x00, 0xE0, // [120 | 152 | 0x98] ordmasculine (0xBA) 182 | 0x80, 0x40, 0x80, // [121 | 153 | 0x99] guillemotright (0xBB) 183 | 0x80, 0x80, 0x00, 0x60, 0x20, // [122 | 154 | 0x9A] onequarter (0xBC) 184 | 0x80, 0x80, 0x00, 0xC0, 0x60, // [123 | 155 | 0x9B] onehalf (0xBD) 185 | 0xC0, 0xC0, 0x00, 0x60, 0x20, // [124 | 156 | 0x9C] threequarters (0xBE) 186 | 0x40, 0x00, 0x40, 0x80, 0xE0, // [125 | 157 | 0x9D] questiondown (0xBF) 187 | 0x40, 0x20, 0x40, 0xE0, 0xA0, // [126 | 158 | 0x9E] Agrave (0xC0) 188 | 0x40, 0x80, 0x40, 0xE0, 0xA0, // [127 | 159 | 0x9F] Aacute (0xC1) 189 | 0xE0, 0x00, 0x40, 0xE0, 0xA0, // [128 | 160 | 0xA0] Acircumflex (0xC2) 190 | 0x60, 0xC0, 0x40, 0xE0, 0xA0, // [129 | 161 | 0xA1] Atilde (0xC3) 191 | 0xA0, 0x40, 0xA0, 0xE0, 0xA0, // [130 | 162 | 0xA2] Adieresis (0xC4) 192 | 0xC0, 0xC0, 0xA0, 0xE0, 0xA0, // [131 | 163 | 0xA3] Aring (0xC5) 193 | 0x60, 0xC0, 0xE0, 0xC0, 0xE0, // [132 | 164 | 0xA4] AE (0xC6) 194 | 0x60, 0x80, 0x80, 0x60, 0x20, 0x40, // [133 | 165 | 0xA5] Ccedilla (0xC7) 195 | 0x40, 0x20, 0xE0, 0xC0, 0xE0, // [134 | 166 | 0xA6] Egrave (0xC8) 196 | 0x40, 0x80, 0xE0, 0xC0, 0xE0, // [135 | 167 | 0xA7] Eacute (0xC9) 197 | 0xE0, 0x00, 0xE0, 0xC0, 0xE0, // [136 | 168 | 0xA8] Ecircumflex (0xCA) 198 | 0xA0, 0x00, 0xE0, 0xC0, 0xE0, // [137 | 169 | 0xA9] Edieresis (0xCB) 199 | 0x40, 0x20, 0xE0, 0x40, 0xE0, // [138 | 170 | 0xAA] Igrave (0xCC) 200 | 0x40, 0x80, 0xE0, 0x40, 0xE0, // [139 | 171 | 0xAB] Iacute (0xCD) 201 | 0xE0, 0x00, 0xE0, 0x40, 0xE0, // [140 | 172 | 0xAC] Icircumflex (0xCE) 202 | 0xA0, 0x00, 0xE0, 0x40, 0xE0, // [141 | 173 | 0xAD] Idieresis (0xCF) 203 | 0xC0, 0xA0, 0xE0, 0xA0, 0xC0, // [142 | 174 | 0xAE] Eth (0xD0) 204 | 0xC0, 0x60, 0xA0, 0xE0, 0xA0, // [143 | 175 | 0xAF] Ntilde (0xD1) 205 | 0x40, 0x20, 0xE0, 0xA0, 0xE0, // [144 | 176 | 0xB0] Ograve (0xD2) 206 | 0x40, 0x80, 0xE0, 0xA0, 0xE0, // [145 | 177 | 0xB1] Oacute (0xD3) 207 | 0xE0, 0x00, 0xE0, 0xA0, 0xE0, // [146 | 178 | 0xB2] Ocircumflex (0xD4) 208 | 0xC0, 0x60, 0xE0, 0xA0, 0xE0, // [147 | 179 | 0xB3] Otilde (0xD5) 209 | 0xA0, 0x00, 0xE0, 0xA0, 0xE0, // [148 | 180 | 0xB4] Odieresis (0xD6) 210 | 0xA0, 0x40, 0xA0, // [149 | 181 | 0xB5] multiply (0xD7) 211 | 0x60, 0xA0, 0xE0, 0xA0, 0xC0, // [150 | 182 | 0xB6] Oslash (0xD8) 212 | 0x80, 0x40, 0xA0, 0xA0, 0xE0, // [151 | 183 | 0xB7] Ugrave (0xD9) 213 | 0x20, 0x40, 0xA0, 0xA0, 0xE0, // [152 | 184 | 0xB8] Uacute (0xDA) 214 | 0xE0, 0x00, 0xA0, 0xA0, 0xE0, // [153 | 185 | 0xB9] Ucircumflex (0xDB) 215 | 0xA0, 0x00, 0xA0, 0xA0, 0xE0, // [154 | 186 | 0xBA] Udieresis (0xDC) 216 | 0x20, 0x40, 0xA0, 0xE0, 0x40, // [155 | 187 | 0xBB] Yacute (0xDD) 217 | 0x80, 0xE0, 0xA0, 0xE0, 0x80, // [156 | 188 | 0xBC] Thorn (0xDE) 218 | 0x60, 0xA0, 0xC0, 0xA0, 0xC0, 0x80, // [157 | 189 | 0xBD] germandbls (0xDF) 219 | 0x40, 0x20, 0x60, 0xA0, 0xE0, // [158 | 190 | 0xBE] agrave (0xE0) 220 | 0x40, 0x80, 0x60, 0xA0, 0xE0, // [159 | 191 | 0xBF] aacute (0xE1) 221 | 0xE0, 0x00, 0x60, 0xA0, 0xE0, // [160 | 192 | 0xC0] acircumflex (0xE2) 222 | 0x60, 0xC0, 0x60, 0xA0, 0xE0, // [161 | 193 | 0xC1] atilde (0xE3) 223 | 0xA0, 0x00, 0x60, 0xA0, 0xE0, // [162 | 194 | 0xC2] adieresis (0xE4) 224 | 0x60, 0x60, 0x60, 0xA0, 0xE0, // [163 | 195 | 0xC3] aring (0xE5) 225 | 0x60, 0xE0, 0xE0, 0xC0, // [164 | 196 | 0xC4] ae (0xE6) 226 | 0x60, 0x80, 0x60, 0x20, 0x40, // [165 | 197 | 0xC5] ccedilla (0xE7) 227 | 0x40, 0x20, 0x60, 0xE0, 0x60, // [166 | 198 | 0xC6] egrave (0xE8) 228 | 0x40, 0x80, 0x60, 0xE0, 0x60, // [167 | 199 | 0xC7] eacute (0xE9) 229 | 0xE0, 0x00, 0x60, 0xE0, 0x60, // [168 | 200 | 0xC8] ecircumflex (0xEA) 230 | 0xA0, 0x00, 0x60, 0xE0, 0x60, // [169 | 201 | 0xC9] edieresis (0xEB) 231 | 0x80, 0x40, 0x80, 0x80, 0x80, // [170 | 202 | 0xCA] igrave (0xEC) 232 | 0x40, 0x80, 0x40, 0x40, 0x40, // [171 | 203 | 0xCB] iacute (0xED) 233 | 0xE0, 0x00, 0x40, 0x40, 0x40, // [172 | 204 | 0xCC] icircumflex (0xEE) 234 | 0xA0, 0x00, 0x40, 0x40, 0x40, // [173 | 205 | 0xCD] idieresis (0xEF) 235 | 0x60, 0xC0, 0x60, 0xA0, 0x60, // [174 | 206 | 0xCE] eth (0xF0) 236 | 0xC0, 0x60, 0xC0, 0xA0, 0xA0, // [175 | 207 | 0xCF] ntilde (0xF1) 237 | 0x40, 0x20, 0x40, 0xA0, 0x40, // [176 | 208 | 0xD0] ograve (0xF2) 238 | 0x40, 0x80, 0x40, 0xA0, 0x40, // [177 | 209 | 0xD1] oacute (0xF3) 239 | 0xE0, 0x00, 0x40, 0xA0, 0x40, // [178 | 210 | 0xD2] ocircumflex (0xF4) 240 | 0xC0, 0x60, 0x40, 0xA0, 0x40, // [179 | 211 | 0xD3] otilde (0xF5) 241 | 0xA0, 0x00, 0x40, 0xA0, 0x40, // [180 | 212 | 0xD4] odieresis (0xF6) 242 | 0x40, 0x00, 0xE0, 0x00, 0x40, // [181 | 213 | 0xD5] divide (0xF7) 243 | 0x60, 0xE0, 0xA0, 0xC0, // [182 | 214 | 0xD6] oslash (0xF8) 244 | 0x80, 0x40, 0xA0, 0xA0, 0x60, // [183 | 215 | 0xD7] ugrave (0xF9) 245 | 0x20, 0x40, 0xA0, 0xA0, 0x60, // [184 | 216 | 0xD8] uacute (0xFA) 246 | 0xE0, 0x00, 0xA0, 0xA0, 0x60, // [185 | 217 | 0xD9] ucircumflex (0xFB) 247 | 0xA0, 0x00, 0xA0, 0xA0, 0x60, // [186 | 218 | 0xDA] udieresis (0xFC) 248 | 0x20, 0x40, 0xA0, 0x60, 0x20, 0x40, // [187 | 219 | 0xDB] yacute (0xFD) 249 | 0x80, 0xC0, 0xA0, 0xC0, 0x80, // [188 | 220 | 0xDC] thorn (0xFE) 250 | 0xA0, 0x00, 0xA0, 0x60, 0x20, 0x40, // [189 | 221 | 0xDD] ydieresis (0xFF) 251 | // Some Icons 252 | // https://www.w3schools.com/charsets/ref_utf_basic_latin.asp 253 | 0x60, 0xC0, 0xE0, 0xC0, 0x60, // [190 | 222 | 0xDE] Euro € (0xC382AC) 254 | 0x20, 0x78, 0xF8, 0x78, 0x20, // [191 | 223 | 0xDF] Arrow left ← (0xE28690) 255 | 0x20, 0x70, 0xF8, 0x70, 0x70, // [192 | 224 | 0xE0] Arrow up ↑ (0xE28691) 256 | 0x20, 0xF0, 0xF8, 0xF0, 0x20, // [193 | 225 | 0xE1] Arrow right → (0xE28692) 257 | 0x70, 0x70, 0xF8, 0x70, 0x20, // [194 | 226 | 0xE2] Arrow down ↓ (0xE28693) 258 | 0x20, 0x20, 0xF8, 0x70, 0x50, // [195 | 227 | 0xE3] Star ★ (0XE29885) 259 | 0xC0, 0xA0, 0x90, 0x90, 0xF0, // [196 | 228 | 0xE4] File 📄 (0xF09F9384) 260 | 0x50, 0xF8, 0xF8, 0x70, 0x20, // [197 | 229 | 0xE5] Heart ♥ (0xE299A5) 261 | 0x70, 0x70, 0xF8, 0x70, 0x20, 0xF8, // [198 | 230 | 0xE6] Download ↧ (0xE286A7) 262 | 0x00, 0x38, 0xCC, 0xFC, 0x48, // [199 | 231 | 0xE7] Car 🚗 (0xF09F9A97) 263 | 0x50, 0x50, 0x20, 0x88, 0x70, // [200 | 232 | 0xE8] Smiley 😀 (0xF09F9880) 264 | 0xE0, 0xFC, 0x84, 0x84, 0xFC // [201 | 233 | 0xE9] Folder 📁 (0xF09F9381) 265 | }; 266 | 267 | // {offset, width, height, advance cursor, x offset, y offset} 268 | const GFXglyph PixelItGlyphs[] PROGMEM = { 269 | // [Index DEC without offset | Index ASCII | Index HEX] Description (ASCII CODE) */ 270 | {0, 8, 1, 2, 0, -5}, // [ 0 | 32 | 0x20] space (0x20) 271 | {1, 8, 5, 2, 0, -5}, // [ 1 | 33 | 0x21] exclam (0x21) 272 | {6, 8, 2, 4, 0, -5}, // [ 2 | 34 | 0x22] quotedbl (0x22) 273 | {8, 8, 5, 4, 0, -5}, // [ 3 | 35 | 0x23] numbersign (0x23) 274 | {13, 8, 5, 4, 0, -5}, // [ 4 | 36 | 0x24] dollar (0x24) 275 | {18, 8, 5, 4, 0, -5}, // [ 5 | 37 | 0x25] percent (0x25) 276 | {23, 8, 5, 4, 0, -5}, // [ 6 | 38 | 0x26] ampersand (0x26) 277 | {28, 8, 2, 2, 0, -5}, // [ 7 | 39 | 0x27] quotesingle (0x27) 278 | {30, 8, 5, 3, 0, -5}, // [ 8 | 40 | 0x28] parenleft (0x28) 279 | {35, 8, 5, 3, 0, -5}, // [ 9 | 41 | 0x29] parenright (0x29) 280 | {40, 8, 3, 4, 0, -5}, // [ 10 | 42 | 0x2A] asterisk (0x2A) 281 | {43, 8, 3, 4, 0, -4}, // [ 11 | 43 | 0x2B] plus (0x2B) 282 | {46, 8, 2, 3, 0, -2}, // [ 12 | 44 | 0x2C] comma (0x2C) 283 | {48, 8, 1, 4, 0, -3}, // [ 13 | 45 | 0x2D] hyphen (0x2D) 284 | {49, 8, 1, 2, 0, -1}, // [ 14 | 46 | 0x2E] period (0x2E) 285 | {50, 8, 5, 4, 0, -5}, // [ 15 | 47 | 0x2F] slash (0x2F) 286 | {55, 8, 5, 4, 0, -5}, // [ 16 | 48 | 0x30] zero (0x30) 287 | {60, 8, 5, 4, 0, -5}, // [ 17 | 49 | 0x31] one (0x31) 288 | {65, 8, 5, 4, 0, -5}, // [ 18 | 50 | 0x32] two (0x32) 289 | {70, 8, 5, 4, 0, -5}, // [ 19 | 51 | 0x33] three (0x33) 290 | {75, 8, 5, 4, 0, -5}, // [ 20 | 52 | 0x34] four (0x34) 291 | {80, 8, 5, 4, 0, -5}, // [ 21 | 53 | 0x35] five (0x35) 292 | {85, 8, 5, 4, 0, -5}, // [ 22 | 54 | 0x36] six (0x36) 293 | {90, 8, 5, 4, 0, -5}, // [ 23 | 55 | 0x37] seven (0x37) 294 | {95, 8, 5, 4, 0, -5}, // [ 24 | 56 | 0x38] eight (0x38) 295 | {100, 8, 5, 4, 0, -5}, // [ 25 | 57 | 0x39] nine (0x39) 296 | {105, 8, 3, 2, 0, -4}, // [ 26 | 58 | 0x3A] colon (0x3A) 297 | {108, 8, 4, 3, 0, -4}, // [ 27 | 59 | 0x3B] semicolon (0x3B) 298 | {112, 8, 5, 4, 0, -5}, // [ 28 | 60 | 0x3C] less (0x3C) 299 | {117, 8, 3, 4, 0, -4}, // [ 29 | 61 | 0x3D] equal (0x3D) 300 | {120, 8, 5, 4, 0, -5}, // [ 30 | 62 | 0x3E] greater (0x3E) 301 | {125, 8, 5, 4, 0, -5}, // [ 31 | 63 | 0x3F] question (0x3F) 302 | {130, 8, 5, 4, 0, -5}, // [ 32 | 64 | 0x40] at (0x40) 303 | {135, 8, 5, 4, 0, -5}, // [ 33 | 65 | 0x41] A (0x41) 304 | {140, 8, 5, 4, 0, -5}, // [ 34 | 66 | 0x42] B (0x42) 305 | {145, 8, 5, 4, 0, -5}, // [ 35 | 67 | 0x43] C (0x43) 306 | {150, 8, 5, 4, 0, -5}, // [ 36 | 68 | 0x44] D (0x44) 307 | {155, 8, 5, 4, 0, -5}, // [ 37 | 69 | 0x45] E (0x45) 308 | {160, 8, 5, 4, 0, -5}, // [ 38 | 70 | 0x46] F (0x46) 309 | {165, 8, 5, 4, 0, -5}, // [ 39 | 71 | 0x47] G (0x47) 310 | {170, 8, 5, 4, 0, -5}, // [ 40 | 72 | 0x48] H (0x48) 311 | {175, 8, 5, 2, 0, -5}, // [ 41 | 73 | 0x49] I (0x49) 312 | {180, 8, 5, 4, 0, -5}, // [ 42 | 74 | 0x4A] J (0x4A) 313 | {185, 8, 5, 4, 0, -5}, // [ 43 | 75 | 0x4B] K (0x4B) 314 | {190, 8, 5, 4, 0, -5}, // [ 44 | 76 | 0x4C] L (0x4C) 315 | {195, 8, 5, 6, 0, -5}, // [ 45 | 77 | 0x4D] M (0x4D) 316 | {200, 8, 5, 5, 0, -5}, // [ 46 | 78 | 0x4E] N (0x4E) 317 | {205, 8, 5, 4, 0, -5}, // [ 47 | 79 | 0x4F] O (0x4F) 318 | {210, 8, 5, 4, 0, -5}, // [ 48 | 80 | 0x50] P (0x50) 319 | {215, 8, 5, 5, 0, -5}, // [ 49 | 81 | 0x51] Q (0x51) 320 | {220, 8, 5, 4, 0, -5}, // [ 50 | 82 | 0x52] R (0x52) 321 | {225, 8, 5, 4, 0, -5}, // [ 51 | 83 | 0x53] S (0x53) 322 | {230, 8, 5, 4, 0, -5}, // [ 52 | 84 | 0x54] T (0x54) 323 | {235, 8, 5, 4, 0, -5}, // [ 53 | 85 | 0x55] U (0x55) 324 | {240, 8, 5, 4, 0, -5}, // [ 54 | 86 | 0x56] V (0x56) 325 | {245, 8, 5, 6, 0, -5}, // [ 55 | 87 | 0x57] W (0x57) 326 | {250, 8, 5, 4, 0, -5}, // [ 56 | 88 | 0x58] X (0x58) 327 | {255, 8, 5, 4, 0, -5}, // [ 57 | 89 | 0x59] Y (0x59) 328 | {260, 8, 5, 4, 0, -5}, // [ 58 | 90 | 0x5A] Z (0x5A) 329 | {265, 8, 5, 4, 0, -5}, // [ 59 | 91 | 0x5B] bracketleft (0x5B) 330 | {270, 8, 3, 4, 0, -4}, // [ 60 | 92 | 0x5C] backslash (0x5C) 331 | {273, 8, 5, 4, 0, -5}, // [ 61 | 93 | 0x5D] bracketright (0x5D) 332 | {278, 8, 2, 4, 0, -5}, // [ 62 | 94 | 0x5E] asciicircum (0x5E) 333 | {280, 8, 1, 4, 0, -1}, // [ 63 | 95 | 0x5F] underscore (0x5F) 334 | {281, 8, 2, 3, 0, -5}, // [ 64 | 96 | 0x60] grave (0x60) 335 | {283, 8, 4, 4, 0, -4}, // [ 65 | 97 | 0x61] a (0x61) 336 | {287, 8, 5, 4, 0, -5}, // [ 66 | 98 | 0x62] b (0x62) 337 | {292, 8, 4, 4, 0, -4}, // [ 67 | 99 | 0x63] c (0x63) 338 | {296, 8, 5, 4, 0, -5}, // [ 68 | 100 | 0x64] d (0x64) 339 | {301, 8, 4, 4, 0, -4}, // [ 69 | 101 | 0x65] e (0x65) 340 | {305, 8, 5, 4, 0, -5}, // [ 70 | 102 | 0x66] f (0x66) 341 | {310, 8, 5, 4, 0, -4}, // [ 71 | 103 | 0x67] g (0x67) 342 | {315, 8, 5, 4, 0, -5}, // [ 72 | 104 | 0x68] h (0x68) 343 | {320, 8, 5, 2, 0, -5}, // [ 73 | 105 | 0x69] i (0x69) 344 | {325, 8, 6, 4, 0, -5}, // [ 74 | 106 | 0x6A] j (0x6A) 345 | {331, 8, 5, 4, 0, -5}, // [ 75 | 107 | 0x6B] k (0x6B) 346 | {336, 8, 5, 4, 0, -5}, // [ 76 | 108 | 0x6C] l (0x6C) 347 | {341, 8, 4, 4, 0, -4}, // [ 77 | 109 | 0x6D] m (0x6D) 348 | {345, 8, 4, 4, 0, -4}, // [ 78 | 110 | 0x6E] n (0x6E) 349 | {349, 8, 4, 4, 0, -4}, // [ 79 | 111 | 0x6F] o (0x6F) 350 | {353, 8, 5, 4, 0, -4}, // [ 80 | 112 | 0x70] p (0x70) 351 | {358, 8, 5, 4, 0, -4}, // [ 81 | 113 | 0x71] q (0x71) 352 | {363, 8, 4, 4, 0, -4}, // [ 82 | 114 | 0x72] r (0x72) 353 | {367, 8, 4, 4, 0, -4}, // [ 83 | 115 | 0x73] s (0x73) 354 | {371, 8, 5, 4, 0, -5}, // [ 84 | 116 | 0x74] t (0x74) 355 | {376, 8, 4, 4, 0, -4}, // [ 85 | 117 | 0x75] u (0x75) 356 | {380, 8, 4, 4, 0, -4}, // [ 86 | 118 | 0x76] v (0x76) 357 | {384, 8, 4, 4, 0, -4}, // [ 87 | 119 | 0x77] w (0x77) 358 | {388, 8, 4, 4, 0, -4}, // [ 88 | 120 | 0x78] x (0x78) 359 | {392, 8, 5, 4, 0, -4}, // [ 89 | 121 | 0x79] y (0x79) 360 | {397, 8, 4, 4, 0, -4}, // [ 90 | 122 | 0x7A] z (0x7A) 361 | {401, 8, 5, 4, 0, -5}, // [ 91 | 123 | 0x7B] braceleft (0x7B) 362 | {406, 8, 5, 2, 0, -5}, // [ 92 | 124 | 0x7C] bar (0x7C) 363 | {411, 8, 5, 4, 0, -5}, // [ 93 | 125 | 0x7D] braceright (0x7D) 364 | {416, 8, 2, 4, 0, -5}, // [ 94 | 126 | 0x7E] asciitilde (0x7E) 365 | // Removed 34 codes to save space 366 | {418, 8, 5, 2, 0, -5}, // [ 95 | 127 | 0x7F] exclamdown (0xA1) 367 | {423, 8, 5, 4, 0, -5}, // [ 96 | 128 | 0x80] cent (0xA2) 368 | {428, 8, 5, 4, 0, -5}, // [ 97 | 129 | 0x81] sterling (0xA3) 369 | {433, 8, 5, 4, 0, -5}, // [ 98 | 130 | 0x82] currency (0xA4) 370 | {438, 8, 5, 4, 0, -5}, // [ 99 | 131 | 0x83] yen (0xA5) 371 | {443, 8, 5, 2, 0, -5}, // [100 | 132 | 0x84] brokenbar (0xA6) 372 | {448, 8, 5, 4, 0, -5}, // [101 | 133 | 0x85] section (0xA7) 373 | {453, 8, 1, 4, 0, -5}, // [102 | 134 | 0x86] dieresis (0xA8) 374 | {454, 8, 3, 4, 0, -5}, // [103 | 135 | 0x87] copyright (0xA9) 375 | {457, 8, 5, 4, 0, -5}, // [104 | 136 | 0x88] ordfeminine (0xAA) 376 | {462, 8, 3, 3, 0, -5}, // [105 | 137 | 0x89] guillemotleft (0xAB) 377 | {465, 8, 2, 4, 0, -4}, // [106 | 138 | 0x8A] logicalnot (0xAC) 378 | {467, 8, 1, 3, 0, -3}, // [107 | 139 | 0x8B] softhyphen (0xAD) 379 | {468, 8, 3, 4, 0, -5}, // [108 | 140 | 0x8C] registered (0xAE) 380 | {471, 8, 1, 4, 0, -5}, // [109 | 141 | 0x8D] macron (0xAF) 381 | {472, 8, 3, 4, 0, -5}, // [110 | 142 | 0x8E] degree (0xB0) 382 | {475, 8, 5, 4, 0, -5}, // [111 | 143 | 0x8F] plusminus (0xB1) 383 | {480, 8, 3, 4, 0, -5}, // [112 | 144 | 0x90] twosuperior (0xB2) 384 | {483, 8, 3, 4, 0, -5}, // [113 | 145 | 0x91] threesuperior (0xB3) 385 | {486, 8, 2, 3, 0, -5}, // [114 | 146 | 0x92] acute (0xB4) 386 | {488, 8, 5, 4, 0, -5}, // [115 | 147 | 0x93] mu (0xB5) 387 | {493, 8, 5, 4, 0, -5}, // [116 | 148 | 0x94] paragraph (0xB6) 388 | {498, 8, 3, 4, 0, -4}, // [117 | 149 | 0x95] periodcentered (0xB7) 389 | {501, 8, 3, 4, 0, -3}, // [118 | 150 | 0x96] cedilla (0xB8) 390 | {504, 8, 3, 2, 0, -5}, // [119 | 151 | 0x97] onesuperior (0xB9) 391 | {507, 8, 5, 4, 0, -5}, // [120 | 152 | 0x98] ordmasculine (0xBA) 392 | {512, 8, 3, 3, 0, -5}, // [121 | 153 | 0x99] guillemotright (0xBB) 393 | {515, 8, 5, 4, 0, -5}, // [122 | 154 | 0x9A] onequarter (0xBC) 394 | {520, 8, 5, 4, 0, -5}, // [123 | 155 | 0x9B] onehalf (0xBD) 395 | {525, 8, 5, 4, 0, -5}, // [124 | 156 | 0x9C] threequarters (0xBE) 396 | {530, 8, 5, 4, 0, -5}, // [125 | 157 | 0x9D] questiondown (0xBF) 397 | {535, 8, 5, 4, 0, -5}, // [126 | 158 | 0x9E] Agrave (0xC0) 398 | {540, 8, 5, 4, 0, -5}, // [127 | 159 | 0x9F] Aacute (0xC1) 399 | {545, 8, 5, 4, 0, -5}, // [128 | 160 | 0xA0] Acircumflex (0xC2) 400 | {550, 8, 5, 4, 0, -5}, // [129 | 161 | 0xA1] Atilde (0xC3) 401 | {555, 8, 5, 4, 0, -5}, // [130 | 162 | 0xA2] Adieresis (0xC4) 402 | {560, 8, 5, 4, 0, -5}, // [131 | 163 | 0xA3] Aring (0xC5) 403 | {565, 8, 5, 4, 0, -5}, // [132 | 164 | 0xA4] AE (0xC6) 404 | {570, 8, 6, 4, 0, -5}, // [133 | 165 | 0xA5] Ccedilla (0xC7) 405 | {576, 8, 5, 4, 0, -5}, // [134 | 166 | 0xA6] Egrave (0xC8) 406 | {581, 8, 5, 4, 0, -5}, // [135 | 167 | 0xA7] Eacute (0xC9) 407 | {586, 8, 5, 4, 0, -5}, // [136 | 168 | 0xA8] Ecircumflex (0xCA) 408 | {591, 8, 5, 4, 0, -5}, // [137 | 169 | 0xA9] Edieresis (0xCB) 409 | {596, 8, 5, 4, 0, -5}, // [138 | 170 | 0xAA] Igrave (0xCC) 410 | {601, 8, 5, 4, 0, -5}, // [139 | 171 | 0xAB] Iacute (0xCD) 411 | {606, 8, 5, 4, 0, -5}, // [140 | 172 | 0xAC] Icircumflex (0xCE) 412 | {611, 8, 5, 4, 0, -5}, // [141 | 173 | 0xAD] Idieresis (0xCF) 413 | {616, 8, 5, 4, 0, -5}, // [142 | 174 | 0xAE] Eth (0xD0) 414 | {621, 8, 5, 4, 0, -5}, // [143 | 175 | 0xAF] Ntilde (0xD1) 415 | {626, 8, 5, 4, 0, -5}, // [144 | 176 | 0xB0] Ograve (0xD2) 416 | {631, 8, 5, 4, 0, -5}, // [145 | 177 | 0xB1] Oacute (0xD3) 417 | {636, 8, 5, 4, 0, -5}, // [146 | 178 | 0xB2] Ocircumflex (0xD4) 418 | {641, 8, 5, 4, 0, -5}, // [147 | 179 | 0xB3] Otilde (0xD5) 419 | {646, 8, 5, 4, 0, -5}, // [148 | 180 | 0xB4] Odieresis (0xD6) 420 | {651, 8, 3, 4, 0, -4}, // [149 | 181 | 0xB5] multiply (0xD7) 421 | {654, 8, 5, 4, 0, -5}, // [150 | 182 | 0xB6] Oslash (0xD8) 422 | {659, 8, 5, 4, 0, -5}, // [151 | 183 | 0xB7] Ugrave (0xD9) 423 | {664, 8, 5, 4, 0, -5}, // [152 | 184 | 0xB8] Uacute (0xDA) 424 | {669, 8, 5, 4, 0, -5}, // [153 | 185 | 0xB9] Ucircumflex (0xDB) 425 | {674, 8, 5, 4, 0, -5}, // [154 | 186 | 0xBA] Udieresis (0xDC) 426 | {679, 8, 5, 4, 0, -5}, // [155 | 187 | 0xBB] Yacute (0xDD) 427 | {684, 8, 5, 4, 0, -5}, // [156 | 188 | 0xBC] Thorn (0xDE) 428 | {689, 8, 6, 4, 0, -5}, // [157 | 189 | 0xBD] germandbls (0xDF) 429 | {695, 8, 5, 4, 0, -5}, // [158 | 190 | 0xBE] agrave (0xE0) 430 | {700, 8, 5, 4, 0, -5}, // [159 | 191 | 0xBF] aacute (0xE1) 431 | {705, 8, 5, 4, 0, -5}, // [160 | 192 | 0xC0] acircumflex (0xE2) 432 | {710, 8, 5, 4, 0, -5}, // [161 | 193 | 0xC1] atilde (0xE3) 433 | {715, 8, 5, 4, 0, -5}, // [162 | 194 | 0xC2] adieresis (0xE4) 434 | {720, 8, 5, 4, 0, -5}, // [163 | 195 | 0xC3] aring (0xE5) 435 | {725, 8, 4, 4, 0, -4}, // [164 | 196 | 0xC4] ae (0xE6) 436 | {729, 8, 5, 4, 0, -4}, // [165 | 197 | 0xC5] ccedilla (0xE7) 437 | {734, 8, 5, 4, 0, -5}, // [166 | 198 | 0xC6] egrave (0xE8) 438 | {739, 8, 5, 4, 0, -5}, // [167 | 199 | 0xC7] eacute (0xE9) 439 | {744, 8, 5, 4, 0, -5}, // [168 | 200 | 0xC8] ecircumflex (0xEA) 440 | {749, 8, 5, 4, 0, -5}, // [169 | 201 | 0xC9] edieresis (0xEB) 441 | {754, 8, 5, 3, 0, -5}, // [170 | 202 | 0xCA] igrave (0xEC) 442 | {759, 8, 5, 3, 0, -5}, // [171 | 203 | 0xCB] iacute (0xED) 443 | {764, 8, 5, 4, 0, -5}, // [172 | 204 | 0xCC] icircumflex (0xEE) 444 | {769, 8, 5, 4, 0, -5}, // [173 | 205 | 0xCD] idieresis (0xEF) 445 | {774, 8, 5, 4, 0, -5}, // [174 | 206 | 0xCE] eth (0xF0) 446 | {779, 8, 5, 4, 0, -5}, // [175 | 207 | 0xCF] ntilde (0xF1) 447 | {784, 8, 5, 4, 0, -5}, // [176 | 208 | 0xD0] ograve (0xF2) 448 | {789, 8, 5, 4, 0, -5}, // [177 | 209 | 0xD1] oacute (0xF3) 449 | {794, 8, 5, 4, 0, -5}, // [178 | 210 | 0xD2] ocircumflex (0xF4) 450 | {799, 8, 5, 4, 0, -5}, // [179 | 211 | 0xD3] otilde (0xF5) 451 | {804, 8, 5, 4, 0, -5}, // [180 | 212 | 0xD4] odieresis (0xF6) 452 | {809, 8, 5, 4, 0, -5}, // [181 | 213 | 0xD5] divide (0xF7) 453 | {814, 8, 4, 4, 0, -4}, // [182 | 214 | 0xD6] oslash (0xF8) 454 | {818, 8, 5, 4, 0, -5}, // [183 | 215 | 0xD7] ugrave (0xF9) 455 | {823, 8, 5, 4, 0, -5}, // [184 | 216 | 0xD8] uacute (0xFA) 456 | {828, 8, 5, 4, 0, -5}, // [185 | 217 | 0xD9] ucircumflex (0xFB) 457 | {833, 8, 5, 4, 0, -5}, // [186 | 218 | 0xDA] udieresis (0xFC) 458 | {838, 8, 6, 4, 0, -5}, // [187 | 219 | 0xDB] yacute (0xFD) 459 | {844, 8, 5, 4, 0, -4}, // [188 | 220 | 0xDC] thorn (0xFE) 460 | {849, 8, 6, 4, 0, -5}, // [189 | 221 | 0xDD] ydieresis (0xFF) 461 | // Some Icons 462 | // https://www.w3schools.com/charsets/ref_utf_basic_latin.asp 463 | {855, 8, 5, 4, 0, -5}, // [190 | 222 | 0xDE] Euro € (0xC382AC) 464 | {860, 8, 5, 6, 0, -5}, // [191 | 223 | 0xDF] Arrow left ← (0xE28690) 465 | {865, 8, 5, 6, 0, -5}, // [192 | 224 | 0xE0] Arrow up ↑ (0xE28691) 466 | {870, 8, 5, 6, 0, -5}, // [193 | 225 | 0xE1] Arrow right → (0xE28692) 467 | {875, 8, 5, 6, 0, -5}, // [194 | 226 | 0xE2] Arrow down ↓ (0xE28693) 468 | {880, 8, 5, 6, 0, -5}, // [195 | 227 | 0xE3] Star ★ (0XE29885) 469 | {885, 8, 5, 5, 0, -5}, // [196 | 228 | 0xE4] File 📄 (0xF09F9384) 470 | {890, 8, 5, 6, 0, -5}, // [197 | 229 | 0xE5] Heart ♥ (0xE299A5) 471 | {895, 8, 6, 6, 0, -5}, // [198 | 230 | 0xE6] Download ↧ (0xE286A7) 472 | {901, 8, 5, 7, 0, -5}, // [199 | 231 | 0xE7] Car 🚗 (0xF09F9A97) 473 | {906, 8, 5, 6, 0, -5}, // [200 | 232 | 0xE8] Smiley 😀 (0xF09F9880) 474 | {911, 8, 5, 7, 0, -5} // [201 | 233 | 0xE9] Folder 📁 (0xF09F9381) 475 | }; 476 | 477 | const GFXfont PixelItFont PROGMEM = {(uint8_t *)PixelItBitmaps, (GFXglyph *)PixelItGlyphs, 0x20, 0xE9, 6}; 478 | 479 | const uint8_t LargePixels_Bitmaps[] PROGMEM = { 480 | // ASCII code and symbol 481 | 0x00, // 0x20 ' ' 482 | 0x80, // 0x21 '!' 483 | 0x74, 0x63, 0x18, 0xC6, 0x2E, // 0x30 '0' 484 | 0x59, 0x24, 0x97, // 0x31 '1' 485 | 0x74, 0x42, 0x22, 0x22, 0x1F, // 0x32 '2' 486 | 0x74, 0x42, 0x60, 0x86, 0x2E, // 0x33 '3' 487 | 0x19, 0x53, 0x1F, 0x84, 0x21, // 0x34 '4' 488 | 0xFC, 0x21, 0xE0, 0x86, 0x2E, // 0x35 '5' 489 | 0x74, 0x61, 0xE8, 0xC6, 0x2E, // 0x36 '6' 490 | 0xF8, 0x42, 0x22, 0x21, 0x08, // 0x37 '7' 491 | 0x74, 0x62, 0xE8, 0xC6, 0x2E, // 0x38 '8' 492 | 0x74, 0x63, 0x17, 0x86, 0x2E, // 0x39 '9' 493 | 0x90 // 0x3A ':' 494 | }; 495 | 496 | // {offset, width, height, advance cursor, x offset, y offset} 497 | const GFXglyph LargePixels_Glyphs[] PROGMEM = { 498 | // ASCII code and symbol 499 | {0, 1, 1, 2, 0, -5}, // 0x20 ' ' 500 | {0, 0, 0, 0, 0, 0}, // 0x21 '!' 501 | {0, 0, 0, 0, 0, 0}, // 0x22 '"' 502 | {0, 0, 0, 0, 0, 0}, // 0x23 '#' 503 | {0, 0, 0, 0, 0, 0}, // 0x24 '$' 504 | {0, 0, 0, 0, 0, 0}, // 0x25 '%' 505 | {0, 0, 0, 0, 0, 0}, // 0x26 '&' 506 | {0, 0, 0, 0, 0, 0}, // 0x27 ''' 507 | {0, 0, 0, 0, 0, 0}, // 0x28 '(' 508 | {0, 0, 0, 0, 0, 0}, // 0x29 ')' 509 | {0, 0, 0, 0, 0, 0}, // 0x2A '*' 510 | {0, 0, 0, 0, 0, 0}, // 0x2B '+' 511 | {0, 0, 0, 0, 0, 0}, // 0x2C ',' 512 | {0, 0, 0, 0, 0, 0}, // 0x2D '-' 513 | {1, 1, 1, 2, 0, 0}, // 0x2E '.' 514 | {0, 0, 0, 0, 0, 0}, // 0x2F '/' 515 | {2, 5, 8, 6, 0, -7}, // 0x30 '0' 516 | {7, 3, 8, 4, 0, -7}, // 0x31 '1' 517 | {10, 5, 8, 6, 0, -7}, // 0x32 '2' 518 | {15, 5, 8, 6, 0, -7}, // 0x33 '3' 519 | {20, 5, 8, 6, 0, -7}, // 0x34 '4' 520 | {25, 5, 8, 6, 0, -7}, // 0x35 '5' 521 | {30, 5, 8, 6, 0, -7}, // 0x36 '6' 522 | {35, 5, 8, 6, 0, -7}, // 0x37 '7' 523 | {40, 5, 8, 6, 0, -7}, // 0x38 '8' 524 | {45, 5, 8, 6, 0, -7}, // 0x39 '9' 525 | {50, 1, 4, 2, 0, -5} // 0x3A ':' 526 | }; 527 | 528 | const GFXfont LargePixels PROGMEM = {(uint8_t *)LargePixels_Bitmaps, (GFXglyph *)LargePixels_Glyphs, 0x20, 0x3A, 8}; 529 | 530 | const uint8_t FatPixels_Bitmaps[] PROGMEM = { 531 | // ASCII code and symbol 532 | 0x00, // 0x20 ' ' 533 | 0x80, // 0x21 '!' 534 | 0x77, 0xF7, 0xBD, 0xEF, 0xEE, // 0x30 '0' 535 | 0x7F, 0xB6, 0xDB, // 0x31 '1' 536 | 0x77, 0xF6, 0x77, 0x73, 0xFF, // 0x32 '2' 537 | 0x77, 0xF6, 0x73, 0xEF, 0xEE, // 0x33 '3' 538 | 0x19, 0xDF, 0xBF, 0xFC, 0x63, // 0x34 '4' 539 | 0xFF, 0xF1, 0xEF, 0x8F, 0xEE, // 0x35 '5' 540 | 0x77, 0xF1, 0xEF, 0xEF, 0xEE, // 0x36 '6' 541 | 0xFF, 0xC6, 0x31, 0x8C, 0x63, // 0x37 '7' 542 | 0x77, 0xF6, 0xEF, 0xEF, 0xEE, // 0x38 '8' 543 | 0x77, 0xF7, 0xF7, 0x8F, 0xEE, // 0x39 '9' 544 | 0x90 // 0x3A ':' 545 | }; 546 | 547 | // {offset, width, height, advance cursor, x offset, y offset} 548 | const GFXglyph FatPixels_Glyphs[] PROGMEM = { 549 | // ASCII code and symbol 550 | {0, 1, 1, 2, 0, -5}, // 0x20 ' ' 551 | {0, 0, 0, 0, 0, 0}, // 0x21 '!' 552 | {0, 0, 0, 0, 0, 0}, // 0x22 '"' 553 | {0, 0, 0, 0, 0, 0}, // 0x23 '#' 554 | {0, 0, 0, 0, 0, 0}, // 0x24 '$' 555 | {0, 0, 0, 0, 0, 0}, // 0x25 '%' 556 | {0, 0, 0, 0, 0, 0}, // 0x26 '&' 557 | {0, 0, 0, 0, 0, 0}, // 0x27 ''' 558 | {0, 0, 0, 0, 0, 0}, // 0x28 '(' 559 | {0, 0, 0, 0, 0, 0}, // 0x29 ')' 560 | {0, 0, 0, 0, 0, 0}, // 0x2A '*' 561 | {0, 0, 0, 0, 0, 0}, // 0x2B '+' 562 | {0, 0, 0, 0, 0, 0}, // 0x2C ',' 563 | {0, 0, 0, 0, 0, 0}, // 0x2D '-' 564 | {1, 1, 1, 2, 0, 0}, // 0x2E '.' 565 | {0, 0, 0, 0, 0, 0}, // 0x2F '/' 566 | {2, 5, 8, 6, 0, -7}, // 0x30 '0' 567 | {7, 3, 8, 4, 0, -7}, // 0x31 '1' 568 | {10, 5, 8, 6, 0, -7}, // 0x32 '2' 569 | {15, 5, 8, 6, 0, -7}, // 0x33 '3' 570 | {20, 5, 8, 6, 0, -7}, // 0x34 '4' 571 | {25, 5, 8, 6, 0, -7}, // 0x35 '5' 572 | {30, 5, 8, 6, 0, -7}, // 0x36 '6' 573 | {35, 5, 8, 6, 0, -7}, // 0x37 '7' 574 | {40, 5, 8, 6, 0, -7}, // 0x38 '8' 575 | {45, 5, 8, 6, 0, -7}, // 0x39 '9' 576 | {50, 1, 4, 2, 0, -5} // 0x3A ':' 577 | }; 578 | 579 | const GFXfont FatPixels PROGMEM = {(uint8_t *)FatPixels_Bitmaps, (GFXglyph *)FatPixels_Glyphs, 0x20, 0x3A, 8}; 580 | -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /include/TempSensor.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPSENSOR_H 2 | #define TEMPSENSOR_H 3 | 4 | enum TempSensor 5 | { 6 | TempSensor_None, 7 | TempSensor_BME280, 8 | TempSensor_DHT, 9 | TempSensor_BME680, 10 | TempSensor_BMP280, 11 | TempSensor_SHT31, 12 | }; 13 | 14 | #endif // TEMPSENSOR_H -------------------------------------------------------------------------------- /include/TemperatureUnit.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPERATUREUNIT_H 2 | #define TEMPERATUREUNIT_H 3 | 4 | enum TemperatureUnit 5 | { 6 | TemperatureUnit_Celsius, 7 | TemperatureUnit_Fahrenheit 8 | }; 9 | 10 | #endif // TEMPERATUREUNIT_H -------------------------------------------------------------------------------- /include/Tools.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /// 4 | /// Adds a leading 0 to a number if it is smaller than 10 5 | /// 6 | String IntFormat(int inputInt) 7 | { 8 | if (inputInt < 10) 9 | { 10 | return "0" + String(inputInt); 11 | } 12 | 13 | return String(inputInt); 14 | } 15 | 16 | boolean IsSummertime(int year, byte month, byte day, byte hour, byte clockTimeZone) 17 | { 18 | if (month < 3 || month > 10) 19 | { 20 | return false; // keine Sommerzeit in Jan, Feb, Nov, Dez 21 | } 22 | if (month > 3 && month < 10) 23 | { 24 | return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep 25 | } 26 | // if (month == 3 && (hour + 24 * day) >= (1 + clockTimeZone + 24 * (31 - (5 * year / 4 + 4) % 7)) || month == 10 && (hour + 24 * day) < (1 + clockTimeZone + 24 * (31 - (5 * year / 4 + 1) % 7))) 27 | if ((month == 3 && (hour + 24 * day) >= (1 + clockTimeZone + 24 * (31 - (5 * year / 4 + 4) % 7))) || (month == 10 && (hour + 24 * day) < (1 + clockTimeZone + 24 * (31 - (5 * year / 4 + 1) % 7)))) 28 | { 29 | return true; 30 | } 31 | else 32 | { 33 | return false; 34 | } 35 | } 36 | 37 | /// 38 | /// Returns 1 hour in daylight saving time and outside 0 39 | /// 40 | int DSToffset(time_t date, float clockTimeZone) 41 | { 42 | return IsSummertime(year(date), month(date), day(date), hour(date), clockTimeZone) ? 1 : 0; 43 | } 44 | 45 | /// 46 | /// Checks if it is a valid IP address 47 | /// 48 | boolean isIP(String str) 49 | { 50 | for (char i = 0; i < str.length(); i++) 51 | { 52 | if (!(isDigit(str.charAt(i)) || str.charAt(i) == '.')) 53 | { 54 | return false; 55 | } 56 | } 57 | return true; 58 | } 59 | 60 | /// 61 | /// Convert UTF8 byte to ASCII 62 | /// 63 | byte Utf8ToAscii(byte ascii) 64 | { 65 | static unsigned long fullSeq; // Full UTF-8 Byte Sequences 66 | static int firstBytePos; // Pos of the 1st Byte 67 | unsigned long tmpSeq; // Buffer to shift UTF-8 Byte Sequences while extracting 68 | int maxByteSeq = 0; // Holds legal UTF-8 Byte Sequences lenght 69 | byte result = 0; // Function result 70 | byte bytes[4] = {0, 0, 0, 0}; // Holds 1-4 Bytes from Full UTF-8 Byte Sequences 71 | 72 | // Shift UTF-8 Byte Sequences to right 73 | // Add new ASCII byte at the end 74 | fullSeq = fullSeq << 8; 75 | fullSeq = fullSeq | ascii; 76 | 77 | // Extract 1-4 Byte from UTF-8 Byte Sequences 78 | // and store them at the right postion 79 | // 0 = 1st Byte 80 | // 1 = 2nd Byte 81 | // 2 = 3rd Byte 82 | // 3 = 4th Byte 83 | tmpSeq = fullSeq; 84 | for (int i = firstBytePos; i >= 0; i--) 85 | { 86 | bytes[i] = tmpSeq & 0xff; 87 | tmpSeq = tmpSeq >> 8; 88 | } 89 | 90 | // Set where we find the 1st Byte 91 | firstBytePos += 1; 92 | 93 | switch (fullSeq) 94 | { 95 | case 0 ... 127: // Basic Latin (Decimal 0-127) 96 | result = ascii; 97 | break; 98 | case 0xC2A1 ... 0xC2BF: // Latin1 Supplement (Decimal 160-191) 99 | result = bytes[1] - 34; 100 | break; 101 | case 0xC380 ... 0xC3BF: 102 | result = (bytes[1] | 0xC0) - 34; 103 | break; 104 | case 0xE282AC: // Euro € 105 | result = 0xDE; 106 | break; 107 | case 0xE28690: // Arrow left ← 108 | result = 0xDF; 109 | break; 110 | case 0xE28691: // Arrow up ↑ 111 | result = 0xE0; 112 | break; 113 | case 0xE28692: // Arrow right → 114 | result = 0xE1; 115 | break; 116 | case 0xE28693: // Arrow down ↓ 117 | result = 0xE2; 118 | break; 119 | case 0XE29885: // Star ★ 120 | result = 0xE3; 121 | break; 122 | case 0xF09F9384: // File 📄 123 | result = 0xE4; 124 | break; 125 | case 0xE299A5: // Heart ♥ 126 | result = 0xE5; 127 | break; 128 | case 0xE286A7: // Download ↧ 129 | result = 0xE6; 130 | break; 131 | case 0xF09F9A97: // Car 🚗 132 | result = 0xE7; 133 | break; 134 | case 0xF09F9880: // Smiley 😀 135 | result = 0xE8; 136 | break; 137 | case 0xF09F9381: // Folder 📁 138 | result = 0xE9; 139 | break; 140 | } 141 | 142 | // Legal UTF-8 Byte Sequences 143 | // https://www.unicode.org/versions/corrigendum1.html 144 | // Check 1st Byte 145 | switch (bytes[0]) 146 | { 147 | case 0x00 ... 0x7F: 148 | maxByteSeq = 1; 149 | break; 150 | case 0xC2 ... 0xDF: 151 | maxByteSeq = 2; 152 | break; 153 | case 0xE0 ... 0xEF: 154 | maxByteSeq = 3; 155 | break; 156 | case 0xF0 ... 0xF4: 157 | maxByteSeq = 4; 158 | break; 159 | default: 160 | maxByteSeq = 0; 161 | break; 162 | } 163 | 164 | // Reset static cache and shift if we have an 165 | // result or we exceed Legal UTF-8 Byte Sequences 166 | if (result != 0 || firstBytePos >= maxByteSeq) 167 | { 168 | firstBytePos = 0; 169 | fullSeq = 0; 170 | } 171 | 172 | return result; 173 | } 174 | 175 | /// 176 | /// Convert UTF8 Chars to ASCII 177 | /// 178 | String Utf8ToAscii(String _str) 179 | { 180 | String result = ""; 181 | char thisChar; 182 | 183 | for (unsigned int i = 0; i < _str.length(); i++) 184 | { 185 | thisChar = Utf8ToAscii(_str.charAt(i)); 186 | 187 | if (thisChar != 0) 188 | { 189 | result += thisChar; 190 | } 191 | } 192 | return result; 193 | } 194 | 195 | String uint64ToString(uint64_t input) 196 | { 197 | String result = ""; 198 | uint8_t base = 10; 199 | 200 | do 201 | { 202 | char c = input % base; 203 | input /= base; 204 | 205 | if (c < 10) 206 | c += '0'; 207 | else 208 | c += 'A' - 10; 209 | result = c + result; 210 | } while (input); 211 | return result; 212 | } 213 | 214 | /// 215 | /// Returns the chip id 216 | /// 217 | String GetChipID() 218 | { 219 | #if defined(ESP8266) 220 | return String(ESP.getChipId()); 221 | #elif defined(ESP32) 222 | return uint64ToString(ESP.getEfuseMac()); 223 | #endif 224 | } 225 | 226 | /// 227 | /// Convert RSSI to percentage quality 228 | /// 229 | int GetRSSIasQuality(int rssi) 230 | { 231 | int quality = 0; 232 | 233 | if (rssi <= -100) 234 | { 235 | quality = 0; 236 | } 237 | else if (rssi >= -50) 238 | { 239 | quality = 100; 240 | } 241 | else 242 | { 243 | quality = 2 * (rssi + 100); 244 | } 245 | return quality; 246 | } 247 | 248 | /// 249 | /// Convert celsius to fahrenheit 250 | /// 251 | float CelsiusToFahrenheit(float celsius) 252 | { 253 | return (celsius * 9 / 5) + 32; 254 | } 255 | 256 | // RGBtoHEX 257 | String RGBtoHEX(int r, int g, int b) 258 | { 259 | String rs = String(r, HEX); 260 | String gs = String(g, HEX); 261 | String bs = String(b, HEX); 262 | 263 | if (rs.length() == 1) 264 | rs = "0" + rs; 265 | if (gs.length() == 1) 266 | gs = "0" + gs; 267 | if (bs.length() == 1) 268 | bs = "0" + bs; 269 | 270 | return rs + gs + bs; 271 | } 272 | 273 | // HEXtoRGB 274 | void HEXtoRGB(String hex, uint8_t &r, uint8_t &g, uint8_t &b) 275 | { 276 | // Remove # if it exists 277 | hex.replace("#", ""); 278 | // trim to 6 characters 279 | hex = hex.substring(0, 6); 280 | // check of the string is a valid hex color 281 | // regex: ^#?([a-f0-9]{6}|[a-f0-9]{3})$ 282 | if (hex.length() == 6) 283 | { 284 | r = strtol(hex.substring(0, 2).c_str(), nullptr, 16); 285 | g = strtol(hex.substring(2, 4).c_str(), nullptr, 16); 286 | b = strtol(hex.substring(4, 6).c_str(), nullptr, 16); 287 | } 288 | else 289 | { 290 | r = 0; 291 | g = 0; 292 | b = 0; 293 | } 294 | } -------------------------------------------------------------------------------- /include/UpdateScreen.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void BuildUpdateScreenJSON(JsonObject &root) 4 | { 5 | 6 | JsonObject &text = root.createNestedObject("text"); 7 | text["textString"] = "New FW available"; 8 | text["hexColor"] = "#FFFFFF"; 9 | text["scrollText"] = true; 10 | 11 | JsonObject &text_position = text.createNestedObject("position"); 12 | text_position["x"] = 7; 13 | text_position["y"] = 1; 14 | 15 | JsonObject &bitmapAnimation = root.createNestedObject("bitmapAnimation"); 16 | bitmapAnimation["animationDelay"] = 400; 17 | bitmapAnimation["limitLoops"] = 0; 18 | 19 | JsonArray &bitmapAnimation_data = bitmapAnimation.createNestedArray("data"); 20 | 21 | JsonArray &bitmapAnimation_data_0 = bitmapAnimation_data.createNestedArray(); 22 | bitmapAnimation_data_0.add(0); 23 | bitmapAnimation_data_0.add(0); 24 | bitmapAnimation_data_0.add(0); 25 | bitmapAnimation_data_0.add(0); 26 | bitmapAnimation_data_0.add(0); 27 | bitmapAnimation_data_0.add(0); 28 | bitmapAnimation_data_0.add(0); 29 | bitmapAnimation_data_0.add(0); 30 | bitmapAnimation_data_0.add(0); 31 | bitmapAnimation_data_0.add(0); 32 | bitmapAnimation_data_0.add(0); 33 | bitmapAnimation_data_0.add(0); 34 | bitmapAnimation_data_0.add(0); 35 | bitmapAnimation_data_0.add(0); 36 | bitmapAnimation_data_0.add(0); 37 | bitmapAnimation_data_0.add(0); 38 | bitmapAnimation_data_0.add(0); 39 | bitmapAnimation_data_0.add(0); 40 | bitmapAnimation_data_0.add(0); 41 | bitmapAnimation_data_0.add(0); 42 | bitmapAnimation_data_0.add(0); 43 | bitmapAnimation_data_0.add(0); 44 | bitmapAnimation_data_0.add(0); 45 | bitmapAnimation_data_0.add(0); 46 | bitmapAnimation_data_0.add(0); 47 | bitmapAnimation_data_0.add(0); 48 | bitmapAnimation_data_0.add(0); 49 | bitmapAnimation_data_0.add(0); 50 | bitmapAnimation_data_0.add(0); 51 | bitmapAnimation_data_0.add(0); 52 | bitmapAnimation_data_0.add(0); 53 | bitmapAnimation_data_0.add(0); 54 | bitmapAnimation_data_0.add(0); 55 | bitmapAnimation_data_0.add(0); 56 | bitmapAnimation_data_0.add(0); 57 | bitmapAnimation_data_0.add(0); 58 | bitmapAnimation_data_0.add(0); 59 | bitmapAnimation_data_0.add(0); 60 | bitmapAnimation_data_0.add(0); 61 | bitmapAnimation_data_0.add(0); 62 | bitmapAnimation_data_0.add(0); 63 | bitmapAnimation_data_0.add(0); 64 | bitmapAnimation_data_0.add(0); 65 | bitmapAnimation_data_0.add(0); 66 | bitmapAnimation_data_0.add(0); 67 | bitmapAnimation_data_0.add(0); 68 | bitmapAnimation_data_0.add(0); 69 | bitmapAnimation_data_0.add(0); 70 | bitmapAnimation_data_0.add(0); 71 | bitmapAnimation_data_0.add(0); 72 | bitmapAnimation_data_0.add(0); 73 | bitmapAnimation_data_0.add(0); 74 | bitmapAnimation_data_0.add(0); 75 | bitmapAnimation_data_0.add(0); 76 | bitmapAnimation_data_0.add(0); 77 | bitmapAnimation_data_0.add(0); 78 | bitmapAnimation_data_0.add(0); 79 | bitmapAnimation_data_0.add(0); 80 | bitmapAnimation_data_0.add(0); 81 | bitmapAnimation_data_0.add(63488); 82 | bitmapAnimation_data_0.add(63488); 83 | bitmapAnimation_data_0.add(0); 84 | bitmapAnimation_data_0.add(0); 85 | bitmapAnimation_data_0.add(0); 86 | 87 | JsonArray &bitmapAnimation_data_1 = bitmapAnimation_data.createNestedArray(); 88 | bitmapAnimation_data_1.add(0); 89 | bitmapAnimation_data_1.add(0); 90 | bitmapAnimation_data_1.add(0); 91 | bitmapAnimation_data_1.add(0); 92 | bitmapAnimation_data_1.add(0); 93 | bitmapAnimation_data_1.add(0); 94 | bitmapAnimation_data_1.add(0); 95 | bitmapAnimation_data_1.add(0); 96 | bitmapAnimation_data_1.add(0); 97 | bitmapAnimation_data_1.add(0); 98 | bitmapAnimation_data_1.add(0); 99 | bitmapAnimation_data_1.add(0); 100 | bitmapAnimation_data_1.add(0); 101 | bitmapAnimation_data_1.add(0); 102 | bitmapAnimation_data_1.add(0); 103 | bitmapAnimation_data_1.add(0); 104 | bitmapAnimation_data_1.add(0); 105 | bitmapAnimation_data_1.add(0); 106 | bitmapAnimation_data_1.add(0); 107 | bitmapAnimation_data_1.add(0); 108 | bitmapAnimation_data_1.add(0); 109 | bitmapAnimation_data_1.add(0); 110 | bitmapAnimation_data_1.add(0); 111 | bitmapAnimation_data_1.add(0); 112 | bitmapAnimation_data_1.add(0); 113 | bitmapAnimation_data_1.add(0); 114 | bitmapAnimation_data_1.add(0); 115 | bitmapAnimation_data_1.add(0); 116 | bitmapAnimation_data_1.add(0); 117 | bitmapAnimation_data_1.add(0); 118 | bitmapAnimation_data_1.add(0); 119 | bitmapAnimation_data_1.add(0); 120 | bitmapAnimation_data_1.add(0); 121 | bitmapAnimation_data_1.add(0); 122 | bitmapAnimation_data_1.add(0); 123 | bitmapAnimation_data_1.add(0); 124 | bitmapAnimation_data_1.add(0); 125 | bitmapAnimation_data_1.add(0); 126 | bitmapAnimation_data_1.add(0); 127 | bitmapAnimation_data_1.add(0); 128 | bitmapAnimation_data_1.add(0); 129 | bitmapAnimation_data_1.add(0); 130 | bitmapAnimation_data_1.add(0); 131 | bitmapAnimation_data_1.add(65472); 132 | bitmapAnimation_data_1.add(65472); 133 | bitmapAnimation_data_1.add(0); 134 | bitmapAnimation_data_1.add(0); 135 | bitmapAnimation_data_1.add(0); 136 | bitmapAnimation_data_1.add(0); 137 | bitmapAnimation_data_1.add(0); 138 | bitmapAnimation_data_1.add(64896); 139 | bitmapAnimation_data_1.add(64896); 140 | bitmapAnimation_data_1.add(64896); 141 | bitmapAnimation_data_1.add(64896); 142 | bitmapAnimation_data_1.add(0); 143 | bitmapAnimation_data_1.add(0); 144 | bitmapAnimation_data_1.add(0); 145 | bitmapAnimation_data_1.add(63488); 146 | bitmapAnimation_data_1.add(63488); 147 | bitmapAnimation_data_1.add(63488); 148 | bitmapAnimation_data_1.add(63488); 149 | bitmapAnimation_data_1.add(63488); 150 | bitmapAnimation_data_1.add(63488); 151 | bitmapAnimation_data_1.add(0); 152 | 153 | JsonArray &bitmapAnimation_data_2 = bitmapAnimation_data.createNestedArray(); 154 | bitmapAnimation_data_2.add(0); 155 | bitmapAnimation_data_2.add(0); 156 | bitmapAnimation_data_2.add(0); 157 | bitmapAnimation_data_2.add(0); 158 | bitmapAnimation_data_2.add(0); 159 | bitmapAnimation_data_2.add(0); 160 | bitmapAnimation_data_2.add(0); 161 | bitmapAnimation_data_2.add(0); 162 | bitmapAnimation_data_2.add(0); 163 | bitmapAnimation_data_2.add(0); 164 | bitmapAnimation_data_2.add(0); 165 | bitmapAnimation_data_2.add(0); 166 | bitmapAnimation_data_2.add(0); 167 | bitmapAnimation_data_2.add(0); 168 | bitmapAnimation_data_2.add(0); 169 | bitmapAnimation_data_2.add(0); 170 | bitmapAnimation_data_2.add(0); 171 | bitmapAnimation_data_2.add(0); 172 | bitmapAnimation_data_2.add(0); 173 | bitmapAnimation_data_2.add(0); 174 | bitmapAnimation_data_2.add(0); 175 | bitmapAnimation_data_2.add(0); 176 | bitmapAnimation_data_2.add(0); 177 | bitmapAnimation_data_2.add(0); 178 | bitmapAnimation_data_2.add(0); 179 | bitmapAnimation_data_2.add(0); 180 | bitmapAnimation_data_2.add(0); 181 | bitmapAnimation_data_2.add(2013); 182 | bitmapAnimation_data_2.add(2013); 183 | bitmapAnimation_data_2.add(0); 184 | bitmapAnimation_data_2.add(0); 185 | bitmapAnimation_data_2.add(0); 186 | bitmapAnimation_data_2.add(0); 187 | bitmapAnimation_data_2.add(0); 188 | bitmapAnimation_data_2.add(1986); 189 | bitmapAnimation_data_2.add(1986); 190 | bitmapAnimation_data_2.add(1986); 191 | bitmapAnimation_data_2.add(1986); 192 | bitmapAnimation_data_2.add(0); 193 | bitmapAnimation_data_2.add(0); 194 | bitmapAnimation_data_2.add(0); 195 | bitmapAnimation_data_2.add(65472); 196 | bitmapAnimation_data_2.add(65472); 197 | bitmapAnimation_data_2.add(65472); 198 | bitmapAnimation_data_2.add(65472); 199 | bitmapAnimation_data_2.add(65472); 200 | bitmapAnimation_data_2.add(65472); 201 | bitmapAnimation_data_2.add(0); 202 | bitmapAnimation_data_2.add(0); 203 | bitmapAnimation_data_2.add(0); 204 | bitmapAnimation_data_2.add(0); 205 | bitmapAnimation_data_2.add(64896); 206 | bitmapAnimation_data_2.add(64896); 207 | bitmapAnimation_data_2.add(0); 208 | bitmapAnimation_data_2.add(0); 209 | bitmapAnimation_data_2.add(0); 210 | bitmapAnimation_data_2.add(0); 211 | bitmapAnimation_data_2.add(0); 212 | bitmapAnimation_data_2.add(0); 213 | bitmapAnimation_data_2.add(63488); 214 | bitmapAnimation_data_2.add(63488); 215 | bitmapAnimation_data_2.add(0); 216 | bitmapAnimation_data_2.add(0); 217 | bitmapAnimation_data_2.add(0); 218 | 219 | JsonArray &bitmapAnimation_data_3 = bitmapAnimation_data.createNestedArray(); 220 | bitmapAnimation_data_3.add(0); 221 | bitmapAnimation_data_3.add(0); 222 | bitmapAnimation_data_3.add(0); 223 | bitmapAnimation_data_3.add(0); 224 | bitmapAnimation_data_3.add(0); 225 | bitmapAnimation_data_3.add(0); 226 | bitmapAnimation_data_3.add(0); 227 | bitmapAnimation_data_3.add(0); 228 | bitmapAnimation_data_3.add(0); 229 | bitmapAnimation_data_3.add(0); 230 | bitmapAnimation_data_3.add(0); 231 | bitmapAnimation_data_3.add(43039); 232 | bitmapAnimation_data_3.add(43039); 233 | bitmapAnimation_data_3.add(0); 234 | bitmapAnimation_data_3.add(0); 235 | bitmapAnimation_data_3.add(0); 236 | bitmapAnimation_data_3.add(0); 237 | bitmapAnimation_data_3.add(0); 238 | bitmapAnimation_data_3.add(383); 239 | bitmapAnimation_data_3.add(383); 240 | bitmapAnimation_data_3.add(383); 241 | bitmapAnimation_data_3.add(383); 242 | bitmapAnimation_data_3.add(0); 243 | bitmapAnimation_data_3.add(0); 244 | bitmapAnimation_data_3.add(0); 245 | bitmapAnimation_data_3.add(2013); 246 | bitmapAnimation_data_3.add(2013); 247 | bitmapAnimation_data_3.add(2013); 248 | bitmapAnimation_data_3.add(2013); 249 | bitmapAnimation_data_3.add(2013); 250 | bitmapAnimation_data_3.add(2013); 251 | bitmapAnimation_data_3.add(0); 252 | bitmapAnimation_data_3.add(0); 253 | bitmapAnimation_data_3.add(0); 254 | bitmapAnimation_data_3.add(0); 255 | bitmapAnimation_data_3.add(1986); 256 | bitmapAnimation_data_3.add(1986); 257 | bitmapAnimation_data_3.add(0); 258 | bitmapAnimation_data_3.add(0); 259 | bitmapAnimation_data_3.add(0); 260 | bitmapAnimation_data_3.add(0); 261 | bitmapAnimation_data_3.add(0); 262 | bitmapAnimation_data_3.add(0); 263 | bitmapAnimation_data_3.add(65472); 264 | bitmapAnimation_data_3.add(65472); 265 | bitmapAnimation_data_3.add(0); 266 | bitmapAnimation_data_3.add(0); 267 | bitmapAnimation_data_3.add(0); 268 | bitmapAnimation_data_3.add(0); 269 | bitmapAnimation_data_3.add(0); 270 | bitmapAnimation_data_3.add(0); 271 | bitmapAnimation_data_3.add(64896); 272 | bitmapAnimation_data_3.add(64896); 273 | bitmapAnimation_data_3.add(0); 274 | bitmapAnimation_data_3.add(0); 275 | bitmapAnimation_data_3.add(0); 276 | bitmapAnimation_data_3.add(0); 277 | bitmapAnimation_data_3.add(0); 278 | bitmapAnimation_data_3.add(0); 279 | bitmapAnimation_data_3.add(63488); 280 | bitmapAnimation_data_3.add(63488); 281 | bitmapAnimation_data_3.add(0); 282 | bitmapAnimation_data_3.add(0); 283 | bitmapAnimation_data_3.add(0); 284 | 285 | JsonArray &bitmapAnimation_data_4 = bitmapAnimation_data.createNestedArray(); 286 | bitmapAnimation_data_4.add(0); 287 | bitmapAnimation_data_4.add(0); 288 | bitmapAnimation_data_4.add(63517); 289 | bitmapAnimation_data_4.add(63517); 290 | bitmapAnimation_data_4.add(63517); 291 | bitmapAnimation_data_4.add(63517); 292 | bitmapAnimation_data_4.add(0); 293 | bitmapAnimation_data_4.add(0); 294 | bitmapAnimation_data_4.add(0); 295 | bitmapAnimation_data_4.add(43039); 296 | bitmapAnimation_data_4.add(43039); 297 | bitmapAnimation_data_4.add(43039); 298 | bitmapAnimation_data_4.add(43039); 299 | bitmapAnimation_data_4.add(43039); 300 | bitmapAnimation_data_4.add(43039); 301 | bitmapAnimation_data_4.add(0); 302 | bitmapAnimation_data_4.add(0); 303 | bitmapAnimation_data_4.add(0); 304 | bitmapAnimation_data_4.add(0); 305 | bitmapAnimation_data_4.add(383); 306 | bitmapAnimation_data_4.add(383); 307 | bitmapAnimation_data_4.add(0); 308 | bitmapAnimation_data_4.add(0); 309 | bitmapAnimation_data_4.add(0); 310 | bitmapAnimation_data_4.add(0); 311 | bitmapAnimation_data_4.add(0); 312 | bitmapAnimation_data_4.add(0); 313 | bitmapAnimation_data_4.add(2013); 314 | bitmapAnimation_data_4.add(2013); 315 | bitmapAnimation_data_4.add(0); 316 | bitmapAnimation_data_4.add(0); 317 | bitmapAnimation_data_4.add(0); 318 | bitmapAnimation_data_4.add(0); 319 | bitmapAnimation_data_4.add(0); 320 | bitmapAnimation_data_4.add(0); 321 | bitmapAnimation_data_4.add(1986); 322 | bitmapAnimation_data_4.add(1986); 323 | bitmapAnimation_data_4.add(0); 324 | bitmapAnimation_data_4.add(0); 325 | bitmapAnimation_data_4.add(0); 326 | bitmapAnimation_data_4.add(0); 327 | bitmapAnimation_data_4.add(0); 328 | bitmapAnimation_data_4.add(0); 329 | bitmapAnimation_data_4.add(65472); 330 | bitmapAnimation_data_4.add(65472); 331 | bitmapAnimation_data_4.add(0); 332 | bitmapAnimation_data_4.add(0); 333 | bitmapAnimation_data_4.add(0); 334 | bitmapAnimation_data_4.add(0); 335 | bitmapAnimation_data_4.add(0); 336 | bitmapAnimation_data_4.add(0); 337 | bitmapAnimation_data_4.add(0); 338 | bitmapAnimation_data_4.add(0); 339 | bitmapAnimation_data_4.add(0); 340 | bitmapAnimation_data_4.add(0); 341 | bitmapAnimation_data_4.add(0); 342 | bitmapAnimation_data_4.add(0); 343 | bitmapAnimation_data_4.add(0); 344 | bitmapAnimation_data_4.add(0); 345 | bitmapAnimation_data_4.add(0); 346 | bitmapAnimation_data_4.add(0); 347 | bitmapAnimation_data_4.add(0); 348 | bitmapAnimation_data_4.add(0); 349 | bitmapAnimation_data_4.add(0); 350 | 351 | JsonArray &bitmapAnimation_data_5 = bitmapAnimation_data.createNestedArray(); 352 | bitmapAnimation_data_5.add(0); 353 | bitmapAnimation_data_5.add(0); 354 | bitmapAnimation_data_5.add(0); 355 | bitmapAnimation_data_5.add(63517); 356 | bitmapAnimation_data_5.add(63517); 357 | bitmapAnimation_data_5.add(0); 358 | bitmapAnimation_data_5.add(0); 359 | bitmapAnimation_data_5.add(0); 360 | bitmapAnimation_data_5.add(0); 361 | bitmapAnimation_data_5.add(0); 362 | bitmapAnimation_data_5.add(0); 363 | bitmapAnimation_data_5.add(43039); 364 | bitmapAnimation_data_5.add(43039); 365 | bitmapAnimation_data_5.add(0); 366 | bitmapAnimation_data_5.add(0); 367 | bitmapAnimation_data_5.add(0); 368 | bitmapAnimation_data_5.add(0); 369 | bitmapAnimation_data_5.add(0); 370 | bitmapAnimation_data_5.add(0); 371 | bitmapAnimation_data_5.add(383); 372 | bitmapAnimation_data_5.add(383); 373 | bitmapAnimation_data_5.add(0); 374 | bitmapAnimation_data_5.add(0); 375 | bitmapAnimation_data_5.add(0); 376 | bitmapAnimation_data_5.add(0); 377 | bitmapAnimation_data_5.add(0); 378 | bitmapAnimation_data_5.add(0); 379 | bitmapAnimation_data_5.add(2013); 380 | bitmapAnimation_data_5.add(2013); 381 | bitmapAnimation_data_5.add(0); 382 | bitmapAnimation_data_5.add(0); 383 | bitmapAnimation_data_5.add(0); 384 | bitmapAnimation_data_5.add(0); 385 | bitmapAnimation_data_5.add(0); 386 | bitmapAnimation_data_5.add(0); 387 | bitmapAnimation_data_5.add(0); 388 | bitmapAnimation_data_5.add(0); 389 | bitmapAnimation_data_5.add(0); 390 | bitmapAnimation_data_5.add(0); 391 | bitmapAnimation_data_5.add(0); 392 | bitmapAnimation_data_5.add(0); 393 | bitmapAnimation_data_5.add(0); 394 | bitmapAnimation_data_5.add(0); 395 | bitmapAnimation_data_5.add(0); 396 | bitmapAnimation_data_5.add(0); 397 | bitmapAnimation_data_5.add(0); 398 | bitmapAnimation_data_5.add(0); 399 | bitmapAnimation_data_5.add(0); 400 | bitmapAnimation_data_5.add(0); 401 | bitmapAnimation_data_5.add(0); 402 | bitmapAnimation_data_5.add(0); 403 | bitmapAnimation_data_5.add(0); 404 | bitmapAnimation_data_5.add(0); 405 | bitmapAnimation_data_5.add(0); 406 | bitmapAnimation_data_5.add(0); 407 | bitmapAnimation_data_5.add(0); 408 | bitmapAnimation_data_5.add(0); 409 | bitmapAnimation_data_5.add(0); 410 | bitmapAnimation_data_5.add(0); 411 | bitmapAnimation_data_5.add(0); 412 | bitmapAnimation_data_5.add(0); 413 | bitmapAnimation_data_5.add(0); 414 | bitmapAnimation_data_5.add(0); 415 | bitmapAnimation_data_5.add(0); 416 | 417 | JsonArray &bitmapAnimation_data_6 = bitmapAnimation_data.createNestedArray(); 418 | bitmapAnimation_data_6.add(0); 419 | bitmapAnimation_data_6.add(0); 420 | bitmapAnimation_data_6.add(0); 421 | bitmapAnimation_data_6.add(63517); 422 | bitmapAnimation_data_6.add(63517); 423 | bitmapAnimation_data_6.add(0); 424 | bitmapAnimation_data_6.add(0); 425 | bitmapAnimation_data_6.add(0); 426 | bitmapAnimation_data_6.add(0); 427 | bitmapAnimation_data_6.add(0); 428 | bitmapAnimation_data_6.add(0); 429 | bitmapAnimation_data_6.add(43039); 430 | bitmapAnimation_data_6.add(43039); 431 | bitmapAnimation_data_6.add(0); 432 | bitmapAnimation_data_6.add(0); 433 | bitmapAnimation_data_6.add(0); 434 | bitmapAnimation_data_6.add(0); 435 | bitmapAnimation_data_6.add(0); 436 | bitmapAnimation_data_6.add(0); 437 | bitmapAnimation_data_6.add(0); 438 | bitmapAnimation_data_6.add(0); 439 | bitmapAnimation_data_6.add(0); 440 | bitmapAnimation_data_6.add(0); 441 | bitmapAnimation_data_6.add(0); 442 | bitmapAnimation_data_6.add(0); 443 | bitmapAnimation_data_6.add(0); 444 | bitmapAnimation_data_6.add(0); 445 | bitmapAnimation_data_6.add(0); 446 | bitmapAnimation_data_6.add(0); 447 | bitmapAnimation_data_6.add(0); 448 | bitmapAnimation_data_6.add(0); 449 | bitmapAnimation_data_6.add(0); 450 | bitmapAnimation_data_6.add(0); 451 | bitmapAnimation_data_6.add(0); 452 | bitmapAnimation_data_6.add(0); 453 | bitmapAnimation_data_6.add(0); 454 | bitmapAnimation_data_6.add(0); 455 | bitmapAnimation_data_6.add(0); 456 | bitmapAnimation_data_6.add(0); 457 | bitmapAnimation_data_6.add(0); 458 | bitmapAnimation_data_6.add(0); 459 | bitmapAnimation_data_6.add(0); 460 | bitmapAnimation_data_6.add(0); 461 | bitmapAnimation_data_6.add(0); 462 | bitmapAnimation_data_6.add(0); 463 | bitmapAnimation_data_6.add(0); 464 | bitmapAnimation_data_6.add(0); 465 | bitmapAnimation_data_6.add(0); 466 | bitmapAnimation_data_6.add(0); 467 | bitmapAnimation_data_6.add(0); 468 | bitmapAnimation_data_6.add(0); 469 | bitmapAnimation_data_6.add(0); 470 | bitmapAnimation_data_6.add(0); 471 | bitmapAnimation_data_6.add(0); 472 | bitmapAnimation_data_6.add(0); 473 | bitmapAnimation_data_6.add(0); 474 | bitmapAnimation_data_6.add(0); 475 | bitmapAnimation_data_6.add(0); 476 | bitmapAnimation_data_6.add(0); 477 | bitmapAnimation_data_6.add(0); 478 | bitmapAnimation_data_6.add(0); 479 | bitmapAnimation_data_6.add(0); 480 | bitmapAnimation_data_6.add(0); 481 | bitmapAnimation_data_6.add(0); 482 | } -------------------------------------------------------------------------------- /include/Version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | typedef struct 5 | { 6 | int major; 7 | int minor; 8 | int patch; 9 | char prerelease[16]; 10 | } Version; 11 | 12 | #endif // VERSION_H -------------------------------------------------------------------------------- /include/Webinterface.h: -------------------------------------------------------------------------------- 1 | // Will be replaced via .github/webui.py script during build pipeline 2 | const char mainPage[] PROGMEM = R"=====(PixelIt WebUI
)====="; -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [common] 12 | framework = arduino 13 | monitor_speed = 115200 14 | upload_speed = 460800 15 | extra_scripts = pre:extra_script.py 16 | build_flags = 17 | -DMATRIX_WIDTH=32 ; Pixel cols 18 | -DMATRIX_HEIGHT=8 ; Pixel rows 19 | esp32_build_flags = 20 | ${common.build_flags} 21 | -DLDR_PIN=34 22 | -DMATRIX_PIN=27 23 | -DDEFAULT_PIN_SCL="GPIO_NUM_22" 24 | -DDEFAULT_PIN_SDA="GPIO_NUM_21" 25 | -DDEFAULT_PIN_DFPRX="GPIO_NUM_17" 26 | -DDEFAULT_PIN_DFPTX="GPIO_NUM_16" 27 | -DDEFAULT_PIN_ONEWIRE="GPIO_NUM_16" 28 | -DDEFAULT_MATRIX_TYPE=1 29 | -DDEFAULT_LDR=GL5516 30 | -DVBAT_PIN=0 31 | esp8266_build_flags = 32 | ${common.build_flags} 33 | -DLDR_PIN=A0 34 | -DMATRIX_PIN=D2 35 | -DDEFAULT_PIN_SCL="Pin_D1" 36 | -DDEFAULT_PIN_SDA="Pin_D3" 37 | -DDEFAULT_PIN_DFPRX="Pin_D7" 38 | -DDEFAULT_PIN_DFPTX="Pin_D8" 39 | -DDEFAULT_PIN_ONEWIRE="Pin_D1" 40 | -DDEFAULT_MATRIX_TYPE=1 41 | -DDEFAULT_LDR=GL5516 42 | -DVBAT_PIN=0 43 | lib_deps = 44 | adafruit/Adafruit BME280 Library@2.2.4 45 | adafruit/Adafruit BME680 Library@2.0.4 46 | adafruit/Adafruit BMP280 Library@2.6.8 47 | adafruit/Adafruit BusIO@1.16.1 48 | adafruit/Adafruit GFX Library@1.11.9 49 | adafruit/Adafruit SHT31 Library@2.2.2 50 | adafruit/Adafruit Unified Sensor@1.1.4 51 | arduino-libraries/ArduinoHttpClient@0.4.0 52 | bakercp/CRC32 @ 2.0.0 53 | bblanchon/ArduinoJson@5.13.4 54 | beegee-tokyo/DHT sensor library for ESPx@1.19.0 55 | claws/BH1750@1.3.0 56 | fastled/FastLED@3.7.0 57 | knolleary/PubSubClient@2.8.0 58 | LightDependentResistor=https://github.com/QuentinCG/Arduino-Light-Dependent-Resistor-Library.git#1.4.0 59 | links2004/WebSockets@2.4.1 60 | marcmerlin/FastLED NeoMatrix@1.2.0 61 | powerbroker2/DFPlayerMini_Fast@1.2.4 62 | robtillaart/Max44009@0.6.0 63 | TimeLib = https://github.com/PaulStoffregen/Time.git#v1.6.1 64 | 65 | [env:ESP32_generic] 66 | platform = espressif32 67 | board = esp32dev 68 | framework = ${common.framework} 69 | board_build.f_cpu = 80000000L 70 | monitor_speed = ${common.monitor_speed} 71 | extra_scripts = ${common.extra_scripts} 72 | upload_speed = ${common.upload_speed} 73 | build_flags = 74 | ${common.esp32_build_flags} 75 | -DBUILD_SECTION="ESP32_generic" 76 | platform_packages = 77 | framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.14 78 | toolchain-xtensa32@~2.80400.0 79 | lib_deps = 80 | ${common.lib_deps} 81 | Hash = https://github.com/bbx10/Hash_tng.git 82 | plerup/EspSoftwareSerial@^6.11.4 83 | WiFiManager = https://github.com/tzapu/WiFiManager.git#v2.0.15-rc.1 84 | 85 | [env:ESP8266_generic] 86 | platform = espressif8266@2.6.3 87 | board = esp12e 88 | framework = ${common.framework} 89 | board_build.filesystem = littlefs 90 | monitor_speed = ${common.monitor_speed} 91 | extra_scripts = ${common.extra_scripts} 92 | upload_speed = ${common.upload_speed} 93 | build_flags = 94 | ${common.esp8266_build_flags} 95 | -DBUILD_SECTION="ESP8266_generic" 96 | lib_deps = 97 | ${common.lib_deps} 98 | mr-glt/SHA-1 Hash@^1.1.0 99 | tzapu/WiFiManager@^0.16.0 100 | 101 | [env:ESP8266_d1_mini] 102 | extends = env:ESP8266_generic 103 | monitor_filters = esp8266_exception_decoder 104 | board = d1_mini 105 | build_flags = 106 | ${common.esp8266_build_flags} 107 | -DBUILD_SECTION='ESP8266_d1_mini' 108 | 109 | [env:ESP8266_nodemcuv2] 110 | extends = env:ESP8266_generic 111 | board = nodemcuv2 112 | build_flags = 113 | ${common.esp8266_build_flags} 114 | -DBUILD_SECTION="ESP8266_nodemcuv2" 115 | 116 | [env:ESP32_d1_mini32] 117 | extends = env:ESP32_generic 118 | board = wemos_d1_mini32 119 | build_flags = 120 | ${common.esp32_build_flags} 121 | -DBUILD_SECTION="ESP32_d1_mini32" 122 | 123 | [env:ESP32_ulanzi] 124 | extends = env:ESP32_generic 125 | build_flags = 126 | ${common.build_flags} 127 | -DLDR_PIN=A7 128 | -DMATRIX_PIN=32 129 | -DULANZI 130 | -DVBAT_PIN=GPIO_NUM_34 131 | -DDEFAULT_PIN_SCL=GPIO_NUM_22 132 | -DDEFAULT_PIN_SDA=GPIO_NUM_21 133 | -DDEFAULT_PIN_DFPRX=SPI_CLK_GPIO_NUM 134 | -DDEFAULT_PIN_DFPTX=SPI_CS0_GPIO_NUM 135 | -DDEFAULT_PIN_ONEWIRE=GPIO_NUM_22 136 | -DDEFAULT_MATRIX_TYPE=2 137 | -DDEFAULT_LDR=GL5516 138 | -DMIN_BATTERY=475 139 | -DMAX_BATTERY=665 140 | -DBUILD_SECTION="ESP32_ulanzi" 141 | -------------------------------------------------------------------------------- /src/Liveview.cpp: -------------------------------------------------------------------------------- 1 | #include "Liveview.h" 2 | #include 3 | 4 | Liveview::Liveview() 5 | { 6 | } 7 | 8 | void Liveview::begin(FastLED_NeoMatrix *matrix, CRGB *leds, uint16_t interval) 9 | { 10 | this->_matrix = matrix; 11 | _leds = leds; 12 | _interval = interval; 13 | _lastUpdate = millis(); 14 | callbackFunction = nullptr; 15 | } 16 | 17 | void Liveview::setCallback(void (*func)(const char *, size_t)) 18 | { 19 | callbackFunction = func; 20 | } 21 | 22 | void Liveview::loop() 23 | { 24 | if (_interval > 0 && (millis() - _lastUpdate) >= _interval) 25 | { 26 | _lastUpdate = millis(); 27 | if (callbackFunction != nullptr) 28 | { 29 | fillBuffer(); 30 | } 31 | } 32 | } 33 | 34 | void Liveview::fillBuffer() 35 | { 36 | // set prefix 37 | memcpy(_liveviewBuffer, _LIVEVIEW_PREFIX, _LIVEVIEW_PREFIX_LENGHT); 38 | 39 | // fill buffer with led values 40 | for (int y = 0; y < MATRIX_HEIGHT; y++) 41 | { 42 | for (int x = 0; x < MATRIX_WIDTH; x++) 43 | { 44 | int index = this->_matrix->XY(x, y); 45 | sprintf(&_liveviewBuffer[(y * MATRIX_WIDTH + x) * 6 + _LIVEVIEW_PREFIX_LENGHT], "%02X%02X%02X", _leds[index].r, _leds[index].g, _leds[index].b); 46 | } 47 | } 48 | 49 | // set suffix 50 | memcpy(&_liveviewBuffer[MATRIX_HEIGHT * MATRIX_WIDTH * 6 + _LIVEVIEW_PREFIX_LENGHT], _LIVEVIEW_SUFFIX, _LIVEVIEW_SUFFIX_LENGHT); 51 | 52 | // calculate checksum 53 | uint32_t newChecksum = CRC32::calculate((byte *)_liveviewBuffer, _LIVEVIEW_BUFFER_LENGHT); 54 | if (_lastChecksum != newChecksum) 55 | { 56 | // Serial.printf("Checksum (new/old): 0x%08X/0x%08X\n", newChecksum, _lastChecksum); 57 | _lastChecksum = newChecksum; 58 | // rise callback 59 | callbackFunction(_liveviewBuffer, _LIVEVIEW_BUFFER_LENGHT); 60 | } 61 | } -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | --------------------------------------------------------------------------------