# Microchip PIC programming question

Discussion in 'Electronic Design' started by [email protected], Jul 9, 2005.

1. ### Guest

Hi,

I am learning how to program a PIC for fun and creating a project for
forward to trying out some code. So I figure start small and build my
way on up. I am not looking for someone to tell me exactly how to do ,
just a few pointers and links would be greatly appreciated.

I am thinking about getting a PIC16F676 after I know what I am doing a
little better.

The first chunk I want to do is:

Input A: 30mv - 75mv
Input B: 2.5V - 6.0V
Vref: > 6.0V

Calculate: Ratio A/B

Output C: PWM % at A/B*32 (would vary from 16% - 96% at extremes)

The second chunk I want to do is:

Load a 10 point table of min to max ratios and corresponding
calibration points from 0-100mv

Based on the calculated Ratio A/B, calculate the corresponding mv using
a linear extrapolation between the two closest points on the curve.

Output D: create another PWM at the calculated mv

The third chunk I want to do is:

Output F: create another PWM that uses fuzzy logic to get the Input E
to match Output D. Increasing Output F will increase Input E.

I broke it up into these three pieces since each one had an output that
became the input for the next section. I wasn't sure it would all fit
on one PIC16F676, but it should all fit on three of them.

that you think will help me with my project.

Thanks
Andy

2. ### John PopelishGuest

The PIC processors are speced to handle a supply voltage between about
2.2 and 5.5 volts. Analog inputs are allowed to be between the supply
rails. The analog to digital converter has a 10 bit resolution (one
part in 1024) but only if its full scale reference is most of the
supply voltage. So if the chip is powered by 5 volts, and the A/D
converter uses that supply as its full scale reference, then each
discrete level is
5 V / 1024 = 4.9 mV
That means, if you try to digitize your 30 millivolt signal, the A/D
converter won't be able to distinguish it from 34.9 mV.

However, if you multiply this voltage by a fixed gain with an opamp,
(say, 50 times) so that the maximum value is closer to the PIC supply
voltage, the resolution will more closely approach the full .1% the
converter is capable of.

The 6 volt peak value of the second input is a problem for a different
reason. It will exceed the absolute maximum voltage for the chip, and
once it gets higher than the A/D converter full scale reference
voltage, all higher voltages will give the same full scale output.
So, this signal will have to be scaled down a bit to make it
compatible with the PIC. If the signal can stand a bit of current
load, you can accomplish this with a two resistor divider.

The Microchip site has math libraries you can use to do the division,
but it is a fun exercise to go through this development just to get
familiar with how this works.

3. ### Roger HamlettGuest

You are going to have to divide your second input voltage to bring it
below the supply voltage of the chip. The same for the Vref.
The first input will need amplification to give acceptable resolution.
This should fit into a single 676 _easily_. I have a board I did some
while ago, that takes readings from a Ph sensor, temperature sensor, and
ammonia sensor, linearises the ammonia reading based on two calibration
points, and a logarithmic curve fit (a lot of arithmetic), outputing a new
reading every second. At the same time it performs a servo loop
controlling a heater with one of the PWM outputs, and regulating this
based on the temperature sensor reading. Finally it converts th Ph sensor
voltage into a Ph value. This only uses 85% of the code space in an 676.
Realistically, the code would be much quicker to write, using a language
like 'C', where in the versions for the PIC, most of the work to perform
basic I/O, and the code needed to retrieve tables etc., is already written
for you. It is down to whether you really want to learn the PIC assembler
or not. There are at least three quite well known C compilers available
for the PIC.

Best Wishes

4. ### Ol' DufferGuest

And the PIC A/D converter is a leaky piece of crap. When they say
input impedance should be < 2.5K, they aren't kidding. You often
need a buffer amp even if the input signal is at a reasonable level.
And don't even think about driving an input above the supply rail,
because this makes all the other inputs leak even worse than spec.

5. ### Guest

Wow, thanks for the quick suggestions!

Okay, now I know that signal A and B need to be different.

I can replace signal A with one with a different sensor that would read
from 1.1v - 2.0v and give 180 steps which should be enough.

Or as John suggested just amplify the signal by 50. Ol' Duffer
mentioned a buffer amp. Is there one that could be used as a buffer
amp and multiply by 50 (two birds - one stone)?

Sensor B can also be run with a different sensor that would read from
0v- 3.5v so there should be no problem there. Since I am just
learning, I didn't realize that Vref had to be less than the supply.
How do I know if I need a buffer amp?

I want to learn how to do this with the PIC assembler language. I
learned C in college, so if this becomes difficult, perhaps I will go
to C, but for now time to learn something new. Just out of curiosity,
how much easier would it be to do this routine in C instead of
assembler? If it is that much easier, perhaps I would do it in a
language I know first then try assembler after I learn some more basics
like vref shouldn't go too high and the like.

Andy

6. ### Bob MonsenGuest

Use a single-supply or rail-to-rail opamp, in which A goes to the
non-inverting input, and the feedback to the inverting input is through
a precision voltage divider that creates 1/50th of the voltage of the
output. Then, with your original sensor, you have a range of from 1.5V
to 3.75V. Noise and output errors will also be multiplied accordingly.
An LM324 would work with 6V Vcc.

For the 2.5 to 6V input, just subtract 1.5V from it, using the
traditional opamp circuit, and it'll go from 1V to 4.5V.

Both of these ranges will be reasonably accurate on the PIC, and you'll
get some buffering from the opamps.

If your reference is 6V, simply use a couple of precision resistors to
divide it down to something the PIC likes. If you use the scheme above,
a 4.5V reference would be ok, if you use 5V as Vdd.
C is about 20x easier to design and debug. You'll be using division and
multiplication. The PIC18 series has multiplication in the instruction
set, but it's 8 bit multiplication. There is no division, so that will
be done in software. You can get both floating point and fixed point
libraries from microchip that you can call from assembler.

Note that you can download a free C compiler for the 12 and 16 series
from www.hitech.com (hitech-lite.)

If it is that much easier, perhaps I would do it in a
--
Regards,
Bob Monsen

If a little knowledge is dangerous, where is the man who has
so much as to be out of danger?
Thomas Henry Huxley, 1877

7. ### John PopelishGuest

A buffer amp just copies the voltage (voltage gain of 1) while
providing any current the load requires, without that current having
to come from the signal. Any opamp suitable for the input and output
voltage range can be used as a buffer or amplifier with a voltage gain
higher than 1.
(snip)

I like the MCP6022 dual rail to rail opamp when having to work with a
5 volt supply (but there are lots of others).
http://rocky.digikey.com/WebLib/Microchip/Web Data/MCP6021,2,3,4.pdf

8. ### bruce varleyGuest

One piece of advice that I still haven't taken to heart seriously. Get
familiar with how the C flag is used during subtraction. It's a bit tricky,
being the reverse of addition. You can easily get your btfsc/s instructions
the wrong way round and it all gets confusing. Good luck.

9. ### Al BorowskiGuest

Or you could just make some macros and save yourself the confusion.

ifbit macro file, bit ; easier way to think about the test/skip instructions
btfsc file, bit
endm

ifnbit macro file, bit ; easier way to think about the test/skip
instructions
btfss file,bit
endm

ifbit STATUS, Z ; Address if the Zero
goto JumpLabel ; Flag is Set
endm

ifnbit STATUS, Z ; Address if the Zero
goto JumpLabel ; Flag is Clear
endm

jc macro JumpLabel
ifbit STATUS, C
goto JumpLabel
endm

jb macro JumpLabel
ifnbit STATUS, C
goto JumpLabel
endm

jnb macro JumpLabel
ifbit STATUS, C
goto JumpLabel
endm

cheers,

Al

10. ### Luhan MonatGuest

For a lot of ideas on PIC's - See website below.

11. ### Guest

I went to www.hitech.com (hitech-lite.) and couldn't find a compiler.
I did a search and found Hitech PICC-Lite at htsoft.com.

Based on the PIC covered I figured I will upgrade from PIC16F676 to
PIC16F684 which is covered in the software. After comparing the two
for the extra couple sense it has a few nice extras.

Andy