Помогите подружить библиотеку с кодом
- Войдите на сайт для отправки комментариев
Пнд, 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 запишите
void MyFuckedFunction(void) {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), но Вы там запостите, найдутся те, кто смогут. Бюджет можно озвучить сразу, чтоб люди с б´ольшими аппетитами не беспокоились.
Молчат)))
Ну, потерпите день-другой