Compiler error when adding a library

(this post was originally in the adafruit forums here Adafruit customer service forums • View topic - Adding Music Maker library causes compiling error and was moved because it appears to be an arduino problem).

I’m working to modify this script:
viewtopic.php?f=31&t=79525&p=402768&hilit=+music+maker+music+maker+trigger#p402768
to work with the plastic flow meter (https://www.adafruit.com/products/828). However, I keep getting an compiling error:

collect2: error: ld returned 1 exit status
exit status 1

In an attempt to isolate the problem, I restarted building the sketch from the flow meter test script. It seems that as soon as I add the line

#include <Adafruit_VS1053.h>

To the script I get the same error. (Full code below). What can I do to fix this? I’m running the arduino IDE 1.6.12 on ubuntu 16.04.

thanks!

#include "SPI.h"
#include <Adafruit_VS1053.h>
#include <SD.h>

/**********************************************************
This is example code for using the Adafruit liquid flow meters. 
Tested and works great with the Adafruit plastic and brass meters
    ------> http://www.adafruit.com/products/828
    ------> http://www.adafruit.com/products/833
Connect the red wire to +5V, 
the black wire to common ground 
and the yellow sensor wire to pin #2
Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!
Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above must be included in any redistribution

**********************************************************/



//&&&&&sensor stuff&&&&&&

// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2
int counter;

// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

//&&&&&endsensortstuff&&&&&&&

void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
   
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
}

void loop()                     // run over and over again
{ 
  ;
  Serial.print("Freq: "); Serial.println(flowrate);
  Serial.print("Rate: "); Serial.println(flowrate/7.5);
  
  
  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  //Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  //Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  //Liters = Pulses / (7.5 * 60)
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;


  Serial.print(liters); Serial.println(" Liters");
  
  
 
  delay(1000);
}

Did you ever download the library from github? That isn't a standard Arduino library, so you have to download it before it knows what you're trying to do.

That should be a start. If it still doesn't recognize the library, you may need to get it in the files and unzip it (extract all) into program files>arduino>libraries

Yes, the library is installed. I also tried to use the arduino web IDE and had the same problem, and adafruit support confirms that they experienced the same issue.

Turn on verbose output for compilation (file/preferences) and you will see what is wrong.

multiple definition of `__vector_14'

This is defined (differently) in both the library .cpp file and the sketch.
SIGNAL(TIMER0_COMPA_vect) {
...

}

Thanks! What is the best way to fix something like that? As far as I can tell the sketch doesn't obviously define __vector_14.

TIMER0_COMPA_vect is __vector_14.
Well you can't define the same ISR/SIGNAL twice. So you will have to use something else in the sketch. Configure another timer and use that perhaps. There are libraries available for timer 1 and timer 2.

Thank you! I changed the timer references in three places and the error appears to have disappeared. In case it is helpful to someone else, the three changes were:

SIGNAL(TIMER0_COMPA_vect) {
became
SIGNAL(TIMER1_COMPA_vect) {

TIMSK0 |= _BV(OCIE0A);
became
TIMSK1 |= _BV(OCIE0A);

TIMSK0 &= ~_BV(OCIE0A);
became
TIMSK1 &= ~_BV(OCIE0A);

That makes the full sketch:

#include "SPI.h"
#include <Adafruit_VS1053.h>
#include <SD.h>

/**********************************************************
This is example code for using the Adafruit liquid flow meters. 
Tested and works great with the Adafruit plastic and brass meters
    ------> http://www.adafruit.com/products/828
    ------> http://www.adafruit.com/products/833
Connect the red wire to +5V, 
the black wire to common ground 
and the yellow sensor wire to pin #2
Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!
Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above must be included in any redistribution

**********************************************************/



//&&&&&sensor stuff&&&&&&

// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2
int counter;

// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER1_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK1 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK1 &= ~_BV(OCIE0A);
  }
}

//&&&&&endsensortstuff&&&&&&&

void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
   
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
}

void loop()                     // run over and over again
{ 
  ;
  Serial.print("Freq: "); Serial.println(flowrate);
  Serial.print("Rate: "); Serial.println(flowrate/7.5);
  
  
  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  //Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  //Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  //Liters = Pulses / (7.5 * 60)
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;


  Serial.print(liters); Serial.println(" Liters");
  
  
 
  delay(1000);
}