Получил в подарок очередной гаджет:
«электронный бэйджик» от Master KIT. Это LED дисплейчик 12х38 точек + USB/ СОМ шнурок. В память дисплея можно загрузить до 8-ми сообщений, общим количеством до 512 символов 8х12. К каждому сообщению можно применить один из 6-ти видов анимации, дополнительно включить мигание или бегушую окантовку экранчика. Единственной управляющей кнопочкой можно переключаться между сообщениями и менять яркость экранчика. Прилагающееся ПО позволяет пользоваться различными шрифтами, вставлять в текст имеющиеся в библиотеке символы и создавать свои.
Игрушка довольно дорогая, сам бы такую не купил. Но, раз уж подарили, решил использовать в хозяйстве, т.е.,например, прикрепить к роботу, чтобы выводить на дисплей тестовую инфу. Единственное, что для этого требуется – расшифровать протокол передачи данных в контроллер дисплея. Немного погуглил, ничего не нашел. И, вооружившись
анализатором СОМ порта, разобрался сам. Результаты изысканий прилагаю ниже. Может кому пригодяться. Надеюсь, что не украл «ноу хау» у мастеркитовцев, тем более, что сущность вещицы явно китайская.
Итак, дисплей не имеет встроенной библиотеки символов, т.е. каждый раз надо загружать 12 байт на каждый символ строки. С одной стороны, это снимает ограничения на представления символов. С другой стороны, для загрузки длинной строки, дисплей гаснет секунд на 10. Единственно возможная скорость передачи 1200 бод.
Описание протокола:
1. Протокол односторонний, т.е. от дисплея никаких ответов не требуется.
2. Вначале передается ключевое слово Hello
3. Потом идет какой-то непонятный байт, который не всегда =0, но на что он влияет выяснить так и не удалось. Я оставляю его =0.
4. Затем идут 8 байт настройки анимации сообщений (старший бит- включение мигания, следующие 3 бита – скорость анимации, следующий бит – включение бегущей рамки по краю экранчика, и младшие 3 бита – это тип анимации
5. Далее идут 8 слов по 4 байта, определяющих разбивку памяти на 8 сообщений. Первое целое число (2 байта) должно содержать общее количество предыдущих символов в предыдущих сообщениях+ 0х0800 (для первого сообщения всегда =0х0800 т.к. предыдущих символов нет), второе целое число – это количество символов в этом сообщении. Ограничений на количество символов в одном сообщении вроде нет, но редактор прилагаемой программки ограничивает ввод 315 символами.
6. Далее идет, собственно, карта памяти. Каждый символ кодируется так:
Вложение:
Комментарий к файлу: «1» светятся, «0» отдыхают.
1.jpg [ 22.71 КиБ | Просмотров: 20291 ]
Все сообщения строятся друг за другом по порядку в одну общую строку. Передается сначала верхний ряд (байт) для каждого символа этой строки, затем следующий и так до 12-го. Логичнее было бы передать первый символ целиком (12 байт), потом перейти ко второму и так далее. Но, видимо, контроллеру дисплея так удобнее считывать...
В принципе достаточно передать только то количество символов, которое требуется, т.к. никакой фиксированной длины пакета или контрольных сумм не предусмотрено.
В заключение короткая программа на Python с примерами функций, обеспечивающих передачу данных на дисплей:
Код:
import serial # класс для работы с последовательным портом
sym_cod_8x12={'1':(0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00),
'2':(0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00),
'3':(0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0xc6,0x7c,0x00,0x00),
'4':(0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x1e,0x00,0x00),
'5':(0x00,0xfe,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00),
'6':(0x00,0x7c,0xc6,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0x7c,0x00,0x00),
'7':(0x00,0xfe,0xc6,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00),
'8':(0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0x7c,0x00,0x00),
'9':(0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0xc6,0x7c,0x00,0x00),
'0':(0x00,0x7c,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00),
'°':(0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
'C':(0x00,0x7c,0xc6,0xc6,0xc0,0xc0,0xc0,0xc6,0xc6,0x7c,0x00,0x00)} # Пример кодировки символов
Msg_Speed=4 # Скорость анимации
Msg_ToLeft=0 # Эффекты анимации
Msg_ToRight=1
Msg_ToUp=1
Msg_ToDown=3
Msg_Freeze=4
Msg_PileUp=5
Msg_Curtain=6
Msg_Animation=7
Msg_Flash=8
Msg_Lamp=8
Led_NumSim=0 #общее количество символов во всех строках
Led_StrNow=1 #номер текущей строки
Led_Text='' #текст, объединяющий все строки
Led_config=[0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00] # массив настройки анимации для 8-ми сообщений
Led_msg=[0x08,0x00,0x00,0x01,0x08,0x01,0x00,0x00,
0x08,0x01,0x00,0x00,0x08,0x01,0x00,0x00,
0x08,0x01,0x00,0x00,0x08,0x01,0x00,0x00,
0x08,0x01,0x00,0x00,0x08,0x01,0x00,0x00] #массив распределение символов по строкам (изначально 1 символ в первом сообщении)
Led_map=[] #массив карты памяти дисплея
def led_ajust(StrNum=1,Speed=Msg_Speed,AnimType=Msg_ToLeft,Flash=0,Lamp=0): #настройка анимации определенного сообщения
global Led_config
Led_config[StrNum]=(Speed<<4 | Flash) | (AnimType | Lamp)
def led_str(StrNum=1,Lstr='0'): #ввод текста в определенное сообщение
global Led_msg
global Led_NumSim
global Led_Text
global Led_StrNow
lenstr=len(Lstr)
if lenstr<1: return False #текст должен содержать хотя бы 1 символ
if lenstr>255: return False #количество символов одной строки не должно превышать 255
if lenstr+Led_NumSim>512: return False #общее количество символов не должно превышать 512
if StrNum>Led_StrNow+1: return False #строки должны вводиться последовательно: 1,2,3...
if StrNum>8: return False #максимальное количество строк =8
if StrNum==1: Led_Text='' #сброс текста всех строк при повторном вводе первой строки
Led_Text+=Lstr
Led_StrNow=StrNum
Led_NumSim+=lenstr
Led_msg[4*StrNum-1]=lenstr #настройка распределения памяти по строкам
for n in range(StrNum,8):
Led_msg[4*n+1]=Led_NumSim
return True
def led_map_gen(): # генерация карты памяти дисплея
global Led_map
global Led_Text
global sym_cod_8x12
Led_map=[]
for n in range(11): #для каждого из 12 байт кодировки символа....
for sym in Led_Text:
sym_cod=sym_cod_8x12[sym]
Led_map.append(sym_cod[n]) #заносим его в память, последовательно проходя все символы всех сообщений.
def led_print(NumPort=8): #вывод полученных данных в последовательный порт
global Led_config
global Led_msg
global Led_map
led_map_gen()
ser=serial.Serial() # настройка порта
ser.port=NumPort-1
ser.baudrate =1200
ser.stopbits=2
ser.parity='N'
ser.bytesize=8
ser.open()
ser.write('Hello'.encode('latin1'))
ser.write(Led_config)
ser.write(Led_msg)
ser.write(Led_map)
ser.close()
# основная процедура
led_ajust(AnimType=Msg_Freeze) #настроим первую строку на статичное изображение
if led_str(1,'25°C'): led_print() # выведем значение температуры на дисплей
Переданный дамп данных:
Код:
48 65 6c 6c 6f 00 44 30 30 30 30 30 30 30 00 08 Hello.D0000000..
00 00 04 08 04 00 00 08 04 00 00 08 04 00 00 08 ................
04 00 00 08 04 00 00 08 04 00 00 08 04 00 00 00 ................
00 00 00 7c fe 18 7c c6 c0 24 c6 06 c0 24 c6 0c ...|þ.|ÆÀ$Æ.À$Æ.
fc 18 c0 18 06 00 c0 30 06 00 c0 60 06 00 c6 c6 ü.À...À0..À`..ÆÆ
c6 00 c6 fe 7c 00 7c 00 00 00 00 Æ.Æþ|.|....
Вложение:
Комментарий к файлу: Результат
Badge.JPG [ 353.63 КиБ | Просмотров: 18929 ]