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

Обсуждаем контроллеры компании Atmel.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

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

Сообщение Martian »

ну дык, сенсор самое главное и интересное и сложное и есть :)
Реклама
Аватара пользователя
valentinovich
Электрический кот
Сообщения: 1004
Зарегистрирован: Ср окт 04, 2017 20:47:40

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

Сообщение valentinovich »

Martian писал(а):... сенсор самое главное и интересное и сложное и есть :)
Имхо главное это то, какая преследуется цель и что для решения задачи есть на данный момент в тумбочке. :)
Пардон - похоже уже флудим в теме. Если есть вопросы, плиз в личку.
Реклама
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5749
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

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

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

Ненене, тоже очень интересно. С пробегом ещё более-менее понятно, а как топливо измеряли?
"Привет!" - соврал он.
Аватара пользователя
valentinovich
Электрический кот
Сообщения: 1004
Зарегистрирован: Ср окт 04, 2017 20:47:40

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

Сообщение valentinovich »

>TEHb<, см. личку.
Реклама
Эиком - электронные компоненты и радиодетали
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Может быть я туплю, конечно, но дела таковы: переключил я таймер 1 в режим захвата. Написал такой код
Спойлер

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

void tim1_ini(void)
{
        // Частота кварца 20000000Гц
	TCCR1A=0x00; // Normal mode
	TCCR1B &= ~((1<<WGM12)|(1<<WGM13)|(1<<CS11)); // Делитель 1024. Частота тактирования после делителя 19530 Гц.
	TCCR1B |= ((1<<CS12)|(1<CS10)); // Захват по спаду
	TCNT1=0;
	TIMSK1 |=(1<<ICIE1); // Разрешение прерывания по захвату
}

volatile uint16_t cnt=0;
uint16_t frec=0;

ISR(TIMER1_CAPT_vect)
{
	TCNT1=0;
	cnt=ICR1;
	
}

int main(void)
{
tim1_ini();
sei();

While(1)
  {
      frec=19530/cnt; // Здесь понятно, что на ноль делить нельзя, просто для понимания.
	sprintf(val_1,"%.0d",frec);
  }
}
Подал с генератора 113 Гц. Получил на экране число 682. И это не дребезг. Период меандра 113 Гц = 8.8 мС. Период частоты тактирования таймера 19530Гц=51.2 мкС. Исходя из этого за 1 период частоты 113 Гц должно посчитаться примерно 170 тиков. Но не 682. По ходу с математикой может я протупливаю?
Реклама
mont-oriol
Мучитель микросхем
Сообщения: 437
Зарегистрирован: Пн май 27, 2019 07:18:28
Откуда: ВВХ-ск

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

Сообщение mont-oriol »

Изображение
Реклама
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

mont-oriol, спасибо тебе огроменное! Моя невнимательность привела меня к такому гемморру...
mont-oriol
Мучитель микросхем
Сообщения: 437
Зарегистрирован: Пн май 27, 2019 07:18:28
Откуда: ВВХ-ск

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

Сообщение mont-oriol »

[uquote="a_b_r_a",url="/forum/viewtopic.php?p=4472413#p4472413"]Датчик представляет из себя обычный геркон, который замыкает подтянутый к 5 вольтам вход приборки на землю.
...
Поставил на вход кондер 0.1 мкф и на землю.[/uquote]
Конденсатор в параллель геркону может сократить ресурс контактов геркона. Я бы примерно так сделал:
Изображение

Добавлено after 19 minutes 50 seconds:
У SMAJ5.0A ток утечки великоват, нужно что-то другое, выбор есть.
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Попробую для начала без кондера включить noice canceler, хотя наверно не поможет. Там провода от датчика проходят рядом с трамблером. Он то скорее всего и наводит шороху. Если не поможет, тогда по железу буду дальше кумекать. Но там вроде идет сигнал на UAF 2115. Думаю, нет там таких токов огромных. Я просто не знал, что кондер в параллель геркону приводит к снижению ресурса.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19055
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

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

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

Сообщение a_b_r_a »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4475077#p4475077"]конденсатор большим током разряжается через него.[/uquote]
Да, спасибо. Я понял. Кондер заряжается в любом случае через резистор подтяжки. При замыкании геркона кондер через него разряжается на массу.

Добавлено after 1 minute 31 second:
Завтра поинтересуюсь еще парой вопросов)
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

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

Сообщение Martian »

Один из них будет про правильное название конденсатора?
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

В догонку... За счет некоторой протяженности проводов и с учетом их какой-то индуктивности возможно ли нивелирование этих эффектов? Понятно, что провода также привносят свою емкостную составляющую.

Добавлено after 2 minutes 9 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4475095#p4475095"]Один из них будет про правильное название конденсатора?[/uquote]

Я знаю его истинное имя-капацитор. Ваш сарказм не уместен
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

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

Сообщение Martian »

Это Ваше уродование слов не уместно. Наверняка, когда к доктору или полицейскому приходите, внезапно грамотность просыпается, но тут-то кто? Тут гопники и быдло, недостойное уважения.
И я спрашивал без сарказма.
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Ну и вообще любителям (болтателям) за " жили-были" и за " кашу манную-жизнь туманную" просьба не флудить, если нечем ответить по конкретике. Все очень знатоки поговорить, подкольнуть, упрекнуть. Как только есть конкретика, так сразу " ну в чужих исходниках грех копать, кот заболел и т.д.". Так пройдите мимо, зачем встревать, если вы бесполезны?

Добавлено after 5 minutes 15 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4475104#p4475104"]Тут гопники и быдло, недостойное уважения.[/uquote]
У Вас низкая самооценка. К тому же под свою самооценку вы подвели всех участников форума, обобщив их. Не нужно так делать. Вы не можете решать за всех. Обратитесь к психологу, он вам поможет. Наверно...
mont-oriol
Мучитель микросхем
Сообщения: 437
Зарегистрирован: Пн май 27, 2019 07:18:28
Откуда: ВВХ-ск

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

Сообщение mont-oriol »

[uquote="a_b_r_a",url="/forum/viewtopic.php?p=4475098#p4475098"]За счет некоторой протяженности проводов и с учетом их какой-то индуктивности возможно ли нивелирование этих эффектов?[/uquote]
Конечно. Но всего один резистор хотя бы сотню ом последовательно с конденсатором это всё гарантированно убирает. Стоит ли тут экономить?
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Да нет, конечно. Не стоит. Просто плата сделана, распаяна. Буду переделывать. Но есть некоторые вопросы. Озвучу позже. Возможнр завтра. Времени не хватает...
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Всем доброго здравия!
Разобрался я с выводом пробега. Все сделал через целочисленные значения. Не то, что хотелось, но float рассчитывается очень неважно. У меня возник еще один вопрос по поводу алгоритма обработки нажатия кнопки. Суть такова, что есть "теневое" меню, где можно корректировать данные в зависимости от пробега авто, производительности форсунки, от емкости топливного бака, от количества импульсов датчика скорости на 1000 метров (комплектации разные) и запоминать их в EEPROM для последующих расчетов. Я набросал некоторые функции по коррекции этих данных, но вопрос уперся в обработку нажатия кнопки. Хочу отметить то, что кнопка всего ОДНА. И нужно как-то выкрутиться. Функцию обработки нажатия кнопки я честно признаюсь украл. Проблема сейчас в том, что при двойном нажатии ловится сначала одиночное нажатие, потом двойное. Код нажатия одиночного 03, двойного 05. Код под спойлером.
Спойлер

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


ISR(TIMER0_OVF_vect)  // Прерывание по Таймеру 0
{
	//TCNT0=131;  // 8MHz
	TCNT0=178;  // 20 MHz
	millis++; // Инкрементируем каждую миллисекунду
}

/*
 * button.c
 *
 * Created: 17.04.2023 18:58:14
 *  Author: ADMIN
 */ 
#include "button.h"

uint8_t button1S;   // храним состояния кнопок (S - State)
uint8_t button1F;   // флажки кнопок (F - Flag)
uint8_t button1R;   // флажки кнопок на отпускание (R - Release)
uint8_t button1P;   // флажки кнопок на нажатие (P - Press)
uint8_t button1H;   // флажки кнопок на удержание (многократный вызов) (H - Hold)
uint8_t button1HO;  // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once)
uint8_t button1D;   // флажки кнопок на двойное нажатие (D - Double)
uint8_t button1DP;  // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)

#define DOUBLE_TIMER 500   // время (мс), отведённое на второе нажатие
#define HOLD 2000           // время (мс), после которого кнопка считается зажатой
#define DEBOUNCE 50        // (мс), антидребезг
uint32_t button1_timer; // таймер последнего нажатия кнопки
uint32_t button1_double; // таймер двойного нажатия кнопки

uint8_t buttons(void)
{
	uint8_t bt1=0; // Будем возвращать результат в этой переменной
	
	if (BitIsClear(BUT1_PIN,BUT1)) button1S=1;
	else button1S=0; // Состояние кнопки
	
	// нажали (с антидребезгом)
	if (button1S && !button1F && millis - button1_timer > DEBOUNCE) 
	{
		button1F = 1; // Установим флаг кнопки
		button1HO = 1; // флаг на удержание
		button1_timer = millis; // таймер последнего нажатия кнопки
		bt1=1;
	}
	// если отпустили до hold, считать отпущенной
	if (!button1S && button1F && !button1R && !button1DP && millis - button1_timer < HOLD) 
	{
		button1R = 1; // флаг на отпускание
		button1F = 0; //флаг кнопки
		bt1=2;
		button1_double = millis; // Таймер двойного нажатия кнопки
	}
	
	// если отпустили и прошло больше double_timer, считать 1 нажатием
	if (button1R && !button1DP && millis - button1_double > DOUBLE_TIMER) 
	{
		button1R = 0;
		button1P = 1;
		bt1=3;
	}
	
	// если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 разa
	if (button1F && !button1DP && button1R && millis - button1_double < DOUBLE_TIMER) 
	{
		button1F = 0;
		button1R = 0;
		button1DP = 1;
		bt1=4;
	}
	
	// если была нажата 2 разa и отпущена, считать что была нажата 2 раза
	if (button1DP && millis - button1_timer < HOLD) 
	{
		button1DP = 0;
		button1D = 1;
		button1_timer = millis;
		bt1=5;
	}
	
	// Если удерживается более hold, то считать удержанием
	if (button1F && !button1D && !button1H && millis - button1_timer > HOLD) 
	{
		button1H = 1;
		bt1=6;
	}
	
	// Если отпущена после hold, то считать, что была удержана
	if (!button1S && button1F && millis - button1_timer > HOLD) 
	{
		button1F = 0;
		button1H = 0;
		button1_timer = millis;
		bt1=7;
	}
	
	// отработка режимов (опускание флага обязательно!)
  if (button1P) button1P = 0;   
  if (button1D) button1D = 0;    
  if (button1H && button1HO) button1HO = 0;
  if (button1H) button1H = 0;
  
  return bt1;  
}


/*
 * Dark_menu.c
 *
 * Created: 18.08.2023 18:05:08
 *  Author: ADMIN
 */ 
#include "dark_menu.h"

uint8_t main_dark_mode=0; // Переменная для хранения режима теневого меню.
uint8_t sub_mode=0; // флаг входа в подменю
uint8_t edit_mode=0; // пока не используется
uint8_t b=0; // счетчик нажатия кнопки
uint8_t pr_var=0; // Переменная, которая в подменю будет инкрементироваться по нажатию кнопки от 0 до 9
uint8_t pr[6]={0,1,2,3,4,5}; // Массив для разбивки пробега(или еще чего-то) поразрядно для возможности коррекции(тест)

void main_text(void) // Основной текст меню
 // Построчный вывод пунктов меню
{
	print_string_5x8(11,0,"MILEAGE(km)");  // Вывод типа " -> MILLEAGE(km)"
	print_string_5x8(11,1,"SPEED SENSOR(imp)");
	print_string_5x8(11,2,"INJECTOR (cc/min)");
	print_string_5x8(11,3,"FUEL TANK MIN NOW");
	print_string_5x8(11,4,"FUEL TANK MAX NOW");
}

void pointer_clear(void)  // очистка стрелочки
{
	for(uint8_t i=0; i<5; i++) 
	{
		print_string_5x8(0,i,"  ");
	}
	
}

void main_dark_menu(void)
{
       screen_clear();
	if (cod==3) // Если нажали и отпустили кнопку
	{
		main_dark_mode++; // Бегаем по основному меню
		if(main_dark_mode>4) main_dark_mode=0; // Бегаем по кругу
	}
	switch (main_dark_mode)
	{
	    case 0:             // коррекция пробега
		        pointer_clear();                         // Очистка стрелочки
		       	print_string_5x8(0,main_dark_mode,"->"); // Cтрелка на нулевой строке, т.к. mode_1 сейчас равен нулю.
				main_text();                             // Выводим все пункты основного меню
				
				if (cod==5)                              // Если двойное нажатие, заходим в подменю
				{
					cod=0;                               // Сразу обнулим код нажатия кнопки
					screen_clear();                      // Очистим экран
					sub_mode=1;                          // Зайдем в режим подменю
					
					
					while(sub_mode)
					{  
						cod=buttons();
 						print_string_5x8(16,2,"SET MILEAGE(km)"); // Тут печать пояснительного текста
 						print_string_5x8(16,3,"x100000----x1");
 						print_string_5x8(16,4,"ALL 6 DIGIT");
						screen_update();
						correction(6,16,pr); // Заходим в функцию коррекции величин
						
						if (cod==6) // Нужно как-то выйти из цикла..
						{
							sub_mode=0;
						}
						
						 
 					}
				}
				break;   
				
		case 1:                    // Speed sensor
		        pointer_clear();
		        print_string_5x8(0,main_dark_mode,"->");
				main_text();
				if (cod==5)
				{
					cod=0;                               // Сразу обнулим код нажатия кнопки
					screen_clear();                      // Очистим экран
					sub_mode=1;
					
					while(sub_mode)
					{
						cod=buttons();
						print_string_5x8(16,2,"SET SPEED SENSOR");
						print_string_5x8(16,3,"IMP/1000m");
						print_string_5x8(16,4,"ALL 4 DIGIT");
						screen_update();
						if (cod==6)
						{
							sub_mode=0;
						}
						
					}
				}
				break;
				
		case 2:           // Injector
		        pointer_clear();
		        print_string_5x8(0,main_dark_mode,"->");
		        main_text();
				if (cod==5)
				{
					cod=0;                               // Сразу обнулим код нажатия кнопки
					screen_clear();                      // Очистим экран
					sub_mode=1;
					
					while(sub_mode)
					{
						cod=buttons();
						print_string_5x8(16,2,"SET INJECTOR");
						print_string_5x8(16,3,"PRODUCTIVITY");
						//print_string_5x8(16,4,"");
						screen_update();
						if (cod==6)
						{
							sub_mode=0;
						}
					}
				}
		        break;
				
		case 3:        // Fuel min
		        pointer_clear();
		        print_string_5x8(0,main_dark_mode,"->");
		        main_text();
				
				if (cod==5)
				{
					cod=0;                               // Сразу обнулим код нажатия кнопки
					screen_clear();                      // Очистим экран
					sub_mode=1;
					
					while(sub_mode)
					{
						cod=buttons();
						print_string_5x8(16,2,"PRESS BUTTON ");
						print_string_5x8(16,3,"FOR MEMORY");
						print_string_5x8(16,4,"ENTRIES MIN");
						screen_update();
						if (cod==6)
						{
							sub_mode=0;
						}
					}
				}
				
		        break;
				
		case 4:       // Fuel max
		        pointer_clear();
		        print_string_5x8(0,main_dark_mode,"->");
		        main_text();
				if (cod==5)
				{
					cod=0;                               // Сразу обнулим код нажатия кнопки
					screen_clear();                      // Очистим экран
					sub_mode=1;
					
					while(sub_mode)
					{
						cod=buttons();
						print_string_5x8(16,2,"PRESS BUTTON ");
						print_string_5x8(16,3,"FOR MEMORY");
						print_string_5x8(16,4,"ENTRIES MAX");
						screen_update();
						if (cod==6)
						{
							sub_mode=0;
						}
					}
				}
		        break;				
		        
		                
	}
}


void correction(uint8_t size,uint16_t eep_number, uint8_t *par)
{    
	
	uint8_t a=51; // Параметр начала строки. Магическое число. С этой позиции курсора начинаем вывод
	
			for (uint8_t i; i<size; i++)
			{
				
				print_MediumNumbers(a,6,par[i]%10 + '0'); // Выводим все разряды корректируемой величины
				a+=12;
				
			}
			
			if (cod==5) // при двойном нажатии прыгаем на следующую циферку, которую нам необходимо изменить и подсвечиваем
			           // ее инверсией
			{
				b++; // при каждом двойном нажатии кнопки инкрементируем переменную
				cod=0; //Обнуляем код нажатия для следующего скана
				if(b==size) b=0; // В зависимости от переданного в функцию количества разрядов корректируемой величины 
				                 // инкрементируем разряды
								 
				pr_var=par[b]; // Читаем в переменную содержание элемента массива
			} 
			
			print_invert_MediumNumbers(51+(b*12),6,par[b]%10 + '0'); // Инвертируем картинку редактируемого разряда
			
			if(cod==3) // Если редактируем
			{
				pr_var++; // Если нажали кнопку, увеличиваем значение переменной на +1
				if(pr_var>9) pr_var=0;
				
				cod=0; // Обнуляем код нажатия кнопки
				par[b]=pr_var; // Записываем это значение в выбранный элемент массива
			}
	}

mont-oriol
Мучитель микросхем
Сообщения: 437
Зарегистрирован: Пн май 27, 2019 07:18:28
Откуда: ВВХ-ск

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

Сообщение mont-oriol »

Попробовал я buttons() в симуляторе
IMHO она нормально не будет работать с двойным кликом. Только если аппаратный антидребезг сделать.
Кроме того, "флажки" не инициализируются, поэтому первый клик часто глючный.

Вот эта библиотека
https://github.com/TanPitch/ButtonKing
В симуляторе работает значительно лучше. Хотя на физической кнопке (типа Jog Dial) могут быть нюансы.

И ещё.
button1_timer = millis;
Эта операция не атомарная. Если прерывание с инкрементом millis сработает внутри, то может оказаться, что часть байтов этой переменной будет от старого состояния millis, часть - от нового. Это касается всех операций с millis.
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

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

Сообщение a_b_r_a »

Спасибо за библиотеку. Правда я не силен в с++, но попробую портировать.
Ответить

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