Cant get the decimal place on a lcd.

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
mazur50
Posts: 68
Joined: Thu Dec 04, 2008 5:19 am

Cant get the decimal place on a lcd.

Post by mazur50 » Sat Dec 04, 2010 3:35 pm

The problem I am having is that the LCD is displaying 45.45 when it should be displaying 45.11

Thanks
Mike

Code: Select all

Device = 18F1220                             // Setup the device/clock information
Clock = 8


// some LCD options...
#option LCD_DATA = PORTB.4
#option LCD_RS = PORTB.2
#option LCD_EN = PORTB.3

// uses LCD and AD libraries...
Include "biming_io.bas"
Include "LCD.bas"
Include "convert.bas"
Include "ADC.bas"

Dim 
    biming_Pot As PORTA.0                     // Declare the biming Pot pin
Dim Timing As Word

    
Function Get_Sample() As float           // Function to grab the ADC sample
 
    result = (410 - 256)* 300 / 1024

End Function

ADCON1 = %11101110


 
//Start Program..

 

    biming = Get_Sample
        LCD.MoveCursor (1,1)
        LCD.Write(" ", DecToStr(biming), ".", dectostr(biming, 2), " ", "Degees")
       
  
End Select
End

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Re: Cant get the decimal place on a lcd.

Post by gramo » Sat Dec 04, 2010 10:21 pm

Code: Select all

LCD.Write(" ", DecToStr(biming), ".", dectostr(biming, 2), " ", "Degees")
I'm going to have a guess and say that the variable "biming" is not of type float, and that is why DecToStr(biming) only displays "45".

dectostr(biming, 2) will pad the string with zeros, two in this case - and also limit the number of characters to 2 in the numeric string.

The result is "45.45"


NB: Looks like a very easy task that is being performed, yet you are wasting a lot of resources by using floats.. Perhaps its worth scaling your math with LongWords?
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

mazur50
Posts: 68
Joined: Thu Dec 04, 2008 5:19 am

Post by mazur50 » Sun Dec 05, 2010 1:38 am

So just dim the variable as a long word.

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Post by gramo » Sun Dec 05, 2010 7:23 am

mazur50 wrote:So just dim the variable as a long word.
So long as you use the appropriate scaling, or else decimal places will be truncated.
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

Jon Chandler
Registered User
Registered User
Posts: 185
Joined: Mon Mar 10, 2008 8:20 am
Location: Seattle, WA USA
Contact:

Post by Jon Chandler » Sun Dec 05, 2010 8:53 am

Bytes, words, long words, etc, are INTEGERS - whole numbers with no fractional part. They cannot have a decimal point.

To achieve one decimal place, the calculations have to be made so that the result is the actual value multiplied by 10, and you'll have to do some calculations to show the correct value.

For your calculation, you might do this

Code: Select all

change this:

result = (410 - 256)* 300 / 1024 

to this:

result = (410 - 256)* 3000 / 1024 
Then the result is the actual value x 10

The order of the math operations is important in integer math - remember any fractional value is lost.

The equation above will work fine where all the multiplications are done first. A small change will make the calculation fail:

result = (410 - 256)* 3000 / 1024 = 462000/1024 = 451 (45.1 actual value)

result = (410 - 256)* (3000 / 1024) = 154 * 2 = 308

3000/1024 = 2 in integer math since the fractional part is lost.
result = (410 - 256)* (3000 / 1024)

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Dec 05, 2010 11:56 am

All good points so far (and that's how I would do it), but if you want to use floats, you might want to make a few changes...

The function 'Get_Sample()' is going to return the float value 45.00, since as written it does the math as all integer until it assigns the result value, where it then converts it to a float. To do the math using floating point, you've got to have a float somewhere in the calculation so the compiler knows you want to use floating point math.

Code: Select all

Function Get_Sample() As float           // Function to grab the ADC sample

    result = (410 - 256)* 300.0 / 1024.0

End Function
Now, 'Get_Sample()' will return 45.1171875

If you declare 'biming' as a float, you can use a single call to convert.FloatToStr() to print the result

Code: Select all

dim biming as float

biming = Get_Sample()

LCD.Write(" ", FloatToStr(biming, 2), " Degrees")

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Post by gramo » Sun Dec 05, 2010 12:11 pm

Jerry Messina wrote:If you declare 'biming' as a float, you can use a single call to convert.FloatToStr() to print the result
Only if you have a Image beside your name :wink:
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Dec 05, 2010 12:23 pm

If those features aren't supported in the free version, there's a very simple solution to that problem... support the developer, buy a copy, and stop freeloading after two years.

Jon Chandler
Registered User
Registered User
Posts: 185
Joined: Mon Mar 10, 2008 8:20 am
Location: Seattle, WA USA
Contact:

Post by Jon Chandler » Sun Dec 05, 2010 4:23 pm

Jerry Messina wrote:If those features aren't supported in the free version, there's a very simple solution to that problem... support the developer, buy a copy, and stop freeloading after two years.
Very true! If you want Swordfish to improve, buy a copy and give Davis some incentive for all the effort he puts in!

be80be
Registered User
Registered User
Posts: 90
Joined: Mon Feb 23, 2009 2:15 am
Location: tn

Post by be80be » Sun Dec 05, 2010 4:38 pm

gramo wrote:
Jerry Messina wrote:If you declare 'biming' as a float, you can use a single call to convert.FloatToStr() to print the result
Only if you have a Image beside your name :wink:
I own swordfish but my profile didn't change

mazur50
Posts: 68
Joined: Thu Dec 04, 2008 5:19 am

Post by mazur50 » Sun Dec 05, 2010 5:50 pm

So that will only work in the non free version.

mazur50
Posts: 68
Joined: Thu Dec 04, 2008 5:19 am

Post by mazur50 » Sun Dec 05, 2010 6:08 pm

Jon Chandler wrote:Bytes, words, long words, etc, are INTEGERS - whole numbers with no fractional part. They cannot have a decimal point.

To achieve one decimal place, the calculations have to be made so that the result is the actual value multiplied by 10, and you'll have to do some calculations to show the correct value.

For your calculation, you might do this

Code: Select all

change this:

result = (410 - 256)* 300 / 1024 

to this:

result = (410 - 256)* 3000 / 1024 
Then the result is the actual value x 10

The order of the math operations is important in integer math - remember any fractional value is lost.

The equation above will work fine where all the multiplications are done first. A small change will make the calculation fail:

result = (410 - 256)* 3000 / 1024 = 462000/1024 = 451 (45.1 actual value)

result = (410 - 256)* (3000 / 1024) = 154 * 2 = 308

3000/1024 = 2 in integer math since the fractional part is lost.
result = (410 - 256)* (3000 / 1024)
I do get 451 thanks for all the help.

But how to I get it to display as 4.51 and not 451.51

Code: Select all

LCD.Write(decToStr(biming), ".", DecToStr(biming, 2), " "

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Mon Dec 06, 2010 10:24 am

Mike,

If your number is a fixed point scaled representation, you'll have to do a little work to separate out the whole number part from the fractional part.
Here's an example

Code: Select all

include "math.bas"
include "convert.bas"

// fixed point number is scaled to hundreths (2 digits)
const scale_factor = 100

dim tmp as integer		// use appropriate type here

// get whole number part
tmp = biming / scale_factor
lcd.write(DecToStr(tmp), ".")

// get fractional part, remove any sign
tmp = abs(biming - (tmp * scale_factor))
lcd.write(DecToStr(tmp, 2))


Post Reply