Помогите подружить библиотеку с кодом
- Войдите на сайт для отправки комментариев
Пнд, 22/08/2016 - 14:36
Добрый день! Есть код, нужно использовать библиотеку 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); } }
Ну, судя по сообщению, в подключаемой Вами библиотеке тоже есть функция
ISR(TIMER1_COMPA_vect)
вот и возникает конфликт - две функции с одним название.
Объединяйтё в одну.
К сожалению знаю только азы программирования)) Моих знаний тут не хватит. Может поможете?
Я не могу, но Вы попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.
s1981
Дело в том, что у Вас в коде для считывания датчика задействован Timer1 и его прерывание по совпадению. В библиотеке ToneAC для генерации сигнала задействован этот же Timer1 и его прерывание по совпадению. Нельзя для двух разных задач использовать один и тот же таймер и прерывание.
А решить это можно? Как то?
Использовать для считывания датчика другой таймер.
Timer0 - занят ардуиновскими delay(), millis(), micros()
Timer1 - занят библиотеками toneAC, Servo
Timer2 - занят ардуиновской tone(). Поскольку у Вас своя библиотека toneAC, его и можно задействовать.
Либо вообще отказаться от прямого использования аппаратного таймера и пользоваться millis().
А решить это можно? Как то?
1. Удалите строки 32-42
2. Вместо строки 45 запишите
3. в файле библиотеки в самом верху напишите
4. найдите в библиотеке функцию
ISR(TIMER1_COMPA_vect)
и в самом её конце (или в самом начале) вставьте строку
Должно заработать.
Спасибо, завтра попробую. Щас на работе
Забудьте про пост №7 - это я думая о своей задаче написал. В моей то такое проходит, а для Вашей этот мой пост - бред сивой кобылы. Забудье.
Ну а что нибудь сделать можно?
Можно, например, так как оллега написал в посте №6
А для этого что нужно исправить?
Наверно, я думаю, измерять скорость вращения колеса без помощи прерываний.
Я это использую не на велосипеде, а на машине. Датчик на кордане, вернее магнит. Через millis не канает. Не успевает что ли, не знаю но не работает. Пробовал, хрень всякую кажет
с какой скоростью вращается кардан?
1 милис это 1 милисекунда. 1000 оборотов в секунду. Надо датчик Холла вешать. У него меньше дребезг. И ловить не импульсы а мерять паузы между импульсами миллисом.
Использовать для считывания датчика другой таймер.
Timer0 - занят ардуиновскими delay(), millis(), micros()
Timer1 - занят библиотеками toneAC, Servo
Timer2 - занят ардуиновской tone(). Поскольку у Вас своя библиотека toneAC, его и можно задействовать.
Либо вообще отказаться от прямого использования аппаратного таймера и пользоваться millis().
А помогите пожалуйста? Что для этого нужно изменить в коде. Таймеры в ардуино для меня к сожалению темный лес
Помогают здесь тем, кто делает сам. Читайте разбирайтесь, делайте, задавайте вопросы.
Если же Вам нужно, что кто-то просто сделал за Вас, то я Вам уже писал - попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.
Таймеры в ардуино для меня к сожалению темный лес
Просвещайтесь:
AVR микроконтроллеры для начинащих (урок 6) таймеры-счетчики
ATMega: режимы работы таймеров/счетчиков
Учебный курс AVR. Таймер - счетчик Т0. Регистры. Ч1
Учебный курс AVR. Таймер - счетчик Т0. Режим Normal. Ч2
Учебный курс AVR. Таймер - счетчик Т0. Режим CTC. Ч2
AVR. Учебный курс. Таймеры
AVR: настройка таймера счетчика
Таймеры счетчики микроконтроллеров AVR
Урок 5. Использование таймера в AVR микроконтроллерах
Помогают здесь тем, кто делает сам. Читайте разбирайтесь, делайте, задавайте вопросы.
Если же Вам нужно, что кто-то просто сделал за Вас, то я Вам уже писал - попробуйте запостить в "Ищу исполнителя" - наверняка кто-нибудь поможет.
Ну а вы можете это сделать. Максимум что я могу ну 1000р на счет тому кто сделает. Меня устраивает мой код
где использую просто ардуиновский Tone. но он не может сгенерировать сигнал меньше 30 Hz((.
А при 31 стрелка спидометра,поднимается уже на 20 км.ч ))) Платить вам десятки тысяч я не готов!!!!!!!
Ну а вы можете это сделать.
Я не могу (я уже писал Вам об этом в посте №3), но Вы там запостите, найдутся те, кто смогут. Бюджет можно озвучить сразу, чтоб люди с б´ольшими аппетитами не беспокоились.
Ну а вы можете это сделать.
Я не могу (я уже писал Вам об этом в посте №3), но Вы там запостите, найдутся те, кто смогут. Бюджет можно озвучить сразу, чтоб люди с б´ольшими аппетитами не беспокоились.
Молчат)))
Ну, потерпите день-другой