NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Problems programming continuous servo

June 15, 2012
by Jacp
Jacp's Avatar

Hello,

I'm challenging myself with this little summer project of mine. My goal is to make an automated curtain opener/closer by using a servo(that I have fixed for continuous rotation), some line and a pulley.

I used a normal pushbutton(see overview) and connected it to my mikrocontroller(uC). I programmed the uC so that the servo should rotate one way at the same speed while holding button down. Not holding button down was supposed to keep the servo still.

What really happened was that pressing the button down during different times would make the servo rotate in different speeds. Not holding the pushbutton down worked as it should.

Anyone got any ideas of what might be the solution or problem in code?

Code is as follows:

#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"

#define PWM_MIN 1842 //1299
#define PWM_MAX 3685 //4449

#define PWM_START 2763 //2764

void pwm_set(uint16_t x) {
  OCR1B = x;
}
//Used when Normal rotation
void pwm_init(){

    //Periode 20ms
    OCR1A = 36864;

    //Compare value
    pwm_set(PWM_START);

    TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10);
    TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);

}
//Used when No Rotation
void pwm_init2(){

    //0 ms periode
    OCR1A = 0;

    //Compare value 0
    pwm_set(0);

    TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10);
    TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);
}

unsigned int GetSW1(){
    unsigned int SW1;

            SW1 = (PINC & (1<<PC0));
            return SW1; 
}

int main() {

    uint16_t pos = PWM_START;

    // Set PB2 as output
    DDRB |= (1<<PB2);// | (1<<PB3);

     //Set switches to input
     DDRC &= ~(1<<PC0); //Set PC0 to input
     DDRC &= ~(1<<PC1); //Set PC1 to input

     PORTC |= (1<<PC0); // turn on internal pull up resistor for PC0
     PORTC |= (1<<PC1); // turn on internal pull up resistor for PC1

    //This while loop is supposed to rotate normally when push button is pressed down, and don't rotate at all when push button is unpressed.
    while(1){

        //When button is pressed
        if(GetSW1()==0)
        {
             // Start PWM
                pwm_init();

            pwm_set(3685);

        //When button is unpressed
        }else { 
                //Start no rotate PWM
                pwm_init2();
                } 
    }

  return 0;
}

Here are some pictures to get an understanding of my project.

System_Overview

Pulley

uC_overview

July 04, 2012
by Jacp
Jacp's Avatar

Fixed after calibrating servo properly!

Post a Reply

Please log in to post a reply.

Did you know that interrupts can cause problems if you're not careful about timing and memory access? Learn more...