29 January 2011

Просмотри видео на сканере штрихкодов

Abnormal programming

«Из всех искусств для нас важнейшими являются кино и цирк»
— В.И. Ленин


Просмотр видео — одно из любимых развлечений в современном мире, фильмы сейчас смотрят практически на всех устройствах, даже на холодильниках. К сожалению, рядом не оказалось подходящего холодильника, и я решил просмотреть фильм на сканере штрихкодов. Под рукой оказался сканер Cipher Lab 8001. Технические характеристики плеера сканера:
  • 16-битный CMOS процессор
  • 1 Мб памяти для программ
  • 1 Мб SRAM для данных
  • FSTN дисплей с LED подсветкой разрешением 100×64


1 Мб памяти должно было хватить для хранения ролика, но это бы лишило плеер интерактивности, и усложнило процесс разработки. Поэтому выводить на экран будем данные, которые поступают непосредственно с инфракрасного порта. Также для простоты не используются крайние 4 столбца экрана. Итоговое разрешение картинки 96×64 (количество точек в строке кратно размеру байта).

Прошивка сканера


В прошивке нет ничего сложного:
  1. Считываем данные с инфракрасного порта;
  2. выводим на экран;
  3. посылаем компьютеру запрос на следующий кадр.

Единственное, на что следует обратить внимание — размер входящего буфера ограничен 256 байтам. А так как размер целого кадра 96×64/8 = 768 байт, нам придется разбить кадр на 4 блока по 16 строчек. Да, данные влезли бы в 3 блока по 256 байт, но хотелось, чтобы номер блока передавался как первый байт входного буфера.

int PlaceFromCom(void) {
long timer;
int position;
char c, picture[BLOCK_SIZE];
unsigned char blockId, loaded;

SendRequest();

timer = sys_msec;
loaded = 0;
position = 0;
while (sys_msec <= timer + TIMEOUT_MSEC) {
if (read_com(COM_PORT_NUM, &c)){
picture[position] = c;
position++;
if (position == BLOCK_SIZE){
loaded = 1;
break;
}
}
}
if (!loaded){
printf("Comm error\r\n");
return 1;
}
blockId = (picture[0] % 4);
show_image (0, blockId * BLOCK_H, IMAGE_WIDTH, BLOCK_H, &(picture[1]));
return 0;
}

Программа вывода


Программа для вывода видео в COM выглядит еще проще, чем прошивка:
  1. Делаем скриншот экрана;
  2. меняем его размер и конвертируем в двухцветное изображение;
  3. разбиваем на блоки и конвертируем в поток байтов;
  4. ждем запроса от сканера, возвращаем буфер.

По какой-то причине снятие скриншота в Питоне занимает очень много времени, поэтому в программе это действие вынесено в отдельный поток. Остальной код тривиален. Например, цикл вывода:
while True:
data = ser.read(9999)
if len(data) > 0:
if data[0] == "V":
ser.write(chr(currentBlock))
ser.write(desktop.strings[currentBlock])
currentBlock = (currentBlock + 1) % blockCount

Результат работы




Исходники программ можно скачать тут.
Tags:Pythonштрихкодпятница
Hubs: Abnormal programming
+244
6.2k 39
Comments 71
Top of the last 24 hours