Printing Percentages to LCD

Arduino is not my first choice for programming stuff, so I’m not an expert at it. I would like to print TemperatureVal to the LCD, and I would like it to not display in decimal form, and always displays without the extra zeros (i.e. 9%, 20%, 100%, so on).

Is this doable? Thanks!

#include <LiquidCrystal.h>

// Declare and Set Pin Names
int TemperatureADC = 0; // Analog Pin 0: Analog Voltage Controlled Temperature Probe
int LCDBacklight = 3; //Digital Pin 3: LCD Backlight Control, PWM Capable 
int FanPWM = 9;    // Digital Pin 9: Up To 120A PWM Controlled DC Fan\Motor Controlled By TI CSD18503KCS 40V N-Channel NexFET™ Power MOSFET

// Declare Variables
double TemperatureVal;    // Variable to Store the Value From the Analog Temperature Probe

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 1,4, 5, 6, 7);

void setup() {
//Set IO Pins
pinMode(3, OUTPUT); //Set OUTPUT Pin for LCD Backlight Control
pinMode(9, OUTPUT); //Set OUTPUT Pin for PWM Controlled DC Fan

//Turn On LCD Backlight
digitalWrite(3, HIGH);

// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.print("Loading...");
delay(2000);
lcd.clear(); // Clear Screen
}

void loop() {
  TemperatureVal = analogRead(TemperatureADC);            // Reads The Value Of The Temperature Probe (value between 0 and 1023; Value Range TBD) 
  TemperatureVal = map(TemperatureVal, 0, 1023, 0, 255);     // Scale It For Use With Values Between 0 And 255
  analogWrite(FanPWM, TemperatureVal); // Write Scaled Value To PWMFan Pin
  
 //Write Percentage\Value To LCD
  lcd.setCursor(0, 0);
  lcd.print((TemperatureVal/255)*100);
  delay(1);      
}

Yes this is possible. I think you want to have a look at the sprintf function.

what is it printing at the moment? 9.00?

if so just add ,0 after TemperatureVal

,0 doesn’t work after testing with serial print as the maths is still being done.

if you do the maths before displaying then it seems to work fine

#include <Wire.h>


#include <LiquidCrystal.h>

// Declare and Set Pin Names
int TemperatureADC = 0; // Analog Pin 0: Analog Voltage Controlled Temperature Probe
int LCDBacklight = 3; //Digital Pin 3: LCD Backlight Control, PWM Capable 
int FanPWM = 9;    // Digital Pin 9: Up To 120A PWM Controlled DC Fan\Motor Controlled By TI CSD18503KCS 40V N-Channel NexFET™ Power MOSFET
int temp;
// Declare Variables
double TemperatureVal;    // Variable to Store the Value From the Analog Temperature Probe

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 1,4, 5, 6, 7);

void setup() {
//Set IO Pins
Serial.begin(9600);
pinMode(3, OUTPUT); //Set OUTPUT Pin for LCD Backlight Control
pinMode(9, OUTPUT); //Set OUTPUT Pin for PWM Controlled DC Fan

//Turn On LCD Backlight
digitalWrite(3, HIGH);

// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.print("Loading...");
delay(2000);
lcd.clear(); // Clear Screen
}

void loop() {
  TemperatureVal = analogRead(TemperatureADC);            // Reads The Value Of The Temperature Probe (value between 0 and 1023; Value Range TBD) 
  TemperatureVal = map(TemperatureVal, 0, 1023, 0, 255);     // Scale It For Use With Values Between 0 And 255
  analogWrite(FanPWM, TemperatureVal); // Write Scaled Value To PWMFan Pin
  
 //Write Percentage\Value To LCD
  lcd.setCursor(0, 0);
  lcd.print((TemperatureVal/255)*100);
  temp = (TemperatureVal/255)*100;
  Serial.println (temp);
  delay(1);      
}

Here's what I did on that little section then:

  //Turn TemperatureVal Into A Percentage
  TempPercent = (TemperatureVal/255)*100;
  
  //Write Value To LCD
  lcd.setCursor(0, 0);
  lcd.print(TempPercent);
  delay(1);

However, when it reaches 100, and then I dial it back down, I have an extra 0 at the end now, so 0 reads as 000, 9 as 90, and so on. There's also a 0 before the single digits

You can either test to see if the number is smaller than 100 and if so print an extra space first, then test if it is less than 10 and if so print another extra space before finally printing your number.

Or you can read the first response to this thread and go look up the sprintf function. It can handle all the padding with spaces or zeroes and all that jazz for you.

dominicluciano:
Here’s what I did on that little section then:

  //Turn TemperatureVal Into A Percentage

TempPercent = (TemperatureVal/255)*100;
 
 //Write Value To LCD
 lcd.setCursor(0, 0);
 lcd.print(TempPercent);
 delay(1);




However, when it reaches 100, and then I dial it back down, I have an extra 0 at the end now, so 0 reads as 000, 9 as 90, and so on. There's also a 0 before the single digits

anything printed to a lcd screen stays there until its told to clear or it is over written. The trouble with over writing is that it leaves old numbers behind.

You can either print " " blank spaces over the old writing or use lcd.clear();

on a wired 2 line lcd clear shouldn’t cause it to flash to bad even when placed in the loop. On a 4 line you learn to only use clear when the data has changed. I would suggest monitoring TempPercent by moving it to prevTempPercent then seeing if it changes example posted

 if (TempPercent != prevTempPercent) {//if the data has changed clear the screen
    lcd.clear();
  }

  //Write Value To LCD
  lcd.setCursor(0, 0);
  lcd.print(TempPercent);
  delay(1);
prevTempPercent=TempPercent;
}

another way is

lcd.setCursor(0, 0);
if (TempPercent < 10) {
  lcd.print(" ");
}
if (TempPercent < 100) {
  lcd.print(" ");
}
lcd.print(TempPercent);
delay(1);
}
void loop() {
  TemperatureVal = analogRead(TemperatureADC);            // Reads The Value Of The Temperature Probe (value between 0 and 1023; Value Range TBD)
  TemperatureVal = map(TemperatureVal, 0, 1023, 0, 255);     // Scale It For Use With Values Between 0 And 255

Don't use map().

You might want this:

  TemperatureVal = (TemperatureVal * (255.0/1023.0));  // Scale It For Use With Values Between 0 And 255
  analogWrite(FanPWM, TemperatureVal); // Write Scaled Value To PWMFan Pin

//Write Percentage\Value To LCD   lcd.setCursor(0, 0);   lcd.print((TemperatureVal/255)*100);   delay(1);   
}

What does that give you?

I would have just declared TemperatureVal as an int, and done this:

void loop() {
  TemperatureVal = analogRead(TemperatureADC);  // Reads Temperature Probe (value between 0 and 1023)
  analogWrite(FanPWM, TemperatureVal / 4); // Scale to Range (0 to 255) and Write Scaled Value To PWMFan Pin

 //Write Percentage Value To LCD
  lcd.setCursor(0, 0);
  lcd.print((TemperatureVal-(TemperatureVal/43))/10); // scale to range (0 to 100)
  lcd.print("% ");
  delay(200); // no point killing the temperature sensor or the display     
}

Or, a less fancy way:

void loop() {
  TemperatureVal = analogRead(TemperatureADC);  // Reads Temperature Probe (value between 0 and 1023)
  analogWrite(FanPWM, (TemperatureVal*255L) / 1023); // Scale to Range (0 to 255) and Write Scaled Value To PWMFan Pin

 //Write Percentage Value To LCD
  lcd.setCursor(0, 0);
  lcd.print((int)((TemperatureVal*100L) / 1023)); // scale to range (0 to 100)
  lcd.print("% ");
  delay(200); // no point killing the temperature sensor or the display     
}

gpop1, that's probably what I'm going to do is just make it check to see if the previous data matches the new data. I need it to refresh pretty fast, and so when I told it to basically clear the LCD every cycle, it was flashing visibly. So the newdata = olddata is a good option.

odometer, this is really rough code I pulled from another project (which was based on a sample project actually). But I like your simplification. Thanks for the advice :)