View Full Version : Please help with servo
I would really like to get some servos working, and I really do not understand how to make them work. NOTHING I have tried has worked.
I have a FUTABA FP-S148 Connected to PWMA0
With the ISOPD V 0.5 and the RC-Servo Adapter. There is +5V to the ISOPOD and +5V to both sides of the RC-Servo Adapter.
All I have been able to do is get the servo to gitter a bit.
Can someone please write a short piece of code so that I can get a good understanding of how to control this servo.
I have 6 of these servos, so If I can get one working I get the others working
petegray
11-20-04, 09:50 AM
cjh,
here's one of the Small C example programs, which allows the control of a servo via a quad encoder (odd, perhaps - but the example killed two birds with one stone). Just in case it doesn't cut-and-paste very well, I'll attach it too.
There should be enough detail so that you can figure out how the servo control works...
/*+++
quad.c
Example program for the IsoPod (see http://www.newmicros.com)
Also tested on NMIN-0803-Mini.
Quadrature encoder directly controls position of servo, encoder values
displayed via SCI (e.g. hyperterm).
Quad A =PHASEA0, Quad B = PHASEB0, PWMA0 = Servo signal.
Tested with CUI Stack Quad Encoder and Hitec HS-322/422 servo.
Peter F Gray (petegray@ieee.org)
23Feb03
---*/
#include "scdefs.h"
/* SCI definitions */
#define SCI0BR 0x0F00
#define SCI0CR 0x0F01
#define SCI0SR 0x0F02
#define SCI0DR 0x0F03
/* PWM definitions */
#define FA1 0x0FA1
#define E00 0x0E00
#define E03 0x0E03
#define E05 0x0E05
#define E06 0x0E06
#define E07 0x0E07
#define E0D 0x0E0D
#define E0E 0x0E0E
#define E0F 0x0E0F
/* Quad registers */
#define E47 0x0E47
#define E48 0x0E48
/* servo left and right max values */
#define MAXLEFT 0x02E4
#define MAXRIGHT 0x0B9A
/* servo incremental movement value */
#define BIGINC 5
/* global var - servo position */
int p;
outsci (a,b)
int *a;
unsigned char *b;
{
int status;
while (*b) {
do status = *SCI0SR; while ((status&0xC000)!=0xC000);
*a = *b;
*b++;
}
do status = *SCI0SR; while ((status&0xC000)!=0xC000);
}
outscichar (a,b)
int *a;
unsigned char *b;
{
int status;
do status = *SCI0SR; while ((status&0xC000)!=0xC000);
*a = *b;
do status = *SCI0SR; while ((status&0xC000)!=0xC000);
}
outscihex (a,b)
int *a;
int b;
{
int c,r,neg;
char t[5];
c = 3; neg = 0;
if ((b&0x8000)==0x8000) { /* test for sign bit */
neg = 1;
b &= 0x7FFF; /* remove if found */
}
while (c>=0) {
r = b&0x000F;
if (r < 10)
t[c] = '0'+r;
else
t[c] = 'A'+((r)-10);
b >>= 4;
c--;
if (neg&&(c==0)) b |= 0x0008; /* put sign bit back */
}
t[4] = 0;
outsci (a,t);
}
/* move servo to new position */
moveto (newpos)
int newpos;
{
int status;
*E06 = newpos;
status = *E00;
*E00 = 0x00C3;
}
/* main program */
main ()
{
int r, pmid;
*SCI0BR = 130; /* set up SCI registers */
*SCI0CR = 12; /* 9600, 8N1 */
*FA1 = 0xF413; /* set up PWM registers */
*E03 = 0x8000;
*E05 = 0x61A8;
*E0D = 0;
*E0E = 0;
*E0F = 0x000E;
outsci (SCI0DR,"\15\nSystem Ready\15\n");
/* calculate starting (mid) point */
p = pmid = (MAXLEFT + MAXRIGHT) / 2;
moveto (p);
while (1) { /* loop forever */
r = *E47; /* read quad position (upper) */
outscihex (SCI0DR,r);
r = *E48; /* read quad position (lower) */
outscihex (SCI0DR,r);
outsci (SCI0DR,"\15");
p = pmid + (r*BIGINC); /* calculate new servo position */
/* and adjust if out-of-bounds */
if (p>MAXRIGHT) {p = MAXRIGHT; *E48 = (MAXRIGHT-pmid)/BIGINC;}
if (p<MAXLEFT) {p = MAXLEFT; *E48 = (MAXLEFT-pmid)/BIGINC;}
moveto (p); /* move servo to new position */
}
}
petegray
11-20-04, 09:58 AM
Hmmm, not sure if the cut-and-paste or the attachment worked too well. You could download from here...
http://petegray.newmicros.com/smallc_progs.zip
... unzip, and look at "quad.c"
Regards,
-Pete.
RMDumse
11-20-04, 08:03 PM
Originally posted by cjh
I have a FUTABA FP-S148 Connected to PWMA0
With the ISOPD V 0.5 and the RC-Servo Adapter. There is +5V to the ISOPOD and +5V to both sides of the RC-Servo Adapter.
All I have been able to do is get the servo to gitter a bit.
Since you say "ISOPD V 0.5" I guess you're using IsoMax(TM) and the small C may not be what your looking for exactly.
It's hard for me to remember what improvements came to the language when, but I think we had PWM-PERIOD and PWM-OUT in the language by then.
If not, I can give you some code to go right to the registers, but lets try this first. You should just be able to download this interactively, and the Servos should snap too, in mid position.
DECIMAL ( default on cold start anyway
32767 PWMA0 PWM-PERIOD
7500 PWMA0 PWM-OUT ( Servo 0
7500 PWMA1 PWM-OUT ( Servo 1
7500 PWMA2 PWM-OUT ( Servo 2
7500 PWMA3 PWM-OUT ( Servo 3
7500 PWMA4 PWM-OUT ( Servo 4
7500 PWMA5 PWM-OUT ( Servo 5
To choose another position, pick a number between 5000 and 10000 and do PWMAx PWM-OUT where x is the servo number you want to move. Most servos can go outside the 90 degrees of the spec, so experiment with your limits, but at the risk of stripping gears if your pulses get too short (under 5000) or too long (over 10000)
Now, to accomplish the same thing directly to the registers of an IsoPod(TM) which is 805 based, we could work easier in hex
HEX
8000 E03 !
0 E0D !
0 E0E !
000E E0F ! ( CENTER ALIGN FOR DIV BY 2
7FFF E05 !
1D4C E06 !
1D4C E07 !
1D4C E08 !
1D4C E09 !
1D4C E0A !
1D4C E0B !
E00 @ DROP C3 E00 !
To change position you alter the value stored in E06 for Servo 0 and so on, then repeat the
E00 @ DROP C3 E00 !
line which is necessary to get the value to load.
One of those methods should get you going. Let us know.
vBulletin v3.0.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.