hi all -
i've written some r/c servo controller code. i'd like to release it as a library. i downloaded the Test library example, but i just can't understand it at all. i have absolutely no idea where to put all the different parts of my code. i don't know c++, only c. could anyone give me some clues? here's the code as written into a sketch, which works fine:
// eight-channel servo system - by Jeff Mann copyright 2007 all rights reserved
// if we have an ATmega168, we can use timer 0, which is running in
// fast pwm mode, and keep timer 2 available for phase correct pwm.
// NOTE: this requires that the timer0 overflow interrupt routine in
// lib/targets/arduino/wiring.c be commented out! find the following:
//
// SIGNAL(SIG_OVERFLOW0)
// {
// timer0_overflow_count++;
// }
// ...and comment it out. remember to re-enable it for other programs!
#if defined(__AVR_ATmega168__)
#define USE_TIMER_0
#endif
// limits on servo pulse width - standard is 1000-2000 microseconds
// wide is roughly 500-2250 microseconds, but that may damage your servo!
#define MAX_SERVO_PULSE 2000
#define MIN_SERVO_PULSE 1000
// utilities to clear/set bits in special function registers
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define TRUE 1
#define FALSE 0
#define SERVO 3 // as opposed to INPUT or OUTPUT
/* variables for Servos */
extern volatile unsigned long timer0_overflow_count; // timer0 from wiring.c
int servoStatus = 0; // define which servo pins output pulses or not
byte processServos = FALSE;
byte servoCount = 0;
byte cycleCount = 0;
byte cycles;
byte turnOff = 0;
// define the mapping of logical servo numbers to arduino pins.
// it's not recommended to change this. if you want to,
// you can re-arrange these, but you must always have exactly 8 servos,
// listed here (numbered 0-7), whether you use them or not.
#define TOTAL_DIGITAL_PINS 14
#define NOT_A_SERVO 255
byte digital_pin_to_servo_array[14] = {
NOT_A_SERVO, // pin 0 - RX - cannot use
NOT_A_SERVO, // pin 1 - TX - cannot use
0, // pin 2
1, // pin 3 - PWM 2B on ATmega168
2, // pin 4
3, // pin 5 - PWM 0B on ATmega168
4, // pin 6 - PWM 0A on ATmega168, but not working if using servos
5, // pin 7
6, // pin 8
NOT_A_SERVO, // pin 9 - PWM 1A
NOT_A_SERVO, // pin 10 - PWM 1B
NOT_A_SERVO, // pin 11 - PWM 2(A) but not working on atmega8 when using servos
7, // pin 12
NOT_A_SERVO, // pin 13 - LED
};
typedef struct {
byte pin;
byte cycles;
byte ticks;
}
servo_t;
servo_t servo_array[8];
#ifdef USE_TIMER_0
ISR(TIMER0_OVF_vect) {
timer0_overflow_count++; // for millis() clock
if(processServos) {
if((cycleCount == 0) && (servoStatus & (1 << servo_array[servoCount].pin))) {
digitalWrite(servo_array[servoCount].pin, HIGH);
}
if(cycleCount == cycles) turnOff = TRUE;
++cycleCount;
}
}
ISR(TIMER0_COMPA_vect) {
if(processServos) {
// turn off the pin for the current servo if flagged
if(turnOff) {
if(servoStatus & (1 << servo_array[servoCount].pin)) {
digitalWrite(servo_array[servoCount].pin, LOW);
}
turnOff = FALSE;
}
if(cycleCount == 3) {
if(++servoCount > 7) servoCount = 0;
// load values for next cycle
cycles = servo_array[servoCount].cycles;
OCR0A = servo_array[servoCount].ticks;
cycleCount = 0;
}
}
}
#else
ISR(TIMER2_OVF_vect) {
if(processServos) {
if((cycleCount == 0) && (servoStatus & (1 << servo_array[servoCount].pin))) {
digitalWrite(servo_array[servoCount].pin, HIGH);
}
if(cycleCount == cycles) turnOff = TRUE;
++cycleCount;
}
}
ISR(TIMER2_COMP_vect) {
if(processServos) {
// turn off the pin for the current servo if flagged
if(turnOff) {
if(servoStatus & (1 << servo_array[servoCount].pin)) {
digitalWrite(servo_array[servoCount].pin, LOW);
}
turnOff = FALSE;
}
if(cycleCount == 3) {
if(++servoCount > 7) servoCount = 0;
// load values for next cycle
cycles = servo_array[servoCount].cycles;
OCR2 = servo_array[servoCount].ticks;
cycleCount = 0;
}
}
}
#endif
// continued in next post!