Skip to main content
SAM Script’s JavaScript mode gives you direct, text-based control over your SAM Labs hardware using a clean, purpose-built API. Every hardware block you connect to SAM Studio is accessible through the global SAM object. You can set outputs, read sensor values, respond to button presses, and build looping programs — all in standard JavaScript with a small set of extra tools built in.
SAM Script runs all JavaScript inside an async context, which means you must use await before any call that talks to hardware. Forgetting await is the most common mistake — your code will run but the hardware won’t respond as expected.

Connecting to a block

Before you can control a SAM hardware block, you need to connect to it by name. Use SAM.connect() and give it the block type as a string:
const led = await SAM.connect('led');
Store the result in a const (or let) variable. All subsequent calls to that block go through this variable.
If you have more than one block of the same type, SAM Studio will prompt you to select which physical block you mean when SAM.connect() runs.

Controlling hardware blocks

LED

Control the LED’s colour and brightness. Pass red, green, and blue values, each between 0 and 255:
const led = await SAM.connect('led');

// Set to orange
await led.setColor(255, 128, 0);

// Reduce brightness to 50 %
await led.setBrightness(50);

// Turn off completely
await led.turnOff();
MethodDescription
setColor(r, g, b)Sets the LED colour. Each channel is 0–255.
setBrightness(level)Sets brightness as a percentage (0–100).
turnOff()Turns the LED off.

Button

Connect to a button and register callback functions that fire when the button is pressed or released:
const button = await SAM.connect('button');

button.onPress(() => {
  console.log('Button pressed!');
});

button.onRelease(() => {
  console.log('Button released!');
});
You can also check the button’s current state at any point in your program:
const held = await button.isPressed();
console.log('Held down:', held);
MethodDescription
onPress(callback)Calls callback each time the button is pressed.
onRelease(callback)Calls callback each time the button is released.
isPressed()Returns true if the button is currently held down.

DC motor

Control the speed and direction of a DC motor:
const motor = await SAM.connect('dcMotor');

await motor.setSpeed(80);         // Run at 80 %
await motor.setDirection('forward');  // Set direction
await SAM.wait(2000);             // Wait 2 seconds
await motor.stop();               // Stop the motor
MethodDescription
setSpeed(percent)Sets motor speed as a percentage (0–100).
setDirection(dir)Sets direction — 'forward' or 'backward'.
stop()Stops the motor immediately.

Servo

Set a servo to a specific angle between 0 and 180 degrees:
const servo = await SAM.connect('servo');

await servo.setAngle(90);    // Centre position
await SAM.wait(1000);
await servo.setAngle(0);     // Rotate to 0 °
await SAM.wait(1000);
await servo.setAngle(180);   // Rotate to 180 °
MethodDescription
setAngle(degrees)Moves the servo to the given angle (0–180).

Light sensor

Read the current light level or register a callback that fires whenever the value changes:
const light = await SAM.connect('lightSensor');

// Read the current value once
const value = await light.getValue();
console.log('Light level:', value);

// React every time the value changes
light.onChange((newValue) => {
  console.log('New light level:', newValue);
});
MethodDescription
getValue()Returns the current light level (0–100).
onChange(callback)Calls callback with the new value whenever it changes.

Buzzer

Play musical notes or raw frequencies on a buzzer block:
const buzzer = await SAM.connect('buzzer');

// Play a note by name and duration (milliseconds)
await buzzer.playNote('C4', 500);
await SAM.wait(500);

// Play a raw frequency (Hz) for a duration (ms)
await buzzer.playFrequency(440, 1000);   // Concert A for 1 second
MethodDescription
playNote(note, duration)Plays a note (e.g. 'C4', 'G#3') for the given duration in ms.
playFrequency(hz, duration)Plays a raw frequency in hertz for the given duration in ms.

Pausing your program

Use SAM.wait() to pause execution for a set number of milliseconds:
await SAM.wait(1000);   // Pause for 1 second
await SAM.wait(500);    // Pause for half a second
Always await this call — without it your program won’t actually pause.

Loops and conditions

You can use any standard JavaScript control flow in SAM Script. Here’s a complete example that reads a button and changes an LED colour in a continuous loop:
const button = await SAM.connect('button');
const led = await SAM.connect('led');

while (true) {
  if (await button.isPressed()) {
    await led.setColor(0, 255, 0);   // Green while pressed
  } else {
    await led.turnOff();             // Off when released
  }
  await SAM.wait(100);   // Check 10 times per second
}
Adding a short SAM.wait() inside a while (true) loop is important. Without a pause, your program sends commands to the hardware as fast as possible, which can overwhelm the Bluetooth connection. A wait of 50–200 ms is usually enough.

Common patterns

There are two main ways to structure a SAM Script JavaScript program: event-driven and polling loops. Each suits different situations.
In an event-driven program, you register callback functions that run automatically when something happens — for example, when a button is pressed. Your main program doesn’t need to check anything repeatedly.Best for: reacting to button presses, timers, or other discrete events.
const button = await SAM.connect('button');
const led = await SAM.connect('led');

button.onPress(async () => {
  await led.setColor(255, 0, 255);   // Purple on press
  await SAM.wait(500);
  await led.turnOff();               // Off after 500 ms
});

button.onRelease(async () => {
  console.log('Button released');
});
When you use await inside a callback, mark the callback as async, as shown above.

Quick reference

TaskCode
Connect to a blockconst x = await SAM.connect('blockType')
Set LED colourawait led.setColor(r, g, b)
Set LED brightnessawait led.setBrightness(0–100)
Turn LED offawait led.turnOff()
Listen for button pressbutton.onPress(() => { … })
Listen for button releasebutton.onRelease(() => { … })
Check if button is heldawait button.isPressed()
Set motor speedawait motor.setSpeed(0–100)
Set motor directionawait motor.setDirection('forward')
Stop motorawait motor.stop()
Set servo angleawait servo.setAngle(0–180)
Read light sensorawait light.getValue()
React to light changeslight.onChange((v) => { … })
Play a noteawait buzzer.playNote('C4', 500)
Play a frequencyawait buzzer.playFrequency(440, 1000)
Pause executionawait SAM.wait(milliseconds)
Use console.log() to print values to the SAM Script console panel at the bottom of the editor. This is the quickest way to check what a sensor is reading or to trace through your program’s logic.