Sequencer
Native sequencer operation in Koheron V1 firmware.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:
fmtlistlists the status fields that can be read withRD;fmtseqlists the commands that can be written withWR.
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:
- stores
25.0inr0; - writes it to
tset; - waits 5000 milliseconds;
- reads
tactintor1; - 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:
r0contains the final temperature measurement;r1contains 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:
- stop the sequencer;
- 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
RDfield; - an unsupported
WRcommand; - 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.