Version 1.2.9 · for StarCode v11.167.0 · 1 October 2026
Everything about StarCode, from the name of each panel on the screen to every block in the toolbox and the code it writes. Start at the beginning, or use the contents to jump to what you need.
Every picture in here is a real screenshot of the app. Download it as a PDF
| Part one | The two views, and the panels inside them | 2 |
| Part two | The categories | 7 |
| 1. Imports | 8 | |
| 2. Events | 12 | |
| 3. Motor | 13 | |
| 4. MotorGroup | 14 | |
| 5. Control | 16 | |
| 6. Sensors | 19 | |
| 7. Operators | 21 | |
| 8. Variables | 25 | |
| 9. Functions | 27 | |
| 10. Sound | 29 | |
| 11. Light | 30 | |
| 12. Timing | 31 | |
| 13. Remote | 33 | |
| 14. Circuit | 35 | |
| Part three | Ideas behind the code | 39 |
| Part four | Getting connected | 47 |
| Part five | What each robot can do | 50 |
| Part six | Words for the robot | 52 |
| Part seven | The Tutor | 53 |
| Part eight | Plans, codes and the portal | 56 |
| Part nine | Terms | 59 |
| Part ten | Every block, by robot and language | 66 |
StarCode has two screens, and you swap between them with the button in the top left corner. Each screen is made of panels, and every panel has its own name. You can drag the bars between them to make one bigger. The word category is saved for the colored circles in the toolbox, and nothing else.
Go to starcoderobot.com and press "Open StarCode". StarCode then asks for a code: "Enter your code to continue". The code for this launch is STARKID. A student with a class code from a teacher types that code instead. Either one opens the app. The code is remembered on that device for a year, so it is typed once.
The button that says "English ▾" opens the language menu, headed Input Language. It holds 22 languages: English, Spanish, French, German, Portuguese, Chinese, Japanese, Korean, Arabic, Hindi, Italian, Russian, Dutch, Turkish, Polish, Vietnamese, Bengali, Urdu, Indonesian, Marathi, Telugu and Thai. The whole app follows it: the categories, the titles, the buttons and every message. The blocks and the Syntax view do not change, because they are code, and code is written the same way in every language.
A canvas of widgets a child lays out themselves, and drives the robot with while the program runs. The app sorts them into three groups: Input, Buttons and Monitors. Every widget comes in the same three sizes, and the Camera has two more. Every widget takes its color from the color picker, and the colors are the app's own: blue, teal, purple, orange, pink and white.
| Widget | What it does |
|---|---|
| Input | |
| Joystick | Push it any way. It gives two numbers, one for across and one for up and down |
| Steering Wheel | Turn it left or right. It gives how far it is turned |
| Tilt | Reads the tablet's own tilt sensor and sends the angle to the robot, so tipping the tablet drives it. On an iPad it asks permission first, because Apple requires it |
| 6D Space | One control that gives three numbers at once: X, Y and Z |
| Slider V | A slider that moves up and down |
| Slider H | A slider that moves across |
| Level | Fills from the bottom and stays where you put it |
| Knob | Turn it around to set a number |
| D-Pad | Four arrows. Each direction is fully on or fully off, never in between |
| Buttons | |
| Button | Pressed or not pressed |
| N-Button | A pill shaped button, the shape of the buttons on the front of a board. It carries a letter, so two of them are A and B |
| E-Stop | Emergency stop. One press stops the robot |
| Toggle | On or off, and it stays where you leave it |
| Monitors | |
| Monitor | Shows a value from the program |
| Speed Gauge | Shows a speed on a dial |
| Radar | A display and nothing more. It reads two numbers the program publishes: which way the sensor is pointing, and how far it can see. How the sensor gets turned is the program's business. It keeps one reading per degree until the sensor comes around again, so the picture is always the last full turn |
| Timer | Two faces driven by one clock: a ring outside and numbers inside. Count up runs from zero. Count down runs to zero from whatever the plus and minus buttons set, and the numbers turn pink at zero |
| Camera | Shows what the robot's camera sees, once a robot is connected |
| The letter | A, B, C or K1 sits above each widget, so a child can say out loud which one they mean |
| Button | What it does |
|---|---|
| Handbook | Opens this handbook over the app |
| Full screen | Gives StarCode the whole screen. Made for a tablet |
| Install | Puts StarCode on the computer as its own app. It only appears where the browser offers it |
| Skins | The paint can. StarCode Dark or StarCode Light |
The control view has its own parts, and they come later in this handbook.
Block View
The whole left side of StarCode. The toolbox and the block canvas together.
|
Toolbox
The strip down the far left. It holds all the categories.
Not: library, palette, sidebar
|
Category
One colored circle in the toolbox. Click it and its blocks slide out.
Not: library
|
Block drawer
The blocks that slide out when you click a category. Drag one onto the canvas.
Not: menu, list
|
Block canvas
The big dotted space where you drag blocks and join them together.
Not: workspace, stage
|
Syntax view
The panel that shows your program as real written code, with line numbers.
Not: code view, output
|
Learn view
Where you can ask the StarCode Tutor a question about your program.
Not: AI panel, chat
|
Map
Where you lay out your steps before you build them, and join them with lines. Free for everybody.
Not: flowchart, diagram
|
Monitor
Shows what is plugged into each port right now, and what the robot is measuring.
Not: console, dashboard
|
Remote page
The control view with its widgets. The button to swap to it is in the top left corner.
Not: control view
|
Every category has its own color, and the blocks inside it are that color too. So a pink block on the canvas came from MotorGroup, wherever it ended up.
| Color | Category | What is in it |
|---|---|---|
| indigo | Imports | Importing your tools, and declaring your parts |
| yellow | Events | Where a program starts |
| blue | Motor | Turning one motor |
| pink | MotorGroup | Making several motors act as one |
| orange | Control | Loops, ifs, and waiting |
| teal | Sensors | Reading color, distance and force |
| green | Operators | Working out an answer, and comparing |
| dark orange | Variables | Making and changing your own names |
| red | Functions | Your own blocks, made from other blocks |
| bright pink | Sound | Beeps and notes |
| purple | Light | The lights and the display |
| light blue | Timing | Timers and waiting. Follows the skin, so it changes with the theme |
| mint | Remote | Sliders and buttons you press yourself |
| red and blue | Circuit | Pins on a board. Two colors because wiring has two sides |
In the order they sit in the toolbox, top to bottom.
Everything that has to happen before your program can run. It is first because it comes first in the code. It holds two kinds of blocks, and they are two different jobs in the same category: the ones that import a tool, and the ones that declare a part.
| Kind of block | Color | What it does |
|---|---|---|
| import lines | purple | Tell the robot to load a tool from its own library into your program |
| declaring lines | multicolored | Give a part its own name, so every block after it can use that name |
Every import line is purple. Every robot has its own library, so
every one uses its own words. The shape never changes.
Examples: from ev3dev2.motor import LargeMotor,
from pybricks.pupdevices import Motor,
from machine import Pin.
| Block | What it brings in |
|---|---|
from pybricks.pupdevices import ... | Motors and sensors |
from pybricks.parameters import ... | Port letters, colors and directions |
from pybricks.hubs import PrimeHub | SPIKE Prime itself |
from pybricks.robotics import DriveBase | Driving motors together |
from pybricks.tools import ... | Waiting and timers |
The declaring lines are multicolored: each one is the color of
the category its part belongs to. Each one makes a name. After that line, every block below can use
the name instead of saying the port again. Again the shape is the same on
every robot and only the words change. Examples:
motorA = LargeMotor(OUTPUT_A),
motorA = Motor(Port.A),
tank = MoveTank(OUTPUT_A, OUTPUT_B).
| Block | What it names |
|---|---|
hub = PrimeHub() | The hub, so you can use its lights, screen and tilt |
motorA = Motor(Port.A) | A motor in one port |
color_sensorA = ColorSensor(Port.A) | A color sensor |
distance_sensorA = UltrasonicSensor(Port.A) | A distance sensor |
force_sensorA = ForceSensor(Port.A) | A force sensor |
drive_base = DriveBase(motorA, motorB, 56, 114) | Two motors as one pair. The numbers are your wheel size and the gap between the wheels, in millimeters |
Open the Imports drawer and you will see one clear gap. That gap is deliberate. Everything above it imports a tool, and it is all purple. Everything below it declares a part, and it is multicolored. Above them both sits a flat-topped block that starts the stack and writes nothing but a comment.
| What you mean | Python | C++ | Java |
|---|---|---|---|
| Bring in a tool | from x import Motor | #include "ev3dev.h" | import lejos.hardware.motor.Motor; |
import. C++ says #include. Same
job, different word, so the category is called Imports in Python and Java and
Include in C++.
Pin(13, Pin.OUT),
Pin(13).value(1), PWM, ADC and
time_pulse_us all need a line from the machine library, and on the
micro:bit every pin block needs from microbit import *. In C++ the
pin commands, pinMode, digitalWrite,
digitalRead, analogWrite, analogRead,
tone and pulseIn, are built into the language, so
there is nothing to fetch and the Include stack stays empty. The one exception
is the servo. It needs #include <Servo.h> on the Arduino or
#include <ESP32Servo.h> on the ESP32, and a declaring line,
Servo servo13;. So the same flashing light program is two import
lines in Python and none in C++. That is the two languages being different, not
StarCode choosing.
On the top row, to the right of the Java button, sits a solid purple button with white writing and a small down arrow. It says Imports in Python and Java and Include in C++. It is there while the program on the canvas is missing a line it needs, and it is gone when the program is complete. It does not matter how the lines got there: one press of the button, dragging the blocks out of the Imports category one at a time, or some of each. The button watches the program. It does not remember whether it was pressed.
One press puts every missing line in, as real blocks in the Imports stack, with their own dropdowns. A student can open them, change them, or throw them away. The Imports stack goes in above everything else on the canvas. It never writes a line the Imports category does not offer.
Where a program begins.
| Block | What it does |
|---|---|
# Program start | The top of your program. Everything hangs underneath it |
async def task1(): | A second stack that runs at the same time as the first |
# comment here | A note for a human. The robot ignores it completely |
Python needs no start line. It simply runs from the top of the
file to the bottom, so in Python the Program start block writes only a comment,
# Program start, and it is green like every comment. C++ and Java
do need a start: the program begins inside a function with a special name, and
everything the program does goes inside its curly brackets.
| Language | The start line on the EV3 | The start line on a bare board |
|---|---|---|
| Python | # Program start | # Program start |
| C++ | int main() { | void setup() { |
| Java | public static void main(String[] args) throws Exception { | not offered |
Events in C++
The EV3 in C++. The program starts inside int main().
|
Events in Java
The EV3 in Java. The program starts inside main.
|
Turning one motor, and asking it questions.
The blocks shown here are the EV3's. Every robot has its own words for the same jobs, and Part ten lists them all.
| Block | What it does |
|---|---|
.on(...) | Turn at a speed and keep going |
.on_for_degrees(...) | Turn a set number of degrees, then stop |
.on_for_seconds(...) | Turn for a set time, then stop |
.stop() | Stop turning |
.position | How far it has turned so far |
.position = 0 | Call where it is now zero |
Making several motors act as one. Driving is the usual reason, but not the only one. Not every robot has all of these, because every library offers a different set: SPIKE Prime pairs two motors, the EV3 uses MoveTank and MoveSteering, and Pybricks builds a DriveBase. Where a robot has no equivalent, the block is not offered for that robot.
On the EV3 there are two ways to join motors, and both are here. Steering takes one speed and how hard to turn. Tank gives each side its own speed.
| Block | What it does |
|---|---|
steer.on(...) | Drive while turning, and keep going |
steer.on_for_degrees(...) | Drive a set number of degrees, then stop |
steer.on_for_seconds(...) | Drive for a set time, then stop |
tank.on(...) | Each side its own speed, and keep going |
tank.on_for_degrees(...) | Each side its own speed, for a number of degrees |
tank.on_for_seconds(...) | Each side its own speed, for a set time |
tank.off() | Stop both motors |
A group can hold any number of motors, which is what you want
for a robot with three or four wheels. But SPIKE Prime's own library only offers
pairs, exactly two, so on SPIKE Prime the blocks say motor_pair.
The category is the idea; the block is what that robot can really do.
Deciding what happens, and how many times.
| Block | What it does |
|---|---|
while True: | Keep going around and around, never stopping |
for i in range(10): | Go around a set number of times |
while <>: | Keep going while something is true |
while not(<>): | Keep going until something becomes true |
if <>: | Do this only when something is true |
if <>: else: | Do this, or else do that |
time.sleep(1) | Pause before the next line. On the EV3 it counts in seconds |
break | Jump out of the loop right now |
continue | Skip the rest of this time around |
raise SystemExit | End the whole program |
from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
tank = MoveTank(OUTPUT_A, OUTPUT_B)
# Program start
for i in range(4):
tank.on_for_seconds(SpeedPercent(50), SpeedPercent(50), 2)
tank.on_for_degrees(SpeedPercent(30), SpeedPercent(-30), 180)All three columns are the EV3's. This is where the languages look most different. The logic is identical every time; only the writing changes.
| What you mean | Python | C++ | Java |
|---|---|---|---|
| Go around forever | while True: | while(true) { | while(true) { |
| Go around ten times | for i in range(10): | for(int i=0;i<10;i++) { | for(int i=0;i<10;i++) { |
| Only if something is true | if x > 5: | if(x > 5) { | if(x > 5) { |
| Otherwise | else: | } else { | } else { |
| Wait one second | time.sleep(1) | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | Thread.sleep(1000); |
Reading what is going on around the robot.
| Block | What it does |
|---|---|
color1.color | What color the color sensor can see |
dist1.distance_centimeters | How far away something is |
touch1.is_pressed | Is it being pushed, yes or no. The only pointed one here |
gyro1.angle | Which way the robot has turned |
gyro1.rate | How fast it is turning right now |
gyro1.reset() | Call the way it is pointing now zero |
> or <. The color block is different: it gives
back a color, so it can only be compared with another color.
from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sensor import INPUT_3
tank = MoveTank(OUTPUT_A, OUTPUT_B)
color3 = ColorSensor(INPUT_3)
# Program start
while not (color3.color == ColorSensor.COLOR_RED):
tank.on(SpeedPercent(30), SpeedPercent(30))
tank.off()Working out an answer: adding numbers, comparing two things, and asking yes or no questions.
Every one of these gives back a yes or a no, never a number. That is why they fit in the pointed slot of an if block.
| Block | What you are asking | Example |
|---|---|---|
== | Are these two the same? | angle == 90 |
!= | Are these two different? | angle != 90 |
> | Is the first one bigger? | angle > 90 |
< | Is the first one smaller? | angle < 90 |
>= | Bigger, or exactly the same? | angle >= 90 |
<= | Smaller, or exactly the same? | angle <= 90 |
speed = 500 means make speed be 500.speed == 500 means is speed the same as 500? The answer is yes or no.
| Block | What it means | Yes when |
|---|---|---|
and | Both have to be true | both sides are yes |
or | Either one will do | at least one side is yes |
not | Flips the answer around | the thing inside was no |
| What you mean | Python | C++ | Java |
|---|---|---|---|
| Both have to be true | and | && | && |
| Either one will do | or | || | || |
| Flip the answer | not | ! | ! |
| Yes | True | true | true |
| No | False | false | false |
| Block | What it does | Example |
|---|---|---|
+ - * / | Add, take away, multiply, divide | speed + 100 |
% | The remainder after dividing. 7 % 2 is 1 | count % 2 |
** | To the power of. 2 ** 3 is 8 | 2 ** 3 |
| round | To the nearest whole number | round(3.7) |
| abs | Throws away the minus sign | abs(-40) |
| math.floor, math.ceil | Always down, or always up, to a whole number | math.floor(3.9) |
| sqrt | Square root | sqrt(16) |
| min, max | The smaller, or the bigger, of two | min(a, b) |
| random.randint | A surprise number in a range | random.randint(1, 6) |
| max(min()) | Keeps a number inside a low and a high. Called constrain in C++ | max(min(x, 100), 0) |
Not every value is a number. These three work on words.
| Block | What it does |
|---|---|
"" + "" | Joins two lots of words into one |
len("") | How many letters are in it |
"".split("") | Chops it up wherever a letter you choose appears |
count % 2 is 0 for every even number and 1 for every odd one. It
is how you make something happen every other time.
from ev3dev2.sound import Sound
import time
spkr = Sound()
# Program start
count = 0
while True:
count += 1
if count % 2 == 0:
spkr.play_tone(440, 0.1)
time.sleep(1)A variable is a name you make up to hold a value, such as a number, so your program can use it and change it later.
| Block | What it does |
|---|---|
x = 0 | Make a name, and give it a value |
x += 1 | Add to what is already in it |
x | Use what is in it |
True | A yes or a no you can put in a name |
print('x =', x) | Show its value on the screen, so you can see what went wrong |
import time
# Program start
x = 0
while True:
x += 1
print('x =', x)
time.sleep(1)All three columns are the EV3's.
| What you mean | Python | C++ | Java |
|---|---|---|---|
| Make a name holding a number | score = 0 | int score = 0; | int score = 0; |
| Add one to it | score += 1 | score++; | score++; |
| Show it on screen | print(score) | std::cout << score << std::endl; | System.out.println(score); |
motorA = Motor(Port.A) and score = 0 are the same
shape. One holds a motor, the other holds a number.
Making your own block out of other blocks.
| Block | What it does |
|---|---|
def my_function(): | Make a new block, and say what it does |
my_function() | Use the block you made |
return 0 | Send an answer back to whoever called it |
from ev3dev2.sound import Sound
import time
spkr = Sound()
def my_function():
spkr.play_tone(440, 0.1)
time.sleep(0.2)
spkr.play_tone(660, 0.1)
# Program start
my_function()
time.sleep(1)
my_function()Making the robot play a sound.
| Block | What it does |
|---|---|
spkr.play_tone(440, 1) | Play a note at a pitch, for a length of time |
Turning on the robot's lights and its display.
| Block | What it does |
|---|---|
leds.set_color('LEFT', 'RED') | Turn on one of the lights in a color |
Measuring how much time has passed.
| Block | What it does |
|---|---|
_timer_start = time.time() | Begin counting from zero |
(time.time() - _timer_start) | How long since it started, in seconds |
from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
import time
tank = MoveTank(OUTPUT_A, OUTPUT_B)
# Program start
_timer_start = time.time()
while (time.time() - _timer_start) < 3:
tank.on(SpeedPercent(50), SpeedPercent(50))
tank.off()The widgets you build on the remote control page, read by your program while it runs. Each block is the value of one widget, and it drops into any block that wants a number. They are the same on every robot and in every language.
| Block | What it reads |
|---|---|
remote_button_1 | A button, pressed or not |
remote_slider_A | Where a slider is |
remote_wheel_A | How far the steering wheel is turned |
remote_joy_A_x | One direction of a joystick |
remote_dpad_x | One direction of the D-Pad |
remote_toggle_1 | A toggle, on or off |
remote_space_x | One direction of the 6D Space |
from ev3dev2.motor import SpeedPercent, LargeMotor, OUTPUT_A
motorA = LargeMotor(OUTPUT_A)
# Program start
while True:
motorA.on(SpeedPercent(remote_slider_A))Wiring your own parts to a board, one pin at a time.
Circuit appears on robots with numbered pins, such as the ESP32, the Arduino and the micro:bit. The table and the picture here are the ESP32's, in Python.
| Block | What it does |
|---|---|
Pin(13, Pin.OUT) | Say whether a pin is listening or talking |
Pin(13).value(1) | Turn a pin fully on or fully off |
Pin(13).value() | Is this pin on or off |
Pin(13).value() == 1 | Is this pin on, yes or no |
PWM(Pin(13)).duty(512) | Turn a pin partly on, for dimming or speed |
ADC(Pin(13)).read() | Read a value that is not just on or off |
PWM(Pin(13), freq=50).duty_ns(500000 + 90 * 11111) | Move a servo to an angle, here 90 |
buzzer = PWM(Pin(13), freq=440) | Make a buzzer sound |
buzzer.deinit() | Stop the buzzer |
time_pulse_us(Pin(14), 1) | Time a pulse, which is how a distance sensor on two pins is read |
from machine import Pin
import time
# Program start
Pin(13, Pin.OUT)
while True:
Pin(13).value(1)
time.sleep_ms(500)
Pin(13).value(0)
time.sleep_ms(500)The tables above say what each block does. These are three finished programs, each one harder than the last. All three are on the EV3, so they match the pictures above. Every one has two stacks: the imports and declaring lines on one, and the program on the other.
Not words, and not blocks. These are the ideas a student has to understand before a program behaves the way they expect. Added to as they come up.
This is the one that explains most of the times a robot does something surprising.
| Kind | What it does | Looks like |
|---|---|---|
| Blocking | The program stops on that line and waits until the motor has finished. Nothing below it happens until then. | motorA.run_angle(500, 360)motorA.on_for_seconds(SpeedPercent(50), 1) |
| Non-blocking | The program turns the motor on and moves straight to the next line. The motor keeps going while everything below runs. | motorA.run(500)motorA.on(SpeedPercent(50)) |
The motor seems to do nothing on is non-blocking, so stop runs straight away. EV3, Python from ev3dev2.motor import SpeedPercent, LargeMotor, OUTPUT_A motorA = LargeMotor(OUTPUT_A) # Program start motorA.on(SpeedPercent(50)) motorA.stop() |
The motor runs for 2 seconds on_for_seconds is blocking, so stop waits its turn. EV3, Python from ev3dev2.motor import SpeedPercent, LargeMotor, OUTPUT_A motorA = LargeMotor(OUTPUT_A) # Program start motorA.on_for_seconds(SpeedPercent(50), 2) motorA.stop() |
A motor or a sensor is named in three places, and all three must
agree. The import line brings in the port, such as INPUT_1. The
declaring line gives the part a name on that port, such as
touch1 = TouchSensor(INPUT_1). And the cable on the robot has to be
plugged into port 1. If any one of the three says a different port, the program
reads the wrong port and the robot does nothing, or does the wrong thing, with
no error to tell you why.
from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import TouchSensor
from ev3dev2.sensor import INPUT_1
tank = MoveTank(OUTPUT_A, OUTPUT_B)
touch1 = TouchSensor(INPUT_1)
# Program start
while not (touch1.is_pressed):
tank.on(SpeedPercent(40), SpeedPercent(40))
tank.off()A program runs from the top down, one line at a time. The same blocks in a different order are a different program. Driving and then turning is not the same as turning and then driving.
Driving for 2 seconds is open loop: the robot does not check anything, so a low battery or a slippery floor changes how far it goes. Driving until a sensor says stop is closed loop: the robot checks and corrects, so it ends up in the same place every time. The drive a square example above is open loop; the touch sensor example is closed loop.
A threshold is the number a reading is compared with, such as dark when reflected light is below 40. Do not guess it. Print the sensor's value to the Monitor, hold the sensor over the dark part and the light part, and pick a number halfway between the two readings. A room with different light needs a different threshold.
When a robot does something unexpected, the program is doing exactly what it was told with the values it has. Print those values to the Monitor and you see what the robot sees. The counting example in Variables shows how.
Standard robot programs, written with StarCode's own blocks on the EV3 in Python. They use a drive base on ports A and B, a color sensor pointing down on port 3, and a distance sensor pointing forward on port 4. If your robot is wired differently, change the ports in the import and declaring lines so all three places match.
from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sensor import INPUT_3
tank = MoveTank(OUTPUT_A, OUTPUT_B)
color3 = ColorSensor(INPUT_3)
# Program start
while True:
if color3.reflected_light_intensity < 40:
tank.on(SpeedPercent(10), SpeedPercent(40))
else:
tank.on(SpeedPercent(40), SpeedPercent(10))from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sensor import INPUT_3
tank = MoveTank(OUTPUT_A, OUTPUT_B)
color3 = ColorSensor(INPUT_3)
# Program start
error = 0
while True:
error = color3.reflected_light_intensity - 40
tank.on(SpeedPercent(25 + error * 0.5), SpeedPercent(25 - (error * 0.5)))from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import UltrasonicSensor
from ev3dev2.sensor import INPUT_4
tank = MoveTank(OUTPUT_A, OUTPUT_B)
dist4 = UltrasonicSensor(INPUT_4)
# Program start
while True:
if dist4.distance_centimeters < 20:
tank.on_for_degrees(SpeedPercent(-30), SpeedPercent(30), 180)
else:
tank.on(SpeedPercent(40), SpeedPercent(40))from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import UltrasonicSensor
from ev3dev2.sensor import INPUT_4
tank = MoveTank(OUTPUT_A, OUTPUT_B)
dist4 = UltrasonicSensor(INPUT_4)
# Program start
turns = 0
while True:
if dist4.distance_centimeters < 25:
tank.off()
tank.on_for_seconds(SpeedPercent(-30), SpeedPercent(-30), 1)
turns += 1
if turns % 2 == 0:
tank.on_for_degrees(SpeedPercent(-30), SpeedPercent(30), 200)
else:
tank.on_for_degrees(SpeedPercent(30), SpeedPercent(-30), 200)
else:
tank.on(SpeedPercent(40), SpeedPercent(40))from ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_B
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sensor import INPUT_3
from ev3dev2.sensor.lego import UltrasonicSensor
from ev3dev2.sensor import INPUT_4
import time
tank = MoveTank(OUTPUT_A, OUTPUT_B)
color3 = ColorSensor(INPUT_3)
dist4 = UltrasonicSensor(INPUT_4)
# Program start
time.sleep(3)
while True:
if color3.color == ColorSensor.COLOR_WHITE:
tank.on_for_seconds(SpeedPercent(-50), SpeedPercent(-50), 1)
tank.on_for_degrees(SpeedPercent(40), SpeedPercent(-40), 300)
elif dist4.distance_centimeters < 50:
tank.on(SpeedPercent(100), SpeedPercent(100))
else:
tank.on(SpeedPercent(30), SpeedPercent(-30))How each robot connects, what it shows on itself, and what to do when something does not work.
This is the most common problem there is, and it is not a StarCode limit. The app opens and works in any browser. It is the connection to the robot that does not.
| On this | Use this |
|---|---|
| Mac | Chrome, and plug the robot in with a cable |
| Windows | Chrome or Edge, cable or Bluetooth |
| Chromebook | Chrome, cable or Bluetooth |
| Android | Chrome, Bluetooth |
| iPad | Nothing connects. Every iPad browser is Safari underneath, and Safari has no cable or Bluetooth connection. A child can still build, see the code and use Learn |
Everything is smaller on a tablet: the two top rows, the category column and the panel buttons. All fourteen categories fit down the side on an iPad held sideways, and both top rows use one button size, the way a computer does. The Full screen button gives StarCode the whole screen.
| Robot | How it connects |
|---|---|
| EV3 | The cable works, including on a Mac. Bluetooth works on Android. Bluetooth on a Mac does not: Chrome lists the EV3, then refuses to open it. Download to the EV3 works over the cable |
| micro:bit | V2 only. Cable and Bluetooth both work |
| SPIKE Prime | Bluetooth, on either of two firmwares, and StarCode asks which when SPIKE Prime is picked. The LEGO SPIKE firmware is what the hub comes with: programs only, no live control from the remote control canvas. The Pybricks firmware does programs and live control. The words on the blocks change between the two, because the two firmwares are two different sets of lines |
| ESP32 | Cable and Bluetooth both work, for live control and for running a program |
Press Connect. Under USB cable and Bluetooth is the install line, and it goes over the USB cable. On the ESP32 it reads Install StarCode, and puts StarCode's own firmware on the board. The micro:bit has two install choices of its own: Install for USB cable puts MicroPython on it, and Install for Bluetooth puts the Bluetooth build on it. The EV3 and SPIKE Prime have no install line. The files ship with the app, so nobody opens the Arduino IDE. A bar shows how far it has got, and a board that is not an ESP32 is refused rather than written to. A board with nothing on it is noticed on connecting and offered the firmware, instead of sitting there looking connected and doing nothing. This is a grown-up job that happens once.
The Name button sits beside the robot's name in the middle row, and opens Name this board. On an ESP32, type the number on the board's sticker, 1 to 99, and it calls itself StarCode 07 in the Bluetooth list from then on. The number survives being switched off, so it is set once when the kit is unpacked. The board restarts afterwards. An EV3 can be renamed the same way, because its own firmware takes a name and broadcasts it. A micro:bit cannot be renamed by anybody, so the button shows the five letters it was given instead, the same five letters on its own screen. A SPIKE Prime shows the name it already has.
A robot with a light or a screen says what it is doing, and each state looks different from across a room, so a teacher with twelve robots can see which one is waiting and which one has gone wrong without walking over.
| Robot | What it shows |
|---|---|
| micro:bit | A plug when it connects by cable, the Bluetooth mark when it connects that way, then a tick. The middle light breathes while it waits. An arrow while a program goes in, a square when stopped, a cross when something went wrong |
| EV3 | A word on the screen and a color on the buttons. READY green, SENDING orange, RUNNING orange, STOPPED green, ERROR red |
| SPIKE Prime | Pybricks firmware only. Green and a dash waiting, orange and S while a program goes in, green and X stopped, red and an exclamation mark when something went wrong |
| ESP32 | Nothing, unless a light is wired to a pin |
Stop is deliberately not something a student builds out of blocks, because a stop that runs through the program only works while the program is working. It ends the program and then switches the motors off, since ending a loop on its own leaves a motor turning at its last speed. Stop is pink, the same pink as an error line and a block that cannot work, so a child only has to learn one color for look here. On an EV3, the Escape button on the EV3 ends a downloaded program and stops the motors too.
When a robot is disconnected, StarCode releases it at once. The Monitor shows that the board is unplugged, Run no longer shows the program as running, and the Connect button returns to Connect. A motor or sensor disconnected from a port is removed from the Monitor when the robot's firmware reports it.
Run starts the program while the robot is connected to StarCode. Download stores the program on the robot itself, so it runs with no computer attached. If a robot cannot download yet, the Download button says so when it is pressed.
The handbook says in several places that not every robot can do everything. This is which. Each number is how many blocks that robot offers in that category, and a dash means none at all. Read out of the app itself, so it cannot claim something the app does not do.
| Robot | Language | Imports | Events | Motor | Group | Control | Sensors | Operators | Variables | Functions | Sound | Light | Timing | Circuit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SPIKE Prime on Pybricks firmware | Python | 11 | 3 | 11 | 12 | 10 | 12 | 23 | 5 | 3 | 2 | 6 | 3 | – |
| SPIKE Prime on LEGO firmware | Python | 6 | 3 | 9 | 9 | 10 | 11 | 23 | 5 | 3 | 3 | 6 | 3 | – |
| micro:bit | Python | 3 | 2 | – | – | 10 | 6 | 23 | 5 | 3 | 4 | 5 | 3 | 5 |
| ESP32 | Python | 3 | 3 | – | – | 10 | – | 23 | 5 | 3 | – | – | 3 | 10 |
| ESP32 | C++ | 5 | 3 | – | – | 11 | – | 22 | 6 | 3 | – | – | 3 | 10 |
| EV3 | Python | 12 | 3 | 8 | 7 | 10 | 8 | 23 | 5 | 3 | 1 | 1 | 3 | – |
| EV3 | C++ | 5 | 3 | 8 | – | 11 | 6 | 22 | 6 | 3 | 1 | 1 | 3 | – |
| EV3 | Java | 2 | 3 | 7 | 4 | 11 | 8 | 23 | 7 | 3 | 1 | 1 | 3 | – |
| Arduino | C++ | 5 | 2 | – | – | 11 | – | 22 | 6 | 3 | – | – | 3 | 10 |
The same on every robot. Each one says what it makes, and its arrow points the way the program travels across the screen.
| Button | Where | What it does |
|---|---|---|
| Generate syntax | under Block View | Writes your blocks out as code in the Syntax view. Free. The app does this by itself and never asks the Tutor |
| Generate blocks | under the Syntax view | Reads the code in the panel and builds the blocks. No Tutor at all: every block already knows the line it writes, so this is a lookup rather than a guess. It is exact, or it lists the lines it could not match |
| Generate syntax + blocks | under the Learn view | Turns what you typed as a question into code and blocks. It is part of Learn: the Tutor writes the program |
Type 600 into a place that only goes to 100, press enter, and it comes back as 100. Every limit is read from the robot's own reference, so a light level on the micro:bit stops at 9 and the same idea on SPIKE Prime stops at 100.
The Syntax view takes typing and pasting from the moment a language is chosen, and an empty one says so. A paste is stripped to plain text, so nothing carries over from wherever it was copied. Edit it, press Generate blocks again, and the blocks follow the change. The import lines become their own stack on the canvas, the way a child builds them, and every stack is laid out in the order it was pasted.
| It can read | Example |
|---|---|
| A block that writes two lines | The touch sensor import |
| A named block of lines | def my_function(): and everything under it |
| A word that comes with the name | distance_sensorB makes the block say UltrasonicSensor |
| A dropdown, by what it shows | rather than by what it holds |
| Brackets | Kept when writing the line back, because a - b * c is a different sum from (a - b) * c |
A program that has been downloaded is stored on the robot and runs with no computer attached. A program started with Run needs the robot to stay connected to StarCode. Part four explains Run and Download.
Port
A connection on a hub, marked with a letter or a number, such as port A or port 1. You plug a motor or a sensor into it.
Not: pin
|
Pin
A connection on the board with a number on it. You wire your own parts to it.
Not: port
|
Hub
A robot with a shell, ports and buttons, such as the EV3 or SPIKE Prime. Always call it by its own name.
Not: brick, controller
|
Board
The ESP32 or the Arduino. A bare board with numbered pins and nothing built in.
Not: the StarCode board
|
Firmware
The software living inside the robot itself, underneath your program.
Not: operating system
|
Dialect
A version of a language made for one kind of machine. The EV3 runs full Python; the ESP32, the micro:bit and SPIKE Prime run MicroPython, a smaller Python.
|
Written for parents and teachers. StarCode has a helper called the StarCode Tutor. A student opens the Learn panel, types a question in ordinary words in their own language, and gets an answer. It is not a general chatbot that happens to live in a coding app: it is fenced into one subject and it stays there. It is powered by Claude, an AI service from Anthropic.
StarCode's Tutor is not a general chatbot pointed at robots. It draws on four separate bodies of work.
| Star Kids teaching | Twelve years of Star Kids class logs, lesson plans and camp curriculum, taught to real children across after school classes and summer camps |
| Recorded lessons | 550 recorded robotics lessons from 381 other instructors across eight platforms, each broken into four things: what the student asked for in their own words, the exact blocks that answered it, why those blocks and not others, and the mistakes students commonly make on that task. 507 of them also record which sensors a given robot does not have, so the Tutor never suggests hardware that is not on the desk |
| Concept inventory | About eighty ideas across programming, controls, engineering and math, each carrying its difficulty, its grade level, and what has to be taught before it |
| Code reference | A per robot code reference covering five boards in three languages, which is what lets the same lesson run on a different robot without being rewritten |
The concepts run from the first day forward: sequencing, loops, if and else, variables and data types, functions, arrays, events, and debugging as a skill of its own. Then sensors and what each one can actually tell you, motors, encoders and gear ratios, parallel programs running two things at once, and combining more than one sensor to decide what to do. At the far end, closed loop control and PID, state machines, autonomous and driver controlled programming, and machine learning: object, face and audio recognition, supervised learning, and the sense, think, decide, act, learn loop that turns an AI decision into a robot actually moving.
Every time a student writes to it, StarCode sends it two things: the code on that student's canvas, and the exact list of blocks that student's robot can run.
Most of the time a robot that does nothing is not a coding problem. It is a wire in the wrong hole, a motor in a port the program is not using, or a part that was never working. The Tutor knows about both sides. It can walk a student through wiring an LED the right way around, the three wires on a servo and why only one of them carries instructions, which port a motor belongs in, and how to prove a part works before blaming the program.
It gives a hint before it gives an answer, and it will not write a student's program for them. Its first message is always the same question, "What would you like to learn?" It does not offer a menu. If a student says they do not know what to do, it looks at what they have already built and suggests one thing, not a list.
It teaches the line StarCode writes, not a block word. A student
who says "repeat until" is told once that it is while not in written
code, and from then on the Tutor says while not.
Every answer has a speaker under it that reads it out loud, in the student's own language from the language menu. The Tutor is told never to write emojis, and anything that slips through is taken out before the answer is read, because the voice would read a picture out by its long name.
Anything that is not StarCode, the program, or the robot. Homework in other subjects, stories, games, films, music, sport, famous people, the news, jokes, personal questions about the student or about itself, shopping, and other students.
The reply is always the same shape: one short friendly line saying it only helps with coding here, then a question about what they are building. It will not answer partly, briefly, or as a joke, and it will not hint toward an answer.
The Tutor does not counsel them and does not continue the conversation. It says kindly that this is something to tell their teacher, their parent, or another trusted adult, and stops.
You can see that a student has been using the Tutor, and roughly how much, in the progress record in the portal. You cannot see what was said. The conversation is not stored anywhere. It exists on the student's screen while they are working and is gone when the window closes. StarCode records only that a conversation took place and when.
| What follows from that | What to do |
|---|---|
| You cannot read transcripts to find who is struggling | Use the progress record instead. It shows repeated steps, long pauses with nothing built, and programs that failed several times, which are the signs the app can honestly observe |
| Students may treat it as private | Tell them plainly it is not a place to say private things, even though nobody reads it. It is a coding helper, and it will send them to you if they try |
In the portal, next to each student's name, there are two switches: AI Learn and Imports button. Each is set for one student at a time. AI Learn is on when a class starts. Imports button is on for every student until a teacher turns it off.
AI Learn: turn it off and the Learn button disappears from that student's screen, so they are not tapping something that does not respond.
Imports button: purple means on, grey means off. Turn it off and that student does not see the Imports button at all, so they find the missing lines themselves. The button in the app never changes color.
Generate syntax + blocks has no switch of its own. It lives inside the conversation, so it is on when AI Learn is on and off when AI Learn is off. Even with Learn on, it stays asleep until the Tutor decides there is a good reason to offer it, so it cannot be used as a shortcut on every task.
Once, at the start of a course, say these three things.
| The Tutor is a computer, not a person. |
| It only helps with coding. It will not answer anything else. |
| It can be wrong. If it says something, try it on your robot and see. |
There is a computer science standard, MS-PRO-RD-03, about students examining code an AI wrote and identifying its strengths and limits. The Tutor is a way to teach that directly.
For parents and teachers. The app is free with the launch code and no payment at all. Two things need a plan: Learn, which is the Tutor inside the app, and the portal that comes with it, where a parent or teacher looks in and sees what a student has been doing.
| Free | Paid, and optional |
|---|---|
| The blocks, the Syntax view, Map, the Monitor, every robot, every language, the remote control page, this handbook and the help page | Learn, and the portal that comes with it |
Pressing Learn or Portal opens the plans panel, "Unlock Learn and the portal". The card is taken by Stripe, on Stripe's own page.
| Plan | Monthly | Yearly |
|---|---|---|
| Teacher | $99 | $990 |
| Parent | $29 | $199 |
| Just me | $19 | $190 |
Teacher is for up to 12 students. Parent is for up to 2 children. Just me is for one person, over 18. AniBot is listed in the plans panel but is not for sale. Its card says "+ Add ons coming soon" and cannot be pressed.
Paying makes a code. It is shown on screen straight after paying, and emailed from starcode@starcoderobot.com to the address used at the checkout. Type it into the app to switch the paid parts on, and into the portal to see progress.
At starcoderobot.com/portal, type the code. Before signing in it just says Portal. After signing in it names itself for whoever bought it: Teacher Portal, Parent Portal, or My Progress.
| What it says | Teacher | Parent | Just me |
|---|---|---|---|
| The list | Your students | Your children | You |
| The big card | The class | Your children | You |
| The hour line | Their hour | Their hour | Your hour |
In the portal, click "Subscription and invoices", at the bottom of the classes screen. That is Stripe's own page: cancel, change the card and download every invoice there. Cancelling ends at the end of the month already paid for, not on the spot.
Every word this app uses, whether or not it appears earlier in this handbook. The parts above are where you learn a word; this is where you look one up. If a word here disagrees with the app, the app is wrong and gets changed.
| Say this | What it means | Not |
|---|---|---|
| Toolbox | The whole left panel holding the categories | library, palette, sidebar |
| Category | One colored circle in the toolbox | library |
| Block canvas | Where blocks are dragged and joined | workspace, stage |
| Syntax view | The middle panel showing the real code | code view, output |
| Learn view | Where the StarCode Tutor answers | AI panel, chat |
| Map | The other half of the right panel, for planning before writing | flowchart, diagram |
| Monitor | The live readings panel | console, dashboard |
| Remote page | The controller view with widgets | control view |
Remote, Undo, Reset, Skins, Handbook, Full screen, Install and Logout across the top. Python, C++ and Java, Portal, Name, Connect, Download, Run, Stop and Save across the second row. Under the block canvas, Generate syntax. Under the Syntax view, Generate blocks. Under the Learn view, Generate syntax + blocks.
StarCode Dark and StarCode Light. Never dark mode or light mode.
A step is one colored rectangle. A wire is a line joining two steps. The step being worked on wears a thin magenta ring, deliberately a color no step can be.
A block is always named by the exact code on its face, such as
while True:. Never by a description like "the loop block".
| Name | Where it runs |
|---|---|
| Pybricks Python | SPIKE Prime on Pybricks firmware. A version of MicroPython |
| MicroPython | ESP32, micro:bit, and SPIKE Prime on the LEGO SPIKE firmware. A cut down Python for small chips |
| Python | The full desktop Python. The EV3 on an ev3dev card runs this one |
Say which one. Python on its own is only correct for the full one.
Never say "the hub". It means nothing on its own, because every one of these has a hub.
| Say this | Not this |
|---|---|
| SPIKE Prime | the hub, SPIKE, the brick |
| SPIKE Prime on Pybricks firmware | Pybricks, the hub |
| SPIKE Prime on LEGO firmware | the newer firmware |
| EV3 | the brick, Mindstorms |
| ESP32 | the board, the StarCode board |
| micro:bit | microbit, the micro |
| Arduino | the board |
A port is a port on the robot. On the ESP32 the same idea is a pin. Those are the only two meanings we use.
| Term | What it means |
|---|---|
| Live control | The robot obeys the moment you move a slider, with no program sent. What the Remote page does |
| Download | Sending a whole program to the robot to be kept and run |
| Run | Starting the program while the robot is connected to StarCode |
| Direct commands | LEGO's name for the EV3's live control. One command in, the motor moves, with nothing installed on the EV3 |
Live control is required on every robot. That is a decision, not a preference.
By their headings: PORTS on a robot with ports, PINS on the ESP32, then REMOTE, VARIABLES, and the robot's own line at the bottom. The headings translate with the language; the meanings do not change.
| Where | What it is called |
|---|---|
| On screen | StarCode Tutor |
| In documents | Large Language Model StarCode Tutor |
Each part is called what is printed on it or what it is sold as: LED, resistor, breadboard, jumper wire, servo, potentiometer. No invented names, the same rule as everywhere else.
| Term | What it means |
|---|---|
| Program | A list of instructions a computer or robot carries out, in order |
| Code | The written instructions of a program, in a language such as Python, C++ or Java |
| Syntax | The rules for how a line of code must be written: the words, symbols and order a language accepts |
| Programming language | A set of words and rules for writing instructions a computer can follow. Python, C++ and Java are three |
| Algorithm | A step by step plan for solving a problem, written so a person can follow it before it becomes code |
| Pseudocode | An algorithm written in plain words that look like code but are not a real language |
| Sequencing | The order in which a program's lines run: top to bottom, one after another |
| Statement | One line of code that does something |
| Comment | A note in a program for people to read. The computer skips it. In Python it starts with #, in C++ and Java with // |
| Value | A single piece of information a program works with, such as the number 5, the word "hello", or True |
| Variable | A name that holds a value. The program can read the value and change it |
| Data type | The kind of value a variable holds: a whole number, a decimal number, a letter, some words, or True or False |
| Integer | A whole number with no decimal point, such as 7 or -3. Written int in C++ and Java |
| Float | A number with a decimal point, such as 0.5 or 3.14. Short for floating point |
| Character | One letter, digit or symbol, such as 'A'. Written char in C++ and Java |
| String | A piece of text: a row of characters, such as "Hello" |
| Boolean | A value that can only be True or False. Every yes or no question in a program gives back a boolean |
| Constant | A value that is set once and never changes while the program runs. Written const in C++ |
| Operator | A symbol that does something to values: + adds, == compares, and joins two questions |
| Expression | Values and operators put together to give one value, such as speed + 10 |
| Condition | A question whose answer is True or False, used to decide what happens next |
| Conditional statement | Code that runs only when a condition is True. if and else are conditional statements |
| Loop | Code that repeats. A for loop repeats a set number of times; a while loop repeats as long as a condition is True |
| Infinite loop | A loop that never ends, such as while True:. On a robot this is usually on purpose |
| Loop interrupt | Leaving a loop early. break leaves it completely; continue skips to the next time around |
| Function | A named group of lines that runs when it is called. Also called a method in Java |
| Parameter | A value a function is given to work with when it is called |
| Return value | The value a function sends back to whoever called it |
| Call | To run a function by writing its name followed by brackets |
| Library | A collection of code someone else wrote that a program brings in with an import |
| Import | The line that brings a library, or part of one, into a program. Called include in C++ |
| Declaring | Creating a name for a variable or a part before it is used, such as motorA = LargeMotor(OUTPUT_A) |
| Scope | Where in a program a name can be used. A name made inside a function can only be used inside it |
| Namespace | A group of names kept under one heading so two things with the same name do not clash, such as std:: in C++ |
| Enum | A short list of named values that go together, such as the colors a color sensor can report. Short for enumeration |
| Array | A list of values stored under one name and reached by their position, starting at 0 |
| List | Python's name for an array: several values kept in order under one name |
| Index | The position of a value in an array or a list, counting from 0 |
| Bug | A mistake in a program that makes it do something other than what was meant |
| Debugging | Finding and fixing bugs, often by printing values to see what the program is really doing |
| Showing a value as text. In StarCode printed values appear in the Monitor | |
| Input | Information going into a program, such as a sensor reading or a button press |
| Output | What a program sends out, such as turning a motor or lighting an LED |
| Event | Something that happens, such as a program starting or a button being pressed, that code can respond to |
| Multi-threading | Running more than one part of a program at the same time. Also called parallel programming |
| Object | A thing in code that holds its own values and has its own functions, such as a motor that knows its port and can be told to turn |
| Class | The plan an object is made from. LargeMotor is a class; motorA = LargeMotor(OUTPUT_A) makes one object from it |
| Object-oriented programming | Writing programs as objects that each hold their own values and functions. Often shortened to OOP |
| Inheritance | When one class takes all the abilities of another class and adds its own |
| Polymorphism | When different classes answer the same function call in their own way |
| Public and private | Whether a name inside a class can be used from outside it (public) or only inside it (private) |
| Pointer | In C++, a variable that holds the memory address of another value instead of the value itself |
| Reference | In C++, another name for a variable that already exists. & and * move between an address and a value |
| Static | A variable that keeps its value for the whole time a program runs, even between function calls |
| Compile | Turning code into instructions the machine runs directly. C++ and Java are compiled before they run |
| Compile time and run time | Compile time is when code is being turned into machine instructions; run time is when the program is actually running |
| Interpreter | A program that reads code and runs it line by line without compiling it first, the way Python usually runs |
| Firmware | The software that lives inside a robot or board, underneath your program |
| Dialect | A version of a language made for a particular kind of machine. MicroPython is a smaller Python made for small chips |
| MicroPython | A smaller version of Python made to run on small chips such as the ESP32 and the micro:bit |
| Term | What it means |
|---|---|
| Robot | A machine that senses what is around it, decides what to do, and acts |
| Hub | A robot's main unit with ports, buttons and a battery, such as the EV3 or SPIKE Prime |
| Board | A small circuit board with a chip and numbered pins, such as the ESP32 or the micro:bit |
| Microcontroller | A small computer on one chip that runs one program and controls hardware |
| Port | A connection on a hub, marked with a letter or a number, where a motor or sensor plugs in |
| Pin | A numbered electrical connection on a board, used to wire your own parts |
| Motor | A part that turns when it is given power |
| Servo | A motor that turns to an exact angle and holds it there |
| Encoder | A sensor inside a motor that counts how far it has turned |
| Sensor | A part that measures something, such as light, distance, touch or turning, and sends it to the robot as input |
| Touch sensor | A button sensor that reports whether it is pressed |
| Color sensor | A sensor that reports the color it sees or how much light bounces back |
| Reflected light | How much of the color sensor's own light bounces back. Dark surfaces reflect little, light ones a lot |
| Ultrasonic sensor | A distance sensor that sends out a sound too high to hear and times the echo |
| Gyro sensor | A sensor that measures turning: which way the robot has turned and how fast |
| Threshold | The value a sensor reading is compared with to decide something, such as 40 for dark and light |
| Calibration | Measuring what a sensor really reads on your own table and your own lines before choosing a threshold |
| Drive base | Two motors that drive a robot together, one on each side. Called a drive base, a tank or a motor pair depending on the library |
| Tank drive | Steering by giving each side of the robot its own speed |
| Steering | Driving by giving one speed and how hard to turn |
| Degrees | How far a motor turns. 360 degrees is one full turn |
| Speed | How fast a motor turns, often given as a percent of its top speed |
| Open loop control | Moving without checking a sensor, such as driving for 2 seconds and hoping the robot went far enough |
| Closed loop control | Moving while checking a sensor and correcting, such as driving until the distance sensor reads 10 cm. Also called a feedback system |
| Feedback | Information from a sensor that tells a program how its last action worked out |
| Bang bang control | The simplest closed loop control: full one way when below the target, full the other way when above it |
| Proportional control | Correcting a little when a reading is a little off and a lot when it is far off |
| PID | Proportional, Integral, Derivative: a control method that tunes three numbers so a robot reaches its goal smoothly without overshooting |
| Motion profile | A planned path of speeds a motor follows, such as speeding up, cruising, then slowing down |
| State machine | A program that is always in one of a few named states, such as searching or pushing, and moves between them on rules |
| Lag | A delay between an input and the robot's response. Also called hysteresis when the delay depends on direction |
| Line follower | A robot program that keeps a robot on a line using a color or light sensor |
| Obstacle avoidance | A robot program that detects something in the way and drives around it |
| Sumo | A robot competition where two robots try to push each other out of a ring |
| Term | What it means |
|---|---|
| Circuit | A complete loop that electricity flows around |
| Voltage | How hard electricity is pushed through a circuit, measured in volts |
| Current | How much electricity is flowing, measured in amps. Also called amperage |
| Resistance | How much a part slows the flow of electricity, measured in ohms |
| Ohm's law | Voltage equals current times resistance: V = I × R |
| LED | A light emitting diode: a small light that only works one way around, with a long leg and a short leg |
| Resistor | A part that limits current, often used to protect an LED |
| Breadboard | A board with rows of holes for building circuits without soldering |
| Jumper wire | A short wire with ends that push into a breadboard or a board's pins |
| Potentiometer | A knob that changes resistance as it turns, often read as a number |
| Digital | A signal that is only on or off, 1 or 0 |
| Analog | A signal that can be any value in a range, not just on or off |
| PWM | Pulse width modulation: switching a pin on and off very fast so a light looks dimmer or a motor runs slower |
| Wire gauge | The thickness of a wire. A bigger gauge number means a thinner wire |
| Torque | Turning force. More torque lets a motor push harder |
| Velocity | Speed in a particular direction |
| Acceleration | How quickly speed changes |
| Sine and cosine | Math functions that turn an angle into a number between -1 and 1, used to work out directions and positions |
| Remainder | What is left over after dividing. 7 % 2 is 1. The % operator is also called modulo |
| Name | What it says |
|---|---|
| Syntax Mirror Rule | A block exists only if the code it writes runs natively in that language on that robot |
| Language Parity Rule | Switching language keeps the logic and makes any loss visible. A block with no equivalent stays on the canvas, marked, and out of the generated code |
The Language Parity Rule is about blocks, not about the language buttons. The buttons show what a robot can run, and the reason a language is missing differs from robot to robot.
Taught in parts one to four, listed here so every word is in one place.
| Say this | What it means | Not |
|---|---|---|
| Block View | The whole left side: the toolbox and the block canvas together | |
| Block drawer | The blocks that slide out when a category is clicked | menu, list |
| Import | The line that brings in a tool before you use it. Called include in C++, and the category is called Include there too | |
| Library | The collection of code an import brings a tool in from. Lives in the robot's firmware, never shown on screen | the colored circles |
| Declaring | Creating a name for a part, such as motorA = Motor(Port.A) | |
| Statement | One line that does something | |
| Block, in code | A group of lines under a line ending in a colon, like a loop or an if | |
| Dialect | A version of a language made for one kind of machine | |
| Firmware | The software on the robot itself, underneath your program | operating system |
Every block StarCode offers, robot by robot, with the exact line
each one writes into the Syntax view. Read out of StarCode v11.167.0 itself, so it answers "does StarCode do this?" without opening it. Where a robot
runs more than one language, or SPIKE Prime runs on either firmware, they sit
side by side. [ ] is a space on the block for a number or another
block. A number shown is the one the block starts with. A block that writes two
lines shows both. Remote is not listed here, because its blocks are the same on
every robot and in every language, and they are in Part two.
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
# importfrom pybricks.pupdevices import Motorfrom pybricks.pupdevices import ColorSensorfrom pybricks.hubs import PrimeHubfrom pybricks.robotics import DriveBasefrom pybricks.tools import waitfrom pybricks.parameters import Colorhub = PrimeHub()motorA = Motor(Port.A)drive_base = DriveBase(motorA, motorB, 56, 114)color_sensorA = ColorSensor(Port.A) | # importimport motorimport motor_pairimport color_sensorimport runloopfrom hub import button |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
# Program startasync def task1():# comment here | # Program startasync def task1():# comment here |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
motorA.run(500)motorA.run_angle(500, 360)motorA.run_time(500, 1000)motorA.run_target(500, 90)motorA.stop()motorA.angle()motorA.reset_angle(0)motorA.speed()motorA.stalled()motorA.done()motorA.dc(100) | motor.run(port.A, 500)await motor.run_for_degrees(port.A, 360, 500)await motor.run_for_time(port.A, 1000, 500)await motor.run_to_relative_position(port.A, 90, 500)motor.stop(port.A)motor.relative_position(port.A)motor.reset_relative_position(port.A, 0)motor.velocity(port.A)motor.set_duty_cycle(port.A, 5000) |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
drive_base.drive(360, 0)drive_base.turn(90)drive_base.stop()drive_base.straight(200)drive_base.arc(100, 90)drive_base.use_gyro(True)drive_base.settings(200, 400, 90, 180)drive_base.angle()drive_base.distance()drive_base.reset(distance=0, angle=0)drive_base.stalled()drive_base.done() | motor_pair.pair(motor_pair.PAIR_1, port.A, port.B)motor_pair.unpair(motor_pair.PAIR_1)motor_pair.move(motor_pair.PAIR_1, 0, velocity=360)await motor_pair.move_for_degrees(motor_pair.PAIR_1, 360, 0, velocity=360)await motor_pair.move_for_time(motor_pair.PAIR_1, 1000, 0, velocity=360)motor_pair.move_tank(motor_pair.PAIR_1, 360, 360)await motor_pair.move_tank_for_degrees(motor_pair.PAIR_1, 360, 360, 360)await motor_pair.move_tank_for_time(motor_pair.PAIR_1, 360, 360, 1000)motor_pair.stop(motor_pair.PAIR_1) |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
while True:for i in range(10):while [ ]:while not ([ ]):if [ ]:if [ ]: … else:wait(1000)breakcontinueraise SystemExit | while True:for i in range(10):while [ ]:while not ([ ]):if [ ]:if [ ]: … else:time.sleep_ms(1000)breakcontinueraise SystemExit |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
color_sensorA.color()Color.REDdistance_sensorA.distance()force_sensorA.pressed()force_sensorA.touched()force_sensorA.force()hub.imu.heading()hub.imu.acceleration(Axis.X)hub.imu.angular_velocity(Axis.X)hub.imu.reset_heading(0)hub.imu.stationary()Button.LEFT in hub.buttons.pressed() | color_sensor.color(port.A)color.BLACKdistance_sensor.distance(port.A)force_sensor.pressed(port.A)force_sensor.force(port.A)motion_sensor.tilt_angles()[0]motion_sensor.acceleration(False)motion_sensor.angular_velocity(False)motion_sensor.reset_yaw(0)motion_sensor.stable()button.pressed(button.LEFT) > 0 |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
0 + 00 < 0[ ] and [ ]not [ ]round(0)abs(0)math.floor(0)math.ceil(0)math.sqrt(0)0 ** 20 % 1math.sin(0)math.cos(0)math.tan(0)min(0, 0)max(0, 0)0 <= 0 <= 100max(min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0random.randint(0, 10)'' + ''len('')''.split('') | 0 + 00 < 0[ ] and [ ]not [ ]round(0)abs(0)math.floor(0)math.ceil(0)math.sqrt(0)0 ** 20 % 1math.sin(0)math.cos(0)math.tan(0)min(0, 0)max(0, 0)0 <= 0 <= 100max(min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0random.randint(0, 10)'' + ''len('')''.split('') |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
x = 0x += 1xTrueprint('x =', x) | x = 0x += 1xTrueprint('x =', x) |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
def my_function():my_function()return 0 | def my_function():my_function()return 0 |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
hub.speaker.beep(440, 500)hub.speaker.volume(100) | await sound.beep(440, 500, 100)sound.stop()sound.volume(100) |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
hub.light.on(Color.RED)hub.display.pixel(0, 0, 50)hub.display.icon(Matrix([[50]*5]*5))hub.display.icon(Icon.HAPPY)hub.display.text('')hub.display.off() | light.color(light.POWER, color.RED)light_matrix.set_pixel(0, 0, 50)light_matrix.show([50] * 25)light_matrix.show_image(light_matrix.IMAGE_HEART)light_matrix.write('')light_matrix.clear() |
| Pybricks firmware, Python | LEGO firmware, Python |
|---|---|
_timer = StopWatch()_timer.time()_timer.reset() | _timer_start = time.ticks_ms()time.ticks_diff(time.ticks_ms(), _timer_start)_timer_start = time.ticks_ms() |
| Python |
|---|
# importfrom microbit import *import music |
| Python |
|---|
# Program start# comment here |
| Python |
|---|
while True:for i in range(10):while [ ]:while not ([ ]):if [ ]:if [ ]: … else:sleep(1000)breakcontinueraise SystemExit |
| Python |
|---|
compass.heading()accelerometer.get_x()accelerometer.is_gesture('shake')microphone.was_event(SoundEvent.LOUD)button_a.is_pressed()button_a.get_presses() |
| Python |
|---|
0 + 00 < 0[ ] and [ ]not [ ]round(0)abs(0)math.floor(0)math.ceil(0)math.sqrt(0)0 ** 20 % 1math.sin(0)math.cos(0)math.tan(0)min(0, 0)max(0, 0)0 <= 0 <= 100max(min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0random.randint(0, 10)'' + ''len('')''.split('') |
| Python |
|---|
x = 0x += 1xTrueprint('x =', x) |
| Python |
|---|
def my_function():my_function()return 0 |
| Python |
|---|
music.pitch(440, 500)music.play(music.DADADADUM, wait=False, loop=True)music.stop()set_volume(100) |
| Python |
|---|
display.set_pixel(0, 0, 9)display.show(Image.HEART)display.show(Image('00000:00000:00000:00000:00000'))display.scroll('', delay=150)display.clear() |
| Python |
|---|
_timer_start = running_time()(running_time() - _timer_start)_timer_start = running_time() |
| Python |
|---|
pin0.write_digital(1)pin0.read_digital()pin0.is_touched()pin0.write_analog(511)pin0.read_analog() |
| Python | C++ |
|---|---|
# importfrom machine import Pinimport time | // include#include <ESP32Servo.h>const int motorA = 13;const int dirA = 25;Servo servo13; |
| Python | C++ |
|---|---|
# Program startasync def task1():# comment here | void setup() {void task1(void *p) {// comment here |
| Python | C++ |
|---|---|
while True:for i in range(10):while [ ]:while not ([ ]):if [ ]:if [ ]: … else:time.sleep_ms(1000)breakcontinueraise SystemExit | while(true) {for(int i=0;i<10;i++) {while([ ]) {while(!([ ])) {if([ ]) {if([ ]) { … } else {delay(1000);break;continue;switch(x) {return; |
| Python | C++ |
|---|---|
0 + 00 < 0[ ] and [ ]not [ ]round(0)abs(0)math.floor(0)math.ceil(0)math.sqrt(0)0 ** 20 % 1math.sin(0)math.cos(0)math.tan(0)min(0, 0)max(0, 0)0 <= 0 <= 100max(min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0random.randint(0, 10)'' + ''len('')''.split('') | 0 + 00 < 0[ ] && [ ]![ ]round(0)abs(0)floor(0)ceil(0)sqrt(0)pow(0, 2)0 % 1sin(0)cos(0)tan(0)min(0, 0)max(0, 0)0 >= 0 && 0 <= 100constrain(0, 0, 100)map(0, 0, 0, 0, 0)random(0, 10)"" + """".length() |
| Python | C++ |
|---|---|
x = 0x += 1xTrueprint('x =', x) | int x = 0;x += 1;x++;x--;xSerial.print("x = "); Serial.println(x); |
| Python | C++ |
|---|---|
def my_function():my_function()return 0 | void my_function() {my_function();return 0; |
| Python | C++ |
|---|---|
_timer_start = time.ticks_ms()time.ticks_diff(time.ticks_ms(), _timer_start)_timer_start = time.ticks_ms() | unsigned long _timer_start = millis();(millis() - _timer_start)_timer_start = millis(); |
| Python | C++ |
|---|---|
Pin(13, Pin.OUT)Pin(13).value(1)Pin(13).value()Pin(13).value() == 1PWM(Pin(13)).duty(512)ADC(Pin(13)).read()PWM(Pin(13), freq=50).duty_ns(500000 + 90 * 11111)buzzer = PWM(Pin(13), freq=440)buzzer.deinit()time_pulse_us(Pin(14), 1) | pinMode(13, OUTPUT);digitalWrite(13, HIGH);digitalRead(13)digitalRead(13) == HIGHanalogWrite(13, 128);analogRead(A0)servo13.write(90);tone(13, 440, 500);noTone(13);pulseIn(14, HIGH) |
| Python | C++ | Java |
|---|---|---|
# importfrom ev3dev2.motor import SpeedPercent, LargeMotor, OUTPUT_Afrom ev3dev2.motor import SpeedPercent, MoveTank, OUTPUT_A, OUTPUT_Bfrom ev3dev2.sensor.lego import TouchSensorfrom ev3dev2.sound import Soundimport timemotorA = LargeMotor(OUTPUT_A)tank = MoveTank(OUTPUT_A, OUTPUT_B)touch1 = TouchSensor(INPUT_1)btn = Button()spkr = Sound()leds = Leds() | // include#include "ev3dev.h"using namespace ev3dev;large_motor motorA(OUTPUT_A);touch_sensor touch1(INPUT_1); | // importimport lejos.hardware.motor.Motor; |
| Python | C++ | Java |
|---|---|---|
# Program startasync def task1():# comment here | int main() {void task1() {// comment here | public static void main(String[] args) throws Exception {Thread task1 = new Thread(() -> {// comment here |
| Python | C++ | Java |
|---|---|---|
motorA.on(SpeedPercent(50))motorA.on_for_degrees(SpeedPercent(50), 360)motorA.on_for_seconds(SpeedPercent(50), 1)motorA.stop()motorA.positionmotorA.position = 0motorA.is_stalledmotorA.is_running | motorA.set_speed_sp(500); motorA.run_forever();motorA.set_speed_sp(500); motorA.set_time_sp(1000); motorA.run_timed();motorA.stop();motorA.set_speed_sp(500); motorA.set_position_sp(360); motorA.run_to_rel_pos();motorA.position()motorA.set_position(0);motorA.state().count("stalled")motorA.state().count("running") | Motor.A.setSpeed(450); Motor.A.forward();Motor.A.setSpeed(450); Motor.A.rotate(360);Motor.A.setSpeed(450); Motor.A.forward(); Thread.sleep(1000);Motor.A.stop();Motor.A.getTachoCount()Motor.A.resetTachoCount();Motor.A.isStalled() |
| Python | C++ | Java |
|---|---|---|
steer.on(0, SpeedPercent(50))steer.on_for_degrees(0, SpeedPercent(50), 360)steer.on_for_seconds(0, SpeedPercent(50), 1)tank.on(SpeedPercent(50), SpeedPercent(50))tank.on_for_degrees(SpeedPercent(50), SpeedPercent(50), 360)tank.on_for_seconds(SpeedPercent(50), SpeedPercent(50), 1)tank.off() | – | pilot.setLinearSpeed(360); pilot.forward();pilot.setLinearSpeed(360); pilot.travel(50);pilot.setLinearSpeed(360); pilot.forward(); Thread.sleep(1000);pilot.stop(); |
| Python | C++ | Java |
|---|---|---|
while True:for i in range(10):while [ ]:while not ([ ]):if [ ]:if [ ]: … else:time.sleep(1)breakcontinueraise SystemExit | while(true) {for(int i=0;i<10;i++) {while([ ]) {while(!([ ])) {if([ ]) {if([ ]) { … } else {std::this_thread::sleep_for(std::chrono::milliseconds(1000));break;continue;switch(x) {return 0; | while(true) {for(int i=0;i<10;i++) {while([ ]) {while(!([ ])) {if([ ]) {if([ ]) { … } else {Thread.sleep(1000);break;continue;switch(x) {System.exit(0); |
| Python | C++ | Java |
|---|---|---|
color1.colorColorSensor.COLOR_NOCOLORdist1.distance_centimeterstouch1.is_pressedgyro1.anglegyro1.rategyro1.reset()btn.up | color1.color()dist1.distance_centimeters()touch1.is_pressed()gyro1.angle()gyro1.rate()button::up.pressed() | new EV3ColorSensor(SensorPort.S1).getColorID()Color.REDnew EV3UltrasonicSensor(SensorPort.S1).getDistanceMode().fetchSample(sample, 0)new EV3TouchSensor(SensorPort.S1).isPressed()new EV3GyroSensor(SensorPort.S1).getAngleMode().fetchSample(sample, 0)new EV3GyroSensor(SensorPort.S1).getRateMode().fetchSample(sample, 0)new EV3GyroSensor(SensorPort.S1).reset();Button.LEFT.isDown() |
| Python | C++ | Java |
|---|---|---|
0 + 00 < 0[ ] and [ ]not [ ]round(0)abs(0)math.floor(0)math.ceil(0)math.sqrt(0)0 ** 20 % 1math.sin(0)math.cos(0)math.tan(0)min(0, 0)max(0, 0)0 <= 0 <= 100max(min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0random.randint(0, 10)'' + ''len('')''.split('') | 0 + 00 < 0[ ] && [ ]![ ]round(0)abs(0)floor(0)ceil(0)sqrt(0)pow(0, 2)0 % 1sin(0)cos(0)tan(0)min(0, 0)max(0, 0)0 >= 0 && 0 <= 100std::max(0, std::min(100, 0))((0 - 0) / (0 - 0)) * (0 - 0) + 0rand() % (10 - 0 + 1) + 0"" + """".length() | 0 + 00 < 0[ ] && [ ]![ ]Math.round(0)Math.abs(0)Math.floor(0)Math.ceil(0)Math.sqrt(0)Math.pow(0, 2)0 % 1Math.sin(0)Math.cos(0)Math.tan(0)Math.min(0, 0)Math.max(0, 0)0 >= 0 && 0 <= 100Math.max(Math.min(0, 100), 0)((0 - 0) / (100 - 0)) * (1 - 0) + 0(int)(Math.random() * (10 - 0)) + 0"" + """".length()"".split("") |
| Python | C++ | Java |
|---|---|---|
x = 0x += 1xTrueprint('x =', x) | int x = 0;x += 1;x++;x--;xstd::cout << "x = " << x << std::endl; | int x = 0;x += 1;x++;x--;xtrueSystem.out.println("x = " + x); |
| Python | C++ | Java |
|---|---|---|
def my_function():my_function()return 0 | void my_function() {my_function();return 0; | void my_function() {my_function();return 0; |
| Python | C++ | Java |
|---|---|---|
spkr.play_tone(440, 1) | sound::tone(440, 500); | Sound.playTone(440, 500); |
| Python | C++ | Java |
|---|---|---|
leds.set_color('LEFT', 'RED') | led::set_color(led::left, led::red); | Button.LEDPattern(0); |
| Python | C++ | Java |
|---|---|---|
_timer_start = time.time()(time.time() - _timer_start)_timer_start = time.time() | auto _timer_start = std::chrono::steady_clock::now();std::chrono::duration<double>(std::chrono::steady_clock::now() - _timer_start).count()_timer_start = std::chrono::steady_clock::now(); | long _timer_start = System.currentTimeMillis();(System.currentTimeMillis() - _timer_start)_timer_start = System.currentTimeMillis(); |
| C++ |
|---|
// include#include <Servo.h>const int motorA = 13;const int dirA = 25;Servo servo13; |
| C++ |
|---|
void setup() {// comment here |
| C++ |
|---|
while(true) {for(int i=0;i<10;i++) {while([ ]) {while(!([ ])) {if([ ]) {if([ ]) { … } else {delay(1000);break;continue;switch(x) {return; |
| C++ |
|---|
0 + 00 < 0[ ] && [ ]![ ]round(0)abs(0)floor(0)ceil(0)sqrt(0)pow(0, 2)0 % 1sin(0)cos(0)tan(0)min(0, 0)max(0, 0)0 >= 0 && 0 <= 100constrain(0, 0, 100)map(0, 0, 0, 0, 0)random(0, 10)"" + """".length() |
| C++ |
|---|
int x = 0;x += 1;x++;x--;xSerial.print("x = "); Serial.println(x); |
| C++ |
|---|
void my_function() {my_function();return 0; |
| C++ |
|---|
unsigned long _timer_start = millis();(millis() - _timer_start)_timer_start = millis(); |
| C++ |
|---|
pinMode(13, OUTPUT);digitalWrite(13, HIGH);digitalRead(13)digitalRead(13) == HIGHanalogWrite(13, 128);analogRead(A0)servo13.write(90);tone(13, 440, 500);noTone(13);pulseIn(14, HIGH) |