|
|
View previous topic :: View next topic |
Author |
Message |
tarmimi
Joined: 07 Jan 2009 Posts: 7
|
convert float value to hex value... |
Posted: Tue Jan 20, 2009 4:24 am |
|
|
hello everyone...
i would like to ask for help is somebody know how to convert float value to hex value...what i means here is,it is not related to fprintf application.Here my example:
i have this:
Code: |
float restemp,truehumid;
sht_rd(restemp,truehumid);
|
So i want to convert the value of restemp and truehumid to hex value.
Can someone help me the way to convert it,if do have exmple can post to me for my reference.Thank you |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Jan 20, 2009 6:19 am |
|
|
Hex is just a representation of the value such as binary and decimal.
A float is stored as a 32 bit value and can be displayed in any format.
You must also be aware that Microchip and therefore CCS use a different format for floats than the IEEE standard so if you are passing float data between a PC and a PIC you will need to convert between the 2.
You need to be more specific in what you want to do with the float data.
you have not given any info on what the function sht_rd actually does.
I expect it is shift right or something that requires 2 floats ?
more info is required. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
Re: convert float value to hex value... |
Posted: Tue Jan 20, 2009 8:13 am |
|
|
tarmimi wrote: | hello everyone...
i would like to ask for help is somebody know how to convert float value to hex value...what i means here is,it is not related to fprintf application.Here my example:
i have this:
Code: |
float restemp,truehumid;
sht_rd(restemp,truehumid);
|
So i want to convert the value of restemp and truehumid to hex value.
Can someone help me the way to convert it,if do have exmple can post to me for my reference.Thank you |
Reiterating on Wayne's comment - tell us what you are trying to do.
Looking at your variable names I am guessing you are working with a Sensirion SHTxx series sensor. Are you trying to record the data to EEPROM or SD/MMC card? If this is the case why not save the preprocesssed data and perform the post processing later - in this way you remove (some) of the complexities of going between systems. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
tarmimi
Joined: 07 Jan 2009 Posts: 7
|
hahha...yes im working with the sensirion sensor sht71 |
Posted: Tue Jan 20, 2009 7:26 pm |
|
|
Sorry if my message is not clear, actually I'm trying to read data which are float value(restemp,truehumid) from sht71. So the value of restemp and the truehumid I directly send to hyperterminal for display.
Now the sht71 proved it can function well but now I'm having problem because I need to run it with modbus. So I put the restemp and truehumid value (still in float) inside the input register as like this:
Code: |
case FUNC_READ_INPUT_REGISTERS: // FC = 0x04
if(modbus_rx.data[0] || modbus_rx.data[2] || modbus_rx.data[1] >= 8 || modbus_rx.data[3] + modbus_rx.data[1] > 8)
modbus_exception_rsp(ModbusAddress, modbus_rx.func, ILLEGAL_DATA_ADDRESS);
else {
if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS /*&& button_triggered==1*/)
modbus_read_holding_registers_rsp(ModbusAddress, (modbus_rx.data[3] * 2), hold_regs + modbus_rx.data[1]);
else {
// input_regs[0] = Output_State;
// input_regs[1] = Fuse_Status;
input_regs[0] = SSR_State;
input_regs[1] = restemp;
input_regs[2] = truehumid;
// input_regs[5] = AN2value;
// input_regs[6] = AN4value;
// input_regs[7] = AN5value;
modbus_read_input_registers_rsp(ModbusAddress, (modbus_rx.data[3] * 2), input_regs + modbus_rx.data[1]);
//button_triggered=0;
}
event_count++;
}
break; |
Above is the code for isr task to run with modbus, and my main program is like this:
Code: |
void main(void)
{
// int1 flashing_toggle;
int8 i;
// RESET_INSTRUCTION 0
// WDT_FROM_SLEEP 3
// WDT_TIMEOUT 7
// MCLR_FROM_SLEEP 11
// NORMAL_POWER_UP 12
// BROWNOUT_RESTART 14
// MCLR_FROM_RUN 15
RestartCauseCode = restart_cause();
#if DEBUG_PORT
delay_ms(1);
fprintf(DEBUG, "\r\n%d\r\n", RestartCauseCode);
fprintf(DEBUG, "\r\nSW: %s\t\tHW: %s\r\n", sw_rev, hw_rev);
fprintf(DEBUG, __DATE__);
fprintf(DEBUG, "\t");
fprintf(DEBUG, __TIME__);
fprintf(DEBUG, "\t\t");
fprintf(DEBUG, "Compiler: %s", compiler_version);
fprintf(DEBUG, "\r\n");
#endif
system_init();
sht_init(); //power up sht71
while(TRUE) {
restart_wdt();
sht_rd(restemp,truehumid); //read temperature and humidity
delay_ms(500); //delay between reading to prevent self heat
} |
All above are example codes from my whole codes just to give an idea what I'm trying to do (don't look too deeply into the code cause I only need an idea how to read the sht71).
So, in the while(true) loop what should I do to allow the modbus poll the data from the restemp and truehumid? |
|
|
tarmimi
Joined: 07 Jan 2009 Posts: 7
|
1 more |
Posted: Wed Jan 21, 2009 7:03 pm |
|
|
one more thing....
Should i convert the float value to int32 by assign another variable to let the modbus read or retrieve the data and can u help me give sample code for it for my reference..
p/s;this is only my idea |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jan 22, 2009 3:11 am |
|
|
OK, still not sure what you are trying to do, you do not specify what you are talking to over the modbus but I think this is what you are after.
A float is 32 bits (4 bytes)
You can get access to these bytes in many different ways.
1. Use a union
Code: |
union mydata {
float fl;
int bytes[4];
struct byte {
int a;
int b;
int c;
intd;
}
}
mydata.fl = 0.1234;
mydata.bytes[0] = 0x??; // First byte
mydata.bytes[1] = 0x??; // Second byte
mydata.bytes[2] = 0x??; // Third byte
mydata.bytes[3] = 0x??; // Fourth byte
mydata.byte.a = 0x??; // first byte
mydata.byte.b = 0x??; // second byte
mydata.byte.c = 0x??; // third byte
mydata.byte.d = 0x??; // fourth byte
|
Using a union in CCS may have issues, you need to see what works for you.
I prefer this method
Code: |
float fl;
int *fl_p;
fl = 0.1234;
fl_p = &fl; // fl_p now points to the float fl data in memory
Either access the data as
fl_p[0]
fl_p[1]
fl_p[2]
fl_p[3]
or as a pointer
*fl_p // the first byte
*(fl_p + 1) // second byte
*(fl_p + 2) // third byte
*(fl_p + 3) // fourth byte
|
Now as I mentioned microchip and CCS use a different standard for floats than the IEEE standard, does this apply to your device ?
Does you device actually use floats or integer values, as you have not specified what the device is or pointed us towards a data sheet we cannot help you there. |
|
|
tarmimi
Joined: 07 Jan 2009 Posts: 7
|
almost... |
Posted: Thu Jan 22, 2009 4:12 am |
|
|
Ok.I will tell one by one so u will never be confused:)
Actually my modbus cant read the data because the value is in float value.So i take a simple step here.We go straight away to the example.
This is my main code:
Code: |
#include <18f6722.h>
#include<math.h>
#include<stdio.h.>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=PC)
#include<sht75.c>
void main()
{
float restemp, truehumid;
sht_init();
while(1)
{
sht_rd (restemp, truehumid);
printf("temperature : %1.1f %%c\n ", restemp);
printf("humidity : %1.1f %%\n ", truehumid);
delay_ms(500); //delay 500 ms between reading to prevent self heating of sensor
}
}
|
and this is the sht75.c code:
Code: |
///////////////////////////////////////////////////////////////////////////////
// //
// Driver file for SHT75 Temperature & Humidity Sensor //
// //
// ***** To initialise SHT75 sensor upon power up ***** //
// //
// Function : sht_init() //
// Return : none //
// //
// //
// ***** To measure and caluculate SHT75 temp & real RH ***** //
// //
// Function : sht_rd (temp, truehumid) //
// Return : temperature & true humidity in float values //
// //
///////////////////////////////////////////////////////////////////////////////
#define sht_data_pin PIN_B0
#define sht_clk_pin PIN_B1
//***** Function to alert SHT75 *****
void comstart (void)
{
output_float(sht_data_pin); //data high
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
output_bit(sht_data_pin, 0); //data low
delay_us(1);
output_bit(sht_clk_pin, 0); //clk low
delay_us(2);
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
output_float(sht_data_pin); //data high
delay_us(1);
output_bit(sht_clk_pin, 0); //clk low
}
//***** Function to write data to SHT75 *****
int1 comwrite (int8 iobyte)
{
int8 i, mask = 0x80;
int1 ack;
//Shift out command
delay_us(4);
for(i=0; i<8; i++)
{
output_bit(sht_clk_pin, 0); //clk low
if((iobyte & mask) > 0) output_float(sht_data_pin); //data high if MSB high
else output_bit(sht_data_pin, 0); //data low if MSB low
delay_us(1);
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
mask = mask >> 1; //shift to next bit
}
//Shift in ack
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
ack = input(sht_data_pin); //get ack bit
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
output_bit(sht_clk_pin, 0); //clk low
return(ack);
}
//***** Function to read data from SHT75 *****
int16 comread (void)
{
int8 i;
int16 iobyte = 0;
const int16 mask0 = 0x0000;
const int16 mask1 = 0x0001;
//shift in MSB data
for(i=0; i<8; i++)
{
iobyte = iobyte << 1;
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
if (input(sht_data_pin)) iobyte |= mask1; //shift in data bit
else iobyte |= mask0;
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
}
//send ack 0 bit
output_bit(sht_data_pin, 0); //data low
delay_us(1);
output_bit(sht_clk_pin, 1); //clk high
delay_us(2);
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
output_float(sht_data_pin); //data high
//shift in LSB data
for(i=0; i<8; i++)
{
iobyte = iobyte << 1;
output_bit(sht_clk_pin, 1); //clk high
delay_us(1);
if (input(sht_data_pin)) iobyte |= mask1; //shift in data bit
else iobyte |= mask0;
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
}
//send ack 1 bit
output_float(sht_data_pin); //data high
delay_us(1);
output_bit(sht_clk_pin, 1); //clk high
delay_us(2);
output_bit(sht_clk_pin, 0); //clk low
return(iobyte);
}
//***** Function to wait for SHT75 reading *****
void comwait (void)
{
int16 sht_delay;
output_float(sht_data_pin); //data high
output_bit(sht_clk_pin, 0); //clk low
delay_us(1);
for(sht_delay=0; sht_delay<30000; sht_delay++) // wait for max 300ms
{
if (!input(sht_data_pin)) break; //if sht_data_pin low, SHT75 ready
delay_us(10);
}
}
//***** Function to reset SHT75 communication *****
void comreset (void)
{
int8 i;
output_float(sht_data_pin); //data high
output_bit(sht_clk_pin, 0); //clk low
delay_us(2);
for(i=0; i<9; i++)
{
output_bit(sht_clk_pin, 1); //toggle clk 9 times
delay_us(2);
output_bit(sht_clk_pin, 0);
delay_us(2);
}
comstart();
}
//***** Function to soft reset SHT75 *****
void sht_soft_reset (void)
{
comreset(); //SHT75 communication reset
comwrite(0x1e); //send SHT75 reset command
delay_ms(15); //pause 15 ms
}
//***** Function to measure SHT75 temperature *****
int16 measuretemp (void)
{
int1 ack;
int16 iobyte;
comstart(); //alert SHT75
ack = comwrite(0x03); //send measure temp command and read ack status
if(ack == 1) return;
comwait(); //wait for SHT75 measurement to complete
iobyte = comread(); //read SHT75 temp data
return(iobyte);
}
//***** Function to measure SHT75 RH *****
int16 measurehumid (void)
{
int1 ack;
int16 iobyte;
comstart(); //alert SHT75
ack = comwrite(0x05); //send measure RH command and read ack status
if(ack == 1) return;
comwait(); //wait for SHT75 measurement to complete
iobyte = comread(); //read SHT75 temp data
return(iobyte);
}
//***** Function to calculate SHT75 temp & RH *****
void calculate_data (int16 temp, int16 humid, float & tc, float & rhlin, float & rhtrue)
{
float truehumid1, rh;
//calculate temperature reading
tc = ((float) temp * 0.01) - 40.0;
//calculate Real RH reading
rh = (float) humid;
rhlin = (rh * 0.0405) - (rh * rh * 0.0000028) - 4.0;
//calculate True RH reading
rhtrue = ((tc - 25.0) * (0.01 + (0.00008 * rh))) + rhlin;
}
//***** Function to measure & calculate SHT75 temp & RH *****
void sht_rd (float & temp, float & truehumid)
{
int16 restemp, reshumid;
float realhumid;
restemp = 0; truehumid = 0;
restemp = measuretemp(); //measure temp
reshumid = measurehumid(); //measure RH
calculate_data (restemp, reshumid, temp, realhumid, truehumid); //calculate temp & RH
}
//***** Function to initialise SHT75 on power-up *****
void sht_init (void)
{
comreset(); //reset SHT75
delay_ms(20); //delay for power-up
} |
So let say i want to change below part to decimal number.Now the value example are 31.1 C for temperature and 56.7% for humidity.I want it to be 31 C and 58%.So what im trying to do is,i dont want to get value as float value because my modbus cant read the float so it must be in int(decimal) to allow my modbus to read the value,however i still dont have an idea to change the float value of and .Hopefully u can help me brush my brain.:
Code: |
while(1)
{
sht_rd (restemp, truehumid);-->this are in float,so i want to change it to decimal(int)
|
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Jan 22, 2009 5:53 am |
|
|
OK now we understand,
the simplest way is to type cast
sht_rd ((int)restemp, (int)truehumid);
This will drop the decimal part and leave you with an 8 bit int so
1.23 = 1
3.78 = 3
The function floor(fl) does the same
(int)floor(1.23) = 1
(int)floor(3.78) = 3
the function ceil(fl) returns the next whole value up so
(int)ceil(1.23) = 2
(int)ceil(3.78) = 4
There does not appear to be a rounding funtion in CCS (Quick check) so you would have to write a routine to do it if you need it:-
Code: |
int round(float fl)
{
float r = fl - floor(fl);
if (r >= 0.5)
return((int)ceil(fl));
else
return((int)floor(fl));
}
|
This will return a 8bit int
You would then need to type cast or alter the routine to work with ints
Something like that, not tested, just wrote it off the top of my head so I hope it works. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jan 22, 2009 6:14 pm |
|
|
Quote: | There does not appear to be a rounding funtion in CCS | True.
This surprised me also, but a search on the internet learned that there are many different ways for how people do want rounding to occur. I think the older C-standards didn't include a round function. The C-99 standard has many... (floor, floorf, floorl, ceil, ceilf, ceill, round, roundf, roundl, trunc, truncf, truncl, rint, rintf, rintl, nearbyint, nearbyintf, nearbyintl and maybe more).
The main differences are how negative values are rounded and how the values at the minimum and maximum ranges are handled.
A slightly compacter version of the posted Round function can be created by omitting the Ceil function: Code: | int round(float fl)
{
return ( (int)floor(fl + 0.5) );
} |
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Jan 23, 2009 2:55 am |
|
|
Nice bit of code ckielstra.
I am sure I would have reduced it to that nice routine if I had put more effort into it
Aren't these functions part of the math lib in C. In CCS these are all built in I think. |
|
|
tarmimi
Joined: 07 Jan 2009 Posts: 7
|
huhu |
Posted: Tue Jan 27, 2009 10:38 pm |
|
|
ahhah...at last..but suddenly i got a new idea of it..now i already can get the value dcimal...i change the code to this code:
Code: |
while(TRUE) {
restart_wdt();
sht_rd(restemp,truehumid); //read temperature and humidity
temp=(int32*)restemp;
hum=(int32*)truehumid;
delay_ms(500); //delay between reading to prevent self heat
|
it run perfectly but the accuracy of reading slightly difference..but not to much as well...it can be consider as tolerance...thanks for your help...from that i get an idea to do in this method... |
|
|
Briany
Joined: 06 Jan 2009 Posts: 15
|
|
Posted: Tue Jan 27, 2009 10:41 pm |
|
|
Wayne_ wrote: |
Code: |
int round(float fl)
{
float r = fl - floor(fl);
if (r >= 0.5)
return((int)ceil(fl));
else
return((int)floor(fl));
}
|
This will return a 8bit int
You would then need to type cast or alter the routine to work with ints
Something like that, not tested, just wrote it off the top of my head so I hope it works. |
just curious, what happens if you type cast the float value to int32? will the decimal be retained? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|