PDA

View Full Version : Problems with Basic Servo Code



wdmagic
- 15th March 2013, 21:46
Ok Im getting confused here on why standard code for working servos does not work

OK here is the info on PULSEOUT strait from the PBP 2.6 manual


PULSOUT Pin,Period

Generates a pulse on Pin of specified Period. The pulse is generated
by toggling the pin twice, thus the initial state of the pin determines the
polarity of the pulse. Pin is automatically made an output. Pin may be
a constant, 0 - 15, or a variable that contains a number 0 - 15 (e.g. B0) or
a pin name (e.g. PORTA.0).

The resolution of PULSOUT is dependent upon the oscillator frequency. If
a 4MHz oscillator is used, the Period of the generated pulse will be in
10us increments. If a 20MHz oscillator is used, Period will have a 2us
resolution.

Defining an OSC value has no effect on PULSOUT. The
resolution always changes with the actual oscillator speed.

‘ Send a pulse 1mSec long (at 4MHz) to PortB.0
PULSOUT PORTB.0,100

Now when I used a 12F675 with Internal OSC, it ran at 4mhz Approx (I thought) and the servo worked fine using any number between 100 and 200.

Using a 12F683, Using the same Code as the 675 Chip and using Internal OSC, Code does not work, unless range is 5 - 55 ? so is the 683 internal OSC running at 8mhz?

The same code on a 18F4550 has the same effect as the 683 chip.

Here is my code for the 12F675 (I used last year, no problems)


DEFINE ADC_BITS 10 ' A/D number of bits
DEFINE ADC_CLOCK 1 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us
Res Var Word ' A/D converter result
TRISIO.0 = 1 ' RA0 (AN0) is input
TRISIO.5 = 0 ' PortB is output
AGAIN:
ADCIN 0, Res ' Read Channel 0 data
res = (res / 654) + 100 '654 = 100 to 200
PULSOUT GPIO.5, res ' Send a pulse
PAUSE 20 ' Wait 20 ms
GOTO AGAIN


Now here is the Code for the 683 (works from 5 - 55)
NOTE: I have the POT range from 0 - 255 and a seperate PIC with a LCD to tell me the number from the POT


DEFINE ADC_BITS 10 ' A/D number of bits
DEFINE ADC_CLOCK 1 ' Use A/D internal RC clock
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in us
Res Var Word ' A/D converter result
TRISIO.0 = 1 ' RA0 (AN0) is input
TRISIO.5 = 0 ' PortB is output
AGAIN:
ADCIN 0, Res ' Read Channel 0 data
res = res / 255 ' 0 to 255
PULSOUT GPIO.5, res ' Send a pulse
PAUSE 20 ' Wait 20 ms
GOTO AGAIN



And last but not least here is the code for the 18F4550
This has the display attaced to read the servo numbers being used, it also has a loop for jitter correction.
Same problem though, works from 5 - 55


INCLUDE "LCD_D.bas"
INCLUDE "ADC_Default.bas"
TRISA = 1 ' PORTA is input
TRISD = 0 ' PORTD is output
TRISB = 0 ' PORTB is output
LCDOUT $FE, 1 ' Clear LCD
PAUSE 250 ' Wait 0.5sec for LCD to initialize
Position Var WORD : Position = 0
X VAR BYTE
Mainloop:
ADCIN 0, Position ' Read ADC Channel 0 (0 - 1024)X64
position = (position / 256) ' 0 - 255
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "Servo Position = ", DEC3 position
For X = 0 to 4 ' Helps with jitters
PULSOUT PORTB.0, Position ' Change Servo to this Position
PAUSE 20 ' Wait 20 ms
Next X
GOTO mainloop ' Repeat
END



So what am I missing/doing wrong.
I would like to use the original 100 - 200 code so that I may get a resolution of 100 with the servo
And Lastly a NOTE: when I used the 100 - 200 code with the 12F675, there was never a problem with jitters!

HenrikOlsson
- 15th March 2013, 22:06
Hi,
As far as I can see the internal oscillator on the 12F683 defaults to 4MHz so I'd say you "should" be OK.
The best thing to do though is to actually measure it. If you have a scope or frequency counter then flipping an output in a loop at a "known" frequency will tell you if the PIC is indeed running at the frequency you think it is - and at the frequency you told the compiler it is. If you don't have a scope or frequency counter then a 1Hz blink should suffice to tell you if it's in the ballpark or off by a factor of two or more.

/Henrik.

wdmagic
- 15th March 2013, 23:08
Thanks for the quick reply henrik,
I decided to try my 18F4550 with a resonator @ 4mhz, and changing the range from 100 - 200. now the servo works correctly however my LCD is throwing up a several groups of arrows, o's and a couple of other symbols, and they do not change during the ontime of the circuit??? weird.

My resonator pins 1 and 3 are hooked to pins 13,14 on the 4550 and pin 2 on resonator is hooked to ground. I'm using PORTD.0-5 for my display.

Any ideas?

wdmagic
- 16th March 2013, 04:10
Further testing,
I've tried HS & XT OSC's
both of these put bad LCD Data somewhere, I even tried moving RS and E bits to another PORT. but servo works great

using INTIO or INTHS
makes the display work but not the servo (servo has to use 5-55 range non smooth operation)

I dont have a external clock right now, all I have is 4mhz resonators.
Getting a headache from this. Eventually I would like to get up to 24 servos running with USB interface, but thats a ways off.
not sure where the problem lies....

wdmagic
- 16th March 2013, 04:18
OK I JUST GOT IT TO WORK!!!

I feel like shooting someone... hehe.

I have to use the Resonator to get my 4mhz, and....

In my FUSE section I have to ENABLE "Powerup Timer"

After I did that, everything worked great, LCD and Servo & also the SERVO now has a 160 degree rotation with a resolution of 130!

Could someone explain to me what Powerup Timer is/does ?

mackrackit
- 16th March 2013, 11:38
http://www.piclist.org/techref/postbot.asp?by=thread&id=%5BPIC%5D%3A+power+Up+timer&w=body&author=Herbert+Graf&tgt=post

Acetronics2
- 16th March 2013, 18:13
INCLUDE "LCD_D.bas"
INCLUDE "ADC_Default.bas"
TRISA = 1 ' PORTA is input
TRISD = 0 ' PORTD is output
TRISB = 0 ' PORTB is output
LCDOUT $FE, 1 ' Clear LCD
PAUSE 250 ' Wait 0.5sec for LCD to initialize


or may be the NO delay :rolleyes: you have allowed BEFORE resetting is a bit short for LCD to power-up ... after having tested dozens of LCD's I generally set it to 700-800 ms ... to be sure.

LCD strange characters often come with too short a delay before sending the first command ...

Alain

wdmagic
- 16th March 2013, 19:33
Ace, glad you caught that, that used to be 500 not 250, dont know why that got changed. I've actually used a fet on the grounds of the lcd backlight to turn the backlight on and off with the pic.

also thanks mackrakit, is this something I can just turn on and leave on with all projects?

if I use the internal timer, I can include the grounds for the whole display on the fet and turn the entire display on and off even after the pic is already running with no bad effects, it only had to do the pause when useing an external/crystal timing source. which is nice because you could take and use an interupt with switch to turn on the display and backlight for X amount of time to save battery power.