how do I get rid of unwanted blocks on my progression bar on the LCD?

Status
Not open for further replies.

Thread Starter

HappyC4mper

Joined Oct 13, 2017
71
Hey guys,
I'm currently in the process of trying to make a digital voltage meter(0-3.3V). However, I came across this problem. When increasing the voltage (using a potometer ), the progress bar is fairly proportional to the voltage. But, when decreasing the voltage, it tends to leave unwanted blocks. Technically, 1 block is 0.2V (3.3/16). Here is a video demonstrating my problem.
https://streamable.com/t5i0p

Here is my conversion code
Code:
void realVoltage ()

{
    unsigned short ADC_DATA;
    ADC_DATA=read_adc();    //reads what ever value is and put into ADC DATA
   
    cmdLCD(LCD_LINE1);
  float voltage = (ADC_DATA*(3.3/4096));   //conversion adc to voltage conversion
    printf( "Volts = %.3f", voltage);        //printing to lcd
   
    }
And here is my Progression bar code:
Code:
void ASignal (float q)   //analogue signal. (q is adcvalue)
{
float divider = 255;   
int sum = q/divider;      

cmdLCD(LCD_LINE2);
   
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);  
}
I tried following this blog which one of the guys from here linked me : https://www.electronicsblog.net/arduino-lcd-horizontal-progress-bar-using-custom-characters/
However, since i'm not using arduino. I couldn't really follow it well.
 

Raymond Genovese

Joined Mar 5, 2016
1,653
Your bar works fine when you are increasing the voltage but fails when decreasing the voltage. I think that the main reason for that is your for-next loop.

C:
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);
}
The highest voltage (3.3V) will be represented by 16 character spaces (int 4096/255). 1.65V will be represented by 8 character spaces (int 2048/255.) If you go from 3.3V to 1.65 volts, run that loop in your head and you will see that you will not touch the character positions above 1.65V because you have left the loop and left whatever was displayed in those character spaces previously.

In fact, your loop is only going to print a single block in all cases and will print a space at all character positions representing voltages below the current reading.

This is easily fixed, but add these line before the start of the loop, to see what I am talking about.

C:
cmdLCD(LCD_LINE2); // presumably sets the cursor at line 2 row 1
putLCD('                ');    //  set the entire row to spaces
cmdLCD(LCD_LINE2); // reset set the cursor
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);
}
This is only to illustrate what I think your code is doing. You can redo the loop in a number of ways to make it cleaner and faster. [Also, think about how/why you are converting between int and float - but that is a separate issue.]

For example, try something like this:
C:
for(int i = 0; i< 16 ; i++)
if(i<=sum)
{
putLCD(0xFF);
}
else putLCD(' ');
}
 

Thread Starter

HappyC4mper

Joined Oct 13, 2017
71
Your bar works fine when you are increasing the voltage but fails when decreasing the voltage. I think that the main reason for that is your for-next loop.

C:
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);
}
The highest voltage (3.3V) will be represented by 16 character spaces (int 4096/255). 1.65V will be represented by 8 character spaces (int 2048/255.) If you go from 3.3V to 1.65 volts, run that loop in your head and you will see that you will not touch the character positions above 1.65V because you have left the loop and left whatever was displayed in those character spaces previously.

In fact, your loop is only going to print a single block in all cases and will print a space at all character positions representing voltages below the current reading.

This is easily fixed, but add these line before the start of the loop, to see what I am talking about.

C:
cmdLCD(LCD_LINE2); // presumably sets the cursor at line 2 row 1
putLCD('                ');    //  set the entire row to spaces
cmdLCD(LCD_LINE2); // reset set the cursor
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);
}
This is only to illustrate what I think your code is doing. You can redo the loop in a number of ways to make it cleaner and faster. [Also, think about how/why you are converting between int and float - but that is a separate issue.]

For example, try something like this:
C:
for(int i = 0; i< 16 ; i++)
if(i<=sum)
{
putLCD(0xFF);
}
else putLCD(' ');
}
Thanks soo Much this worked and fixed my problem!! Do you mind explaining a bit what you changed so I can understand further?
I tried the code you showed me
Code:
cmdLCD(LCD_LINE2); // presumably sets the cursor at line 2 row 1
putLCD('                ');    //  set the entire row to spaces
cmdLCD(LCD_LINE2); // reset set the cursor
for(int i = 0; i< sum + 1 ; i++)
if(i==sum)
{
putLCD(' ');
}
else putLCD(0xFF);
}
which basically shows me the same as the video i posted. Not really too sure what you meant.
 

Raymond Genovese

Joined Mar 5, 2016
1,653
I am glad that you got it working. In the first example, I was trying to show the effect of clearing the entire progress bar before printing the block. Not sure why that did not work but no matter.

Remember, when you use cmdLCD(LCD_LINE2) it looks like you are simply setting the cursor location (to the first position on the second line). Subsequently, every time you do a putLCD('x') you transfer the character code to memory and increment the cursor by 1. To get a complete progress bar, you have to account for all 16 memory locations (print areas) because you don't know what was in those memory locations after the previous reading. Changing the loop to for (int i = 0; i< 16 ; i++) does that. Again, there are lots of ways to approach this but if you are happy with it this way - good deal.
 

Thread Starter

HappyC4mper

Joined Oct 13, 2017
71
I am glad that you got it working. In the first example, I was trying to show the effect of clearing the entire progress bar before printing the block. Not sure why that did not work but no matter.

Remember, when you use cmdLCD(LCD_LINE2) it looks like you are simply setting the cursor location (to the first position on the second line). Subsequently, every time you do a putLCD('x') you transfer the character code to memory and increment the cursor by 1. To get a complete progress bar, you have to account for all 16 memory locations (print areas) because you don't know what was in those memory locations after the previous reading. Changing the loop to for (int i = 0; i< 16 ; i++) does that. Again, there are lots of ways to approach this but if you are happy with it this way - good deal.
Wow, thanks for the information, it made soo much more sense! :) appreciate it!


Actually out of curiosity, what 1 other approach would you do? If its too much hassle dont worry about it :)
 
Status
Not open for further replies.
Top