Стрелочный тахометр, тини25 и баском

Обсуждаем контроллеры компании Atmel.
Ответить
Slawakuzmich
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт мар 10, 2011 20:29:23
Откуда: Челяб. обл, Троицкий район
Контактная информация:

Стрелочный тахометр, тини25 и баском

Сообщение Slawakuzmich »

Маленькое предысловие. Я вообще считаю что тахометр для постоянного использования(на доске приборов) в авто-мото технике вещь сугубо условная. Если не настраивать по нему двигатель, то для езды точность его совершенно не нужна. Ну какая разница, сколько тысяч твой двигатель крутит при скорости 40 на 5 передаче, 2 тысячи или 20 тысяч оборотов в минуту. Главное - чтоб тахометр показывал от холостых оборотов до красной зоны. А там уже градуируй по своему желанию, хоть вместо цифр пиши названия"мкс мощ, мкс кр. м, макс экономия, холостые, желт зона" и подобное. То есть для езды нужно чтоб он легко читался(то есть нужна обязательно стрелка) и без всяких выкрутасов почти линейно махал ею.

В общем у меня и есть такая задача - поставить тахометр на мотоцикл. По вышесказанному понятно что точность не важна, главное - исправная работа. По этим условиям можно вроде бы воткнуть любой тахометр, хоть самый доступный от ваз 2106. Как в принципе я и пытался сделать в течении 5 лет. Но тут есть большие подводные камни. А именно: вибрация. Мотоцикл не машина, и нежный вазовский прибор от трясок и вибраций при агрессивном стиле езды приходит в негодность за пару месяцев. У меня было всё - и отвалившаяся стрелка, и отломившиеся радиодетали от электроплаты прибора, и даже различные разрушения самого механизма тахометра, от отломившейся катушки миллиамперметра до полного разваливания подвижных частей прибора. Пытался найти более совершенные приборы, но по условиям компоновки(в мой тахометр врезан электронный спидометр) идеально подходило только вазовское устройство. Но вот как то подвернулся механизм от другого мотоцикла который после долгих плясок с бубном влез на предназначенное место в чужом корпусе.
Вроде бы вот оно, красота - механизм который будет отлично работать в диких условиях 2х колёс, но возникла электрическая трабла, а именно сигнал управления тахометром. Если например в обычных вазовских классиках импульс на прибор берется с катушки зажигания, то хондовское чудо управлялось от блока управления двигателем путем подачи нужного напряжения на стрелку...
Как раз в эти моменты глаза мозолила маленькая плата от фонарика фос-3 с ATTINY25 на борту и мосфетом на ноге с аппаратным шимом. Решение лезло в голову только одно - соединить их вместе, миллиамперметр от мотоцикла хонда и attiny25, чем я и занялся.
Вроде бы в сети полно всяких тахометров и частотометров на Авэрках, но они все для вывода информации на дисплей, а мне нужен вывод на шим...
Пришлось писать программу самому без каких либо похожих примеров. Ну и как всегда столкнулся с трудностями. Основная- прибор стрелочный, значит должен быстро реагировать на изменение частоты, задержки даже в полсекунды тут неприятны. Тини 25 камушек без наворотов, а значит программа должна быть максимально простой, ну и точность прибора тоже вторична - главное чтоб при оборотах меньше 50 стрелка была на нуле и достигала миксимума при 8000 с достаточной линейностью по всей шкале.
Аппаратные возможности камушка довольно малы - 2 восьмибитных таймера, причем без режима захвата(но с шим), и одно внешнее прерывание INT0.
По нужным требованиям и возможностям МК алгоритм выходит только один - мерить время между импульсами, импульсы фиксировать с помощью прерывания INT0, переводить время в частоту(обороты) и выводить их на шим в сответствии с углом поворотом стрелки прибора.
Как уж мнего раз упоминал, ювелирная точность мне не нужна, а значить в в уже готовую электросхему фонарика ничего нового вносить не хочется, то для тактирования был выбран внутренний RC генератор 8мгц, для обеспечения быстродействия.
Так как таймеры в МК восьмибитные, а частота камушка довольно велика, то считать время между ипульсами по обычной схеме(просто копировать содержимое таймера в переменную) не выходит так как таймер успевает переполнится раз 100 при оборотах 2000 и предделителе таймера 64. Пришлось ввести еще пару переменных которые считают количество переполнений таймера.
Программу написал, смоделировал в протеусе - работает. Закинул в железо - Тоже работает, но сильно глючит.
Основной глюк -частые прыжки стрелки почти до конца шкалы при малых оборотах, при нарастании оборотов прыжки становятся меньше, при оборотх чуть выше середины шкалы прыжки переходят в плавание стрелки. И самый прикол в том что эти прыжки и плавания стрелки не на всём диапазоне оборотов, а только на некоторых значениях: например на оборотах до 1000 прыжки частые, до 1500 реже, до 2000 вообще нету, около 2500 снова появляются, при 3000 опять пропадают и так далее.
Второй глюк - после приветствия(когда при включении устройства стрелка плавно доходит до конца шкалы и обратно) после включения прерываний стрелка опять же делает скачок до середины шкалы.
И третий глюк - когда вместо датчика на вход импульсов просто подать низкий уровень (землю) стрелка прыгает до упора и держится там полсекунды, хотя программно вообще не должна.
И еще глюк с плаванием стрелки появлялся когда при отладке подключал ко входу тахометра генератор импульсов из атмеги8, и плавание было опять же при определенной частоте.
Уже месяц бьюсь с этими приколами, но ничего не могу сделать( . помогите пожалуйста, ткните носом где я напартачил...


Вот код :
Спойлер

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

$regfile = "attiny25.dat"
$crystal = 8000000
$hwstack=40
$swstack=16
$framesize = 32



   Config Timer1 = Timer , Prescale = 64                    'таймер 1 для подсчета тиков для измерения времени между импульсами
Config Timer0 = Pwm , Compare B Pwm = Clear Down , Prescale = 64       'таймер 0  - шим
Config Portb.1 = Output                                     'выход шима
Config Pinb.2 = Input                                       'вход для импульсов
Config Int0 = Rising


Dim A As Word

Dim Wtime As Single
Dim Timercounter As Byte
Dim Freq As Word
Dim Freq2 As Word
Dim S As Single
Dim N As Byte
Dim M As Word




 Disable Interrupts                                         'отключаем прерывания
 Disable Int0

For M = 1 To 260
  N = Lookup(m , Calibrovka)                                'подпрограмма махания стрелкой до упора и обратно при включении прибора."приветствие"
  Pwm0b = N
  Waitms 3
Next M
For M = 260 To 1 Step -1
  N = Lookup(m , Calibrovka)
  Pwm0b = N
  Waitms 3
Next M
 Pwm0b = 0

 On Int0 Stopbutton:
 On Timer1 Pulse:

enable Interrupts
Enable Int0                                                 ' включаем прерывания
Enable Timer1
Stop Timer1
Timercounter = 0
Freq = 41500


Do
 If A > 41500 Then                                          'если количество переполнений таймера1 велико(частота входящих импульсов меньше 3гц)
 Stop Timer1
 Freq = 41500                                               'то останавливаем таймер, присваеваем пременной фрек время которое равно 3 гц.

 Timer1 = 0                                                 'обнуляем таймер и его переполнения.
 A = 0
 End If

  Freq2 = Freq                                              'рисваиваем Значение Freq Переменной Freq2  - количество тиков таймера между одним импульсом

 If Freq2 < 400 Then                                        ' Если Количество Тиков Таймера Мало(частота Входящих Импульсов Более 350 Гц)
   Freq2 = 41500                                            'то скидываем частоту на минимум
 End If


  If Freq2 > 41500 Then                                     'если количество тиков велико(частота меньше 3 гц)
   Freq2 = 41500                                            'то  больше тики не увеличиваем
  End If

   Wtime = Freq2 * 8                                        'считаем время между импульсами в микросекундах(количество тиков умножаем на время одного тика)

   S = 1000000 / Wtime                                      'Считаем частоту импульсов в герцах путём деления одной секунды на время между импульсами.


  If S > 283 Then S = 283                                          'если частота выше 255гц и время между импульсами не слишком велико(частота ниже 350 гц)




M = S                                                       'присваиваем переменной частоту, для избавления от дробной части

N = Lookup(m , Calibrovka)                                  'в зависимости от частоты присваиваем переменной скважности шима калибровочную величину

Pwm0b = N
                                                             'присваиваем шиму нужную скважность
Loop


Stopbutton:                                                 'Программа Обработки Прерывания По Приходу Импульса

  Stop Timer1                                               'Останавливаем Таймер0

  Timercounter = Timer1                                     'присваеваем переменной таймерконтер количество тиков таймера.
  Freq = Timercounter + A                                   'складываем кол-во тиков таймера  и его переполнений и присваиваем это значение переменной freq   -
                                                            'получаем количество тиков таймера между импульсами.



 Timer1 = 0                                                 'Обнуляем Таймер0

  A = 0                                                     'Обнуляем Количество Переполнений Таймера

 Start Timer1                                               'Запускаем Таймер0

 Gifr = 64


Return

Pulse:                                                      'Программа Обработки Прерывания Переполнения Таймера '
 A = A + 255                                                'Считаем Количество Переполнений Таймера В Тиках


Return





End


  Calibrovka:
Data 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34
Data 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 72 , 73
Data 74 , 75 , 76 , 77 , 77 , 78 , 78 , 79 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 108 , 109
Data 109 , 110 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 123 , 124 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 142 , 143 , 144 , 145 , 146
Data 147 , 148 , 149 , 149 , 150 , 151 , 152 , 153 , 154 , 155 , 155 , 156 , 156 , 157 , 158 , 159 , 160 , 161 , 162 , 163 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 176 , 177 , 177 , 178 , 179
Data 180 , 181 , 182 , 182 , 183 , 183 , 184 , 185 , 186 , 187 , 188 , 188 , 189 , 189 , 190 , 191 , 192 , 193 , 194 , 195 , 195 , 196 , 196 , 197 , 198 , 199 , 200 , 201 , 201 , 202 , 202 , 203 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208
Data 209 , 210 , 211 , 212 , 212 , 213 , 214 , 215 , 216 , 217 , 218 , 219 , 220 , 220 , 221 , 221 , 222 , 223 , 224 , 226 , 227 , 229 , 230 , 232 , 234 , 235 , 236 , 237 , 238 , 239 , 239 , 240 , 240 , 241 , 242 , 243 , 244 , 246 , 247 , 249
Data 250 , 251 , 252



схема протеуса - во вложении

Если кто то решит вникнуть в код, то сразу оговорюсь - переменную s я не округляю а присваиваю к другой переменной - так происходит избавление от дробной части с минимальным объёмом флеш памяти, если использовать команду типа ROUND и подобные - объем программы сразу занимает на 20 % больше и не влезает в лимит флэша
Вложения
ъ.rar
(14.45 КБ) 149 скачиваний
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Стрелочный тахометр, тини25 и баском

Сообщение akl »

По мне, Вы напрасно делаете операцию деления, за которой следует выбор табличного значения. Можно ведь составить таблицу, исходя из накопленных тактов за период.
ATtiny25 маленький, но не такой уж и беспомощный камень. Например, он может формировать ШИМ без прерывания. Ему нужно в любой момент загрузить OCR0A и всё. Т.к. таймер Т0 всё равно работает непрерывно, логичнее использовать его переполнение для наращивания старшей части переменной А. Младшая часть А фиксируется при активном фронте INT0. Т.е. таймер Т1 вообще выпадает из программы.
Ограничивать размер стека обязательно для BASCOM или нет?
Переполнение таймера наступает каждые 256 тактов
Pulse: 'Программа Обработки Прерывания Переполнения Таймера '
A = A + 256 'Считаем Количество Переполнений Таймера В Тиках
; A = A + 255 'Считаем Количество Переполнений Таймера В Тиках
Slawakuzmich
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт мар 10, 2011 20:29:23
Откуда: Челяб. обл, Троицкий район
Контактная информация:

Re: Стрелочный тахометр, тини25 и баском

Сообщение Slawakuzmich »

Не вариант. Во первых таймер при взятии из него знаяения нужно обнулять, а если его обнулить то шима не получишь. По таблице данных- если не переводить тики в частоту то я тогда не знаю как в зависимости от количества тиков брать нужное значение из таблицы.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Стрелочный тахометр, тини25 и баском

Сообщение akl »

Slawakuzmich писал(а):... таймер при взятии из него знаяения нужно обнулять, а если его обнулить то шима не получишь.
Можно и так, но DS на ATtiny25 рассказывает и о других режимах работы таймера T0.
PWM_T0.GIF

Slawakuzmich писал(а):...если не переводить тики в частоту то я тогда не знаю как в зависимости от количества тиков брать нужное значение из таблицы.
Например, полученное значение прогоняется по такой таблице; точка сравнения однозначно будет определять значение PWM.

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

RPM_50: 60*K*Fo/256/50
.
.
.
RPM_8000: 60*K*Fo/256/8000
Slawakuzmich
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт мар 10, 2011 20:29:23
Откуда: Челяб. обл, Троицкий район
Контактная информация:

Re: Стрелочный тахометр, тини25 и баском

Сообщение Slawakuzmich »

Все равно это переполнение таймера, а нужно же вместо переполнения считать его тики. Хотя если предделитель уменьшить чтоб переполнение было например каждые 100 микросекунд то можно и так. Но тогда период шима будет маловат.
По таблице все равно не понял- проверять значение по условию? Типа команды IF или CASE?
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Стрелочный тахометр, тини25 и баском

Сообщение akl »

У Вас всегда запущен Т0, при активном фронте INT0 считываете TCNT0, запоминаете его значение как начальное, при следующем активном фронте INT0 вновь считываете TCNT0, добавляете число накопленных переполнений, вычитаете начальное значение и получаете переменную А. Далее последовательно сравниваете полученное значение с табличными данными и наращиваете счетчик положения. Нашли значение таблицы, при котором произошло сравнение и отправили значение счётчика в буфер OCR0A. Обнулили старшую часть переменной А, таким образом приняв её за начальную. Далее таймер Т0 сам аппаратно формирует ШИМ.
Slawakuzmich
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт мар 10, 2011 20:29:23
Откуда: Челяб. обл, Троицкий район
Контактная информация:

Re: Стрелочный тахометр, тини25 и баском

Сообщение Slawakuzmich »

Ага, принцип понял. А как программно реализовать сравнение с табличными данными? например в результате таймер нам насчитал 2000 тиков. сравниваем это число с первым значением в таблице командой IF. Если совпадения нет то наращиваем счетчик, и переходим к следущему значению. Я вижу это так:
If a=100 then goto exit else b=b+1
if a=200 then goto exit else b=b+1
...
if a=2000 then goto exit else b=b+1

Exit:
ocr1a =b
return

только если так писать сравнение то памяти ни в одном контроллере не хватит
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Стрелочный тахометр, тини25 и баском

Сообщение akl »

Не знаю как это будет выглядеть на BASCOM.
очистить счётчик PWM
* сравнить полученное значение с табличным, выбранным по номеру счётчика
если меньше, нарастить счетчик и вернуться на *
в противном случае, занести значение счётчика в OCR0A.
Slawakuzmich
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт мар 10, 2011 20:29:23
Откуда: Челяб. обл, Троицкий район
Контактная информация:

Re: Стрелочный тахометр, тини25 и баском

Сообщение Slawakuzmich »

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

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

Спойлер

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

$regfile = "attiny25.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32



   Config Timer1 = Timer , Prescale = 4                     'таймер 1 для подсчета тиков для измерения времени между импульсами
Config Timer0 = Pwm , Compare B Pwm = Clear Down , Prescale = 64       'таймер 0  - шим
Config Portb.1 = Output                                     'выход шима
Config Int0 = Falling               'прерывание по спаду
Config Pinb.2 = Input                            'вход
Set Portb.2                                      'подтягиваем резистор ко входу

Dim A As Word

Dim Wtime As Single
Dim Timercounter As Word
Dim X As Bit
Dim S As Single
Dim N As Byte
Dim M As Word




  On Timer0 Obnow:
  On Int0 Stopbutton:
 On Timer1 Pulse:


 Disable Interrupts                                         'отключаем прерывания
 Disable Int0

For M = 1 To 280
  N = Lookup(m , Calibrovka)                                'подпрограмма махания стрелкой до упора и обратно при включении прибора."приветствие"
  Pwm0b = N
  Waitms 3
Next M
For M = 280 To 1 Step -1
  N = Lookup(m , Calibrovka)
  Pwm0b = N
  Waitms 3
Next M
Pwm0b = 30
Waitms 3


 Enable Interrupts
Enable Int0
Enable Timer1
Enable Timer0
Stop Timer1
Timercounter = 1
X = 0







Do


If X = 0 And Timercounter > 26 Then                      'если бит превышеня сброшен и количество тиков больше чем 26(частота меньше 300ГЦ) то
   Wtime = Timercounter * 128                               'считаем время между импульсами в микросекундах(количество тиков умножаем на время одного тика)
     S = 1000000 / Wtime                                      'Считаем частоту импульсов в герцах путём деления одной секунды на время между импульсами.
   M = S                                          'округляем частоту
N = Lookup(m , Calibrovka)                                  'присваиваем переменной n число скважности в зависимости от таблицы


Else                                              'иначе если частота импульсов меньше 15гц или выше300гц
N = 10                                             ' скважность шима устанавливаем в 10

End If


Loop


Stopbutton:                                       'обработка прерывания INT0

  Stop Timer1                                        'останавливаем таймер
  Timercounter = A                                   ' присваиваем меременной количество тиков
  Timer1 = 0                                                'Обнуляем Таймер0
  X = 0                                                       'обнуляем бит превышения
  A = 0                                                     'Обнуляем Количество Переполнений Таймера
  Start Timer1                                               'Запускаем Таймер0
 Return

Pulse:                                                    'прерывание таймера1
 Incr A                                                    'инкреминируем переменную
 If A > 780 Then X = 1                                     'если количество тиков больше 20 герц то устанавливаем бит превышения
 Return

Obnow:                                                   'прерывание таймера шима
 Pwm0b = N                                               'присваиваем шим переменную
Return

End


  Calibrovka:
Data 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34
Data 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 72 , 73
Data 74 , 75 , 76 , 77 , 77 , 78 , 78 , 79 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 108 , 109
Data 109 , 110 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 123 , 124 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 142 , 143 , 144 , 145 , 146
Data 147 , 148 , 149 , 149 , 150 , 151 , 152 , 153 , 154 , 155 , 155 , 156 , 156 , 157 , 158 , 159 , 160 , 161 , 162 , 163 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 176 , 177 , 177 , 178 , 179
Data 180 , 181 , 182 , 182 , 183 , 183 , 184 , 185 , 186 , 187 , 188 , 188 , 189 , 189 , 190 , 191 , 192 , 193 , 194 , 195 , 195 , 196 , 196 , 197 , 198 , 199 , 200 , 201 , 201 , 202 , 202 , 203 , 204 , 205 , 205 , 206 , 206 , 207 , 207 , 208
Data 209 , 210 , 211 , 212 , 212 , 213 , 214 , 215 , 216 , 217 , 218 , 219 , 220 , 220 , 221 , 221 , 222 , 223 , 224 , 226 , 227 , 229 , 230 , 232 , 234 , 235 , 236 , 237 , 238 , 239 , 239 , 240 , 240 , 241 , 242 , 243 , 244 , 246 , 247 , 249
Data 250 , 251 , 252
Ответить

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