3

Im using Spark fun pro micro:https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro

I am controlling a servo motor which reads its data from a pot connected to A0, and then writes to the servo on D9.

A speaker is connected to A5. Im using tone()

If I comment out the servo part of it, the tone() works out just fine and vise versa.. The error message I get is "multiple definition of `__vector_32'"

Got a clue??! Thanks!

  • What version of the Arduino software are you using? – Edgar Bonet May 26 '15 at 18:18
2

The link you provided shows a board built around the ATmega32U4. On this chip, “__vector_32” is the low-level name of an ISR (Interrupt Service Routine) named “TIMER3_COMPA_vect”. Your problem comes from having two libraries trying to define an ISR for the same interrupt, which is generated by the timer 3 of the chip. Merging the ISRs is actually unlikely to work, because since each library configures the timer in its own way, the timing of the interrupts will be wrong for at least one of the libraries. You really have to use different timers.

On my copy of Tone.cpp I can read:

#elif defined(__AVR_ATmega32U4__)

#define AVAILABLE_TONE_PINS 1
#define USE_TIMER3

const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };

which shows that the code is configured to use timer 3 on this particular chip. In Servo.h I have:

#elif defined(__AVR_ATmega32U4__)  
#define _useTimer1 
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;

which shows it should use timer 1, and not conflict with Tone.cpp.

It seems we have different versions of Servo.h. Mine is from Arduino 1.0.5. You may try to fix the problem by modifying the relevant section of either file (just after #elif defined(__AVR_ATmega32U4__)) and have them use different timers.

Edit: It appears this issue has already been fixed... on June 2012! See this diff: Avoid TIMER3 conflict with Servo and tone() on the Arduino GitHub repository. The simplest fix in your case may be to just upgrade your Arduino software. You could also manually apply that (really small) diff to your current copy.

| improve this answer | |
  • @downvoter: care to comment? – Edgar Bonet May 27 '15 at 14:43
  • An upgrade did the job! Thanks a lot!! But a new problem occurred, I had a timer interrupt connected as well which now is conflicting with the servo... gaaaah!! =) Guess I´ll have to modify or change the timer which interrupts – MrHaze May 31 '15 at 20:10
2

The problem you're seeing arises when two codes (e.g. libraries) try to use the same interrupt.

If you look at the source code of the two libraries, you'll find that they both make use of a number of ISRs (interrupt service routines): Tone.cpp uses

ISR(TIMERn_COMPA_vect) {...}

for n = 0..5, while Servo.cpp uses

ISR(TIMERn_COMPA_vect) {...}

for n = 1, 3, 4, 5.

Now what happens when you compile this code is that they both libraries generate identical symbols (the __vector_32 part) which then clash when the compiled code is linked to give the final binary you'd upload to your Arduino.

There is no simple way around this because the interrupt handlers need to be registered at certain fixed positions in flash memory and there can only be exactly one interrupt handler for each of these slots (these slots are simply entries in a look-up table with the addresses of the interrupt handlers in flash, cf. Table 9-1 in the datasheet).

Now to solve this problem you would need to find a way to either merge the interrupt handlers of the two libraries (not so easy I guess), or make them use different interrupts (without looking further into what options the pro micro offers, the code suggests that there are several TIMER interrupts which could be assigned one to the Servo, one to the Tone, if that is supported by the hardware).

In any case you'll not get around modifying the libraries (or writing your own code for one functionality or the other).

| improve this answer | |
1

The libraries are not compatible with each other, welcome to Arduino.

I dont use either library, and usually avoid libraries altogether because of things like this. I will assume you want a solution, not a clue.

The quickest route is to pick one of the libraries, and globally modify __vector_32 to something like __vector_32x.

That probably is not the best solution but the quickest. The best solution would be to understand how it is used in both libraries, and modify them to work together. In the end it might be as simple as wrapping it with some #ifdef, but that requires understanding it enough to get to that conclusion, and it will take some time. Maybe someone else already has.

| improve this answer | |
  • ok thanks! You know of any other way of generate simple sounds that IS compatible with servo.h? And another Q: Im pretty used to computers but I can't find my servo.h on my mac?!?! Freaks me out!! You know where to look?? – MrHaze May 26 '15 at 16:06
  • 3
    You are unlikely to find __vector_32 in any of those libraries. More likely something like ISR(TIMER3_COMPA_vect) or so. And renaming one of those won't help: you have to merge their contents. – Edgar Bonet May 26 '15 at 16:09
  • @MrHaze: It's “Servo.h”, with a capital ‘S’. – Edgar Bonet May 26 '15 at 16:10
  • @MrHaze You will find Servo.h in /Applications/Arduino.app/Resources/Java/libraries/Servo/src. – NobodyNada May 28 '15 at 20:13
  • Great!! Found it! Its weird I can't find it with spotlight though. Thx a lot. – MrHaze May 31 '15 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.