Mobile printing



    Nowadays, one won’t surprise anyone by printing pictures on a piece of paper. There is a huge selection of printers (including pocket ones). Many of my friends buy or assemble 3D printers. I want to tell you how I invented the bike again. So again, a step back - this is the story of 2D printing. The story is about how I made a mobile printer for a phone based on a thermal printer (a printer that prints on thermal paper - you do not need ink, only special paper and electricity), a bluetooth module and a few other things.
    I want to immediately warn that in electronics and electrical engineering I do not understand anything, that I basically did not use ready-made solutions and libraries. Therefore, this is a story about handshaking and bicycles, about the problems that I encountered. Continue reading at your own risk.

    Super technology device


    I think that I do not need to be reminded that we live in the age of mobile technology. I remember how about 20 years ago I thought that here is a little more and the world will be full of robots, flying cars and many, many more surprising things. Given that I thought that a little more and everyone would have their own robots, it’s symbolic that we really don’t have robots (I ask forgive vacuum cleaner advocates to forgive me for the last sentence), but there’s something else ... I probably wouldn’t He believed if they would then tell me that almost every person on earth in his pocket will have a super-technological device, with which, people, sitting in the toilet, will run a simulation of the physical interactions of the process of stuffing birds into pigs. And if they told me that this device would be called a telephone, I would have laughed at all in the face of the narrator.

    A bit of history


    It was the 95th year on my nose (maybe earlier, but in the last paragraph I wrote about “20 years ago”, and “20” is a beautiful and round number, so I’ll stay with him) and one of my friends from the yard had Gameboy (DMG-001). I don’t think it’s worth telling how cool he was by the standards of that time and what kind of line was built up to watch and hold in his hands this miracle of technology. In the early 2000s, this device again reminded of itself, because additional peripherals appeared to it, namely the camera and printer. There was no real need for such a camera or printer (much less of such quality), but the very idea of ​​a mobile device from which to print a small picture seemed a step into the future.



    Back to the topic


    So, 20 years have passed and I thought that it would be possible to make a similar device, only for a super-technological device - a phone.

    The idea was quite simple and was based on the following things:
    1. Thermal Printer (A2 Micro Panel Thermal Printer).
    2. Bluetooth module (JY-MCU BT_BOARD V1.06).
    3. Controller (Stellaris Launchpad LM4F120XL. To avoid the questions “why?”, I’ll immediately answer that I just had this particular board on hand).
    4. Screen (LCD 84x48 Nokia 5110) and several LED diodes to indicate status.
    5. Battery and regulator (Turnigy UBEC 5A).
    6. An Android application for controlling the printer (read how to “print”).
    7. The category of handshaking and poor knowledge of the basics of electrical engineering.

    It is because of the 7th point that I have to apologize to everyone who is upset by my implementation. Forgive me, but you will not find adequate device design in the production of printed circuit boards, debugging devices using an oscilloscope and other goodies. I also do not have the necessary tools, because in everyday life I do not work in this area, and I don’t want to lose the rank of handshaking. I tried to slightly improve my knowledge of the subject area, but somehow, I understand that I can be mistaken in terminology. I myself find it painful to look at the code of people far from programming, so in order not to take up more time from lovers of the beautiful in the field of electrical engineering, I post a photo of how everything was assembled:



    Well, for everyone who continued reading after the last photo, the achievement "Survived the hell of a perfectionist electrical engineer" is available ...



    So, as I said, the idea was simple: there is a picture on the phone (it doesn’t matter what the source of the picture is, we just assume that the picture is there), you need to reduce it, perform manipulations with brightness and contrast (if necessary), then dithering to get a black and white image, then sending via bluetooth to the printer and printing directly.

    Since I am developing software, there were no problems or troubles with the software part. A simple protocol for exchanging data between the printer and the control device was implemented (since the printer accepts commands via bluetooth, it makes no sense to be limited only to the phone):
    1. A binary protocol is used to trick data.
    2. Data is transmitted in the form of packets, each of which begins with a header (what kind of packet, how much data).
    3. There are two responses to each request packet (“request received” and “request complete”). One answer could be dispensed with, but in this mode it was possible to better control the printer status - there is no need to implement the command queue on the controller side, because the controller itself reports that it is ready to fulfill a new request.

    In addition to service commands such as “Is the printer alive?”, Only a few commands were implemented that are directly related to printing (image printing and paper feeding - feed).

    Since the printer is capable of printing only monochrome images, a simplified Bitmap analogue with 1bpp (1 bit per pixel) was chosen as the image format. The printer is capable of printing 384 dots per line, which means that to print one complete line, 48 bytes are needed (not counting the header).

    Communication problems


    I will not focus on the fact that the controller refused to receive data from the bluetooth module due to the too low voltage on the leg of the TX module, because I really spent a lot of time debugging this part. I killed about two days for this, because first I checked everything that I could and only then went to read the Internet, from where I found out that this is a feature of the selected module and that I’ll have to pull up the level to the required 3.3V myself or have to force the module and solder the diode from it (which I decided not to do).



    After I was able to receive packets on the controller side, another problem appeared: the data came partially. Until now, I can’t say exactly what the problem was, but here the buffer limit of the bluetooth module is there, its transmission / processing speed is tooli. The problem was this: we are sending a packet (for example, a kilobyte of data), on the controller side we get 990-1023 bytes with losses in a random range (random data area, random amount). Data loss occurred in about 50% of cases and always amounted to a small percentage of the original data (no more than 50 bytes, even when sending several kilobytes). The problem was repeated at all data exchange rates (not that I checked everything, but checked both the average value and the borders - 1200 and 115200 baud), but disappeared when I added a delay between sending data.
    1. A packet checksum has been added.
    2. The data within the packet was transmitted in fragments, after the data fragment was transmitted, a response was expected from the controller, which sent the sequence number of the received fragment.
    3. A service package was added to set the fragment size (usually 128 bytes are used, but I left the opportunity to change the fragment size).

    So, the first thing that was necessary to determine the beginning of the package was a signature (a specific sequence of bytes):
    inline bool _receiveSignature( )
    {
        unsigned char character;
        unsigned int offset = 0;
        while( offset != SIGNATURE_SIZE )
        {
            if( _readByte( &character ) )
            {
                if( character != SIGNATURE[offset] )
                {
                    if( character == SIGNATURE[0] )
                        offset = 1;
                    else
                        offset = 0;
                }
                else
                    offset++;
            }
            else
                return false;
        }
        return true;
    }
    


    An idea with a signature is not new. In the event that one of the parties, for whatever reason, interrupted the packet reception in the middle of transmission, then the remaining packet data should not be interpreted as the next packet. Thus, the reception begins with the fact that all bytes are removed (ignored) from the buffer, before the signature - the beginning of the packet header. Thus, it is ensured that random garbage in the buffer (the remnants of the previous packet) will not be considered the header of the new packet.

    Code for receiving data in fragments (data area, after receiving and checking the header):
    unsigned char *buffer = m_buffer;
    unsigned int size = m_header.size;
    _sendCallback( 0 ); // resets fragment id
    while( size > 0 )
    {
        unsigned int fragmentSize = _min( size, m_fragmentSize );
        if( read( buffer, fragmentSize ) )
        {
            size -= fragmentSize;
            buffer += fragmentSize;
            _sendCallback( );
        }
        else
        {
            _sendCallback( 0 ); // sends wrong fragment id
            _setError( READ_ERROR );
            return false;
        }
        // тут был код для вызова callback (экран и прочее)
    }
    unsigned int checksum = _getChecksum( m_buffer, m_header.size );
    if( m_header.checksum != checksum )
    {
        send( COMMAND_ERROR );
        _setError( INVALID_CHECKSUM );
        return false;
    }
    


    Since there is a possibility that there will be losses during data transmission, it is necessary to check the serial number of the packet. For example, a print request has been sent but no response has been received. In this case, the request will be sent again, but it is not necessary to execute it, because just answer with the status of the previous query execution. Each of the parties considers the packets and if the serial number of the packet is incorrect, then you should start communication “from scratch” (reset the counters).

    In addition to the printer itself


    In addition to the printer itself, the controller and the communication module (bluetooth), several elements were added to indicate the status. 3 LEDs have been added:
    1. Power indicator.
    2. Indicator of communication with the phone (lights up if there has been data transfer in the last 5 seconds).
    3. Print indicator (lights when printing is in progress).



    In addition to simple indicators, a monochrome screen was added to display progress, status and other details.

    The general scheme looks like this:


    Appearance


    For the case, I decided to use 4mm plywood, I entrusted the cutting of plywood to a machine with a laser. All that was required of me was a vector drawing and money for the work. The drawing came out like this:


    Areas that needed to be burned out rather than cut were marked in red. Satisfied with the result. Of the minuses of this box, I can only say that it is glued and can not be disassembled. Fortunately, I deduced the port for new controller firmware and the port for charging the battery, so there is no need to disassemble the box:


    It should be clarified that the box turned out the third time. At first, the box simply did not fit together - I hurried, did not check the dimensions and one face did not fit. Then I redid the drawing, but made a rather stupid choice in how to fix the glass protecting the screen:


    As a result, the glass was hidden in the case and did not stick out from the outside (I will not again insert the picture from the beginning of the article here).

    application


    On the phone side, I made a rather primitive interface:
    Selecting a picture for printing (from the camera or from the file system):


    Image settings - brightness and contrast:


    Several controls (connecting to a printer, printing, paper feed, image rotation):


    results


    The print quality is pretty decent (for a thermal printer):


    Like many printers, this one is no exception and is a bit “striped”:


    In general, what I would like to say with this story is that you should not be afraid to do things with your own hands, you should not be afraid of bicycles either. Nowadays, the development of their devices has become much easier. Controllers are not so limited in resources, unpretentious in work and forgive some mistakes (which a person who understands in electrical engineering would not have made). Do things with your own hands, reinvent your bikes. Thanks to everyone who read to the end.

    Also popular now: