Вызов метода класса из прерывания.
- Войдите на сайт для отправки комментариев
Пт, 21/02/2014 - 11:45
Решил освоить классы и их применение. Написал простую программу, но так и не смог добиться её работы.
// Arduino. Test Class & Interrupt. // #define IOPort Serial #define PortSpeed 9600 // class foo { public: foo(): counter(42) {} void up(){ counter++; } void dn(){ counter--; } int get(){return counter;} private: int counter; }; // foo bar; // void setup(){ IOPort.begin (PortSpeed); attachInterrupt (0, bar.up, FALLING); attachInterrupt (1, bar.dn, FALLING); } void loop(){ IOPort.println (bar.get()); delay (1000); }
Идея проста, увеличивать или уменьшать значение counter.
Помогите, пожалуйста!
Как-то странно объявлен class foo! А вы компилировали (проверяли) скетч в Arduino IDE?
Как-то странно объявлен class foo! А вы компилировали (проверяли) скетч в Arduino IDE?
Да, проверял. И если менять значения не через прерывания, то работает. А через прерывания - ошибки.
Ошибки чего, компиляции?
foo(): counter(42) {} - подскажите, что значт? Не силен в ООП под С++. Похоже на конструктор, который инициализирует couter значением 42?
Сразу есть подозрение, что в аттаче должна быть функция void (), а не метод класса! Точнее указатель на функцию void ().
Для нормальной работы с переменными в прерываниях переменная должна бать описана как
volatile int counter;
см пример http://arduino.ru/Reference/AttachInterrupt
Ошибки чего, компиляции?
foo(): counter(42) {} - подскажите, что значт? Не силен в ООП под С++. Похоже на конструктор, который инициализирует couter значением 42?
Сразу есть подозрение, что в аттаче должна быть функция void (), а не метод класса! Точнее указатель на функцию void ().
1. Ошибки компиляции, да.
2. foo(): counter(42) {} это конструктор - я по книге делал, не сам придумал :-)
3. Натолкнуло на мысль. Проверю.
Получилось, НО.
То, что получилось полностью не соответствует замыслу :-(
Значится так, это не С, а С++.... Вообщем если коротко то учите мат.часть.
А если длинно то это невозможно, дело в том, в attachInterrupt передается указатель на функцию. Но метод класса не возможно вызвать без его инстанса. грубо говоря если раскрутить вызов метода в обычный С то
Короче говоря, вызов метода класса, можно рассматривать как вызов обычной функции С, где первый параметр это указатель на класс.
А attachInterrupt ни о какой передаче и ни о каком инстансе и слыхом не слыхивал, можете использовать статические методы класса, там прокатит, но это все равно что писать внешние функции, вообщем С++ не всегда красиво стыкуется с С.
А я думаю, что просто подход неправильный в данном случае у автора. Зачем подстраивать класс под аттач, когда можно сделать все просто. Класс оставляем, но пишем свои функции-обертки, которые будут вызываться в аттачах:
так и приходиться делать, есть более изящные конструкции, но они частенько сложны для понимания если С++ не родной язык :-)
Спасибо за замечания и комментарии.
Получилось не так, как хотелось, но то, что нужно. Теперь с помощью двух прерываний я умею менять значения нескольких переменных.
Буду продолжать учить матчасть и попробую решить эту задачу поизящнее :-)
Тихий ужас.. i используется в цикле в loop и в прерывании, натурально - обезьяна с гранатой.
Второе, после цикла у Вас i == N, если пойдет прерывание, то получите channel[N].up() или dn(), т.е. выстрел в неизвестность.
На счет классов - не получится решить задачу, только через задницу (как сейчас), либо через вызов статических методов классов.
О чего нарыл - обработчик прерывания статическим методом класса с доступом к private данным.
Правда это код для ARM LeafMaple (attachInterrupt немного другой), но надо проверить под Arduino!
О чего нарыл - обработчик прерывания статическим методом класса с доступом к private данным.
Правда это код для ARM LeafMaple (attachInterrupt немного другой), но надо проверить под Arduino!
Спасибо, почитаю и это. Я сейчас зарылся полностью в изучение "матчасти", думаю ещё на неделю-другую хватит.
Есть сомнения в работоспособности примера - статические методы работают могут работать только со статическими переменными. (ну по крайней мере по другому я не знаю)
Работать не будет, ошибка компилятора, опять не пропускает с разными типами параметров в attach-е, да и в примере они передают 4 параметра, а в доке по libmaple attach с тремя параметрами (тоже не должно скомпилиться, но не могу проверить - сдох АРМ)!