Learn a Language: Shopping List Translator and Print on Thermal Printer QR701

by mcgurkryan in Circuits > Arduino

609 Views, 4 Favorites, 0 Comments

Learn a Language: Shopping List Translator and Print on Thermal Printer QR701

audry.png
list_page.png
bear_gray.png

This thermal printer connects to your network and serves a webpage where you can add items to a shopping list. The items are translated line by line to a language of your choice using the free google translate API. Your shopping list is then sent to the printer and printed.

This is a great way to practice and learn a new language.

The list is printed as an image. Therefore the target language need not actually be supported by your thermal printer.

Of course other images can be printed as well!!!


get source code

cheeky-breeky/thermal-printer-print-translated-shopping-list: enter a shopping list, translates to target language item by item, prints to QR701 thermal printer (github.com)


the code uses a websocket to send data to the printer via esp8266.


language translation is done at

"https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=es&dt=t&q="


change the target language "tl" to a language of your choice. language codes can be found on w3schools

Supplies

QR701 Thermal printer

ESP8266 mcu

printer_wire.png
wiring.png
CaptureCreds.PNG
CaptureLanguageCode.PNG
CaptureLang.PNG

download the source code , set your network-id and password.

set your language of choice.

the image shows how the target language is set

find your desired language at

HTML ISO Language Code Reference (w3schools.com)

and edit the tl=xx parameter in the language lookup url (image) where xx is your desired language

tx pin from board pin 1 goes to rx blue wire on printer. as shown in image

the GND and 5V are shared and are provided by an old USB phone charger capable of delivering up to 2A.

How It Works

CaptureSocket.PNG
CaptureSocketJS.PNG

This is a modified version of the ESP8266 sample code HelloServer

the server serves an html file, a JavaScript file (requested by the html) and an optional favicon

server.on("/", handleRoot);
server.on("/zuri.js", handleJS);

server.on("/favicon.ico", handleFavicon);


The favicon is optional but I really like how this image is served in the original sample code, also the image itself is fun and i like that the background can alternate in colour.

The html code is very short and simple, it just sets a title for the page, requests the javascript and defines

the elements you see on the page.

JavaScript.

This code is also based on some sample code found online, unfortunately I can't remember where i found it and give the author due credit. The sample code would allow you to navigate your pc, upload an image file and have it display in an <image> element. Interestingly the code made use of a hidden <canvas> element, this was very useful as the image manipulation was easier for me to implement using the canvas element rather than the image element.

The code will accept any sort of image, but for the image to be compatible with the thermal printer it must be a binary image (black and white). However using "halftone" techniques it is possible to create 'grayscale' images with fairly good resolution. As can be seen by the image of the bear (cover).

The code also inverts the image, as a '1' on a pc screen denotes an ON pixel (white) but ON on a thermal printer results in a black pixel.

The image is also resized, as the printer has a maximum print width of 384 pixels. the height of the image must be padded so that the height of the image is a multiple of 24 pixels. This is because the printer expects image data in a specific format and the algorithm becomes much simpler if the image is the exact height. the image is padded with white.

The printer expects data in this format, the first 24 bits are printed from top to bottom, the next 24 bits start at the top again right along side the first 24, and so on for the duration of the width.

Sending the data to the ESP8266 board from the browser is accomplished by opening a websocket.

the Websocket code is also modified from the Arduino IDE samples library.

The JavaScript needs to create and use the port, the Arduino code needs to accept a websocket connection and accept data from it.

The printer is too slow to handle all the data at one, and rather than store the image data in an array in RAM, it is more efficient to implement a basic flow control over the websocket and send small chuncks of data at a time.

the messages are quite simple:

First we send a message PRINT Height.

it is not necessary to specify the width as all images are adjusted to be the same width, but height will likely vary.

the arduino sends a reply "YES"

and the javascript replies by sending data chunks..

DATA 0x00 0x00 0x00 ......

The arduino receives the data, identifies the header DATA and sends the remaining bytes to the printer. After a short delay, to give the printer enough time, the arduino code sends a "RTR" string (Ready To Receive) over the websocket, and the JavaScript will respond with more DATA, or a "END" string if the end of the image has been reached.

The printer itself needs some headers and footers

These print commands and headers and footers we taken from the adafruit thermal printer sample code.

basically we send a header, with width information, then 24 * 384 bits, then the footer to get the printer out of raw image data mode.

This prints a strip of the image, 384 wide by 24 pixels high, and the whole process is repeated again for the next strip of the image, until all the data has been processed.


Language Translation

CaptureGetText.PNG

Now that we can print images, we get to why I built this project in the first place.

I wanted a way to print shopping lists, in both a source language, English, and a target language.

This I can practice using my desired language and can refer to the English word if I'm stuck, however the target language of my choice was not supported by the printer, so I realised the only way to achieve this was to send the shopping list to the printer in image form.

Luckily the html canvas element is great for this.

Text can be written to the canvas, in a multitude of languages, in a multitude of fonts, and then read out as an image!!

this is done using the fillText() function, textAlign() can be used to set "left" or "right" justified, which is useful when laying out the text and separating source and target language into columns.

The canvas can of course also handle a lot of colours, but the printer does not, so stick to black and white.

Actually translating the text is quite simple but it took a bit of research. Finally i came across an example that uses a simple GET request to the url:

"https://translate.googleapis.com/translate_a/singl... + data"

Where "data" is the word you wish to translate, tl is the target language.

If successful a JSON object is returned, and you can index the data at index [0][0][0].

as can be seen in the code.

If the lookup is not successful then the target word is set to "????" which is what will be added to the shopping list.

When the print button is clicked, the list is printed out as an image just a described above.

Hopefully this project is useful to someone, most of the code is modified sample code and great work done by others, and stitched together rather roughly with too many hardcoded magic numbers. However the code is in github, and all are welcome to tidy it up and add features and use freely.