├── photopea_parking_sensor_128x64.psd ├── .github └── FUNDING.yml ├── LICENSE ├── README.md └── parking_sensor_128x64.ino /photopea_parking_sensor_128x64.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/upiir/arduino_parking_sensor/HEAD/photopea_parking_sensor_128x64.psd -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [upiir] 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 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 upir 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 | # Arduino Parking Sensor 2 | Simple parking sensor with Arduino UNO, Ultrasonic sensors and OLED display. 3 | 4 | For more details, please view youtube video 5 | 6 | - Video overview: https://youtu.be/sEWw087KOj0 7 | - Full tutorial video: https://youtu.be/gg08H-6Z1Lo 8 | 9 | WOKWI online emulator: https://wokwi.com/projects/348388602879672914 10 | 11 | useful links: 12 | - OLED Display: https://s.click.aliexpress.com/e/_AWSVnt 13 | - 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh 14 | - Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz 15 | - u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference 16 | - Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h 17 | - Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le 18 | - Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9 19 | - Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx 20 | 21 | Related videos: 22 | - Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk 23 | - Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0 24 | - Knob over OLED Display - https://youtu.be/SmbcNx7tbX8 25 | - Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA 26 | - Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ 27 | 28 | Parts: 29 | - Arduino UNO 30 | - 3x HC-SR04 Ultrasonic sensors 31 | - 128x64px SSD1306 OLED Display 32 | 33 | ![image](https://user-images.githubusercontent.com/117754156/201975217-f027c7f4-dd7a-4dcd-9278-5358ba945e05.png) 34 | 35 | ![image](https://user-images.githubusercontent.com/117754156/202236055-07dfee91-5953-4094-8cb8-b69f465fe526.png) 36 | 37 | 38 | Some random photos: 39 | 40 | ![photo_01](https://user-images.githubusercontent.com/117754156/202244684-9616d042-c163-455e-bc8a-484f01130e00.jpg) 41 | ![photo_02](https://user-images.githubusercontent.com/117754156/202244697-7372ae43-8a29-4783-8407-74a1a7a4c39e.jpg) 42 | ![photo_03](https://user-images.githubusercontent.com/117754156/202244709-036adbcc-28c0-458b-a8ae-48e61b059f32.jpg) 43 | ![photo_04](https://user-images.githubusercontent.com/117754156/202244720-7a1dad65-619e-446b-99f8-37910240a0f5.jpg) 44 | ![photo_05](https://user-images.githubusercontent.com/117754156/202244734-58ab8eb3-5c9c-4ae4-9987-0d65885905f4.jpg) 45 | 46 | 47 | ![THUMB_diy_parking_sensor_arduino_full_tutorial4](https://user-images.githubusercontent.com/117754156/203079080-dad706d2-3343-4c88-a855-e8119168453b.jpg) 48 | -------------------------------------------------------------------------------- /parking_sensor_128x64.ino: -------------------------------------------------------------------------------- 1 | // simple project using Arduino UNO and 128x64 OLED Display for parking sensor 2 | // created by upir, 2022 3 | // youtube channel: https://www.youtube.com/upir_upir 4 | 5 | // youtube video: https://youtu.be/sEWw087KOj0 6 | // Github: https://github.com/upiir/arduino_parking_sensor 7 | 8 | // u8g fonts (fonts available for u8g library): https://nodemcu-build.com/u8g-fonts.php 9 | // u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference 10 | // Wokwi starting project: https://wokwi.com/arduino/projects/300867986768527882 11 | // Wokwi starting project distance sensor: https://wokwi.com/projects/304444938977804866 12 | // Photopea (online Photoshop-like tool): https://www.photopea.com/ 13 | // image2cpp (convert images into C code): https://javl.github.io/image2cpp/ 14 | 15 | // useful links: 16 | // OLED Display: https://s.click.aliexpress.com/e/_AWSVnt 17 | // 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh 18 | // Transparent OLED display: https://s.click.aliexpress.com/e/_Dns6eLz 19 | // u8g documentation: https://github.com/olikraus/u8glib/wiki/userreference 20 | // Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h 21 | // Arduino UNO MINI: https://store.arduino.cc/products/uno-mini-le 22 | // Big OLED Display: https://s.click.aliexpress.com/e/_ADL0T9 23 | // Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx 24 | 25 | // Related videos: 26 | // Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk 27 | // Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0 28 | // Knob over OLED Display - https://youtu.be/SmbcNx7tbX8 29 | // Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA 30 | // Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ 31 | 32 | 33 | 34 | #include "U8glib.h" 35 | 36 | U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI 37 | 38 | 39 | // 'car_image', 56x15px 40 | const unsigned char bitmap_car_image [] PROGMEM = { 41 | 0xc0, 0x40, 0x00, 0x00, 0x00, 0x02, 0x03, 0xc0, 0x8f, 0xff, 0xff, 0xff, 0xf1, 0x03, 0xe0, 0x70, 42 | 0x00, 0x00, 0x00, 0x0e, 0x07, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xc0, 0xff, 0x00, 0x00, 43 | 0x00, 0xff, 0x03, 0xc0, 0x00, 0x05, 0x75, 0xc0, 0x00, 0x03, 0x47, 0xf8, 0x05, 0x51, 0x40, 0x1f, 44 | 0xe2, 0x47, 0xfc, 0x05, 0x65, 0x80, 0x3f, 0xe2, 0x40, 0x78, 0x06, 0x45, 0x40, 0x1e, 0x02, 0x30, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x01, 0xff, 0xff, 0xff, 0x80, 0x78, 0x07, 0xe2, 0x00, 46 | 0x00, 0x00, 0x47, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, 47 | 0xfd, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x06, 0x00 48 | }; 49 | // 'sensor_01_a_off', 32x14px 50 | const unsigned char bitmap_sensor_01_a_off [] PROGMEM = { 51 | 0x00, 0x40, 0x00, 0x00, 0x02, 0xa8, 0x00, 0x00, 0x05, 0x55, 0x00, 0x00, 0x02, 0xaa, 0xa0, 0x00, 52 | 0x05, 0x55, 0x54, 0x00, 0x0a, 0xaa, 0xaa, 0xa0, 0x15, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa0, 53 | 0x01, 0x55, 0x55, 0x40, 0x00, 0x2a, 0xaa, 0xa0, 0x00, 0x15, 0x55, 0x40, 0x00, 0x02, 0xaa, 0xa0, 54 | 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x02, 0xa0 55 | }; 56 | // 'sensor_01_a_on', 32x14px 57 | const unsigned char bitmap_sensor_01_a_on [] PROGMEM = { 58 | 0x00, 0xc0, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 59 | 0x0f, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 60 | 0x03, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xe0, 61 | 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x03, 0xe0 62 | }; 63 | // 'sensor_01_b_off', 32x16px 64 | const unsigned char bitmap_sensor_01_b_off [] PROGMEM = { 65 | 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x05, 0x54, 0x00, 0x00, 66 | 0x0a, 0xaa, 0x80, 0x00, 0x15, 0x55, 0x50, 0x00, 0x0a, 0xaa, 0xaa, 0x80, 0x15, 0x55, 0x55, 0x50, 67 | 0x0a, 0xaa, 0xaa, 0xa8, 0x05, 0x55, 0x55, 0x50, 0x00, 0xaa, 0xaa, 0xa8, 0x00, 0x15, 0x55, 0x50, 68 | 0x00, 0x02, 0xaa, 0xa0, 0x00, 0x00, 0x55, 0x50, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x50 69 | }; 70 | // 'sensor_01_b_on', 32x16px 71 | const unsigned char bitmap_sensor_01_b_on [] PROGMEM = { 72 | 0x02, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 73 | 0x0f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xf8, 74 | 0x1f, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xf8, 75 | 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xf0 76 | }; 77 | // 'sensor_01_c_off', 32x17px 78 | const unsigned char bitmap_sensor_01_c_off [] PROGMEM = { 79 | 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 80 | 0x2a, 0xaa, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00, 0x2a, 0xaa, 0xaa, 0x00, 0x55, 0x55, 0x55, 0x40, 81 | 0x2a, 0xaa, 0xaa, 0xaa, 0x15, 0x55, 0x55, 0x54, 0x02, 0xaa, 0xaa, 0xa8, 0x00, 0x55, 0x55, 0x54, 82 | 0x00, 0x0a, 0xaa, 0xa8, 0x00, 0x01, 0x55, 0x54, 0x00, 0x00, 0x2a, 0xa8, 0x00, 0x00, 0x05, 0x54, 83 | 0x00, 0x00, 0x00, 0x28 84 | }; 85 | // 'sensor_01_c_on', 32x17px 86 | const unsigned char bitmap_sensor_01_c_on [] PROGMEM = { 87 | 0x08, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 88 | 0x3f, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xe0, 89 | 0x7f, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfc, 90 | 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x07, 0xfc, 91 | 0x00, 0x00, 0x00, 0x3c 92 | }; 93 | // 'sensor_01_d_off', 32x18px 94 | const unsigned char bitmap_sensor_01_d_off [] PROGMEM = { 95 | 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x00, 0x00, 96 | 0x55, 0x50, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x50, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 97 | 0x55, 0x55, 0x55, 0x50, 0x2a, 0xaa, 0xaa, 0xaa, 0x05, 0x55, 0x55, 0x54, 0x02, 0xaa, 0xaa, 0xaa, 98 | 0x00, 0x55, 0x55, 0x54, 0x00, 0x0a, 0xaa, 0xaa, 0x00, 0x01, 0x55, 0x54, 0x00, 0x00, 0x2a, 0xa8, 99 | 0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0x08 100 | }; 101 | // 'sensor_02_a_off', 32x9px 102 | const unsigned char bitmap_sensor_02_a_off [] PROGMEM = { 103 | 0x05, 0x55, 0x55, 0x40, 0x0a, 0xaa, 0xaa, 0xa0, 0x05, 0x55, 0x55, 0x40, 0x0a, 0xaa, 0xaa, 0xa0, 104 | 0x05, 0x55, 0x55, 0x40, 0x0a, 0xaa, 0xaa, 0xa0, 0x05, 0x55, 0x55, 0x40, 0x0a, 0xaa, 0xaa, 0xa0, 105 | 0x15, 0x55, 0x55, 0x50 106 | }; 107 | // 'sensor_01_d_on', 32x18px 108 | const unsigned char bitmap_sensor_01_d_on [] PROGMEM = { 109 | 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 110 | 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xfe, 0x00, 111 | 0x7f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xfe, 112 | 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xfc, 113 | 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x1c 114 | }; 115 | // 'sensor_02_a_on', 32x9px 116 | const unsigned char bitmap_sensor_02_a_on [] PROGMEM = { 117 | 0x07, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 118 | 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 119 | 0x1f, 0xff, 0xff, 0xf0 120 | }; 121 | // 'sensor_02_b_off', 32x9px 122 | const unsigned char bitmap_sensor_02_b_off [] PROGMEM = { 123 | 0x15, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa0, 0x15, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa0, 124 | 0x15, 0x55, 0x55, 0x50, 0x2a, 0xaa, 0xaa, 0xa8, 0x15, 0x55, 0x55, 0x50, 0x2a, 0xaa, 0xaa, 0xa8, 125 | 0x05, 0x55, 0x55, 0x40 126 | }; 127 | // 'sensor_02_b_on', 32x9px 128 | const unsigned char bitmap_sensor_02_b_on [] PROGMEM = { 129 | 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 130 | 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 131 | 0x0f, 0xff, 0xff, 0xe0 132 | }; 133 | // 'sensor_02_c_off', 32x10px 134 | const unsigned char bitmap_sensor_02_c_off [] PROGMEM = { 135 | 0x10, 0x00, 0x00, 0x04, 0x0a, 0xaa, 0xaa, 0xa8, 0x15, 0x55, 0x55, 0x54, 0x2a, 0xaa, 0xaa, 0xaa, 136 | 0x15, 0x55, 0x55, 0x54, 0x2a, 0xaa, 0xaa, 0xaa, 0x15, 0x55, 0x55, 0x54, 0x2a, 0xaa, 0xaa, 0xaa, 137 | 0x15, 0x55, 0x55, 0x54, 0x0a, 0xaa, 0xaa, 0xa8 138 | }; 139 | // 'sensor_02_c_on', 32x10px 140 | const unsigned char bitmap_sensor_02_c_on [] PROGMEM = { 141 | 0x18, 0x00, 0x00, 0x0c, 0x1f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfe, 142 | 0x3f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfe, 143 | 0x3f, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf8 144 | }; 145 | // 'sensor_02_d_off', 40x10px 146 | const unsigned char bitmap_sensor_02_d_off [] PROGMEM = { 147 | 0x02, 0x80, 0x00, 0x00, 0x28, 0x01, 0x55, 0x55, 0x55, 0x50, 0x02, 0xaa, 0xaa, 0xaa, 0xa8, 0x01, 148 | 0x55, 0x55, 0x55, 0x50, 0x02, 0xaa, 0xaa, 0xaa, 0xa8, 0x05, 0x55, 0x55, 0x55, 0x54, 0x02, 0xaa, 149 | 0xaa, 0xaa, 0xa8, 0x05, 0x55, 0x55, 0x55, 0x54, 0x02, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x55, 0x55, 150 | 0x55, 0x40 151 | }; 152 | // 'sensor_02_d_on', 40x10px 153 | const unsigned char bitmap_sensor_02_d_on [] PROGMEM = { 154 | 0x03, 0x80, 0x00, 0x00, 0x38, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x03, 155 | 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 156 | 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 157 | 0xff, 0xe0 158 | }; 159 | // 'sensor_03_a_off', 32x14px 160 | const unsigned char bitmap_sensor_03_a_off [] PROGMEM = { 161 | 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x00, 0x01, 0x55, 0x40, 0x00, 0x0a, 0xaa, 0x80, 162 | 0x00, 0x55, 0x55, 0x40, 0x0a, 0xaa, 0xaa, 0xa0, 0x15, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa0, 163 | 0x05, 0x55, 0x55, 0x00, 0x0a, 0xaa, 0xa8, 0x00, 0x05, 0x55, 0x50, 0x00, 0x0a, 0xaa, 0x80, 0x00, 164 | 0x05, 0x50, 0x00, 0x00, 0x0a, 0x80, 0x00, 0x00 165 | }; 166 | // 'sensor_03_b_on', 32x16px 167 | const unsigned char bitmap_sensor_03_b_on [] PROGMEM = { 168 | 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x3f, 0xf0, 169 | 0x00, 0x01, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfc, 170 | 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xfc, 0x00, 171 | 0x0f, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00 172 | }; 173 | // 'sensor_03_a_on', 32x14px 174 | const unsigned char bitmap_sensor_03_a_on [] PROGMEM = { 175 | 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 176 | 0x00, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 177 | 0x0f, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xfc, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0x80, 0x00, 178 | 0x0f, 0xf8, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00 179 | }; 180 | // 'sensor_03_b_off', 32x16px 181 | const unsigned char bitmap_sensor_03_b_off [] PROGMEM = { 182 | 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x2a, 0xa0, 183 | 0x00, 0x01, 0x55, 0x50, 0x00, 0x0a, 0xaa, 0xa8, 0x01, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa8, 184 | 0x15, 0x55, 0x55, 0x50, 0x0a, 0xaa, 0xaa, 0xa0, 0x15, 0x55, 0x55, 0x00, 0x0a, 0xaa, 0xa8, 0x00, 185 | 0x05, 0x55, 0x40, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00 186 | }; 187 | // 'sensor_03_c_off', 32x17px 188 | const unsigned char bitmap_sensor_03_c_off [] PROGMEM = { 189 | 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x0a, 0xa8, 190 | 0x00, 0x00, 0x55, 0x54, 0x00, 0x02, 0xaa, 0xa8, 0x00, 0x55, 0x55, 0x54, 0x02, 0xaa, 0xaa, 0xaa, 191 | 0x55, 0x55, 0x55, 0x54, 0x2a, 0xaa, 0xaa, 0xa8, 0x15, 0x55, 0x55, 0x40, 0x2a, 0xaa, 0xaa, 0x00, 192 | 0x15, 0x55, 0x50, 0x00, 0x2a, 0xaa, 0x80, 0x00, 0x15, 0x54, 0x00, 0x00, 0x2a, 0xa0, 0x00, 0x00, 193 | 0x14, 0x00, 0x00, 0x00 194 | }; 195 | // 'sensor_03_d_on', 32x18px 196 | const unsigned char bitmap_sensor_03_d_on [] PROGMEM = { 197 | 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x07, 0xfc, 198 | 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xfe, 199 | 0x1f, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0x80, 200 | 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 201 | 0x7f, 0x80, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00 202 | }; 203 | // 'sensor_03_d_off', 32x18px 204 | const unsigned char bitmap_sensor_03_d_off [] PROGMEM = { 205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x02, 0xa8, 206 | 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x15, 0x55, 0x54, 0x00, 0xaa, 0xaa, 0xaa, 207 | 0x15, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xa8, 0x55, 0x55, 0x55, 0x40, 0xaa, 0xaa, 0xaa, 0x80, 208 | 0x55, 0x55, 0x54, 0x00, 0xaa, 0xaa, 0xa0, 0x00, 0x55, 0x55, 0x00, 0x00, 0x2a, 0xa8, 0x00, 0x00, 209 | 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 210 | }; 211 | // 'sensor_03_c_on', 32x17px 212 | const unsigned char bitmap_sensor_03_c_on [] PROGMEM = { 213 | 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 214 | 0x00, 0x00, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xfe, 215 | 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0x00, 216 | 0x3f, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 217 | 0x3c, 0x00, 0x00, 0x00 218 | }; 219 | // 'sound_on', 24x10px 220 | const unsigned char bitmap_sound_on [] PROGMEM = { 221 | 0x03, 0xc0, 0x0f, 0x02, 0x0c, 0x01, 0x02, 0x1c, 0x11, 0x02, 0x3c, 0x49, 0x00, 0x7d, 0x28, 0x00, 222 | 0x7d, 0x28, 0x02, 0x3c, 0x49, 0x02, 0x1c, 0x11, 0x02, 0x0c, 0x01, 0x03, 0xc0, 0x0f 223 | }; 224 | // 'unit_cm', 24x10px 225 | const unsigned char bitmap_unit_cm [] PROGMEM = { 226 | 0xf0, 0x03, 0xc0, 0x80, 0x00, 0x40, 0xbe, 0xff, 0x40, 0xb6, 0xdb, 0x40, 0x30, 0xdb, 0x00, 0x30, 227 | 0xdb, 0x00, 0xb6, 0xdb, 0x40, 0xbe, 0xdb, 0x40, 0x80, 0x00, 0x40, 0xf0, 0x03, 0xc0 228 | }; 229 | 230 | /* 231 | Fontname: gamer_digits 232 | Copyright: Created with Fony 1.4.7 233 | Capital A Height: 0, '1' Height: 6 234 | Calculated Max Values w= 5 h= 6 x= 1 y= 0 dx= 6 dy= 0 ascent= 0 len= 6 235 | Font Bounding box w= 9 h= 5 x= 0 y=-6 236 | Calculated Min Values x= 0 y=-6 dx= 0 dy= 0 237 | Pure Font ascent = 6 descent= 0 238 | X Font ascent = 6 descent= 0 239 | Max Font ascent = 0 descent=-6 240 | */ 241 | const u8g_fntpgm_uint8_t gamer_digits[137] U8G_FONT_SECTION("gamer_digits") = { 242 | 0,9,5,0,250,6,0,0,0,0,48,57,0,0,250,6, 243 | 0,5,6,6,6,0,250,248,216,216,216,216,248,4,6,6, 244 | 6,1,250,224,96,96,96,96,240,5,6,6,6,0,250,248, 245 | 24,120,192,192,248,5,6,6,6,0,250,248,24,248,24,216, 246 | 248,5,6,6,6,0,250,56,120,216,248,24,24,5,6,6, 247 | 6,0,250,248,192,248,24,24,248,5,6,6,6,0,250,248, 248 | 192,248,216,216,248,5,6,6,6,0,250,248,24,24,24,24, 249 | 24,5,6,6,6,0,250,248,216,248,216,216,248,5,6,6, 250 | 6,0,250,248,216,216,248,24,248}; 251 | 252 | 253 | 254 | 255 | // set the correct pins for the distance sensors, we can (probably) use any digital pins 256 | #define sensor_01_ECHO_PIN 6 257 | #define sensor_01_TRIG_PIN 7 258 | #define sensor_02_ECHO_PIN 4 259 | #define sensor_02_TRIG_PIN 5 260 | #define sensor_03_ECHO_PIN 2 261 | #define sensor_03_TRIG_PIN 3 262 | 263 | // number of sensors - note that adding a new sensor is not as simple as changing the number, as the image drawing is hardcoded 264 | #define NUMBER_OF_SENSORS 3 265 | 266 | struct sensor_data { // structure for the sensor data 267 | int echo_pin; // ECHO pin for the ultrasonic distance sensor 268 | int trig_pin; // TRIG pin for the ultrasonic distance sensor 269 | int measured_distance_cm; // measured distance in CM 270 | int label_xpos; // x position of the distance label 271 | int label_ypos; // y position of the distance label 272 | int label_width; // calculated width of the distance string 273 | int label_startpos_x; // start X position for the label 274 | int label_startpos_y; // start Y position for the label 275 | int label_endpos_x; // end X position for the label 276 | int label_endpos_y; // end Y position for the label 277 | }; 278 | 279 | char buffer[10]; // helper C-style array of characters to store integers converted to strings 280 | 281 | struct sensor_data sensor[NUMBER_OF_SENSORS]; // we have 3 sensors for now 282 | 283 | int min_dist = 2; // minimum distance to display in cm, this is also the minimum measurable distance for the used sensor 284 | int max_dist = 100; // maximum distance to display in cm with the tile images, maximum measurable distance is 400cm = 4m 285 | 286 | int dist_step_01; // distance for the first tile (there are 4 tiles for each sensor) 287 | int dist_step_02; // distance for the 2nd tile 288 | int dist_step_03; // distance for the 3rd tile 289 | int dist_step_04; // distance for the 4th tile 290 | 291 | 292 | 293 | void setup() { 294 | // calculate individual steps for the 4 tiles 295 | dist_step_01 = min_dist + round((max_dist - min_dist) / 4.0 * 1.0); 296 | dist_step_02 = min_dist + round((max_dist - min_dist) / 4.0 * 2.0); 297 | dist_step_03 = min_dist + round((max_dist - min_dist) / 4.0 * 3.0); 298 | dist_step_04 = min_dist + round((max_dist - min_dist) / 4.0 * 4.0); 299 | 300 | // initialize pins for sensors 301 | sensor[0].echo_pin = sensor_01_ECHO_PIN; 302 | sensor[0].trig_pin = sensor_01_TRIG_PIN; 303 | sensor[1].echo_pin = sensor_02_ECHO_PIN; 304 | sensor[1].trig_pin = sensor_02_TRIG_PIN; 305 | sensor[2].echo_pin = sensor_03_ECHO_PIN; 306 | sensor[2].trig_pin = sensor_03_TRIG_PIN; 307 | 308 | // set pins to outputs and inputs - trigger is output, echo is input 309 | pinMode(sensor[0].trig_pin, OUTPUT); 310 | pinMode(sensor[0].echo_pin, INPUT); 311 | pinMode(sensor[1].trig_pin, OUTPUT); 312 | pinMode(sensor[1].echo_pin, INPUT); 313 | pinMode(sensor[2].trig_pin, OUTPUT); 314 | pinMode(sensor[2].echo_pin, INPUT); 315 | 316 | // initialize label position data 317 | // those are manualy defined in the Photoshop/Photopea file, since it´s just easier to do it that way instead of guessing the numbers 318 | sensor[0].label_startpos_x = 41; 319 | sensor[0].label_startpos_y = 20; 320 | sensor[0].label_endpos_x = 30; 321 | sensor[0].label_endpos_y = 58; 322 | sensor[1].label_startpos_x = 63; 323 | sensor[1].label_startpos_y = 23; 324 | sensor[1].label_endpos_x = 63; 325 | sensor[1].label_endpos_y = 60; 326 | sensor[2].label_startpos_x = 85; 327 | sensor[2].label_startpos_y = 20; 328 | sensor[2].label_endpos_x = 97; 329 | sensor[2].label_endpos_y = 57; 330 | 331 | u8g.setFont(gamer_digits); // gamer digits font - manually generated, only includes digits 332 | u8g.setColorIndex(1); // white color 333 | 334 | Serial.begin(115200); // debug only 335 | } 336 | 337 | void loop() { 338 | 339 | for (int i=0; i dist_step_01 ? bitmap_sensor_01_a_on : bitmap_sensor_01_a_off); 375 | u8g.drawBitmapP( 21, 25, 32/8, 16, sensor[0].measured_distance_cm > dist_step_02 ? bitmap_sensor_01_b_on : bitmap_sensor_01_b_off); 376 | u8g.drawBitmapP( 18, 34, 32/8, 17, sensor[0].measured_distance_cm > dist_step_03 ? bitmap_sensor_01_c_on : bitmap_sensor_01_c_off); 377 | u8g.drawBitmapP( 16, 43, 32/8, 18, sensor[0].measured_distance_cm > dist_step_04 ? bitmap_sensor_01_d_on : bitmap_sensor_01_d_off); 378 | 379 | u8g.drawBitmapP( 48, 23, 32/8, 9, sensor[1].measured_distance_cm > dist_step_01 ? bitmap_sensor_02_a_on : bitmap_sensor_02_a_off); 380 | u8g.drawBitmapP( 48, 33, 32/8, 9, sensor[1].measured_distance_cm > dist_step_02 ? bitmap_sensor_02_b_on : bitmap_sensor_02_b_off); 381 | u8g.drawBitmapP( 47, 42, 32/8, 10, sensor[1].measured_distance_cm > dist_step_03 ? bitmap_sensor_02_c_on : bitmap_sensor_02_c_off); 382 | u8g.drawBitmapP( 42, 52, 40/8, 10, sensor[1].measured_distance_cm > dist_step_04 ? bitmap_sensor_02_d_on : bitmap_sensor_02_d_off); 383 | 384 | u8g.drawBitmapP( 72, 17, 32/8, 14, sensor[2].measured_distance_cm > dist_step_01 ? bitmap_sensor_03_a_on : bitmap_sensor_03_a_off); 385 | u8g.drawBitmapP( 74, 25, 32/8, 16, sensor[2].measured_distance_cm > dist_step_02 ? bitmap_sensor_03_b_on : bitmap_sensor_03_b_off); 386 | u8g.drawBitmapP( 77, 34, 32/8, 17, sensor[2].measured_distance_cm > dist_step_03 ? bitmap_sensor_03_c_on : bitmap_sensor_03_c_off); 387 | u8g.drawBitmapP( 80, 43, 32/8, 18, sensor[2].measured_distance_cm > dist_step_04 ? bitmap_sensor_03_d_on : bitmap_sensor_03_d_off); 388 | 389 | for (int i=0; i