Colibri Runtime
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in Colibri Zephyr orchestrating the hardware resources, I/O drivers and Lua user scripts.
Initially, a single Lua script is supported. But more might follow.
User Program Requirements
The user program/script MUST contain the following functions;
Limits in Lua
Host API
event(event_id, value) publish(event, value) subscribe(event_type, value) unsubscribe(event_type) is_type(event_id, event_type)
Event Types
TIME_PERIOD COUNTER ERROR_CODE MEASURED_VALUE COMPUTED_VALUE SETPOINT MIN_VALUE MAX_VALUE LOW_THRESHOLD HIGH_THRESHOLD RUN_INDICATION ALARM_INDICATION RGB_SET
Example 1 - Blinky
-- do..end is called an "explicit lexical scope", and needed to
-- allow for so called "upvalues", that is the variables in that scope
-- which will persist over invocations from the system.
do
local next=0
local state=0
local period_id
-- local functions are not visible to the host system.
local function tick(now)
if next < now then
-- publish() is the main way to interact with the system
-- Event type RGB_SET is making a request to set the RGB LED to the color value
-- in the second argument, and that value is equal to (r << 16 | g << 8 | b)
-- Negative colors are predefined colors, currently;
-- -1 OK (typically Green)
-- -2 WARNING (typically Yellow)
-- -3 ERROR (typically Red)
-- -4 INFO (typically Cyan)
publish( RGB_SET, -state)
state = (state + 1) % 5
next = now + 300
end
end
-- Called once after program has been loaded into memory.
-- To be called periodically, subscription to a TIME_PERIOD
-- event should be established.
function init()
period_id = subscribe(TIME_PERIOD, 250)
end
-- Entry point for all events. All interaction with the
-- system and I/O subsystem are handled through events.
-- This is to ensure future-compatibility, so that firmware
-- doesn't need to be upgraded when new I/O modules are
-- introduced.
function event(event_id, value)
if event_id == period_id then
tick(value)
end
end
-- terminating() is called just before the program is terminated
-- and removed from memory
function terminating()
publish(RGB_SET, 0)
end
end
Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz
-- do..end is called an "explicit lexical scope", and needed to
-- allow for so called "upvalues", that is the variables in that scope
-- which will persist over invocations from the system.
do
local state1 = 0
local state2 = 0
local counter1 = 0
-- local functions are not visible to the host system.
local function tick()
-- publish to slot 5, channel 2, and the value
publish( create_io( 5, 2, state2 ) )
state2 = !state2
if counter1 = 0 then
-- publish to slot 5, channel 1, and the value
publish( create_io( 5,1, state1 ) )
state1 = !state1
end
counter1 = ( counter1 + 1 ) % 5
end
-- Called once after program has been loaded into memory.
function init()
-- request the 5Hz
period_id = subscribe( TIME_PERIOD, 200 )
end
-- Entry point for all events. All interaction with the
-- system and I/O subsystem are handled through events.
-- This is to ensure future-compatibility, so that firmware
-- doesn't need to be upgraded when new I/O modules are
-- introduced.
function event( event, value )
if event_type( event ) == period_type then
tick()
end
end
-- terminating() is called just before the program is terminated
-- and removed from memory
function terminating()
publish( RGB_SET, 0 )
end
end
Example 3 - Set Analog Output 1 in Slot 4
Example 4 - Raise an Alarm condition
Example 5 - Get Analog Input 2 in slot 1
Example - Level check
Check every minute if Analog Input 2 in slot 2 is >10mA, if so set SSR output 1, and if input < 5mA turn it off.
Example - PID implementation in Lua
Example - Interface Colibri PID1
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.
SetP - Setpoint in ˚C Cycle - Sample frequency in ms P - Proportional constant I - Integral time D - Derivative time MD - Max Derivative value Min - Minimum value, default 0 Max - Maximum value, default 100
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).
Historical
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in Colibri Zephyr orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.