29 #ifndef _LIGHTWEIGHT_SERVO_HPP
30 #define _LIGHTWEIGHT_SERVO_HPP
32 #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
40 int sMicrosecondsForServo0Degree = 544;
41 int sMicrosecondsForServo180Degree = 2400;
50 void initLightweightServoPin9And10() {
54 DDRB |= _BV(DDB1) | _BV(DDB2);
55 TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);
56 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
57 ICR1 = ISR1_COUNT_FOR_20_MILLIS;
68 void initLightweightServoPin9_10(
bool aUsePin9,
bool aUsePin10) {
70 uint8_t tNewTCCR1A = TCCR1A & (_BV(COM1A1) | _BV(COM1B1));
71 tNewTCCR1A |= _BV(WGM11);
75 tNewTCCR1A |= _BV(COM1A1);
80 tNewTCCR1A |= _BV(COM1B1);
84 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
85 ICR1 = ISR1_COUNT_FOR_20_MILLIS;
91 void initLightweightServoPin9() {
93 TCCR1A = _BV(WGM11) | _BV(COM1A1);
94 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
95 ICR1 = ISR1_COUNT_FOR_20_MILLIS;
101 void initLightweightServoPin10() {
103 TCCR1A = _BV(WGM11) | _BV(COM1B1);
104 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
105 ICR1 = ISR1_COUNT_FOR_20_MILLIS;
109 void deinitLightweightServoPin9_10(
bool aUsePin9,
bool aUsePin10) {
111 DDRB &= ~(_BV(DDB1));
112 TCCR1A &= ~(_BV(COM1A1));
115 DDRB &= ~(_BV(DDB2));
116 TCCR1A &= ~(_BV(COM1B1));
126 int writeLightweightServo(
int aDegree,
bool aUsePin9,
bool aUpdateFast) {
127 if (aDegree <= 180) {
128 aDegree = DegreeToMicrosecondsLightweightServo(aDegree);
130 writeMicrosecondsLightweightServo(aDegree, aUsePin9, aUpdateFast);
134 void writeMicrosecondsLightweightServo(
int aMicroseconds,
bool aUsePin9,
bool aUpdateFast) {
135 #if !defined(DISABLE_SERVO_TIMER_AUTO_INITIALIZE)
137 if ((TCCR1B != (_BV(WGM13) | _BV(WGM12) | _BV(CS11))) || (aUsePin9 && ((TCCR1A & ~_BV(COM1B1)) != (_BV(COM1A1) | _BV(WGM11))))
138 || (!aUsePin9 && ((TCCR1A & ~_BV(COM1A1)) != (_BV(COM1B1) | _BV(WGM11))))) {
139 initLightweightServoPin9_10(aUsePin9, !aUsePin9);
145 uint16_t tTimerCount = TCNT1;
146 if (tTimerCount > 5000) {
152 OCR1A = aMicroseconds;
154 OCR1B = aMicroseconds;
162 void setLightweightServoRefreshRate(
unsigned int aRefreshPeriodMicroseconds) {
163 ICR1 = aRefreshPeriodMicroseconds * 2;
168 void setLightweightServoPulseMicrosFor0And180Degree(
int aMicrosecondsForServo0Degree,
int aMicrosecondsForServo180Degree) {
169 sMicrosecondsForServo0Degree = aMicrosecondsForServo0Degree;
170 sMicrosecondsForServo180Degree = aMicrosecondsForServo180Degree;
176 void write9(
int aDegree,
bool aUpdateFast) {
177 writeLightweightServo(aDegree,
true, aUpdateFast);
180 void writeMicroseconds9(
int aMicroseconds,
bool aUpdateFast) {
181 writeMicrosecondsLightweightServo(aMicroseconds,
true, aUpdateFast);
187 void writeMicroseconds9Direct(
int aMicroseconds) {
188 OCR1A = aMicroseconds * 2;
194 void write10(
int aDegree,
bool aUpdateFast) {
195 writeLightweightServo(aDegree,
false, aUpdateFast);
198 void writeMicroseconds10(
int aMicroseconds,
bool aUpdateFast) {
199 writeMicrosecondsLightweightServo(aMicroseconds,
false, aUpdateFast);
205 void writeMicroseconds10Direct(
int aMicroseconds) {
206 OCR1B = aMicroseconds * 2;
212 int DegreeToMicrosecondsLightweightServo(
int aDegree) {
213 return (map(aDegree, 0, 180, sMicrosecondsForServo0Degree, sMicrosecondsForServo180Degree));
216 int MicrosecondsToDegreeLightweightServo(
int aMicroseconds) {
217 return map(aMicroseconds, sMicrosecondsForServo0Degree, sMicrosecondsForServo180Degree, 0, 180);
220 #endif // defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
221 #endif // _LIGHTWEIGHT_SERVO_HPP