khoih-prog / TimerInterrupt

This library enables you to use Interrupt from Hardware Timers on an Arduino, such as Nano, UNO, Mega, etc. It now supports 16 ISR-based timers, while consuming only 1 hardware Timer. Timers' interval is very long (ulong millisecs). The most important feature is they're ISR-based timers. Therefore, their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks.
MIT License
98 stars 11 forks source link

Conflict with Servo library #2

Closed hank880907 closed 4 years ago

hank880907 commented 4 years ago

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();
}
khoih-prog commented 4 years ago

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.

hank880907 commented 4 years ago

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?

khoih-prog commented 4 years ago

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.