Help understanding LCD progress bar code please

Please help me understand how the progress bar  increments and de-increments according to the analog input (a potentiometer on pin A0). The code is from https://www.electronicsblog.net/. Don't understand how the if, for, while, case, break  etc are used to make the progress bar work. I understand the theory of the functions and statements etc but don't understand how it works together to manipulate the progress bar. Note the code change after case 1. Need a line by line explanation. Please help. Many thanks.

//All code

//[code lang=”arduino”]

//https://www.electronicsblog.net/
//Arduino LCD horizontal progress bar using custom characters

#include <LiquidCrystal.h>

#define lenght 16.0

double percent=100.0;
unsigned char b;
unsigned int peace;

// custom charaters

// LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7, 8);// change to this for my LCD wiring scheme
byte p1[8] = {
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10,
0x10};

byte p2[8] = {
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18};

byte p3[8] = {
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C,
0x1C};

byte p4[8] = {
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E,
0x1E};

byte p5[8] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F};

void setup() {

delay(100);
lcd.createChar(0, p1);
lcd.createChar(1, p2);
lcd.createChar(2, p3);
lcd.createChar(3, p4);
lcd.createChar(4, p5);

lcd.begin(16, 2);

}

void loop()
{

lcd.setCursor(0, 0);

//ADC conversion

unsigned int value = analogRead(0);

percent = value/1024.0*100.0;

lcd.print(value);

lcd.print(" – ");

lcd.print(percent);
lcd.print(" % ");

lcd.setCursor(0,1);

double a=lenght/100*percent;

// drawing black rectangles on LCD

if (a>=1) {

for (int i=1;i<a;i++) {

lcd.write(4);

b=i;
}

a=a-b;

}

peace=a*5;

// drawing charater’s colums

switch (peace) {

case 0:

break;

case 1:
//lcd.write(0);
lcd.print((char)0); // This change was made according to instructions at end of sketch

break;

case 2:
lcd.write(1);
break;

case 3:
lcd.write(2);
break;

case 4:
lcd.write(3);
break;

}

//clearing line
for (int i =0;i<(lenght-b);i++) {

lcd.print(" ");
}

;
}

//

//Update for Arduino IDE 1.0 and newer version users

//lcd.write(0); leads to “call of overloaded ‘write(int)’ is ambiguous” //error, so please replace it to lcd.print((char)0);

//This entry was posted in Arduino and tagged bar, Hitachi HD44780, LCD, progress on February 8, //2011.

ElectronicsBlog_LCD.ino (1.83 KB)

What part of that mess you posted don't you understand?

An analog pin is read. The reading is converted to a %age. The %age is multiplied by the length of the area that the bar is to be drawn in. The portion that is then supposed to be filled is filled. Any part that is filled, from last time, that is not supposed to be is erased.

Sorry about the messy code. I'm new to Arduino and the site. Just don't understand the code beginning with if (a>=1) and everything below. Don't understand how it produces the bar. I understand the map part but don't get how the code after that (if (a>=1) works to create the progress bar. It works good and the bar follows the potentiometer on A0 back and fourth fine but I don't understand the code. It seems like the length of the bar should be 5*16=80 for each column of the 16 X 2 LCD. Not 100. The goal is to display a LCD bar that represents the antenna direction (pan only for now). The feedback pot is located on the pan/tilt motor assembly. It works but don't understand the code. Please help. Thanks.

It seems like the length of the bar should be 5*16=80 for each column of the 16 X 2 LCD.

The length of the bar is set to 16 (though you could change that). There is some percentage of the bar to fill. That translates into some full squares and one partial square. The special characters are the partial (1/5, 2/5, etc.) squares. In that code, a is the number of squares to fill.

Still don't understand. Yes the custom characters define each column but I don't understand how the rest of it works. Everything after if (a>=1) {. Also why does write(4) come before write(1), write(2), write(3)?

You need to walk through the code yourself. For example, if analogRead() is midscale, it returns the value 512, so value = 512. If value is 512, then percent = 50. Then:

a = 16/100 * 50 = .16 * 50 = 8 // I would write this as: a = (length / 100) * 50;

This means 8 of your 16 character display should show a “solid block” on the LCD display. The for loop:

for (int i=1;i<a;i++) {

lcd.write(4);

b=i;
}

displays those 8 blocks. The remaining part of the code is used to display “fractional blocks” or “peace” in the last character displayed, if needed. The statements

a=a-b;

}

peace=a*5;  // This would make more sense if spelled correctly, "piece"

determines which piece of the piece block to display. You need to follow the rule: If-you-need-to-eat-an-elephant-start-one-bite-at-a-time. You couldn’t see the trees for the forest.

Its beginning to make sense! So when a =8 the for statement causes write(4) to send custom character (4) eight times to the lcd. Since that character is only the fifth column of a block, how can it write 8 filled blocks? It seems like it would only write the fifth column of in each of the eight blocks.

Its beginning to make sense! So when a =8 the for statement causes write(4) to send custom character (4) eight times to the lcd. Since that character is only the fifth column of a block, how can it write 8 filled blocks?

It looks to me like you should test that assertion. It looks to me like the write(4) writes the character defined by the array p5, which looks to me like it turns every pixel in the 5 x 8 block on. So, it looks to me like write(4) writes a filled block. It looks like write(3) writes a block that is 80 % full, while (2), (1), and (0) write blocks that are 60%, 40% and 20% full, respectively.

Thank you very very much! Its making sense finally! Everything works like it should. Thank you again. Somehow I thought the characters consisted of a single vertical line whose position moves left to right until the block is full (five times). Now I get it - 20%,(one vert line) 40% (two vert lines) etc.