Firmware code base: v0.900
The WOSM web browser interface communicates with the WOSM microcontroller via a plain text command set. The WOSM language allows users to write macros to 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 plain text commands are fundamental to the way the controller works. They can be called from:
WML the WOSM Macro Language Micromanager scripts (beanshell / java), running over Telnet HTML includes - usually to include information pages 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) SPI A (Raspberry Pi compatible) behaves like a terminal interface mcu firmware making local calls (C calls) Command timing: The timing information in these tables shows macro timing recorded using the macro at the bottom of this page. That is a single macro, running in "fast" conditions, on the MZ board (252MHz clock). Networking protocols (HTML, Ajax and Telnet), add a latency that varies depending on your network infrastructure, network traffic and packet size. Network turnaround, eg. querying led brightness and getting that value back, can vary from 100us (telnet protocol over direct ethernet cable) to several milliseconds.
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 (not supported yet...) 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 bit7: (128) Addressable LED bus |
Command | Argument | t (µs) | Description |
---|---|---|---|
delta | [all] [clear] |
Delta is a "what's changed" call. Used by an interface, controller software or a web page (eg. a request for "/delta.json") to get updates on any hardware changes. A reply to a delta command will include the command name (command details throughout this page) followed by the current parameter value. A single parameter change is reported for each delta call. eg. delta dig_in 0x00000009 delta sys_unixtime 1567676848 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, SPI A). This way a parameter update will only be sent once, to each interface. The "all" argument will request to re-send all parameters (now in the hundreds) on subsequent calls to delta. The "clear" will clear all the delta pending flags, so only newly changed parameters will be sent. |
Command | Arguments | t (µs) | Description |
---|---|---|---|
sys_time | 14 | Returns the system time (UTC). Read only. | |
sys_time_offset | +/-hours | 14 | Get/set the offset hours applied to UTC to display local time/date (sys_time_loc & sys_date_loc). |
sys_time_loc | 14 | Return the local time (after the UTC +/- offset has been applied). | |
sys_date | 12 | System date. Read only. | |
sys_date_loc | 12 | System date with the local time offset applied. Read only. | |
sys_usec | 2.5 | Returns the time since boot in microseconds. Useful for accurate timing in macros. | |
sys_usec_wait | time_usec | [Macro-only] Pauses the macro until the system microsecond value (sys_usec) reaches time_usec. | |
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) |
The number X in the command refers the module index (0 to number of modules - 1).
Command | Arguments | t (µs) | Description |
---|---|---|---|
temp_ser | X [serial] |
8 | Get/Set the serial (hexadecimal) number for this module. |
temp_ref | X [setname] |
2.5 | Get/set the friendly name (reference) for this module. Up to 7 characters. eg. temp_ref 4 room |
temp_off | X [offset] |
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 [colour] |
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 http://html-color-codes.info |
|
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. |
Commands to control a serial run of addressable LEDs.
Command | Argument | t (µs) | Description |
---|---|---|---|
led_conf | n=numLEDs T0H=n1 T0L=n2 T1H=n3 T1L=n4 |
Set the number of LEDs one the line with "n=??". Bit timing can be adjusted by setting TL (time low) and TH (time high) to read ones and zeros on the bus. You can get these from the datasheet of your RGB or RGBW led. Default timings work for WS2812B LEDs, one of the more popular types. The timing numeric defines tenths of a microsecond. eg.led_config ch=0 n=25 T0H=3 T0L=8 T1H=6 T1L=5 # write to 25 LEDs # zero timing (0.3us high, 0.8us low) # one timing (0.6us high, 0.5us low) |
|
led_buff | RGBval [buff write mask] |
Setup the buffered values to send to the LEDs. This writes RGB(W) values to the buffer, not to the LEDs. This is where you define the colours and relative brightnesses of the LEDs (for overall brightness use the led_bright command). The buff write mask sets the LEDs to write the new value (bit 0 = first LED, bit 1 = second ... etc). eg. led_buff 0xFF00FF 0x000000010 # make LED number 9 purple |
|
led_bright | 0 - 255 | This is the brightness multiplier (0 - 255) is applied to the led buffer before sending (dimmest 0 to 255 brightest). | |
led_mask | [ masknum / + ] | Select which mask to use, by number (0 to 5) or select the next mask with "+".led_mask 3 |
|
led_mask_def | [n=masknum] [ref="nameit"] [mask=newmask] |
Set/get the LED mask. Define any one of 5 masks (n=1 to 5). Masks define which LEDs are active (bit 0 = first LED, bit 1 = second ... etc). The ref is just a friendly name for the mask, shown in the UI and keypad, 7 characters max. Mask n=0 is always "All LEDs on" ie. 0xFFFFFFFFFFFFFFFF. eg.led_mask_def n=1 ref="BrightF" mask=0x0000FF00 #Just use LEDs 8 to 16 led_mask 1 #make mask 1 active |
|
led_on | 0 or 1 | LED array off (0) or on (1). |
The 26 digital lines are labelled A to Z.
Command | Argument | 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 [t=??s] |
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. eg. 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] or [val32 mask32] |
2.5 or 11.6 |
Set a single output line low (0), high (1) or toggle(2) the output. eg. dig_out c 1 #will set ttl output high on line C. dig_out t 0 #switch off line t. dig_out w 2 #toggle line w. If no parameters specified a single hex value is returned, representing the out value of all digital output lines. |
dig_mode | a-z [setmode] |
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 [newname] |
3 / 5 | Get/set the reference/name for this digital line. |
dig_hilo dig_lohi |
a-z time [nowait] |
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. Examples: 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. If you add the "nowait" option, the command is non-blocking. After the first signal change, the macro continues with the next line. eg. in this command sequence dig_hilo a 20ms nowait dig_hilo b 20ms The two output pulses are almost simultaneous, save for the approx 10us of interpreter time at the start of the signal on line b. |
dig_all_modes | 6.7 | Read only. List the modes of all lines A to Z. | |
dig_all_refs | 6 | Read only. List the modes of all lines A to Z. |
By varying the on-time of rapidly repeating (50Hz to multi-kHz) digital signal can provide accurate analog-like control. R/C servos use pulse width to control motor position. LED brightness can be controlled by altering the duty-cycle of the pwm line. All commands must specify the channel argument ie. "1" to "5".
Command | Argument | t (µs) | Description |
---|---|---|---|
pwm_conf | ch [mode=0/1/2] [ref=aName] [min=count] [max=count] [timeout=timeval] |
Configure the PWM mode for channels PWM1 to PWM5. Modes: 0=line not used, 1= r/c/ servo, 2= LED pwm. pwm_conf 2 mode=1 ref=Iris2 timeout=3s # r/c servo on channel 2 pwm_conf 4 mode=2 ref=Blue # Blue LED on PWM channel 4 Two modes are currently available: Mode 1, typically for driving PWM based R/C servos. This will output a 50Hz repeating PWM signal with a default min equivalent to 1ms, and a max of 2ms. These min/max values can be overridden to give a servo more/less movement range. Take care not to strain or grind the gears, you can mangle them by going too far. Mode 2, typically for driving LEDs. This will output a 100kHz repeating PWM signal with a default min=0 and a max of 10µs. These min/max values can also be overridden. You can drive an LED directly from the line, but ensure an in-series resistor keeps the maximum current below 10mA (at 3.3V that would be 330ohms to be safe). You can drive higher currents by using the neighbouring 5Vpin, an in-series resistor and an n-channel MOSFET. |
|
pwm_set | ch [on=0/1/t/timeval] [val=PWMval] [percent=set_percent] |
Get/Set the pwm value. The pwm timing can be set as an actuatl timer count (val) or as a percentage. In percentage terms "min" is 0%, and max is 100% (see pwm_conf for how to define min/max). pwm_set 2 # get the on/off state and timer value of PWM2 pwm_set 3 on=4ms val=208 # PWM3 turn on for 4ms, set count to 208 pwm_set 5 on=t # toggle on/off PWM5<br>pwm_set 2 percent=50 # PWM2 duty cycle set to 50% |
|
pwm_on | [bitmask] | Single command to turn on/off all 5 channels by bitmask. For channels 1,2,3,4,5 add 1,2,4,8,16 respectively. pwm_on 0 # All pwm channels (1 to 5) OFF pwm_on 31 # All pwm channels (1 to 5) ON pwm_on 9 # PWM1 (+1) on, PWM4(+8) on, others off |
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..).
Counters are available on lines "q" and "r".
NB. You need to configure a line as a counter for these to work!
Command | Argument | t (µs) | Description |
---|---|---|---|
cnt_en | counter [0/1] |
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. |
Command | Argument | 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_rot_expo | [rate] | Zero means linear output from the rotary encoder. If non-zero, faster turns will take you much further. An acceleration effect, while maintaining good control when moved slowly. Test with a value of 10 and adjust up and down to your liking. The actual value varies depending on ticks/turn from your encoder and user. (Actual function is quadratic, exponential was too harsh). | |
kyp_led | LEDname [on/off/0-16] |
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: 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_screen | [t=timeout] [small] [nowait] "text" | Show a temporary LCD screen, with a specified timeout. Text is escaped before showing on the LCD. For a new line, use "\n". If you use small text, you can fit 8 lines of text, otherwise 4. eg. kyp_lcd_screen t=1s small "Alert!!!\nRead this quickly\nIt's only here for\n1 second." If t is not specified, the default timeout is 2s. title plots the first line inverted, as a heading, or a title. nowait Macro progress will continue while the text is displayed. Without this the macro will pause until the screen times out. |
|
kyp_lcd_text | [small] [inv] [upd] [x=0 to 127] [y=0 to 63] "escaped text" | Show text on the current screen. small for smaller text inv to plot the text light and background dark upd force immediate screen update (useful in fast mode, where the macro hogs the mcu so much that the screen does not get updated) eg. kyp_lcd_text small x=20 y=33 "Yerluvinunclebert" |
|
kyp_lcd_mode | mode number | Get/set the LCD screen mode. |
Motors are referenced in two characters referring to the host board (usually "m" for microcontroller board) and the motor number. The main mcu board can be configured with up to 4 sterpper motors (m1 to m4). Stepper positions and limits are defined in step units (steps or microsteps).
Command | Arguments | t (µs) | Description |
---|---|---|---|
mot_ref | m1-4 [newname] | Get / set the friendly name for this motor. eg. mot_ref m4 Zdrive/td> |
|
mot_stat | m1-4 | Motor state, options are: 0 = Not available in this hardware config (dig io lines may need setting?) (default). 1 = Disabled / not configured 2 = Motor off. Stays off, does not respond to new mot_dest commands. 3 = Motor on but power saving (offtime reached, usually low torque, steppers have no current. 4 = Motor on >4 Various motor moving states reported by the firmware eg. accel, full speed, decel (in flux in code...) |
|
mot_dest | m1-4 [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_pos | m1-4 [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). |
|
mot_out mot_outn |
m1-4 [new dest] |
10 | If no new destination value, this returns the motor position value in real-world units rather than step. If a new destination is set, this takes the real-world units configured in mot_out_conf. The "mot_outn" version does not include the user-defined units in the output. eg. mot_out m6 20.34 // move the stage Z to 20.34 microns above the slide surface |
mot_out_conf | m1-4 [mult=multiplier] [offs=offset] [units="?"] [decp=n] |
Configure the output of the mot_out command. The offset value is subtracted from the motor position before the multiplier is applied. Steppers should not need an offset if you set your min/max and pos. eg. mot_out_conf m6 mult=0.006095 unit="um" decp=3 // Newport TRA12PP stepper in x4 microstepping mode |
|
mot_offtime | m1-4 [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). | |
mot_wait | m1-4 | (macro-only) Pause the macro till the motor has arrived at destination. | |
mot_end_low mot_end_high |
m1-4 [motorpos] [stp=0/1] [rst=0/1] [inv=0/1] |
Define a software 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. The fourth control line can define a hardware endstop, for step position referencing and preventing movement beyond this limit. On lowering step value, if the limit pulls low, the hardware endstop has been reached. Motor position value is redefined to be equal to the "motorpos" value. Hardware limit switches (Steppers only) The fourth line (lim) of each stepper motor interface is an input used for hardware limit switches. stp=0/1 Specifies that the motor should stop abruptly when the limit line is activated. If stp is set, the motor will reverse direction, stepping at the start rate, until the limit signal deactivates. rst=0/1Resets the current motor position to be "motorpos" when the limit line de-activates. inv=0/1Typically when the limit switch is active the line reads high, set inv=1 where a reading low means an activated limit switch. |
|
mot_lim | Returns the state of the stepper motor limit switches. Bitfields alternating low & high limit switches, starting at motor m1. ie. bit 0 for motor m1 low, bit 1 m1 high. eg. a return value of 16 means that motor m3 low limit switch is active. |
||
mot_rate | m1-4 [time] | 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 ( 5µus ), 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 m4 200us |
|
mot_accl | m1-4 [new_accel] | (Steppers only, Hz/sec2) How fast to accelerate / decelerate the stepper. Will depend the inertia of your system, motor size, and driver current capability. Reduce it if you are getting missed steps, or the motor is getting warmer than you would like. | |
mot_bckl | m1-4 [+/-steps] | Get/set motor backlash. Correct for slack in your mechanical gearing. | |
mot_nudge | m1-4 | 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. |
The power board (board reference "p") has 8 analogue out channels split into 2 groups.
The lower 4 channels are configured for 0 to 5V output. Each channel can be configured for one of the following:
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.
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 | Argument | 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_mode | line [newname] | Get/set the DAC mode: 0 = Off, stay at 0V output. 1 = Off, floating (not working yet...). 2 = Voltage output. 3 = LED driver (RCD-24 module). 5 = Stage axis mode. eg. dac_mode ps 3 // LED driver on DAC channel S |
|
dac_dest | line [0-65535] or 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 increase the output by 5% 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_out_conf. The output of the dac_outn variant does not include the units. |
dac_out_conf | line [mult=multiplier] [offs=offset] [units="?"] [decp=n] |
Configure the output of the dac_out command. The offset value is subtracted from the dac output value before the multiplier is applied. eg. dac_out_conf ps mult=0.022186 unit="mA" decp=3 // 1200mA LED driver on channel S |
|
dac_nudge | line | Get/set the nudge value. Mostly influences the speed of the change keys on the keypad. |
Configure any combination of motors (mot) and analogue out (dac) for a stage interface. For example you could have a combination of stepper motor XY (mot interface) and piezo Z (dac interface) configured to control your stage XYZ.
Command | Arguments | t (µs) | Description |
---|---|---|---|
stg_cnf_x stg_cnf_y stg_cnf_z |
int=interface [invert] |
Configure each axis with a control interface. Include "Invert" to reverse the interface directionality (web page and keypad). Output also shows min/max and unit information. | |
stg_out_x stg_out_y stg_out_z |
Read the stage position. | ||
stg_val_x stg_val_y stg_val_z |
(read only) Current value in digital units | ||
stg_dst_x stg_dst_y stg_dst_z |
(read only)Destination in digital units (motor steps or dac values) |
Two types of interface are supported: Serial peripheral interphase, sometimes called the 4-wire bus or SPI and RS232. WOSM boards have 3x 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)
Command | Arguments | t (µs) | Description |
---|---|---|---|
ser_mode | channel modenum |
Get/set the serial comms mode. The applicable mode numbers are: 0 Macro comms only (default mode) 1 Laser trap daughterboard (channel b only) 100 Slave terminal (channel a only, eg. Raspberry Pi comms) eg. ser_mode a 10 # runs a command/response terminal slave on channel b, macro independent |
|
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 eg. 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) eg. ser_config d on pdsel=2 stsel=0 #turn on serial bus D, 8 data bits, even parity, 1 stop bits |
|
ser_brg | channel [divisor] |
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. eg. ser_brg a 0 #set SPI bus A to 20MHz |
|
ser_cs | channel [CS line] [low] |
(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 data |
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_send_rep | channel repeats char |
Send same repeated character down the bus. Max repeat is eg. ser_send_rep b 64 "\xFF" |
|
ser_recv | channel [max=?] [ignore=?] |
Recieve data from the SPI channel buffer. The SPI bus master may need to clock out dummy bytes in order to fill this buffer. eg. ser_send b "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" #dummy bytes to read data from device ser_send b "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ${fsize} = ser_recv b max=32 eol=" " ignore="\xFF" |
|
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 filename.ext |
(slow) | (2019 still in dev...) Read a file from a daughterboard. The local (WOSM SD card) default folder is /"//wosm//data/". The daughterboard folder is the root folder. First line returned (ascii) contains these details (MD5 included if the "filename.ext.MD5" file exists: filename.ext numbytes fatdate [MD5]\n [binary file data .....] eg. ser_file_rd b newdata.dat |
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
lan_ip 192.168.77.44
lan_subn 255.255.255.0
lan_gateway 192.168.77.1
lan_dns1 192.168.77.1
Command | Argument | t (µs) | 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_subnet | Get/set the lan subnet | ||
lan_subn_pfx | Get the lan subnet as prefix bit count. eg. 24 | ||
lan_domain | |||
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). | ||
lan_dns1 lan_dns2 |
Get/set the lan nameserver IPs. Set requires that lan_config=1. | ||
lan_ttl_user lan_ttl_drvr |
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. |
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.
Command | Argument | t (µs) | Description |
---|---|---|---|
wml_run wml_run_wait |
macroname [param1=value] ... [param5=string] |
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. eg. wml_run timelapse2D nframes=1000 expos=100ms intervl=2000ms Will run the macro "timelapse2D.wml". Within this macro commands can refer to the variables "${nframes}" and "${expos}". eg. loop count=${nframes} dur=${intervl} { dig_hilo n ${expos} # camera trigger on line "n" } |
|
macroname | |||
wml_running | (read only) Returns a space-separated list of running macros. | ||
wml_stop | macroname | Stops the macro. Details: On first call the macro is put in "no_loop" mode. Any loops do not repeat, so usually the macro finishes quite quickly. This is intentional behaviour, that will allow any cleanup or housekeeping commands a the end of the macro to run. If this is called when the macro is already in "no_loop" mode, the macro will be halted abruptly. |
|
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. |
These commands will only work in WOSM macros. They will not be recognised in any other context, they'll just raise an "unknown" error.
Command | Argument | t (µ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=?] [dur=?] {...} |
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. Example: loop count=1024 dur=250ms { other commands here.... } 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_text x=0 y=0 "Loop index:\${lp}" #show it on the lcd } |
||
if | ( v1 < v2 ) or ( v1 = v2 ) or ( v1 > v2 ) or ( 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. Example: ${temp} = temp_deg 0 ${msg} = "Normal" if ( ${temp} > 30.0 ){ ${msg} = "HIGH" } if ( ${temp} < 15.0 ){ ${msg} = "LOW" } kyp_lcd_text "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 pause loop {...} (really this sets the fast count-down count to 1, see the loop command) |
stop_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.stop_on -timeout # don't stop the macro if a timeout happens dig_wait a 1 1s # wait 1s for line "a" to go high stop_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. stop_on -all would remove all possible reasons to halt the macro, probably a bad idea. All macros start with an implied "stop_on all" condition, so there's no need to include that command in the macro. |
Some commands accept a time value (eg. "pause 200ms") which needs to be interpreted quickly. The following restrictions apply to these time values:
Each macro has a limited number of local variables. These are text based.
Variables can be set within the macro, or on the macro call line.
eg.
wml_run acquire2D nframes=2000 expos=200ms
This example would set two variables that can be used in the macro "acquire2D.wml", accessible in the macro as as ${nframes} and ${expos}.
Notes:
Global variables: Up to 32 global variables are available to all running macros. They persist after a macro exits. Not wiped till you reboot. Define global variables by prefixing the variable name with "g_".
eg.
${g_count} = ical ${g_count} + 1 #increment a global counter
Command | Argument | 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. eg. ${expos} = "100ms" #set variable 'expos' = '100ms' dig_hilo_t ${expos} #put out a 100ms pulse on line 't' |
||
ical fcal |
${v1} operation ${v2} ["format"] |
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) Examples: ${t1} = ical ${t1} - ${t2} # subtract t2 from t1 ${v1} = fcal ${v1} / 10.24 "%.3Lf" # divide v1 by 10.24, save 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, '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 var1 [var2] ["format"] |
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 = 4) ${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) |
Here for my reference (NJC). Not too useful for macros.
Command | Arguments | t (µs) | Description |
---|---|---|---|
sys_file_app sys_file_boot |
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) | ||
sys_fdat_app sys_fdat_boot |
Read only. Returns the creation date of the file of the last firmware update, main app or bootloader. | ||
sys_ver_app sys_ver_boot |
Read only. Returns the app or bootloader firmware version string. | ||
sys_sdfw_app sys_sdfw_boot |
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 mz_??????.hex, bootloader updates named mzbl????.hex |
||
sys_flash_app sys_flash_boot |
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 MZ_?????.hex, bootloarder firmware is called MZBL????.hex. The ????? is usually the firmware version number. eg. sys_flash_app MZ_0912 will flash the hex file "/wosm/firmware/MZ_0912.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_board | Returns "MX" or "MZ" depending on microcontroller type. | ||
sys_upd_val | 20 | Time (unixtime) of the most recent update check (SD card files). | |
sys_upd_str | 37 | When was the most recent online HTML page update (SD card files). | |
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. |
Users login at HTTP and Telnet connections. The default user "admin" cannot be deleted. At the moment user login is simply for network login.
Command | Arguments | t (µs) | Description |
---|---|---|---|
usr_set | username [MD5=passwordMD5] or 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_del | username | Remove 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. |
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.
Command | Argument | t (µ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_recv | name | [Telnet port 1023 only]. Binary receive the data. |
Here for reference only. These commands provide dynamic HTML content for fast web page loads. Not too useful for macros.
Command | Argument | t (µs) | Description |
---|---|---|---|
htm_sign | |||
htm_edt1 | |||
htm_edt2 | |||
htm_mnu_int1 | |||
htm_mnu_int2 |
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.
fast
${tz} = sys_usec
########### 10 commands to time between 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
############ ... and here.
${t} = sys_usec
${t} = ical ${t} - ${tz} #subtract start time of command block
${t} = ical ${t} - 6 #correct for timer read delay
${t} = fcal ${t} / 10 fmt="%.1Lf" #divide by n=10
kyp_lcd_screen t=1s "Command time:\n\n ${t} us"