Ligne 6 : |
Ligne 6 : |
| | | |
| <syntaxhighlight lang="c"> | | <syntaxhighlight lang="c"> |
− | | + | /** Arduino Uno Timer 2 Servo Example |
| + | This example code for the Arduino Uno shows how to use Timer 2 on |
| + | the ATmega328P to control a single servo. This can be useful for |
| + | people who cannot use the Arduino IDE's Servo library. For |
| + | example, the ZumoMotors library uses the same timer as the Servo |
| + | library (Timer 1), so the two libraries conflict. |
| + | |
| + | The SERVO_PIN macro below specifies what pin to output the |
| + | servo on. This pin needs to be connected to the signal input |
| + | line of the servo. The Arduino's GND needs to be connected to |
| + | the ground pin of the servo. The servo's ground and power pins |
| + | need to be connected to an appropriate power supply. |
| + | */ |
| + | |
| + | // This line specifies what pin we will use for sending the |
| + | // signal to the servo. You can change this. |
| + | #define SERVO_PIN 11 |
| + | |
| + | // This is the time since the last rising edge in units of 0.5us. |
| + | uint16_t volatile servoTime = 0; |
| + | |
| + | // This is the pulse width we want in units of 0.5us. |
| + | uint16_t volatile servoHighTime = 3000; |
| + | |
| + | // This is true if the servo pin is currently high. |
| + | boolean volatile servoHigh = false; |
| + | |
| + | void setup() |
| + | { |
| + | servoInit(); |
| + | } |
| + | |
| + | void loop() |
| + | { |
| + | servoSetPosition(1000); // Send 1000us pulses. |
| + | delay(1000); |
| + | servoSetPosition(2000); // Send 2000us pulses. |
| + | delay(1000); |
| + | } |
| + | |
| + | // This ISR runs after Timer 2 reaches OCR2A and resets. |
| + | // In this ISR, we set OCR2A in order to schedule when the next |
| + | // interrupt will happen. |
| + | // Generally we will set OCR2A to 255 so that we have an |
| + | // interrupt every 128 us, but the first two interrupt intervals |
| + | // after the rising edge will be smaller so we can achieve |
| + | // the desired pulse width. |
| + | ISR(TIMER2_COMPA_vect) |
| + | { |
| + | // The time that passed since the last interrupt is OCR2A + 1 |
| + | // because the timer value will equal OCR2A before going to 0. |
| + | servoTime += OCR2A + 1; |
| + | |
| + | static uint16_t highTimeCopy = 3000; |
| + | static uint8_t interruptCount = 0; |
| + | |
| + | if(servoHigh) |
| + | { |
| + | if(++interruptCount == 2) |
| + | { |
| + | OCR2A = 255; |
| + | } |
| + | |
| + | // The servo pin is currently high. |
| + | // Check to see if is time for a falling edge. |
| + | // Note: We could == instead of >=. |
| + | if(servoTime >= highTimeCopy) |
| + | { |
| + | // The pin has been high enough, so do a falling edge. |
| + | digitalWrite(SERVO_PIN, LOW); |
| + | servoHigh = false; |
| + | interruptCount = 0; |
| + | } |
| + | } |
| + | else |
| + | { |
| + | // The servo pin is currently low. |
| + | |
| + | if(servoTime >= 40000) |
| + | { |
| + | // We've hit the end of the period (20 ms), |
| + | // so do a rising edge. |
| + | highTimeCopy = servoHighTime; |
| + | digitalWrite(SERVO_PIN, HIGH); |
| + | servoHigh = true; |
| + | servoTime = 0; |
| + | interruptCount = 0; |
| + | OCR2A = ((highTimeCopy % 256) + 256)/2 - 1; |
| + | } |
| + | } |
| + | } |
| + | |
| + | void servoInit() |
| + | { |
| + | digitalWrite(SERVO_PIN, LOW); |
| + | pinMode(SERVO_PIN, OUTPUT); |
| + | |
| + | // Turn on CTC mode. Timer 2 will count up to OCR2A, then |
| + | // reset to 0 and cause an interrupt. |
| + | TCCR2A = (1 << WGM21); |
| + | // Set a 1:8 prescaler. This gives us 0.5us resolution. |
| + | TCCR2B = (1 << CS21); |
| + | |
| + | // Put the timer in a good default state. |
| + | TCNT2 = 0; |
| + | OCR2A = 255; |
| + | |
| + | TIMSK2 |= (1 << OCIE2A); // Enable timer compare interrupt. |
| + | sei(); // Enable interrupts. |
| + | } |
| + | |
| + | void servoSetPosition(uint16_t highTimeMicroseconds) |
| + | { |
| + | TIMSK2 &= ~(1 << OCIE2A); // disable timer compare interrupt |
| + | servoHighTime = highTimeMicroseconds * 2; |
| + | TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt |
| + | } |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
| {{Pololu-Zumo-Shield-Arduino-TRAILER}} | | {{Pololu-Zumo-Shield-Arduino-TRAILER}} |