Помогите подружить библиотеку с кодом

s1981
Offline
Зарегистрирован: 22.12.2013

Добрый день! Есть код, нужно использовать библиотеку toneAC.h http://playground.arduino.cc/Code/ToneAC

при компиляции вылетает ошибка :

Arduino: 1.6.9 (Windows 10), Плата:"Arduino Nano, ATmega328"
 
libraries\toneAC\toneAC.cpp.o: In function `__vector_11':
 
C:\Program Files (x86)\Arduino\libraries\toneAC/toneAC.cpp:66: multiple definition of `__vector_11'
 
sketch\newsp.ino.cpp.o:C:\Users\zamot\OneDrive\Documents\Arduino\newspidometr\newsp/newsp.ino:47: first defined here
 
Если отключить библиотеку код, нормально компилируется. Помогите пожалуйста разобраться, за ранее благодарю
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,20,4);
// данные пользователя - вводятся индивидуально
const int ledPin =  9; 
int ledState = LOW;
unsigned long previousMillis = 0;
const int sensorPin = 10;   // порт для датчика
const float radius = .1; // радиус колеса в метрах ВАШЕГО велосипеда
const float magnets = 1; // количество магнитов для датчика на колесе
const int timeout = 500; // (миллисекунд) масимальное время ожидания
const int debounce = 10; // защита от дребезга контактов
int km = 0; // скорость на выходе
const float circumference = TWO_PI*radius; // расстояние одного оборота колеса
const float RPMtoKMH = circumference * 0.06 / magnets; // коэф перевода (об/мин) в (км/ч)

long timer = 0;   // для замера времи одного оборота (в миллисекундах)
long measuredTimer = 100000;   // время одного оборота (в миллисекундах)
float rpm = 0.0;  // оборотов в минуту
long counter = 0; // счетчик оборотов

boolean state = LOW;
boolean prevState = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  Serial.begin(9600); // включаем вывод в последовательный порт
  pinMode(sensorPin, INPUT);
  // TIMER - выставляем таймер с частотой прерывания в 1 кГц
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1999;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  // END
}

ISR(TIMER1_COMPA_vect) {//Функция прерывания с частотой в 1кГц для считывания датчика
  prevState = state;
  state = digitalRead(sensorPin);// считываем датчик
  if (state == HIGH && prevState == LOW && timer > debounce){//если датчик сработал
    measuredTimer = timer; //фиксируем результат замера
    timer = 0; //обнуляем счетчик времени
    counter++; //увеличиваем счетчик оборотов на единицу
  }

  timer++;  
  if (timer > timeout){// если импульсов долго нет, значит стоим
    measuredTimer = measuredTimer + 100; 
  }
}

void loop(){
    // рассчитываем обороты в секунду и сглаживаем низкочастотным фильтром
    //  (чем больше коэф (к единице) тем плавнее значения)
rpm = digitalLowPass(rpm, 60000.0 /measuredTimer, 0.75); 
km=rpm * RPMtoKMH, 1;
Serial.println(km);
lcd.setCursor(0,0);
lcd.print(km);
lcd.print(" ");
if (km<10){
  noTone(9);
}
if (km>10 && km<30){
  tone(9,31);
}
if (km>30 && km<35){
  tone(9,32);
}
if (km>35 && km<40){
  tone(9,36);
}
if (km>40 && km<45){
  tone(9,42);
}
if (km>45 && km<50){
  tone(9,48);
}
if (km>50 && km<55){
  tone(9,54);
}
if (km>55 && km<60){
  tone(9,60);
}
if (km>60 && km<65){
  tone(9,66);
}
if (km>65 && km<70){
  tone(9,72);
}
if (km>70 && km<75){
  tone(9,78);
}
if (km>75 && km<80){
  tone(9,84);
}
if (km>80 && km<85){
  tone(9,90);
}
if (km>90 && km<95){
  tone(9,96);
}
if (km>95 && km<100){
  tone(9,112);
}
if (km>100 && km<105){
  tone(9,118);
}
if (km>105 && km<110){
  tone(9,124);
}
if (km>110 && km<115){
  tone(9,130);
}
if (km>115 && km<120){
  tone(9,136);
}
if (km>120 && km<125){
  tone(9,142);
}
if (km>125 && km<130){
  tone(9,148);
}
if (km>130 && km<135){
  tone(9,154);
}
if (km>135 && km<140){
  tone(9,160);
}
if (km>145 && km<150){
  tone(9,166);
}
}

//Digital low pass filter - цифровой низкочастотный фильтр, коэф фильтра до единицы (чем ближе к единице тем выше фильтрация)
float digitalLowPass(float last_smoothed, float new_value, float filterVal)
{
  return (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
}
void spee(long interval){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

 

 
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, судя по сообщению, в подключаемой Вами библиотеке тоже есть функция 

ISR(TIMER1_COMPA_vect) 

вот и возникает конфликт - две функции с одним название.

Объединяйтё в одну.

s1981
Offline
Зарегистрирован: 22.12.2013

К сожалению знаю только азы программирования)) Моих знаний тут не хватит. Может поможете?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я не могу, но Вы попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

s1981
Дело в том, что у Вас в коде для считывания датчика задействован Timer1 и его прерывание по совпадению. В библиотеке ToneAC для генерации сигнала задействован этот же Timer1 и его прерывание по совпадению. Нельзя для двух разных задач использовать один и тот же таймер и прерывание.

s1981
Offline
Зарегистрирован: 22.12.2013

А решить это можно? Как то?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Использовать для считывания датчика другой таймер.

Timer0  - занят ардуиновскими delay(), millis(), micros()

Timer1 - занят библиотеками toneAC, Servo

Timer2 - занят ардуиновской tone(). Поскольку у Вас своя библиотека toneAC, его и можно задействовать. 

Либо вообще отказаться от прямого использования аппаратного таймера и пользоваться millis().

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

s1981 пишет:

А решить это можно? Как то?

1. Удалите строки 32-42

2. Вместо строки 45 запишите

void MyFuckedFunction(void) {

3. в файле библиотеки в самом верху напишите

void MyFuckedFunction(void);

4. найдите в библиотеке функцию

ISR(TIMER1_COMPA_vect)

и в самом её конце (или в самом начале) вставьте строку

MyFuckedFunction();

Должно заработать.

s1981
Offline
Зарегистрирован: 22.12.2013

Спасибо, завтра попробую. Щас на работе

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Забудьте про пост №7 - это я думая о своей задаче написал. В моей то такое проходит, а для Вашей этот мой пост - бред сивой кобылы. Забудье.

s1981
Offline
Зарегистрирован: 22.12.2013

Ну а что нибудь сделать можно?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Можно, например, так как оллега написал в посте №6

s1981
Offline
Зарегистрирован: 22.12.2013

А для этого что нужно исправить?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Наверно, я думаю, измерять скорость вращения колеса без помощи прерываний.

s1981
Offline
Зарегистрирован: 22.12.2013

Я это использую не на велосипеде, а на машине. Датчик на кордане, вернее магнит. Через millis не канает. Не успевает что ли, не знаю но не работает. Пробовал, хрень всякую кажет

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

с какой скоростью вращается кардан?

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

1 милис это 1 милисекунда. 1000 оборотов в секунду. Надо датчик Холла вешать. У него меньше дребезг. И ловить не импульсы а мерять паузы между импульсами миллисом.

s1981
Offline
Зарегистрирован: 22.12.2013

Jeka_M пишет:

Использовать для считывания датчика другой таймер.

Timer0  - занят ардуиновскими delay(), millis(), micros()

Timer1 - занят библиотеками toneAC, Servo

Timer2 - занят ардуиновской tone(). Поскольку у Вас своя библиотека toneAC, его и можно задействовать. 

Либо вообще отказаться от прямого использования аппаратного таймера и пользоваться millis().

А помогите пожалуйста? Что для этого нужно изменить в коде. Таймеры в ардуино для меня к сожалению темный лес

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Помогают здесь тем, кто делает сам. Читайте разбирайтесь, делайте, задавайте вопросы.

Если же Вам нужно, что кто-то просто сделал за Вас, то я Вам уже писал - попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014
s1981
Offline
Зарегистрирован: 22.12.2013

ЕвгенийП пишет:

Помогают здесь тем, кто делает сам. Читайте разбирайтесь, делайте, задавайте вопросы.

Если же Вам нужно, что кто-то просто сделал за Вас, то я Вам уже писал - попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.

Ну а вы можете это сделать. Максимум что я могу ну 1000р на счет тому кто сделает. Меня устраивает мой код

где использую просто ардуиновский Tone. но он не может сгенерировать сигнал меньше 30 Hz((.

А при 31 стрелка спидометра,поднимается уже на 20 км.ч ))) Платить вам десятки тысяч я не готов!!!!!!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

s1981 пишет:

Ну а вы можете это сделать. 

Я не могу (я уже писал Вам об этом в посте №3), но Вы там запостите, найдутся те, кто смогут. Бюджет можно озвучить сразу, чтоб люди с б´ольшими аппетитами не беспокоились.

s1981
Offline
Зарегистрирован: 22.12.2013

ЕвгенийП пишет:

s1981 пишет:

Ну а вы можете это сделать. 

Я не могу (я уже писал Вам об этом в посте №3), но Вы там запостите, найдутся те, кто смогут. Бюджет можно озвучить сразу, чтоб люди с б´ольшими аппетитами не беспокоились.

Молчат)))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, потерпите день-другой