WriterBot part 2

In this project we will combine the 'Text Entry' program with the 'WriterBot v1' program to make a program that will allow the user to enter a text string that will then be written out by the robot.

This is very straightforward - it's just necessary to check the variable names to make sure that there is no 'clash' of variable names i.e. makes sure that there are no variables with the same names in the two programs that are being used for different purposes.

I also renamed the 'mytext' variable in the text entry program to 'mystring' for consistency with the WriterBot code, and I added a few lines (highlighted below) to link the programs together. Here is the finished code for WriterBot v2. As usual, you can copy and paste this into Small Basic and try it for yourself. You know how to select long blocks of text, right? Left-click just before the start of the block, then hold down Shift and left-click just after the end of the block.

'WriterBot v2 by Nigel Ward

'See the 'Going Further' section of EV3Basic.com

'*******************TEXT ENTRY CODE STARTS HERE******************

'Allows a string of up to 11 characters to be typed

'This program is compatible with brick mode 

'(it can be compiled to the brick)

'Each character has dimensions 16x22 on screen

'Columns are numbered 1-11



LCD.Text(1,0,3,1," <=Backspace  >=Enter")




line[4]="WXYZ -  < >"





LCD.Rect(1,0,103,178,25)  'draw rect around typing area

col=6   'current column

row=2   'current row

x=81    'x coordinate of highlighted char

y=35    'y coordinate of highlighted char


loop="True"   'loop control variable

While loop



  LCD.InverseRect(x,y,16,22)   'clear inverse

  If Button="R" Then

    col=1+Math.Remainder(col,11)  'allow jump from col 11 to col 1

  ElseIf Button="L" Then

    col=11-Math.Remainder(12-col,11)  'allow jump from col 1 to col 11

  ElseIf Button="U" Then

    row=4-Math.Remainder(5-row,4)  'allow jump from row 4 to row 1

  ElseIf Button="D" Then

    row=1+Math.Remainder(row,4)  'allow jump from row 1 to row 4

  ElseIf Button="E" Then

    If row=4 and col>6 Then

      If col =9 then   'backspace

        If  mystring<>"" Then

          'remove last character from mystring


        Else  'nothing to delete



      ElseIf col = 11 Then   'Enter

        Loop="False"   ' do not repeat loop

      Else   'col=7,8 or 10, which is not valid in row 4



    Else  'middle button was pressed over a normal character

      If text.GetLength(mystring)<>11 Then


      Else  'already have the maximum 11 characters





  x=-15+col*16  'calculate x coordinate of character to be highlighted

  y=-9+row*22  'calculate y coordinate of character to be highlighted


  LCD.text(1,1,107,2,"           ")  'clear text




LCD.text(1,0,0,2,"Your text:")


LCD.text(1,0,40,2,"Press Enter")

LCD.text(1,0,60,2,"when the")

LCD.text(1,0,80,2,"robot is")




'*******************ROBOT WRITER CODE STARTS HERE******************



scale=10  'desired letter height in cm

s = scale * 0.0515  'adjust scale factor

tf=2   'turnfactor = motor turn angle / robot turn angle

'depends on wheel separation and wheel diameter

'recommended value =2 for standard 

'driving base with wheel separation=12.5cm and wheel diam=5.6cm

sf = 1 'speed factor 1-3 (recommended value =1)

'For compatibility with the EV3 Explorer compiler, 

'use array indices that are the Unicode

'code numbers of the corresponding characters. 

'For example, the code number for "A" is 65

sequence[48]= "0A 1P 2c cA Cc 6c Ca 5p 1C 10"          '0

sequence[49]= "0A 30 0c 0P cc 0a 4p 0A 5P 2p"          '1

sequence[50]= "0A 3c 0P ca ca dC 1A 2p"                '2

sequence[51]= "0A 3c 0P ca ca cA cA Ca Cp cC 10"       '3

sequence[52]= "1A 0P 2p 2A 0H 0P gG 0A 2p 0a 1A"       '4

sequence[53]= "0A 1C 0P Ca cA cC 1a 2a 2p 0a 4A"       '5

sequence[54]= "0A 2a 0P 1c cA CA cc 2c ca cp 0c 3A"    '6

sequence[55]= "1K 0P jk 6p 0e fE"                      '7

sequence[56]= "1C 0P cA da ca ca dA cp 0C 10"          '8

sequence[57]= "0a 5C 0P cA cC 2C ca Ca cC 1p 0a 2A"    '9

sequence[65]= "0A 0P 2p 0a 2P 6F ef 0f ee 2p 0A"       'A

sequence[66]= "0A 2a 0P 1C cA cC 1A 4a 5C Ca cp Cc 5a" 'B

sequence[67]= "2A 1c 0P CA cc 2c ca cp 0c 3A"          'C

sequence[68]= "0P 1C cC 2C cC 1a 8p 0a 20"             'D

sequence[69]= "0A 2a 0P 1p 0F ef 0P 6a 4A 2p"          'E

sequence[70]= "0A 2a 0P 1F 0p ef 0P 6a 4p 0A 20"       'F

sequence[71]= "0C cP 0c 1C CA cc 2c ca cp 0c 3A"       'G

sequence[72]= "0A 2a 0P 2p 0C DC 0P 4p 0a 2a 0P 4p 0A" 'H

sequence[73]= "0A 4a 0P 2p 5a 0P 4p 0A 5P 2p"          'I 

sequence[74]= "0A 4a 0P 2a 3c cA Cp cC 10"             'J

sequence[75]= "0A 0P 4p 0a 2C 0P Da dp 0C"             'K

sequence[76]= "0A 4P 8a 2p"                            'L

sequence[77]= "0A 0P 4C Ca cC 8p 0a"                   'M

sequence[78]= "0A 0P 4E Fe 4p 8a"                      'N

sequence[79]= "1C 0P cC 2C cA cC 2C cp 0C 10"          'O

sequence[80]= "0A 0P 4a 1c cA Cc 5p 0c dC"             'P

sequence[81]= "0a 5C 0P cA cC 2C ca 5C 6p 0a 1c 0P cp 0C" 'Q

sequence[82]= "0A 0P 4a 1c cA Cc 5c dp 0C"             'R

sequence[83]= "0a 5C 0P cA cA da ca cp 0c 3A"          'S

sequence[84]= "0A 4a 0P 20 5a 4p 0A 10"                'T

sequence[85]= "0a 8P 3C cA cC 3p 7P 5p 0a"             'U

sequence[86]= "0A 4J 0P Jj 0j jp 0J 8a"                'V

sequence[87]= "0A 4P 8e eE 0E Ee 4p 8a"                'W

sequence[88]= "0F 0P fp 0f 6f 0P fp 0F"                'X

sequence[89]= "1A 0P 2E ep Ee 0e 0P ep 0E 8a"          'Y

sequence[90]= "0A 4a 0P 2F Ff 2p"                      'Z

sequence[32]= "20"                                     'space

sequence[45]= "0A 1a 0P 2p 0a 2A"                      'hyphen

sequence[46]= "0P 0b 0b 0p 0B 0B 10"                   'period

For j=1 To Text.GetLength(mystring)


  'extracts jth character from mystring


  For n=1 to (1+Text.GetLength(sequence[unicode_for_char]))/3



    If move_unicode>64 And move_unicode<91 Then  'capital letter









    If turn_unicode>64 And turn_unicode<91 Then  'capital letter







    If movechar="1" Then


    ElseIf movechar="2" Then


    ElseIf movechar="3" Then


    ElseIf movechar="4" Then


    ElseIf movechar="5" Then


    ElseIf movechar="6" Then


    ElseIf movechar="7" Then


    ElseIf movechar="8" Then



    ElseIf movechar="c" Then  'move sqr(2)*100*s


    ElseIf movechar="d" Then


    ElseIf movechar="e" Then

      Motor.Move(ports,movesign*10*sf,223.6*s,"True") 'sqr(5)

    ElseIf movechar="f" Then

      Motor.Move(ports,movesign*10*sf,447.2*s,"True") '2*sqr(5)

    ElseIf movechar="g" Then 

      Motor.Move(ports,movesign*10*sf,316.2*s,"True") 'sqr(10)

    ElseIf movechar="j" Then 'sqr(5)

      Motor.Move(ports,movesign*10*sf,412.3*s,"True") 'sqr(17)

    ElseIf movechar="m" Then

      Motor.Move(ports,movesign*10*sf,360.6*s,"True") 'sqr(13)



    If turnchar="a" Then


    ElseIf turnchar="b" Then


    ElseIf turnchar="c" Then


    ElseIf turnchar="e" Then


    ElseIf turnchar="f" Then


    ElseIf turnchar="g" Then


    ElseIf turnchar="h" Then


    ElseIf turnchar="j" Then


    ElseIf turnchar="k" Then


    ElseIf turnchar="m" Then


    ElseIf turnchar="n" Then


    ElseIf turnchar="p" Then 


           'lowers pen if turnsign positive



  Motor.Move(ports,10*sf,100*s,"True")  'space between characters



I hope the above program works well for you. Feel free to modify it.

Of course, other people have made writer robots with NXT and EV3. It's interesting to compare WriterBot with others such as these:

This one is very neat and quite accurate, but limited to small text.

This one is surprisingly accurate, thanks to the use of line following to recover from errors made in the drawing of each letter.

This next one, an NTX robot, has a static base and therefore good accuracy:

Here's a more sophisticated version of the above, running under the EV3Dev operating system:

This industrial robot probably costs hundreds of times as much as an EV3 but look at that amazing precision!

This amazing sudoko solver could easily be modified to become a very accurate robot writer, but it's not a 'run-around' robot like mine and certainly isn't a simple attachment for the EV3 driving base model. In fact it's an NXT robot, which makes it all the more impressive - it even has optical character recognition! The creator has kindly made available info and building instructions at tiltedtwister.com.

This tic-tac-toe solver uses similar hardware to the previous mode but uses a more sophisticated x-y movement, with a rare part (rack 13M, part number 64781, available from bricklink.com) and one more motor needed. The software is less impressive than for the sudoko solver.

I haven't yet found a Lego writer robot other than mine that has all these features:

Maybe it can be done with the standard EV3-G software, maybe it can't ... yes, that's a challenge to you EV3-G fans!!

By the way, I said you can rescale the characters (change their height in cm) by changing a single line of code (the line 'scale=10' near the top of the robot writer code). If you would like the user to be able to choose the scale at runtime then first delete the line 'scale=10' and then insert the following code above all the other code.

height=10  'desired character height in cm


LCD.Text(1,0,   0,2,"Use left &")

LCD.Text(1,0,  20,2,"right keys")

LCD.Text(1,0,  40,2,"to select")

LCD.Text(1,0,  60,2,"the text")

LCD.Text(1,0,  80,2,"height (cm)")


Button="R"   'must give Button a value before we can refer to it

While Button<>"E"



  If Button="L" And height > 5 Then      'min height = 5cm


  ElseIf Button="R" and height <20 then  'max height = 20cm



  LCD.Text(1,70,100,2,height + " ")  'think about why I added a space



LCD.Text(1,0,  0,2,"Next enter")

LCD.Text(1,0, 20,2,"the desired")

LCD.Text(1,0, 40,2,"text.")

LCD.Text(1,0, 60,2,"Press any")

LCD.Text(1,0, 80,2,"button to")



Buttons.Flush () 'get rid of button input

scale=height  'for compatibility with robot drawing code

You can also run the above code by itself to test it out.