Корректор спидометра
- Войдите на сайт для отправки комментариев
Доброго времени суток. Дабы не разводить длинное повествование:
-пилю для себя корректор, свапнул мотор, датчик скорости СОВСЕМ другой, спидометр безбожно врёт
-полноценной платы Ардуино жалко, да и не нужна оня сжечь, я "щитаю". Тем более под руками оказалась attiny85 в составе digispark
Доброго времени суток. Дабы не разводить длинное повествование:
-пилю для себя корректор, свапнул мотор, датчик скорости СОВСЕМ другой, спидометр безбожно врёт
-полноценной платы Ардуино жалко, да и не нужна оня сжечь, я "щитаю". Тем более под руками оказалась attiny85 в составе digispark
В чем вопрос: не поддерживает стабильный множитель в диапазоне частот преобразования 0-200Гц. Выходная частота при множителе, к примеру 3.5, плавает от 2.8 до 4. Но это в протеусе. В железе нет возможности померять, в условиях гаража отсутствуют приборы. Если есть у кого возможность собрать на стенде и померять, буду благодарен
Код:
#include
//********************************************************************
unsigned long freq = 0; // Время срабатывания датчика
unsigned long t_time = 0; // буферная переменная
const byte divider = 128; // Делитель прескалера
const float factor = 3.5; // Множитель частоты
const int redraw = 100; // Период обновления показаний
#define PIN_OUTPUT 1
//********************************************************************
void setup(){
attachInterrupt(0, sense, RISING); //прерывание по фронту импульса
TinySoftPwm_begin(divider, 0);}
//********************************************************************
void loop(){
static uint32_t StartUs = micros();
static uint32_t StartMs = millis();
if ((micros() - StartUs) >= freq) {
TinySoftPwm_process();
StartUs = micros();}
if ((millis()-StartMs) >= redraw) {// Обновляем показания
StartMs = millis();
if (freq <= 5000) TinySoftPwm_analogWrite(PIN_OUTPUT, 128);
else TinySoftPwm_analogWrite(PIN_OUTPUT, 0);}}
//********************************************************************
void sense(){ //измеряем длину периода импульса на входе по прерыванию
freq = (micros()- t_time)/(divider*factor);
t_time = micros();}
Выходная частота при множителе, к примеру 3.5, плавает от 2.8 до 4. Но это в протеусе. В железе нет возможности померять, в условиях гаража отсутствуют приборы. Если есть у кого возможность собрать на стенде и померять, буду...
ан@хер тагда пр@теуз, ежли всиравно вжилезе сабирать?)))
Он для того и создан, чтобы была возможность СИМУЛИРОВАТЬ всё без паяльников и стендов!!!
рука_лицо_(((
Спасибо за содержательный ответ.
Вслушайся в свои-же пейсанины - ты придлагаешь к@му-то сАбрать за тебя стенд для проверки??? ты в своём уме??? жаль, я не курю такое дерьмо, мошт с слава_богу, шо никурю... ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
klialex можете обьяснить, что у вас в коде происходит? Вы правда рассчитываете на основе PWM сделать спидометр?
Все делается куда проще - по прерыванию считаете входные импульсы и транслируете их на выход в нужном отношении... PWM-у в этом алгоритме места нет
Дело в том, что я тоже так пробовал. Все равно при генерации плавает коэффициент в протеусе, но к этому ещё и добавлялись помехи в выходном сигнале, наверное в момент срабатывания счётного прерывания. Возможно я не с той стороны зашёл. Считать надо не по аппаратному внешнему прерыванию, по таймеру с определенной частотой дискретизации проверять вход и с этой же частотой на основе множителя формировать выходной сигнал.Как бы по тикам процессора. Но я пока не знаю как этого реализовать здесь
Вслушайся в свои-же пейсанины - ты придлагаешь к@му-то сАбрать за тебя стенд для проверки??? ты в своём уме??? жаль, я не курю такое дерьмо, мошт с слава_богу, шо никурю... ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Если у кого-то на столе валяется digistump, есть под рукой генератор меандра и частотомер - дел на пару минут. У меня этого сейчас нет, в самоизоляции сидим. Потому и прошу помощи. Или подсказать где ошибся в кодах. А вы с вашей "пейсаниной" застряли где-то в Олбании 2007 года
не, это тупик, первый вариант лучше. Считаешь прерыванием число входящих импульсов и транслируешь их на выход с нужным делителем.
Только в случае прерывания нужно боротся с дребезгом и наводками. Во-первых, подтянуть вход к плюсу или к минусу, поставить конденсатор параллельно входу. Если частота низкая. можно и программно дребезг подавлять, как на кнопке
Вот именно у меня не получилось организовать стабильную генерацию меандра на выходе. Без ШИМ во время генерации процессор занят обработкой прерывания. И происходит такое же херня с плаванием коэффициента преобразования частоты в зависимости от частоты входящего сигнала. Как выдержать непрерывную генерацию на выходе? Я нашел только аппаратный ШИМ.
а частоты какие, примерно?
Диапазон входных частот 0 - 200Гц. На 100Гц оно должно показывать 60км/ч Соответственно мой датчик работает на пониженной частоте, и ее надо увеличить.
при таких частотах никакие прерывания вовсе не нужны. просто обрабатываете как нажатие кнопки.
А коэффициент передачи в любом случае будет плавать, ведь число импульсов может быть только целым.
Множитель не должен плавать. Период и частота следования импульсов могут быть и не целыми.
Как врет спидометр сейчас ?
Как вы себе представляете не целое число импульсов на один оборот датчика ???
;) Но мне же не важно количество импульсов на один оборот. Я не считаю абсолютных значений скорости. У меня задача увеличить частоту импульсов в определенное число раз. А частота входящих импульсов может быть и не целыми числом, но период их следования да. Я не считаю число импульсов, а измеряю время между импульсами, вернее их положительными фронтами прерыванием, делю на коэффициент и формирую выходной сигнал с вычисленным периодом. Так вот частота выходного сигнала плавает. Не могу понять либо это протеус прикалывается, либо на таких частотах уже не хватает времени процессора. Сейчас на скорости 70км/ч показывает 20км/ч. Т.е. если на входе 10Гц, на выходе должно быть 35Гц, если на входе 100Гц, соответственно на выходе 350Гц. Но у меня не так, нелинейно умножает.
Вы считаете частоту, устанавливаете скважность, а после этого у вас МК виноват? Китайцы проклятые? Америка и Обама лично?
Я такое делал чисто на таймерах человеку одному - даже в ардуине килогерцы нормально масштабировались. Но всякие миллисы уже не канают.
Тут на форуме был универсальный генератор. Я бы взял за основу, прикрутил счетчик с этим множителем и загонял как параметр в функцию того скетча. По крайней мере на выходе будет заданная частота и само плавать не будет. Но вообще что то не пойму проблемы - можно прям в одном цикле замерять период, умножать на коэффициент и тут же формировать сигнал на выходе с новым периодом, считать можно в любых попугаях, наверное даже тупо счетчиком цикла.
3.5 раза ? Очень странно !
и разве
static uint32_t StartUs = micros();
static uint32_t StartMs = millis();
не должны быть вне loop ?
Так статик же ж! Кто ж их выносит.)
Волатильными должны быть переменные используемые в прерывании.
тогда для чего эта строка
if ((micros() - StartUs) >= freq) {
? Только что присвоили static uint32_t StartUs = micros(); и сразу сравниваем ...
тогда для чего эта строка
if ((micros() - StartUs) >= freq) {
? Только что присвоили static uint32_t StartUs = micros(); и сразу сравниваем ...
не ожидал от вас :)
строчка static uint32_t StartUs = micros(); выполняется один раз при первом прогоне loop()... на то оно и static
не проснулся видимо ещё ...
надо будет кстати глянуть - во что static выливается в выходном коде ...
klialex,
Во-первых, вставьте код правильно. Иначе невозможно его обсуждать без номеров строк.
Ошибок в коде много. Я бы сказал, что это сплошная ошибка, начиная с негодного подхода. Вы копите погрешности везде, где только можете, в прерывании используете неволатильные переменные, а потом удивляетесь, что оно плавает.
Кроме того, сформулируйте (в первую очередь, для себя) кратко, чётко, и в одном месте чётко задачу. Диапазон частот! Коэффициент? Кстати, Вы уверены, что он одинаковый на всём диапазоне частот? Или он сам по себе ещё от частоты зависит?
В общем, давайте чёткую формулировку задачи и правильно выложенный код.
вижу такой алгоритм:
в переменной pp храним длительность выходного полупериода
в основном цикле просто ждем когда проходит время pp и инвертируем состояние выхода
в прерывании вычисляем период входных импульсов, делим его на 3.5*2 и сохраняем в pp
можно,но не обязательно - ещё продумать ситуацию когда импульсов нет или мало - авто стоит или ОЧЕНЬ медленно едет
можно,но не обязательно - ещё продумать
Думать всегда обязательно.
При Вашем алгоритме оно НИКОГДА не покажет 0 просто потому, что после последнего импульса, она будет продолжать долбить каждые pp, в ожидании нового импульса.
ЕвгенийП для спидометра это не очень важно -очень инерционная хрень, а вот одометр будет медленно наращивать показания
Прошу прощения. Был в гараже, открыл тему с телефона, кнопочек {code} не нашел. Сейчас и в дальнейшем исправлюсь.
Постановка задачи проста - увеличить частоту импульсов на выходе относительно входной в заданное число раз. Множитель необязательно целочисленный. Форма сигнала - меандр. За основу брал статью с https://fanclub-vw-bus.ru/forum/viewtopic.php?t=25745
Собственно код из топика:
Пробовал еще и так:
в 18 строке у вас каждый проход деление и умножение на МК, в котором ни того ни другого нет !
деление умножение надо перенести в 27 строку, убрать FLOAT и делить на 7
21 и 22 надо заменить на прямое обращение к порту
и что данный код не работает ? в автомобиле надо ещё простейший фильтр RC припаять на вход - там очень "шумно" ...
Спасибо. Не могу только понять как для digispark прямое обращение к порту реализуется
И до машины пока не дошло, в протеусе уже некрасиво выглядит, а машина пока не ездит, дальше работы ведутся
и что данный код не работает ? в автомобиле надо ещё простейший фильтр RC припаять на вход - там очень "шумно" ...
думаю из-за шумов и не работает. Шумный сигнал +прерывание = ступор, шуиы на входе способны полностью заморозить этот код
Какие шумы в протеусе?
b707 когда круиз-контроль себе делал - то же столкнулся с шумами на сигнале от датчика скорости.
Какие шумы в протеусе?
да причем тут протеус? Вы в протеусе пробовали код. состоящий из кучи ошибок, его и вспоминать не стоит.
Сначала залейте в протеус вот это и посмотрите
Спасибо. Не могу только понять как для digispark прямое обращение к порту реализуется
даташит в помощь, раздел называется "GPIO toogle" или как-то похоже
стр 53
writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register
Нашел причину того что на разных частотах ТС видит разный результат :-) ...
при старте freq = 0 и пока пройдёт первый период на входе - цикл выдаёт "мешок" сигналов на выход и потом начинает нормально считать
на разной частоте этот "мешок" разного размера ..
пока не измерен период входного сигнала (не прошло два прерывания) - нельзя начинать генерацию на выходе
ЕвгенийП для спидометра это не очень важно -очень инерционная хрень,
Что значит "не важно"? Она ведь не "медленно будет до нуля сползать", а никогда не сползёт - остановится на последнем показании. Начали Вы достаточно резко тормозить - последний раз было зафиксировано, скажем, 20, а до следующего импульса машина уже стала - так он Вам будет вечно 20 показывать!
Мы же каждый импульс мониторим - если случилось что скорость упала с 20 до нуля за один импульс, то вы куда то воткнулись.
если случилось что скорость упала с 20 до нуля за один импульс, то вы куда то воткнулись.
Во, так это не баг, а фича получается - показывает последнюю зафиксированную скорость до втыкания.
Не воткнулся, а просто резко тормозил. ТС пишет о частотах в единицы герц (10 упоминал) - при хорошем торможении ... делов-то. По-любому это неправильно, Вы это уже поняли, так чего спорить - переделывать надо алгоритм.
При этом этот счётный алгоритм у других людей работает. Не в точности, но очень похожий. Выше давал ссылку
Да, я видел такое на старте. Пакет мусора, но дальше счёт идёт нормально. Только набегает погрешность
Авто спидометры изначально завышают скорость на 10 % ...
так сейчас-то в чем проблема, решили же все вроде