Простой фэйлсэйф - помогите с программой
- Войдите на сайт для отправки комментариев
Здравствуйте! Я хочу сделать на базе ардуино модуль для модели, выполняющий роль фэйл-сэйфа и инвертора одного серво-канала. Модуль будет работать с обычным р/у приемником, он будет промежуточным звеном между некоторыми сервами и приемником.
Я не программист, и решил сейчас потренироваться и сделать программу, по которой ардуино будет просто копировать длительность серво импульса на другую ногу - восходящий фронт серво сигнала через прерывание ставит 1 в булевую переменную, нисходящий ставит 0, в основном цикле программа проверяет состояние переменной: если переменная равна 1 то ставит high на пин с серво, если 0 соответственно low. Моя китайская мега работает на 12мгц, то есть она вроде должна успевать все делать даже при самом коротком серво-импульсе, ведь и программа маленькая.
Сначала я вообще хотел использовать прерывание по лоу левелу на входном пине (жаль нет прерывания по высокому уровню..), и в отработчике прерывания ставить значение на выходной пин, и совсем ничего не делать в основном цикле, имхо, так надежнее, но тогда нужно ставить инвертор, а мне не хотелось паять.
[code] int pin0 = 2; //пин, на который идет сигнал с приемника int pin1 = 7;//выходной сигнал на серву boolean state = 0;//состояние выхода void setup() { pinMode(pin0, INPUT); pinMode(pin1, OUTPUT); attachInterrupt(pin0, get_rise, RISING); attachInterrupt(pin0, get_fall, FALLING); } void get_rise() { state = 1; } void get_fall() { state = 0; } void loop() { if(state == 0) pin1 = LOW; if(state == 1) pin1 = HIGH; } [/code]
Все верно подключаю, а серва не реагирует, подскажите, что не так.. Приемник и серва рабочие, несколько раз уже все проверял.
Я стараюсь писать максимально просто, потому что потом на эту мегу я хочу добавить гироскоп, чтобы одна из серв автоматически держала горизонт(в моем случае дифферент), а для этого судя по всему нужен будет пид -регулятор, не знаю пока, насколько он будет сложен в реализации, плюс еще на меге должен калман работать.
1. Переменные, которые изменяются в обработчике прерывания, должны быть объявлены с volatile.
2. Использование attachInterrupt неправильное. Указывать надо не номер пина, а номер прерывания (0 или 1). То, что они сидят на пине 2 и 3 указывать не надо. Поэтому строки 2 и 6 можно убрать. И как ниже написал коллега dimax, для одного внешнего прерывания (для одного пина) может быть только один обработчик. С одним из четырёх режимов: LOW, CHANGE, RISING, FALLING.
3. Вместо:
Должно быть:
Vladimir_KVG, код ужасный. Начиная от крупных косяков (типа 8 и 9 строка -должно быть что-то одно, либо райзин либо фоллин). Заканчивая вообще идеологией. Зачем применять МК там, где можно использовать один транзистор? :)
Спасибо за ответы! Про volatile и только одно прерывание на порт я не знал, спасибо. Буду основательно все изучать :)
А фэйлсэйф будет работать по такому алгоритму:
-на вход с прерыванием по низкому уровню подается инвертированный (транзистором :) ) сигнал с приемника
-в прерывании выходной порт ставится в 1, обнуляется значение специальной переменной
-в основном цикле программа по таймеру инкрементирует значение переменной, и если оно достигнет определенного значения(из-за пропадания сигнала и, значит, прерываний, обнуляющих эту переменную) выполняет "фэйлсэйфовые" операции
Алгоритм, вроде, рабочий. Может можно как-то проще сделать?