Прошу помочь дописать программу
- Войдите на сайт для отправки комментариев
Я не программист, но пришлось для проекта использовать микроконтроллер, выбор пал на ардуино.
Задача достаточно простая. К аналоговому входу подключен резистивный датчик, к PWM выходу - стрелочный индикатор-логометр. Прибор меряет уровень жидкости, который постепенно уменьшается с ее расходом.
Заготовку кода взял из обучающего видео Джереми Блюма:
int sensePin = 0; int OUTPin = 6; void setup() { pinMode(OUTPin, OUTPUT); } void loop() { int val = analogRead(sensePin); val = constrain(val, 45, 540); int OUTLevel = map(val, 45, 540, 0, 200); analogWrite(OUTPin, OUTLevel); }
То есть при изменении значения датчика в пределах от 45 до 540 уровень ШИМ пропорционально меняется от 0 до 200
Так все работает, но жидкость в емкости плескается и вместе с ней скачет стрелка. Нужно как-то добавить сглаживание. Мне предложили использовать для этотого следующий метод:
При включении один раз все делается как в приведенном выше коде значение OUTLevel выводится на стрелку и сохраняется для дальнейшего использования. А дальше датчик снова опрашивается, вычисляется OUTLevel_temp и сравнивается с предыдущим значением. Если новое значение больше чем старое, то к старому прибавляется некая константа инерции, которую нужно будет подобрать эксперементально, если меньше - то соответственно эта константа вычитается из старого значения уровня. Результат этого действия выводится на стрелку, а OUTLevel становится равным OUTLevel_temp И так по кругу до бесконечности. Таким образом стрелка за один такт не сможет изменить свое положение больше чем на значение константы инерции. Если уровень меняется резко - например при доливе жидкости, то нужно выключить питание и включить снова, для задания начального уровня.
Но вот написать скетч по этому алгоритму у меня не получается. Кто-нибудь может помочь?
Вернее не совсем так, "OUTLevel становится равным OUTLevel_temp" - это не правильно.
OUTLevel становится равным результату вычисления
Что то как то всё сложно. Предлагаю свою версию. Датчик производит замер раз 10 в 1 минуту а потом вычисляет среднее значение и выводит его на стрелку.
Ну как вариант я это тоже рассматривал, но есть небольшой ньюанс, этот же контроллер будет еще кое что делать, и если делать паузы между измерениями с помощью Delay, то и все сотальные функции будут тормозить
Забываем про псевдо-многозадачность))))) можно использовать прерывания по таймеру (пожертвовав 2 шим) или реализовать программно.
Ну можно и без задержки сделать
http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Ну яш написал что не програмист :)
А на счет сложности описанного метода, мне казалось что не так уж это и сложно. Вроде как по такому методу работают например указатели уровня топлива в автомобильных панелях приборов. (собственно свой вариант такого указателя я и делаю )
Можно и ваш метод использовать. Только осталось разобраться что вы имеете под словом такт?
Ну я имел ввиду за одно измерение
Нееее!!!!
Одно измерение будет происходить через определённое время или каждое прохождение Loop()?
Ну я даже не знаю :)
Наверное каждое прохождение Loop()
Я думаю что через чур. Вы получите тоже самое что имеете сейчас. Так что лучше каждый раз опрашивать по времени. И ИМХО лучше вычислять среднее значение. Вроде так меньше кода будет. Хотя надо смотреть. Ещё шим задействованы?
Да задействован еще один шим на 5 ножке для второго указателя.
И еще настроен таймер для увеличения частоты ШИМ, в setup добавлена строчка:
иначе логометры гудят
Попробуйте так
Инерция будет пропорционально зависить от переменной Delay. Если хотите то вожно сделать однонапрвленную инерцию....
Блин. Почему я плохо знаю программирование(((((
ОК ребята спасибо, поробую, попозже отпишусь по результатам теста
maksim а что подразумевается под однаправленной инерцией?
Попробовал пока на столе, в качестве датчика - переменный резистор, в качестве индикатора - светодиод и еще добавил в код вывод значения OUTLevel в COM порт и смотрю на него через терминал.
При включении сначала уровень минимальный и растет до нужного значения, то есть стрелка будет наоборот при включении подниматься на максимум и опускаться до нужного уровня
При таком значении Delay примерно 7 секунд уходит на измение от полного уровня до 0
Вроде как все работает, завтра буду пробовать
Значит, что сейчас при изменении в любую сторону значение инерционно, а можно например, чтобы при уменьшении значения была инерция, а при увеличении нет. Но я думаю когда речь идет об изменении уровня жидкости, то нужна инерция и на увеличение и на уменьшение.
Кстати, можно сделать так, чтобы при включении не было наростания т.е. чтобы при включении инерция отсутствовала. Для этого в функцию setup надо добавить строку:
Да, я тоже так думаю, она же плещется во все стороны :)
ОК завтра когда со стрелкой буду тестировать, попробую без наростания и с наростанием
Теперь нужно добавить еще один датчик с указателем и светодиод низкого уровня
Второй датчик сам по себе инерционный и там стрелка не скачет.
При увеличении частоты ШИМа и время инерции уменьшилось, поэтому сделал Delay = 1000.
Но возник глюк, почему то при изменени сопротивления одного датчика меняется уровень на обоих указателях
Где то видимо накосячил:
Я так понял добавили светодиод dut = 8; но почему то он завязан на показания первого датчика
Если так задумано прошу прощения)
Да, этот диод для первого датчика.
Второй- датчик температуры, потом к нему тоже добавлю пару диодов - прогрев и перегрев
Может что не так подключили?
Да вот как раз сижу смотрю...
Собирал пока на макетке, к машине еще не подключал.
В коде косяков нет?
Вроде бы нет, попробуйте так
тут опрос датчиков производится не зависимо друг от друга.
Хм, видимо каие-то наводки в самой макетке.
Датчик (переменный резистор) у меня один, подключаю его по почереди то к одному входу то к другому и один из входов остается в воздухе. Если его коснуться пальцем - наводка пропадает. Надо было подтянуть к земле
maksim еще раз спасибо большое за помощь!!!
Попробую на машине - отпишусь.
Вобщем все отлично!
Скетч залил, инерцию при старте убрал, delay еще увеличил до 2000. Машину шатал - стрелка стоит как вкопаная. Поеду с работы домой вечером - проверю на ходу.
Хм, видимо каие-то наводки в самой макетке.
Датчик (переменный резистор) у меня один, подключаю его по почереди то к одному входу то к другому и один из входов остается в воздухе. Если его коснуться пальцем - наводка пропадает. Надо было подтянуть к земле
Естественно, когда вывод в воздухе значение будет хаотично меняться.
Так может вместо стрелочных приборов задуматься о цифровых индикаторах?
Да не, меня устраивают стрелки :)
Просто поставил приборную панель от другой машины, а там датчик уровня топлива имел другое сопротивление и указатель врал, а указатель температуры вообще информацию получал с мозга в цифровом виде. Пришлось сделать управление этими указателями с отдельного контроллера :)
Естественно, когда вывод в воздухе значение будет хаотично меняться.
Так в том то и дело что не хаотично, это и сбило меня столку. Кручу резистор и обе стрелки синхронно поднимаются-опускаются.
Следующий этап - сделать индикатор номера передачи АКПП.
Займусь если получится на следующей неделе, наброски уже есть :)