Searching \ for '[PIC] converting C to F' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=c
Search entire site for: 'converting C to F'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] converting C to F'
2010\05\13@083909 by alan smith

picon face
Processor is a 18F23K20

I've never had the requirement to do much math with a PIC, other than simple divide by 2 or 4 (shifts), add and subtract

So looking for a little help in implementing this

temp_F = (temp_C * 9 / 5) + 32;

The temp_C * 9 can be done with the MULLW instruction.  Just not to sure about the divide by 5 part?



     

2010\05\13@085143 by Minto Witteveen

picon face
Multiply by 10, then shift 1 left?


--------------------------------------------------
From: "alan smith" <spam_OUTmicro_eng2TakeThisOuTspamyahoo.com>
Sent: Thursday, May 13, 2010 14:39
To: "Microcontroller discussion list - Public." <.....piclistKILLspamspam@spam@mit.edu>
Subject: [PIC] converting C to F

{Quote hidden}

2010\05\13@085421 by Minto Witteveen

picon face
pls ignore previous post. Stupid.......


--------------------------------------------------
From: "Minto Witteveen" <Minto.WitteveenspamKILLspamgmail.com>
Sent: Thursday, May 13, 2010 14:51
To: "Microcontroller discussion list - Public." <.....piclistKILLspamspam.....mit.edu>
Subject: Re: [PIC] converting C to F

{Quote hidden}

2010\05\13@090237 by Isaac Marino Bavaresco

flavicon
face
Em 13/5/2010 09:39, alan smith escreveu:
> Processor is a 18F23K20
>
> I've never had the requirement to do much math with a PIC, other than simple divide by 2 or 4 (shifts), add and subtract
>
> So looking for a little help in implementing this
>
> temp_F = (temp_C * 9 / 5) + 32;
>
> The temp_C * 9 can be done with the MULLW instruction.  Just not to sure about the divide by 5 part?
>  


Use a fixed-point approach: Multiply by 65536 / 5 (which is approx.
13107) and then divide the result by 65536 (shift right 16 places).

You could speed things up by multiplying by ( 32768 * 9 / 5 == approx.
58982 ), then divide by 32768 (shift right 15 places). This method would
need just one operation.
Even the shift right by 15 may be simplified to a shift left by 1.

Of course you need to deal with 32-bit intermediate values.


Regards,

Isaac

__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/

2010\05\13@090534 by PICdude

flavicon
face
For fixed values like this, I generally divide in one of two ways...

- Subtract 5 continuously in a loop, until the remainder is less than  
5.  (Then process the remainder as required).

- Convert 1/5 (=0.2) into a value that is <integer>/256 (or even  
<integer>/65536, or other depending on precision required).  Then  
multiply by that integer and shift to divide by 256 etc.  To find that  
integer, I generally would keep multiplying 1/5 by 2, and look for as  
whole a number as possible.  For 1/5, multiplying by 256 is close to  
whole at 51.2.  51/256 = 0.1992, which is 0.4% error from 0.2.  If  
that's acceptable, then the code just needs to multiply by 51, then  
drop the right-most byte.  You can even check the MSB of the  
right-most byte and increment the next byte if required to round the  
result.

FWIW, there are some divide routines in the PIClist source-code library.

BTW, I've done C to F before, and I did the math for 9/5 at once.  I  
used 717/512 = 1.40039 which is 0.03% error.

Cheers,
-Neil.



Quoting alan smith <@spam@micro_eng2KILLspamspamyahoo.com>:

{Quote hidden}

> -

2010\05\13@090646 by Isaac Marino Bavaresco

flavicon
face
Em 13/5/2010 09:51, Minto Witteveen escreveu:
> Multiply by 10, then shift 1 left?
>  


Did you mean "shift 1 right" ?
__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/

2010\05\13@090944 by Olin Lathrop

face picon face
alan smith wrote:
> So looking for a little help in implementing this
>
> temp_F = (temp_C * 9 / 5) + 32

Step back and ask yourself whether you really really need the temperature
representation in the PIC to be specifically in F or C.  Unless the result
will be displayed to a user directly by the PIC, the answer is most likely
"no".  Pick whatever representation has the resolution and range you need,
and is otherwise convenient inside the PIC.

I've done a lot of PIC applications that have to measure something as part
of their operation, and its very very rare these need to be converted to any
standard units.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2010\05\13@091145 by Jan-Erik Soderholm

face picon face
>> So looking for a little help in implementing this
>>
>> temp_F = (temp_C * 9 / 5) + 32;
>>

How many possible input values (in deg C) do you have ?

I'm thinking "lookup-table" here... :-)

Jan-Erik.

2010\05\13@092316 by Isaac Marino Bavaresco

flavicon
face
Em 13/5/2010 10:06, Isaac Marino Bavaresco escreveu:
> Em 13/5/2010 09:51, Minto Witteveen escreveu:
>  
>> Multiply by 10, then shift 1 left?
>>  
>>    
>
> Did you mean "shift 1 right" ?
>  


Ah! Got bite by this one :) Only noticed he was multiplying twice,
missed that he was *multiplying* by 5, not dividing by 5.


__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/

2010\05\13@092722 by Isaac Marino Bavaresco

flavicon
face
Em 13/5/2010 10:02, Isaac Marino Bavaresco escreveu:
{Quote hidden}

If your input range is small and you can accept a little loss of
precision, you could use 256 and 128 instead of 65536 and 32768, then
shift right by 8 or by 7. This way you would need to deal at most with
16-bit numbers.


Regards,

Isaac

__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/

2010\05\13@092747 by alan smith

picon face
Its being displayed on an LCD, so yes.  User selects to display in C or F.
Otherwise I would agree with you...the other applications where Ive had to read a temperature, it was just comparing to setpoints to turn on or off outputs and there its typically a 10 bit value from the A/D to deal with.

--- On Thu, 5/13/10, Olin Lathrop <KILLspamolin_piclistKILLspamspamembedinc.com> wrote:

{Quote hidden}

> -

2010\05\13@092910 by alan smith

picon face
Thanks Neil...thats what I was looking for.

--- On Thu, 5/13/10, PICdude <TakeThisOuTpicdude3EraseMEspamspam_OUTnarwani.org> wrote:

{Quote hidden}

> > --

2010\05\13@093200 by Isaac Marino Bavaresco

flavicon
face
Em 13/5/2010 10:09, Olin Lathrop escreveu:
> alan smith wrote:
>  
>> So looking for a little help in implementing this
>>
>> temp_F = (temp_C * 9 / 5) + 32
>>    
> Step back and ask yourself whether you really really need the temperature
> representation in the PIC to be specifically in F or C.  Unless the result
> will be displayed to a user directly by the PIC, the answer is most likely
> "no".  Pick whatever representation has the resolution and range you need,
> and is otherwise convenient inside the PIC.
>
> I've done a lot of PIC applications that have to measure something as part
> of their operation, and its very very rare these need to be converted to any
> standard units.
>  


I also like this approach. Once I designed a battery charger for a very
specific product (all parameters fixed, no display, just an LED).
Internally I only dealt with ADC units, not even one conversion needed.

Isaac

__________________________________________________
Fale com seus amigos  de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/

2010\05\13@094041 by Walter Banks

picon face


alan smith wrote:

{Quote hidden}

9/5 is 1.8 so

(temp_C  * 1.8) + 32

(temp_C  * 0.8) + temp_C + 32

Using the PIC 18's mullw which is a 16 = 8 * 8 muliplier

0.8 = 204.8 / 256   (No magic it is 0.8 * 256)

0.8 ~ 205 / 256

temp_C * 205 result in PRODH is result / 256

so conversion to temp_F

(temp_C * 205)

PRODH + temp_C + 32

One mult two adds  accurate to 2 parts in 460 less than half persent

Regards

w..
--
Walter Banks
Byte Craft Limited
http://www.bytecraft.com



2010\05\13@094350 by Chris McSweeny

picon face
On Thu, May 13, 2010 at 1:39 PM, alan smith <RemoveMEmicro_eng2EraseMEspamEraseMEyahoo.com> wrote:
> The temp_C * 9 can be done with the MULLW instruction.  Just not to sure about the divide by 5 part?

It's not actually that difficult to do a proper binary divide if you
want to. Consists of a loop with a couple of (multi-byte) left shift
operations, and a comparison/subtraction. Code for 8 bit:

MOVLW 8
MOVWF count
CLR working
CLR result
:loop
RLF orig
RLF working
MOVLW 5
SUBWF working, w
BTFSC STATUS, C
MOVWF working
RLF result
DECFSZ count
GOTO loop

2010\05\13@094701 by Walter Banks

picon face


PICdude wrote:

{Quote hidden}

Because the PIC18 has only a 16bit = 8bit by 8 bit multiply
change the 1.8 to a ((0.8 * 256 ) + an add) and the whole
conversion becomes a mult and two adds in 8 bits good to
256F in 8 bit calculations.

Walter..


2010\05\13@095224 by Djula Djarmati

flavicon
> Processor is a 18F23K20
>
> I've never had the requirement to do much math with a PIC, other than simple divide by 2 or 4 (shifts), add and subtract
>
> So looking for a little help in implementing this
>
> temp_F = (temp_C * 9 / 5) + 32;
>
> The temp_C * 9 can be done with the MULLW instruction.  Just not to sure about the divide by 5 part?

If you don't need decimals:

temp_F = temp_C + 32      Tf=Tc*1.8+32. This line does Tf=Tc*1+32
temp_F = temp_F + HIBYTE(temp_C * 205); Add Tc*0.8 (205/256 is ~0.8)

This works only for temp_C=<0:255> for negative temp_c you could shift
temp_C to positive with adding 100 and after the conversion subtracting
 180 from the result. This will give a temp_C range <-100:155>

Djula

2010\05\13@100051 by William Couture

face picon face
On Thu, May 13, 2010 at 9:05 AM, PICdude <RemoveMEpicdude3spam_OUTspamKILLspamnarwani.org> wrote:

> BTW, I've done C to F before, and I did the math for 9/5 at once.  I
> used 717/512 = 1.40039 which is 0.03% error.

Hmmm... 9/5 = 1.8
           717/512 = 1.40039

That doesn't seem like a 0.03% error.  Am I missing something here?

Personally, I'd use 461 / 256 = 1.80078  (0.0434% error).

Bill

--
Psst...  Hey, you... Buddy...  Want a kitten?  straycatblues.petfinder.org

2010\05\13@103555 by Spehro Pefhany

picon face
At 08:39 AM 13/05/2010, you wrote:
>Processor is a 18F23K20
>
>I've never had the requirement to do much math with a PIC, other
>than simple divide by 2 or 4 (shifts), add and subtract
>
>So looking for a little help in implementing this
>
>temp_F = (temp_C * 9 / 5) + 32;
>
>The temp_C * 9 can be done with the MULLW instruction.  Just not to
>sure about the divide by 5 part?

In assembly, I use fixed-point 32-bit math. I multiply by 0.9 which
is 0x7333 3333 (the way I do it), and the rest is just shifts and adds
(arithmetic shift left by 1 to get * 1.8 and add the '32').

That's for accurate instrumentation and controls-- for a single byte
value, a LUT might be easiest, as others have suggested.

Best regards,

Spehro Pefhany --"it's the network..."            "The Journey is the reward"
RemoveMEspeffTakeThisOuTspamspaminterlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com



2010\05\13@103913 by Djula Djarmati

flavicon
>> BTW, I've done C to F before, and I did the math for 9/5 at once.  I
>> used 717/512 = 1.40039 which is 0.03% error.
>
> Hmmm... 9/5 = 1.8
>             717/512 = 1.40039
>
> That doesn't seem like a 0.03% error.  Am I missing something here?
>
> Personally, I'd use 461 / 256 = 1.80078  (0.0434% error).

The same thing but only 8 bits:

1 + 205/256 = 1.80078

What is important with this "division to multiplication" approximations
is that a small negative error is worse than a larger positive error.

i.e. 1.799999 can cause some result to be 123.99998 which is 123 for the
PIC - 1.803 would be much better. You can add rounding up but that
quickly gets complicated.

Djula

2010\05\13@110803 by Michael Rigby-Jones
flavicon
face


> -----Original Message-----
> From: EraseMEpiclist-bouncesspamspamspamBeGonemit.edu [RemoveMEpiclist-bouncesKILLspamspammit.edu] On
Behalf
{Quote hidden}

sure
> about the divide by 5 part?

What range of input values do you need to cover?  By adding an offset
you can use a close approximation for your fractional calculation and
spread the error out.  e.g.

temp_F = ( ( (temp_C * 205) + 112 ) >> 8 ) + 32 + temp_C

This gives results accurate to within +-0.4 Fahrenheit over the range
-50 to +200 degrees Celsius

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2010\05\13@114125 by PICdude

flavicon
face
Wow, fail on my part!  1.4 was for something else that I did recently.  
 I'm looking at the C-to-F code now, and I did indeed use 461/256.

BTW, for similar apps, where the sample/refresh rate is not critical,  
and I'm averaging many samples, I've just added 'n' samples where 'n'  
would happen to multiply the result so that the resulting math is some  
power of two.

Cheers,
-Neil.



Quoting William Couture <bcoutureSTOPspamspamspam_OUTgmail.com>:

{Quote hidden}

>

2010\05\13@190045 by Veronica Merryfield

picon face

On 2010-05-13, at 5:39 AM, alan smith wrote:

> Processor is a 18F23K20
>
> I've never had the requirement to do much math with a PIC, other than simple divide by 2 or 4 (shifts), add and subtract
>
> So looking for a little help in implementing this
>
> temp_F = (temp_C * 9 / 5) + 32;
>
> The temp_C * 9 can be done with the MULLW instruction.  Just not to sure about the divide by 5 part?

In this case one can multiple by 9/5, 1.8. However, 1.8 does not fit exactly into a small number of bits in a fixed point binary number scheme. But with a limited number range, a small error could be tolerated to make the number scheme easier. For instance, multiple by 2 across a small range might work with an adjustment to the constant 32.

Since this is to be displayed to a user and not for internal calculation, where any units of you choice can and should be used (ADC counts will do), one can fudge it in all sorts of ways as the display is rendered. Without knowing the temperature range for display or the format of temp_c or the require display precision it is hard to make a suggestion.

2010\05\14@174653 by Barry Gershenfeld

picon face
On Thu, May 13, 2010 at 6:05 AM, PICdude <KILLspampicdude3spamBeGonespamnarwani.org> wrote:

>
> - Subtract 5 continuously in a loop, until the remainder is less than
> 5.  (Then process the remainder as required).
>

An astute observation here, since division is defined as repeated
subtraction.

And if all the application does is display temperature to a user, it
probably spends most of its time doing nothing.  So division done this way
would have no visible effect on the application.  Of course, if you say, "on
a battery", then that's different :)

2010\05\14@175328 by Joshua Shriver

picon face
When I first saw this thread header I thought it was a C language to
Fortran translator request.
-Josh

2010\05\14@175524 by Mark Rages

face picon face
On Fri, May 14, 2010 at 4:46 PM, Barry Gershenfeld <EraseMEgbarry42spamEraseMEgmail.com> wrote:
> On Thu, May 13, 2010 at 6:05 AM, PICdude <@spam@picdude3@spam@spamspam_OUTnarwani.org> wrote:
>
>>
>> - Subtract 5 continuously in a loop, until the remainder is less than
>> 5.  (Then process the remainder as required).
>>
>
> An astute observation here, since division is defined as repeated
> subtraction.
>
> And if all the application does is display temperature to a user, it
> probably spends most of its time doing nothing.  So division done this way
> would have no visible effect on the application.  Of course, if you say, "on
> a battery", then that's different :)

Repeated subtraction can be several times faster than software
long-division if the dividend is known to be small.  This observation
saved several milliseconds of wake time in a battery-powered
application I'm working on.

Regards,
Mark
markrages@gmail
--
Mark Rages, Engineer
Midwest Telecine LLC
spamBeGonemarkragesspamKILLspammidwesttelecine.com

2010\05\14@180857 by Olin Lathrop

face picon face
Barry Gershenfeld wrote:
> An astute observation here, since division is defined as repeated
> subtraction.
>
> And if all the application does is display temperature to a user, it
> probably spends most of its time doing nothing.  So division done
> this way would have no visible effect on the application.  Of course,
> if you say, "on a battery", then that's different :)

This extensive discussion about how to convert from degC to degF is perhaps
interesting to some, but everyone seems to be answering the details asked
about instead of the real solution, which is not to be in this situation in
the first place.

The OP has said the PIC is directly displaying temperature to a user, so he
does have to convert whatever the internal measurement value is to standard
units for display.  But converting between display units makes no sense,
especially from integer C to integer F since the former has less resolution.
There will be quite a few degF values that will never be displayed.  Nearly
half the time the F value will jump by 2 even when the temperature is
changing slowly.  For example 20C --> 68F, 21C --> 70F.

The real question is how to convert from the internal representation to
either C or F depending on the user units switch.  The answer depends on how
the temperature is measured or communicated to the PIC in the first place.
Once you've converted to integer degC, a lot of information has already been
lost.

For example, if temperature is measured with a linear temperature to voltage
sensor, then the internal representation is probably the 10 bit A/D reading.
This needs to be converted to either degC or degF, but not both and not
between the two.  In this case I'd use a wide integer multiply routine so
that the desired result comes out with a whole number of bits below the
binary point.  The choice of F or C is just using a different multiplication
constant.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2010\05\15@082854 by PICdude

flavicon
face
Quoting Olin Lathrop <.....olin_piclistspam_OUTspamembedinc.com>:

> ... everyone seems to be answering the details asked
> about instead of ...

Yeah, some of us have a habit of doing that -- answering what was  
actually asked. :)


{Quote hidden}

Not necessarily -- we don't know if there's some other source of the  
original deg-C data.  Perhaps the data is coming from a digital  
sensor.  Perhaps the OP has the deg-C data available at a higher than  
1-deg-C resolution.  Perhaps he's even tapping off a 7-segment display  
(and yes, I've done that in the past).

Cheers,
-Neil.



2010\05\15@095114 by Olin Lathrop

face picon face
PICdude wrote:
> Yeah, some of us have a habit of doing that -- answering what was
> actually asked. :)

Which is often not the best solution to the real problem.

> Not necessarily -- we don't know if there's some other source of the
> original deg-C data.

Exactly, we don't know.  This needs to be determined before useful answers
can be given.

> Perhaps the OP has the deg-C data available at a higher than
> 1-deg-C resolution.

Then most of the answers that assume degC is a integer value in a single
byte are wrong.  See what I mean?

2010\05\15@101520 by Marechiare

picon face
> When I first saw this thread header I thought it was a
> C language to Fortran translator request.

Or C# to F#.

2010\05\15@101943 by Marcel Birthelmer

flavicon
face
On Sat, May 15, 2010 at 4:15 PM, Marechiare <TakeThisOuTmarechiare.....spamTakeThisOuTgmail.com> wrote:
>
> Or C# to F#.


Capo?

2010\05\15@103912 by Marechiare

picon face
>> Or C# to F#.
>
>
> Capo?

VS 2010

2010\05\16@033810 by Walter Banks

picon face


Olin Lathrop wrote:
>
> Then most of the answers that assume degC is a integer value in a single
> byte are wrong.  See what I mean?

Actually the techniques remain the same independent of
the raw format be it in some recognized engineering units
or some internal format.

Many of the posts reviewed the approach to use and
some of the solutions (including mine) dealt with
the issues of minimizing the converting code size
and execution time. Almost all of them converted
the 9/5 conversion factor into fixed point.



Regards,

w..
--
Walter Banks
Byte Craft Limited
http://www.bytecraft.com

2010\05\19@191454 by Barry Gershenfeld

picon face
On Sat, May 15, 2010 at 4:15 PM, Marechiare <TakeThisOuTmarechiareKILLspamspamspamgmail.com> wrote:

> >
> > Or C# to F#.
>
> Capo?
>

Auto-Tune?

2010\05\19@194919 by Bob Ammerman

flavicon
face
>> >
>> > Or C# to F#.
>>
>> Capo?
>>
>
> Auto-Tune?

C# and F# are two Microsoft .NET languages

-- Bob Ammerman
RAm Systems

2010\05\20@205711 by Oli Glaser

flavicon
face

----- Original Message -----
From: "Bob Ammerman" <.....rvammermanspamRemoveMEroadrunner.com>
To: "Microcontroller discussion list - Public." <RemoveMEpiclistspamspamBeGonemit.edu>
Sent: Thursday, May 20, 2010 12:49 AM
Subject: Re: [PIC] converting C to F


>>> >
>>> > Or C# to F#.
>>>
>>> Capo?
>>>
>>
>> Auto-Tune?
>
> C# and F# are two Microsoft .NET languages

I still like the Capo idea though..
Or just stick to C instead, far easier key to deal with :-)

2010\05\21@021805 by Marechiare

picon face
>>>> > Or C# to F#.
>>>>
>>>> Capo?
>>>>
>>>
>>> Auto-Tune?
>>
>> C# and F# are two Microsoft .NET languages
>
> I still like the Capo idea though..
> Or just stick to C instead, far easier key to deal with :-)

Don't stick with that under [PIC] tag, the admin hat member will force
you back to PICs quickly :-)

More... (looser matching)
- Last day of these posts
- In 2010 , 2011 only
- Today
- New search...