Programming ATtiny13 with Arduino Uno to control a Servo Motor

Published  August 2, 2019   1
Programming ATtiny13 with Arduino Uno to control a Servo Motor

Servo motor works on the principal of Pulse Width Modulation (PWM) and its angle of rotation is controlled by the duration of the pulse applied to its control pin. Here in this tutorial we will control a servo motor with ATtiny13 microcontroller using PWM technique. So before going any further we will first learn about PWM, Servo Motor and how to program ATtiny13 with Arduino Board.

 

Pulse Width Modulation (PWM)

Pulse Width Modulation (PWM) is defined as a method for generating an analog signal using a digital source. A PWM signal consists of two main components- duty cycle and frequency. These components define its behavior. Duty cycle describes the amount of time the signal is in a high state. It is denoted as a percentage of the total time it takes to complete one cycle.

Duty Cycle =Turn ON time/ (Turn ON time + Turn OFF time)

 

The frequency defines how fast the PWM completes a cycle and how fast the signal switches between high and low states. A frequency of 100Hz means 100 cycles per second. By switching a digital signal ON and OFF at a fast rate and with a certain duty cycle, the output will appear like a constant voltage analog signal. One of the powerful benefits of PWM is that the power loss is very minimal.

 

PWM signals are used for a variety of control applications. The main purpose of the PWM signal is to control the power that is supplied to various electrical devices, especially to inertial loads such as AC/DC motors. It can also be used to control pumps, valves, hydraulics, and other mechanical parts. The frequency of the PWM signal depends upon the application and the response time of the device that is being powered.

 

Controlling Servo Motors using PWM signals

A servo motor consists of three wires, out of which two are used for power supply (positive and negative) and one control wire is used for the signal that is to be sent from the microcontroller. A servo motor is basically made up of a DC motor which is controlled by a potentiometer and some gears. The high speed force of a DC motor is converted into torque by the gears. In a DC motor force is less and speed is high where as in a servo motor, force is high and speed is less. The potentiometer is connected to the output shaft of the servo motor to calculate the angle and to stop the DC motor on the required angle. To learn more about Servos follow the detailed article on Servo Motor.

 

Servo motor is controlled by pulse width modulation (PWM) or sending an electrical pulse of variable width, through the control wire. There will be a repetition rate, a minimum pulse, and a maximum pulse. A servo motor can turn 90o in either direction from its neutral position for a total movement of 180o. The motor’s neutral position is where the servo has the same amount of potential rotation in both the clockwise and counter-clockwise direction. The PWM signal sent to the motor determines the position of the shaft. The rotor will turn to the desired position based on the duration of the pulse sent through the control wire. The servo motor expects a pulse every 20 milliseconds (ms) and the length of the pulse determines how far the motor will turn.

A servo motor can be rotated from 0 to 180 degree. When a 1.5ms pulse is given to the control wire the motor will turn to the 90o position. When a pulse shorter than 1.5ms is given, the motor will move in the counter-clockwise direction towards the 0o position. If a pulse longer than 1.5ms is given, then the motor will turn in a clockwise direction towards the 180o position.

 

All servo motors work directly with +5V supply, but we have to be careful on the amount of current the motor would consume. If we are using more than two servo motors a proper servo shield should be designed.

Before Connecting Servo to Attiny13, you can test your servo with the help of this Servo Motor Tester Circuit. Here we have interfaced servo motor with many microcontrollers:

 

Programming ATtiny13 using Arduino

Attiny13 can be programmed using Arduino Uno or any other Arduino board. Connect Attiny13 to Arduino Uno as shown in the figure below.

  • Arduino 5V – ATtiny13 pin 8
  • Arduino GND – ATtiny13 pin 4
  • Arduino pin 13 – ATtiny13 pin 7
  • Arduino pin 12 – ATtiny13 pin 6
  • Arduino pin 11 – ATtiny13 pin 5
  • Arduino pin 10 – ATtiny13 pin 1

 

Circuit Diagram for Programming ATtiny13 using Arduino

 

Arduino is set as a programmer to program ATtiny13. This is done by uploading ArduinoISP sketch to Arduino. This Arduino sketch is available inside the examples in Arduino IDE. Open the Arduino IDE and go to Files > Examples > ArduinoISP.

Programming ATtiny13 using Arduino

 

Now the program for ArduinoISP will pop up. Upload the program to the Arduino Uno.

Upload Program in ATtiny13 using Arduino

 

Arduino Uno is now ready to program Attiny13. But we have to set up the Attiny by installing its core files. To do this go to File>>Preferences in Arduino IDE

Set Program Preference in ATtiny13 using Arduino

 

Then a new window will pop-up. And in the “Additional Board Manager URL’s” add the below link and click “OK”.

https://raw.githubusercontent.com/sleemanj/optiboot/master/dists/package_gogo_diy_attiny_index.json 

Set Board Manager for Programming ATtiny13 using Arduino

 

Now in your Arduino IDE go to Tools>>Board>>Boards Manager

Select Board Manager for Programming ATtiny13 using Arduino

 

Then another window will pop-up where in search box type ‘Attiny’ then you will get “DIY ATtiny” then click on ‘install’ button (I already installed it, that is why the install button in gray colour)

Install ATtiny13 Library in Arduino IDE

 

To start programming ATtiny 13, we must burn Bootloader to it. For that, go to Tools > Board > ATtiny13.

Burst Bootloader in ATtiny using Arudino IDE

 

Now go to Tools > Processor version and check whether the correct version of ATtiny is selected. Select either ATtiny13 or ATtiny13a depending on your chip.

Then click Burn bootloader button at the bottom of the Tools menu.

Burning Bootloader in ATtiny using IDE

 

After burning the bootloader, ATtiny is now ready to be programmed. Now you can upload your program.

 

Components Required

  • ATtiny13 Microcontroller
  • Servo motor
  • Potentiometer
  • +5V battery
  • Arduino IDE
  • Connecting wires

 

Circuit Diagram and Working

Circuit diagram to control a servo motor using pot with ATtiny13 is given below.

Circuit Diagram for Controlling a Servo Motor using Pot with ATtiny13

 

Below are the connections

  • Connect the servo motor control pin to  pin 5 of ATtiny13
  • Connect ground of servo motor to pin 4 of ATtiny13
  • Connect VCC of servo motor to pin 8 of ATtiny13
  • Connect middle pin of potentiometer to pin 7 of ATtiny13
  • Connect the first and third pins of potentiometer to the VCC and GND.
  • Connect the positive of +5V battery to the pin 8 of ATtiny13
  • Connect the negative of +5V battery to the pin 4 of ATtiny13

 

Circuit for Connecting ATtiny13 with Servo Motor.

 

A potentiometer is connected to the pin 7 (PB2) of the ATtiny13 and the control wire of the servo motor is connected to pin 5 (PB0).

Programming ATtiny13 with Arduino Uno to control a Servo Motor

 

Here the potentiometer value is read and it is converted to a value between 0 and 180. Then this angle value is converted to microseconds and a pulse is given to the control pin of servo motor with the calculated microseconds delay. Now the servo motor will turn according to the value of the potentiometer as demonstrated in the video given below.

Code

#define F_CPU 9600000
int servo = PB0;  //connect servo to PB0
long angle;
int pwm;
#include <avr/io.h>
void adc_setup (void) 
{
    // Set the ADC input to PB2/ADC1
  ADMUX |= (1 << MUX0);
  ADMUX |= (1 << ADLAR);
  // Set the prescaler to clock/128 & enable ADC
  // At 9.6 MHz this is 75 kHz.
  ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}
int adc_read (void)
{
  // Start the conversion
  ADCSRA |= (1 << ADSC);
  // Wait for it to finish
  while (ADCSRA & (1 << ADSC));
  return ADCH; // return the value
}
void setup()
{
  pinMode(servo, OUTPUT);  // set servo as output pin
}
void loop ()
{
  long a;
  adc_setup();  
  a = adc_read();  // read the potentiometer value
  angle = (a * 3) / 2; // convert the reading to angle between 0 and 180.
  servoPulse(servo, angle);  // call the servoPulse function.
}
void servoPulse (int servo, int angle)
{
  pwm = (angle * 11) + 500;    // Convert angle to microseconds
  digitalWrite(servo, HIGH);
  delayMicroseconds(pwm);
  digitalWrite(servo, LOW);
  delay(50);                   // Refresh cycle of servo
}

 

Video

Have any question realated to this Article?

Ask Our Community Members

Comments

I'm a newbie just trying to make sense of stuff. I liked your example.

In your example,

// Set the prescaler to clock/128 & enable ADC

you set the prescalers as 

ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);

should that have been 

ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);