Printing unsigned long integer

I am trying to get percentage printed on LCD but getting wrong output

unsigned long batt_perc;
unsigned int batt_cap;
unsigned int aH;
 
batt_cap = 18000;
aH = 17450;

batt_perc = (unsigned long)((aH * 100) / batt_cap);
lcd.setCursor(0.0);
lcd.print(batt_perc);

It prints 1 instead of 96.
Whats wrong with the formula?

aH * 100 = 1745000 and thus overflows as an unsigned int has a limited range (0..65535)

Make it an unsigned long will probably make it look better.

Force the divide to be done using 32 bit integers as follows:
batt_perc = (aH * 100UL) / batt_cap;

1 Like

or use

batt_perc = (100ul * aH) / batt_cap;

the 100ul will promote the whole math expression to be evaluated using unsigned long integrals

void setup() {
  unsigned long batt_perc;
  unsigned int batt_cap;
  unsigned int aH;

  Serial.begin(115200);
  batt_cap = 18000;
  aH = 17450;

  batt_perc =  100ul * aH / batt_cap;
  Serial.print(batt_perc);
}

void loop() {}

1 Like

Are these two equivalent? That is to say, is the order effecting the result? (your replies were nearly simultaneous)

Thats the reason I have used the expression

(unsigned long)((aH*100)/batt_cap);

This was how it was done in PIC programing when the whole expression needed to be executed as long. This expression works in my PIC program. I am converting the pic program to Arduino.

I think both are equivalent. I have tried the expression by user @jremington and it works. Will try the other and post the results.

Well, I dont believe the numbers - the battery would need to be rather large.
A typical alkaline or NiMH battery in the standard “AA” size has about 2000 to 3000 mAh (or 2 to 3 Ah)

yes they are. (100ul * aH) and (aH * 100UL) are evaluated in the same way as an unsigned long multiplication.

I just moved the constant in front to make it clearer (in my eyes) that we wanted to perform an unsigned long calculation

side note: I prefer non capital letters for ul but because lower-case L can look like numeric 1 in some fonts, some developers prefer to use upper-case literals. Others use lower case suffixes except for L so you could see uL or uLL

Arduino language is based on C. If you were programming PIC in C then the same rules and problems apply, and your solution would not have worked on PIC either... Or at least, not guaranteed to work.

The fact that you ran into this problem at all tells us that you are using an 8-bit Arduino like Uno, Mega etc. If you had used a 32-bit Arduino like Due, Zero etc then you would not have encountered the problem.

On 8-bit Arduino, (unsigned) int is 16 bits and (unsigned) long is 32 bits. On 32-bit arduino, int and long are both 32 bits.

Perhaps the PIC you were programming was a 32-bit PIC? Or maybe on 8-bit PIC, int is 32 bits?

1 Like

I am making this program for my ebike battery of 18ah, that's how the figure is 18000. I am using mA so that I can display "18.000aH"

Why do you need an arduino and a display and a PC to calculate1745/18 = 96.944?

The result is incorrect - not because the number is wrong, but because the precision is wrong. You should not (with a VERY few exceptions) expect more than three figure accuracy for any REAL battery.

So sensibly you can show two values - eg 95% and 18Ah or estimated range etc. on your display.

Previously I had written the program for PIC16F886. But the ROM is full with no place to add more code. So I am converting that code to Arduino. I am making a battery coulometer. So I need the LCD to display the voltage of battery, current consumption of the motor,power calculation etc. the current read would be upto 18000mA but displayed as 18.00A. the percentage in 2 digits, eg. 95%. Accuracy in battery percentage not that important. This code has worked well as I have already tried it, first on proteus simulator and then real hardware. I am trying to add speedometer/ odometer to the code thats where I am falling short of ROM space on the PIC. Coding in Arduino is more kind of universal. Code written for Nano can be used in Uno and Mega also.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.