roboforum.ru

Технический форум по робототехнике.

Бортовой компьютер на инжектор

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Бортовой компьютер на инжектор

Сообщение Sun-dey » 23 апр 2009, 14:24

Законченный проект:
viewtopic.php?f=2&t=3912&p=121238#p121238





Доброго времени суток, появилась мысль сделать бортовой комп, чтобы расход топлива считал, пробег и т.п.
Имеется Atmega8, LCD. Совсем немного опыта программирования на СИ, около месяца :oops:
Застрял на подсчете времени открытия форсунки, оно может быть ориентировочно от 0,5мс до 10мс.
Использовал TIMER1 для подсчета времени открытия (одно переполнение при текущих настройка составляет 1мс), не получается отловить остаток таймера на момент прерывания INT1 (Провод от форсунки, +12В= открытие форсунки).

Запущены 2 таймера, один считает время для скорости (с ним все нормально вроде), второй время для впрыска.


//FuelCounter - увеличивается на 1 за каждое переполнение TIMER1

interrupt [EXT_INT1] void ext_int1_isr(void)

OstCountFuel=TCNT1; // Остаток таймера на момент прерывания

TCNT1H = 0xFF; //устанавливаем максимальное значение (255) при котором произойдет прерывание
TCNT1L = 0x83; // начинаем считать с 131, вроде бы...этой строчкой и предыдущей сбрасываем таймер и он начинает считать заново или я ошибаюсь?

Fuel = ((FuelCounter*125)+(OstCountFuel-131))*10 ; // Длительность открытия форсунки в тиках таймера*10, 131 я правильно вычитаю?
FuelCounter=0;
OstCountFuel=0;
Fuel = (Fuel/125) ;// должно по идее получиться в мс*10, но получается фигня.
например ставлю в протеусе длительность импульса
1мс получается прыгающие 6-7-8-9
2мс 17-18-19
ладно, мог там с периодом таймера напутать. но если выставить
0,5мс получается уже 523 :crazy:

P.S. забыл совсем, все это безобразие в CodeVisionAvr
Последний раз редактировалось Sun-dey 28 сен 2009, 12:44, всего редактировалось 1 раз.
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение boez » 24 апр 2009, 23:18

Блин, инет глюканул и большое мое сообщение потерялос :(

Оставлю маленькое, за краткость извиняюсь, если что - отвечу на вопросы. Просто самого тема интересует.

Для какого авто система?

Рассматривался ли вариант, работающий по величине расхода воздуха, прочитанной по интерфейсу OBD-II и умноженной на фиксированный коэффициент бензин/воздух? Читал вот статью с описанием такой штуки на AVR: http://www.lightner.net/lightner/bruce/Lightner-183.pdf Правда для моего Форда не подойдет, у него не VPW, а PWM интерфейс, но это только вопрос схемы и части прошивки, формулы расчета одинаковые.

А по коду вообще не совсем понятна идея, как это все предполагалось считать. Зачем что-то считать кусками, может стоит запрограммировать предделитель таймера, чтобы его тик был равен например 1 мкс, и считать счетчиком таймера все значение целиком, от 0 до 10000, без никаких его переполнений? Начальное значение ставить в ноль в начале импульса, без странных констант... И еще может выгоднее завести сигнал на Capture вход и мерять длительность аппаратно?
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 25 апр 2009, 10:35

Привет. Вариант с воздухом рассматривался. Цеплял ноут и катался с ним...что то даже похожее на правду показывает :) Но это если датчик кислорода нормально работает и МАФ. и процент кислорода в воздухе неизменный, т.е. в городе завышать явно будет :no: теоретически конечно удобнее, из-под капота провода не тянуть.....
Мне тоже на Форд, ФМ-2 98г PWM интерфейс.
Еще добрался до разъема к которому часы подключены (иногда там комп заводской стоит :) ) проводков много там, может туда можно подключиться ?

По коду знаю, пипец полный, т.к. с СИ знаком всего месяц, именно из-за борткомпа осваиваю. Раньше были мысли освоить- повода не было :oops: таймер на 1мкс пробовал настроить, в протеусе жк в этом случае не завелся а в железе не пробовал.


запрограммировать предделитель таймера, чтобы его тик был равен например 1 мкс, и считать счетчиком таймера все значение целиком, от 0 до 10000, без никаких его переполнений? Начальное значение ставить в ноль в начале импульса, без странных констант... И еще может выгоднее завести сигнал на Capture вход и мерять длительность аппаратно?


А вот с этого места можно с примерами? :beer:
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение boez » 25 апр 2009, 22:39

Ну вот что-то типа такого (щас лень смотреть синтаксис объявления обработчиков, да и разный он вроде в gcc и cvavr, так что я просто идею опишу).

Код: Выделить всёРазвернуть
Переменные:

unsigned char ExtSignalFlag;
unsigned short TimeVal;

Инициализация:
ExtSignalFlag = 0;
MCUCR = (MCUCR | ((1<<ISC01)|(1<ISC00))); //внешнее прерывание настроено на фронт сигнала

Прерывание по сигналу с форсунки:
{
  if (ExtSignalFlag) {
    TimeVal = TCNT1;
    TCCR1B = 0; //Выключили таймер
    MCUCR |= (1<<ISC00); //Настроить прерывание на фронт сигнала (rising edge):
    ExtSignalFlag = 0;
  }
  else {
    TCNT1 = 0;
    TCCR1B = (1<<CS11); //F = Tosc/8, если кварц 8 МГц, то тик таймера = 1 мкс, старт таймера
    MCUCR &= ~(1<<ISC00); //Настроить прерывание на спад сигнала (falling edge)
    ExtSignalFlag = 1;
  }
}



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

А с Input Capture я глянул, похоже что проще чем этот код оно не будет. Все равно получается, что надо обнулять счетчик таймера ручками в начале импульса, тогда оно сможет поймать его хвост аппаратно.

А, да, регистры взяты восьмой атмеги, как сделать в других - курить даташит.
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 23 авг 2009, 19:18

boez , я его всетаки сделал :)Если есть желание ознакомится- пиши :)

А вот вопросы все равно остались- нужно значения полного расхода и общего пути записать в еепром, т.к. при выключении зажигания все сбросится.
Если записывать слишком часто- я так понял МК просто не успевает это сделать?
Если записывать изредка- часть данных теряется....
Идеальный вариант- чтобы программа отслеживала падение напряжения при выключении зажигания, и в этот момент записывала, но АЦП боюсь не осилю :durak:
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение Master » 23 авг 2009, 22:20

А смысл отключать МК от питания при отключении зажигания? Пустить его напрямую к аккумулятору, потребляет она ерунду. А данные в ЕЕПРОМ писать после выключения зажигания, но тогда нада тянуть провод к замку зажигания, лучше просто наверное каждые 15-30 сек писать данные и все.
И это, раз уж собрал сфоткал бы, кинул описание, схемы и т. д., а то никрасиво.
Аватара пользователя
Master
 
Сообщения: 4468
Зарегистрирован: 21 дек 2006, 19:56
Откуда: Украина, г.Одесса
прог. языки: Delphi и С

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 24 авг 2009, 12:38

Насчет потребляет- не замерял, но все же хочется отключать :)
Вытащил в main запись в еепром- все пишется, все успевает.....Но как скоро еепром до дыр протрется? :?:
фоты и описалово будет, правда к концу недели, на сей опус нужно время...
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение yak-40 » 24 авг 2009, 12:54

Sun-dey писал(а):Но как скоро еепром до дыр протрется?

через 100.000 циклов :)
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!
Аватара пользователя
yak-40
 
Сообщения: 3037
Зарегистрирован: 23 окт 2007, 22:03
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 24 авг 2009, 13:27

Подстава, всего за пару дней получается :oops:
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение yak-40 » 24 авг 2009, 13:35

Надо согласиться с Мастером, и не отключать МК от аккумулятора.
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!
Аватара пользователя
yak-40
 
Сообщения: 3037
Зарегистрирован: 23 окт 2007, 22:03
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец

Re: Бортовой компьютер на инжектор

Сообщение Digit » 24 авг 2009, 13:44

тем более, что у МК есть режимы низкого энергопотребления, при которых он считай что вообще ничего не ест. Отрубая всю переферию, можно добиться вообще чисто номинального потребления (соизмеримого с током утечки аккума - или как там оно зовется).
Если совсе уж жалко аккум, то тогда поставьте туда микроаккумулятор, от которого МК будет питаться в обесточенном состоянии (но все равно переводите его в сон), а при заведенном движке пусть этот резервный аккум заряжается...
Но нафига такой изврат при мизерном потреблении МК - я ума не приложу :pardon:
злой полицейский
Аватара пользователя
Digit
 
Сообщения: 3339
Зарегистрирован: 27 ноя 2004, 00:42
Откуда: совсем Москва
ФИО: Григорий

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 24 авг 2009, 13:55

Дело в том, что еще LCD дисплей подключен, а вот он по сравнению с МК немало потребляет, придется еще его усыплять :)
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение yak-40 » 24 авг 2009, 14:00

Sun-dey писал(а):Дело в том, что еще LCD дисплей подключен, а вот он по сравнению с МК немало потребляет

Да чего он там потребляет :)
Отключи подсветку и делов то...

З.Ы. Все автосигнализации на микроконтроллерах, и ни одна от питания не отключается.
- Этот человек - не человек! это робот!
- Как? уже делают?!
- Делают!!!
Аватара пользователя
yak-40
 
Сообщения: 3037
Зарегистрирован: 23 окт 2007, 22:03
Откуда: Москва
прог. языки: С
ФИО: Евгений Яковец

Re: Бортовой компьютер на инжектор

Сообщение Sun-dey » 24 авг 2009, 14:05

Собственно сам код, ОООчень буду рад дельным советам :friends:

Модератор Vooon:Прикрепи исходный код архивом к сообщению!!!


Код: Выделить всёРазвернуть
/*****************************************************
Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/
#include <stdlib.h>
#include <mega8.h>
       
#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>

char TotalFuelStr[14];
char Vtoraya_Stroka[14];
char LitrNaSotnyStr[14];
char TotalPutStr[14];
int rezhim=2;    // 1- общий расход, л/100    2- общий расход, общий пробег    3-настройка   4-коэффициент форсунки   5- датчик скорости  6- обнуление
int timetimer=0;
//int Key_interval=0;
float LitrNaSotny=0;
float TotalFuel;
float TotalPut;

unsigned long int  StoGramm=0;
unsigned long int  SpeedCounter=0;
unsigned long int  i=0;
unsigned long int  Speed_For_light=0;
//unsigned long int  Speed=0;


eeprom unsigned long int  eepromPrFors; // производительность форсунки (время в мкс, за которое наливается 0,01л)/1000
eeprom unsigned long int eepromImpuls_km;
unsigned long int  PrFors=0;
unsigned long int  Impuls_km=0;
eeprom unsigned long int eepromTotalFuel;
eeprom unsigned long int eepromTotalPut;
//****************************************************************************************************************************




void knopki(void) {     //назначение данной функции- изменение значения "rezhim", и только :)
                   
       if ( PINC.1==0) {
           lcd_clear();
            rezhim++;   
                       if (rezhim>2) {
       
                       rezhim=1;
     
                       };
           
  delay_ms(400); 
}; // конец обработки нажатия кнопки   

        if ( PINC.2==0) {
           lcd_clear();
            rezhim++;
           
            if (rezhim<4) {
       
                       rezhim=4;
     
                       };
                       
                         
                       if (rezhim==7) {
       
                       rezhim=4;
     
                       };
                         delay_ms(400); 
}; 
} // конец обработки нажатия кнопки


void display(void) {


 
      //******************************************* 
              // отображение первого режима
             if (rezhim==1) {               
       
         lcd_gotoxy(10,0);
      lcd_putsf("Litrs ");
      lcd_gotoxy(10,1);
      lcd_putsf("L/100 ");
       
       
          lcd_gotoxy(1,0); // общий расход
         ftoa(TotalFuel/100,2,TotalFuelStr);
         lcd_puts(TotalFuelStr);
         lcd_putsf("   ");
       
       lcd_gotoxy(1,1);    // литры/100км
       ftoa(LitrNaSotny/100,1,LitrNaSotnyStr);
       lcd_puts(LitrNaSotnyStr);
       lcd_putsf("   ");
       
   
       
       
       };  // конец if (rezhim==1)
       
       
             // отображение второго режима
             if (rezhim==2) {               
       
       lcd_gotoxy(10,0);
      lcd_putsf("Litrs");
      lcd_gotoxy(10,1);
      lcd_putsf("Kilom.");
       
       
          lcd_gotoxy(1,0); // общий расход
         ftoa(TotalFuel/100,2,TotalFuelStr);
         lcd_puts(TotalFuelStr);
         lcd_putsf("   ");
       
       lcd_gotoxy(1,1);    // всего км
       ftoa(TotalPut/Impuls_km,2,TotalPutStr);
       lcd_puts(TotalPutStr);
       lcd_putsf("   ");
     
       
   
       
       
       };  // конец if (rezhim==2)
       
       
                                                 
     
             // отображение третьего режима
             if (rezhim==3) {               
       
       lcd_gotoxy(4,0);
       lcd_putsf("Options");     
       
   
       
       };  // конец if (rezhim==3)
     
     
                 // отображение четвертого режима
             if (rezhim==5) {               
       
       lcd_gotoxy(4,0);
      lcd_putsf("Forsunka");
      itoa(PrFors/1000,Vtoraya_Stroka);
       lcd_gotoxy(5,1);
       lcd_puts(Vtoraya_Stroka);
       lcd_putsf("   ");
     
       if ( PINC.3==0) {      // +
       PrFors=PrFors+1000;
       eepromPrFors=PrFors/1000;
      delay_ms(100);
       };
     
        if ( PINC.4==0) {      // -
       PrFors=PrFors-1000;
       eepromPrFors=PrFors/1000;
      delay_ms(100);
       };
     
       
       };  // конец if (rezhim==4)
     
     
     
                       // отображение пятого режима
             if (rezhim==6) {               
       
       lcd_gotoxy(4,0);
      lcd_putsf("Speed");
      lcd_putsf("   ");
      itoa(Impuls_km,Vtoraya_Stroka);
       lcd_gotoxy(5,1);
       lcd_puts(Vtoraya_Stroka);
       lcd_putsf("   ");
     
       if ( PINC.3==0) {      // +
       Impuls_km++;
       eepromImpuls_km=Impuls_km;
      delay_ms(100);
       };
     
        if ( PINC.4==0) {      // -
       Impuls_km--;
       eepromImpuls_km=Impuls_km;
      delay_ms(100);
       };
     
       
       };  // конец if (rezhim==5)
     
                        // отображение шестого режима (очистка полного пробега и расхода)
             if (rezhim==4) {               
       
       lcd_gotoxy(4,0);
      lcd_putsf("Clear all ?");
     
     
       if ( PINC.3==0) {      // +    типа да
        eepromTotalPut=0;
       eepromTotalFuel=0;
       TotalPut=0;
       TotalFuel=0;
       
       rezhim=2;
       
      lcd_clear();
     
       };
     
        if ( PINC.4==0) {      // -
      rezhim=2;
      lcd_clear();
       };
     
       
       };  // конец if (rezhim==6)












}


//****************************************************************************************************************************
         
// таймер времени, 1 сек
interrupt [TIM0_OVF] void timer0_ovf_isr(void)  // Clock value: 7,813 kHz/256 = 30 раз в секунду
{
timetimer++;
if (timetimer>30) {
timetimer=0;
Speed_For_light=0;
};






};



interrupt [EXT_INT0] void ext_int0_isr(void)
{
SpeedCounter++;
TotalPut=TotalPut+1;
Speed_For_light++;

}


// Прерывание по форсунке
interrupt [EXT_INT1] void ext_int1_isr(void)
{

    if ( PIND.3 ) 
        {
           // Закрытие форсунки, считаем время открытия
        MCUCR=0x0B;// разрешаем прерывание по спаду
        TCCR1B=0x00; // останавливаем таймер
        i=i+TCNT1; // имеем тики таймера, то есть мкс :) за 0.83 сек вливается 0,01л
        TCNT1=0;
       
        if (i>PrFors) {
              StoGramm++; // на самом деле 10 грамм :))
              i=0;
              //  посчитаем л/100км       SpeedCounter- количество импульсов с датчика скорости с последнего рассчета
           
           LitrNaSotny=Impuls_km*100/SpeedCounter;   // сколько импульсов получиться за 100км делим на
                                                     // количество импульсов с датчика скорости с последнего рассчета
                                                     // узнаем сколько нужно будет таких огрызков чтобы получилось 100км
                                                     // 1 огрызок= 10грамм топлива.
                                                     
          if (LitrNaSotny>10000) {
          LitrNaSotny=99990 ;
               };
                                           
                                                     
                                                     
                                                     
                                                     
         
           SpeedCounter=0;
           TotalFuel=TotalFuel+1;   // 10 грамм+
           
             
              };


    }
    else   // Открытие форсунки
    {   
             
             MCUCR=0x0F;      // разрешаем прерывание по нарастанию
        TCCR1B=0x02;// 1 кгц // запускаем таймер

}
      }







void main(void)
{

PORTB=0x00;
DDRB=0x00;

PORTC=0x7F;
DDRC=0x00;

PORTD=0x01;
DDRD=0x01;
//PORTD=0x00;
//DDRD=0xF3;
//DDRD=0x00;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0=0x05;
TCNT0=0x00;










// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x03;
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: On
// INT0 Mode: Rising Edge
// INT1: On
// INT1 Mode: Any change
GICR|=0xC0;
//MCUCR=0x07;
MCUCR=0x0B;
GIFR=0xC0;

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

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



// Global enable interrupts
#asm("sei")
// LCD module initialization
lcd_init(16);
delay_ms(100);
//lcd_putsf("test");
delay_ms(5);

if (eepromPrFors<200) {  // для первого включения
eepromPrFors=830;
};
if (eepromImpuls_km<200) {
eepromImpuls_km=5000;
};


TotalFuel=0;
PrFors=eepromPrFors*1000;
Impuls_km=eepromImpuls_km;
//TotalFuel=eepromTotalFuel;
//TotalPut=eepromTotalPut;

//PORTD=0x00;
//delay_ms(100);
// PORTD=0x01;
// delay_ms(100); Pos Test :))
// PORTD=0x00;
//delay_ms(100);
// PORTD=0x01;
// delay_ms(100);
PORTD=0x00;
//delay_ms(100);
// PORTD=0x01;
// delay_ms(100);

lcd_clear();
         lcd_gotoxy(0,0);
      lcd_putsf(" Trip Comp v 1.2");
         lcd_gotoxy(0,1);
      lcd_putsf("   23.08.2009   ");
      delay_ms(1000);
        lcd_clear(); 
while (1)

{
 
 
  if (Speed_For_light>83) {
  TIMSK=0x00;
PORTD=0x01;
};

       
   display(); 
   knopki();   
       //********************************************
       // типа все посчитали-вывели, пробуем записать промеж. данные в еепром
      // eepromTotalPut=TotalPut;
      // eepromTotalFuel=TotalFuel;
       
       };  // конец цикла
     
}
Sun-dey
 
Сообщения: 106
Зарегистрирован: 23 апр 2009, 14:12
Откуда: Курская обл.

Re: Бортовой компьютер на инжектор

Сообщение Myp » 24 авг 2009, 16:46

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

прилепить часовую таблетку или парочку полюбому надо
машина штука такая, вдруг акумулятор менять будешь...
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

След.

Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21