Термопринтер из старого терминала (кассового аппарата)
- Войдите на сайт для отправки комментариев
Чт, 05/09/2019 - 00:26
Всем привет! Имеется на руках дохлый терминал Ingenico I5100. Интересного в нем LCD дисплей wd-h12069-6ylyd и Термопринтер ELPM sen701130c. Очень интересно подключить термопринтер к Ардуино. Сам терминал признаков жизни не подает. По этому голическим анализатором (или осциллографом) смотреть нечего...
Что удалось узнать:
- скорость печати (ЛПС) 65 мм / С (при 7.2 В постоянного тока)
- ширина печати (мм) и 48 мм (384 точек),
- импульсный блок питания напряжением 5 ~ 8.5 отрицательного полюса источника питания логики 5В + 5%
- Определение температуры печатающей головки - термистор
(Перевод с Китайского) http://www.youboy.com/s502527612.html
Сама печатающая головка имеет маркировку gp16b337 (в Гугле пусто)
Немного прошелся тестером по плате, получилась (примерно) следующая распиновка:
Steper Drive Steper Drive Steper Drive Steper Drive Оптопара (датчик наличия бумаги) Оптопара (датчик наличия бумаги) GND VDD VDD VDD sen723379d RAM FLASH MODULE gnd gnd gnd Соединен с 18 и идет на Триггер Шмидта (пин 6Y) sen723379d RAM FLASH MODULE +3.3 Соединен с 15 и идет на Триггер Шмидта (пин 6Y) gnd gnd gnd sen723379d RAM FLASH MODULE sen723379d RAM FLASH MODULE VDD VDD VDD
Где:
VDD - подключается (через мосфет) напрямую к блоку питания
15-й и 18-й соединены вместе
sen723379d RAM FLASH MODULE - "Мозги" терминала. Запаянная коробочка и залитая эпоксидкой....
Примерная схема с некоторыми компонентами:
Из распиновки складывается подозрение что принтер подключается по i2c...
Может у вас есть какие-то мысли и идеи как его запустить?
Фото выложу чуть позже.
Ура! распиновку победил! Вот результат:
Вот основной код вывода картинки:
Привет! Этя Коля с ютуба (ты используешь мой скетч). Посмотри 2 вопроса - первый - подсчитай количество точек в строке (под лупой, хотя бы примерно) - мой скетч рассчитана на 128, возможно у тебя в три раза больше. Попробуй отрисовать ОДНУ точку процедурой
Point(X,Y,1);
//X,Y,Color - 1/0 - я не помню какая черная 1 или 0, попробуй два варианта
Поптом посмотрим что получается
Точек у меня однозначно больше - 384.
Я как раз все разобрал :))) а то у меня все на "соплях" висело, решил нормально все собрать и перепаять. Соберу, проверю, отпишусь.
Если точек больше, то просто за раз выводится 3 строки - это легко поправимо
В общем, промучился я с весь день...
Если рисовать только 1 точку, или линию, или что-либо, то изображение дважды дублируется. Получается не 1 изображение, а три. Немного поигравшись с временем прожига выяснил что это не расслоение, а именно дублирование. Печатающая головка похоже неравномерно все пропечатывает, из-за чего копии казались слегка разными (и я подумал что изображение расслаивается).
Настроил печать, теперь по высоте изображение получается нормальным. Печать ускорилась в 2 раза, но все равно немного медленно печатает: более 70 мс на каждую строку длинной в 120 точек. Вот код:
Осталось только разобраться с некоторыми проблемами:
1) почему происходит дублирование. Кстати, при печати картинки добавляется еще некоторые артефакты в самой первой строке. Все. Дублирование убрал. В строке
for
(
int
i=0; i<16; ++i) 16 заменил на 48.
2) изображение получается отзеркаленым по горизонтали
3) Еще не могу разобраться в алгоритме передачи данных на головку. Пробовал разобраться и вручную вывести что-нибудь, но ничего не вышло.
Можете мне в этом помочь? Что означает эта строчка:
pinValue = bitRead(bitmap[l*16+15-i], j) != 0 ? HIGH : LOW;
Что означает эта конструкция: bitmap[l*16+15-i] и вот эта: != 0 ? HIGH : LOW ?
Я когда-то делал побайтовое чтение из памяти (шрифт), эта функция у меня выглядела так:
Картинка состоит из одномерного массива элементов в шестнадцатиричном виде, получается если преобразовать одно число из шестнадцатиричного вида в двоичный получим ряд единичек - например FF=11111111, F0=11110000.
Каждая единичка или ноль - это точка на бумаге или пропуск.
Это проверяется вот этой процедурой, привожу сразу примеры с конкретными числами (берутся из массива bitmap[i]), а не переменными: bitRead(F0, 1)=1, bitRead(F0, 5)=0
pinValue - это значение на выходе для сдвигового регистра - они проталкиваются по очереди, как паровозик.
l - количество элементов в масиве картинки
i - от 1 до 16 - количество бит в двухзначном шестнадцатиричном числе
j - от 1 до 8 - количество символов массива для образование строки из 128 точек пачками по 16 точек - надо прочитать 8 элементов массива
l*16+15-i - это вычисляется номер бита в элементе массива картинки, нагромождение с числом 15 связанао скорее всего с тем, что линии по 16 точек шли правильно, но в каждом блоке из 16 точек, точки стояли зеркально по оси Х
Немного все же в этом запутался. Проблема в том что печать получается в зеркальном виде (на качество печати не обращайте внимания, нужно почистить головку):
Верхняя картинка печатается "правильно", то есть морда панды с левой стороны, но каждый блок из 8-ми пикселей отражен по горизонтали. Чтение производилось так:
Вторая печать прошла красиво, но в зеркальном отражении... Чтение было стандартной командой:
pinValue = bitRead(bitmap[l*48+47-i], j) != 0 ? HIGH : LOW;
Как исправить переворачивание блоков по 8 пикселей? Эта часть не влияет?: != 0 ? HIGH : LOW;
С рисованием все еще хуже (и с прописью текста тоже). Вот здесь происходит именно расслаивание. Текст не смогу показать, сильно мелко, но он расслаивается на всю длину печати (384 точки...). Как это исправить?
вот так вот свою панду печатайте
Теперь немного пояснений, что какой индекс значит. Пусть простит меня Nkl-777 (типа автор кода?) - но то что он понаписал в сообщении #7 - лучше не читать, он похоже сам запутался :)
Значит так, в коде #9
l = 134 - размер картинки по вертикали в пикселях
i = 48 - размер картинки по горизонтали в байтах, то есть ширина картинки в писелях = 8*i
j - число бит в байте, всегда 8
Имейте в виду, что размеры циклов l =134 и i =48 - относится только к этой конкретной картинке.
Вообще, процедуру бы надо переписать правильно, чтобы она принимала высоту битмапа H и ширину W в качестве парметров, а уже из них вычисляла все нужные индексы.
Вы не поверите, но правда автор кода. Писал его год назад. Я вообще не хотел учавствовать в этом обсуждении - потому что это как испорченный телефон - не имея аппарата в руках, что-то пытаться исправить. Чисто из уважения к ТС, поднял тему. Но нет так нет - вы больший специалист, а я новичек. Удачи вам!
forfrends - Попробуй в этом цикле for (int j = 0; j < 8; ++j) читать биты с другой стороны for (int j = 7; j>-1; --j)
в коде b707 - ошибка, номерация у бит идет с 0 до 7
forfrends - выведешь картинку, все остальные объекты начнут работать - точки, прямые и текст сначала переносятся в массив, а потом каждый раз массив печатается, гоняя ленту вперед-назад.
Только добавь количество пустых элементов в массив битмап, или укажи его длину. Так же поправь ширину и высоту картинки (рабочего поля) - у меня стоит поле 128х128.
Я занимаюсь этими проектами ради удовольствия - 2-3 раза в год, начал с приборной панели на мотоцикл, все работает, но проект остался в коробке, на мотоцикл некогда поставить, делал лед часы на светодиодах и сдвиговых регистрах - код взят с них - там я сделал процедуры для рисования прямых по координатам начала и конца, процедуру для рисования круга, процедуру вывода текста. Все самописное, с моими ошибками, но в итоговом проекте все работает уже пару лет - часы у брата и у мамы, ни разу сбоев не было.
Конечно не приятно, когда меня хотят упрекнуть, что автор не я - посмотрите видео и найдите схожий проект - такого нет, я сам много чего перелопатил и сервисной документации и другие источники, сжог одну головку, хорошо их легко достать.
А дальше у тебя появился помощник b707. Я думаю, он в этой области больше осведомлен, чем я.
forfrends - Попробуй в этом цикле for (int j = 0; j < 8; ++j) читать биты с другой стороны for (int j = 7; j>-1; --j)
в коде b707 - ошибка, номерация у бит идет с 0 до 7
Вы код читать умеете? - похоже нет
forfrends - сначала попробуй код из #9, а потом будешь решать, есть там ошибка или нет
b707, вы большой специалист, - удачи Вам в жизни и вашей профессии!
Конечно не приятно, когда меня хотят упрекнуть, что автор не я - посмотрите видео и найдите схожий проект - такого нет, я сам много чего перелопатил и сервисной документации и другие источники, сжог одну головку, хорошо их легко достать.
Nkl-777 - вообще-то совершенно непонятно, что вы так обиделись. Я ведь очень мягко пошутил в вашу сторону, написав, что вы всего лишь "запутались". Если говорить прямо, в сообщении #7 написана куча ерунды, взять хотя бы высказывание про "16 бит в двухзначном шестнадцитиричном числе". Поневоле возникает впечатление, что вы сами в этом коде мало что понимаете...
Впрочем, это довольно характерно для авторов Ютюба.
Впрочем, это довольно характерно для авторов Ютюба.
ты сегодня мне польстил, так как не автор ютуба видимо я крутой специалист )))
Nkl-777 - вообще-то совершенно непонятно, что вы так обиделись. Я ведь очень мягко пошутил в вашу сторону, написав, что вы всего лишь "запутались". Если говорить прямо, в сообщении #7 написана куча ерунды, взять хотя бы высказывание про "16 бит в двухзначном шестнадцитиричном числе". Поневоле возникает впечатление, что вы сами в этом коде мало что понимаете...
Впрочем, это довольно характерно для авторов Ютюба.
Я не автор-ютубер - у меня есть маленький канал куда я выкладываю свои самоделки и отправляю посмотреть брату и друзьям радиолюбителям.
Там я ошибся, торопился - хотел помочь человеку быстрее. Я хотел сказать что в двузначном шестнадцатиричном числе у меня хранится последовательность из 8 точек.
Вот врагмент в котором хранится часть картинки - я использую в нем двухзначные шестнадцатиричные числа: 0x00,0xE0,0xFF
из этих чисел получается последовательность нолей и единиц, вот такая: 00000000 11100000 11111111, которая и строится на бумаге - 0 пропуск, 1 - прожиг.
Друзья, не ссорьтесь. Спасибо всем за помощь! Nkl-777, ваша помощь на самом деле очень большая!
Все заработало с вот такой конструкцией:
Хоть печать и ускорилась в несколько раз, но все же очень далека от той, какой должна быть. Сейчас картинка "Панды" размерами 384х134 (48х16 мм) печатается за (примерно) 3 секунды. А это в 7 раз медленнее чем должно быть. Вот пример работы аппарата, с которого я взял термопринтер: https://youtu.be/NpgrLEuK3cg?t=57
Вот еще пример: https://youtu.be/pXnbft-Jdpk?t=131
Такая скорость печати возможна ТОЛЬКО если "прожиг" будет происходить вместе с шагом двигателя, то есть без пауз на печать, а одновременно.
Столкнулся еще с одной неприятной вещью. Нагар на печатающей головке. Он образуется сразу же после первой печати, и с каждой последующей печатью становится только хуже. Нагар легко убрать. Но все же он образуется потому что лента во время прожига стоит на месте и прилипает к головке. Кстати, время прожига на это не влияет. "Пригорание" происходит даже на самых блеклых отпечатках. Если делать печать на движущейся ленте, то такого не происходит (проверял).
НО! Текущий алгоритм не подходит для печати "на лету". Я пробовал. Происходит расслоение изображения. Каждые 32 точки происходит 1/2 шага мотора (1 прожиг), таких сегментов 12, 12 полу-шагов мотора, соответствует 3-м строкам... На одной линии (строке) это не заметно, но вот следующая строка (линия) отстоит от первой в 3 раза дальше чем должна быть. Изображение пропечатывается хорошо, но "полосатое" и в 3 раза выше чем должно быть. В общем, данный алгоритм не подходит. Если бы можно было прожигать одновременно всю линию, или несколько сегментов то проблем бы не было...
Может у кого-то есть идеи как сделать одновременный прожиг? То есть как сделать запись сразу во все регистры, а не в 1 из 12?
P.S. ...на заметку: скорость печати на прямую зависит от напряжения питания головки. Если напряжение питания 7-8 вольт то на прожиг одного сегмента нужно примерно 5 мс. Если напряжение 12 вольт то 1 мс вполне достаточно. Как результат - увеличение скорости в 2-3 раза...
forfrends, привет!
В инструкции к моей печатающей головке было ограничение по печати в 32 точки из 128 за раз, при этом она потребляет около 3 ампер, если всю строку печатать точками то выходило до 12 ампер в пике, и там дорожки сгорают.
Я вот переделал алгоритм без деления строки на 4 части, т.е. в теории должно печатать всю строку за 1 раз. Но отладить не смог, так в блокноте отредактировал. Проверь...
Спасибо! Заработало! Немного переделал, теперь летает! На печать всего буфера (384х134 точек) уходит в среднем 600 мс. При чем скорость печати зависит от количества точек в линии: меньше точек - меньше время на прожиг - быстрее печать. А если точек в линии нет, то вообще пропускается без задержки на прожиг!
Три строчки "среднего" шрифта печатаются "примерно" за 500 мс!!!
Картинка панды печатается дольше, до 1 сек. Из-за того что там много сплошных участков.
Функция печати:
Я использовал не линейную зависимость длительности прожига от количества пикселей в линии. График функции выглядит как парабола. Формула выглядит так:
где:
FireH - максимальное время прожига линий с наибольшим заполнением. Измеряется в мс. У меня установлено значение 12 мс
FireL - минимальное время прожига, если точек очень мало (на пример одна...) Измеряется в мс. У меня установлено 2 мс
StrobeEn - количество пикселей в строке
0.17667 - коэфициент: 100/566, как высчитал 566, уже не вспомню... расчеты не сохранил. Но он на прямую зависит от количества точек на головке (384).
_Standby() - функция отключает питание шаговика, чтобы не перегрелся.
Конечно, можно было так не заморачиваться, но я хотел добиться одинаковой "яркости" линий с разным заполнением, и при этом не жечь на всю катушку... В общем пытался поймать золотую середину между пережиганием пикселей (когда точки расплываются и сливаются от нагрева) и пропусками от очень слабого нагрева.
Остальной код не менял, но в будущем нужно будет переписать большинство функций.
Завтра скину фотки и видео работы.
Вот что получилось:
https://youtu.be/FU0y-hKLpLk
Супер! я тоже одну сжег при разработке, но тут было пару лет назад массовое списание кассовых аппаратов и я мог их бесплатно брать для изучения, изучил, сжег и отложил)
:)))
Теперь осталось прикрутить дисплей, клавиатуру, и наладить интерфейс связи :) Думаю будет прикольно :)
А я поиграл и практического применения не нашел - были идеи какие-то данные фиксироватьт - температура, давление, освещенность, скорость, но не придумал ничего нормального.
На выставку какую-нить поставить - из твиттера распечатывать посты.
Forfrends, привет!
Круто получилось!
А можешь дать полный скетч под этот принтер?
Основной код написан выше: http://arduino.ru/forum/apparatnye-voprosy/termoprinter-iz-starogo-terminala-kassovogo-apparata#comment-477159
Только нужно заменить функцию печати: http://arduino.ru/forum/apparatnye-voprosy/termoprinter-iz-starogo-terminala-kassovogo-apparata#comment-478465