“Of all the arts, cinema and circus are the most important for us” - IN AND.Lenin
Watching video is one of the favorite entertainment in the modern world, films are now watched on almost all devices, even on refrigerators. Unfortunately, there was no suitable refrigerator nearby, and I decided to watch the movie on a barcode scanner. The Cipher Lab 8001 scanner was on hand. The scanner player’s technical specifications:
16-bit CMOS processor
1 MB of program memory
1 MB SRAM for data
FSTN display with LED backlight resolution of 100 × 64
1 MB of memory should have been enough to store the video, but it would deprive the player of interactivity, and complicate the development process. Therefore, we will display data that comes directly from the infrared port. Also, for simplicity, the last 4 columns of the screen are not used. The final resolution of the image is 96 × 64 (the number of points in the line is a multiple of the size of the byte).
Scanner firmware
There is nothing complicated in the firmware:
We read data from the infrared port;
display on the screen;
send the computer a request for the next frame.
The only thing you should pay attention to is that the size of the incoming buffer is limited to 256 bytes. And since the size of the whole frame is 96 × 64/8 = 768 bytes, we will have to split the frame into 4 blocks of 16 lines each. Yes, the data would fit into 3 blocks of 256 bytes, but I wanted the block number to be transmitted as the first byte of the input buffer. ')
int PlaceFromCom ( void ) { long timer ; int position ; char c , picture [ BLOCK_SIZE ] ; unsigned char blockId , loaded ;
The program for outputting video to COM looks even simpler than the firmware:
Make a screenshot of the screen;
change its size and convert to a two-color image;
break into blocks and convert to a stream of bytes;
waiting for a request from the scanner, return the buffer.
For some reason, taking screenshots in Python takes a lot of time, so this program is in a separate thread in the program. The rest of the code is trivial. For example, the output loop:
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