Entire Forum This board This topic Members Entire Site
 Pages: [1]
 Author Topic: help with converting integer16 to float32 in CCS-C  (Read 2394 times) 0 Members and 1 Guest are viewing this topic.
sphinx
Hero Member

Offline

Posts: 682

Thank You
-Given: 473

 « on: August 09, 2019, 05:40:24 05:40 »

I am trying to display a calculated value on an lcd, but i can not get iti to work.

I am using it with pic16f677 and usiing a 10 bit adc value. I can get that value
on lcd as 0-1023, but when i try to get it converted to float32 i get weird values.

So i need to convert that 10-bit integer to float32 but the ways i tried it with
does not work, anyone that can help with this?

/sphinx
 Logged

the more you learn, the lesser you get to understand. is it then good know alot but not understand what you know or.......
Manuel
Active Member

Offline

Posts: 209

Thank You
-Given: 340

 « Reply #1 on: August 09, 2019, 07:36:37 07:36 »

do you mean something like this ?

float a;
unsigned int b;

.......
b=10;
a=(float) b;
.....
or
.....
b=10;
a=b * 1.0;
.....I think that then you covert the value to e displayed....maybe the problem is there...

or
.........
float percentage;
// ...
percentage = (float)number/total * 100;
// percentage = 100.0f*number/total;

or
...........
int total=0, number=0;
float percentage=0.0;

percentage=(number/total)*100;
printf("%.2f",percentage); // use the 'right' printf for your necessity...

update me.

take care,
X!

 « Last Edit: August 09, 2019, 07:40:06 07:40 by Manuel » Logged

-> An Apple a Day does not Let U become a Macintosh!
sphinx
Hero Member

Offline

Posts: 682

Thank You
-Given: 473

 « Reply #2 on: August 09, 2019, 08:50:08 08:50 »

Hi and thandks, i will have a look at it later.
The code i am using is, i have taken out the code that was commented out
for testing purposes.
The software i am using is CCS PIC-C 5.083

#include <16f677.h>
#fuses INTRC_IO,NOMCLR,NOWDT,NOPROTECT
#use delay(internal=8M)

#define LCD_ENABLE_PIN  PIN_A0
#define LCD_RS_PIN      PIN_A1
#define LCD_RW_PIN      PIN_A2
#define LCD_DATA4       PIN_B4
#define LCD_DATA5       PIN_B5
#define LCD_DATA6       PIN_B6
#define LCD_DATA7       PIN_B7

#include <LCD.C>

float32 flo;

void main()
{

lcd_init();

While(true)
{

set_adc_channel(7);                                             // Sets a/d channel to number 7
delay_ms(10);                                                    // dealy 10ms
//      flo = adcvalue * 0.0012219;
lcd_gotoxy(1,1);
//      lcd_gotoxy(10,2);
printf(lcd_putc,"%9.0w A out", flo);
//      printf(lcd_putc,"%1.3w A out", flo);
}
}

/sphinx

 « Last Edit: August 09, 2019, 08:52:52 08:52 by sphinx » Logged

the more you learn, the lesser you get to understand. is it then good know alot but not understand what you know or.......
Magnox
Active Member

Offline

Posts: 247

Thank You
-Given: 956

Oink!

 « Reply #3 on: August 09, 2019, 09:58:00 09:58 »

From CCS help on printf:

w   -- unsigned int with decimal place inserted

So there's why the above is giving weird values if you feed it a float. It's intended for when you do your maths with integers (which I usually do unless I really need float; just need to keep track of where the point should be) and the w makes it simpler to print the resulting integer as if it is a floating point.

Change the w into an f, and it will probably work. I'm not at my PC with CCS on to check, but it should work similarly to what you want.
 « Last Edit: August 09, 2019, 10:03:46 10:03 by Magnox » Logged
sphinx
Hero Member

Offline

Posts: 682

Thank You
-Given: 473

 « Reply #4 on: August 09, 2019, 10:51:00 10:51 »

Ok now it works i did not think of that as the w in the printf line was unsigned now the code works
no i learned that i need to think that itis different unsigned and unsigned even if the values are low.

 Logged

the more you learn, the lesser you get to understand. is it then good know alot but not understand what you know or.......
Magnox
Active Member

Offline

Posts: 247

Thank You
-Given: 956

Oink!

 « Reply #5 on: August 09, 2019, 11:46:30 11:46 »

It's not to do with w specifying unsigned, it is to do with it specifying integer.

A floating point number is stored completely differently to an integer. Floats are stored as a sign bit, an exponent, and a mantissa within the 32 bits. So, if you pass a float to printf but have told printf to expect an integer (with w), printf will just display the 32 bits as if it is a simple integer and the result will be strange.

Note that 32 bit floating point is quite limited in resolution, due to having to store the exponent too. Float can store very small to very large numbers, but only to a few useful digits of precision.

Double (64 bit float) is better, or do what I usually do and use integers by scaling all the values by powers of ten. For instance, 1023 * 12219 = 12500037 would be your maximum value in integers... that fits in a 32 bit integer. I shifted the 0.0012219 decimal place 7 steps to the left right to make it a whole number. Then to display it, you need to put the decimal place 7 places to the left, 1.2500037. the printf w is for that.

That will take less code, and give more precision that 32 bit float.

To explain, your floating point variable "flo" will store 1.2500037 as binary 00111111 10100000 00000000 00011111. That is actually 1.250003695..... because 1.2500037 cannot be stored exactly in a 32 bit float.

printf, if told to expect an integer with w, will interpret the binary number above as an integer (unsigned) and give you 1067450399.

If you used a double float, 1.2500037 could be stored more accurately as 1.2500036999999999398....
But using the integer method I said above, it would be exact and probably take less storage and CPU cycles.
 « Last Edit: August 09, 2019, 01:59:19 13:59 by Magnox » Logged
Magnox
Active Member

Offline

Posts: 247

Thank You
-Given: 956

Oink!

 « Reply #6 on: August 10, 2019, 03:38:50 03:38 »

A follow up to the above to say that the printf w format is very buggy, at least in the latest CCS PCD compiler for the dsPIC I'm using.

I've just used printf w to do a debug output for a scaled float-in-an-integer (I don't usually use w) and it was giving me odd characters. After some testing to make sure I wasn't doing anything wrong, I ended up with the following simple test code:

printf("%u  %5.3w\r\n",t,t);

where t is an unsigned int and the above line was in a loop reading out measurements. This was the output:

Code:
11166  [email protected]
18544  18.5;0
14401  14.400
18548  18.5<0
20694  20.6G0
23665  [email protected]
27208  27.220
28961  28.9?0

As you can see, it's rubbish. Yet another bug in CCS - can't those people write a working compiler??? I've found a few comments searching the web about pcd being buggy for printf w, so it's not just me.

It works if you stick to one decimal place, at two decimal places it gets the last number wrong, and at three or more it's like the above output.

Note that the w format does seem to accept and work with a 32 bit unsigned integer as well as a standard int, but with the same buggy behaviour as above in the decimal places.

 « Last Edit: August 10, 2019, 03:42:59 03:42 by Magnox » Logged
BharatSujanani
Junior Member

Offline

Posts: 47

Thank You
-Given: 30

All is Well

 « Reply #7 on: September 24, 2019, 12:45:48 12:45 »

You can use sprintf function which will give you string than you can display that string data to lcd.

sprintf(str,"%1.02f",floatVariable);
 Logged

Bharat Sujanani
 Pages: [1]