Измерение скорости автомобиля по штатному датчику
Эдак можно и FRAM микросхему приделать. Протокол совместимый с обычной EEPROM, но можно и проще. Ресурс и скорость почти как у оперативной памяти. Если писать каждую секунду, то примерно на возраст вселенной хватит.
Усложнять просто. Упрощать сложно.
- Реклама
- Сообщения: 1006
- Зарегистрирован: Ср окт 04, 2017 20:47:40
Коротко и ясно!АлександрЛ
посчитать количество импульсов с датчика за определённое время, а время счёта подобрать так, чтобы количество посчитанных за это время импульсов получалось равным скорости?
Блин и разве не видно, что в данном предложении представлена вся правильная логика нужного счёта.
Если время получиться очень малым (часто для вывода), есть смысл усреднять (ADD и ROL) счёт (по вашему усмотрению) за N отсчётов. Да и вообще - всегда для показа иметь хотя бы слабо интегрированное значение параметра, чтоб цифирь не мелькала. Фсё!
И зачем чего-то там гадать на "кофейной" сколько на км, метр, .см., мм?
И для программы бортовика, для любителей ставить не "родные" колёсЬя, есть смысл в программу вводить спец режим авто-коррекции именно сосчитав имп/км, ибо -Martian
Надо сосчитать, проехав километр
Разницей всего в несколько имп. можно пренебречь ибо не принципиально, т.к. километровые столбы тоже не до мм устанавливают.MartianНемного разницы в диаметре колёс - наверняка даст разное число.
В EEPROM я писал нужные значения из оперативной памяти ТОЛЬКО при выкл. зажигания, там же хранились и стартовые (заводские
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
Вроде нашел причину. Не успевает считать пришедшие импульсы во внешнем прерывании. Не вывозит столько задач этот камень к сожалению. Попробую конечно по захвату как-то сделать, но думаю, что не вывезет.
- Сообщения: 12867
- Зарегистрирован: Сб дек 18, 2021 19:25:32
Этот "камень" может гораздо больше. Если 4000 импульсов на километр, то при скорости 300 км/ч какая частота импульсов? 350 герц? И не успевает? 
Последний раз редактировалось Martian Вт сен 05, 2023 20:44:43, всего редактировалось 1 раз.
Эээээ.... Чо? Как он может не успевать, но при этом насчитать импульсов больше? Не сходится. Гляньте осциллографом что там происходит, скорее всего дребезг какой-нибудь.
Усложнять просто. Упрощать сложно.
- Реклама
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
Помимо внешних прерываний учтите прерывания по усарту для поддержания связи, по RX и по TX. Учтите прерывания по таймеру T0 каждую миллисекунду (аналог millis arduino) чтобы уйти от Delay. Учтите запрет прерываний на обмене данными с датчиком температуры DS - не помню, 1320 вроде. И нормуль так получится.
Теперь как я узнал:
1)путем несложных математических расчетов, мы знаем, что скорость 100 км/ч= 27,7777 м/c.
2)Знаем, что на 1 км пройденного пути приходится 4073 импульса.
3) На 1 метр приходится 4,073 импульса.
4) Для скорости 100 км/ч считаем частоту следования импульсов 27,7 м/c*4,073 импульса на метр и получаем 112,8 Гц.
Затем я взял генератор прямоугольных импульсов, выставил на нем 113 Гц, пошел в машину и подкинул его вместо датчика скорости. И спидометр(на автомобиле, штатный показал мне 105 км/ч.
Затем я пошел домой, и подключил этот генератор к своему БК, и он мне показал 25 км/ч.
Вот так вот я и узнал)
Теперь как я узнал:
1)путем несложных математических расчетов, мы знаем, что скорость 100 км/ч= 27,7777 м/c.
2)Знаем, что на 1 км пройденного пути приходится 4073 импульса.
3) На 1 метр приходится 4,073 импульса.
4) Для скорости 100 км/ч считаем частоту следования импульсов 27,7 м/c*4,073 импульса на метр и получаем 112,8 Гц.
Затем я взял генератор прямоугольных импульсов, выставил на нем 113 Гц, пошел в машину и подкинул его вместо датчика скорости. И спидометр(на автомобиле, штатный показал мне 105 км/ч.
Затем я пошел домой, и подключил этот генератор к своему БК, и он мне показал 25 км/ч.
Вот так вот я и узнал)
- Сообщения: 12867
- Зарегистрирован: Сб дек 18, 2021 19:25:32
Ну, стенд правильный, а вот с программой что-то не то... со всем перечисленным можно ещё в спящий режим загнать микроконтроллер, чтоб в простое электричество не жрал 
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
А потом я вывел на экран значение счетчика, который считает импульсы во внешнем прерывании (количество за 1 сек) при частоте 113 Гц и получил значение 28-30. Что все и объясняет.
Добавлено after 1 minute 44 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4473348#p4473348"]можно ещё в спящий режим загнать микроконтроллер,
[/uquote]
Он у меня спит вместе с дисплеем в глубоком самом шатдауне))) Я просто об этом не рассказал.
Добавлено after 1 minute 44 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4473348#p4473348"]можно ещё в спящий режим загнать микроконтроллер,
Он у меня спит вместе с дисплеем в глубоком самом шатдауне))) Я просто об этом не рассказал.
Не упомянули МК, напр ATmega328:
VectorNo. 1 -> INT0 External Interrupt Request 0.
VectorNo. 19, 20, 21 -> USART
VectorNo. 15, 16, 17 -> TIMER0
То, что считаете причиной, таковым не является.
VectorNo. 1 -> INT0 External Interrupt Request 0.
VectorNo. 19, 20, 21 -> USART
VectorNo. 15, 16, 17 -> TIMER0
То, что считаете причиной, таковым не является.
Последний раз редактировалось veso74 Вт сен 05, 2023 21:20:50, всего редактировалось 2 раза.
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
Да, кстати, преобразователь импульсный по питанию. К7805-500R3. Трехлапый. Ток холостого потребления всего 0.5 mA. До 36В входного, 500 mA нагрузка. Рекомендую.
Добавлено after 1 minute 17 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4473353#p4473353"]То, что считаете причиной, таковым не является.[/uquote]
Можете привести доводы?
Добавлено after 1 minute 17 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4473353#p4473353"]То, что считаете причиной, таковым не является.[/uquote]
Можете привести доводы?
Как вариант, можно в целевом прерывании моргать диодиком. Хотя бы понятно будет как оно срабатывает.
Усложнять просто. Упрощать сложно.
Прочитайте о прерываниях и их приоритетах. Это интересно.
--
--
Тогда не удивляйтесь показаниям. Попробуйте разместить импульсные преобразователи там, где они нужны, а не везде.... преобразователь импульсный по питанию К7805-500R3
Последний раз редактировалось veso74 Вт сен 05, 2023 21:26:37, всего редактировалось 1 раз.
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
[uquote="veso74",url="/forum/viewtopic.php?p=4473357#p4473357"]Прочитайте о прерываниях и их приоритетах.[/uquote]
Так я читал. Если выполняется одно, и возникло другое, то пока первое не закончится, втрое не прервет первое. Независимо от приоритета Это как бы я знаю точно.
Добавлено after 4 minutes 47 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4473357#p4473357"][quote
Попробуйте разместить импульсные преобразователи там, где они нужны, а не везде.[/uquote]
Он на своем месте. И работает очень неплохо. И не создает проблем. От генератора импульсов все четко, ничего не дергается и стабильно. Или вы думаете, что имульсный источник питания в 4 раза занижает показания? А на остальное он никак не воздействует?)))
Так я читал. Если выполняется одно, и возникло другое, то пока первое не закончится, втрое не прервет первое. Независимо от приоритета Это как бы я знаю точно.
Добавлено after 4 minutes 47 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4473357#p4473357"][quote
Попробуйте разместить импульсные преобразователи там, где они нужны, а не везде.[/uquote]
Он на своем месте. И работает очень неплохо. И не создает проблем. От генератора импульсов все четко, ничего не дергается и стабильно. Или вы думаете, что имульсный источник питания в 4 раза занижает показания? А на остальное он никак не воздействует?)))
Устройство ваше, вы его проектируете. Мы полагаем, даем идеи и надеемся сократить время на обнаружение неточности в работе. (+транслейт)
Я не видел имп.источника питания, который не мешал бы в измерениям. В первом приближении: да, но это зависит от установленного уровня.
Я не видел имп.источника питания, который не мешал бы в измерениям. В первом приближении: да, но это зависит от установленного уровня.
Последний раз редактировалось veso74 Вт сен 05, 2023 21:37:16, всего редактировалось 1 раз.
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
Ну я как бы и отписал, в чем проблема кроется. Просто вы не можете поверить в то, что прерывания могут профукивать приходящие импульсы. Это же не пентиум 4.
Измените начин. С помощью этого МК коллеги измеряют (частотомером например) до Fclk/2.
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
[uquote="veso74",url="/forum/viewtopic.php?p=4473367#p4473367"]С помощью этого МК коллеги измеряют (частотомером например) до Fclk/2.[/uquote]
Абсолютно с вами согласен. Но там-то устройство заточено на только измерение частоты и вывод показаний. Но когда вам нужно помимо всего этого метаться каждый раз к ЭБУ и отвечать на каждый посланный им бит подтверждением, и не терять связь, то тут как бы уже проблема есть.
Добавлено after 2 minutes 21 second:
Там нельзя покурить, почесать яйки, а потом такой: " Ну-ка дружок, что там у нас с температурой?" Нет, там нон-стоп все идет.
Абсолютно с вами согласен. Но там-то устройство заточено на только измерение частоты и вывод показаний. Но когда вам нужно помимо всего этого метаться каждый раз к ЭБУ и отвечать на каждый посланный им бит подтверждением, и не терять связь, то тут как бы уже проблема есть.
Добавлено after 2 minutes 21 second:
Там нельзя покурить, почесать яйки, а потом такой: " Ну-ка дружок, что там у нас с температурой?" Нет, там нон-стоп все идет.
Причём сам ЭБУ мотора можно сделать на меге16. Есть такие проекты. ДВС крутить задачка посерьёзнее будет, чем температурку узнать и 122 герца посчитать, не так ли? Всё влезет в мегу8 и по процессорному времени и по объёму кода. Главное не сдаваться.
Усложнять просто. Упрощать сложно.
a_b_r_a, тебе уже посоветовали забыть о float, чтобы он не расходовал процессорное время, и работать с целыми числами.
стандартное правило - в прерываниях делать необходимый минимум, а основную работу делать в основном цикле. и уж тем более, в прерывании не делать вычисления с использованием "флота".
пусть по прерыванию только инкрементируется счетчик импульсов, а потом 1 раз в секунду в основном цикле один раз вычислить скорость.
по датчику температуры (DS18B20) - не нужно запрещать прерывания на весь цикл обмена с датчиком.
нужно в начале каждого слота времени запретить.
при чтении - через примерно 14 мкс прочитать пин датчика и разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
при записи - после выдачи бита на пин можно сразу же разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
а по таймеру T0 1 мс - зачем тебе так часто? и что конкретно (как много) делается в прерывании по таймеру T0?
стандартное правило - в прерываниях делать необходимый минимум, а основную работу делать в основном цикле. и уж тем более, в прерывании не делать вычисления с использованием "флота".
пусть по прерыванию только инкрементируется счетчик импульсов, а потом 1 раз в секунду в основном цикле один раз вычислить скорость.
по датчику температуры (DS18B20) - не нужно запрещать прерывания на весь цикл обмена с датчиком.
нужно в начале каждого слота времени запретить.
при чтении - через примерно 14 мкс прочитать пин датчика и разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
при записи - после выдачи бита на пин можно сразу же разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
а по таймеру T0 1 мс - зачем тебе так часто? и что конкретно (как много) делается в прерывании по таймеру T0?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 57
- Зарегистрирован: Ср янв 27, 2010 21:53:52
Код: Выделить всё
#include "ds18b20.h"
volatile uint32_t last_time;
uint8_t st=0;
//=========================
//Определение датчика на шине
uint8_t dt_test_device(void)
{
uint8_t stektemp=SREG; // сохранение значения стека
cli(); // запрещаем прерывания
uint8_t dt;
DDRTEMP |= 1<< BITTEMP;
PORTTEMP &= ~ (1<<BITTEMP); // Притягиваем к нулю шину
_delay_us(485); // Задержка на минимум 480 мкС
sei();
DDRTEMP &= ~ (1<<BITTEMP); // Отпускаем шину
_delay_us(65); //Задержка на минимум 60 мкС
if ((PINTEMP & (1<<BITTEMP))==0 ) // Проверяем, ответит ли устройство
{
dt=1; // Устройство ответило
}
else dt=0; // Устройства нет
SREG=stektemp; // Вернем значение стека
_delay_us(420); //
sei();
return dt;
}
//=========================
// Функция чтения бита с датчика
uint8_t dt_readbit(void)
{
uint8_t stektemp=SREG; // сохранение значения стека
cli(); // запрещаем прерывания
uint8_t bt; // Переменная хранения бита
DDRTEMP |= 1<< BITTEMP;
PORTTEMP &= ~ (1<<BITTEMP); // Притягиваем к нулю шину
_delay_us(2);
DDRTEMP &= ~ (1<<BITTEMP); // Отпускаем шину
_delay_us(13);
bt=(PINTEMP & (1<<BITTEMP))>>BITTEMP; // Читаем бит
_delay_us(45);
SREG=stektemp; // Вернем значение стека
sei();
return bt;
}
//========================
// Функция чтения байта с датчика
uint8_t dt_readbyte(void)
{
uint8_t c=0;
uint8_t i;
for(i=0;i<8;i++)
c|=dt_readbit()<<i; // Читаем бит
return c;
}
//=========================
// Функция записи бита
void dt_sendbit(uint8_t bt)
{
uint8_t stektemp=SREG; // сохранение значения стека
cli(); // запрещаем прерывания
DDRTEMP |= 1<< BITTEMP;
PORTTEMP &= ~ (1<<BITTEMP); // Притягиваем к нулю шину
_delay_us(2);
if(bt)
DDRTEMP &= ~ (1<<BITTEMP); // Отпускаем шину
_delay_us(65);
DDRTEMP &= ~ (1<<BITTEMP); // Отпускаем шину
SREG=stektemp; // Вернем значение стека
sei();
}
//=========================
// Функция записи байта в датчик
void dt_sendbyte(uint8_t bt)
{
uint8_t i;
for(i=0;i<8;i++)
{
if ((bt & (1<<i))==1<<i)
dt_sendbit(1); // Передаем 1
else
dt_sendbit(0); // Передаем 0
}
}
//==========================
uint16_t dt_check(void)
{
uint8_t bt; // переменная для считывания байта
if (!st) // Начало первой фазы измерения
{
if (dt_test_device()==1) // Если устройство нашлось
{
dt_sendbyte(NO_ID); // Пропускаем идентификацию
dt_sendbyte(T_CONVERT);// Измеряем температуру
st=1; // Установим флаг окончания первой фазы измерения
last_time=millis;
}
}
// Вторая фаза измерения
if (millis-last_time>750) // Проверяем, прошло ли 750 мС. В 12 битном режиме преобразование 750 мС
{
last_time=millis;
dt_test_device();
dt_sendbyte(NO_ID);
dt_sendbyte(READ_DATA); //Даем команду на чтение данных
bt=dt_readbyte(); // Читаем младший бит
ttt=dt_readbyte();
ttt=(ttt<<8)|bt; // Сдвигаем старший байт влево, на его место пишем младший байт
st=0; // Готовимся к новому измерению
}
else asm("nop");
return ttt; // Возвращаем измеренную температуру
}
//========================
// Преобразование температуры в единицы
uint8_t converttemp(uint16_t tt)
{
uint16_t b=0;
uint8_t t;
b=tt;
b=b>>11; // Оставляем 5 старших знаковых бит
if (b) // Если хотя бы один из этих бит равен 1, то температура отрицательная
{
v=1; // Установим флаг отрицательной температуры
t=((~tt)+1)>>4; // Проинвертируем побитно и прибавим 1 для преобразования
}
else
{
v=0; // Температура положительная
t=tt>>4; // отсекаем часть младших битов. Оставляем только единицы градусов.
}
return t;
}
Блин, не знаю, как спойлер сделать. 1 мсек это типа функции millis arduino. Чтобы заменить delay


