View previous topic :: View next topic |
Author |
Message |
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
controlling a servo with 12f675 |
Posted: Wed Sep 28, 2011 8:22 pm |
|
|
is it possible to control a servo with a 12f675 I was browsing the code, on this forum and most of the codes I seen they use CCP_PWM or the servo.c and that does not work on the 12f675, can anyone point me out some same code that I can use to control a servo using a 12f675, thanks |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Wed Sep 28, 2011 8:53 pm |
|
|
are you the one selling that code? shame on you. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Wed Sep 28, 2011 9:00 pm |
|
|
What is your problem!
Actually I used Google and found this info in 30 seconds which is
something YOU should have done on your own before you came asking
for help. You can bet I won't respond to your request for help on this board
in the future.... _________________ Google and Forum Search are some of your best tools!!!! |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Wed Sep 28, 2011 9:12 pm |
|
|
dyeatman wrote: | What is your problem!
Actually I used Google and found this info in 30 seconds which is
something YOU should have done on your own before you came asking
for help. You can bet I won't respond to your request for help on this board
in the future.... |
I was just kidding cause they want $7 for that code, and is for a different compiler that has different library, but thanks anyways. |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Wed Sep 28, 2011 10:40 pm |
|
|
I did some reading on servos, and I end up doing the programs myself
the timing on mine is different cause the timing in the picture didnt work for me, so you might have to adjust it, but at the end delay 1 and delay 2 should add up to 20ms cause the servo reads the pulse every 20ms
Code: | #include <12F675.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR
#use delay(clock=4000000)
int i;
void main()
{
while(1)
{
for(i=0;i<100;i++) // 0 degrees
{
output_high(PIN_A2);
delay_us(700); // delay 1
output_low(PIN_A2);
delay_us(19300); //delay 2
} // delay 1 + delay 2 = 20000us
for(i=0;i<100;i++) //180 degrees
{
output_high(PIN_A2);
delay_us(2000);
output_low(PIN_A2);
delay_us(18000);
}
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9216 Location: Greensville,Ontario
|
|
Posted: Thu Sep 29, 2011 5:13 am |
|
|
When asking for help,you should also say WHAT type of servo you need code for. From the responses so far, you're looking for 'hobby RC type servos' NOT the 'default' servos that I work with.
There is tons of code for RC servos out there though...nothing for 3HP ones though !! |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Sep 29, 2011 7:21 am |
|
|
oh - rc hobby servos ........
a thing you would NOT know
most hobby servos do NOT need anything like the refresh rate that is spec'd.
in a project i did for hire last year - i found that HiTech brand servos needed NO refresh at all!!!
when the servo is first powered up -- idle -
it took TWO back to back pulse sequences to:
pulse 1: wake it up // but no motion
pulse 2: move to position and stay indefinitely
i think you will find that refresh time in general is not much of an issue
anyway......
you are NOT going to make a useful program with all those primitive LOOOOONG delay_ms() function calls .
my humble suggestion is to use a 16 mhz external crystal and work out
how to use timer0 to get any precise delay you want - without stalling your execution in dead-end code - ie: delay_ms(whatever)
no program worth using , ever creates delays of that duration -
the way you do - its ALL about how to use timers creatively.
thats your next homework assignment:
figure out how to tell relative time without using "delay_ms()" |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Thu Sep 29, 2011 7:54 am |
|
|
thanks, but my application is very simple, what I need to do, is press one button and the rc servo would move to 0 and press the same button again and the RC servo would move to 180, but I would look into TIMER0, when I looked at the 12f675 datasheet I didn't see it had PWM so I though it was not possible to do it that way. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Sep 29, 2011 12:27 pm |
|
|
I you setup_timer0()
with a divider of RTCC_DIV_1
then each COUNT of the timer is 1 uSec.
If you can spare the pins i would use a 16mhz crystal and set
RTCC_DIV_4 - so you get some useful clock cycles as well ;-))
BTW: the commercial product i worked on for controlling multiple multiplexed Hitech RC servos -
used an 18F part with 16mhz reference such that i could use the 16 bit Timer0 to preload the counter with the usec delay i wanted:
as in load (65536-mydelay) and then just poll for the overflow T0IF flag to tell me the delay has expired. In that 18F family it can even be handled on an interrupt basis - and you have NO foreground overhead other than
toggling the output line high - set the delay and let my #int routine clear the output line when the count is up.
NO FOREGROUND MONITOR - NO delay_MS() |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Thu Sep 29, 2011 1:27 pm |
|
|
Thanks, I'm just trying to avoid putting the crystal because all this would go in a tini box. I found this code in the forum and I was trying to figure out how to jump in the loop of 0 and in the loop of 180 by pressing a push button.
http://www.ccsinfo.com/forum/viewtopic.php?t=19874
I tried putting the code in all different loops, but still does not work,
Should I post this as a new topic? |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Sep 29, 2011 6:39 pm |
|
|
i am getting your point - you need to go very simple - and your specs dont require programmability - so i guess you are stuck with 4mhz internal
at least your instruction cycle is appx 1uSEC - there is not much you can do with that - given thta you want programmatic resolution equal to an instruction cycle. i would make the delays a couple counts SHORTER than the delay you want to allow for the cycles used in pin switchjing ;-))
your .LST file will reveal more about that |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Thu Sep 29, 2011 6:53 pm |
|
|
Thanks asmboy, what can you suggest, I will run the loop of 0 and 180 for a second and then go back to the main loop, but on the main loop how do I know what loop was on last? my idea is
Press button go to
0 degree loop
press button again go to
180 degree loop
and so on, I just trying to figure out the logic of how to jump between loops with one button. |
|
|
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
|
Posted: Thu Sep 29, 2011 11:18 pm |
|
|
I did this code and it works the only problem if I hold the button for more than 1 second it the servo keeps moving left and right, is there a way to make it so no matter how long is pressed it would stay in that location, and it would only move when I pressed again:
Code: |
#include <12F675.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR
#use delay(clock=4000000)
#define BUTTON PIN_A4
#define Right 0
#define Left 1
int i;
void main()
{
int8 ServoLocation = Left;
while (TRUE)
{
if ((input(BUTTON) == 0) && (ServoLocation == Left))
{
for(i=0;i<100;i++) //servo would move to left
{
output_high(PIN_A2);
delay_us(2000);
output_low(PIN_A2);
delay_us(18000);
ServoLocation = Right;
}
}
else if (input(BUTTON) == 0 && (ServoLocation == Right))
{
for(i=0;i<100;i++) // servo would move to right
{
output_high(PIN_A2);
delay_us(700); // delay 1
output_low(PIN_A2);
delay_us(19300); //delay 2
ServoLocation = Left;
}
}
}
} |
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Sep 30, 2011 9:33 am |
|
|
you are running afoul of several things -
the ACTION you command is all done in millisecs but you are STILL HOLDING the button TRUE - so it flips right away to the OTHER function before you can release it.
ALSO you could have contact bounce - further complicating this
what you want to do is DETECT WHEN A BUTTON IS PRESSED
but do NOTHING Until it is RELEASED - THEN enter the operating mode
and i see you DO not initialize the servo on 'wakeup' either - so i did ;-))
like this:
Code: |
#include <12F675.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR
#use delay(clock=4000000)
#define BUTTON PIN_A4
#define Right 0
#define Left 1
int i;
void leftie(void){
output_high(PIN_A2);
delay_us(2000);
output_low(PIN_A2);
// ?? delay_us(18000); // WHY THIS DELAY ???
}
void rightie(void){
output_high(PIN_A2);
delay_us(700); // delay 1
output_low(PIN_A2);
// delay_us(19300); // 19300 WHY ????? delay 2
}
void main()
{
UNSIGNED int8 ServoLocation = Left;
int1 GoMove=0;
// the fast way i would intialize this thing
leftie();
delay_ms(60); // 55 msec typical deadband max for servo
leftie();
while (TRUE){ // loop forever
// separate the BUTTON management simplistically from ACTIONS
// *--*
if (input(button)){ // BUTTON PRESSED ??
delay_ms(30); // wait short simplest debounce interval
if (input(button)){ // still PRESSED down ??
while(input(button)){}; // YES - IDLE till released
gomove=1; // move the servo NOW
} // implied ELSE IE: not held down long enuf to matter so exit
}
// now move is executed ONLY if a complete press and release was done
if (gomove) {
if (ServoLocation == Left){
leftie();
ServoLocation == Right;
}
ELSE {
rightie();
ServoLocation = Left;
}
gomove=0;
delay_ms(60); // deadband between any possible next moves
// ONLY Needed ONCE after each move
} // end go move
} //end while(1)
}// end main
|
I URGE YOU TO BEFORE doing any moves - INITIALIZE the position TWICE - as i found necessary for Hitech servos
ALSO the SECOND long delay at the END of leftie and rightie ??
makes NO Sense to me at all ?? at least not NOW
the servo ONLY needs the time HIGH controlled by the FIRST delay to
move -- with a dead band BETWEEN commands of NO MORE than the MAXIMUM move command time of abt 50 msec !!!!
if you need it for some other reason - then put it back or insert it ONCE after the GO CMD as i did for 60 msec |
|
|
|