Thymio reads bar codes
Bar codes are ubiquitous
At all possible and impossible places we find bar codes!
What are bar codes? Bar codes simply represent numbers and strings, which can be very easily read by machines.
On all items at the grocery store, the item numbers are attached as bar codes. These are 'scanned' at the checkout, the cash register knows the price for each number and the item will be deleted directly from the stock and possibly even ordered automatically.
A bar code for Thymio
The bar codes which Thymio can read must have much broader bars than the ones commercially used. Also we cannot encode long texts, so we restrict ourselves to the numbers from '0' to '7'. This will be our barcode:
The bar code consists of four equally sized fields or bits, coloured either 'black' or 'white'. Thymio 'reads' the colour of these fields and calculates, using the colour, the numerical value of the bar code.
The first field is always black, so that Thymio can recognize that a new bar code is beginning: this field will be called the sync bit. The sync bit is followed by three so-called data bits, where our number is coded:
- If the first bit is white, it has the value 1, else 'zero'
- If the second bit is white, it has the value 2, else 'zero'
- If the third bit is white, it has the value 4, else 'zero'
The value of the bar code is now the sum of these three values. If all data bits are 'black', then the requested number is 0 + 0 + 0 = 0, when all data bits are 'white', then the number is 1 + 2 + 4 =7. We can code all numbers from 0 to 7.
The following figure shows some examples. (N.B.: these bar codes must be read from 'bottom' to 'top', the lowest bit is thus the sync bit.)
The bar codes can be cut from the template and 'painted' with markers, but they can also, as shown in the picture, be drawn by hand. The bar codes are then mounted on the straightest possible route sections at 20 mm distance parallel to the runway.
Thymio reads bar codes
A bar code reader should have the following abilities:
- It must follow a path at a constant speed. Only one bottom sensor may be used for this purpose. On the page Thymio follows a black edge the tracking of a line with only a bottom sensor is described in detail.
- It must read the bar code: Thymio moves 'over the barcode' and reads the bar code with second bottom sensor. This will be described below.
- It has to do something with the scanned bar codes. (See Bar code light painting as an example.) Here either nothing is done with the scanned bar code or it is simply displayed. The idea is that the program can be used as a basis for your own developments and enhancements.
The reading process
The bottom sensors Thymio measure, at intervals of 0.1 seconds, the brightness of the surface. The speed of Thymio has to be adjusted, so that in 0.1 seconds Thymio moves exactly 5 mm1. As a bit is 25 mm wide, Thymio makes 5 measurements for each bit.2.
In the figure below each measurement of the bottom sensor is displayed as a vertical line.
If Thymio discovers 'black' for the first time, it has found the sync bit and it begins to count the individual measurements. Since this 'black' measurement is on the far left of the sync bit, counting starts with the value -2.
Whenever the counter is divisible by 5 (represented by red numbers), it is in the middle of the bit and the corresponding value (1, 2 or 4) of this bit is, if the measurement at this point results as 'white', added to the code.
If the counter has reached 20, Thymio terminates the read process and begins to search for a sync bit again.
Here is the described algorithm as Blockly Program:
The first four 'lines' of this program are used to track the line, the rest for reading bar codes.
The program is fully functional, but the bar codes are only read and not further processed. In the empty subroutine use_results you can (or better you should) insert your own actions.
This algorithm is not limited to bar codes with three data bits (wordlen=3): It can read bar codes from 0 to 15 data bits.
The same3 reading program as text program.
A complete example with automatic calibration.
Select the speed
At startup this program displays the (pre-)selected speed on the circle leds. When it displays
- 0 the speed is 'low'. (interval=7)
- 1 the speed is 'medium'. (interval=5)
- 2 the speed is 'high'. (interval=3)
With the buttons 'left' and 'right' you can choose another speed.
Calibrate the speed
It is extremely important that the speed is precisely adapted to the length of the bits. This can be done, somewhat laboriously, empirically or better automatically.
To calibrate the speed a special 'bar code' is used: this bar code consists of eight 'black' bits and is therefore exactly 20 cm long.
Thymio is placed in front of this bar code and then the 'reverse' button is touched; Thymio travels over the special bar code and stops when the calibration has finished.
When an SD card is inserted, the calibration is permanently stored on the card and read automatically at each restart.
Read the bar codes
By touching the 'forward' button the reading operation is started: Thymio follows the path and reads all recognized bar codes. The values of the bar codes (0..7) are displayed on the circle leds.
With the 'centre' button Thymio can be stopped.
This program as text program .aesl or as Blockly program .aesl.
All files in one zip-file.
Challenge: Create and read bar codes with several 'grey levels'
The bar codes previously used have two levels, they are therefore also called binary codes. It is also possible to encode using several grey levels.
To make the bar codes 'printer friendly' a sequence of white and black bars is used. As the bottom sensor averages the measurement in a field of about 6 mm size, it measures the average grey level of this field. Here are the digits representing '0' to '9' as raster grey level:
The measurement has to be much more accurate than in binary case, therefore, the kind of the bar code is somewhat adapted: Following the sync field, which is also used to calibrate the 'black' value, there is a white field in order to calibrate the 'white'-value. As an example, now a the bar code with a value '834':
The reading program is based on the previous 'binary version'. However, it was supplemented by a b/w calibration the and the ability to decode several grey levels. Here is the code:
#onevent startup
interval = 5
system = 4
wordlen = 2
grey=512
call sd.open(1000,status)
if status == 0 then
call sd.read(product,status)
call sd.open(-1,status)
else
product=733 # a guess for product
end
speed=product/interval
sub use_result
# put your action here
emit spy result
sub follow_the_track
p1 = prox.ground.delta[1]
preg = (p1 - grey) / 4
ireg += preg / 3
steer = preg + ireg
motor.left.target = speed + steer
motor.right.target = speed - steer
onevent prox
callsub follow_the_track
p0 = prox.ground.delta[0]
if state == S_WAIT_SYNC then
if p0 < grey then
state = S_READING
counter = -interval / 2
digit = BLACK
digival = 1
code = 0
end
else
counter++
if counter % interval == 0 then
if digit == BLACK then
black = p0
elseif digit == WHITE then
white = p0
diff = white - black
grey= (white + black) / 2
elseif digit < wordlen then
valeur = ((system - 1) * (p0 - black) + diff / 2) / diff
code += valeur * digival
digival *= system
else
state = S_WAIT_SYNC
result = code
callsub use_result
end
digit++
end
end
The program as a download.
Outlook
Printing and reading of bar codes with a lot grey levels is a major challenge. Until now it was only possible to read bar codes with 5 gray levels. It certainly needs some further experiments with different rasters and algorithms to read bar codes with ten grey levels.
A generator for bar codes
The bar code generator produces bar codes with any number of fields and any number of "digits" per field. That's how it's done4:
stotz.basil@amxa:~$ ./gen_barcodes.sh
usage: ./gen_barcodes.sh numbase wordlength val_1 val_2 val_3 .... val_N
numbase is the number of values per field (2..~10). wordlength is the number of data fields (0..~8) and val_1, val_2 etc. are the numbers to be encoded. The program outputs a LaTeX source, which is then translated by pdflatex into a PDF. The command
stotz.basil@amxa:~$ ./gen_barcodes.sh 6 3 192 13 24 101 | pdflatex
generates a PDF-file with 4 bar codes for the values 192, 13, 24 and 101 using the base 6 and 3 data fields.
The generated file texput.pdf can be printed directly.
The field to calibrate the 'white' level is not printed in binary bar codes (numbase = 2).