PDA

View Full Version : PIC16F676 Problem



Atom058
- 18th April 2007, 16:16
Hello - I am trying to use a 676 to control a servo motor via a pot using RCTIME. I have done this many times with other PICs with no problem but for some reason I can't get it to work with the 676. I have poured over the posts and the datasheet and still no results. When I power up the PIC, the servo runs over full clock-wise and pegs out. Any ideas on what I am missing? Thanks! Atom058

Here is the code:

@ DEVICE pic16F676, INTRC_OSC_NOCLKOUT

CMCON = 7
ANSEL = %00000000 ' Turn off analog input
TRISC = %00000001

RCVal var Word
Posit var word

PotIn var PORTC.0
Servo var PORTC.3

low servo

MoveServo:
gosub ReadPot
posit = rcval + 350
PULSOUT Servo, posit ' move the servo
pause 25
goto MoveServo

ReadPot:
high potin
pause 1
rctime potin, 1, rcval
return

End

skimask
- 18th April 2007, 16:29
@ DEVICE pic16F676, INTRC_OSC_NOCLKOUT
cmcon=7 : ansel=0 : trisc=1 : posit var word : servo var portc.3 : low servo
main:
for posit = 1000 to 2000 : pulsout servo,posit : pause 15 : next posit
for posit = 2000 to 1000 step -1 : pulsout servo,posit : pause 15 : next posit
goto main

That should run your servo back and forth.
If it does, you've got problems with your POT input.
If it doesn't, you've got problems with your servo hookup.
But you probably already knew that.
Your offset of 350 might be wrong.
Try using the POT command instead of RCTIME.

Atom058
- 18th April 2007, 17:42
Thanks Skimask. I tried your code and it did the same thing. The problem must be on my board. I will look closer at my circuit and let you know what I find. Atom058

skimask
- 18th April 2007, 17:44
Thanks Skimask. I tried your code and it did the same thing. The problem must be on my board. I will look closer at my circuit and let you know what I find. Atom058

My program was flawed. Timing isn't right for a 4mhz oscillator.
Try replacing the 1000 and 2000, with 100 and 200.

In fact, in your original program, change the line:

posit = rcval + 350

to

posit = rcval

and see what happens.

The pulsout command at 4mhz sending out pulses in increments of 10us.
You're minimum pulse width the way you wrote the program would automatically send out a pulse width of 3500us (3.5ms) which is above the 2ms (average) pulse width for a servo. If this works, post back. You might only have a little bit of POT movement for a lot of servo movement, but that part of the program can be rewritten to compensate for that. (think pause statement instead of pulsout)

Atom058
- 19th April 2007, 00:45
Skimask - Thanks for the info - this would explain why I have been able to do this task on other chips - I have always been using a 20 mHz resonator. This is the first time that I am not. I'll try this out and post my results.
Thanks again!

Atom058
- 19th April 2007, 15:48
Skimask - Your info worked perfectly. My pot-controlled servo is now working just fine! Thanks for your help!!!

Here is my updated code:

@ DEVICE pic16F676, INTRC_OSC_NOCLKOUT

CMCON = 7
ANSEL = %00000000 ' Turn off analog input
TRISC = %00000001

RCVal var Word
Posit var word

PotIn var PORTC.0
Servo var PORTC.3

low servo

MoveServo:
gosub readpot

'produce a value between 75 and 255 when running at 4 mhz
posit = 75 + rcval + (rcval / 2)

'produce a value between 350 and 950 when running at 20 mhz
'Posit = 350 + RCVAL

PULSOUT Servo, posit ' move the servo
pause 25
goto MoveServo

ReadPot:
'At 4 mhz, returns 0-120. At 20 mhz, returns 0-600
' with a 10K pot and 0.1 uf cap
high potin
pause 1
rctime potin, 1, rcval
return

End

skimask
- 19th April 2007, 16:05
I think I'd change your 'Pause 25' to something a bit lower.
Servo's want to be updated at about 50-60hz. You've got it set up for no more than 37hz update rate (pause 25 + 1ms minimum pot read + 1ms minimum pulsout).
I'd put it somewhere around Pause 14 or so...to give a minimum of 50hz.