Events

Events are predefined robot functions into which you can embed conditional logic. When an event occurs, the conditional logic is called and then the program returns to the main loop where it left off. The event will be called every time it occurs by default, unless you customize it. For example, "on collision, change LED lights to red and play the Collision sound," then return to the main loop. 

==Note: In the basic examples below the logic in the main loop is nested in a while 1 loop. This ensures there is logic to "return" to after an event is called. If there was longer time delayed logic in the main loop, you would not need the while 1 loop.==

On Collision

onCollision() executes conditional logic when the robot collides with an object. 

async function onCollision() {

    // code to execute on collision

}

registerEvent(EventType.onCollision, onCollision);

For example, below is a basic pong program where Sphero bounces off walls, or your hands/feet in perpetuity. Place the robot on the floor between two parallel walls/objects and run the program with the robot pointed perpendicularly at one wall. On collision, the program will speak "collision" and change the LED's to red, then continue in the opposite direction: 

async function onCollision() {

stopRoll();

setMainLed({ r: 255, g: 0, b: 0 });

await speak("Collision", false);

setHeading((getHeading() + 180));

await delay(0.5);

setMainLed({ r: 255, g: 22, b: 255 });

setSpeed(100);

}

registerEvent(EventType.onCollision, onCollision);

async function startProgram() {

setMainLed({

r: 255,

g: 255,

b: 255

});

setSpeed(100);

}


Note:
onCollision() is not supported with RVR/RVR+, since repeated collisions can damage the motors.

On Total Distance

onTotalDistance() executes conditional logic when when a specific distance (in centimeters) has been traveled. 

async function onTotalDistance(distance) {

    // code to execute on specified total distance

}

registerEvent(EventType.onTotalDistance, onTotalDistance);

registerEventCondition(EventType.onTotalDistance, onTotalDistance, 50);

For example, below is a basic program in which BOLT+ rolls at a set speed until 50cm has been traveled, at which point a celebratory confetti animation is displayed on the BOLT+ LCD screen:

async function startProgram() {

setSpeed(100);

}


async function onTotalDistance(distance) {

stopRoll();

await setDisplayAnimation("confetti", true);

}

registerEvent(EventType.onTotalDistance, onTotalDistance);

registerEventCondition(EventType.onTotalDistance, onTotalDistance, 50);

Unlike many other event commands, you can use multiple instances of On Total Distance. For example, you can write code to execute at 50cm, 100cm, and 200cm, and all three instances will execute. Just make sure that each instance has a unique distance. 

Note:
onTotalDistance() is only supported with Sphero BOLT+.

On Time Elapsed

onTimeElapsed() executes conditional logic when when a specific time (in seconds) has elapsed

async function onTimeElapsed(program_run_time) {

    // code to execute on specified elapsed time

}

registerEvent(EventType.onTimeElapsed, onTimeElapsed);

registerEventCondition(EventType.onTimeElapsed, onTimeElapsed, 15);

For example, below is a basic program in which BOLT+ rolls at a set speed until 15 seconds has elapsed, at which point a celebratory confetti animation is displayed on the BOLT+ LCD screen:

async function startProgram() {

setSpeed(100);

}


async function onTimeElapsed(program_run_time) {

stopRoll();

await setDisplayAnimation("confetti", true);

}

registerEvent(EventType.onTimeElapsed, onTimeElapsed);

registerEventCondition(EventType.onTimeElapsed, onTimeElapsed, 15);

Unlike many other event commands, you can use multiple instances of On Time Elapsed. For example, you can write code to execute at 15s, 30s, and 60s, and all three instances will execute. Just make sure that each instance has a unique time

Note:
onTimeElapsed() is only supported with Sphero BOLT+.

On Ambient Light

onAmbientLight() executes conditional logic when when the ambient light in your environment is greater than or less than specified values.

async function onAmbientLight(ambientLight) {

    // code to execute on specified ambient light condition

}

registerEvent(EventType.onAmbientLight, onAmbientLight);

registerEventCondition(EventType.onAmbientLight, onAmbientLight, function check(ambientLight) { return ambientLight >= 500 });


Unlike many other event commands, you can use multiple instances of On Ambient Light. For example, below is a basic program in which the BOLT+ LEDs will change to green if the ambient light is above 500lux and change to red if the ambient light is below 400lux:

async function startProgram() {

}


async function onAmbientLight(ambientLight) {

setMainLed({ r: 0, g: 255, b: 0 });

}

registerEvent(EventType.onAmbientLight, onAmbientLight);

registerEventCondition(EventType.onAmbientLight, onAmbientLight, function check(ambientLight) { return ambientLight >= 500 });


async function onAmbientLight_2(ambientLight) {

setMainLed({ r: 255, g: 0, b: 0 });

}

registerEvent(EventType.onAmbientLight, onAmbientLight_2);

registerEventCondition(EventType.onAmbientLight, onAmbientLight_2, function check(ambientLight) { return ambientLight <= 400 });

Note:
onAmbientLight() is only supported with Sphero BOLT+.

On Button Selected

onSoftwareButton() executes conditional logic when the associated software button is selected.

async function onAmbientLight(ambientLight) {

    // code to execute on specified ambient light condition

}

registerEvent(EventType.onAmbientLight, onAmbientLight);

registerEventCondition(EventType.onAmbientLight, onAmbientLight, function check(ambientLight) { return ambientLight >= 500 });

You can define up to three software buttons. Each defined software button must have a unique name to ensure the program executes without errors. Unlike other on event commands, On Button Selected allows the user to directly control when the associated code executes, which opens up many interesting opportunities. 

The example below shows how these buttons can be combine in interesting ways with other BOLT+ commands. 

var _softwareButtonEvents = ['aim','honk horn','change LED color'];


async function startProgram() {

registerSoftwareButton(_softwareButtonEvents);


drive(true);

}


async function onSoftwareButton(button) {

if (button !== 'aim') return;


resetAim();

}

registerEvent(EventType.onSoftwareButton, onSoftwareButton);


async function onSoftwareButton_2(button) {

if (button !== 'honk horn') return;


await Sound.Mechanical.CarHorn.play(false);

}

registerEvent(EventType.onSoftwareButton, onSoftwareButton_2);


async function onSoftwareButton_3(button) {

if (button !== 'change LED color') return;


setMainLed(getRandomColor());

}

registerEvent(EventType.onSoftwareButton, onSoftwareButton_3);

In this example, we are turning BOLT+ into a horn honking car as we drive it around our environment. On program start, drive(true) allows the user to manually drive BOLT+ around their environment. The first button (titled "aim") is set to allow the user to reset their heading at will

async function onSoftwareButton(button) {

if (button !== 'aim') return;


resetAim();

The second button (titled "honk horn") allows the user to play a car horn sound effect at will:

async function onSoftwareButton_2(button) {

if (button !== 'honk horn') return;


await Sound.Mechanical.CarHorn.play(false);

The third button (titled "change LED color") allows the user to randomize the LEDs at will:

async function onSoftwareButton_3(button) {

if (button !== 'change LED color') return;


setMainLed(getRandomColor());

Note:
onSoftwareButton() is only supported with Sphero BOLT+.

On Freefall

onFreeFall() executes conditional logic when gravity is the only force acting on the robot, such as when dropping or throwing it. Free fall is measured by an accelerometer reading of < 0.1g for => 0.1s, where 1g is resting. On earth, objects in free fall accelerate downwards at 9.81 m/s². If you are in orbit, objects appear to be at rest with a reading of 0g because they (and you) are always in free fall, but they never hit the Earth.

async function onFreefall() {

    // code to execute on freefall

}

registerEvent(EventType.onFreefall, onFreefall);

For example, to speak "freefall" and change the LED's to red on freefall use: 

async function onFreefall() {

setMainLed({ r: 255, g: 0, b: 0 });

await speak("freefall", false);

await delay(0.5);

}

registerEvent(EventType.onFreefall, onFreefall);


async function startProgram() {

while (true) {

setMainLed({ r: 255, g: 255, b: 255 });

await delay(0.1);

}

}


Note:
onFreeFall() is not supported with RVR/RVR+, since repeated falls can damage mechanical components

On Landing

onLanding() executes conditional logic when the robot lands after being in free fall. You don't need to define an onFreeFall() event for the robot to experience an onLanding(), but the robot must meet the conditions for free fall before landing.

async function onLanding() {

    // code to execute on landing

}

registerEvent(EventType.onLanding, onLanding);

For example, to speak "landing" and change the LED's to green after landing use:

async function onLanding() {

setMainLed({ r: 0, g: 255, b: 0 });

await speak("landing", false);

await delay(0.5);

}

registerEvent(EventType.onLanding, onLanding);


async function startProgram() {

while (true) {

setMainLed({ r: 255, g: 255, b: 255 });

await delay(0.1);

}

}


Note:
onLanding() is not supported with RVR/RVR+, since repeated falls can damage mechanical components. 

On Gyro Max

onGyroMax() executes conditional logic when the robot exceeds the bounds of measurable rotational velocity of -2,000° - 2,000° per second. This can be triggered by spinning the robot around like a top on a table really fast. You need to spin it around > 5.5 revolutions per second.

async function onGyroMax() {

    // code to execute on gyromax

}

registerEvent(EventType.onGyroMax, onGyroMax);

For example, to speak "gyromax" and change the LED's to red when you reach gyromax, use:

async function onGyroMax() {

setMainLed({ r: 255, g: 0, b: 0 });

await speak("gyromax", true);

await delay(1.0);

}

registerEvent(EventType.onGyroMax, onGyroMax);


async function startProgram() {

setStabilization(false);

setBackLed(255);

while (true) {

setMainLed({ r: 255, g: 255, b: 255 });

await delay(0.5);

}

}


Note:
onGyroMax() is not supported with RVR/RVR+.

On Charging

onCharging() executes conditional logic called when the robot starts charging its battery. This can be triggered by placing your robot in it's charging cradle, or by plugging it in. 

async function onCharging() {

    // code to execute on charging

}

registerEvent(EventType.onCharging, onCharging);


Note:
onCharging() is not supported with RVR/RVR+ since the battery is physically removed when charging.
onCharging() is not supported with Mini since the Mini resets when charging starts.
onCharging() is not supported with BOLT+ since the BOLT+ resets when charging starts and connection is not supported while in the charging cradle. 

On Not Charging

onNotCharging() executes conditional logic called when the robot stops charging its battery. This can be triggered by removing your robot from it's charging cradle, or unplugging it.

async function onNotCharging() {

    // code to execute on charging

}

registerEvent(EventType.onCharging, onNotCharging);

For example, to have Sphero execute 3 different conditions for on, on charging, and on not charging, use:

async function onCharging() {

setMainLed({ r: 6, g: 0, b: 255 });

await speak("charging", true);

await delay(1.0);

await speak("remove me from my charger", true);

}

registerEvent(EventType.onCharging, onCharging);


async function onNotCharging() {

setMainLed({ r: 255, g: 0, b: 47 });

await speak("not charging", true);

await delay(2.0);

}

registerEvent(EventType.onNotCharging, onNotCharging);


async function startProgram() {

await speak("place me in my charger", true);

while (true) {

setMainLed({ r: 3, g: 255, b: 0 });

await delay(0.5);

}

}


Note:
onNotCharging() is not supported with RVR/RVR+ since the battery is physically removed when charging.
onNotCharging() is not supported with Mini since the Mini resets when charging starts.
onNotCharging() is not supported with BOLT+ since the BOLT+ resets when charging starts and connection is not supported while in the charging cradle. 

On IR Message Received

onIRMessage4(channel) executes conditional logic called when an infrared message is received on the specified channel. This can be triggered by one robot receiving a message from another robot. For example, to have Sphero BOLT change the matrix to red when receiving a message on channel 4 use:

var _messageChannels = [4];


async function startProgram() {

listenForIRMessage(_messageChannels);

}


async function onIRMessage4(channel) {

if (channel !== 4) return;


setMainLed({ r: 255, g: 0, b: 0 });


listenForIRMessage(_messageChannels);

}

registerEvent(EventType.onIRMessage, onIRMessage4);


Note:
onIRMessage4(channel) is supported with Sphero BOLT, BOLT+, and RVR/RVR+.

On Color

onColor(color) executes conditional logic called when Sphero RVR/RVR+'s color sensor returns a specified RGB color value.

var _colors = [{"r":255,"g":15,"b":60}];


async function startProgram() {

listenForColorSensor(_colors);

}


async function onColor(color) {

if (color.r !== 255 || color.g !== 15 || color.b !== 60) return;

}

registerEvent(EventType.onColor, onColor);

The color that RVR/RVR+'s color sensor returns needs to be very close to the color set with onColor(color) for the event to execute correctly. We recommend setting the desired color with the "on color" event block in the block canvas, then copying the RGB values into your JavaScript code. To accomplish this, do the following:

"On color" block popup:

Note:
The physical color sensor must be enabled for onColor(color) to execute correctly. If listenForColorSensor(_colors) is not included, then the color sensor will return an RGB value of 0,0,0 (black). Always ensure the following code is included while setting up onColor(color events:

async function startProgram() {

listenForColorSensor(_colors);

}