В общем у меня и есть такая задача - поставить тахометр на мотоцикл. По вышесказанному понятно что точность не важна, главное - исправная работа. По этим условиям можно вроде бы воткнуть любой тахометр, хоть самый доступный от ваз 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 % больше и не влезает в лимит флэша