├── LICENSE ├── README.md └── arduino_1602_oled_gauge.ino /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 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 | # Smooth 16x2 gauges without custom characters 2 | 3 | Simple design for 16x2 OLED Character Display using the US2066 chip 4 | 5 | **YOUTUBE VIDEO: https://youtu.be/MEhJtpkjwnc** 6 | 7 | Links from the video: 8 | - 16x2 OLED Character Display IIC - https://s.click.aliexpress.com/e/_DlwXF69 9 | - Arduino UNO - https://s.click.aliexpress.com/e/_AXDw1h 10 | - Arduino breadboard prototyping shield - https://s.click.aliexpress.com/e/_ApbCwx 11 | - Arduino Library - https://github.com/gadjet/1602-OLED-Arduino-Library 12 | - I2C Scanner sketch - https://playground.arduino.cc/Main/I2cScanner/ 13 | 14 | My other videos with 16x2 character display: 15 | - Smooth Arduino 16x2 Gauge - https://youtu.be/cx9CoGqpsfg 16 | - Arduino Gauge in 11 Minutes - https://youtu.be/upE17NHrdPc 17 | - DIY Battery Indicator - https://youtu.be/Mq0WBPKGRew 18 | - 1 DISPLAY 3 SENSORS - https://youtu.be/lj_7UmM0EPY 19 | - small display - BIG DIGITS - https://youtu.be/SXSujfeN_QI 20 | 21 | ![THUMB_flat_oled_displays](https://user-images.githubusercontent.com/117754156/233292155-ab2b0920-7f6e-40bb-9446-06afad1cd234.jpg) 22 | 23 | 24 | 25 | Small animations: 26 | 27 | 28 | ![flat_oled_16x2_gauge_blue_green_SHORT](https://user-images.githubusercontent.com/117754156/233304668-3ec73beb-67a1-4eba-bf58-ab03eb7a3044.gif) 29 | 30 | ![flat_oled_16x2_gauge_red_white_SHORT](https://user-images.githubusercontent.com/117754156/233304729-8e08a146-a7c7-4a80-bb4f-bc1b86ad8e5f.gif) 31 | 32 | 33 | 34 | 35 | 36 | Screenshots from the video: 37 | 38 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_00_00;22)](https://user-images.githubusercontent.com/117754156/233304329-0482db79-45c3-4ad7-9f7b-0fd9a2992580.jpg) 39 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_00_04;03)](https://user-images.githubusercontent.com/117754156/233304341-1b8b95de-2da7-43e1-9f16-f242260bd7d5.jpg) 40 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_00_11;24)](https://user-images.githubusercontent.com/117754156/233304348-743ce39c-41e5-4c0d-abc1-bc3c8d09db1a.jpg) 41 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_00_17;23)](https://user-images.githubusercontent.com/117754156/233304350-45be2db5-edb8-4586-85f7-742eb2343831.jpg) 42 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_01_48;02)](https://user-images.githubusercontent.com/117754156/233304355-611a74b2-7213-49ca-a940-30e89f7a8f1c.jpg) 43 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_02_33;25)](https://user-images.githubusercontent.com/117754156/233304363-e038f688-030c-473d-80fa-9fab6005290d.jpg) 44 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_03_23;13)](https://user-images.githubusercontent.com/117754156/233304365-4d4ac76e-ceb8-4526-9dc6-054b077a6c71.jpg) 45 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_03_34;29)](https://user-images.githubusercontent.com/117754156/233304367-b1626668-02bd-4d38-872c-063fbcdc95b1.jpg) 46 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_03_46;00)](https://user-images.githubusercontent.com/117754156/233304371-63f53db7-b851-4eaf-9fd7-5b8553ea1b94.jpg) 47 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_04_23;13)](https://user-images.githubusercontent.com/117754156/233304373-e109660c-4ebf-4b44-9440-e231db652abd.jpg) 48 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_04_40;15)](https://user-images.githubusercontent.com/117754156/233304375-408c3013-fe32-48f0-a243-08caeef59fdb.jpg) 49 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_05_18;25)](https://user-images.githubusercontent.com/117754156/233304382-83a5252e-8bf0-4c50-8f9e-a2da6ae9e789.jpg) 50 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_05_33;13)](https://user-images.githubusercontent.com/117754156/233304386-6a8aee39-b22e-4570-a035-b7575950756b.jpg) 51 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_05_34;24)](https://user-images.githubusercontent.com/117754156/233304389-76fb536e-b5af-4066-a69d-c7749e91a5f3.jpg) 52 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_05_39;04)](https://user-images.githubusercontent.com/117754156/233304392-706120bd-4d72-4d96-9a56-b48890a5436a.jpg) 53 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_06_07;21)](https://user-images.githubusercontent.com/117754156/233304396-fa48089f-fa3e-450d-ae22-771041c6240c.jpg) 54 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_07_02;07)](https://user-images.githubusercontent.com/117754156/233304403-3ef680b4-ad56-4e75-95d5-267df2112542.jpg) 55 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_08_48;10)](https://user-images.githubusercontent.com/117754156/233304410-2d4c2100-4c9d-444a-af9f-296c034af9ff.jpg) 56 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_09_05;28)](https://user-images.githubusercontent.com/117754156/233304416-a90c8170-0478-4de5-a73c-c6bfae6d8c35.jpg) 57 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_09_20;14)](https://user-images.githubusercontent.com/117754156/233304422-f1b125d9-bc43-4e01-a2ea-171abcbb3fd2.jpg) 58 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_09_44;21)](https://user-images.githubusercontent.com/117754156/233304424-325598a7-6124-46a9-9cae-ad84a85cb8fa.jpg) 59 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_10_51;23)](https://user-images.githubusercontent.com/117754156/233304428-e8ecf0da-fb03-43ed-8269-b4cfd7d9688f.jpg) 60 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_11_31;26)](https://user-images.githubusercontent.com/117754156/233304432-2a3d9f26-ef37-4e79-9ea5-ab14f890acad.jpg) 61 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_11_48;06)](https://user-images.githubusercontent.com/117754156/233304435-284c8454-e80d-45d9-af77-4b51bdfb2b39.jpg) 62 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_14_49;22)](https://user-images.githubusercontent.com/117754156/233304440-79c0b11b-6d2b-43f8-bb4e-6354255df389.jpg) 63 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_15_44;27)](https://user-images.githubusercontent.com/117754156/233304446-05b1a773-09db-4009-8ff8-ad5863af202a.jpg) 64 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_15_52;08)](https://user-images.githubusercontent.com/117754156/233304451-85329ded-c5ab-4ceb-92ba-f6c2f25908ae.jpg) 65 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_16_04;13)](https://user-images.githubusercontent.com/117754156/233304455-c2929678-0c8d-4555-8f4a-f77288477dc6.jpg) 66 | ![CAMTASIA_lcd_smooth_gauge_no_special (Time 0_16_16;09)](https://user-images.githubusercontent.com/117754156/233304458-8398cad7-3456-4fbf-9ee7-ad2249e5ad45.jpg) 67 | -------------------------------------------------------------------------------- /arduino_1602_oled_gauge.ino: -------------------------------------------------------------------------------- 1 | // simple project using Arduino UNO and 16x2 OLED character display to display smooth filling gauges and animated digits 2 | // created by upir, 2023 3 | // youtube channel: https://www.youtube.com/upir_upir 4 | 5 | // FULL TUTORIAL: https://youtu.be/MEhJtpkjwnc 6 | // Source files: https://github.com/upiir/1602_oled_character_display 7 | 8 | // Links related to this project: 9 | // 16x2 OLED Character Display IIC - https://s.click.aliexpress.com/e/_DlwXF69 10 | // Arduino UNO - https://s.click.aliexpress.com/e/_AXDw1h 11 | // Arduino breadboard prototyping shield - https://s.click.aliexpress.com/e/_ApbCwx 12 | // Arduino Library - https://github.com/gadjet/1602-OLED-Arduino-Library 13 | // I2C Scanner sketch - https://playground.arduino.cc/Main/I2cScanner/ 14 | 15 | // My other videos with 16x2 character display: 16 | // Smooth Arduino 16x2 Gauge - https://youtu.be/cx9CoGqpsfg 17 | // Arduino Gauge in 11 Minutes - https://youtu.be/upE17NHrdPc 18 | // DIY Battery Indicator - https://youtu.be/Mq0WBPKGRew 19 | // 1 DISPLAY 3 SENSORS - https://youtu.be/lj_7UmM0EPY 20 | // small display - BIG DIGITS - https://youtu.be/SXSujfeN_QI 21 | 22 | 23 | 24 | #include "Wire.h" 25 | #include "OLedI2C.h" 26 | OLedI2C LCD; 27 | 28 | // this variable holds all the characters (both lines) that will be displays on the character display 29 | char line_final[56] = {144, 214, 214, 216, 32, 146, 214, 214, 215, 32, 32, 18, 49, 221, 130, 134, // first line 16 characters 30 | 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // required space between two lines 31 | 145, 214, 214, 217, 32, 147, 214, 214, 218, 32, 32, 19, 55, 221, 133, 128}; // second line 16 characters 32 | 33 | int num_value_max; // number to be displayed on the right side of the first line 34 | int num_value_min; // number to be displayed on the right side of the second line 35 | char num_value_max_buffer[5]; // helper buffer for converting integer to a c-style string 36 | char num_value_min_buffer[5]; // helper buffer for converting integer to a c-style string 37 | 38 | int gauge_value_note = 0; // gauge value for the gauge next to the note icon 39 | int gauge_value_doublenote = 25; // gauge value for the gauge next to the double note icon 40 | int gauge_value_bell = 50; // gauge value for the gauge next to the bell icon 41 | int gauge_value_heart = 75; // gauge value for the gauge next to the heart icon 42 | 43 | void setup() 44 | { 45 | Wire.begin(); // begin the I2C communication 46 | LCD.init(); // initialization for the LCD display 47 | } 48 | 49 | // custom function to draw a gauge 50 | void generate_gauge (int value, int value_max, int gauge_chars_length, int gauge_chars_start) { 51 | 52 | for (int i = 0; i < gauge_chars_length; i++) { // go over every single character in the gauge 53 | 54 | float min_char_value = (value_max / gauge_chars_length * 1.0) * i; // min. value for the currently drawn character 55 | float max_char_value = (value_max / gauge_chars_length * 1.0) * (i + 1); // max. value for the currently drawn character 56 | float one_step = (value_max / gauge_chars_length * 1.0) / 5.0; // one step = 1/5 of the character width (since the character is 5px wide) 57 | 58 | if (value >= max_char_value) {line_final[gauge_chars_start + i] = 214;} // fully filed character 59 | else if (value <= min_char_value) {line_final[gauge_chars_start + i] = 32;} // empty character 60 | else { // partially filled character 61 | if (value >= (min_char_value + one_step * 4)) {line_final[gauge_chars_start + i] = 215;} // 4 vertical lines filled 62 | else if (value >= (min_char_value + one_step * 3)) {line_final[gauge_chars_start + i] = 216;}// 3 vertical lines filled 63 | else if (value >= (min_char_value + one_step * 2)) {line_final[gauge_chars_start + i] = 217;}// 2 vertical lines filled 64 | else if (value >= (min_char_value + one_step * 1)) {line_final[gauge_chars_start + i] = 218;}// 1 vertical line filled 65 | } 66 | } 67 | } 68 | 69 | void loop() 70 | { 71 | 72 | // set the new values for the gauges 73 | gauge_value_note++; 74 | gauge_value_doublenote++; 75 | gauge_value_bell++; 76 | gauge_value_heart++; 77 | 78 | // restrict the gauge values between 0-100 79 | if (gauge_value_note > 100) {gauge_value_note = 0;} 80 | if (gauge_value_doublenote > 100) {gauge_value_doublenote = 0;} 81 | if (gauge_value_bell > 100) {gauge_value_bell = 0;} 82 | if (gauge_value_heart > 100) {gauge_value_heart = 0;} 83 | 84 | // generate four gauges based on the values above 85 | generate_gauge(gauge_value_note, 100, 4, 1); // generate_gauge( value, maximum value, number of characters, where to place the gauge in the main string) 86 | generate_gauge(gauge_value_doublenote, 100, 4, 41); 87 | generate_gauge(gauge_value_bell, 100, 4, 6); 88 | generate_gauge(gauge_value_heart, 100, 4, 46); 89 | 90 | // code below is for the digits/numbers displays on the right side of the display 91 | 92 | num_value_max++; // increment value by one 93 | if (num_value_max > 999) {num_value_max = 0;} // if the value is over 3 digits, set it back to zero 94 | num_value_min--; // decrement value by one 95 | if (num_value_min < 0) {num_value_min = 999;} // if the value is below zero, set it back to max. value (999) 96 | 97 | sprintf(num_value_max_buffer, "%03d", num_value_max); // convert the value into string with 3 leading zeros 98 | sprintf(num_value_min_buffer, "%03d", num_value_min); // convert the value into string with 3 leading zeros 99 | 100 | num_value_max_buffer[4] = 0; // set end of the string 101 | num_value_max_buffer[3] = num_value_max_buffer[2] + 80; // convert the digit to use small digit font 102 | num_value_max_buffer[2] = num_value_max_buffer[1] + 80; // convert the digit to use small digit font 103 | num_value_max_buffer[1] = 221; // special character for the decimal point 104 | 105 | num_value_min_buffer[4] = 0; // set end of the string 106 | num_value_min_buffer[3] = num_value_min_buffer[2] + 80; // convert the digit to use small digit font 107 | num_value_min_buffer[2] = num_value_min_buffer[1] + 80; // convert the digit to use small digit font 108 | num_value_min_buffer[1] = 221; // special character for the decimal point 109 | 110 | // manually copy the "max" value to the main string 111 | line_final[12] = num_value_max_buffer[0]; 112 | line_final[13] = num_value_max_buffer[1]; 113 | line_final[14] = num_value_max_buffer[2]; 114 | line_final[15] = num_value_max_buffer[3]; 115 | 116 | // manually copy the "min" value to the main string 117 | line_final[52] = num_value_min_buffer[0]; 118 | line_final[53] = num_value_min_buffer[1]; 119 | line_final[54] = num_value_min_buffer[2]; 120 | line_final[55] = num_value_min_buffer[3]; 121 | 122 | 123 | // draw the line_final to the LCD, in includes both lines 124 | LCD.sendString(line_final,0,0); 125 | 126 | } 127 | --------------------------------------------------------------------------------