HUD спидометр — от идеи до результата
Всем привет!
Давно ничего не писал, теперь это больше новостной ресурс, а не практический. Попробую подправить ситуацию. Расскажу про разработку HUD-спидометра. Хоть и не лазерная проекция, зато доступно и компактно.
Введение
Началось с того, что мне в руки попали большие 3.3» семисегментные индикаторы. Заказывали их для часов, которые так и не родились. Надо было 4 шт, в лоте 5, китаец положил шесть. Оценив размер, яркость и отражение от лобового стекла я решил — вот оно. Благодаря размеру не видно раздвоения изображения, а якрость позволяет использовать даже при прямом солнце. Сразу соглашусь, что у китайцев есть красивые готовые штуки, которые стоят совсем недорого (все цены на момент написания статьи) — от 1800р. Недостатков всего пара (закроем глаза на неспортивность такого решения):
1. Надо клеить плёнку на стекло — она хоть и прозрачная, но всё ж перекрывает обзор, а я не люблю, когда на стекле что-то мешает. Чуть откинулся, сдвинул кресло — и плёнку надо переклеивать. Ну и даже с плёнкой почти ничего не видно в солнечный день.
2. Можно плёнку не клеить, тогда циферки (они довольно мелкие) двоятся, а в солнце не видно вообще ничего.
Для затравки, результат без плёнки в любом месте стекла и даже днём:
Под катом обещаю много картинок, посредственное видео, код и текст — всё в лучших традициях.
Теория
Идея простая — за фиксированный промежуток времени считаем количество импульсов от датчика скорости. В качестве ЦП простой и доступный ATMega8.
Первая сложность оказалась в согласовании МК 5 В и индикаторов 7.5 В. Фантазия рисовала схему из пачки транзисторов и резисторов (7 элементов при динамической индикации). Из всех гуглов мне помогла всего одна статья про замену индикаторов в часах, жаль потерял её адрес. Пользуясь возможностью, передаю благодарность автору за идею использовать TD62783 (от 5 шт в лоте). Собственно, это драйвер семисегментных индикаторов, внутри транзисторная сборка.
Далее, DC/DC преобразователь. Сделал на MC34063, их у меня много, их я запас. Посчитал на калькуляторе, проверил тестером — 7.5 В. В полевых испытаниях оказалось мало, яркости не хватало, увеличил до 10 В.
Яркость регулируется исходя из показаний датчика света, который обычный китайский фоторезистор.
В итоге схема получилась такой:
Практика
Печатную плату мне развёл TopoR. Я воспользовался авторазмещением, хоть и зафиксировал большую часть элементов вручную. Должен же прогресс работать на меня, а не только я на прогресс. Получилась красота:
С шириной корпуса U4 промахнулся, пришлось дорисовывать дорожки и не припаивать 11ю ногу.
Как это выглядит в реале:
Следующий нежданчик подкрался в софте (не буду рассказывать, как я забыл отзеркалить 2 и 5, 4 — тут нечем гордиться). Сложнее была проблема такая: счётчик насчитывал нужное количество импульсов слишком долго. К примеру, при 60 км/ч подсчёт 60 импульсов с датчика скорости занимал больше секунды. Такое редкое обновление показаний меня не устроило.
Пришлось каждые пол измерения умножать на 2.
Линейное изменение яркости по сравнению с освещённостью не подошло: когда было чуть темнее — яркость оказывалась недостаточной, когда было почти темно — яркости было чересчур. Запустил эксель, построил график для разных математических функций. В итоге выбрал квадрат.
Код Bascom:
'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 'счётчик в основной цикл
Dim N As Byte 'счётчик в таймер
Dim Pwm_value As Integer 'яркость
Dim Speed As Integer , Speed_half As Integer , First_symbol As Integer , Second_symbol As Integer
Dim A As Integer 'разность Speed и Speed_half
Dim R1 As Word
Declare Sub Digit_indication(digit As Integer) 'вывод цифры
Const P = 500
Const T = 5000 'время горения одного индикатора
Const T1 = 1000 'время паузы для срабатывания PWM
Pwm_value = 5
Tcnt0 = 0 'счётчик
Do
Incr I
If I = 25 Then 'чтоб не перегружать МК
R1 = Getadc(7)
R1 = Sqr(r1) 'делаем гиперболу
R1 = R1 * 8
If R1 < 250 Then
Pwm_value = 250 - R1
Else
Pwm_value = 3 'минимальная яркость
End If
I = 0
End If
Gosub Indication
Loop
Indication:
If Speed < 3 Then 'если скорость 0 - не горит, 3 - защита от помех
Pwm_value = 0
End If
While Speed > 99 'т.к. всего 2 знака
Speed = Speed - 100
Wend
First_symbol = Speed / 10 'записали отдельно
Second_symbol = First_symbol * 10 'десятки
Second_symbol = Speed - Second_symbol 'отдельно еденицы
Pwm1b = 0
Pwm1a = 0
Waitus T1 'без паузы подмигивает
Call Digit_indication(first_symbol) 'и выводим цифры
Pwm1b = Pwm_value
Waitus T
Pwm1b = 0
Pwm1a = 0
Waitus T1 'без паузы подмигивает
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 = количество импульсов с датчика
Tcnt0 = 0 'сброс счётчика импульсов
End If
If N = 13 Then 'т.к. количество импульсов набегает слишком долго (редко меняются показания)
Speed_half = Tcnt0 * 2 'добавим удвоение
A = Speed - Speed_half
A = A And &B0111111111111111 'модуль
If A > 2 Then
Speed = Speed_half
End If
End If
Timer2 = 135 'корректировочка 135 логан
Return
В конце 135 — поправочный коэффициент, подбирал его для каждой машины индивидуально (135 это для логана, для соляриса было меньше — у всех разные датчики скорости).
Обещанное видео. За качество простите, снимал на кусок синей изоленты одной рукой, другой рулил:
Индикаторы не горят, когда скорость меньше 3 км/ч. Если скорость больше 99, то отображает без первого знака.
Бюджет:
ATMega8 — 200р за 5 шт — 40р
Индикаторы — 825р за 10 шт — 165р
TD62783 — 250р за 5 шт — 50р
Остальная рассыпуха у меня была, но в целом видно, что в 500р можно уложиться.
Больше рассказать и нечего. Получился большой красивый счётчик. Тестировал на Солярисе. На фокусе не удалось, на фокусе не оказалось датчика скорости. Чуть допилю программу для работы с OBD2 через ELM327.
Папка с проектом на Яндекс.Диске
Всем спасибо за внимание!