Adding Servo library (ServoTimer1 from the playground) by Jim Studt.

This commit is contained in:
David A. Mellis 2008-05-07 19:53:52 +00:00
parent 6a7f8fdf53
commit 8f1f736e36
4 changed files with 204 additions and 3 deletions

View File

@ -0,0 +1,125 @@
#include <Servo.h>
#include <avr/interrupt.h>
/*
Servo.h - Hardware Servo Timer Library
Author: Jim Studt, jim@federated.com
Copyright (c) 2007 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
uint8_t Servo::attached9 = 0;
uint8_t Servo::attached10 = 0;
void Servo::seizeTimer1()
{
uint8_t oldSREG = SREG;
cli();
TCCR1A = _BV(WGM11); /* Fast PWM, ICR1 is top */
TCCR1B = _BV(WGM13) | _BV(WGM12) /* Fast PWM, ICR1 is top */
| _BV(CS11) /* div 8 clock prescaler */
;
OCR1A = 3000;
OCR1B = 3000;
ICR1 = clockCyclesPerMicrosecond()*(20000L/8); // 20000 uS is a bit fast for the refresh, 20ms, but
// it keeps us from overflowing ICR1 at 20MHz clocks
// That "/8" at the end is the prescaler.
#if defined(__AVR_ATmega168__)
TIMSK1 &= ~(_BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
#else
TIMSK &= ~(_BV(TICIE1) | _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
#endif
SREG = oldSREG; // undo cli()
}
void Servo::releaseTimer1() {}
#define NO_ANGLE (0xff)
Servo::Servo() : pin(0), angle(NO_ANGLE), min16(34), max16(150) {}
Servo::Servo(int min, int max) : pin(0), angle(NO_ANGLE), min16(min / 16), max16(max / 16) {}
uint8_t Servo::attach(int pinArg)
{
if (pinArg != 9 && pinArg != 10) return 0;
pin = pinArg;
angle = NO_ANGLE;
digitalWrite(pin, LOW);
pinMode(pin, OUTPUT);
if (!attached9 && !attached10) seizeTimer1();
if (pin == 9) {
attached9 = 1;
TCCR1A = TCCR1A & ~_BV(COM1A0) | _BV(COM1A1);
}
if (pin == 10) {
attached10 = 1;
TCCR1A = TCCR1A & ~_BV(COM1B0) | _BV(COM1B1);
}
return 1;
}
void Servo::detach()
{
// muck with timer flags
if (pin == 9) {
attached9 = 0;
TCCR1A = TCCR1A & ~_BV(COM1A0) & ~_BV(COM1A1);
pinMode(pin, INPUT);
}
if (pin == 10) {
attached10 = 0;
TCCR1A = TCCR1A & ~_BV(COM1B0) & ~_BV(COM1B1);
pinMode(pin, INPUT);
}
if (!attached9 && !attached10) releaseTimer1();
}
void Servo::write(int angleArg)
{
uint16_t p;
if (angleArg < 0) angleArg = 0;
if (angleArg > 180) angleArg = 180;
angle = angleArg;
// bleh, have to use longs to prevent overflow, could be tricky if always a 16MHz clock, but not true
// That 8L on the end is the TCNT1 prescaler, it will need to change if the clock's prescaler changes,
// but then there will likely be an overflow problem, so it will have to be handled by a human.
p = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/8L;
if (pin == 9) OCR1A = p;
if (pin == 10) OCR1B = p;
}
uint8_t Servo::read()
{
return angle;
}
uint8_t Servo::attached()
{
if (pin == 9 && attached9) return 1;
if (pin == 10 && attached10) return 1;
return 0;
}

View File

@ -0,0 +1,51 @@
#ifndef Servo_h
#define Servo_h
/*
Servo.h - Hardware Servo Timer Library
Author: Jim Studt, jim@federated.com
Copyright (c) 2007 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include <wiring.h>
class Servo
{
private:
uint8_t pin;
uint8_t angle; // in degrees
uint8_t min16; // minimum pulse, 16uS units (default is 34)
uint8_t max16; // maximum pulse, 16uS units, 0-4ms range (default is 150)
static void seizeTimer1();
static void releaseTimer1();
static uint8_t attached9;
static uint8_t attached10;
public:
Servo();
Servo(int, int); // pulse length for 0 degrees in microseconds, 540uS default
// pulse length for 180 degrees in microseconds, 2400uS default
uint8_t attach(int); // attach to a pin, sets pinMode, returns 0 on failure, won't
// position the servo until a subsequent write() happens
// Only works for 9 and 10.
void detach();
void write(int); // specify the angle in degrees, 0 to 180
uint8_t read();
uint8_t attached();
};
#endif

View File

@ -0,0 +1,22 @@
#######################################
# Syntax Coloring Map Servo
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
Servo KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
attach KEYWORD2
detach KEYWORD2
write KEYWORD2
read KEYWORD2
attached KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -17,6 +17,7 @@ Wire library patch: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206621511
AVR AVR
Support pin change interrupts.
Fix interference between millis() / timer 0 overflow interrupt and pwm output on pins 5 and 6. Fix interference between millis() / timer 0 overflow interrupt and pwm output on pins 5 and 6.
Problems including WProgram.h twice? Problems including WProgram.h twice?
Add #defines for the analog input pins. Add #defines for the analog input pins.
@ -90,12 +91,14 @@ Style guide for examples, references, and foundations.
DOCUMENTATION / NAVIGATION DOCUMENTATION / NAVIGATION
Move navigation to a toolbar at the top of the page. Move Hacking section into Learning (and rename?).
Reorganize sub-menus (create sub-sections). Create About section.
Not clear where some things go: foundations, environment, etc. Move Board into the Hardware section.
Move Environment into the Reference section (which should be renamed Programming).
DOCUMENTATION / CONTENTS DOCUMENTATION / CONTENTS
Document Matrix, Sprite, and Wire libraries on the Arduino site.
Add examples using specific hardware (simple analog sensors, optocouplers, etc.) Add examples using specific hardware (simple analog sensors, optocouplers, etc.)
Get good top-down, well-lit, plain-white-background photos of the Arduino boards. Get good top-down, well-lit, plain-white-background photos of the Arduino boards.
Documentation for moving from Arduino to custom PCBs. Documentation for moving from Arduino to custom PCBs.