Jump to content
тимвал

Инжектор По Цене Карбюратора

Recommended Posts

22580, в общем то получается.

5b824c3e6fe75_.thumb.PNG.13e968fc8b96e6e41256c80a88d8a767.PNG

Вот два лога. С небольшим по длительности впрыском, и длительный с наложением. Во втором варианте что то типа ШИМа по отдельному таймеру. Частота на картинке 2кГц. Максимально можно сделать 16 кГц. Все события: включение, выключение форсунок, переход в режим ШИМ-удержание происходят через прерывания таймера, т.е. максимально точно по времени. Реализовал буфер событий, который полостью обрабатывается на прерываниях. Что то типа очереди, когда один таймер выполняет событие, и загружает следующиее из этой очереди, и так по кругу. Этот буфер событий можно править из основного цикла программы в любой момент, не задумываясь, что и когда должно произойти по времени. Даже если в осномном цикле будет происходит какая то сложная работа, или обмен по USARTу, это никак не отражается на выходном графике. На данный момент алгоритм занимает 2,5кб. Тестовый проц 90AT8535 на 8мГц. Если 8кБ хватит для реализации всего задуманного, попробую ради праздного интереса запустить все это на процах 8051

Edited by Sheleh

Share this post


Link to post
Share on other sites

Интересное решение, а на чём вы пишете? Сейчас хочу подобрать PIC для реализации инжектора.

Сделал опытную плату под старую реализацию на 16м пике 28 выводов и для новой, на 18м

 

P80829-124944.jpg

Share this post


Link to post
Share on other sites

Высококачественные конденсаторы Panasonic для надежности вашей электроники!

Электролитические алюминиевые конденсаторы Panasonic отличаются повышенной надежностью, длительным сроком службы, низким импедансом и выдерживают большой ток пульсаций, в то время как семейства полимерных конденсаторов Panasonic SP-CAP, POSCAP, OS-CON и HYBRID характеризуют сверхнизкий ESR и увеличенная емкость, работа при высоких напряжениях и в расширенном температурном диапазоне. Приобретая продукцию Panasonic, вы гарантированно получаете самое передовое решение для ваших задач. Для облегчения вашего выбора, мы подготовили подборку полезных материалов.

Читать статьи

На bascom.

С пиками никогда не работал. Подсел на АВР, и пока для моих задач этих контроллеров хватитает с головой.

На пике - это ваша реализация с нуля? На какой стадии проект?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
                     

Вебинар "Как создать BLE-устройство на базе новейшего беспроводного микроконтроллера STM32WB55"

27 ноября 2019 года компания КОМПЭЛ приглашает разработчиков, технических руководителей и энтузиастов беспроводной связи на вебинар, посвященный новинке 2019 года – мультипротокольному беспроводному микроконтроллеру STM32WB55, который позволяет создавать устройства на базе стандартов BLE 5.0; BLE Mesh; 802.15.4/ZigBee и Thread. На вебинаре мы покажем, как с помощью привычных инструментов STM32Cube и STM32CubeMX можно создать свое первое, надежно работающее BLE-приложение.

Зарегистрироваться на вебинар

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

Share this post


Link to post
Share on other sites

Вы прямо весь проект кучей. Кое как отыскал исходник. Еще и на асме.

У меня поскромнее пока.

Скрытый текст

$regfile = "m8535.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 32

'----------------------------------------------------------------------------------------------
 'Config Lcd = 16 * 2"
  'Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0"
  'Config Lcdmode = Port"
  'Cls"
 'Cursor Off"
'----------------------------------------------------------------------------------------------


'----------------------------------------------------------------------------------------------
Config Timer0 = Timer , Prescale = 8                        'таймер для PWM HOLD форсунок
On Timer0 OnTimer0:
Enable Timer0

Config Timer1 = Timer , Prescale = 256 , Clear Timer = 0    'основной таймер
Enable Timer1
Compare1a = 100                                             'конфигурируем по сравнению
On Compare1A OnTimer1
Enable Compare1a


'Config Timer2 = Timer , Prescale = 8
'On Timer2 OnTimer2:
'Enable Timer2
'----------------------------------------------------------------------------------------------

Enable Interrupts                                           'конфигурируем прерывание с ДПКВ
Config Pind.2 = Input
On Int0 Onint0
Config Int0 = Rising
Enable Int0

'------------------конфигурация АЦП-------------------------
Config Adc = Single , Prescaler = 128 , Reference = Aref
Config Pina.5 = Input
Config Pina.0 = Input
Start Adc
'----------------------------------------------------------------------------------------------

'------------------конфигурация USART-----------------------
'Open "comb.4:115200,8,n,1" For Output As #1
'Open "comb.3:115200,8,n,1" For Input As #2
$baud = 57600
Config Pind.1 = Output
Config Pind.0 = Input
Echo Off
'-----------------------------------------------------------

Config Pind.7 = Output                                      'форсунки
Config Pind.6 = Output
Config Pind.5 = Output
Config Pind.4 = Output

Declare Sub SetPortState(byval F As Byte , byval S As Byte)

Dim J As Byte
Dim D As Integer
Dim N As Byte
Dim I As Byte
Dim R As Byte
Dim Q As Byte
Dim Rx As String * 100
Dim Interspace As Integer                                   'время в единицих TIMER1 между импульсами ДПКВ
Dim Pulseflag As Bit
Dim Cycle As Byte : Cycle = 1                               'счетчик наступления рабочтей точки МВТ
Dim PortState(8) As Byte                                    'в этом массиве я храню текущее состояние форсунок. Только для работы PWM HOLD
Dim Port As Byte
Dim AFS As integer
Dim EventTime(5) As Integer                                 'время наступления событий
Dim EventShift(5) As Byte                                   'расчетный период, когда должно наступить событие
Dim EventEnable(5) As Byte                                  'массив флагов исполненности событий

Dim CylindersCount As Byte : CylindersCount = 4             'количество цилиндров в данной конфигурации
Dim PhaseInjShift As Integer : PhaseInjShift = 10           'за какой количество тиков таймера до ВМТ дожна зыкрыться форсунка
Dim TimeIgtCharge As Integer : TimeIgtCharge = 500          'время включения катушки перед моментом зажигания
Dim IgtAngle As Integer                                     'УОЗ


Do
  If Pulseflag = 1 Then                                     'если сработало предывание от ДПКВ
    Pulseflag = 0

    AFS = GetADC(0) * 3

    EventTime(2) = Interspace - PhaseInjShift               'Время закрытия форсунки
    EventTime(4) = Interspace - IgtAngle                    'Момент зажигания
    EventTime(1) = EventTime(2) - AFS                       'Время открытия форсунки
    EventTime(3) = EventTime(1) + 100                       'время включения PWM
    EventTime(5) = EventTime(4) - TimeIgtCharge             'Заряд катушки зажигания
    for i = 1 to 5 : EventShift(i) = 0 : next               'обозначим события как неисполненные
    for i = 1 to CylindersCount -1
      for j = 1 to 5                                        '
        if EventTime(j) < 0 then                            'расчитаем сдвиги событий. Например, если форсунка должна закрыться в текущем
          EventTime(j) = EventTime(j) + Interspace          'такте, но время ее открытия не "влезает" в текущий такт, т.е. идет перкрытие
          incr EventShift(j)                                'Т.е. если время открытого состояния форсунки больше времени между соседними
        end if                                              'работчими МВТ, то вычисляем сдвиг, на какую фазу придется данное событие
      next
    next
    if EventTime(1) < 0 then EventTime(1) = 1
    if EventTime(3) < 0 then EventTime(3) = 1



    'Enable Timer1

    'Locate 1 , 1
    'lcd "         "
    'locate 1 , 1
    'Lcd AFS
    '
    'Locate 2 , 1
    'lcd "         "
    'locate 2 , 1
    'Lcd Interspace



    'Print Hex(interspace)

    If Ischarwaiting() = 1 Then                             'проверка наличия команды в буфере UART
      Input "" , Rx
      If Len(rx) = 5 Then                                   '
        'S=mid(Rx,1,2)
        'T=HEXVAL(S)
        'S=mid(Rx,3,2)
        'dd=HEXVAL(S)
        Print Hex(interspace)
        Rx = ""
      End If
    End If


  End If
Loop

Sub SetPortState(byval F As Byte , byval S As Byte)
  if S < 4 then
    if S = 3 then S = 1
    if S = 2 then S = 0
    if F = 1 then Portd.7 = S                               '1. форсунки в порядке их работы
    if F = 2 then Portd.6 = S                               '2.
    if F = 3 then Portd.5 = S                               '3.
    if F = 4 then Portd.4 = S                               '4.
    'if F = 5 then PortB.7 = S
    'if F = 6 then PortB.6 = S
    'if F = 7 then PortB.5 = S
    'if F = 8 then PortB.4 = S
  else
    S = S - 4
    if F = 1 or F = 3 then PortB.7 = S                      '1-3 зажигание DIS-2
    if F = 2 or F = 4 then PortB.6 = S                      '2-4
'    if F = 3 then PortB.5 = S
'    if F = 4 then PortB.4 = S
  end if
End Sub


OnTimer0:
  if PortState(1) = 3 then Toggle Portd.7                   'тут по таймеру происходит непрерывная инверсия
  if PortState(2) = 3 then Toggle Portd.6                   'выходов форсунок, находящихся в режиме PWM HOLD
  if PortState(3) = 3 then Toggle Portd.5                   '
  if PortState(4) = 3 then Toggle Portd.4                   '
  'if PortState(5) = 3 then Toggle PortB.7
  'if PortState(6) = 3 then Toggle PortB.6
  'if PortState(7) = 3 then Toggle PortB.5
  'if PortState(8) = 3 then Toggle PortB.4
Return

OnTimer1:                                                   'таймер с самозагузкой. Выполняет очередь событий
  L:
  Port = EventShift(n) + Cycle : if Port > CylindersCount then Port = Port - CylindersCount       'вычисляе порт, на котором должно произойти событие
  Call SetPortState(Port , n)                               'выполняем событие
  if n < 4 then PortState(Port) = n                         'если событие не связано с зажиганием, изменяем статус порта форсунки(если n=3 то HOLD PWM)
  EventEnable(n) = 0                                        'помечаем событие, как исполненное

  n = 0
  D = interspace                                            'ищем следующие событие.
  for j = 1 to 5
   if EventEnable(j) = 1 and EventTime(j) < D then          'выбираем ближайшее по времени событие. Они не отсортированы
     D = EventTime(j)
     n = j                                                  'запоминаем его номер
   end if
  next

  if n > 0 then                                             'если события не закончились
   D = EventTime(n) - TIMER1                                'записываем разницу между текущим временем таймера и планируемым
   if D < 5 then goto L                                     'если осталось мало времени до его исполнения,
   Compare1a = EventTime(n)                                 'или вообще мы его успели просахатить, то отправляемся на его немедленное исполнение
  end if                                                    'если время еще есть, грузим планируемое премя следующего события в регистр сравнения.
Return                                                      'как только подойдет время таймера все повторится


Onint0:                                                     'обработчик прерывания датчика в трамблере
   Interspace = Timer1                                      'запомнили сколько тиков натикало с момента предыдущего прерывания. Почти RPM
   Timer1 = 0                                               'обнуляем счетчик
   Pulseflag = 1
   Compare1a = Interspace                                   'загружаем в регистр сравнения максимальное время периода PRM
   for j = 1 to 5                                           'прогоним очереь сообщений на предмет неисполненых. Такое возможно, если обороты увеличились
     if EventEnable(j) = 1 then
       Port = EventShift(j) + Cycle : if Port > CylindersCount then Port = Port - CylindersCount
       Call SetPortState(Port , j)                          'выполняем немедлянно все неисполненные.
       if j < 4 then PortState(Port) = j
     end if

     if EventTime(j) < Compare1a then                       'перебираем очередь сообщений
       Compare1a = EventTime(j)                             'загружаем ближайщее событие
       n = j
     end if
     EventEnable(j) = 1                                     'настал новые период, помечаем все сообщения как неисполненные
   next

   Incr Cycle : If Cycle > CylindersCount Then Cycle = 1    'увеличиваем счетчик периода
   if Compare1a < 4 then Compare1a = 4                      'если событие дишит в затылок. Отодвинем его чуть-чуть. В начале цикла это не зажигание. Значит не страшно

   'Start Timer1
Return





End

 

Сама сложная часть написана. Много чего еще осталось. Дальше я прикручу таблицы VE и УОЗ. Потом алгоритм их OnLine изменения. Плюс корекции всякие. Ну и ХХ. Буду делать так, что бы расчетов в МК было по-минимуму. Желательно вообще избежать использование чисел с плавающей точкой. Т.е. таблицы уже будут с готовыми значениями, пригодными для их непосредственной загрузки в таймеры. Все переводы значений из абсолютных (кПа, углы, температуры) в непосредственные значения регистров МК буду производить на стороне ПК. Тоже есть заготовка на делфи.

Вот тут на драйве начало моих экспериментов и занимательное видео. Как я изучал работу компа от 3S-FE.

Скрытый текст

 

 

Edited by Sheleh
Дополнение

Share this post


Link to post
Share on other sites

@Sheleh , а у вас схема есть? какие датчики применены? какая модель впрыска?

 

А что за софт применён на компе для снятия параметров открытия форсунки?

Edited by hc13nx2

Share this post


Link to post
Share on other sites

@hc13nx2 , ну софт - это громко сказано. Так, набросок на делфи. Там самое интересное, это компонент, позволяющий в 3D отображать таблицы.

Сам алгоритм очень прост. Непрерывно МК измеряет 3 характеристики - время впрыска, время периода между впрысками, по которому мы определяем обороты, ну и АЦП цепи ДАД с резистором, меняющим напряжение от 0 до 5в. Кстати, таким образом можно все это подключить к любой машине и на ходу захватывать данные и формировать таблицу. Подобным способом можно так же слить карту УОЗ. 

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

Если охота пощупать: открываете в протеусе INJECTOR8535.DSN, в МК загружаете main.hex (это откомпилированный исходник, который я приводил выше), запускаете симуляцию. Откроется анализатор. В нем нажимаете "capture", смотрите, что получилось. Там есть переменный резистор, изменение его сопротивление меняет напряжение на АЦП контроллера, внутри которого меняется значение от 0 до 1024. Умножая его на 3 я использую это значение в качестве времени впрыска. Эти цифры не имеют никакого отношения к реальности и к каким либо абсолютным величинам. Это просто для отладки алгоритма. Т.е. посмотреть как справляется МК с короткими впрысками, и что происходит при увеличении этого времени, когда они начинают перекрывать друг друга.

По модели впрыска. В качестве ДАД у меня уже стоит тоетовский. выдает напряжение от 1,5в до 5. В качестве ДПКВ обычный трамблер 4 импульса на 2 оборота коленвала. ДФ пока нет. Думаю, как вообще его не использовать. Т.е. хочу программно придумать, как то определять нужную фазу (говорят на свежих ТАЗах ДФ отсутствует, а тем не менее впрыск фазированный). Типа заводиться на одновременном впрыске. Потом переключаться на фазированный и следить за оборотами. Если падают, то не угадал с фазой. И далее по циклу, пока обороты не перестанут падать.

Датчики температуры тоже тоетовские. Но все это более менее стандартно. В качестве стабилизатора ХХ тоже тоетовский клапан, управлямый ШИМом по двум каналам. ДПДЗ у меня сей час контактный. Буду ставить резистивный. Но это самый второстепенный датчик. Обогощение при тапке в пол можно реализовать и по ДАДу.

CarLoggerClient.rar

SDL.zip

Share this post


Link to post
Share on other sites

@Sheleh Интересно, гляну на схему, я так тоже начинал, что у меня схемы не было нормальной, а плату в спринте разводил и кусок схемы отлаживал в шпроте. Но так тяжело развиваться, сейчас использую Proteus 8 там и схема и плата.

ДАД я использовал MPX4100, я его ещё покупал для МПСЗ, на него есть спецификация и понятно как приводить напряжение к давлению, он до 105кПа, что покрывает все потребности атмосферных двигателей и можно использовать спокойно 8бит АЦП.

По датчику фаз, предлагаю сделать как в Invent Jetronic, одна шторка подпиливается, хоть и на запуске и получаем на один цилиндр хромой угол, но это ничего страшного. http://invent-labs.com/wp-content/uploads/Montazh-komplekta-Invent-Jetronic-v1.pdf

Регулятор ХХ у меня шаговый, вполне стандартный и присутствует во всех автомагазинах, главное что им управлять просто и понятно, в случае замены полная повторяемость. Но занимает лишние выходы на ЭБУ.

ДПДЗ можно не менять, главное детектировать опускание педали для стабилизации ХХ, включение экономайзера я использую по ДАД, что даже позволяет добавить крутящего момента при трогании, когда педаль газа нажата не сильно, но нагрузка на двигатель уже большая и давление уже где-то 65-70кПа во впускном коллекторе.

 

Интересно как у вас реализован ШИМ форсунки. Чисто программная модель?

Share this post


Link to post
Share on other sites

Пока вообще не вижу смысла в тарированности ДАД. Таблицу я уже слил. У меня она там не в кПа, а в вольтах. Зачем переводить туда-сюда? По крайней мере настроить можно и по напряжению, а если что, то я смогу тарировать с помощью подопытного ЭБУ от тоеты из видео. Он же сыпет текучку в которой четко показывает какое в данный момент давление. Например врубил ему 2 вольта, а он столько то кПа, врубил 2.1в, и он соответственно. Сиди только записывай.

Ну я бы не сказал, что управление шаговиком проще, хотя... У меня например нужно будет составить таблицу - насколько процентов открывать ШИМ канал управления клапаном в зависимости от оборотов. Хотя все это не принципиально. Можно и  шаговиком управлять, просто жалко 4 пина.

По ДПКВ. У меня трамблер по-другому устроен. Нет никаких шторок. Есть зубцы, пролетающие мимо катушки. Я уже думал, могу в принципе еще один зубец наростить рядом с одним из 4х имеющихся. Можно сваркой наварить, и болгаркой придать необходимую форму. Програмно такой лишний зубец очень легко отлавливается на основании того, что прерывание на нем произойдет значительно раньше, чем это бы соответствовало текущим оборотам. А дальше я думаю понятно.

По поводу ШИМа. Просто отдельный таймер 8бит. Срабатывает каждые сколько то там наносек, и единственное, что он делает - инвертирует пины форсунок, но не всех, а только тех, что находятся в статусе PWM HOLD. Получается програмно-апаратный шим. Программно конечно жрет, но судя по всему очень мало. Чатоту и скважность можно будет настраивать. Чем выше частота, тем больше срабатываний, тем меньше процессорного времени остается для работы остольного алгоритма. Тут надо эксперементировать, подбирать минимально возможную частоту шим, что бы ее хватало держать форсунку в удерживающем состоянии. Если как сей час при минимальной нагрузке, т.е. максимальное время таймера, то получается 4кГц при частоте кварца в 16мГц. Хватит ли такой частоты, не знаю. Бензиновые форсунки у меня высокоомные, им ШИМ не нужен, а вот газовые 2 ома, тут без ШИМа никак.

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

Вообще что бы не было каких либо проблем, на фоне нехватки ресурсов, я реализую такую ахитектуру. Тот исходник, который я предоставил - это, можно сказать пока только драйвер железа. Т.е. вы в него просто загружаете информацию, что и когда должно произойти, а дальше он ее мусолит самостоятельно, без всякого вмешательства по кругу(как будто бы режим работы ДВС устоявшийся). Т.е. все это работает на прерываниях, типа в отдельном кольце. При чем кольце реального времени. Т.е. если мы не успели пересчитать для предстоящей полуфазы такие вещи, как время подачи импульса открытия/закрытия/вклPWM форсунки, а так же время вкл/выкл катушки(ек) зажигания, эти данные уже есть из предыдущей полуфазы, и фраза "неуспели посчитать", означает, что просто не успели обновить, и никаких сбоев и провалов не произойдет, потому что предыдущие данные за одну полуфазу не очень то и устареют.

И поэтому актуальные задержки и длительности для алгоритма-драйвера пускай считаются непрерывно по кругу за пределами этих прерываний, т.е. в основном цикле программы. И эти расчеты можно вести в асинхронном от фаз режиме. Например данные об оборотах мы не можем обновлять чаще, чем происходят прерывания с ДПКВ. В моем случае на нем всего 4 зубца. А это всего лишь 2 зубца на один оборот КВ. Что достаточно мало по современным меркам, особенно для режимов, когда надо резко ускоряться. Но зависимость длительности впрыска от оборотов не столь существенна, по сравнению с параметром разряжения во впускном коллекторе. И на низких оборотах этот параметр можно проверять чаще, чем частота импульсов с ДПКВ. Соответственно и готовить актуальные данные для драйверной части чаще. Тут только другой вопрос. Праметры ДАД пульсируют. И пишут, что их лучше снимать только в определенный момент.

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

И вообще у меня тут появляются новые грабли. Как сделать он-лайн правку 2х таблиц 16х16 если они просто не влазят в SRAM. Если делать без он-лайн редактирования, то таблицы можно было бы держать как константы, и оператива им не нужна. Т.е. для этого бы хватило 8кб чипа - Атмега8535(512байт RAM). А так придется ставить Мегу16 с1кб озу.

Share this post


Link to post
Share on other sites

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

Таблица обороты-шим не проканает, обороты надо держать в достаточно узком диапазоне, а ход РХХ будет большой. Тут нужно интегральное управления, пропорциональная компонента никак не катит.

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

По ШИМу, интересное решение, но тогда надо очень сильно вычищать код в прерываниях. Что-то грузить и сохранять, тут же ставить флаги и выходить, обработку всех данных только DPC делать основного цикла.

По снятию показания ДАД я сделал как в МПСЗ, снимаю показания в определённый момент, по приходу синхронизирующего импульса, т.е. если даже АЦП что-то считал, я его останавливаю и выбираю канал ДАД. Проблем каких-то не было обнаружено.

Вот допустим напряжение питания почему-то у меня постоянно скачет, на делителе 2к-2к/1к +1мкф, в новой плате уже зарезервировал место под танталовый электролит 10мкф.

Может таблицу править прямо в ЕЕПРОМ? только не целиком грузить, а по отдельным компонентам. У меня пока всё как константы и то одномерная обороты/коррекция.

Edited by hc13nx2

Share this post


Link to post
Share on other sites

Согласен учитывать напряжение надо. Тут наверное достаточно небольшого двухмерного массива.

Трамблер индуктивный. Физически центробежный регулятор уоз выкинут. Заварен намертво. Так что физически ничего никуда не должно плавать. Если имеется ввиду инерционность индуктивных процессов, то я о таком не слышал.
.Сам трамблер примерно выглядит так:

Скрытый текст

proveryaem-kommutator-samostoyatelno_7_1.jpg.3d6da56d9da4fc509f86654eb36b2817.jpg

А в какой именно момент надо снимать показания ДАД?

По поводу правки таблицы в EEPROM. Не знаю. На самом деле я лишь недавно начал программировать под контроллеры и с ЕЕПРОМом мне работать пока не приходилось.

А скорость работы на чтение с ЕППРОМ такая же как и с SRAM? (Надо почитать)

Share this post


Link to post
Share on other sites

Плывёт УОЗ электрически, изменяется напряжение на катушке в зависимости от оборотов,  напряжение срабатывания компаратора постоянное.

По напряжению обычно применяют одномерную таблицу, напряжение-время.

Когда считывать момент с ДАД анализ этого я не проводил,. повторил готовое решение из МПСЗ читая в одно и то же время.

Кроме старый пиков, можно использовать для хранения таблиц и память программ и программно её модифицировать. Иначе в ОЗУ отредактировать получится, а потом как сохранить? Перепрошивкой?

Share this post


Link to post
Share on other sites

@hc13nx2 , да, я так и планировал. У меня для прошивки и для настроки один и тот же шнурок.

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

 Можно даже на ходу перепрошивать, если едешь накатом. Или вообще не использовать оперативу, хранить во флеш, а дистанционно переписывать только необходимую область. Только я не знаю, можно ли averdud'у задать конкретный диапазон программируемой памяти. Будет быстрее, чем переписывать память целиком, но проц всеравно будет сбрасываться. Неудобно конечно.

 

32 минуты назад, hc13nx2 сказал:

По напряжению обычно применяют одномерную таблицу, напряжение-время.

Пардон. Думаю об одном, пишу другое. Я это и имел ввиду.

 

Edited by Sheleh
Добавление

Share this post


Link to post
Share on other sites

@Sheleh , попробуйте для начала меньше размер таблицы VE, допустим 8 по ДАД и 12 по оборотам.

 

У вас как обороты рассчитываются?

Edited by hc13nx2

Share this post


Link to post
Share on other sites

что бы уложиться в 1 Byte

RPM = 47685 / Interspace (константу делю на количество тиков между прерываниями с ДПКВ)

Получается 10000об/мин = 255. Соответственно 1000=25, 500=12. Т.е. с дискретностью в ~ 40 оборотов.

 

 

Share this post


Link to post
Share on other sites

@hc13nx2 , а как вы сделали сам расчет длительности впрыска? Я имею ввиду, допустим я делаю карту 16х16. Если просто брать значения из таблицы, то получается дикая дискретность. Надо же как то с определнной линейностью интерполировать между соседними значениями таблицы. Если просто брать значения из таблицы, то явно же будут подергивания при переходе между ячейками.

Share this post


Link to post
Share on other sites

Для интерполяции необходимо запрашивать сразу 4 соседних значения из таблицы. Т.е. 4 для топлива, и 4 для угла. Остальные поправки (от температур) можно обновлять реже. Если таблицу оставляю во флеш-памяти, то как это отразится на скорости. Понятно, что запись в Флеш медленая по причине сложности алгоритма, но нигде не сказано про скорость чтения. Я не знаток в архитектуре микроконтроллеров, но что мне подсказывает, что это не должно быть так критично. Вот на PC код программы сначала грузится в оперативу, а на МК, я так понял исполняется прямо из флеш. Значит флешка то достаточно быстрая? Или я не прав, и применяются каки-нибудь хитрости, типа кэширования.

Надо попробывать сделать цикличное чтение с подсчетом итераций за промежуток времени.

Share this post


Link to post
Share on other sites

Ура, получилось! В школе по математике я был далеко не отличником. Я даже среднеспециальное не закончил. Хотя мне говорили, хочешь быть программистом, дружи с матиматикой. Fuck U asshole!!!

Даже не верится, что сам разобрался с интерполяцией. Не ну конечно, любой отличик бы наверное справился бы с этим за 15 мин... Хотя очень сомневаюсь, что современным отличникам это по зубам.

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

Скрытый текст

    AFS = GetADC(0) - 259                                   'обрезаем все что ниже нижней работчей границы ДАД
    if AFS < 1 then AFS = 1                                 'Убираем отрицательные значения
    AFS = AFS * 10                                          'Масштабируем в Byte
    AFS = AFS / 32
    RPM = 37600 / Interspace                                'Масштабируем обороты. при частоте 16МГц значению 255 будет соответствовать 10000об/мин
    X = RPM / 16 : Y = AFS / 16                             'Вычисляем положение в таблице
    Kx = X * 16                                             'находим коэффициент для интерполяции по оборотам
    Kx = RPM - Kx
    Ky = Y * 16                                             'находим коэффициент для интерполяции по давлению
    Ky = AFS - Ky
    I = Y * 16 : I = I + X                                  'Вычисляем N соответсвубщего значения в массиве
    X1 = Lookup(I , Saturation)                             'Заносим в X1
    incr I                                                  'Следующий
    X2 = Lookup(I , Saturation)
    I = I + 16                                              'переходим на следующую строку
    X4 = Lookup(I , Saturation)
    decr I
    X3 = Lookup(I , Saturation)                              так у нас есть 4 искомых значения для того что бы из них интерполировать искомое
    Ky = Ky * 100                                           'Для того что бы не работать с дробными числами
    Ky = Ky / 16                                            '
    Kx = Kx * 100                                           'Для того что бы не работать с дробными числами
    Kx = Kx / 16                                            '
    X2 = X2 - X1                                            'Дальше уже сложо коменнтировать, ибо код родился
    X4 = X4 - X3                                            'каким то мгновенным озарением.
    X2 = X2 * 10
    X = X2 * Kx
    X = X / 1000                                            'Что бы не работать с дробью, ранее мы умножали на 100 и на 10. Настала пора делить обатно
    X = X + X1
    X4 = X4 * 10
    Y = X4 * Kx
    Y = Y / 1000                                            'Что бы не работать с дробью, ранее мы умножали на 100 и на 10. Настала пора делить обатно
    Y = Y + X3
    X = Y - X
    X = X * Ky
    X = X / 100
    InjTime = X1 + X                                        'искомое интерполированное значение
-------------------------------
      
Saturation:
Data 26 , 27 , 28 , 28 , 28 , 28 , 29 , 30 , 31 , 32 , 33 , 33 , 32 , 32 , 31 , 30
Data 30 , 31 , 32 , 32 , 32 , 32 , 34 , 35 , 36 , 37 , 38 , 38 , 37 , 37 , 36 , 35
Data 35 , 36 , 37 , 37 , 37 , 37 , 39 , 41 , 42 , 43 , 44 , 44 , 43 , 43 , 42 , 41
Data 41 , 42 , 43 , 43 , 43 , 43 , 45 , 48 , 49 , 50 , 51 , 51 , 50 , 50 , 49 , 48
Data 48 , 49 , 50 , 50 , 50 , 50 , 52 , 56 , 57 , 58 , 59 , 59 , 58 , 58 , 57 , 56
Data 56 , 57 , 58 , 58 , 58 , 58 , 60 , 65 , 66 , 67 , 68 , 68 , 67 , 67 , 66 , 65
Data 65 , 66 , 67 , 67 , 67 , 67 , 70 , 75 , 77 , 78 , 79 , 79 , 78 , 78 , 77 , 75
Data 75 , 77 , 78 , 78 , 78 , 78 , 81 , 87 , 89 , 90 , 92 , 92 , 90 , 90 , 89 , 87
Data 87 , 89 , 90 , 90 , 90 , 90 , 94 , 101 , 103 , 104 , 107 , 107 , 104 , 104 , 103 , 101
Data 101 , 103 , 104 , 104 , 104 , 104 , 109 , 117 , 119 , 121 , 124 , 124 , 121 , 121 , 119 , 117
Data 117 , 119 , 121 , 121 , 121 , 121 , 126 , 136 , 138 , 140 , 144 , 144 , 140 , 140 , 138 , 136
Data 136 , 138 , 140 , 140 , 140 , 140 , 146 , 158 , 160 , 162 , 167 , 167 , 162 , 162 , 160 , 158
Data 158 , 160 , 162 , 162 , 162 , 162 , 169 , 183 , 186 , 188 , 194 , 194 , 188 , 188 , 186 , 183
Data 183 , 186 , 188 , 188 , 188 , 188 , 196 , 212 , 216 , 218 , 225 , 225 , 218 , 218 , 216 , 212
Data 212 , 216 , 218 , 218 , 218 , 218 , 227 , 246 , 251 , 253 , 255 , 255 , 253 , 253 , 251 , 246
Data 246 , 251 , 253 , 253 , 253 , 253 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255

 

Теперь коэффициент VE изменяется плавно от 1 до 255. С дискретностью 1. В ms это будет 0,08ms

По поводу чтения из флеш. В BASCOM это производится коммандой Lookup. Она медленее обычного присваивания из переменной в RAM. Но медленее она всего лишь в 2,2 раза, что на самом деле тоже очень быстро.  И держать большие объемы данных в ОЗУ имеет смысл лишь для полноценно-онлайновной настройки. Но тогда нужны будут чипы большей размерности. Но моя цель была попытаться использовать самый дешевый из возможных. Я конечно еще много чего не реализовал, но хотя бы появилась уверенность, что полноценный код таки можно уместить в 8кб.

Весь код интерполяции плюс расчет временных задержек выполняется за 0.4 ms. И это без использования ассемблера.

Так же в процессе реализации я пришел к выводу, что BASCOM - это супер-компилятор, ни чем не уступающий аналогичным решениям на С. Конечно лучшим решением для ядра AVR считается IAR, так как они учавствовали в разработке архитектуры ядра. BASCOM на мой взгляд занимает твердое второе место. А вот GCC я бы поставил на 3-е, есть статья на хабре, где они сравниваются.

Исходя из вышеописанного становится реалистичнее идея засунуть полноценный алгоритм ЭСУД в древнейший чип на архитектуре Intel 8051. Конечно сам 8051 обладает лишь 4кБ памяти, а вот 8052 с 8кБ уже вполне подходит под наши задачи. Просто у меня их огромная куча, да и стоимость их на али не больше 100р за шт. И это за полноценных 40 ног! Вы только представьте, по себестоимости ЭБУ менее 500р, где большую часть бюджета - это транзисторы.

Edited by Sheleh
Исправление ашыбак

Share this post


Link to post
Share on other sites

Sheleh, ты правильно отметил про компиляторы.Только не GCC.

Atmega и  предназначалась под языки вроде си, сравни структуру регистров и доступа к памяти классического 8051 и атмеги.

С классическими 8051 не все так гладко, тут либо asm, либо .современные ядра с переферией и кейл,иар.

Atmel - мертва.

Делай ядро для 8051 с молулями и ты сможешь запустить его на любом автомбильном блоке bosch, который стоит иногда даже бесплатно.

Например mono jetronic. - 80c52.

В более навороченных применяются 80с515,535,509 и все они имеют одинаковую структуру.

Сделаешь по плате мапинг по портам и вперед.

https://www.drive2.ru/users/avtoelektron/#blog

Вот он на Си пишет под 8051.

Share this post


Link to post
Share on other sites

@sr86, по компиляторам: ну возможно GCC не так уж и плох (всяко лучше arduino'вского), но тем нее мнее BASCOM совсем не хуже. Кстати, он изначально разрабатывался для архитектуры 8051. Как заявляют разработчики он процентов на 30-40 уступает чистому ассемблеру по размеру прошивки. На сколько я знаю, ситуациия с GCC ничем не лучше. Лишь у IAR значительно лучше.

Подожди. Ты хочешь сказать, что Январь работает на 8051? Я живу в Бурятии, и тачки на январе для нас тут редкость. В основном одни жапанцЫ.  Поэтому не силен в архитектуре западных (по отношению к Сибири) ЭСУД.

Так что "бесплатность" такого блока у нас отсутствует. Вообще январь днем с огнем не сыщешь. Зато какой нибудь тоетовский на разборе можно за рублей 500 взять, если не GTE конечно.

Edited by Sheleh
Исправление ашыпки

Share this post


Link to post
Share on other sites

@Sheleh Да. на Январе стоит расширенный 51 по периферии + вроде арифметика там добавлена. А по поводу расчёта времени впрыска, проще сделать либо линейную интерполяцию между двумя значениями (смесь на ХХ и на максимальном режиме) от ДАД, либо значение ДАД умножать на коэфф. топливной смеси, а дальше уже умножать на полученное значение из таблицы VE, так можно таблицу обновлять реже.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...