Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #67 by changing Servo constructors and adding destructors #110

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Servo.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class Servo
{
public:
Servo();
~Servo();
uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or INVALID_SERVO if failure
uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
void detach();
Expand All @@ -114,7 +115,7 @@ class Servo
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
bool attached(); // return true if this servo is attached, otherwise false
private:
uint8_t servoIndex; // index into the channel data for this servo
uint8_t servoIndex = INVALID_SERVO;// index into the channel data for this servo
int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH
int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
};
Expand Down
30 changes: 20 additions & 10 deletions src/avr/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
static servo_t servos[MAX_SERVOS]; // static array of servo structures
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)

uint8_t ServoCount = 0; // the total number of attached servos


// convenience macros
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
Expand All @@ -54,12 +51,12 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
if( Channel[timer] < 0 )
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else{
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true )
if( SERVO_INDEX(timer,Channel[timer]) < MAX_SERVOS && SERVO(timer,Channel[timer]).Pin.isActive == true )
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated
}

Channel[timer]++; // increment to the next channel
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
if( SERVO_INDEX(timer,Channel[timer]) < MAX_SERVOS && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks;
if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
Expand Down Expand Up @@ -222,12 +219,25 @@ static boolean isTimerActive(timer16_Sequence_t timer)

Servo::Servo()
{
if( ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i].servoIndex == INVALID_SERVO) {
this->servoIndex = i;
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
else
this->servoIndex = INVALID_SERVO ; // too many servos
}

uint8_t Servo::attach(int pin)
Expand Down
24 changes: 18 additions & 6 deletions src/mbed/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ class ServoImpl {
int32_t duration = -1;
};

static ServoImpl* servos[MAX_SERVOS]; // static array of servo structures
uint8_t ServoCount = 0; // the total number of attached servos
static ServoImpl* servos[MAX_SERVOS] = {NULL}; // static array of servo structures

#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min) // minimum value in us for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max) // maximum value in us for this servo
Expand All @@ -53,10 +52,23 @@ uint8_t ServoCount = 0; // the total number o

Servo::Servo()
{
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++;
} else {
this->servoIndex = INVALID_SERVO; // too many servos
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i] == NULL) {
this->servoIndex = i;
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
}

Expand Down
29 changes: 20 additions & 9 deletions src/megaavr/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

static servo_t servos[MAX_SERVOS]; // static array of servo structures

uint8_t ServoCount = 0; // the total number of attached servos

static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)

// convenience macros
Expand All @@ -32,15 +30,15 @@ void ServoHandler(int timer)
// Write compare register
_timer->CCMP = 0;
} else {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < MAX_SERVOS && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) {
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
}

// Select the next servo controlled by this timer
currentServoIndex[timer]++;

if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < MAX_SERVOS && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
Expand Down Expand Up @@ -114,11 +112,24 @@ static boolean isTimerActive(timer16_Sequence_t timer)

Servo::Servo()
{
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
} else {
this->servoIndex = INVALID_SERVO; // too many servos
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i].servoIndex == INVALID_SERVO) {
this->servoIndex = i;
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
}

Expand Down
23 changes: 16 additions & 7 deletions src/nrf52/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,30 @@

static servo_t servos[MAX_SERVOS]; // static array of servo structures

uint8_t ServoCount = 0; // the total number of attached servos



uint32_t group_pins[3][NRF_PWM_CHANNEL_COUNT]={{NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}};
static uint16_t seq_values[3][NRF_PWM_CHANNEL_COUNT]={{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

Servo::Servo()
{
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
} else {
this->servoIndex = INVALID_SERVO; // too many servos
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i].servoIndex == INVALID_SERVO) {
this->servoIndex = i;
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
}

uint8_t Servo::attach(int pin)
Expand Down
29 changes: 20 additions & 9 deletions src/sam/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@

static servo_t servos[MAX_SERVOS]; // static array of servo structures

uint8_t ServoCount = 0; // the total number of attached servos

static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)

// convenience macros
Expand Down Expand Up @@ -80,13 +78,13 @@ void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel)
if (Channel[timer] < 0) {
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
} else {
if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true) {
if (SERVO_INDEX(timer,Channel[timer]) < MAX_SERVOS && SERVO(timer,Channel[timer]).Pin.isActive == true) {
digitalWrite(SERVO(timer,Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
}

Channel[timer]++; // increment to the next channel
if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
if( SERVO_INDEX(timer,Channel[timer]) < MAX_SERVOS && Channel[timer] < SERVOS_PER_TIMER) {
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
if(SERVO(timer,Channel[timer]).Pin.isActive == true) { // check if activated
digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
Expand Down Expand Up @@ -182,11 +180,24 @@ static boolean isTimerActive(timer16_Sequence_t timer)

Servo::Servo()
{
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
} else {
this->servoIndex = INVALID_SERVO; // too many servos
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i].servoIndex == INVALID_SERVO) {
this->servoIndex = i;
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
}

Expand Down
29 changes: 20 additions & 9 deletions src/samd/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@

static servo_t servos[MAX_SERVOS]; // static array of servo structures

uint8_t ServoCount = 0; // the total number of attached servos

static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)

// convenience macros
Expand Down Expand Up @@ -63,15 +61,15 @@ void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel, uint8_t in
tc->COUNT16.COUNT.reg = (uint16_t) 0;
WAIT_TC16_REGS_SYNC(tc)
} else {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < MAX_SERVOS && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) {
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
}

// Select the next servo controlled by this timer
currentServoIndex[timer]++;

if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO_INDEX(timer, currentServoIndex[timer]) < MAX_SERVOS && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
Expand Down Expand Up @@ -197,11 +195,24 @@ static boolean isTimerActive(timer16_Sequence_t timer)

Servo::Servo()
{
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
} else {
this->servoIndex = INVALID_SERVO; // too many servos
// Iterate over array to find an uninitialized servo
this->servoIndex = INVALID_SERVO; // index of this servo or INVALID_SERVO if not found
for (int8_t i = 0; i < MAX_SERVOS; i++) {
if (servos[i].servoIndex == INVALID_SERVO) {
this->servoIndex = i;
servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values
break;
}
}
// servoIndex will be INVALID_SERVO if no free timers found
}

Servo::~Servo()
{
if( this->servoIndex != INVALID_SERVO ) { // if this instance is attached to a pin, make it available to be reused
// Disable this servo if it was attached
this->detach();
this->servoIndex = INVALID_SERVO; // This instance of servo can now be reused
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/stm32f4/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ Servo::Servo() {
this->resetFields();
}

Servo::~Servo() {
this->detach();
this->resetFields();
}

bool Servo::attach(uint8 pin, uint16 minPW, uint16 maxPW, int16 minAngle, int16 maxAngle)
{
// SerialUSB.begin(115200);
Expand Down