Jumbo Number Display

It would be useful to be able to display numbers (integers between 0 and 999, for example) in jumbo size on the EV3 display so that they can be read easily even while the robot is moving.

My solution was to display three images side by side on the screen, with each image showing a digit. I prepared the image files for each digit 0-9 using the GIMP program then imported them into the EV3 Image Editor and placed each of them at the extreme left of the EV3 screen.

Then a rather clever EV3 program does this:

  • In my program (downloadable below), readings are input from the ultrasound sensor continuously, inside an infinite loop. The ultrasound sensor reading are numbers in the range 0-255 (cm).
  • The reading is written into a numeric variable called 'dist' (for distance)
  • A loop is entered which uses a fiendishly clever calculation (explained in more detail below) to determine the hundreds digit, the tens digit and the unit digit as the loop loops around three times (first finding the hundreds digit etc).
  • Each digit is passed to the display block via a data wire. Since the image files in this project have names like '0', '1', '2' etc the corresponding image is displayed.
  • The image of the digit is displayed in an 'x' (horizontal) position that depends on the loop's count output. The count output supplies the number of times the blocks in the loop have been executed. The first time the loop runs the count output is zero and the image corresponding to the hundreds digit is displayed at x=0. The next time the loop runs the image corresponding to the tens unit is displayed at x=59. Etc.
  • The display block is set NOT to erase the screen so that when the tens and unit digits are displayed this does NOT cause the existing digit(s) to be erased. Thus the displayed number is displayed bit by bit, first the hundreds digit then the tens digit then the unit digit, but this happens too fast to see.
  • A wait block makes the display remain static for 0.2 seconds ensuring a more steady display but limiting the refresh rate to 5 readings per second.

Here is more detail on the fiendishly clever calculation which uses the index number of the loop as well as modulo and 'floor' rounding to determine the corresponding digit. Here is the formula used: floor(a%(10^(3-b))/(10^(2-b)))

where a is the reading of the ultrasound sensor, as stored in the variable 'dist'

and b is the inner loop's count output.

Note that

  • the 'Floor' function simply 'rounds down' so that Floor(3.9) = 3, for example.
  • Modulo (represented by a '%' sign) is the remainder when one number is divided by another, so for example 9%4=1 and 17%5=2.
  • The loop's count output is the number of times the sequence of blocks inside the loop has been completely run, so the first time the sequence is run the count output is zero, the second time it is 1 and the third AND LAST time it is 2.

The best way to understand the calculation is to see how it works with a specific number such as a=245.

On the first passage through the inner loop its count output is zero (=b).

10^(3-b) = 10^3=1000

a%(10^(3-b))= 245%1000 = 245 (the remainder when 245 is divided by 1000)

10^(2-b)=10^2=100

a%(10^(3-b))/(10^(2-b))=245/100=2.45

floor(a%(10^(3-b))/(10^(2-b)))=floor(2.45)=2 ('floor' just means 'round down')

so the first digit of the reading has been determined to be a '2' and this number is passed to the display block causing the image file with the name '2' to be displayed.

On the second passage through the inner loop its count output is 1(=b).

10^(3-b) = 10^2=100

a%(10^(3-b))= 245%100 = 45 (the remainder when 245 is divided by 100)

10^(2-b)=10^1=10

a%(10^(3-b))/(10^(2-b))=45/10=4.5

floor(a%(10^(3-b))/(10^(2-b)))=floor(4.5)=4 ('floor' just means 'round down')

so the second digit of the reading has been determined to be a '4' and this number is passed to the display block causing the image file with the name '4' to be displayed, just to the right of the first digit (59 pixels to the right, to be exact).

I'll leave it to you to check that the third pass (iteration) through the loop gives the output '5' as expected.

If I had tried to determine each digit separately instead of using a loop to find all three digits then the code in each part would have been simpler, but there would have been three parts instead of one. Other improvements could be to hide leading zero(s) so that sixty five, for example, would appear as 65 and not 065. My program is incapable of displaying negative numbers or decimal parts. I don't know how it would handle numbers larger than 999 - it is certainly not designed to handle numbers larger than this.

Use the link below to download the project, which includes the 10 image files. The project also includes a second, much simpler project which continually displays the ultrasound sensor reading using the regular built-in type 2 font which is larger than type 1 but tiny compared to the digits that my program displays. So, was it worth it?