Firmware code base: v0.900

WOSM MCU command set


The WOSM web browser interface communicates with the WOSM microcontroller via a plain text command set. This same language allows users to write programmes (macros) for the microscope that control illumination schemes, detection schemes, stage position and many other parameters. Accurately timed acquisition loops are simple to write. The microcontroller can be controlled from Micromanager.

These commands are fundamental to the way the controller works. They can be called from variety of sources:
* WOSM Macro Language (WML)
* Micromanager scripts (beanshell / java), communicating over Telnet or USB
* HTML includes - this is ususally to include information pages are served from the controller
* HTTP arguments - typically to set a single parameter on page load (command within the url)
* Ajax (for live updates and changes on web pages, without full page reload)
* Telnet command line (for testing macros and diagnostics and all comms with the acquisition software)
* local calls from the mcu firmware (C calls)
* USB virtual serial (MX board only, from acquisition software or a user test terminal)

Timing and latency: The command timing information in these tables shows macro timing recorded using this macro. That is a single macro, running in "fast" conditions, on the standard (MZ core clocked at 252MHz). Networking protocols (HTML, Ajax and Telnet), add a latency that varies depending on your network structure and packet size, this can be on the millisecond timescale. USB latency is 1ms or slower.

Command categories:

Digital ports, TTL in / out / configure eg. triggers
Digital counters
Serial interphases (SPI and RS232)
Motors: Stepper motors and small servos
Analogue out (0 - 5V / 16bits). Incl. current control for LEDs / lasers
Keypad and rotary encoder
USB control commands
Macro control commands
Macro flow control
Macro variables
System versions and updates
User management


Command Arguments t (µs) Description
sys_reset System reset
sys_poweroff Will power off the ATX power supply. NB. Jumper J? can override this.
sys_interf int (4) Read/write the system interface bitfields:
bit0: ( 1) ethernet
bit1: ( 2) usb
bit2: ( 4) keypad: lcd, buttons and leds
bit3: ( 8) rotary encoder (usually on keypad)
bit4: (16) PSU ATX power control
bit5: (32) PSU board analogue out
bit6: (64) DS18B temperature modules


Command Arguments t (µs) Description
delta [all] A "what's new" call. Used by controller software (or a web page via a request for "/delta.json") to get updates on any hardware changes. A reply to a delta command will include the command name (details throughout this page) followed by the current parameter value. A single change is reported for each delta call.
dig_in 0x00000009
sys_uptime 00:00:11
If there's nothing to report, a blank line is returned. The controller maintains an internal list of what has been reported to each interface (http, usb, driver telnet, user telnet). This way changes don't get sent twice. The "all" parameter will request to re-send all parameters on subsequent calls to delta.


Command Arguments t (µs) Description
sys_time 14 System time (UTC or GMT). Read only.
sys_date 12 System date. Read only.
sys_core 3.0 System core timer value (64bit). Starts counting when you switch on. Counts at half the system clock rate.
MX board: system 80MHz, core timer counts at 40MHz (25ns per tick)
MZ board: system 252MHz, core timer 126MHz (~7.93ns per tick).
Read the real core timer rate using the sys_core_mhz command.
sys_core_mhz Read only. Get the core timer rate, in Megahertz. If you're using the coretimer for timing, read this value to easily convert to microseconds.
sys_uptime 4 Read only. How long since switch on. Days, hours, mins & secs.
sys_ntp_last GMT string of most recent NTP check
sys_ntp_next GMT string of the next NTP check
sys_ntp_now Force immediate NTPD check.
sys_xtal_ppm Crystal error "parts per million" relative to the NTP server references.
sys_unixtime unixtime 3 Get/set the wosm unixtime. Returns the current UTC (seconds since start of 1970)

Temperature modules (DS18)

The number X in the command refers the module index (0 to number of modules - 1).

Command Arguments t (µs) Description
temp_ser X
8 Get/Set the serial (hexadecimal) number for this module.
temp_ref X
2.5 Get/set the friendly name (reference) for this module. Up to 7 characters.
eg. temp_ref 4 room
temp_off X
6 Get/set the temperature offset. For temperature offset calibration
eg. for a +1°C offset correction "temp_off 0 256". Offset values are saved in the module's limited storage space, so it should be retained if you move modules later.
temp_val X 2.7 Get the last temperature reading from module. Signed integer value returned with 256th degree units (ie. divide by 256 to get degrees.
temp_d5m X 2.8 Get the temperature change over the last 5 minutes. (256th degree units).
temp_deg X 6.5 Get the last temperature reading from module. Value returned in degrees with single decimal place (eg. "23.42").
temp_col X
GUI colour used for this temperature module. In hex
eg. temp_col 0 2020D0
Would be parsed as "#2020D0" in the html. For help choosing codes go to
temp_set_all signed float Correct the offset calibration for all modules to give the temperature you set here.
A useful set-up calibration. Have all modules running together for several minutes in the same temperature controlled environment, ideally next to a trusted thermocouple. Or what about in a bag in melting ice?
eg. "temp_set_all 21.3" will correct all module offsets so they all read out 21.3°C.
temp_log_clr Zeros the temperature log buffers.

Digital lines in / out (TTL) eg. shutters, triggers

The 26 digital lines are labelled A to Z.

Command Arguments t (µs) Description
dig_in [a-z] 2.1 Read only. If specified, read from a single TTL in line. Returns 0 or 1. A return value of -1 means this line is not currently configured to be a ttl input. If no line is specified, a hex value representing all input lines is returned (bit 0 for line 'a', bit 1 for line 'b' etc.)
dig_wait a-z
1 / 0
Read only. Macro only. Halt macro progress until the line reads high (1) or low (0). This will work for "TTL in" lines and "TTL out" lines.
Timeout: (v0.816 and later) If not specified, this command times-out after 1s. The timeout value can be entered in the command.
dig_wait n 1 t=20s #wait 20s for line N to go high
dig_wait s 0 t=100us #wait 100us for line S to go low
By default, when this command times-out it will stop the macro. (see ... to prevent this...)
dig_out [a-z] [0/1] 2.4 Set a single output line high or low.
eg. dig_out c 1 #will set ttl output high on line C.
If no parameters specified a single hex value is returned, representing the out value of all digital output lines.
dig_mode a-z
4 Set/get the line mode.
eg. "dig_mode a 4" will configure line A to be a "TTL out" line
(other modes available on certain lines, see web GUI)
dig_ref a-z
3 / 5 Get/set the reference/name for this digital line.
5.5 Accurately timed signal output commands. Immediately starts a pulse output on the line specified, enter the delay in the wosm time format. Either high(3.3V) to low (0V), or low to high. Useful for opening a shutter or switching on a laser for a accurately defined duration.

dig_hilo q 1s   #(open the shutter on line Q for 1s)
dig_hilo m 2us  #(2 microsecond pulse on line m)
This should have microsecond repeatability. Try it on an oscilloscope and let me know....
Minimum pulse duration is 1µs (mz board).
NB. These commands are non-blocking. ie. pulse durations longer than 5 microseconds will complete during the execution of the subsequent commands. Add a dig_wait command if you want to halt the macro until the output is finished.
dig_hilo q 1s   #(open the shutter on line Q for 1s)
dig_wait q 0     #pause macro until 1s pulse is complete...

Possible future enhancements to this (ie. if someone asks for it):
- add a "wait" parameter to block macro progress for the duration of the command.
dig_all_modes 6.7 Read only. List the modes of all lines A to Z.
dig_all_refs 6 Read only. Get all reference names in one call.

MZ boards: line reference

MX boards: line reference


16bit counters will sum the signal pulses (3.3V TTL) on the line. Currently 16bit only. Should be capable of a few MHz (limits not tested yet..).
On the MZ (250MHz) board, counters are available on lines "q" and "r". On the mx board counters are available on lines m, n & o. NB. You need to configure a line as a counter for these to work! (eg. dig_mode q 9).

Command Arguments t (µs) Description
cnt_en counter
2.6 Counter enable. 0=disable, 1=enabled. The counter total is not changed so this command functions as a pause/continue.
eg. cnt_en m 1 #enable the counter on line m
cnt_en_all 0/1 2.6 All counters simultaneously. 0=disable, 1=enabled.
cnt_clr counter 2.4 Zero the counter.
cnt_val counter 2.4 Read only. Read the counter value.

Serial communications (SPI and RS232)

Two types of interface are supported: Serial peripheral interphase, sometimes called the 4-wire bus or SPI and RS232. WOSM boards have 2 (3 on the mz board) SPI connectors which allow data transfer to daughterboards or other controllers that can talk SPI.
Channel designations as follows:
A (SPI) (26pin, slave mode) Is Raspberry Pi pinout compatible. Has 1 slave select line, and 2 spare TTL. (work in progress)
B (SPI) (10pin, master mode) Has 4 CS lines.
C (SPI) (10pin, master mode)
D (RS232, (3pin GND, TX, RX) Low voltage (0V / 3.3V)
E (RS232) (3pin GND, TX, RX)
F (RS232) (3pin GND, TX, RX)

CommandArgumentst (µs)Description
ser_config channel
[config register]
Get/set the serial configuration register (hexadecimal value). For full configuration details see the microcontroller chip or family PDF. Supports 32-bit hex value or alternatively and some key words.

On the SPI channles (A, B & C) this writes to the SPIxCON register.
Legible switches include:
on or off to enable or disable the SPI module (CON bit 15)
cke=0 or cke=1 Clock edge
ckp=0 or ckp=1 Clock polarity
ser_config a on cke=1 ckp=0 #turn on SPI bus A
ser_config a 0x18260 #enable SPI bus A in master mode

On the RS232 channels (D, E & F) this writes to the UxMODE register.
More legible switches include:
on or off to enable or disable the serial module
pdsel=? data/parity selection: 0 -> 8/none, 1 -> 8/even, 2->8/odd, 3->9/none
stsel=? stop bits (0 for 1-stop, 1 for 2stop bits)
ser_config d on pdsel=2 stsel=0 #turn on serial bus D, 8 data bits, even parity, 1 stop bits
ser_brg channel
Get/set the SPI baud rate generator divisor. Outputs the current divisor value and the resulting bus clock speed in Hz ie. bit-rate, not byte-rate.
ser_brg a 0 #set SPI bus A to 20MHz
ser_cs channel
[CS line]
(SPI master mode only) Get/set the SPI chip select line. SPI connectors have up to 4 ( 1 to 4) chip select lines. When a line is selected, all subsequent calls to ser_send will pull this line low when data is transmitted. The line is pulled high at the end of transmission.
On call this command will set the line high (usually means "unselected"), unless you add the "low" parameter. eg.
ser_cs a 1 #SPI bus A to use CS line 1. This line set high. It will pull low automatically when the wosm sends data
ser_cs c 2 low #SPI bus C to use CS line 2, pull it low immediately
ser_cs b 0 #SPI bus B will not use any chip select line
ser_send channel
Send the data down the bus. The sent data is escaped ascii in double quotes.
The following escape characters are supported: \r \n \t \0 \" \' \\ as well as \xFE to define individual hexadecimal characters. eg.
ser_send b "reset\r\n"
ser_send b "reset\x0D\x0A"
ser_recv channel
Recieve data from the SPI channel. eg.
ser_recv b eol="\n" ignore="\xFF" max=16 #
ser_recv_clr channel Clears any data in the receive buffer.
ser_wait channel (macro only) Wait for serial hardware to be idle.
In SPI bus master mode macro execution blocked until the most recent send is complete.
In SPI slave mode the macro will halt here until the SS line is high (the bus master has stopped sending).
ser_file_rd channel
(slow) (2018 in dev...) Read file from daughterboard. A total of byte-count dummny 0xFF bytes are clocked out, to read the data in.
The local (WOSM SD card) default folder is /"//wosm//data/".
The daughterboard folder is the root folder.
ser_file_rd b newdata.dat 124723

Keypad, rotary encoder and LCD

Command Arguments t (µs) Description
kyp_val (read only) 5.5 Returns a 32bit hex value representing the keypad buttons and LED states.
kyp_rot 2.1 Return the rotary encoder cumulative counter (signed 32bit int)
kyp_led LEDname
9.7 Set the keypad indicator LED brightness (current) values (0=off, 1=dim, 16=bright). Slightly quicker for the "on" / "off" commands as there is no current set operation. The "on" command remembers the last brightness setting (defaults to 12 on boot.....check this...?).
Valid names for the LEDname are:
alrt the alert/error led at the top of the keypad
usr1 spare led 1
usr2 spare led 2
m1...m5 macro leds, above the macro keypad buttons
lcd all lcd backlight leds
lcdr lcdg lcdb individual rgb leds if you have the RGB backlight
kyp_lcd_type 0, 1 or 2 Which LCD screen hardware used in the keypad.
0 = No LCD used
1 = SP5 GFX1 LCD (older style keypads with vertically arranged macro buttons)
2 = EA-DOGL128 (default)
kyp_lcd_cont 0 to 63 LCD contrast. Start with 30. Adjust to taste.
kyp_lcd_msg text to display Show message on LCD screen with a specified timeout.
Content format is: t[timeout(ms)] title\line1\line2\line3
eg. kyp_lcd_msg t500 Alert!!!\Read this quickly\It's only here for\0.5s
If t is not specified, the default timeout is 1s
kyp_lcd_mode mode number Get/set the LCD screen mode.

Motors: steppers and servos

Motors are referenced in two characters refereing to board (usually "m" for microcontroller board) and the motor number. The main mcu board can be configured with up to 3 steppers: "m1" (lines A-D), "m2" (lines E-H) and "m3" (lines I-L) and 3 servos: "m4" (line V), "m5" (line W) and "m6" (line X).
Stepper positions and limits are defined in step units (usually microsteps) and servos in pulse width units (in microseconds).

Command Arguments t (µs) Description
mot_ref m1-9 [newname] Get / set the friendly name for this motor.
eg. mot_ref m4 Zdrive/td>
mot_en m1-9 [0/1]value
Motor drive mode, options are:
-2 = Not available in this hardware config (dig io lines may need setting?) (default).
-1 = Disabled / not configured
0 = Motor off. Stays off, does not respond to new mot_dest commands.
1 = Motor on
mot_mode m1-9 [setmode] Motor drive mode, options are:
0 = Continuous sweep movement.
1 = Goes to saved positions only. Makes the memory locations "sticky", on mot_dest commands, the motor will go to the nearest memory location.
mot_dest m1-9 [new_destination] 4.5 Get/set the current motor destination. This command is non-blocking, the command does not wait for the motor to arrive. Use the mot_wait command if you need that. The destinations do not buffer, ie. if you set a new destination while it's moving, it will start heading to the newly defined destination (including any deceleration required for direction reversal).
eg. mot_dest m2 +3200 #will start moving to position +3200
eg. mot_dest m2 r+320 #relative move, add 320 steps to the current destination position
eg. mot_dest m3 r-n #relative move, step "nudge" steps in the minus direction ( "r+n" for the other way)
mot_posn m1-9 [redefined pos] Outputs the current motor position (can be different from the destination value if it's still moving). Writing a "redefined pos" (steppers only) will redefine the current position to be the value given (ie. this is for position re-definition or zeroing, the stepper motor will not move).
NB. You cannot redefine servo positions in this way. In servos the position value is the same as the output pulse-width, in microseconds.
mot_offtime m1-9 [time]
Get / set the motor off-time (milliseconds). If zero the motor will stay on (high torque) until mode set to 0. Otherwise the motor driver will turned off, if static for this amount of time. This can reduce motor heating and possibly some vibration or hum. It may also allow the mechanism to be turned manually. For steppers this can cause loss of stepper synch (step position). In servos, the pulse-width signal will stop (Note that some digital servos may remain in the high-torque state after the pulse signal stops).
mot_wait m1-9 (macro-only) Pause the macro till the motor has arrived at destination.
mot_end_low m1-9 [motorpos] Define a soft low end-stop. Any motor destination set below this value, will be set to this value. You cannot set a low endstop above the current step position.
mot_end_high m1-9 [motorpos] Define a soft high end-stop. Any motor destination set above this value, will be set to this value. You cannot set a high endstop below the current step position.
mot_rate m1-9 [time] (Steppers only) Sustained pulse rate when turning at full (max) speed. Defined as the interval between step pulses, so smaller is faster. There's a low firmware limit (20µs MX boards, 5µus MZ boards), but you will probably have electronics or mechanical limits that are slower than this. Too fast and your stepper may skip steps, and lose synch. Tune to taste.
mot_rate m5 200us
mot_slow m1-9 [time] (Steppers)get / set the pulse rate when starting a move. The motor will accelerate from this value up to the "rate" value, and decelerate to it when stopping. Must be larger (ie. slower) or equal to the "rate" value.
mot_accl m1-9 [new_percentage] How fast to accelerate / decelerate between the "slow" and "rate" speeds. Should probably be smaller than your "rate" value. But will depend the inertia of your system. Reduce it if you are getting missed steps. Smaller values give smoother but slower acceleration.
mot_bckl m1-9 [+/-steps] Get/set motor backlash. Correct for slack in your mechanical gearing.
mot_save m1-9
name:ref [pos:numeric]
mem:N (N:0-31)
The name/pos version saves the numeric position with the name given.
eg. mot_save_m3 name:ND3 pos:1347
The "mem" will return the name/pos at that memory location (0 to 31)
eg. mot_save_m4 mem:4
Note that internally the memory list is maintained in ascending motor position order, so memory index values will change if new lower position value motor locations are added.
mot_wipe m1-9 Delete the stored position for the current pwm value.
mot_nloc m1-9 (Read only) Returns the number of motor locations saved.
mot_nudge m1-9 Get/Set the sizeo of a motor nudge. eg. used with keypad "+" and "-" buttons.
mot_present (read only) Bit fields showing which motors are configured. Mainly useful for constructing interfaces.
mot_type m1-9 (read only) Is the motor undefined (0), a stepper (1) or a servo (2).

Analogue out control (eg. laser power, LED current, stage position)

The power board (board reference "p") has 8 analogue out channels split into 2 groups.

Channels ps, pt, pu & pv (0 to 65535 -> 0 to 5V)

The lower 4 channels are configured for 0 to 5V output. Each channel can be configured for one of the following:

Channels pw, px, py & pz (0 to 65535 -> 0 to 10V)

Typically configured with 0 to 10V output using an amplifier set to 2x gain. These may be used for fast stage drive control (PI, Madcity etc). To drive an XYZ stage, connect to channels X, Y, and Z if you want the direction keypad keys to work sensibly.

Linked on/off control TTL

If selected on digital i/o config page, each analog-out channel can be linked to a corresponding digital line letter for on/off control. For the lower four channels (S, T, U & V) these lines are wired directly to the power board and have an n-channel MOSFET at the analog output stage. This allows faster "ON" and "OFF" control than can be provided by the DAC.
Command Arguments t (µs) Description
dac_ref line [newname] 3.7 Get/set the reference name for this line. 11 characters max.
eg. dac_refr ps laser561
dac_dest line [0-65535]


line [r+/-/*diff]
11 Sets the DAC output destination value (16bits, 0 to 65535). Full scale (65535) gives a DAC output of 5V. A relative incremental / decremental / multiplier change can be produced using "r+", "r-" or "r*". If no value given, the current destination value is returned.
In a macro, this command is non-blocking, meaning if slew-rate limiting is applied on this channel (see dac_rateL), then the output signal may continue to change over the following commands. If you need macro progress to wait till it arrives, use the dac_wait command. Examples:
dac_dest ps 32768 #(channel s, set to half scale (2.5V) out
dac_dest pt r+200 #(channel t add 200 to the current destination DAC value
dac_dest pz r+n #(channel z add "nudge" units the the current output
dac_dest pu r*1.05 #(channel z add "nudge" units the the current output
dac_dest pz #(get the value on channel Z)

dac_val line 2.5 (read only) Returns the present dac output value. This can be different from dac_dest value if the output is changing with rate limiting active (ramps applied).
dac_rate line [0-32767] If rate > 0, this will apply a slew (ramp) rate limit to the DAC output. Set to zero to remove any rate limiting. The value sets the maximum DAC unit change that happens per 100µs write cycle. This can cause dac output changes to span the commands that follow a dac_dest change. Use dac_wait if you need to pause the macro till the dac output change finishes.
dac_rate pz 0 # no ramp rate limiting on channel Z
dac_rate py 2000 # full scale change would take about 3ms (ie. 0.1ms x 65536 / 2000)
dac_rate px 1 # slow ramping. full scale change would take ~ 3.3s (ie. 0.1ms x 65536)
dac_wait [line] ~ (macro-only) When slew rate limiting, this will halt macro progress until the DAC channel has reached it's destination (or reached min or max limits). If rate limiting is not applied (eg. dac_rate ps 0), this command does nothing. With no line specified (dac_wait) macro progress will halt until all 8 channels are at their destination value.
dac_last [line] 3.5 (read only) Return the time (microseconds) since the last change on the line specified (or most recently changed channel if non-specified). If a rate-limited move is in progress, this function returns zero.
dac_min line [0-65534] Set the minimum output value. Usually used with the RCD24-1.2 programmable current module only. Get/set DAC output value where the LED driver current output is zero milliamps.
dac_max line [1-65535] Get/set the DAC output limit when the channel is in voltage out mode. 0 = 0V, 65535 = 5V
dac_out line 10 (read only) Returns the channel output value in real-world units rather than DAC units. The formatting of this output can be tuned using the commands dac_range and dac_unit.
dac_unit line [unit text] Set the unit string. Goes with the dac_range config command. This defaults "mV".
dac_unit ps mW
dac_range Set a full-scale value. Alters how the analog out signal is shown to the user. Real world units can be more useful than DAC units. This defaults to 5000 or 10000 to show the "millivolts" out. But can be changed to display milliwatts of laser power or microns of stage movement.

eg. if you had a 200 micron stage drive on channel X, enter the following commands
dac_refr px Stage X
dac_range px 200
dac_unit px um

eg2. you have a 50mW laser on channel t

dac_refr_pt Laser561
dac_rang_pt 50
dac_unit_pt mW
dac_nudge line Get/set the nudge value. Mostly influences the speed of the change keys on the keypad.

Network and TCP/IP

These commands are used if you're setting a static network config, otherwise the network settings are obtained automatically using DHCP (make sure you have "lan_conf_ip 2" in your config.wml on the SD card. You can see the network settings on the Network page on the keypad.
If you can connect you can make static settings changes on the web gui conf/network page. Else you will need to edit the "wosm/macros/config.wml" file on the SD card directly. Example static network settings below
lan_conf_ip 1

Command Arguments Description
lan_host up to 15 char. Get/set the computer hostname.
lan_conf_ip 0, 1 or 2 0=private address, 1=static, 2=DHCP(default)
lan_subn Get/set the lan subnet
lan_ip Get/set the lan IP address. To set the address, the lan_config must be set to 1 (static).
lan_mac Get lan MAC address.
lan_gateway Get/set the gateway IP. (lan_config must be 1 to set this).
Get/set the lan nameserver IPs. Set requires that lan_config=1.
You can reduce the TTL of IP packets leaving the controller. Time to live (TTL) defines the IP packet lifetime in terms of network hops. If you connect to a controller across two network switches, your TTL must be more than 2 (TTL >= 3) or the connection will fail due to packet loss.
Mainly useful for security. This is simple network firmware. As yet there is no packet encryption (no HTTPS or SSH). A low TTL can rule out internet connections as well as longer range lan connections, independent of any firewall config you may have.
You could also use it to count hops to your controller, but you would be better off using traceroute (which also works by incrementing packet TTL) from your host PC. User connection TTL (lan_ttl_user) sets the maximum number of hops for HTTP (port 80) and user Telnet (port 23) connections. Driver TTL (lan_ttl_drvr) is for controller PC comms (Telnet over port 1023).
NB. On this page you will see two meanings of TTL. It's just an acronym coincidence, they shouldn't be confused. The time-to-live of network packets is rarely used in the same context as transistor-transistor logic, referring to digital signalling between ICs. At this point nobody should mention "through-the-lens" light metering on microscope systems.

USB commands

Command Arguments t (µs) Description
usb_echo 0 or 1 USB command echo on (1) or off (0).

Macro control commands

Macros are stored in the folder /wosm/macro/ on the µSD card. You can edit them from there or more usefully via the web gui. Up to 8 macros can be loaded and running simultaneously on the wosm. On first run macros need to be loaded from the micro-SD card, this takes about 7ms on my development system but will depend on your SD card speed and macro size. Subsequent calls to the macro will be much faster (a few microseconds, not milliseconds) as the macro stays in ram. If all macro slots are full, non-running macros are removed on a 'last-used' basis when a new macro needs to be loaded. The functions below do not need the ".wml" extension part of the macro filename.

CommandArgumentst (µs)Description

Run the named macro. If called from a macro, both macros will continue simultaneously.
If you want the calling macro to wait until the called macro finishes, you should use the wml_run_wait version. Optional parameters will be available as variables in the macro.
wml_run timelapse2D nframes=1000 expos=100 intervl=2000
Will run the macro "timelapse2D.wml". Within this macro commands can refer to the variables "${nframes}" and "${expos}". eg.
loop count=${nframes} dur=${intervl}ms {
    dig_hilo_n ${expos}ms      # trigger camera/laser
wml_running (read only) Returns a space-separated list of running macros.
wml_stop macroname Immediately stop the macro.
wml_pause macroname Pause execution of the macro. ( Not functional, Needs work/testing, timed loops will not behave nicely yet..., NJC).
wml_unload [macroname] Remove this macro from RAM. If no macro named, then it will try to remove all loaded macros. Running or paused macros are not unloaded.
wml_file_new macroname New macro file.
wml_file_del macroname Delete this macro from the SD card.
wml_file_cat [number] Catalogue / list the defined macros (alphabetical?) on the memory card, returns nothing when number > last file number.

Macro flow control

These commands will only work in WOSM macros. They will not be recognised in any other context, they'll just raise an "unknown" error.

CommandArgumentst (µs)Description
pause delay_time Pause the macro for delay_time. The delay is entered in the wosm time format. The minimum period possible is 15µs on last scope tests (if running "fast", see below). Timing accuracy is about a microsecond. Pause commands less than 30µs are blocking commands, ie. they will not service any other macros or devices during the pause.
Also note that a pause longer than 30µs will remove any fast running condition. eg.
pause 127us
pause 48ms
pause 20min
loop [count=?]
Loop the curly bracketed commands "count" times. You can nest loops up to 8 levels.

Use "dur=" to specify a timed loop, in wosm time format. The timing delay for dur occurs during the jump back to the start of the loop ie. the first pass through the loop happens without any delay. and no delay is added to the end of the last pass through the loop.

loop count=1024 dur=250ms
This example would loop 1024 times at 4 loops/second (ie. 250ms loop duration).
There is an implicit "fast 1" at the start '{' and end '}' of each loop, mostly to give you the chance ot set fast mode in the first command of the loop if you need it. This may be useful for timing-critical start of loop commands.
loop_idx Get the interation number at this loop level.
loop count=10 dur=1s
   ${lp} = loop_idx;                     #get the loop index
   kyp_lcd_msg t900 Loop index:\${lp}    #show it on the lcd
if ( v1 < v2 )
( v1 = v2 )
( v1 > v2 )
Fairly basic conditional execution. Values can be numbers or variables or a combination. Values are converted to 64bit floating point numbers for comparison.
It's fussy, it will fail if there is not opening and closing brackets (), and the opening curly bracket "{" on the same macro line.
As yet no "else" option.
${temp} = temp_deg 0
${msg} = "Normal"
if ( ${temp} > 30.0 ){
   ${msg} = "HIGH"
if ( ${temp} < 15.0 ){
   ${msg} = "LOW"
kyp_lcd_msg t2000 Temperature:\${temp} C\${msg}
fast [n] 0.5 Run the next 'n' commands as fast as the microcontroller can interpret them. Just use this where you need it, as it blocks other macros and processes.
If you omit the 'n' value, the internal fast command count-down counter is set to 232. In most circumstances one of the commands below will bring the macro out of fast mode before this counter reaches zero.
The following commands bring the macro out of 'fast' mode:
fast 0
loop {...}
(really this sets the fast count-down count to 1, see the loop command)
exit_on [conditions] By default macros will halt on any error or timeout. There may be conditions where you want the macro to continue to the next command if there is a timeout. The following commands would allow that, for just one dig_wait command.
exit_on -timeout       # don't stop the macro if a timeout happens
dig_wait_a 1 1s
exit_on timeout        # any further timeouts will halt as normal...
Valid conditions are: all, unknown, timeout
Precede conditions with a minus ("-") to remove the condition
eg. exit_on -all
would remove all possible reasons to halt the macro, probably a bad idea.
All macros start with an implied "exit_on all" condition, so there's no need to include that command in the macro.

WOSM time format

Some commands accept a time value (eg. "pause 200ms") which needs to be interpreted quickly. The following restrictions apply to these time values:

Macro variables

Each macro has a limited number of variables. These are text based.
Variables can be set witin the macro, or on the macro call line.
eg. wml_run acquire2D nframes=2000 expos=200ms
This example would set two variables in the macro "acquire2D.wml", accessible in the macro as as ${nframes} and ${expos}.

Command Arguments t (µs) Description
${varname} = wosm_cmd To set the variable called "varname" (case sensitive) to the output of the wosm_command. Variable names can be up to 7 characters, variable content currently limited to 16 characters.
eg. ${roomtmp} = temp_deg2
${varname} = "string" To set the variable called "varname" to the string shown. Quotes required, stored as strings.
${expos} = "100ms"       #set variable 'expos' = '100ms'
dig_hilo_t ${expos}      #put out a 100ms pulse on line 't'
6-15 Simple calculations.
ical works on signed 64bit integers
fcal, for floating point calculations (long double, 64bit float).
arithmetic operations (ical and fcal): + - / *
logical operations (ical only): & (and), | (or)
Calculations must have two values, or variables, and a single operator, more complex operations should split over several lines.
The optional format, in quotes, allows you to format the output value: limit decimal places, or write the output in hex etc. (see C printf for more formatting options)

${t1} = ical ${t1} - ${t2}                  # subtract t2 from t1
${v1} = fcal ${v1} / 10.24 "%.3Lf"          # divide v1 by 10.24, save the result in v1 (output formatted to 3 decimal places)

ical (integer) format examples:
"%lld"      (default) 64bit signed decimal, fmt not necessary
"%012lld"   12 character, 64bit decimal integer, with zero padding if necessary
"%llx"      64bit hexadecimal eg. "F4E1D21F45ED1"
"0x%016llx" 64bit hexadecimal, 16characters including zero padding and a '0x' prefix eg. "0x000014EF1ABCDEF7"

fcal (floating point) format examples:
"%Lf"    (default), fmt not necessary
"%.3Lf"  3 decimal places
"%.3LE"   output showing exponent, 3 decimal places
fn function
Returns a floating point (64bit) answer. Formatting options the same as fcal.

Function list with examples:
${v} = fn pow 2 16        #power  2^16, v = 65536
${v} = fn sqrt 16         #square root
${v} = fn fabs -7.47      #absolute value, removes minus sign, v=7.47
${v} = fn sin 1           #sine
${v} = fn asin 1          #arcsine
${v} = fn cos 1           #cosine
${v} = fn acos 1          #arccos
${v} = fn tan 1           #tangent
${v} = fn atan 1          #arc tan
${v} = fn ln 2            #natural log, v = 0.6931471805599
${v} = fn exp 0.69314718  #exponential, v = 2

System versions and updates

Here for reference only. These commands provide dynamic HTML content for fast web page loads. Not too useful for macros.

Command Arguments t (µs) Description
Read only. Returns the name of the file flashed on the last firmware update, either for the main wosm firmware (app) or the bootloader (boot)
Read only. Returns the creation date of the file of the last firmware update, main app or bootloader.
Read only. Returns the app or bootloader firmware version string.
Read only. Returns the filename (without the .hex extension) of the most recent 'flashable' update present on the sd card. This is used to populate the update web page. I can't think of another possible reason you would want to use it.
In order to be listed:
* File must be dated (created) later than the current firmware.
* App updates must be named mx??????.hex, bootloader updates named bl??????.hex
8char Perform a wosm app or bootloader firmware update. The app requires a reboot/reset to complete on next wosm bootup. The firmware hex image must be on the SD card, in the folder "/wosm/firmware/". The file must have the ".hex" file extension, and the filename cannot be more than 8 characters. App firmware must be named mx??????.hex, boot firmware called bl??????.hex. The ?????? is usually the compile date in the YYMMDD format.
eg. sys_flash_app mx150819
will flash the hex file "/wosm/firmware/mx150819.hex" on next wosm reset or boot. It takes a few seconds to complete. Returns the name of the pending flash file....? Notes:
* the word "latest" will flash the most recent hex in the firmware folder.
* cutting the power while flashing is in progress is deemed unfriendly.
* This command will not work in a macro (command-line or web click only)
* the firmware flash performs a crc check on the entire file before any flash happens.
* The bootloader can only read cards that are FAT32 formatted (although wosm firmware can work with other formats)
sys_upd_val 20
sys_upd_str 37 When was the most recent online HTML page update (SD card files not firmware flash).
sys_upd_mode Automatic web updates. 0=Off, 1=Every boot, 2=Weekly (within 2min of boot)
sys_upd_now Update the WOSM control pages from wosmic.org. Runs in the background, will take a minute or so to complete. New web pages are functional immediately. New firmware (hex) images may also be downloaded to the SD card during this update process, new firmware images will not be flashed automatically, you must select firmare updates on the update config page.

User management

Users login at HTTP and Telnet connections. The default user "admin" cannot be deleted.

CommandArgumentst (µs)Description
usr_setusername [MD5=passwordMD5]
username [pass=password]
If the user does not exist, is created. Also sets the password for this user:
usr_set barry pass=mysecret
Note that only the password hash (MD5) is saved.
usr_delusernameRemove this user. You cannot remove the default "admin" user. This does not delete user macros from the SD card.
usr_name[0-15]If no arguments, returns the currently authenticated user. The number argument returns the user name from the user database.

Data buffer commands

Work in progress. These commands work with the Wosm64 data acquisition software (not with Micromanager at this stage). Mostly concerned with getting a low bandwidth image to the browser, for remote monitoring acquisition progress.

CommandArgumentst (µs)Description
dat_name(read only) Read the the (file)name of the data buffer.
dat_size(read only) Return the size (bytes) of the data in the buffer.
dat_max[SetMax](read only) Return the maximum buffer data size.
dat_recvname[Telnet port 1023 only]. Binary receive the data.

HTML commands

Here for reference only. These commands provide dynamic HTML content for fast web page loads. Not too useful for macros.

CommandArgumentst (µs)Description

Command speed test macro

Timing information on this page is measured in the script below. The command to be timed is run 10 times in fast mode. With this digital output example you can confirm the timing on a scope. Just make sure that line q is configured to be an output.
${tz} = sys_core
# 10 commands to time here
dig_out q 1
dig_out q 0
dig_out q 1
dig_out q 0
dig_out q 1
dig_out q 0
dig_out q 1
dig_out q 0
dig_out q 1
dig_out q 0
${t} = sys_core
${t} = ical ${t} - ${tz}                     #subtract start time of command block
${t} = ical ${t} - 1000                      #correct for timer read delay
${conv} = sys_core_mhz                       # tick rate in MHz, to convert coretimer to microseconds
${conv} = ical ${conv} * 10                  # n commands
${t}    = fcal ${t} /${conv}  fmt="%.2Lf"    # convert to microseconds
kyp_lcd_msg t2000 Command time:\${t} us