Cricket Logo
A Brief Introduction
to Programming Your Cricket


 


Cricket Logo was designed and implemented by Brian Silverman. This tutorial was written by Fred Martin with Robbie Berg.

Overview

Cricket Logo has the following features:

Red Dot Reference

When using Cricket Logo, user programs are compiled into tokens which are beamed via infrared to the Cricket. Cricket Logo is a procedural language; procedures are defined using Logo to and end syntax:

to procedure-name
procedure-body
end

Motors

The Cricket has two motors, which are named A and B. A bi-color LED indicates the state of each motor.

Motor commands are used by first selecting the motor (using ``a,'', ``b,'', or ``ab,'') and then telling it what to do (e.g., ``on'', ``off'', ``rd'', etc.).

a,
Selects motor A to be controlled.
b,
Selects motor B to be controlled.
ab,
Selects both motors to be controlled.
on
Turns the selected motors on.
off
Turns the selected motors off.
thisway
Sets the selected motors to go the ``thisway'' direction, which is defined as the way that makes the indicator LEDs light up green.
thatway
Sets the selected motors to go the ``thatway'' direction, which is defined as the way that makes the indicator LEDs light up red.
rd
Reverses the direction of the selected motors. Whichever way they were going, they will go the opposite way.
setpower level
Sets the selected motor(s) power level. Input is in the range of 0 (coasting with no power) to 8 (full power).

Timing and Sound

The timing and sound commands are useful to cause the Cricket to do something for a length of time. For example, one might say

ab, on wait 20 off

to turn the motors on for two seconds.

Please note that there are two different reference values for timing: 0.1 second units, used in wait and in note, and 0.004 second units, used in timer.

wait amount
Delays for amount of time, where amount is given in tenths-of-seconds. E.g., ``wait 10'' inserts a delay of one second.
beep
Plays a short beep.
note pitch duration
Plays a note of a specified pitch and duration. Increasing values of the pitch create lower tones (the pitch value is used as a delay counter to generate each half of the tone's squarewave). The duration value is specified in tenths-of-seconds units. The correspondence between the numbers used to define the pitch and the musical notes in the octave between middle c and high c is shown in the table below.

pitch number

119

110

110

105

100

100

94

89

84

84

79

74

74

70

66

66

62

59

musical notation

c

c#

db

d

d#

eb

e

f

f#

gb

g

g#

ab

a

a#

bb

b

c2
For example, "note 119 5" will play a middle c for half a second. Alternatively, the musical notation can be used directly: "note c 5" does the same thing.
timer
Reports value of free-running elapsed time device. Time units are reported in 4 millisecond counts.
resett
Resets elapsed time counter to zero.

Sensors

The Cricket has two sensors, named A and B.

sensora
Reports the value of sensor A, as a number from 0 to 255.
sensorb
Reports the value of sensor B, as a number from 0 to 255.
switcha
Reports true if the switch plugged into sensor A is pressed, and false if not.
switchb
Reports true if the switch plugged into sensor B is pressed, and false if not.

Control

Cricket Logo supports the following control structures:

loop [body]
Repetitively executes body indefinitely. Note: it is preferable to build a tail-recursive procedure than to use the loop construct; this will save 3 bytes of program space and one stack call.
repeat times [body]
Executes body for times repetitions. times may be a constant or calculated value.
if condition [body]
If condition is true, executes body. Note: a condition expression that evaluates to zero is considered true; non-zero expressions are false.
ifelse condition [body-1] [body-2]
If condition is true, executes body-1; otherwise, executes body-2.
waituntil[ condition]
Loops repeatedly testing condition, continuing subsequent program execution after it becomes true. Note that condition must be contained in square brackets; this is unlike the conditions for if and ifelse, which do not use brackets.
stop
Terminates execution of procedure, returning control to calling procedure.
output value
Terminates execution of procedure, reporting value as result.

Numbers

The "Red Dot" version of Cricket Logo uses 8-bit numbers. (The new "Blue Dot" Crickets use 16 bit numbers.) That's right, all numbers consist of values from 0 to 255. Numbers outside this range will "wrap around". For example "repeat 257 [beep wait 1]" is the same as "repeat 1 [beep wait 1]" and "send (4 - 6)" has the same effect as "send 254".

All arithmetic operators must be separated by a space on either side. E.g., the expression ``3+4'' is not valid. Use ``3 + 4''.

+
Infix addition.
-
Infix subtraction.
*
Infix multiplication.
/
Infix division.
%
Infix modulus (remainder after integer division).
and
Infix logical and operation (bitwise or).
or
Infix logical or operation (bitwise and).
not
Prefix bitwise not operation.
random
Reports pseudo-random number from 0 to 255.

Global Variables

Global variables are created using the global [variable-list] directive at the beginning of the procedures buffer. E.g.,

global [foo bar]

creates two globals, named foo and bar. Additionally, two global-setting primitives are created: setfoo and setbar. Thus, after the global directive is interpreted, one can say

setfoo 3

to set the value of foo to 3, and

setfoo foo + 1

to increment the value of foo.

Because global variables are stored in an electrically eraseable programmable read-only memory (eeprom) chip on the Cricket their values are persistent, their values will be maintained even when the power is turned off. The eeprom is specified to last through 10,000,000 write/erase cycles, a limit which means that one should avoid using "tight loops" that frequently reset the global variables for extended periods of time. For example the loop

loop [setfoo foo + 1]

will set the value of foo about 50 times a second, so that the limit of 10,000,000 writes will be reached in about 50 hours.

Procedure Inputs and Outputs

Procedures can accept arguments using the colon syntax. E.g.,

to arf :times
ab,
repeat :times [on wait 20 rd]
end

creates a procedure named arf that takes an input which is used as the counter in a repeat loop.

Procedures may return values using the output primitive; e.g.:

to go
ab,
repeat third [on wait 10 rd]
end

to third
if sensora < 20 [output 1]
if sensora < 50 [output 2]
output 3
end

The go procedure will execute 1, 2, or 3 times depending on the value of sensor A.

 

Data Recording and Playback

There is a single global array for storing data which holds 256 one-byte numbers. There is no error checking to prevent overrunning the data buffer.

setdp number Sets the value of the data pointer.

record value Records value in the data buffer and advances the data pointer.

recall value Reports the value of the current data point and advances the data pointer.

For example the procedure take-data can be used to store data recorded by a sensor once every second:

to take-data
setdp 0
repeat 255 [record sensora wait 10]
end

(You may wonder why the take-data procedure uses "repeat 255" when the data array can hold 256 points. This is done because in the red dot version of Cricket Logo, "repeat 256" is the same as "repeat 0"!)

The data can be "replayed" using the following send-data procedure:

to send-data
setdp 0
repeat 255 [send recall wait 5]
end

This causes the data to appear in the monitor box on the Cricket Logo screen on the desktop, updating twice a second. The Cricket Logo desktop also contains built-in graphing capabilities for rapidly uploading, graphing, and analyzing data.

 

Recursion

Cricket Logo supports tail recursion to create infinite loops. For example:

to beep-forever
beep wait 1
beep-forever
end

 

is equivalent to

to beep-forever
loop [beep wait 1]
end

The recursive call must appear as the last line of the procedure and cannot be part of a control structure like if or waituntil. Thus the following is not valid:

to beep-when-pressed
beep wait 1
if switcha [beep-when-pressed]
end

 

Infrared Communication

Overview

Crickets can send infrared signals to each other using the send primitive, and receive them using the ir primitive. The ir primitive reports the value sent by the send primitive, or 0 if there has been no IR code received since the last call to ir.

There are some subtleties regarding the ir primitive that can lead to confusion. There is a single byte of memory inside each Cricket that acts as the received IR buffer, storing only the infrared byte that was most recently received. The ir primitive reports the value of the number stored in the buffer and then clears the buffer , so that if the ir primitive is used again, before any new infrared communication is received, it will report 0.

To illustrate this point, suppose you wanted to use infrared communication to remotely select one of two different procedures for a Cricket to execute. Specifically, suppose you'd like a Cricket to run a procedure called thing-1 if you send a 1 via infrared and do a procedure called thing-2 if you send a 2. Note that the following will not work, because the infrared buffer is zeroed each time the ir primitive is used. Sending a 1 or a 2 causes the program to exit the waituntil loop, but subsequent use of the ir primitive in the if statements will report 0.

;this won't work!
to main
waituntil [ir > 0]
;wait for a non-zero infrared byte
if ir = 1 [thing-1]
;this test clears the ir buffer
if ir = 2 [thing-2]
;ir is zero now
end

to thing-1
...
end

to thing-2
...
end

One way to deal with this problem is illustrated in the program below. It uses a procedure called dispatch that copies the value reported by the ir primitive into a local variable and then tests the local variable:


to main
dispatch ir
main
end

to dispatch :value
if :value = 0 [stop]
if :value = 1 [thing-1]
if :value = 2 [thing-2]
end

to thing-1
...
end

to thing-2
...
end

Note that in this case it is desirable to use local variables instead of global variables in order to avoid frequent writes to the eeprom.

Details

If a Cricket is not running a procedure, codes from 128 to 129 are interpreted to launch remote-start lines 1 or 2 on the Cricket Logo screen.

Infrared codes in the range of 135 and higher are used by the underlying Cricket operating system as escape codes for infrared program download. Therefore please restrict general purpose user broadcast of IR codes to the range of 1 to 127.

Household TV/VCR remotes may also be used to cause the Cricket to launch its two remote-start lines. Use a Sony remote, or a universal remote set to talk to a Sony TV, and use the keys numbered 1 and 2.

Received infrared values issued with the send primitive are displayed on the Cricket Logo screen in the small text box next to the download button.

Mouse-click on the yet smaller grey box to the right of the text box can be used to enable display of these values (if they seem to be disabled).

The Button

When the Cricket is idle, pressing its pushbutton causes it to begin executing remote-start line 1 on the Cricket Logo screen.

When the Cricket is running a program, pressing the button causes it to halt.

Caveats

The maximum size of a Cricket Logo program is 1536 bytes. (If the record primitive is not used, programs as long as 1792 bytes are possible.) A maximum of 224 different global variables may be used.

When a program is downloaded, its size is displayed in the Microworlds command center.

Two Sample Programs

Dancing Crickets

Here's a simple program written by two 10 year old boys who had seen the "dancing Crickets" and wanted to build their own (single Cricket) version:

to dance
cha-cha-cha
go-round
shake-it
end 

to cha-cha-cha
repeat 4 [back-and-forth]
ab, off
end

to back-and-forth
ab, thisway onfor 3
beep
ab, thatway onfor 3
beep
end

to go-round
a, on thisway
b, on thatway
beep wait 1 beep wait 1 beep
wait 60
ab, off
end

to shake-it
a, thisway
b, thatway
ab,
repeat 10 [beep onfor 1 beep rd onfor 1 rd]
end

Note that these kids made their program easier to follow by nesting procedures inside of other procedures. For example, the procedure dance calls the procedure cha-cha-cha, which in turn calls back-and-forth.

The Wandering LEGObug

The LEGObug is a creature with two motors connected to its two rear wheels. It also has two touch sensors connected to two "whiskers" positioned on either sides of its head and two light sensors that serve as "eyes." Detailed plans for building the LEGObug are available at the following URL:

http://lc s.www.media.mit.edu/people/fredm/projects/legobug/

The procedure seek shown below causes the creature to be attracted to bright light. It assumes that the light sensors are plugged into the Cricket's sensor-ports. The light sensors have the property that the greater the amount of light that hits them, the smaller the sensor value that is produced. (In typical indoor lighting the light sensors might give readings in the 15 - 30 range, if you shine a flashlight on them, they will produce a reading in the 1 - 5 range. It takes almost complete darkness to produce a reading of 255.)

to seek
loop [
  ifelse (sensora < 10) or (sensorb < 10)
    [go-forward]
    [stop-motors]
  ]
end

to go-forward
ab, on thisway
;the motors are each hooked up so that the
        ;"thisway" direction causes them to drive forward
end

to stop-motors
ab, off
end

As an exercise you might try making creatures that run away from the dark, or ones that turn toward a bright light.

The procedure wander shown below causes LEGObug to drive straight until a whisker bumps into an obstacle. (It assumes that the touch sensors are plugged into the two sensor-ports.) In an attempt to avoid the obstacle, it the creature backs up a bit, turns a small (random) amount and continues to drive forward.

to wander
go-forward
waituntil [touch-left? or touch-right?]
ifelse touch-left?
  [back-up turn-right]
  [back-up turn-left]
wander
;Cricket Logo allows "tail recursion", an
       
;elegant alternative to using the "loop" primitive
end

to go-forward
ab, on thisway
end

;touch-left reports "true" if the sensor
;plugged into sensor-port "a" is pressed
to touch-left?
output switcha
end

;touch-left reports "true" if the sensor
;plugged into sensor-port "a" is pressed
to touch-right?
output switchb
end

;turns right for a random amount of time between 0 and 5 seconds.
;the primitive random reports a random number between 0 and 255
to turn-right
b, off 5
a, thisway onfor (random / 5)
end

to turn-left
a, off
b, thisway onfor (random / 5)
end

to back-up
ab, thatway onfor 20
end

 


Cricket Home Page
Epistemology and Learning Group
MIT Media Laboratory
20 Ames Street Cambridge, MA 02139
Mon Jul 7 10:14:36 1997