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.

Sensors, Actuators, and Robotics » Servo reverse rotation/ positioning problem.

April 08, 2012
by rmore
rmore's Avatar

Hello All!

I think I am making some progress with all the electronics stuff that I have been playing with before I build a simple robot!

I have a question regarding positioning a Servo. I did go through the 3 servo related questions posted in this forum but none of them quite answered my question directly.

My servo has to rotate clockwise and anticlockwise successively. It does rotate at the start...and after securing its position it then just makes a whining sound when i switch a button to reverse its rotation.

The code is as follows:


// servo.c
// for NerdKits with ATmega168
// mrobbins@mit.edu

#define F_CPU 14745600

#include <stdio.h>

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

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// Practice for Servos

int main(void)
{
// Defining the input -: Switch when pressed operates the Servo
// Switch on PORTD - Pin0

    DDRC &= ~(1 << PINC5);  // Defining register D
    PORTC |= (1 << PINC5);  // Always high. When button pressed, it goes to 0

// Timer stuff

    // Generating PWM signal

    TCCR1A |= (1 << COM1A1) | (1 << COM1A0) | (1 << WGM11);
    TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);

    ICR1 = 294911;  // F_CPU/50Hz

    // Defining the output -: Control pin of Servo - PORTB, Pin1

    DDRB |= (1 << PINB2);   // LED on here
    DDRB |= (1 << PINB1);   // SERVO on here

    while(1)
    {
    PORTC |= (1 << PINC5);      // sets Servo pin to high
    PORTB ^= (1 << PINB2);      // toggels LED

    if (bit_is_clear(PINC,5)) 
        {
            OCR1A = ICR1 - 29491;   // 2msec = 29491; 1.5 msec = 22118; 1 msec = 14745
            // determines Servo position

            delay_ms(100);          // LED blinks faster
        }
        else 
        {
            OCR1A = ICR1 - 22118;   // 2msec = 29491; 1.5 msec = 22118; 1 msec = 14745
            // determines Servo position

            delay_ms(1000);         // LED blinks slower
        }

    }

}

  1. Comment on Line 36 uses a dividing factor of 50Hz. This was because I saw on a Youtube tutorial that '50Hz' was used since 'the Servo calls for it'. What is meant by this?

  2. Comment on Line 50 and 57 talk about positioning the Servos by creating pulse widths of 2,1.5 and 1 msec. Is this the correct way? Why does the servo not reverse-rotate after the first rotation? (The three numbers were arrived at by the following understanding: 20 msec <-> 294912. So 2 msec <-> 29491.)

Thanks for your replies in advance.

April 08, 2012
by pcbolt
pcbolt's Avatar

rmore -

There is some source code on the Nedkits tutorial page that deals with this. You'll just have to add in your own controls. Here is the link...the source code link is near the bottom of the page. The comments in the code explain quite a bit.

April 08, 2012
by missle3944
missle3944's Avatar

Rmore,

Try to use the code that the nerdkits gave you. If you have the serial line setup then you will be able to manage your servo very easily! Just build off their code!

-Dan

April 26, 2012
by rmore
rmore's Avatar

Hello!

I went through the Servo Squirter code and I did not understand a few things in it. I would appreciate it if somebody could please clarify some things in the code.

%%%%%%%%%%%%%%%%%%%

At the start of the code, there is a function defined 'pwm_set'.

      void pwm_set(uint16_t x) {
        OCR1B = x;
      }

Why is OCR1B used in this block of code? We already have OCR1A for generating the PWM. Please explain the usage of OCR1B here.

%%%%%%%%%%%%%%%%%%%%

What is the following part of the code doing? What are the ']' and '[' for? What is pos+/- = 25?

      // Wait for a character to be sent to the serial port.
      tc = uart_read();
      if(tc==']') pos+= 25;
      if(tc=='[') pos-= 25;
      if(tc=='0') PORTB &= ~(1<<PB3);
      if(tc=='1') PORTB |= (1<<PB3);

%%%%%%%%%%%%%%%%%%%%%%

I am sorry if I am asking silly questions....but I am just not getting this. I am trying to move my servo in one direction when a photoresistor outputs a value higher than some x value and move the servo in different direction when the value is lower than x. So i started going thru the code for servo squirter and came across these questions.

Thank you.

RMORE

Post a Reply

Please log in to post a reply.

Did you know that two resistors can be used to make a voltage divider? Learn more...