Author Topic: please help me cure my servoes  (Read 2150 times)

0 Members and 1 Guest are viewing this topic.

Offline njubiTopic starter

  • Beginner
  • *
  • Posts: 2
  • Helpful? 0
please help me cure my servoes
« on: April 16, 2007, 04:07:02 PM »
could somone please compile my c program for running 4 servoes and see if your servoes also jidders?
im affraid its my program thats wrong sins i have tried all other things to get them to stand still...
im using an atmega 16 microcontroller
(the program is in norwegian, but i have translated most words...)

my goal is to build somthing like this:
http://www.lynxmotion.com/images/jpg/bratgrp2.jpg

in this program the servoes just goes back and forth... for testing...

Quote
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>

// ****strukturer****

typedef struct {
   unsigned long teller; // teller = counter in english
   unsigned char flag;
   } timer_type;

timer_type T1, servo1_timer, servo2_timer, servo3_timer, servo4_timer;

// ***Avbruddsrutine***

SIGNAL(SIG_OUTPUT_COMPARE1A) {

OCR1A+=400;

if(T1.teller !=0){
   T1.teller--;
   
   if((T1.teller==0))
   T1.flag=1;
   }


if (servo1_timer.teller !=0){
   servo1_timer.teller--;

   if ((servo1_timer.teller==0))
   servo1_timer.flag=1;
   }

if (servo2_timer.teller!=0) {
   servo2_timer.teller--;

   if ((servo2_timer.teller==0))
   servo2_timer.flag=1;
   }

if (servo3_timer.teller !=0){
   servo3_timer.teller--;

   if ((servo3_timer.teller==0))
   servo3_timer.flag=1;
   }

if (servo4_timer.teller !=0){
   servo4_timer.teller--;

   if ((servo4_timer.teller==0))
   servo4_timer.flag=1;
   }

}

// ***Deklarerer tilstander***

static enum {av1,paa1} servo1=av1;
static enum {av2,paa2} servo2=av2;
static enum {av3,paa3} servo3=av3;
static enum {av4,paa4} servo4=av4;
static enum {en,to,tre,fire} tilstand=en; //en,to,tre,fire = one, two, three and four in english

   unsigned char pos1=0;
   unsigned char pos2=0;
   unsigned char pos3=0;
   unsigned char pos4=0;

// ***oppdaterer posisjon***

void oppdater(void) {

   if (T1.flag!=0) {
switch(tilstand) {

case en: // one
   
   pos1=10;
   pos2= 30;
   T1.teller = 10000;
   T1.flag=0;
   tilstand=to;
   break;
case to: // two
   pos2 = 10;
   pos1=30;
   T1.teller = 10000;
   T1.flag=0;
   tilstand=tre;
   break;
case tre: //three
   pos3 = 10;
   pos4=30;
   T1.teller = 10000;
   T1.flag=0;
   tilstand=fire;
   break;
case fire: // four
   pos4 = 10;
   pos3=30;
   T1.teller = 10000;
   T1.flag=0;
   tilstand=en;
   break;

   }//endswitch

   }//endif1
}//endtest


//***initialiserer timer***

void init_timer1(void) {
   TCCR1A=0;
   TCCR1B=(1<<CS10);
   TCNT1=0;
   OCR1A=400;
   TIMSK=(1<<OCIE1A);
   sei();
   }


//***initialiserer porter***

void init_porter(void) {

   DDRB=0xFF; //OUT
   PORTB=0xFF;
   
   DDRA=0; //INN
   DDRD=0xFF;
   PORTD=0;
   }

//***oppdaterer servoer*** (servo update)

void servo_oppdater(servopos1,servopos2,servopos3,servopos4) {
switch(servo1){
         case paa1:
            if(servo1_timer.flag==1) {
            servo1=av1;
            servo1_timer.flag=0;
            servo1_timer.teller=(400-servopos1); // 20 ms
            PORTD&=(char)(~1);
            }
            break;

         case av1:
            if(servo1_timer.flag==1) {
            servo1=paa1;
            servo1_timer.flag=0;
            servo1_timer.teller=(12+servopos1);
            PORTD|=1;
            }
            break;
            }

switch(servo2){
         case paa2:
            if(servo2_timer.flag==1) {
            servo2=av1;
            servo2_timer.flag=0;
            servo2_timer.teller=(400-servopos2);
            PORTD&=(char)(~2);
            }
            break;

         case av2:
            if(servo2_timer.flag==1) {
            servo2=paa1;
            servo2_timer.flag=0;
            servo2_timer.teller=(12+servopos2);
            PORTD|=2;
            }
            break;
            }

switch(servo3){
         case paa3:
            if(servo3_timer.flag==1) {
            servo3=av1;
            servo3_timer.flag=0;
            servo3_timer.teller=(400-servopos3);
            PORTD&=(char)(~4);
            }
            break;

         case av3:
            if(servo3_timer.flag==1) {
            servo3=paa1;
            servo3_timer.flag=0;
            servo3_timer.teller=(12+servopos3);
            PORTD|=4;
            }
            break;
            }

switch(servo4){
         case paa4:
            if(servo4_timer.flag==1) {
            servo4=av1;
            servo4_timer.flag=0;
            servo4_timer.teller=(400-servopos4);
            PORTD&=(char)(~8);
            }
            break;
            

         case av4:
            if(servo4_timer.flag==1) {
            servo4=paa1;
            servo4_timer.flag=0;
            servo4_timer.teller=(12+servopos4);
            PORTD|=8;
            }
            break;
            }

} //end switch

//**********MAIN**************

void main(void){
   init_porter();
   init_timer1();
   sei();
   pos1=0;
   pos2=0;
   pos3=0;
   pos4=0;
   servo1_timer.flag=1;
   servo2_timer.flag=1;
   servo3_timer.flag=1;
   servo4_timer.flag=1;
   T1.teller = 10000;
   T1.flag=0;
   while(1) {
   servo_oppdater(pos1,pos2,pos3,pos4);
   oppdater();
   } //end while
   } //end main


Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,659
  • Helpful? 169
    • Society of Robots
Re: please help me cure my servoes
« Reply #1 on: April 19, 2007, 11:47:53 AM »
hmmm i cant seem to figure out your code . . .

have you tried my method of doing servos?
http://www.societyofrobots.com/downloads/sbs_source_photovore_v1.zip

when sharing code, its really really good to put comments up the wazoo so others have less trouble figuring it out (and so you can figure out your own code a year after programming it)

as for servo jerking, making sure you do the following things:
servo off -> servo on -> servo off (not the inverse)
make sure about 20ms pass before the next square wave going to the servo
make sure there isnt electrical signal interference causing false PWM

hope this helps . . .
« Last Edit: April 19, 2007, 12:33:17 PM by Admin »

Offline dunk

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 1,086
  • Helpful? 21
Re: please help me cure my servoes
« Reply #2 on: April 19, 2007, 12:28:39 PM »
ok, glancing through your code it looks like you are trying to do the right sort of thing.
i *think* the problem might be you are trying to send the pulses too close together.
in the line
Quote
            servo1_timer.teller=(400-servopos1); // 20 ms

try increasing 400 to a higher value.

with servos it doesn't matter too much how often you sent the pulse, as long as the pulse is the right length.

so, that's what i think is causing your problem.
just for the record though, here's a list of things that have caused servo jitter on my projects in the past:
1. too short a gap between pulses. (this is what i described above.)
2. too long a gap between pulses. (this tends to cause the servo to make larger random movements rather than the slight vibration you are describing.)
3. unclean power supply. (try using a different power source. use more capacitors. i saw this once on a board powered from a laptop USB port. weird hu?)
4. interupt from different microcontroller peripheral being called during timing pulse. (i don't think this is your problem as you don't have any interupts other than your timer enabled.)
5. USART being enabled on AVR ATMEGA8. i don't know if this is a problem on other AVRs but i have found the timer on the ATMEGA8 doesn't keep time precisely if you switch the USART on. (again, this is not causing your problem. i'm just putting it in here to be complete.)

so the other thing you could try is using someone else's servo controll program to test your hardware.
there is an example servo controll program in the /examples directory of http://hubbard.engr.scu.edu/avr/avrlib/.

let us know how you get on,

dunk.

Offline njubiTopic starter

  • Beginner
  • *
  • Posts: 2
  • Helpful? 0
Re: please help me cure my servoes
« Reply #3 on: May 04, 2007, 03:30:09 PM »
well, the problem i solved. i had to move the case where i say the gate should go high or low into the interrupt routine. maby it shouldt have been obvious, but im new to programming C, or everything else for that sake...
(please dont correct my writing errors, i know i suck...)
tnx for all the help!

tnx to whoever made society of robots! great site! =)

 


Get Your Ad Here