Sequencer

Native sequencer operation in Koheron V1 firmware.
Firmware V1 documentation · V1.0-rc54-2d701ce

Koheron products currently ship with firmware V0.x by default. Firmware V1 is under active development and is not publicly available yet.

Contact us if you would like early access or want to evaluate V1 firmware on your device.

Sequencer

The sequencer executes a program directly on the device without requiring continuous communication with the computer.

A program can:

  • read measurements and status fields;
  • change device settings;
  • perform integer, floating-point, and bitwise operations;
  • compare values and make conditional jumps;
  • implement loops;
  • wait for precise time intervals.

Programs are written, transferred, started, and monitored from the Koheron Control GUI.

Available fields and commands

The instructions available to a program depend on the connected device and firmware.

The GUI reads two descriptions from the device:

  • fmtlist lists the status fields that can be read with RD;
  • fmtseq lists the commands that can be written with WR.

The final line returned by each command is a four-digit hexadecimal CRC. The CRC identifies the complete field or command schema.

The GUI stores these CRCs in the program. When the firmware loads the program, it checks that they still match the current firmware.

This prevents a program from reading or writing the wrong item after a firmware update.

Users do not need to calculate or enter the CRCs manually. After a firmware update, transfer the program again from the GUI.

Program structure

A program is a list of instructions executed in order.

FSET 25.0 r0
WR tset r0
WAIT 5000
RD tact r1
END

This program:

  1. stores 25.0 in r0;
  2. writes it to tset;
  3. waits 5000 milliseconds;
  4. reads tact into r1;
  5. finishes.

A program can contain up to 63 instructions, including the final END.

Comments, blank lines, and labels do not count as instructions.

Registers

The sequencer provides 16 general-purpose 32-bit registers:

r0
r1
...
r15

Registers can contain:

  • signed or unsigned integers;
  • bit masks;
  • IEEE-754 single-precision floating-point values;
  • raw values read from the device.

The instruction determines how the register bits are interpreted.

Syntax

Operands are written source-first and destination-last.

ADD r0 r1 r2

means:

r2 = r0 + r1

The editor accepts:

  • blank lines;
  • labels;
  • // comments;
  • ; comments;
  • decimal integers;
  • hexadecimal integers starting with 0x;
  • floating-point literals.

Example:

// Set the temperature
FSET 25.0 r0
WR tset r0

; Wait for stabilization
WAIT 5000

END

Core instructions

NOP

Do nothing.

NOP

END

Finish the program.

END

END must be the final instruction.

WAIT

Wait for a number of milliseconds.

WAIT 1000

A register can also contain the delay:

SET 1000 r0
WAIT r0

The delay must be between 0 and 2147483647 milliseconds.

Integer instructions

SET

Store an integer value.

SET 100 r0
SET 0xFF r1

MOV

Copy a register.

MOV r0 r1

ADD

Add two registers.

ADD r0 r1 r2

SUB

Subtract two registers.

SUB r0 r1 r2

Integer addition and subtraction wrap modulo 232.

CMP

Compare two registers as signed 32-bit integers.

CMP r0 r1
JCC LT lower

Floating-point instructions

Floating-point operations use IEEE-754 single-precision values.

FSET

Store a floating-point literal.

FSET 25.0 r0
FSET -0.125 r1

Arithmetic

FADD r0 r1 r2
FSUB r0 r1 r2
FMUL r0 r1 r2
FDIV r0 r1 r2

FCMP

Compare two floating-point registers.

FCMP r0 r1
JCC GT above_limit

When the comparison is unordered, for example because one value is NaN, only NE is true.

Bitwise instructions

AND r0 r1 r2
OR  r0 r1 r2
XOR r0 r1 r2
NOT r0 r1

TST

The sequencer executes a compiled KSEQ version 1 binary from a dedicated 1024-byte user EEPROM allocation. Source text exists only on the host; firmware loads a 16-byte header and up to 63 fixed 16-byte records. The maximum is 62 executable instructions followed by mandatory END.

Labels and jumps

A label identifies an instruction position.

start:
    WAIT 100
    JMP start

JMP

Jump unconditionally.

JMP target

JCC

Jump according to the result of the most recent CMP, FCMP, or TST.

JCC EQ target
JCC NE target
JCC LT target
JCC LE target
JCC GT target
JCC GE target

Example:

CMP r0 r1
JCC LT below_limit

Reading device values

Use RD to read a field listed by fmtlist.

RD tact r0

Examples may include:

RD tact r0
RD ilaser r1
RD err r2

The available names depend on the connected product and firmware.

Values are copied into a 32-bit register:

  • 8-bit and 16-bit values are zero-extended;
  • 32-bit values are copied directly;
  • for 64-bit values, only the lower 32 bits are returned;
  • floating-point values are copied in IEEE-754 binary32 form.

A floating-point measurement can be used directly with floating-point instructions:

RD tact r0
FSET 30.0 r1
FCMP r0 r1
JCC GT too_hot

Writing device settings

Use WR to write a register value to a command listed by fmtseq.

WR tset r0

Examples may include:

WR tset r0
WR laso r1
WR teco r2

The available names depend on the connected product and firmware.

The register value is interpreted according to the command type:

  • floating-point;
  • unsigned integer;
  • signed integer;
  • Boolean.

For Boolean commands:

  • zero means disabled;
  • any nonzero value means enabled.

The normal command checks remain active. A write can fail because of an invalid value, an interlock, insufficient access rights, or another device safety condition.

If a write fails, the program stops with an execution error.

Timing model

At most one instruction executes per millisecond.

Ordinary instructions consume execution slots, but only WAIT advances the program timeline.

Consider:

FSET 20.0 r0
WR tset r0
WAIT 100
FSET 25.0 r0
WR tset r0
WAIT 100
END

Each WAIT 100 advances the scheduled timeline by 100 milliseconds.

The second deadline is therefore 200 milliseconds after the initial timeline, rather than 100 milliseconds after the second WAIT happens to execute.

This prevents small processing delays from accumulating after every wait.

If execution reaches a wait after its deadline has already passed, the wait completes immediately. Missed instruction slots are not replayed.

A final wait keeps the program active until its deadline:

SET 1 r0
WR laso r0
WAIT 1000
END

Examples

The command and field names used below are examples. Check the names available for the connected device in fmtlist and fmtseq.

Apply a setpoint and enable the outputs

This program configures the temperature controller before enabling the TEC and laser.

// Register allocation:
// r0: temperature setpoint
// r1: Boolean value true

FSET 25.0 r0       // Temperature setpoint: 25 °C
SET 1 r1           // Boolean true

WR tset r0         // Apply the temperature setpoint
WR teco r1         // Enable the TEC

WAIT 5000          // Allow five seconds for initial stabilization

WR laso r1         // Enable the laser
END

The exact warm-up time required depends on the system. A fixed delay does not guarantee that the target temperature has been reached.

Enable the laser only after temperature stabilization

This program waits until the measured temperature remains within ±0.1 °C of the target before enabling the laser.

// Register allocation:
// r0: measured temperature
// r1: lower acceptable temperature
// r2: upper acceptable temperature
// r3: Boolean value true

FSET 24.9 r1       // Lower limit
FSET 25.1 r2       // Upper limit
SET 1 r3           // Boolean true

wait_temperature:
    RD tact r0              // Read the measured temperature

    FCMP r0 r1              // Is tact below 24.9 °C?
    JCC LT retry

    FCMP r0 r2              // Is tact above 25.1 °C?
    JCC GT retry

    WR laso r3              // Temperature is in range: enable laser
    END

retry:
    WAIT 100                // Check again after 100 ms
    JMP wait_temperature

This program waits indefinitely if the temperature never enters the requested range. A production sequence may also need a timeout.

Wait for stabilization with a timeout

This version stops waiting after 30 seconds if the temperature does not reach the acceptable range.

// Register allocation:
// r0: measured temperature
// r1: lower acceptable temperature
// r2: upper acceptable temperature
// r3: elapsed check count
// r4: maximum check count
// r5: increment value
// r6: Boolean value true

FSET 24.9 r1       // Lower acceptable temperature
FSET 25.1 r2       // Upper acceptable temperature

SET 0 r3           // No checks performed yet
SET 300 r4         // 300 checks × 100 ms = 30 seconds
SET 1 r5           // Counter increment
SET 1 r6           // Boolean true

check_temperature:
    RD tact r0

    FCMP r0 r1
    JCC LT not_ready

    FCMP r0 r2
    JCC GT not_ready

    // Temperature reached the requested range.
    WR laso r6
    END

not_ready:
    ADD r3 r5 r3           // Increment the check counter
    CMP r3 r4
    JCC GE timeout         // Stop after 30 seconds

    WAIT 100
    JMP check_temperature

timeout:
    // The laser remains disabled.
    END

The GUI register view can be used after completion to distinguish the successful path from the timeout path by inspecting r3.

Generate a temperature setpoint ramp

This program increases the temperature setpoint from 20 °C to 25 °C in steps of 0.5 °C, with one second between steps.

// Register allocation:
// r0: current setpoint
// r1: setpoint increment
// r2: number of setpoints to apply
// r3: number already applied
// r4: counter increment

FSET 20.0 r0       // Initial setpoint
FSET 0.5 r1        // Step size

SET 11 r2          // 20.0, 20.5, ..., 25.0: eleven values
SET 0 r3           // Applied-value counter
SET 1 r4           // Counter increment

ramp:
    WR tset r0              // Apply the current setpoint

    ADD r3 r4 r3            // Count this setpoint
    CMP r3 r2
    JCC GE finished         // Stop after the final value

    WAIT 1000               // Hold the setpoint for one second
    FADD r0 r1 r0           // Calculate the next setpoint
    JMP ramp

finished:
    END

There is no final one-second wait after the last setpoint. Add WAIT 1000 before END when the final value must also be held for a complete interval before the program finishes.

Generate a triangular setpoint scan

This program repeatedly scans a setpoint upward and downward between two limits.

// Register allocation:
// r0: current setpoint
// r1: positive step
// r2: negative step
// r3: upper limit
// r4: lower limit

FSET 20.0 r0       // Initial setpoint
FSET 0.1 r1        // Upward step
FSET -0.1 r2       // Downward step
FSET 25.0 r3       // Upper limit
FSET 20.0 r4       // Lower limit

scan_up:
    WR tset r0              // Apply the current setpoint
    WAIT 100                // Hold it for 100 ms

    FADD r0 r1 r0           // Increase the setpoint
    FCMP r0 r3
    JCC LE scan_up          // Continue until the upper limit is exceeded

    FADD r0 r2 r0           // Return to the upper limit

scan_down:
    WR tset r0
    WAIT 100

    FADD r0 r2 r0           // Decrease the setpoint
    FCMP r0 r4
    JCC GE scan_down        // Continue down to the lower limit

    FADD r0 r1 r0           // Return to the lower limit
    JMP scan_up             // Repeat indefinitely

This is an infinite program. It runs until stopped from the GUI or until a command fails.

The effective period also includes the execution slots used by the instructions between waits.

Pulse the laser output a fixed number of times

This program enables the laser for 200 ms, disables it for 800 ms, and repeats the cycle ten times.

// Register allocation:
// r0: Boolean false
// r1: Boolean true
// r2: completed pulse count
// r3: requested pulse count
// r4: counter increment

SET 0 r0           // Laser off
SET 1 r1           // Laser on
SET 0 r2           // No pulses completed
SET 10 r3          // Generate ten pulses
SET 1 r4           // Counter increment

pulse:
    WR laso r1              // Enable the laser
    WAIT 200

    WR laso r0              // Disable the laser
    WAIT 800

    ADD r2 r4 r2            // Count the completed pulse
    CMP r2 r3
    JCC LT pulse

END

If execution stops during the first wait because of an error or an explicit stop, the sequencer does not automatically execute the later WR laso r0. Device interlocks and safe output defaults must therefore remain the primary safety mechanisms.

Shut down the laser when a limit is exceeded

This program continuously monitors temperature and laser current. It disables the laser when either measurement exceeds its limit.

// Register allocation:
// r0: current measurement
// r1: maximum temperature
// r2: maximum laser current
// r3: Boolean false

FSET 35.0 r1       // Maximum allowed temperature
FSET 0.150 r2      // Maximum allowed laser current
SET 0 r3           // Boolean false

monitor:
    RD tact r0              // Read temperature
    FCMP r0 r1
    JCC GT shutdown

    RD ilaser r0            // Read laser current
    FCMP r0 r2
    JCC GT shutdown

    WAIT 10                 // Repeat approximately every 10 ms
    JMP monitor

shutdown:
    WR laso r3              // Disable the laser
    END

The actual monitoring interval is slightly longer than 10 ms because each instruction consumes an execution slot.

This software check complements the device interlocks; it must not replace them.

Wait for an error bit

This example waits until any bit selected by a mask appears in the err status field.

// Register allocation:
// r0: current error word
// r1: error mask

SET 0x0000000F r1  // Monitor error bits 0 through 3

wait_error:
    RD err r0
    TST r0 r1              // Test err & mask
    JCC NE error_detected

    WAIT 100
    JMP wait_error

error_detected:
    END

TST does not modify the source registers. After the program finishes, r0 contains the error word that caused the condition.

Perform a finite measurement sequence

This program samples the temperature once per second for ten seconds. Because the sequencer has only registers and no sample buffer, each new measurement replaces the previous one.

// Register allocation:
// r0: latest measured temperature
// r1: sample count
// r2: requested number of samples
// r3: counter increment

SET 0 r1           // No samples acquired
SET 10 r2          // Acquire ten samples
SET 1 r3           // Counter increment

sample:
    RD tact r0              // Store the latest measurement in r0

    ADD r1 r3 r1            // Count the sample
    CMP r1 r2
    JCC GE finished

    WAIT 1000
    JMP sample

finished:
    END

After completion:

  • r0 contains the final temperature measurement;
  • r1 contains the number of acquired samples.

The sequencer cannot store a complete acquisition history. Use the GUI or another host application when all samples must be recorded.

Starting and stopping

Use the Sequencer panel in the GUI to transfer, start, and stop a program.

When started, the device loads and validates the stored program before executing it.

To restart a finished or stopped program:

  1. stop the sequencer;
  2. start it again.

Starting an already enabled sequencer does not restart it.

Status and errors

The GUI displays the current state, instruction position, register values, and stop reason.

Possible states include:

State Meaning
Stopped The sequencer is not running.
Loading The program is being loaded and validated.
Waiting The program is active and waiting for its next deadline.
Finished The program completed normally.
Error Loading or execution failed.

A loading error can be caused by:

  • an invalid instruction;
  • an invalid register or jump target;
  • a missing or misplaced END;
  • an unsupported RD field;
  • an unsupported WR command;
  • a schema CRC mismatch;
  • corrupted stored program data.

An execution error can be caused by:

  • a rejected WR;
  • an out-of-range value;
  • an interlock;
  • a device fault;
  • insufficient access rights.

After a firmware update, transfer the program again from the GUI so that it uses the current fmtlist and fmtseq CRCs.

Safety

A sequencer program can change device outputs without continuous user interaction.

Before starting a program:

  • verify all setpoints and limits;
  • check every loop exit condition;
  • provide a safe shutdown path;
  • test with conservative output limits;
  • confirm that device interlocks are active.

Closing the GUI or disconnecting the computer does not necessarily stop a program already running on the device.