Перейти к содержанию

Круиз-контроль для Mitsubishi Grandis Atmega8535


Гость еще один max

Рекомендуемые сообщения

12.55 11 июня 2010 года. Осуществлен первый опытный проезд под управлением "электронной педали". Все системы сработали как запланировано!!!

:smile:

Припаял 2 кнопы к свободным ногам процессора. По нажатию одной в переменной перестают обновляться данные с педали, т.е. выводится последнее считанное значение. По нажатию другой впадаем в режим дубликации. Кнопы подтянуты к плюсу через 10кОм, активный сигнал - замыкание на массу. Получилась "виртуальная нога", костыль, упертый в педаль в определенном положении.

Ну что сказать - не вариант однозначно. Еду по прямой, 60 км/ч, фиксирую. В горку падает до 40, с горки разгоняется до 80. Нужна обратная связь по скорости. И пока нет концевика на тормозе эксперименты проводить рискованно: держать руль, жать тормоз и одновременно выключать "костыль" свободной рукой... Никакой безопасности!

Но кайф есть - уже могу иногда акселератор отпустить, то, что я и хотел!!!

Писец как приятно...

Вернемся на землю: MAX5293 нет в том интернет-магазине, что мне привозил мс.

_https://store.antrek.ru/

Посмотрю на том сайте, что ты дал.

Мысль прокралась - а зачем? если 8-битный работает отлично. Я просто на разрядность грешил пока проблему с выводом данных педали не решил, как-то холостые неустойчиво работали. А теперь прям как влитые стоят (тьфу-тьфу), ни ООС на другом АЦП не надо, ни читать вторую педаль...

Ну посмотрим :smile:

Женя, спасибо!

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 218
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Привет всем!

За прошедшие дни спаял эмульку джойстика-рычажка, не дождался пока привезут. Подобрал в загашниках миниклаву на 4 кнопки (как раз!), купил резюки... Конечно 1% ряда не было, купил что было. Какое же было удивление, когда один из резисторов показал именно 787 Ом, то, что надо для пульта! Вместо 200 Ом получилось 194, вместо 100 - 96. Очень близко, думаю что все сработает без перенастройки когда подключу настоящий рычажок. а пока вот такой девайс:

post-1142-1276776940_thumb.jpg

Применил двухцветный светодиод, офигительно: зеленый при активированном круизе, красный при включенном режиме поддержки скорости, не горит - круиз деактивирован.

 

Несколько дней ваял в свободные времена программу. Первая рабочая версия, нет подпрограмм увеличения и уменьшения отслеживаемой скорости с джойстика. Не вписал еще... Но тем не менее, встречайте - версия 0.1:

Здесь был спойлер.
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Mitsubishi Grandis Cruise Control Unit
Version : 0.1
Date	: 12.06.2010
Author  : Maxim Cherepanov
Company : 
Comments: 


Chip type		   : ATmega8535
Program type		: Application
Clock frequency	 : 8,000000 MHz
Memory model		: Small
External RAM size   : 0
Data Stack size	 : 128
*****************************************************/

#include <mega8535.h>

#include <delay.h>

#define zaderjka 150
#define delta_pedal 14
#define limit_low 40
#define limit_top 160
#define delta 1
#define timer 40

#define ADC_VREF_TYPE 0x20

// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}
// Declare your global variables here

unsigned char pedal_cur;
unsigned char pedal_ecu;
unsigned char speed_cur;
eeprom unsigned char speed_ecu;
unsigned char joystick;
unsigned char joystick_cur;
eeprom unsigned char rejim;
bit flag;

//eeprom unsigned char speed_control;
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x30;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=1 State6=0 State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x80;
DDRD=0xC0;

// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x06;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
// Only the 8 most significant bits of
// the AD conversion result are used
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;
SFIOR&=0xEF;

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/512k
#pragma optsize-
WDTCR=0x1D;
WDTCR=0x0D;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

while (1)
  {
  // Place your code here
  
  /*-----------------------------------*/
  //Joystick
  joystick_cur=read_adc(3);
  delay_ms(1);
	if (joystick_cur<=26) joystick=1;//MAIN
	else { if (joystick_cur<=82) joystick=2;//CANCEL
		else { if (joystick_cur<=145) joystick=3;//SET
			else { if (joystick_cur<=220) joystick=4;//RESET
				else { if (joystick_cur>220) joystick=0; //No operation
				}
			}		
		}
	}
	
  /*-----------------------------*/
  //Speed
  TCNT0=0x00;
  delay_ms(timer);
  speed_cur=TCNT0;//speed v km-ch
  
  /*------------------------------*/
  switch (joystick)//Ustanovka rejima
  {
  
  //No operation
  case 0: 
  flag=0;
  break;
  
  // MAIN Aktivaciya-deaktivaciya cruise
  case 1: 
	if (flag==0){
			if (rejim>=1) 
			rejim=0;
			else rejim=1;
		   }
	flag=1;
  break;
  
  //CANCEL  Otmena podderjki skorosti
  case 2: 
  if (rejim>0) rejim=1;// Sbros
  break;
  
  //SET  Vkluchenie podderjki skorosti
  case 3:
	if (rejim>0) {
		//Proverka limit
		if (speed_cur>=limit_low) {
		   if (speed_cur<=limit_top) {
			rejim=2;
			pedal_ecu=pedal_cur;
			speed_ecu=speed_cur;//Zadanie skorosti!!!
		   }
	   }
	}
  break;
  
  //RESET Vklucheni ranee ustanovlennoi skorosti
  case 4:
	if (rejim>0) {
		//Proverka limit
		if (speed_cur>=limit_low) {
		   if (speed_cur<=limit_top) {
			rejim=2;
			pedal_ecu=pedal_cur;//Vosstanovlenie podderjki
			}
		}
	}
  break;
  }
  
  /*--------------------------------*/
  //Proverka skorosti
   if (speed_cur<limit_low) {
	if (speed_cur>limit_top) {
		if (rejim>=1) rejim=1;
		}
		}
		
  /*-------------------------------*/
  //Tormoz
	if (PINA.0==0) {
	if (rejim>=1) rejim=1;  
	}
	
  //Indikaciya
  if (rejim==0) {PORTA.5=0; PORTA.4=0;} //Ne gorit
  if (rejim==1) {PORTA.5=1; PORTA.4=0;} //Green
  if (rejim==2) {PORTA.5=0; PORTA.4=1;} //Red
		
  //Pedal
  pedal_cur=read_adc(1);
  
  /*-----------------------------------------*/
  //Rejim rabota
  switch (rejim)
  {
	//Dublikacia
	case 0:
	case 1:
	PORTC=pedal_cur;
	PORTD.6=0;//Out A
	PORTD.7=0;
	PORTD.7=1;
	PORTC=pedal_cur-delta_pedal;
	PORTD.6=1;//Out B
	PORTD.7=0;
	PORTD.7=1;   
	break;
	
	//Podderjka skorosti, obgon i vosstanovlenie
	case 2: {
	if (speed_cur<speed_ecu) pedal_ecu=pedal_ecu+delta;
	if (speed_cur>speed_ecu) pedal_ecu=pedal_ecu-delta;
	if (pedal_ecu<55) pedal_ecu=55; // ne nije holostogo hoda
	if (pedal_ecu>210) pedal_ecu=210; // ne vishe 80% hoda
	
		//obgon
		if (pedal_cur>=pedal_ecu)
		{ 
		PORTC=pedal_cur;
		PORTD.6=0;//Out A
		PORTD.7=0;
		PORTD.7=1;
		PORTC=pedal_cur-delta_pedal;
		PORTD.6=1;//Out B
		PORTD.7=0;
		PORTD.7=1;
		}
	
		//podderjkam i vosstanovlenie
		else 
		{ 
		PORTC=pedal_ecu;
		PORTD.6=0;//Out A
		PORTD.7=0;
		PORTD.7=1;
		PORTC=pedal_ecu-delta_pedal;
		PORTD.6=1;//Out B
		PORTD.7=0;
		PORTD.7=1;
		delay_ms(zaderjka);
		}
	}  
  }
  #asm ("wdr")
  };
}

Привожу весь листинг без купюр. Комментарии в транслитерации, ибо Винда и Линукс по умолчанию применяют разные кодировки для кириллицы, чтобы не пялиться потом на кракозябры.

Женя, будь добр - посмотри, прокомментируй. Видишь, я логику применил "в лоб". Надеюсь многие строки можно заменить комбинацией булевых операторов. Что-то вынести в подпрограммы, что-то в функции. Очень на тебя надеюсь.

Программа вполне работоспособна, при старте поддержки скорости на ровной поверхности при скорости от 60 до 100 км час и если в это время не разгон и не торможение держит скорость как привязанную. На подъемах и спусках (если небольшие) через 2-3 приближения скорость стабилизирует. При разгоне и торможении и на крутых горках ведет себя похуже.

Мешает отсутствие концевика тормоза, приходится все время левую руку держать на пульте на кнопочке отключения круиза.

Контроллер ведет себя молодцом!

Ну вот как-то так, такое развитие событий...

Ссылка на комментарий
Поделиться на другие сайты

Привет макс...если я не прав думаю меня поправят...ибо СИ я только только осваиваю.....большей частью я ближе к асму(и то знаю хорошо асм 51 процессоров)...

...значит подпрограмма на асме ..это скорей тоже самое что функция в сях...и где часто призводится адни и те же действия делают в асме попрограмму а на сях функцию.....засовывают туда данные и вызывают либо попрограмму либа на сях функцию.....

..в твоём варианте лучше использовать функции...(не.. канечно можно и попрограммы но тогда придется делать ассемблерные вставки в твоей программе...а нужно?...если я не прав пусть меня исправят....)...

.....вот сморю у тебя часто повторяющийся код это передача данных в цап....этот кусок просто просится сделать как функцию...с названием типа write_dac.....и код сразу станет читабельный ..потому что будет ясно что мы этим куском кода делаем....

насчет булевой ...логики .. или математики как бы точнее ...я сней не владах (толком ненаучили....хотя скорей наобарот ненаучился сам..)....но думаю у тя и так код вполне оптимизирован.и прямолинеен..и что самое главное панятен тебе...а ресурсов мк современных хватает с лихвой..чтоб современных писателей эмбедеров избавить от многих проблем...

....другое дело не совсем оптимальна сама реализация программы регулятора.(ведет себя по разному на разных горках ну и спусках )...тут нада подумать...и послушать больше советов....

...мае видение насчёт управления и поддержания скорости в изменяемых условиях(горка..крутая горка..спуск крутой спуск..).....машина тоесть как ты сказал тяжелая...тоесть инерционная...если она уменьшает скорость..то регулятор начинает увеличивать задание на педальку газа...увеличивая мошность на выходе с трансмиссии.....как бы начинает подерживать скорость машины...а если горка попалась крутая..то скорость ..все равно будет падать...потому что необходимо увеличить мощность на выходе из трансмисси за единицу времени сразу больше.....именно сразу....и поэтому просится сюда в регулятор воткнуть диф часть...чтоб поддал за единицу времени мощности(дал газу)...дальше пропоциональная часть дорегулирует....

..насчёт катится с горки...тут одни вопросы....потомучто поддержать скорость на заданном уровне здесь одним двигателем сложно.....если у машины вес большой .....хоть до конца закрывай заслонку газа....она разгонится......главное после такова крутого спуска что бы регулятор вышел адекватно на регулируемую скорость......будь то прямая ...или ..начнётся крутой подъем.....

 

 

 

Добавлено после раздумий:

....слушай...я тута подумал насчет концевика тормоза ..а нельзя тама никак использовать штатный а?!

Ссылка на комментарий
Поделиться на другие сайты

Я так и думал сделать, вывод данных на ЦАП вынести в функцию. Пока все "в затылок", чтобы отработать логику и легче было найти ошибки.

Программа переписывается 2-3 раза в день, в перерыв выпрыгиваю на машину, втыкаю контроллер и старюсь успеть откататься 2 раза, с разными параметрами. Та версия уже сильно изменена, но идея пока та же.

Может и я со временем на ассемблер перейду. Хотя вряд ли...

Можно и присутствующий концевик использовать, только он нормально разомкнутый. И 12 вольт там, а не 5. Дождусь уж нормального.

Ссылка на комментарий
Поделиться на другие сайты

....макс какие проблемы то с 12 вольтами...через транзистор...и на вход...а то что он нормально разомкнутый....разве это проблема для программы?!

 

Добавлено после раздумий:

для асма есть прецентент именно в этом качестве ?!!...для всеобщего понимания чего тамо и как делается его желательно знать....

Ссылка на комментарий
Поделиться на другие сайты

Да проблем никаких, даже транзистор не нужен - делитель резисторный и стабилитрон. Но не в этом дело, заказал уже концевик с 2 парами контактов вместе с рычажком. Полезу туда один раз, все поменяю сразу, хочу все-таки полную развязку от 12 вольт.

Я надеялся, что в Си для AVR есть конструкция "gosub... return" или что-то подобное. Функция это функция, это немного другое, она возвращает значение в зависимости от аргумента. Меня немного удивила функция чтения из встроенного АЦП. Мне придется делать такую же. А в асме, насколько я знаю, есть именно подпрограммы.

Вообще Си я доволен, все очень понятно для непрофессионала, скорость вполне. Подозреваю, что какой-нибудь Алгоритм Билдер или Бейсик тоже бы справился, но скорость Си должна быть на порядок лучше.

Ссылка на комментарий
Поделиться на другие сайты

Да проблем никаких, даже транзистор не нужен - делитель резисторный и стабилитрон. Но не в этом дело, заказал уже концевик с 2 парами контактов вместе с рычажком. Полезу туда один раз, все поменяю сразу, хочу все-таки полную развязку от 12 вольт.

Я надеялся, что в Си для AVR есть конструкция "gosub... return" или что-то подобное. Функция это функция, это немного другое, она возвращает значение в зависимости от аргумента. Меня немного удивила функция чтения из встроенного АЦП. Мне придется делать такую же. А в асме, насколько я знаю, есть именно подпрограммы.

Вообще Си я доволен, все очень понятно для непрофессионала, скорость вполне. Подозреваю, что какой-нибудь Алгоритм Билдер или Бейсик тоже бы справился, но скорость Си должна быть на порядок лучше.

....Макс с концевиком всё ясно...

..насчет си ..... в сях есть два типа функций та каторая возвращает какое либо значение и та каторая не возвращяет ничего а чтото делает и всё(в твоем примере именно такая функция и нужна будет, она тупо будет передавать в цап значение и всё) в других языках это типа называется процедура... так вот вызов функции это падобие твоего оператора gosub или на асме типа команды CALL а название этой функции это метка куда прейти...а внутри функции каторая должна чтот то вернуть ...нужно будет написать ретурн... и заканчивается это все фигурной скобкой это типа команды(ретурн или на асме команда RET) вернутся назад из подпрограммы в место откуда была вызвана попрога....вот функция чтения из ацп на сях это пример использования подпрограммы.....но понятней про функции пишет книга лебедева кодевизион для авр....посмотри тамо как тие её лучше написать...

Ссылка на комментарий
Поделиться на другие сайты

Люди, нужна помощь!

В настоящее время в программе управления считывание текущей скорости осуществляется следующим образом:

Инициализируется таймер_0 в следующей конфигурации:

// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x06;
TCNT0=0x00;
OCR0=0x00;

т.е. просто считает внешние импульсы.

В режиме активности круиза включается кусочек программы:

//Speed
TCNT0=0x00;
delay_ms(timer);
speed_cur=TCNT0;

timer=40, за 40 миллисекунд в счетчик набегает количество внешних импульсов, равное количеству скорости в км/ч. Вообще очень странно, по расчету у меня выходило timer=5, ну ладно, значит хреновый я математик.

Вроде все путем, но нельзя ли сделать так: запустить второй счетчик (допустим timer_2), чтобы он считал до 40 мс, и по достижении верхнего предела происходило прерывание. В обработке прерывания пусть во временную переменную сохраняется значение скорости, обнуляются таймеры 0 и 2 и происходит возврат из прерывания. Таким образом во временной переменной (speed_temp) будет постоянно находиться текущая скорость.

Попробовал. Фигу, не вышло! Не включается, у меня стоит ограничение по допустимой скорости (работаем только от 40 до 130), видимо в таймер_0 не попадает нужное количество импульсов. Сделал так: задал в eeprom переменную, обнуляю таймер_2, делаю delay_ms(40), считываю показания таймера в переменную, записываю в eeprom значение переменной по нажатой кнопке. Получается все время 38h, т.е. 56. О, думаю, вот и верхний предел для таймера_2. Хрен, не работает, сцуко!

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x07;
TCNT2=0x00;
OCR2=0x00;
...
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;

В прерывании таймера_2 пишу

speed_temp=TCNT0;
TCNT0=0x00;
TCNT2=0x00;

Потом из временной скорости передаю в постоянную, делаю сравнения и пр. Вот не работает и все, такая засада. Как только перевожу на считывание по задержке, все работает.

Где может быть косяк?

Подумал, может я неправильно задал фьюзы? И тактируется мк не от кварца, а от встроенного генератора на фиг знает какой частоте. и показатель этого то, что по расчетам пауза 5 мс, а фактически требует 40. Т.е. в 8 раз быстрее процессор работает? Вообще чушь (в Протеусе все было как по нотам!), но чем черт не шутит... Проверил по букингам, добавил еще один фьюз (уровень тактирующего сигнала, от него энергопотребление зависит, но мне оно как-то пофиг, поставил максимум). Да вроде все правильно, 8 МГц! Тем более, что я верхний предел для прерывания счетчика задал, подбирая фактическое значение из регистра счетчика...

И о переполнении подумал. Задействовал timer_1, там предел аж FFFF, старший бит все время по такой схеме 0, младший те же загадочные 38h :smile:

Ткните плиз для слезания с граблей!

Ссылка на комментарий
Поделиться на другие сайты

макс привет чесно говоря не совсем разобрался с твоим расчетом скорости.....ещё когда просматирвал прогу твою первый раз......если в проте все работает как надо...значит траблы у реального устройства ...возможно..что на вход счётный таймера приходит не то....форма сигнала не идеальная или помехи типа, в симуляции в проте это всё идеализировано...

..второе поскольку это аврка.....возможные баги с конфигурационными битами(FUSE)....ну тута паможет даташит с очень внимательным его изучением...

..так что если начать копать то необходимо начинать с того что у тя прилетает на вход мк...желательно оффцелографом посмотреть форму сигнала его амплитуду и все такое....

Ссылка на комментарий
Поделиться на другие сайты

На вход там прилетает все нормально.

Если я томожу мк на 40 мс, а счетчик в это время считает импульсы, то все нормально получается. Смотри, допустим скорость 40 км/ч, частота для такой скорости 1000 Гц. Сколько мы насчитаем за 40 мс?

1000*0,04=40 импульсов. Столько и будет в регистре таймера_0.

Но получается, что мк реагирует на воздействие на педаль как минимум на 40мс+задержка при выравнивании скорости (при слежении)+время выполнения операций. Хочу убрать хотя бы эти 40 мс, и делать не задержку самого мк, а заставить таймер_2 прерывать программу каждые 40 мс и обновлять скорость. Вот настройки таймера_2 и не получаются, я их привел выше. Не прерывается программа для подсчета. Что я не так делаю?

Ради истины стоит заметить, что запоздания в реакции субъективно не ощущается. При неактивном круизе я это место программы исключаю, при дубликации остается только замер скорости (40 мс), а при слежении когда обгоняю пока нога "долетает" до состояния педали, все задержки проходят не один раз. Но мозги-то (мои имеются в виду) знают, что мк практически все время в ожидании...

Ссылка на комментарий
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...