MetkuMods

How to get started with microcontrollers - Part 2

Interfacing with a computer, controlling motors, servos etc.
 
Author: Aki Korhonen
Published: 06.05.2009
In English In English
Suomeksi Suomeksi

Example 2.4 - Low resolution servo controller using PWM

Thing to learn: external interrupt (button press activates an interrupt so we can use it instead of polling the button all the time)

One more PWM example. This time a low resolution (only ~30 steps) servo controller.

Parts:
  • ATiny45
  • 100 nF capacitor
  • Push button
  • 10k ohm resistor
  • Standard R/C servo motor
 

How to get started with microcontrollers - Part 2
Example 2.4

 

How to get started with microcontrollers - Part 2
Example 2.4


/**
* MetkuMods - http://metku.net/
* How to get started with AVR microcontrollers, part 2
* Example 2.4 - Low resolution servo controller using PWM
*
* Author: Aki Korhonen
* Date: 2009-04-29
*/

// If clock speed isn't set in the project settings then it is set here
#ifndef F_CPU
	#define F_CPU 1000000UL // 1 MHz
#endif

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

#include <inttypes.h>
#include <util/delay.h>

// Servo at PB0, OCR0A
#define SERVO_PIN 0

// Button at PB2, INT0
#define BTNPIN 2

// Predefined Servo position values for OCR0A
// You might want to fine tune these for your own servo
#define SERVO_LEFT 7
#define SERVO_CENTER 22
#define SERVO_RIGHT 35

uint8_t position = 1;

int main(void)
{
	// PB2 input, others output
	DDRB = 0b11011;

	// Enable internal pull-up resistor on PB2 and set others low
	PORTB = 0b00100;

	// -------------------------
	// Initialize external interrupt 0 (INT0)
	
	// The falling edge of INT0 generates an interrupt request (hi -> low)
	MCUCR |= (1<<ISC01);

	// Enable INT0
	GIMSK |= (1<<INT0);
	
	// Enable global interrupts
	sei();
	
	// -------------------------
	// Initialize PWM

	// Fast PWM
	TCCR0A |= (1<<WGM01) | (1<<WGM00);

	// Clear OC0A/OC0B on Compare Match
	// Set OC0A/OC0B at BOTTOM (non-inverting mode)
	TCCR0A |= (1<<COM0A1);

	// Set prescaler to 64
	// 1 MHz / 64*256 = 61 Hz PWM frequency
	TCCR0B |= (1<<CS01) | (1<<CS00);

	// -------------------------

	// Start with the servo in center position
	OCR0A = SERVO_CENTER;
	
	while(1)
	{
		// No need to poll the button here because the button
		// press will be handled in the interrupt handler
	}

	return 0;
}

// Interrupt handler for INT0
// Cycles through the predefined servo positions
ISR(SIG_INTERRUPT0)
{
	cli();

	switch(position)
	{
		case 0:
			OCR0A = SERVO_LEFT;
			break;
		case 1:
			OCR0A = SERVO_CENTER;
			break;
		case 2:
			OCR0A = SERVO_RIGHT;
			break;
		default:
			break;
	}

	position++;

	if(position == 3)
		position = 0;
	
	_delay_ms(300);

	sei();
}





Pages:  1 2 3 4 5 6 


 
  Content in english!
  Sisältö suomeksi!

 Google




Add to Technorati Favorites
add
add
add
add
add

 .:Back to top Bandwidth by Mpoli

Copyright © Metku.net, All Rights Reserved.
All content and graphics in MetkuMods are sole property of Jani Pönkkö and may not be reproduced or copied in any manner without written permission from him.
All brand names, trademarks and copyrights are the property of their respective owners.Privacy Policy