Advertisement
drkillaz

Arduino Test

Jan 28th, 2023
756
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 7.89 KB | Source Code | 0 0
  1. // simple project using Arduino UNO and 16x2 character display to display smooth gauge,
  2. // created by upir, 2022
  3. // youtube channel: https://www.youtube.com/upir_upir
  4.  
  5. // FULL TUTORIAL: https://youtu.be/ZzIGHiHObYw
  6. // GAUGE IN 11 MINUTES TUTORIAL: https://youtu.be/upE17NHrdPc
  7.  
  8. // Links related to this project:
  9. // Arduino UNO - https://s.click.aliexpress.com/e/_AXDw1h
  10. // Arduino breadboard prototyping shield - https://s.click.aliexpress.com/e/_ApbCwx
  11. // 16x2 displays with IIC - https://s.click.aliexpress.com/e/_9Hl3JV
  12. // 16x2 display with RGB backlight - https://s.click.aliexpress.com/e/_9wgpeb
  13. // original sketch from YWROBOT - https://wokwi.com/arduino/libraries/LiquidCrystal_I2C/HelloWorld
  14. // character creator - https://tusindfryd.github.io/screenduino/
  15. // another character creator - https://maxpromer.github.io/LCD-Character-Creator/
  16. // sprintf explanation - https://www.programmingelectronics.com/sprintf-arduino/
  17. // custom characters simplest project - https://wokwi.com/projects/294395602645549578
  18. // Arduino I2C scanner - https://playground.arduino.cc/Main/I2cScanner/
  19. // 16x2 available characters - https://docs.wokwi.com/parts/wokwi-lcd1602#font
  20. // Bitwise Operators in GIFs - https://blog.wokwi.com/bitwise-operators-in-gifs/
  21. // Bitwise operators Arduino documentation - https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitshiftleft/
  22.  
  23.  
  24.  
  25. #include <LiquidCrystal_I2C.h>     // if you don´t have I2C version of the display, use LiquidCrystal.h library instead
  26.  
  27. LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  28. //LiquidCrystal_I2C lcd(0x3f,16,2);    // set the LCD address to 0x3f for a 16 chars and 2 line display
  29. // if you don´t know the I2C address of the display, use I2C scanner first (https://playground.arduino.cc/Main/I2cScanner/)
  30.  
  31. // define custom characters/arrays - every character is 5x8 "pixels"
  32. byte gauge_empty[8] =  {B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111};    // empty middle piece
  33. byte gauge_fill_1[8] = {B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111};    // filled gauge - 1 column
  34. byte gauge_fill_2[8] = {B11111, B11000, B11000, B11000, B11000, B11000, B11000, B11111};    // filled gauge - 2 columns
  35. byte gauge_fill_3[8] = {B11111, B11100, B11100, B11100, B11100, B11100, B11100, B11111};    // filled gauge - 3 columns
  36. byte gauge_fill_4[8] = {B11111, B11110, B11110, B11110, B11110, B11110, B11110, B11111};    // filled gauge - 4 columns
  37. byte gauge_fill_5[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111};    // filled gauge - 5 columns
  38. byte gauge_left[8] =   {B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111};    // left part of gauge - empty
  39. byte gauge_right[8] =  {B11111, B00001, B00001, B00001, B00001, B00001, B00001, B11111};    // right part of gauge - empty
  40.  
  41. byte gauge_mask_left[8] = {B01111, B11111, B11111, B11111, B11111, B11111, B11111, B01111};  // mask for rounded corners for leftmost character
  42. byte gauge_mask_right[8] = {B11110, B11111, B11111, B11111, B11111, B11111, B11111, B11110}; // mask for rounded corners for rightmost character
  43.  
  44. byte warning_icon[8] = {B00100, B00100, B01110, B01010, B11011, B11111, B11011, B11111};     // warning icon - just because we still have one custom character left
  45.  
  46. byte gauge_left_dynamic[8];   // left part of gauge dynamic - will be set in the loop function
  47. byte gauge_right_dynamic[8];  // right part of gauge dynamic - will be set in the loop function
  48.  
  49. int cpu_gauge = 0;       // value for the CPU gauge
  50. char buffer[10];         // helper buffer to store C-style strings (generated with sprintf function)
  51. int move_offset = 0;     // used to shift bits for the custom characters
  52.  
  53. const int gauge_size_chars = 16;       // width of the gauge in number of characters
  54. char gauge_string[gauge_size_chars+1]; // string that will include all the gauge character to be printed
  55.  
  56. void setup()
  57. {
  58.   lcd.init();                       // initialize the 16x2 lcd module
  59.   lcd.createChar(7, gauge_empty);   // middle empty gauge
  60.   lcd.createChar(1, gauge_fill_1);  // filled gauge - 1 column
  61.   lcd.createChar(2, gauge_fill_2);  // filled gauge - 2 columns
  62.   lcd.createChar(3, gauge_fill_3);  // filled gauge - 3 columns
  63.   lcd.createChar(4, gauge_fill_4);  // filled gauge - 4 columns  
  64.   lcd.createChar(0, warning_icon); // warning icon - just because we have one more custom character that we could use  
  65.   lcd.backlight();                  // enable backlight for the LCD module
  66. }
  67.  
  68.  
  69. void loop()
  70. {
  71.   float units_per_pixel = (gauge_size_chars*5.0)/100.0;        //  every character is 5px wide, we want to count from 0-100
  72.   int value_in_pixels = round(cpu_gauge * units_per_pixel);    // cpu_gauge value converted to pixel width
  73.  
  74.   int tip_position = 0;      // 0= not set, 1=tip in first char, 2=tip in middle, 3=tip in last char
  75.  
  76.   if (value_in_pixels < 5) {tip_position = 1;}                            // tip is inside the first character
  77.   else if (value_in_pixels > gauge_size_chars*5.0-5) {tip_position = 3;}  // tip is inside the last character
  78.   else {tip_position = 2;}                                                // tip is somewhere in the middle
  79.  
  80.   move_offset = 4 - ((value_in_pixels-1) % 5);      // value for offseting the pixels for the smooth filling
  81.  
  82.   for (int i=0; i<8; i++) {   // dynamically create left part of the gauge
  83.      if (tip_position == 1) {gauge_left_dynamic[i] = (gauge_fill_5[i] << move_offset) | gauge_left[i];}  // tip on the first character
  84.      else {gauge_left_dynamic[i] = gauge_fill_5[i];}                                                     // tip not on the first character
  85.  
  86.      gauge_left_dynamic[i] = gauge_left_dynamic[i] & gauge_mask_left[i];                                 // apply mask for rounded corners
  87.   }
  88.  
  89.   for (int i=0; i<8; i++) {   // dynamically create right part of the gauge
  90.      if (tip_position == 3) {gauge_right_dynamic[i] = (gauge_fill_5[i] << move_offset) | gauge_right[i];}  // tip on the last character
  91.      else {gauge_right_dynamic[i] = gauge_right[i];}                                                       // tip not on the last character
  92.  
  93.      gauge_right_dynamic[i] = gauge_right_dynamic[i] & gauge_mask_right[i];                                // apply mask for rounded corners
  94.   }  
  95.  
  96.   lcd.createChar(5, gauge_left_dynamic);     // create custom character for the left part of the gauge
  97.   lcd.createChar(6, gauge_right_dynamic);    // create custom character for the right part of the gauge
  98.  
  99.   for (int i=0; i<gauge_size_chars; i++) {  // set all the characters for the gauge
  100.       if (i==0) {gauge_string[i] = byte(5);}                        // first character = custom left piece
  101.       else if (i==gauge_size_chars-1) {gauge_string[i] = byte(6);}  // last character = custom right piece
  102.       else {                                                        // character in the middle, could be empty, tip or fill
  103.          if (value_in_pixels <= i*5) {gauge_string[i] = byte(7);}   // empty character
  104.          else if (value_in_pixels > i*5 && value_in_pixels < (i+1)*5) {gauge_string[i] = byte(5-move_offset);} // tip
  105.          else {gauge_string[i] = byte(255);}                        // filled character
  106.       }
  107.   }
  108.  
  109.   // gauge drawing
  110.   lcd.setCursor(0,0);                         // move cursor to top left
  111.   sprintf(buffer, "CPU:%3d%% ", cpu_gauge);    // set a string as CPU: XX%, with the number always taking at least 3 character
  112.   lcd.print(buffer);                          // print the string on the display
  113.   lcd.write(byte(0));                         // print warning character  
  114.  
  115.   lcd.setCursor(0,1);              // move the cursor to the next line
  116.   lcd.print(gauge_string);         // display the gauge
  117.  
  118.  
  119.  
  120.   // increase the CPU value, set between 0-100
  121.   cpu_gauge = cpu_gauge +1;
  122.   if (cpu_gauge > 100) {cpu_gauge = 0;}
  123.  
  124.   delay(100);  // wait for a while - 100ms = update the screen 10x in a second
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement