Введение
Началось с того, что мне в руки попали большие 2.3" семисегментные индикаторы. Заказывали их для часов, которые так и не родились. Надо было 4 шт, в лоте 5, китаец положил шесть. Оценив размер, яркость и отражение от лобового стекла я решил — вот оно. Благодаря размеру не видно раздвоения изображения, а якрость позволяет использовать даже при прямом солнце. Сразу соглашусь, что у китайцев есть красивые готовые штуки, которые стоят совсем недорого (все цены на момент написания статьи) — от 1800р. Недостатков всего пара (закроем глаза на неспортивность такого решения):
1. Надо клеить плёнку на стекло — она хоть и прозрачная, но всё ж перекрывает обзор, а я не люблю, когда на стекле что-то мешает. Чуть откинулся, сдвинул кресло — и плёнку надо переклеивать. Ну и даже с плёнкой почти ничего не видно в солнечный день.
2. Можно плёнку не клеить, тогда циферки (они довольно мелкие) двоятся, а в солнце не видно вообще ничего.


Под катом обещаю много картинок, посредственное видео, код и текст — всё в лучших традициях.

Теория
Идея простая — за фиксированный промежуток времени считаем количество импульсов от датчика скорости. В качестве ЦП самый простой контроллер — AtMega8.
Первая сложность оказалась в согласовании МК 5 В и индикаторов 7.5 В. Фантазия рисовала схему из пачки транзисторов и резисторов (7 элементов при динамической индикации). Из всех гуглов мне помогла всего одна статья, жаль потерял её адрес. Пользуясь возможностью, передаю благодарность автору за идею использовать TD62783 (от 5 шт в лоте). Далее, DC/DC преобразователь. Сделал на MC34063, их у меня много, их я запас. Посчитал на калькуляторе, проверил тестером — 7.5 В. В полевых испытаниях оказалось мало, увеличил до 10 В резистором (на схеме не показан).
В итоге схема получилась такой:

Практика
Печатную плату мне развёл TopoR. Я воспользовался авторазмещением, хоть и зафиксировал большую часть элементов вручную. Должен же прогресс работать на меня, а не только я на прогресс. Получилась красота (это не ирония, по мне так действительно красота):

Как это выглядит в реале:



Следующий нежданчик подкрался в софте (не буду рассказывать, как я забыл отзеркалить 2 и 5, 4 — тут нечем гордиться). Сложнее была проблема такая: счётчик насчитывал нужное количество импульсов слишком долго. К примеру, при 60 км/ч подсчёт 60 импульсов с датчика скорости занимал больше секунды. Такое редкое обновление показаний меня не устроило.
Пришлось каждые пол измерения умножать на 2.
'HUD-speedometer
'17/01/2016
'21/01/2016
'v1.1

$regfile = "m8adef.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Config Portb = Output
Config Portc = Output
Config Portd = Output
Config Portd.4 = Input
Portd.4 = 1
Config Timer0 = Counter , Edge = Falling
Config Timer1 = Pwm , Pwm = 8 , Compare_a_pwm = Clear_up , Compare_b_pwm = Clear_up , Prescale = 8
Config Timer2 = Timer , Prescale = 1024
On Timer2 Mytimer2
Enable Interrupts
Enable Timer2
Config Adc = Single , Prescaler = Auto , Reference = Internal
Start Adc

Dim I As Byte 'n??o?ee a iniiaiie oeee
Dim N As Byte 'n??o?ee a oaeia?
Dim Pwm_value As Integer 'y?einou
Dim Speed As Integer , Speed_half As Integer , First_symbol As Integer , Second_symbol As Integer
Dim A As Integer '?aciinou Speed e Speed_half
Dim R1 As Word
Declare Sub Digit_indication(digit As Integer) 'auaia oeo?u

Const P = 500
Const T = 5000 'a?aiy ai?aiey iaiiai eiaeeaoi?a
Const T1 = 1000 'a?aiy iaocu aey n?aaaouaaiey PWM
Pwm_value = 5
Tcnt0 = 0 'n??o?ee

Do
Incr I
If I = 25 Then '?oia ia ia?aa?o?aou IE
R1 = Getadc(7)
R1 = Sqr(r1) 'aaeaai aeia?aieo
R1 = R1 * 8
If R1 < 250 Then
Pwm_value = 250 - R1
Else
Pwm_value = 3 'ieieiaeuiay y?einou
End If
I = 0
End If
Gosub Indication
Loop

Indication:
If Speed < 3 Then 'anee nei?inou 0 - ia ai?eo, 3 - caueoa io iiiao
Pwm_value = 0
End If
While Speed > 99 'o.e. anaai 2 ciaea
Speed = Speed - 100
Wend
First_symbol = Speed / 10 'caienaee ioaaeuii
Second_symbol = First_symbol * 10 'aanyoee
Second_symbol = Speed - Second_symbol 'ioaaeuii aaaieou
Pwm1b = 0
Pwm1a = 0
Waitus T1 'aac iaocu iiaieaeaaao
Call Digit_indication(first_symbol) 'e auaiaei oeo?u
Pwm1b = Pwm_value
Waitus T
Pwm1b = 0
Pwm1a = 0
Waitus T1 'aac iaocu iiaieaeaaao
Call Digit_indication(second_symbol)
Pwm1a = Pwm_value
Waitus T
Return

Sub Digit_indication(digit As Integer)
Select Case Digit
Case 0:
Portd.0 = 0
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Portc.4 = 1
Portc.5 = 1
Case 1:
Portd.0 = 0
Portc.0 = 1
Portc.1 = 0
Portc.2 = 0
Portc.3 = 0
Portc.4 = 0
Portc.5 = 1
Case 2:
Portd.0 = 1
Portc.0 = 0
Portc.1 = 1
Portc.2 = 1
Portc.3 = 0
Portc.4 = 1
Portc.5 = 1
Case 3:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 1
Portc.2 = 0
Portc.3 = 0
Portc.4 = 1
Portc.5 = 1
Case 4:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 0
Portc.2 = 0
Portc.3 = 1
Portc.4 = 0
Portc.5 = 1
Case 5:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 1
Portc.2 = 0
Portc.3 = 1
Portc.4 = 1
Portc.5 = 0
Case 6:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Portc.4 = 1
Portc.5 = 0
Case 7:
Portd.0 = 0
Portc.0 = 1
Portc.1 = 0
Portc.2 = 0
Portc.3 = 0
Portc.4 = 1
Portc.5 = 1
Case 8:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Portc.4 = 1
Portc.5 = 1
Case 9:
Portd.0 = 1
Portc.0 = 1
Portc.1 = 1
Portc.2 = 0
Portc.3 = 1
Portc.4 = 1
Portc.5 = 1
End Select
End Sub

Mytimer2:
Incr N
If N = 26 Then
N = 0
Speed = Tcnt0 'Speed = eiee?anoai eiioeunia n aao?eea
Tcnt0 = 0 'na?in n??o?eea eiioeunia
End If
If N = 13 Then 'o.e. eiee?anoai eiioeunia iaaaaaao neeoeii aieai (?aaei iaiy?ony iieacaiey)
Speed_half = Tcnt0 * 2 'aiaaaei oaaiaiea
A = Speed - Speed_half
A = A And &B0111111111111111 'iiaoeu
If A > 2 Then
Speed = Speed_half
End If
End If
Timer2 = 135 'ei??aeoe?iai?ea 135 eiaai
Return


Мои тщательно описанные комментарии перекракозабрались.
Обещанное видео:

youtu.be/s9eSjLEi_6M

Больше рассказать и нечего. Получился большой красивый счётчик. Тестировал на Солярисе. На фокусе не удалось, на фокусе не оказалось датчика скорости. Чуть допилю программу для работы с OBD2 через ELM327. Всем спасибо за внимание!
Поделиться с друзьями
-->

Комментарии (0)