[Из песочницы] Перепрограммируем кассу и печатаем на ней Киану Ривза
Привет, Хабр!
Как то раз была у меня «работа» — нужно было сделать управление кассовым аппаратом Штрих-ФР-К. Так как моя карьера начиналась с ремонта ККТ, торешил взяться за эту работу.
Так выглядит сама касса и пробное изображение моего коллеги:
Так же по мимо управления движками и термоголовкой в аппарате пришлось написать небольшой скрипт на питоне с использованием библиотеки OpenCV. Итак, поехали.
Все началось с изучения рем. дока. к данной кассе и последующего подключения логического анализатора на пины термоголовки. Я отправил на печать, через штриховый тест драйвер букву «С». И вот что у меня получилось:
По DATA значение точек (всего 432 точки в строке), SCK — cинхросигнал, STB0, STB1, STB2 — стробы для нагрева термоголовки, LATCH — защелкивание данных. Строчку вбил в сдвиговый регистр, прожег, пошел дальше.
Следующий этап был доработка платы для ускорения процесса разработки.
Теперь перейдем к коду.
void go(int n, int shag)
{
switch (shag)
{
case 0: PORTA=0b10001000; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 1: PORTA=0b10101010; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 2: PORTA=0b00100010; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 3: PORTA=0b01100110; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 4: PORTA=0b01000100; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 5: PORTA=0b01010101; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 6: PORTA=0b00010001; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
case 7: PORTA=0b10011001; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011;
break;
}
}
Есть две схемы управления шаговым двигателем для этой кассы. 4-шаговый и 8-шаговым. Я выбрал 8, так как движки работали лучше.
#define DATA 2
#define SCK 1
#define LATCH 3
#define STB0 2
#define STB1 3
#define STB2 4
#define DATA_IN PORTB
#define STB_IN PORTE
int sck()
{
_delay_us(3);
DATA_IN|= (1<0)
{
DATA_IN|=(1<
Код отправки данных в термоголовку. Термоголовка работает как сдвиговый регистр. Как она работает я писал выше.
void print_all_pixel()
{
while(n<55)
{
print_stroka(str[n]);
_delay_us(3);
n++;
}
latch();
n=0;
STB_IN&=0b11111011;
_delay_us(500);
STB_IN|=(1<
Функция печати и прожига строк.
void recieve()
{
///while(f);
if ((com==0x50)&&(rezhim==0))/// P
{
//USART_Transmit('P');
com=0;
rezhim=1;
}
if ((rezhim==1)&&(com!=0))
{
//USART_Transmit('P');
str[iFF]=com;
com=0;
iFF++;
if (iFF==54)
{
print_all_pixel();
rezhim=0;
iFF=0;
USART_Transmit('P');
USART_Transmit('R');
USART_Transmit('I');
USART_Transmit('N');
USART_Transmit('T');
USART_Transmit('E');
USART_Transmit('D');
}
}
if ((com==0x52)&&(rezhim==0))///R
{
com=0;
promotka();
USART_Transmit('O');
USART_Transmit('K');
//vpered(300);
}
}
Основная функция, которая крутится в вечном вайле. Когда приходит буква «P» я включаю вход в режим печати. Далее все остальные символы начинают набиваться в буфер. Далее когда буфер набивается 54 байтами (или 432 бита), то печатаем строку и отправляем по УСАРТ слово PRINTED.
Ну вот и все с железной частью. В следующей части я распишу про программную часть, а именно про программу на питоне. Исходники.