xplain - servo control

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
not so long ago i bought atmel xplain evaluation board
(green one with xmega128a1) and servo (futaba s3003).

Is it possible to control this servo with xplain board ? Should i have something else/more for this task ?

sorry for my poor english and thanks for any advice.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is it possible to control this servo with xplain board ? Should i have something else/more for this task ?

Quite possible - nothing more needed.

You can control a servo with the very most basic micro as long as you can change the state of an IO pin over time. The Xmega has lots of goodies to make this easier but you don't have to use that if you don't want. Just turn a pin on and somewhere between 1ms to 2ms turn it off again. 20ms later repeat the sequence.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code below will set up PWM signal on timer/counter C0 with a frequency of 50Hz. This is appropriate for servo use. This also assumes 32Mhz system clock. If you're not sure how to do that there are several posts by electronic.designer showing how.

void PWM_Init(void)
{
	/* Set PWM pin as output type */
	PORTC.DIR |= PIN0_bm;

	/* Configure Registers */
	TCC0.CTRLA = (PIN2_bm) | (PIN0_bm);
	TCC0.CTRLB = (PIN4_bm) | (PIN2_bm) | (PIN1_bm);
	
	/* Set top value */
	TCC0.PER = 5000;

	/* Set CCx value to center */
	TCC0.CCA = 375;
}

Change TCC0.CCA value to change the pulse width.
250 = 1.0ms pulse
375 = 1.5ms pulse (usually middle for servos)
500 = 2.0ms pulse

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanku you very much, i'am gonna try it :)

edit//
i'am quite noob in avr programming so i need some help again :) it's my second day playing with xplain, and i must say its pretty fun. So one more time: i would like to move servo and i have managed to write something like this:

#include 
#include "compiler.h"
#include "preprocessor.h"
#include "board.h"
#include "ioport.h"

#define IOPORT_PIN_LED LED0_GPIO
#define IOPORT_PIN_BTN GPIO_PUSH_BUTTON_0

void PWM_Init(void)
{
   /* Set PWM pin as output type */
   PORTC.DIR |= PIN0_bm;

   /* Configure Registers */
   TCC0.CTRLA = (PIN2_bm) | (PIN0_bm);
   TCC0.CTRLB = (PIN4_bm) | (PIN2_bm) | (PIN1_bm);
   
   /* Set top value */
   TCC0.PER = 5000;

   /* Set CCx value to center */
   TCC0.CCA = 375;
}


int main (void)
{
	board_init();
	ioport_set_pin_low(IOPORT_PIN_BTN);
	while(1)
	{
		if (ioport_pin_is_low(IOPORT_PIN_BTN)) {
			ioport_set_pin_low(IOPORT_PIN_LED);
		    PWM_Init();
		}else{
			ioport_set_pin_high(IOPORT_PIN_LED);
		}
	}

}

so when I press button0 on xplain led0 lights up and pwm signal should start. Whats next ? i dont really get how can i output it on PORTD of my xplain board. I think it should be on PORTD, to connect servo to pin. Servo should have +/grnd form external dc adapter and control signal from xmega ? Am i right ? Going to read atmel datasheet on timers but any help would be apprecieated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Servo should have +/grnd form external dc adapter and control signal from xmega ? Am i right ?

You also need to connect the grounds of the microcontroller and the servo together.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code I posted will set up the timer C0 on Pin C0. If you want to output on pin D0, then you should change all the TCC0 to TCD0.

If you read the xmega datasheet you will see that it has 8 timers, two on each port. Each of the 0 timers have four compare registers (CCA, CCB, CCC, CCD) which correspond to pins 0, 1, 2, 3 on each port. So TCC0.CCA corresponds to port C, pin 0. If you want to set up the servo on pin D3 for example, you would instead change the value of TCD0.CCD.

Also, if you keep the value of CCA at 375 your servo will probably not do anything since that is usually the center value.

I would also call PWM_Init at the beginning to set up the servo. Then when the button is pressed you can change the value of CCA to 500 or 250 like this.

int main (void) 
{ 
   board_init(); 
   PWM_Init(); 
   ioport_set_pin_low(IOPORT_PIN_BTN); 
   while(1) 
   { 
      if (ioport_pin_is_low(IOPORT_PIN_BTN)) { 
         ioport_set_pin_low(IOPORT_PIN_LED);
         TCD0.CCA = 500; 
          
      }else{ 
         ioport_set_pin_high(IOPORT_PIN_LED); 
      } 
   } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok, so to sum up and test this, please looka at my "hi-tec" setup :)
http://img854.imageshack.us/img854/2253/setupm.jpg

seems right ? dont really want to burn something :P

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From what I can tell, that should work fine.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yep its working, servo is moving, but its only jumping right now, hard to explain. Pressing button dont make any diference. But i think i can go by myself from here.
Thank you for help :)