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

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Тахометр с управлением ЭППХ

Сообщений 1 страница 24 из 24

1

С наступающим новым годом господа!
Решил сделать тахометр с управлением холостого хода двигателя , для моего коня. Но, чтото застрял на тахометре, кто нибудь пытался соорудить тахометр на 4тактный двигатель. Подскажите пожалуйста. Вот привожу то, что я нагородил. "по моему получилась какаято КЕЛЬНЯ"

Код:
$regfile = "m8def.dat"
$crystal = 8000000

Config Portb = Output
Config Portd = Output
Config Portb.5 = Input
Config Timer1 = Timer , Prescale = 64 , Capture Edge = Rising

A Alias Portd.0
B Alias Portd.1
C Alias Portd.2
D Alias Portd.3
E Alias Portd.4
F Alias Portd.5
G Alias Portd.6                                             'Тут вписываем порты к которым подключены сегменты индикатора
Dig1 Alias Portb.0
Dig2 Alias Portb.1

On Capture1 Captmr
Enable Interrupts
Enable Capture1

'Wtime = 100

Dim Wtime As Byte
Dim Rpm As Single
Dim Rpm2 As Integer
Dim V As Byte , Z As Byte , Y As Byte , I As Byte , Chislo(8) As Long , Viv_peremennaya As Long , Temp_print As Long       ' задаем переменные
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse :    ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts : Enable Timer0                           ' разрешаем прерывания и таймер 0

'....................
Do

  'Pinb.5 = 1
  Waitms Wtime
  Locate 1 , 1
  Rpm = Capture1 * 0.008
  Rpm = Rpm / 0.008
  Rpm = 60 / Rpm
  Rpm2 = Rpm / 0.000008
Loop

Pulse:
Stop Timer0
Temp_print = Rpm2
For I = 1 To 4                                              ' цикл в котором разбивается переменная на отдельные числа от 0 до 9
Chislo(i) = Temp_print Mod 10                               ' заносим в масив последнюю цифру от числа Temp_print(12345678 mod 10 = 8)
Temp_print = Temp_print / 10                                ' отсекаем последнюю цифру от числа Temp_print (12345678/10=1234567)
Next                                                        ' останавливаем таймер 0
Set Dig1 : Set Dig2
Incr V : If V > 4 Then V = 1                                ' выбираем какую цифру сейчас включать
Y = 0
Gosub Look : A = Z                                          ' переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А
Gosub Look : B = Z
Gosub Look : C = Z
Gosub Look : D = Z
Gosub Look : E = Z
Gosub Look : F = Z
Gosub Look : G = Z

Select Case V                                               ' включаем цифру которую выбрали (w). Подаем минус на общий провод конкретной цифры
 Case 1 : Reset Dig1
 Case 2 : Reset Dig2
End Select
Start Timer0                                                ' запускаем таймер0
Return                                                      ' возвращаемся к выполнению основной программы

Look:                                                       ' подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму
Z = Chislo(v) * 7 : Z = Y + Z                               ' определяем порядковый номер числа из таблици DATA. W - это цифра которую будем выводить 0..1..2..3.......9, Y это номер сегмента (A=0 B=1 C=2...G=7)
Z = Lookup(z , Cifri)                                       ' выбираем из таблици включить или выключить нужный сегмент
Incr Y                                                      'Y это номер сегмента (A=0 B=1 C=2...)
Captmr:
  Timer1 = 0
Return                                                      'возвращаемся на место откуда сюда прислали

Cifri:
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9

0

2

Если это мотоцикл, то светодиодные индикаторы лучше не использовать - в солнечную погоду их не видно. Здесь нужен ч/б ЖКИ.

Нет, это автомобиль с объемом двигателя 1500.

0

3

Неужели ни укого нет никаких советов.
Будте добры подскажите.

0

4

Привет всем!
С наступающим вас новым годом.
Опять решил попробовать тахометр соорудить, набросал код, но не та работа, подскажите где ошибся.

Код:
$regfile = "m8def.dat"
$crystal = 8000000

Config Portd = Output
Config Portb = Output
'Config Portc = Output
'Config Portb.7 = Input

A Alias Portd.5
B Alias Portd.0
C Alias Portd.3
D Alias Portb.1
E Alias Portd.7
F Alias Portd.6
G Alias Portd.4
Dp Alias Portd.2                                            'Тут вписываем порты к которым подключены сегменты индикатора
Dig1 Alias Portb.2
Dig2 Alias Portd.1


Dim W As Byte , Z As Byte , Y As Byte , I As Byte , Chislo(8) As Long , Viv_peremennaya As Long , Temp_print As Long       ' задаем переменные
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse :    ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts : Enable Timer0                           ' разрешаем прерывания и таймер 0

'Gosub Tahometer
Config Timer1 = Timer , Capture Edge = Rising , Prescale = 1

'Stop Timer1                                                 'задание начальных условий
Timer1 = 0
Compare1a = 2

Dim Wtime As Byte
Dim Rpm As Single
Dim Rpm2 As Integer

On Capture1 Captmr                                          'Captmr
Enable Interrupts
Enable Capture1

Wtime = 100

Do
  'Waitms Wtime
  Locate 1 , 1
  'If Pinb.7 = 1 Then
  'Rpm = Locate 7
  Rpm = Capture1 * 0.008
  Rpm = Rpm / 0.008
  Rpm = 60 / Rpm
  Rpm2 = Rpm / 0.000008
  Incr Temp_print                                             ' переменная, которая будет отображатся на семисегментнике.
  Waitms 100
  'End If
Loop

Captmr:
'Stop Timer1
  Timer1 = 0
Return
End                                                         'Sub

Pulse:
Stop Timer0
Temp_print = Rpm2
For I = 1 To 4                                              ' цикл в котором разбивается переменная на отдельные числа от 0 до 9
Chislo(i) = Temp_print Mod 10                               ' заносим в масив последнюю цифру от числа Temp_print(12345678 mod 10 = 8)
Temp_print = Temp_print / 10                                ' отсекаем последнюю цифру от числа Temp_print (12345678/10=1234567)
Next                                                        ' останавливаем таймер 0
Set Dig1 : Set Dig2
Incr W : If W > 4 Then W = 1                                ' выбираем какую цифру сейчас включать
Y = 0
Gosub Look : A = Z                                          ' переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А
Gosub Look : B = Z
Gosub Look : C = Z
Gosub Look : D = Z
Gosub Look : E = Z
Gosub Look : F = Z
Gosub Look : G = Z

Select Case W                                               ' включаем цифру которую выбрали (w). Подаем минус на общий провод конкретной цифры
 Case 1 : Reset Dig1
 Case 2 : Reset Dig2
End Select
Start Timer0                                                ' запускаем таймер0
Return                                                      ' возвращаемся к выполнению основной программы


Look:                                                       ' подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму
Z = Chislo(w) * 7 : Z = Y + Z                               ' определяем порядковый номер числа из таблици DATA. W - это цифра которую будем выводить 0..1..2..3.......9, Y это номер сегмента (A=0 B=1 C=2...G=7)
Z = Lookup(z , Cifri)                                       ' выбираем из таблици включить или выключить нужный сегмент
Incr Y                                                      'Y это номер сегмента (A=0 B=1 C=2...)
Return                                                      'возвращаемся на место откуда сюда прислали

Cifri:
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '0
Data 0 , 1 , 1 , 0 , 0 , 0 , 0                              '1
Data 1 , 1 , 0 , 1 , 1 , 0 , 1                              '2
Data 1 , 1 , 1 , 1 , 0 , 0 , 1                              '3
Data 0 , 1 , 1 , 0 , 0 , 1 , 1                              '4
Data 1 , 0 , 1 , 1 , 0 , 1 , 1                              '5
Data 1 , 0 , 1 , 1 , 1 , 1 , 1                              '6
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '7
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '8
Data 1 , 1 , 1 , 1 , 0 , 1 , 1                              '9

0

5

Честно говоря я кода не понял .

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

0

6

Честно говоря я и сам запутался, помогите исправить.

0

7

Для того, чтобы исправить надо понять алгоритм работы устройства.

В 4-х тактном двигателе искра в цилиндре возникает 1 раз на 2 оборота, а цилиндров 4, то получается, что искра будет возникать 2 раза на 1 оборот коленвала.  Для определения числа оборотов двигателя я бы делал примерно так. Один таймер - в режиме таймера, второй таймер - в режиме счетчика. Таймер отсчитывает время - полсекунды. За это время в счетчике - частота оборотов. Ну а дальше - вывод результата на индикатор.

А как устройство должно управлять ЭПХХ?

0

8

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

0

9

Про код тахометра я нашол в этой статьеhttp://radiokot.ru/forum/viewtopic.php?f=20&t=6408&start=1620

0

10

А нужен ли здесь МК? В машине с карбюратором (а в другой нет ЭПХХ) контактное зажигание, будет море дребезга, помех и работать будет через пень, особенно на схеме захвата. Здесь обычный частотный дискриминатор пойдет, импульсы заряжают конденсатор, на него "смотрит" аналоговый компаратор, если частота импульсов больше 1500, то конденсатор успеет зарядиться больше уровня компаратора, он опрокинется и клапан закроет, а как меньше 1300 компаратор наоборот откроет клапан. Кнопка на педали принудительно клапан отпирает.

Если у ж так хочется непременно на МК, то я бы подсчитывал число импульсов за единицу времени, например за 500 мс или вовсе за секунду, усреднял, проверял больше их стало или меньше и клапаном управлял бы. Все равно на тахометр выводить нужно не чаще раза в секунду а то и в две, иначе плясать будут младшие разряды. А клапан соотвественно щелкать зря.   
Один таймер в подсчет импульсов нужно запрограммировать, другой в таймер и стать по "тикам" в прерывании второго таймера, сколько насчитал первый, тут же обнулять первый и в основной программе уже все обрабатывать.
Но еще раз повторюсь, схема формирователя будет едва ли проще целиком аналогового формирователя, если не выводить обрпты, то я бы предпочел аналог.

0

11

Моя основная идея это тахометр, а ЭПХХ на 2 месте. Почему на МК? чтобы изменять параметры отключения клапана на разных оборотах.

0

12

На Тани 26 примерно так:

Код:
Config Timer0 = Counter , Edge = Rising                     ' Счет импульсов по спаду на входе T0 (PB6)
Config Timer1 = Timer , Prescale = 16384                    ' Раз в секунду
On Timer1 Timer1_int Nosave
Enable Interrupts
Enable Timer1
Dim Freq As Byte
......

Основной код, где что то поделываешь.
Частота в переменной Freq в виде количества импульсов в секунду. 
......
' Прерывание по таймеру
Timer1_int:
$asm
    Push R31                                                'сохраним регистры
    In R31 , Sreg
    Push R31

    LDI R31 , 12                                            'Загрузить таймер 256 - (4000000/16384)
    OUT Tcnt1 , R31

'---- Каждую секунду
    In R31 ,Tcnt0                                           ' Перепишем значение счетчика в переменную Freq
    STS {Freq}, R31
    clr R31
    OUT Tcnt0 , R31                                         ' и обнулим счетчик

    Pop R31
    Out Sreg , R31                                          'восстановим регистры
    Pop R31
    reti
$end Asm
Return

0

13

Спасибо, буду пробовать сложить все до кучи.

0

14

Привет IgorL !
Попробовал прикрепить твой код, но ничего не вышло.
Посмотри может у тебя получится.

Код:
$regfile = "attiny26.dat"
$crystal = 8000000

Config Portb = Output
Config Porta = Output
Config Porta.0 = Input

A Alias Porta.5
B Alias Porta.6
C Alias Portb.5
D Alias Portb.2
E Alias Portb.4
F Alias Porta.4
G Alias Porta.3                                             'Тут вписываем порты к которым подключены сегменты индикатора
Dig1 Alias Porta.2
Dig2 Alias Portb.3

Dim X As Byte , Z As Byte , Y As Byte , I As Byte , Cifri(4) As Byte , Chislo(8) As Long , Viv_peremennaya As Long , Perenoschikobsh_provodov As Byte , Perenoschiksegmentov As Byte , Temp_print As Long       ' задаем переменные
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse :    ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts : Enable Timer0                           ' разрешаем прерывания и таймер 0

Config Timer0 = Counter , Edge = Rising                     ' Счет импульсов по спаду на входе T0 (PB6)
Config Timer1 = Timer , Prescale = 16384                    ' Раз в секунду
On Timer1 Timer1_int Nosave
Enable Interrupts
Enable Timer1
Dim Freq As Byte
'......
Do
'Основной код, где что то поделываешь.
'Частота в переменной Freq в виде количества импульсов в секунду.
'......
' Прерывание по таймеру
Timer1_int:
$asm
    Push R31                                                'сохраним регистры
    In R31 , Sreg
    Push R31

    LDI R31 , 12                                            'Загрузить таймер 256 - (4000000/16384)
    Out Tcnt1 , R31

'---- Каждую секунду
    In R31 ,Tcnt0                                           ' Перепишем значение счетчика в переменную Freq
    STS {Freq}, R31
    clr R31
    Out Tcnt0 , R31                                         ' и обнулим счетчик

    Pop R31
    Out Sreg , R31                                          'восстановим регистры
    Pop R31
    reti
$end Asm
Incr Temp_print
Return
Loop
Pulse:
'Stop Timer0
Temp_print = Freq
For I = 1 To 4                                              ' цикл в котором разбивается переменная на отдельные числа от 0 до 9
Cifri(i) = Temp_print Mod 10                                ' заносим в масив последнюю цифру от числа Temp_print(12345678 mod 10 = 8)
Temp_print = Temp_print / 10                                ' отсекаем последнюю цифру от числа Temp_print (12345678/10=1234567)
Next                                                        ' подпрограмма прерываний таймера0
Perenoschikobsh_provodov = &HFF
Gosub Perenos
Incr X : If X > 3 Then X = 0
Perenoschiksegmentov = Lookup(cifri(x + 1) , Dta)
Reset Perenoschikobsh_provodov.x
Gosub Perenos
Return                                                      '  возвращаемся на место откуда прервали программу


Perenos:
Dig1 = Perenoschikobsh_provodov.1
Dig2 = Perenoschikobsh_provodov.0
A = Perenoschiksegmentov.5
B = Perenoschiksegmentov.7
C = Perenoschiksegmentov.3
D = Perenoschiksegmentov.1
E = Perenoschiksegmentov.0
F = Perenoschiksegmentov.6
G = Perenoschiksegmentov.4
Return

       Dta:                                                 '  таблица с данными о цифрах зажигает по порядку : 0123456789
       Data &HEF , &H8C , &HB7 , &HBE , &HDC , &H7E , &H7F , &HAC , &HFF , &HFE

0

15

Могу предложить исходник от бортового компьютера который я делал для скутера. Там и измерение скорости и километража и тахометр и напряжение бортовой сети и уровень топлива и 2 температуры (1 двигатель 2 за бортом) (уставки по температуре двигвтеля, превышения числа оборотов и превышения бортовой сети) время а также чтоб избавиться от замка зажигания сделано зажигание через пароль если в течении 10 секунд не вводиться пароль он отключает питание. Схема испробована и работает до сих пор. Информация выводится на 11 разрядов 7 сегментка

Отредактировано SyncMVGP (2012-12-14 23:44:41)

0

16

Если вас не затруднит, буду благодарен.

0

17

krasser написал(а):

Привет IgorL !
Попробовал прикрепить твой код, но ничего не вышло.
Посмотри может у тебя получится.

У меня то получится :) Кусок был из работающей программы.
Во первых ты подпрограмму прерывания засунул в основной цикл, это работать не будет конечно же.
Ну а не компилится у тебя из за массива типа long, который ты нигде больше не используешь.
И вообще, код, который я тебе привел в качестве примера считает число импульсов в секунду, а ты же хочешь в обороты в минуту, надо делить на 2 и умножать на 60 (естественно в коде нужно умножать на 30, что бы не делать лишнее деление ) и уже это число выводить.

Наверное тебе действительно проще будет разобраться по коду готового тахометра.

Отредактировано IgorL (2012-12-15 08:26:11)

0

18

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

0

19

Подскажите что не так, не становится на 0,

Код:
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32

' указываем конфигурацию подключения дисплея к портам МК
Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3

Config Lcd = 16 * 1                                         ' тип используемого дисплея

'настраиваем таймер в режим захвата по восходящему фронту

Config Timer1 = Timer , Prescale = 64 , Capture Edge = Rising

Dim Timercounter As Word
Dim Period As Single                                        ' период измеряемого сигнала
Dim F1 As Single
Dim F As Word                                               ' переменная для хранения значения частоты
'Dim Overflow As Byte

'On Timer0 Tm0_intsub
'On Timer1 Tm1_intsub

'Overflow = 0

Const T = 0.000008                                          ' примерное время в секундах за которое значение
                                                        ' счетчика увеличивается на 1
On Capture1 Zaxvat
Capture1 = 0
Timercounter = 0
Waitms 50
Enable Interrupts
Enable Capture1
'Start Capture1
'Cursor Off

Do                                                          ' главный цикл программы

 If Timercounter = 1 Then                                   ' проверка значения переменной

  F = 0                                                     ' если 0, то частота тоже 0

 Else                                                       ' в обратном случае высчитываем частоту

 Period = Timercounter * T                                  ' определяем период
 F1 = 15 / Period                                           ' считаем частоту
 F = Abs(f1)                                                ' округляем до целого
 Cls
            Cursor Off
            Lcd "Freq= "
            Lcd F
            Lcd " Hz"
            Locate 1 , 1
            Reset Timercounter
            Capture1 = 0
End If

'выводим показания на дисплей

'Cls


'Lcd "Freq: " ; F ; " Hz"



Waitms 100

Loop


Zaxvat:
 Timercounter = Timer1                                      ' копируем значение таймера в переменную
 Timer1 = 0                                                 ' обнуляем таймер

Return

http://s3.uploads.ru/t/X0lZk.png

0

20

'1 вычислять хотя бы так

Period = Timercounter                                  ' преобразовать в Single
Period = Period * T                                  ' определяем период
F1 = 15 / Period                                           ' считаем частоту
F1 = Abs(f1)                                                ' округляем до целого
F = f1                                                ' преобразовать в целое

'

0

21

F1 = Abs(f1)                                                ' это не округление

F = Int(f1)                                                'а это формирование целого

0

22

Подскажи еще, при работе, когда убираеш импульс нет сброса индикатора на 0

0

23

1 нет импульсов - нет прерываний - нет данных. Но это в идеале
на практике еще бывает шум и помехи на входе
т.е. требуется программная защита от пропадания сигнала,
например контролировать превышение длительности измеряемого периода
2 лучший алгоритм, когда счетчик считает не останавливаясь, а захватываешь
значения по переходу сигнала через нуль. этим же прерыванием.
я выкладывал на форум такие примеры, кажется

0

24

Подскажи пожалуйста где эти примеры!

0