Измерение скорости автомобиля по штатному датчику

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 5806
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Эдак можно и FRAM микросхему приделать. Протокол совместимый с обычной EEPROM, но можно и проще. Ресурс и скорость почти как у оперативной памяти. Если писать каждую секунду, то примерно на возраст вселенной хватит.
Усложнять просто. Упрощать сложно.
Контактная информация:
Реклама
Электрический кот
Аватара пользователя
Сообщения: 1006
Зарегистрирован: Ср окт 04, 2017 20:47:40

Сообщение valentinovich »

АлександрЛ
посчитать количество импульсов с датчика за определённое время, а время счёта подобрать так, чтобы количество посчитанных за это время импульсов получалось равным скорости?
Коротко и ясно!
Блин и разве не видно, что в данном предложении представлена вся правильная логика нужного счёта.
Если время получиться очень малым (часто для вывода), есть смысл усреднять (ADD и ROL) счёт (по вашему усмотрению) за N отсчётов. Да и вообще - всегда для показа иметь хотя бы слабо интегрированное значение параметра, чтоб цифирь не мелькала. Фсё!

И зачем чего-то там гадать на "кофейной" сколько на км, метр, .см., мм? :)
Martian
Надо сосчитать, проехав километр
И для программы бортовика, для любителей ставить не "родные" колёсЬя, есть смысл в программу вводить спец режим авто-коррекции именно сосчитав имп/км, ибо -
MartianНемного разницы в диаметре колёс - наверняка даст разное число.
Разницей всего в несколько имп. можно пренебречь ибо не принципиально, т.к. километровые столбы тоже не до мм устанавливают. :)
В EEPROM я писал нужные значения из оперативной памяти ТОЛЬКО при выкл. зажигания, там же хранились и стартовые (заводские :) ) параметры для возврата к исходному состоянию. Ничего там за ХХ лет не убилось.
Реклама
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

Вроде нашел причину. Не успевает считать пришедшие импульсы во внешнем прерывании. Не вывозит столько задач этот камень к сожалению. Попробую конечно по захвату как-то сделать, но думаю, что не вывезет.
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Этот "камень" может гораздо больше. Если 4000 импульсов на километр, то при скорости 300 км/ч какая частота импульсов? 350 герц? И не успевает? :shock:
Последний раз редактировалось Martian Вт сен 05, 2023 20:44:43, всего редактировалось 1 раз.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 5806
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Эээээ.... Чо? Как он может не успевать, но при этом насчитать импульсов больше? Не сходится. Гляньте осциллографом что там происходит, скорее всего дребезг какой-нибудь.
Усложнять просто. Упрощать сложно.
Контактная информация:
Реклама
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

Помимо внешних прерываний учтите прерывания по усарту для поддержания связи, по 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 км/ч.
Вот так вот я и узнал)
Реклама
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Ну, стенд правильный, а вот с программой что-то не то... со всем перечисленным можно ещё в спящий режим загнать микроконтроллер, чтоб в простое электричество не жрал ;)
Контактная информация:
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

А потом я вывел на экран значение счетчика, который считает импульсы во внешнем прерывании (количество за 1 сек) при частоте 113 Гц и получил значение 28-30. Что все и объясняет.

Добавлено after 1 minute 44 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4473348#p4473348"]можно ещё в спящий режим загнать микроконтроллер, ;)[/uquote]
Он у меня спит вместе с дисплеем в глубоком самом шатдауне))) Я просто об этом не рассказал.
Поставщик валерьянки для Кота
Сообщения: 1922
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

Не упомянули МК, напр ATmega328:

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

Сообщение a_b_r_a »

Да, кстати, преобразователь импульсный по питанию. К7805-500R3. Трехлапый. Ток холостого потребления всего 0.5 mA. До 36В входного, 500 mA нагрузка. Рекомендую.

Добавлено after 1 minute 17 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4473353#p4473353"]То, что считаете причиной, таковым не является.[/uquote]
Можете привести доводы?
Друг Кота
Аватара пользователя
Сообщения: 5806
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Как вариант, можно в целевом прерывании моргать диодиком. Хотя бы понятно будет как оно срабатывает.
Усложнять просто. Упрощать сложно.
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1922
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

Прочитайте о прерываниях и их приоритетах. Это интересно.
--
... преобразователь импульсный по питанию К7805-500R3
Тогда не удивляйтесь показаниям. Попробуйте разместить импульсные преобразователи там, где они нужны, а не везде.
Последний раз редактировалось veso74 Вт сен 05, 2023 21:26:37, всего редактировалось 1 раз.
Контактная информация:
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

[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 раза занижает показания? А на остальное он никак не воздействует?)))
Поставщик валерьянки для Кота
Сообщения: 1922
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

Устройство ваше, вы его проектируете. Мы полагаем, даем идеи и надеемся сократить время на обнаружение неточности в работе. (+транслейт)
Я не видел имп.источника питания, который не мешал бы в измерениям. В первом приближении: да, но это зависит от установленного уровня.
Последний раз редактировалось veso74 Вт сен 05, 2023 21:37:16, всего редактировалось 1 раз.
Контактная информация:
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

Ну я как бы и отписал, в чем проблема кроется. Просто вы не можете поверить в то, что прерывания могут профукивать приходящие импульсы. Это же не пентиум 4.
Поставщик валерьянки для Кота
Сообщения: 1922
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария

Сообщение veso74 »

Измените начин. С помощью этого МК коллеги измеряют (частотомером например) до Fclk/2.
Контактная информация:
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

[uquote="veso74",url="/forum/viewtopic.php?p=4473367#p4473367"]С помощью этого МК коллеги измеряют (частотомером например) до Fclk/2.[/uquote]
Абсолютно с вами согласен. Но там-то устройство заточено на только измерение частоты и вывод показаний. Но когда вам нужно помимо всего этого метаться каждый раз к ЭБУ и отвечать на каждый посланный им бит подтверждением, и не терять связь, то тут как бы уже проблема есть.

Добавлено after 2 minutes 21 second:
Там нельзя покурить, почесать яйки, а потом такой: " Ну-ка дружок, что там у нас с температурой?" Нет, там нон-стоп все идет.
Друг Кота
Аватара пользователя
Сообщения: 5806
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж

Сообщение >TEHb< »

Причём сам ЭБУ мотора можно сделать на меге16. Есть такие проекты. ДВС крутить задачка посерьёзнее будет, чем температурку узнать и 122 герца посчитать, не так ли? Всё влезет в мегу8 и по процессорному времени и по объёму кода. Главное не сдаваться.
Усложнять просто. Упрощать сложно.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

a_b_r_a, тебе уже посоветовали забыть о float, чтобы он не расходовал процессорное время, и работать с целыми числами.
стандартное правило - в прерываниях делать необходимый минимум, а основную работу делать в основном цикле. и уж тем более, в прерывании не делать вычисления с использованием "флота".
пусть по прерыванию только инкрементируется счетчик импульсов, а потом 1 раз в секунду в основном цикле один раз вычислить скорость.
по датчику температуры (DS18B20) - не нужно запрещать прерывания на весь цикл обмена с датчиком.
нужно в начале каждого слота времени запретить.
при чтении - через примерно 14 мкс прочитать пин датчика и разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
при записи - после выдачи бита на пин можно сразу же разрешить прерывания. а на сколько растянется слот за счет работы любого прерывания - по фигу.
а по таймеру T0 1 мс - зачем тебе так часто? и что конкретно (как много) делается в прерывании по таймеру T0?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Сообщение a_b_r_a »

Код: Выделить всё

#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;
	
}
Добавлено after 1 minute 49 seconds:
Блин, не знаю, как спойлер сделать. 1 мсек это типа функции millis arduino. Чтобы заменить delay
Ответить

Вернуться в «AVR»