khoih-prog/TimerInterrupt

Conflict with Servo library

hank880907 opened this issue · 3 comments

My board was an Arduino Mega.
I cannot include the servo library if I include the TimerInterrupt.
I am using timer 5 which should be ok to use.

the error message is here:

libraries/Servo/avr/Servo.cpp.o (symbol from plugin): In function ServoCount': (.text+0x0): multiple definition of __vector_42'
sketch/sketch_aug05b.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Mega or Mega 25

my source code:

//These define's must be placed at the beginning before #include "TimerInterrupt.h"
#define TIMER_INTERRUPT_DEBUG      0

#define USE_TIMER_1     false
#define USE_TIMER_2     false
#define USE_TIMER_3     false
#define USE_TIMER_4     true
#define USE_TIMER_5     false

#include "TimerInterrupt.h"
#include <Servo.h>
#define IO_POWER  49
#define stepsPerRevolution 1600


// defines pins numbers
const int stepPin = 31;
const int dirPin = 30;
int Stepper_steps = 400;

unsigned long testTime;
unsigned long diff;



void TimerHandler1(void)
{
  static bool previous = false;
  if (Stepper_steps > 0) {
    if (previous == false) {
      digitalWrite(dirPin, HIGH);
      previous = true;
    }
    Stepper_steps -= stepper_motor_step();
  } else if (Stepper_steps < 0) {
    if (previous == true) {
      digitalWrite(dirPin, LOW);
      previous = false;
    }
    Stepper_steps += stepper_motor_step();
  }

  if (Stepper_steps==0){
    ITimer4.detachInterrupt();
  }
}


void setup() {
  Serial.begin(9600);
  pinMode(IO_POWER, OUTPUT);              //Pin 49 is used to enable IO power
  digitalWrite(IO_POWER, 1);              //Enable IO power on main CPU board
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  digitalWrite(stepPin, 0);
  digitalWrite(dirPin, 0);

  // Select Timer 1-2 for UNO, 0-5 for MEGA
  // Timer 2 is 8-bit timer, only for higher frequency   
  ITimer4.init();
   
  // Using ATmega328 used in UNO => 16MHz CPU clock , 
  
  if (ITimer4.attachInterrupt(4000, TimerHandler1, 0))
    Serial.println("Starting  ITimer1 OK, millis() = " + String(millis()));
  else
    Serial.println("Can't set ITimer1. Select another freq. or timer");

    ITimer4.detachInterrupt();

    
}

void loop() {
  Serial.println("Hi");
  delay(1000);
  stepper_motor_callback();
  delay(1000);
  set_stepper_motor_step(-100);
}


static bool stepper_motor_step() {
  static bool first = true;
  static bool sFlag = false;
  if (first) {
    digitalWrite(stepPin, HIGH);
    first = false;
  } else if (first == false) {
    digitalWrite(stepPin, LOW);
    sFlag = true;
    first = true;
  }

  if (sFlag) {
    sFlag = false;
    return true;
  } else {
    return false;
  }
}
void set_stepper_motor_step(int steps) {
  Stepper_steps += steps;
}

void stepper_motor_callback() {
  ITimer4.reattachInterrupt();
}

Hi @hank880907

You included Servo.h but didn't use any feature of Servo Library.

Just comment the line to

//#include <Servo.h>

to eliminate compiler error

It's very tricky, without any conflict, to use both low-level libraries dealing with Interrupts.

Just use either Servo or TimerInterrupt library.

Hi thanks for replying
I needed to use the servo library in my project (just haven't written any code for it yet)
So are there a way to use the Servo library and timer interrupt library at the same time?

Currently no way unless one of the library has to be rewritten or a combined library is created.
I'm not ready to spend time to do the combination as I did for ESP32 and ESP8266 as they are much more powerful and popular.

For example

  1. ESP8266_ISR_Servo
  2. ESP32_ISR_Servo

I suggest that you use either ESP8266 or ESP32 to replace the old Mega.