🔍
v1.3.8

Standard Library

The standard library (NEW_FB_STANDARD_LIB_V3) provides helper functions and function blocks used across all XBB recipes. It includes things like value clamping, dimming control, battery monitoring, and wake-up logic.

Important: You Must Add Libraries Manually

Standard libraries are not added automatically to new recipes. You must manually add them to your recipe’s library list in the correct order. The standard libraries are available as shared libraries in the system - you do not need to create them, but you do need to link them to your recipe.

The correct library order is:

  1. NEW_FB_STANDARD_LIB_V3 - core function blocks
  2. NEW_UDS_DID_WAKE_UP_V2 (UDS) or NEW_PP_CAN_FD_WAKE_UP_V1 (PP-CAN) - wake-up
  3. Your DID module / CAN reading library
  4. NEW_STANDARD_FUNCTIONS_V1 - settings, flashers, worklights
  5. Your main recipe (last)

Once the standard library is linked, all its functions and function blocks become available in your code. For example, HW : HARDWARE is declared and initialized by the standard library, so you can use HW.SUPPLY_VOLTAGE directly without declaring it yourself.

Helper Functions

VAL_CLAMP

Clamps a value to a min/max range. Returns MIN if below, MAX if above, otherwise unchanged.

// Definition (in standard library):
FUNCTION VAL_CLAMP : DINT
    VAR_INPUT
        INVAL : DINT;   // Value to clamp
        MIN : DINT;      // Lower bound
        MAX : DINT;      // Upper bound
    END_VAR;

// Usage in your recipe:
result := VAL_CLAMP(brightness, 0, 1000);    // Clamp to PWM range
temp := VAL_CLAMP(rawTemp, 0, 250);           // Clamp to sensor range
speed := VAL_CLAMP(rawSpeed, 0, 300);         // Clamp to max speed
Tip

VAL_CLAMP is used extensively in production recipes, especially for the HIGHBEAM output: HIGHBEAM(VALUE := VAL_CLAMP(signal, 0, 1000), PERIOD := 1000);

PLC_INPUT

Converts the analog input voltage to a clean BOOL by comparing it against the supply voltage. Returns TRUE when analog input is above 70% of supply, FALSE when below 30%. Holds previous state between 30–70% (hysteresis).

// Definition:
FUNCTION PLC_INPUT : BOOL
    VAR_INPUT
        REF : DINT;     // Reference voltage (mV) - use HW.SUPPLY_VOLTAGE
        IN : DINT;      // Input voltage (mV) - use HW.ANALOG_IN0
    END_VAR;

// Usage (read ignition from analog input on Dongle-2):
VAR_SIGNAL
    HW : HARDWARE;
    SIGNAL_IN_TANDNING : BOOL;
END_VAR;

HW();
SIGNAL_IN_TANDNING := PLC_INPUT(HW.SUPPLY_VOLTAGE, HW.ANALOG_IN0);

Recommended for VAG vehicles (VW, Audi, Skoda, Seat, Cupra, Porsche) with +12V on OBD-II pin 1. See Example 6.

GET_PLC_TIME

Returns time in milliseconds since program start as UDINT. This is the PLC’s internal clock, similar to GET_SYSTEM_TIME().

VAR
    start : UDINT;
    elapsed : UDINT;
END_VAR;

start := GET_PLC_TIME();
// ... do work ...
elapsed := GET_PLC_TIME() - start;  // Elapsed time in milliseconds

RND

Pseudo-random number generator using a Linear Congruential Generator (LCG) algorithm. Returns a value from 0 to MAX−1.

// Definition:
FUNCTION RND : UDINT
    VAR_INPUT
        MAX : UDINT;    // Upper bound (exclusive)
    END_VAR;

// Usage:
random_value := RND(100);         // Returns 0-99
random_delay := 500 + RND(1500);  // Returns 500-1999

About the Algorithm

LCG is a simple, fast, and deterministic algorithm commonly used in embedded systems. It uses the formula: seed = (a * seed + c) mod m, where a, c, and m are fixed constants. The output is then mapped to the range 0..MAX-1 using modulo.

What this means for you:

Good for: random flash patterns, variable delays, visual effects, staggering CAN request timing.
Not suitable for: cryptography, encryption keys, security tokens.

BYTE_TO_BOOL

Converts a BYTE to BOOL. Returns TRUE if value > 0, FALSE if value = 0.

FUNCTION BYTE_TO_BOOL : BOOL
    VAR_INPUT
        MYBYTE : BYTE;
    END_VAR;

// Usage:
flag := BYTE_TO_BOOL(canData[3]);   // TRUE if byte is non-zero

Function Blocks

These function blocks are instantiated automatically by the standard library. You interact with them by setting their input variables and reading their outputs.

DIM_MATRIX

Smooth dimming controller for lights. Creates fade-in/fade-out effects by ramping the output value gradually instead of switching instantly.

VariableTypeDirectionDescription
DIMBOOLInputEnable gradual dimming (ramp up when TRUE, ramp down when FALSE)
ONBOOLInputInstant on/off (bypasses dimming, jumps to MAX/MIN)
UPINTInputIncrement step per scan cycle when ramping up
DOWNINTInputDecrement step per scan cycle when ramping down
MININTInputMinimum output value
MAXINTInputMaximum output value
OUTINTOutputCurrent output level (ramps between MIN and MAX)
OUT_STATICINTOutputTarget level (MIN or MAX)
VAR
    DIMMER : DIM_MATRIX;
END_VAR;

VAR_OUTPUT
    LIGHT : OUTPUT;
END_VAR;

// Configure dimming parameters
DIMMER(
    DIM  := SIGNAL_HELLJUS,    // Ramp up when high beam on, ramp down when off
    ON   := FALSE,             // Not using instant on
    UP   := 50,                // Ramp up speed (higher = faster)
    DOWN := 30,                // Ramp down speed (lower = smoother fade-out)
    MIN  := 0,
    MAX  := 1000
);

// Use the dimmer output for smooth light control
LIGHT(VALUE := DIMMER.OUT, PERIOD := 1000);
Tip

Adjust UP and DOWN to control transition speed. Typical values: UP=50, DOWN=30 (slightly slower fade-out than fade-in). Higher values = faster transition, lower = smoother.

GYRO_DETECT

Gyroscope-based movement detection. Detects vehicle movement by monitoring the dongle’s built-in gyroscope. Key component of the wake-up system.

VariableTypeDirectionDescription
XINTInputGyro X axis (from HW.GYRO_X)
YINTInputGyro Y axis (from HW.GYRO_Y)
ZINTInputGyro Z axis (from HW.GYRO_Z)
THRESHOLDINTInputMovement threshold (higher = less sensitive)
INIT_DELAYTIMEInputIgnore readings during startup
MOVEMENTBOOLOutputTRUE when movement detected
READYBOOLOutputTRUE when init delay has passed

GYRO_DETECT is used internally by the wake-up library to detect vehicle movement. The wake-up library creates the instance, feeds it gyro data from HW, and uses it to trigger system wake-up. You configure it indirectly through your recipe’s wake-up settings:

// In your main recipe - this is all you need:
GYRO_WAKE_UP := TRUE;     // Enable gyro-based wake-up
GYRO_VALUE := 60;          // Sensitivity threshold (higher = less sensitive)

// The wake-up library internally does:
//   GYRO.X := HW.GYRO_X;
//   GYRO.Y := HW.GYRO_Y;
//   GYRO.THRESHOLD := GYRO_VALUE;   (your setting)
//   GYRO();
//   IF GYRO.MOVEMENT THEN ... wake up ...
Tip

For electric vehicles with heat pumps or other vibration sources, increase GYRO_VALUE to 100–150 to prevent false wake-ups. Default is 60.

BATT_MONITOR

Battery voltage monitor with hysteresis and delay. Detects low-battery conditions to prevent draining the vehicle battery. Managed internally by the wake-up library.

VariableTypeDirectionDescription
VOLTAGEINTInputCurrent voltage (mV)
OFF_MVINTInputLow battery threshold (mV)
ON_MVINTInputRecovery threshold (mV)
DELAYTIMEInputDelay before state change
LOW_BATTBOOLOutputTRUE when battery is low

Like GYRO_DETECT, you configure battery monitoring through your recipe’s wake-up settings - the wake-up library does the rest:

// In your main recipe - this is all you need:
BATTOFF := 11500;          // 11.5V - shut down threshold
BATTON := 11900;           // 11.9V - recovery threshold (hysteresis)
LOW_BATT_DELAY := T#30s;   // Wait 30s before declaring low battery

// The wake-up library internally does:
//   BATT.VOLTAGE := HW.SUPPLY_VOLTAGE;
//   BATT.OFF_MV := BATTOFF;        (your setting)
//   BATT.ON_MV := BATTON;          (your setting)
//   BATT.DELAY := LOW_BATT_DELAY;  (your setting)
//   BATT();
//   IF BATT.LOW_BATT THEN SIGNAL_SYSTEM_ON := FALSE;

BLINKER

Simple blink generator with configurable period. Toggles output on/off at a fixed rate. Unlike the wake-up blocks above, BLINKER can be used directly in your code.

VariableTypeDirectionDescription
PERIODTIMEInputHalf-period (full cycle = 2x PERIOD)
QBOOLOutputToggling output (TRUE/FALSE)
VAR
    BLINK : BLINKER;
    blink_value : INT;
END_VAR;

VAR_OUTPUT
    WARNING_LED : OUTPUT;
END_VAR;

// Configure and call the blinker
BLINK.PERIOD := T#300ms;   // 300ms on, 300ms off = ~1.7 Hz
BLINK();

// Use BLINK.Q to drive output (via intermediate variable)
IF BLINK.Q THEN
    blink_value := 1000;
ELSE
    blink_value := 0;
END_IF;

// Output always called every cycle
WARNING_LED(VALUE := blink_value, PERIOD := 1000);

WAKE_TIMER

Off-delay timer for system wake-up. Unlike TOF, WAKE_TIMER starts with Q = FALSE (safe at startup - system stays off until triggered). Managed internally by the wake-up library.

VariableTypeDirectionDescription
INBOOLInputTrigger (movement, ignition, etc.)
PTTIMEInputHold time after trigger goes FALSE
QBOOLOutputSystem-on output

You configure the hold time via your recipe:

// In your main recipe - this is all you need:
SYSTEM_ON_TIME := T#30s;   // Stay awake 30s after last movement/ignition

// The wake-up library internally does:
//   TMR_SYSTEM_ON.IN := GYRO.MOVEMENT OR SIGNAL_TANDNING;
//   TMR_SYSTEM_ON.PT := SYSTEM_ON_TIME;   (your setting)
//   TMR_SYSTEM_ON();
//   SIGNAL_SYSTEM_ON := TMR_SYSTEM_ON.Q;

Behavior: When IN is TRUE, Q is TRUE. When IN goes FALSE, Q stays TRUE for PT milliseconds, then goes FALSE. This keeps the system awake for a configurable period after the last movement or ignition signal.

BMW_WAKE_SPECIAL

BMW-specific wake-up handler. BMW vehicles trigger alarms if the CAN bus is not periodically acknowledged. This block toggles between SILENT and NORMAL CAN mode every few seconds to empty the CAN buffer without triggering the alarm. Managed internally by the wake-up library.

VariableTypeDirectionDescription
ENABLEBOOLInputMaster enable
ACK_INTERVALTIMEInputHow often to cycle CAN mode
ACTIVEBOOLOutputBMW special mode is active
CAN_MODE_OUTBYTEOutput1=SILENT, 2=NORMAL

You enable it via your recipe’s wake-up settings:

// In your main recipe - this is all you need for BMW:
CAN_WAKE_UP := TRUE;       // Must be TRUE for BMW
GYRO_WAKE_UP := FALSE;     // Must be FALSE when CAN_WAKE_UP is TRUE
BMW_WAKE_UP := TRUE;        // Enable BMW alarm handling

// The wake-up library internally does:
//   BMW.ENABLE := BMW_WAKE_UP AND CAN_WAKE_UP;
//   BMW.ACK_INTERVAL := T#3s;
//   BMW();
//   IF BMW.ACTIVE THEN
//       toggle CANMODE between SILENT and NORMAL every 3s
//   END_IF;
Warning

BMW_WAKE_SPECIAL is only for BMW vehicles. Setting BMW_WAKE_UP := TRUE on non-BMW vehicles will cause the CAN controller to switch between SILENT and NORMAL mode repeatedly, which prevents normal communication.

Global Hardware Instance

The standard library declares a global HARDWARE instance named HW:

// Declared by the standard library (do NOT redeclare):
VAR_SIGNAL
    HW : HARDWARE;
END_VAR;

HW();
HW.GYRO_Z := 0;   // Workaround for faulty Z axis on some hardware

This HW instance is available in all recipe files. You do not need to declare it yourself - just use HW.SUPPLY_VOLTAGE, HW.GYRO_X, HW.BUTTON, etc. directly.

Standard Libraries Reference

These are the standard libraries you should add to your recipe. They are shared libraries available in the system - you link them to your recipe, you do not create them yourself.

LibraryReference RecipePurpose
NEW_FB_STANDARD_LIB_V3 1332 / 1568 Core function blocks, helper functions, HW instance (this chapter)
NEW_UDS_DID_WAKE_UP_V2 1332 UDS wake-up: gyro detection, CAN init, sleep management
NEW_PP_CAN_FD_WAKE_UP_V1 1568 PP-CAN wake-up: voltage detection, CAN mode management
NEW_STANDARD_FUNCTIONS_V1 1332 / 1568 Settings UI, flasher patterns, worklights, common utilities
Do NOT Recreate

These libraries already exist in the system. Do not create your own copies - just link the existing ones to your recipe. Duplicating them causes compilation errors from duplicate variable declarations.

You can find these libraries by searching in the library list. If you are starting from a template or copying an existing recipe, the libraries are usually already linked. If you are creating a recipe from scratch, add them manually in the order shown above.