Pulse Width Modulation - Servo position control

Embedded Systems Programming
Servos
Elementary Robotics with Servos
Pulse-Width-Modulation - Revisited
1
Recall - Pulse Width Modulation
PWM means controlling the relative widths of the positive and negative parts
of an output waveform, whilst keeping the pulse frequency constant.
PWM thus controls the amount of energy in the waveform (used to regulate
the speed of a motor, the brightness of a light etc.).
The proportion of time the signal is on is called the ‘duty cycle’:
A duty cycle of 100% means that maximum energy is provided, and a duty
cycle of 0% means that minimum energy is provided to the controlled device.
A square wave has a 50% duty cycle.
Duty Cycle
25%
50%
75%
2
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Recall - Pulse Width Modulation on ATmega1281 using Timer/Counter 0
All three Timer/Counters on the ATmega1281 are capable of producing a
PWM output pulse. Timer/Counter 0 is used for illustration.
‘Overflow’
Interrupt can be
generated at start
of new pulse
‘Output Compare’
Interrupt can be
generated at the
switchover point
in the pulse
Direct output of
pulse waveform
onto the OC0A pin
(bit 7 of Port B)
3
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Servos - what is a servo
A servo is an actuator that provides precision rotational movement
To achieve this, a servo comprises:
A motor
A gearbox
A positional feedback system
A control circuit
The gearbox provides an overall ratio of about 1,000:1 to 5000:1
And enables a very small, but fast motor running on about 4-6 Volts at a few
milliamps, to generate very high torque, but at much slower rotational speed.
Positional feedback is provided via a shaft encoder.
Programming of position is achieved by adjusting the width of the control pulse sent to
the servo.
A control circuit converts the pulse-width into a ‘position’ value, and uses the positional
feedback to move the motor to the correct position and hold it there.
4
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Applications of Servos Vs Motors
Generally -
Motors are used to provide motion
Servos are used to provide positional control
Servos provide precision positioning – such as in machinery, robotics.
Miniature servos are used in:
Electronic cameras etc – for focus control, zoom etc.
Toys and models (cars, boats, aeroplanes, helicopters etc.)
Servos are better than motors for accuracy
But are:
More expensive
Slower because of heavy gearing
More complex to control
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
5
Servo - Architecture
Input signal is a pulse, the
pulse-width indicates the
desired position of the servo
Output shaft
Servo control
circuit
Motor
Gearbox
Control signal
drives motor in
either direction
Rotational-position feedback
Shaft-encoder provides
rotational position feedback
Optical type illustrated, but
can also be magnetic, or
based on a potentiometer
6
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Servo - Control
The servo position is indicated by a repeated pulse:
• The width of the pulse is decoded by the servo control circuit, and converted into a
‘target’ position
• The servo motor is then powered on until the positional feedback indicates that the
target position has been reached.
• The servo motor is continually powered to hold this position – until the pulse-width
changes, indicating a new position.
The pulse-width is typically in the range 500 microseconds to 2500 microseconds, and
servo rotational angle is typically 180 degrees. Thus:
• Pulse of 500µS indicates fully anticlockwise,
• Pulse of 2500µS indicates fully clockwise,
• Pulse of 1500µS indicates centre position.
The pulse is repeated at a typical rate of 18 milliseconds, thus the timing looks like:
Pulse (P)
2500µS
500µS
Equivalent
servo
position
Interval (I) = 18 ms typical
7
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
SERVO - Typical characteristics
'Standard' SERVO - Such as - (WWW.GWS.COM.TW
Part number S03N STD)
3-Wire system (no feedback) Red 5V, Black 0V, White\Yellow 3-5V control pulse
Pulse width to control position 0.5ms – 2.5ms ("1.5ms neutral")
Pulse rate, approximately every 18ms
Torque 3.4Kg / cm
Rotation 180 degrees +/- 10 degrees
Current draw standby about 8mA, maximum about 550mA
General purpose
servo
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
8
Servo - Control circuit
Control circuit
usually contains a
microcontroller, or
a custom logic
chip
9
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Servo – Gears and positional feedback
Shaft
encoder
Servo
output
(to servo
horn)
Gear
train
Motor
output
shaft
10
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Pulse Width Modulation Servo position control (1)
A 1500 microsecond pulse
moves the servo to its
central position
11
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Pulse Width Modulation - Servo position control (2)
750 microseconds pulse
1500 microseconds pulse
2250 microseconds pulse
12
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Programming – Generating PWM pulse on ATmega1281 – example1 p1
The simplest way to produce a PWM waveform is to use one of the
programmable timers. The alternative being to set port bits high and low
alternatively from direct software control
In the C example below, the 16-bit timer/counter 3 is used, and the PWM
output is produced directly on an output pin Port E bit 3 (alternate function
OC3A (Output Compare match Output 3A)). PORT D Switches are used to
control servo rotation.
// Define values representing each input switch
#define Switch_0_Pressed 0b00000001
#define Switch_1_Pressed 0b00000010
#define Switch_2_Pressed 0b00000100
#define Switch_3_Pressed 0b00001000
#define Switch_4_Pressed 0b00010000
#define Switch_5_Pressed 0b00100000
#define Switch_6_Pressed 0b01000000
#define Switch_7_Pressed 0b10000000
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
13
Programming – Generating PWM pulse on ATmega1281 – example1 p2
int main( void ) {
InitialiseGeneral();
InitialiseTimer3_FastPWM_Single();
unsigned char SwitchesValue;
while(1)
{
SwitchesValue = ~PIND;
// Read value on switches
switch(SwitchesValue)
{
// Pulse width ranges from 750uS to 2250uS
case Switch_0_Pressed:
OCR3A = 750;
_delay_ms(80);
break;
...
case Switch_7_Pressed:
OCR3A = 750 + (214 * 7);
_delay_ms(80);
break;
// Minimum value 750uS
// Switch debounce delay
// 2248 (i.e. approx 2250)
// Switch debounce delay
}
}
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
14
Programming – Generating PWM pulse on ATmega1281 – example1 p3
void InitialiseGeneral()
{
DDRD = 0x00; // Configure PortD direction for Input (switches)
DDRE = 0xFF; // Port E bit 3 must be set as OUTPUT to provide the
// PWM pulse on OC3A
// Port E bit 7 Input Capture 3 Pin (ICP3) must be set
// as OUTPUT to prevent noise values entering ICR3
// (ICR3 is used as TOP value for PWM counter)
PORTE = 0x00; // Set all bits initially
sei();
}
// Enable interrupts, set Global Interrupt Enable (I) bit
15
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Programming – Generating PWM pulse on ATmega1281 – example1 p4
void InitialiseTimer3_FastPWM_Single()
{
// TCCR3A – Timer/Counter 3 Control Register A
// Bit 7:6 – COMnA1:0: Compare Output Mode for Channel A
// Bit 5:4 – COMnB1:0: Compare Output Mode for Channel B
// Bit 3:2 – COMnC1:0: Compare Output Mode for Channel C
// Bit 1:0 – WGMn1:0: Waveform WGM(3..0) 1110 Fast PWM ICR3 is TOP
TCCR3A = 0b10000010;
// Fast PWM non inverting, ICR3 used as TOP
// TCCR3B – Timer/Counter 3 Control Register B
// Bit 7 – ICNCn: Input Capture Noise Canceler
// Bit 6 – ICESn: Input Capture Edge Select
// Bit 5 – Reserved Bit
// Bit 4:3 – WGMn3:2: Waveform Generation Mode
// Bit 2:0 – CSn2:0: Clock Select
TCCR3B = 0b00011001;
// Fast PWM, Use Prescaler '1'
// TCCR3C – Timer/Counter 3 Control Register C
// Bit 7 – FOCnA: Force Output Compare for Channel A
// Bit 6 – FOCnB: Force Output Compare for Channel B
// Bit 5 – FOCnC: Force Output Compare for Channel C
TCCR3C = 0b00000000;
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
16
Programming – Generating PWM pulse on ATmega1281 – example1 p5
// Set Timer/Counter3 Input Capture Register (16 bit) ICR3
// For the SERVO, the pulses should occur every 18ms, i.e. 18000uS
// 1MHz clock, each pulse takes 1us, so need to count 18000 clock pulses
// Decimal 18000 = 0x4650 (This value defines where a single cycle ends)
// The actual pulse width is much shorter than the whole cycle.
ICR3H = 0x46; // 16-bit access (write high byte first, read low byte first)
ICR3L = 0x50;
// Set Timer/Counter count/value registers (16 bit) TCNT1H and TCNT1L
TCNT3H = 0; // 16-bit access (write high byte first, read low byte first)
TCNT3L = 0;
// Initialise Channel A servo to mid-range position
// Set Output Compare Registers (16 bit) OCR3AH and OCR3AL
// Pulse width ranges from 750uS to 2250uS, Neutral pulse width = 1500uS
OCR3A = 1500;
// TIMSK3 – Timer/Counter 3 Interrupt Mask Register
TIMSK3 = 0b00000000; // No ints used, PWM pulses appear on OC3A (PE3)
// TIFR3 – Timer/Counter3 Interrupt Flag Register
TIFR3 = 0b00101111; // Clear all interrupt flags
}
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
17
Programming – Generating PWM pulse on ATmega1281 – example2 p1
In the C example below, the 16-bit timer/counter 3 is used, and the PWM
output is produced directly on an output pin Port E bit 3 (alternate function
OC3A (Output Compare match Output 3A)). A Potentiometer on PORT F bit 2
(Analogue input) determines the servo position.
int main(void)
{
InitialiseGeneral();
InitialiseTimer3_FastPWM_Single();
Initialise_ADC();
while(1)
{
}
}
18
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Programming – Generating PWM pulse on ATmega1281 – example2 p2
void InitialiseGeneral()
{
DDRB = 0xFF;
// Configure PortB direction for Output (LEDs)
PORTB = 0xFF;
// LEDs initially Off
DDRE = 0xFF;
PORTE = 0x00;
// Port E bit 3 must be set as OUTPUT to provide
// the PWM pulse on OC3A
// Port E bit 7 Input Capture 3 Pin (ICP3) must be
// set as OUTPUT to prevent noise entering ICR3
// (ICR3 used as TOP value for PWM counter)
// Clear all bits initially
// PORT F bit 2 is set automatically for Analogue input when the
// ADC module is configured
sei();
// Set Global Interrupt Enable (I) bit
}
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
19
Programming – Generating PWM pulse on ATmega1281 – example2 p3
void InitialiseTimer3_FastPWM_Single()
Timer 3 configuration is
{
same as in example 1
// TCCR3A – Timer/Counter 3 Control Register A
// Bit 7:6 – COMnA1:0: Compare Output Mode for Channel A
// Bit 5:4 – COMnB1:0: Compare Output Mode for Channel B
// Bit 3:2 – COMnC1:0: Compare Output Mode for Channel C
// Bit 1:0 – WGMn1:0: Waveform WGM(3..0) 1110 Fast PWM ICR3 is TOP
TCCR3A = 0b10000010;
// Fast PWM non inverting, ICR3 used as TOP
// TCCR3B – Timer/Counter 3 Control Register B
// Bit 7 – ICNCn: Input Capture Noise Canceler
// Bit 6 – ICESn: Input Capture Edge Select
// Bit 5 – Reserved Bit
// Bit 4:3 – WGMn3:2: Waveform Generation Mode
// Bit 2:0 – CSn2:0: Clock Select
TCCR3B = 0b00011001;
// Fast PWM, Use Prescaler '1'
// TCCR3C – Timer/Counter 3 Control Register C
// Bit 7 – FOCnA: Force Output Compare for Channel A
// Bit 6 – FOCnB: Force Output Compare for Channel B
// Bit 5 – FOCnC: Force Output Compare for Channel C
TCCR3C = 0b00000000;
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
20
Programming – Generating PWM pulse on ATmega1281 – example2 p4
// Set Timer/Counter3 Input Capture Register (16 bit) ICR3
// For the SERVO, the pulses should occur every 18ms, i.e. 18000uS
// 1MHz clock, each pulse takes 1us, so need to count 18000 clock pulses
// Decimal 18000 = 0x4650 (This value defines where a single cycle ends)
// The actual pulse width is much shorter than the whole cycle.
ICR3H = 0x46; // 16-bit access (write high byte first, read low byte first)
ICR3L = 0x50;
// Set Timer/Counter count/value registers (16 bit) TCNT1H and TCNT1L
TCNT3H = 0; // 16-bit access (write high byte first, read low byte first)
TCNT3L = 0;
// Initialise Channel A servo to mid-range position
// Set Output Compare Registers (16 bit) OCR3AH and OCR3AL
// Pulse width ranges from 750uS to 2250uS, Neutral pulse width = 1500uS
OCR3A = 1500;
// TIMSK3 – Timer/Counter 3 Interrupt Mask Register
TIMSK3 = 0b00000000; // No ints used, PWM pulses appear on OC3A (PE3)
// TIFR3 – Timer/Counter3 Interrupt Flag Register
TIFR3 = 0b00101111; // Clear all interrupt flags
}
Embedded Systems Programming II
Timer 3 configuration is
same as in example 1
Richard Anthony, Computer Science, The University of Greenwich
21
Programming – Generating PWM pulse on ATmega1281 – example2 p5
void Initialise_ADC()
{
// ADMUX – ADC Multiplexer Selection Register
// bit7,6 Reference voltage selection (00 AREF,01 AVCC)
// bit 5 ADC Left adjust the 10-bit result
// Bits 4:0 – MUX4:0: Analog Channel (00010 = ADC2)
ADMUX = 0b01100010;
// AVCC REF, Left-adjust output, Channel 2
// ADCSRA – ADC Control and Status Register A
// bit 7 ADC ENable), bit 6 Start Conversion bit 5 Auto Trigger Enable
// bit 4 ADC Interrupt Flag, bit 3 ADC Interrupt Enable
// bit 2,1,0 prescaler 000=2, 010=4, 011=8,100=16,101=32,110=64,111=128
ADCSRA = 0b10101101; // Enabled, Auto trig, Int enabled, Prescale = 32
// ADCSRB – ADC Control and Status Register B
// Bit 3 MUX5: Analog Channel and Gain Selection Bit (0 for ADC0-7)
// Bit 2:0 Auto Trigger Source (active when ADATE bit in ADCSRA is set)
// 0 0 0 Free Running mode
ADCSRB &= 0b11110000;
// clear bits 3,2,1,0 (Free running mode)
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
22
Programming – Generating PWM pulse on ATmega1281 – example2 p6
// void Initialise_ADC() – continued
// DIDR0 – Digital Input Disable Register 0
// Bit 7:0 – ADC7D:ADC0D: ADC7:0 Digital Input Disable
DIDR0 = 0b00000100;
// Disable digital input on bit 2
// DIDR2 – Digital Input Disable Register 2
// Bit 7:0 – ADC15D:ADC8D: ADC15:8 Digital Input Disable
DIDR2 = 0b11111111;
// Disable digital input on all bits
// Start the ADC Conversion (start first sample, uses 'free run' mode)
//bit 6 ADCSRA (ADC Start Conversion) = 1 (START)
// Read ADSCSR and OR with this value to set flag
ADCSRA |= 0b01000000; // start ADC conversion
}
23
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Programming – Generating PWM pulse on ATmega1281 – example2 p7
ISR(ADC_vect)
// ADC Interrupt Handler
{
unsigned char ADCH_temp = ADCH;
// Convert ADC value into Servo Pulse width for PWM channel A
// Adjust the Most-significant 8-bits of the input value to a suitable
// position pulse-width value
// The ADC input (values 0 - 255) represent pulse-width value in the
// 1500us-wide range 750us to 2250us
// A simple approximation is used:
// Multiply by 6, to get a value in range 0 - 1536, then add the 750 offset.
OCR3A = (ADCH_temp * 6) + 750;
PORTB = ~ADCH_temp;
}
Embedded Systems Programming II
// Display the ADC value onto the LEDs
Richard Anthony, Computer Science, The University of Greenwich
24
Application example – A simple, two-servo robot arm (1)
Servo #1
Servo #2
25
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Application example – A simple, two-servo robot arm (2)
Servo #2
26
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Application example – A simple, two-servo robot arm (3)
View from above
Servo #2
Servo #1
27
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
Application example – A simple, two-servo robot arm (4)
Connection to Atmel
microcontroller (Port D)
Servo power and control cables
(yellow wire carries the control pulse)
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich
28
Application example – A simple, two-servo robot arm (5)
29
Embedded Systems Programming II
Richard Anthony, Computer Science, The University of Greenwich