Skip to main content

Script Basics and Syntax

Structure of .nnpscript files and line syntax


File Format​

Script files use the .nnpscript extension and are plain text files. Each non-comment line is assembled into tokens (OpCode + operands) and compiled into a compact binary image for download to the Power Module. Comments and whitespace are stripped during assembly.

% Script metadata and description
% Author: Your Name
% Created: YYYY-MM-DD

% Variable declarations
global uint8 myCounter = 0
stack uint16 tempValue = 0

% Code sections with labels
{Init}
MOV 0 => myCounter
GOTO => MainLoop

{MainLoop}
ADD myCounter 1 => myCounter
GOTO => End

{End}
NOP

Comments​

Comments begin with % and continue to the end of the line:

% This is a single-line comment
MOV 5 => myVar % Inline comment

Code Block Labels​

Labels define jump targets for control flow. They must be enclosed in braces:

{SectionName}
% Code goes here

{AnotherSection}
% More code

Basic Script Line Form​

Every executable line follows this pattern:

OpCode Operand Operand => Destination
  • OpCode — from the OpCode list (e.g., MOV, ADD, BEQ)
  • Operands — 0 to 5 inputs, depending on the OpCode
  • Destination — result location, a jump label, or omitted

Data Types​

Scripts support the following data types. When writing to a network location, the type name is required (e.g., N7:1F53.1|uint8).

TypeSizeRangeNotes
uint88-bit0 to 255Unsigned byte
uint1616-bit0 to 65,535Unsigned short
uint3232-bit0 to 4,294,967,295Unsigned integer
int88-bit-128 to 127Signed byte
int1616-bit-32,768 to 32,767Signed short
int3232-bit-2,147,483,648 to 2,147,483,647Signed integer
BOOL8-bit0 or 1Boolean
stringvariable—Text; cannot be used as an array
FIXP32-bit—Fixed point: 16-bit signed integer + 8-bit decimal
BYTEARRAYvariable—Byte array; can only be a constant

Variable Scope​

Variables must be declared before use. Three scope levels are available, each with a different persistence model.

Stack Variables (stack)​

Temporary variables that do not persist between script executions. Memory is released when the script completes and the value is not accessible from other scripts.

Syntax (text editor):

stack <type> <name> = <initial_value>

Examples:

stack uint8 loopCounter = 0
stack int16 sensorReading = -1
stack string logPrefix = "Scan"

Global Variables (global)​

Persistent variables that retain their values between script runs. Accessible from other scripts running on the same module. Global variables are not shared across scripts directly.

Syntax (text editor):

global <type> <name> = <initial_value>

Examples:

global uint8 sessionCount = 0
global uint16 totalStimTime = 0
global uint8 systemState = 0

Constant Variables (const)​

Global in scope but cannot change value once declared.

Syntax (text editor):

const <type> <name> = <initial_value>
const <type> <name>[<size>] = [<v1> <v2> ... <vN>]

Examples:

const uint8 maxFrequency = 43
const uint8 patternList[7] = [1 2 3 4 5 6 9]

Array Variables​

Any integer data type may be stored as an array. The array size must be specified in the declaration. Strings cannot be arrays. Byte arrays can only be constants.

Declaration:

const uint8 patternList[7] = [1 2 3 4 5 6 7]
stack uint8 channelAmps[4] = [0 0 0 0]

Accessing array elements — use brackets with an index after the variable name:

% Read element at index 2
MOV patternList[2] => currentPattern

% Write to element at index 0
MOV 50 => channelAmps[0]

Memory Addressing​

NNPScript provides direct access to the Object Dictionary (OD) for reading and writing device parameters.

Address Syntax​

% Simplified (most common)
N<NODE>:<INDEX>.<SUBINDEX>|<TYPE>

% Advanced
N<PORT,NETID>NODE:INDEX.SUBINDEX|TYPESPEC^NUMSUBINDICES

Components​

ComponentDescriptionExample
NODEDevice node ID (PM=7, CT=8, RM=1-6,9-15)7
INDEXOD index in hexadecimal1006, 1F53
SUBINDEXOD subindex in hexadecimal0, 03, 1A
TYPEData type specifieruint8, uint32
^COUNTNumber of consecutive subindices (optional)^2, ^4

Reading from OD​

MOV N7:1006.0|uint32 => syncPeriod
MOV N5:1018.3|uint32 => nodeSWRev

Writing to OD​

When writing, cast the destination with the type:

MOV 50 => (uint32)N7:1006.0
MOV syncPeriod => (uint32)N7:1006.0

Defined Variables (Memory Aliases)​

define creates a named reference to a specific Object Dictionary location. These act as aliases to persistent memory locations and are resolved at assembly time.

Syntax:

define <name> = N<node>:<index>.<subindex>|<type>
define <name> = N<node>:<index>.<subindex>^<count>|<type>

Examples:

% Single value alias
define stimFreq = N7:1F57.5|uint8

% Array / multiple value alias: 2 consecutive subindices starting at subindex 3
define StimParams[] = N7:1F57.3^2|uint8

Naming Conventions​

ElementConventionExample
VariablescamelCasestimFrequency, loopCounter
LabelsPascalCase{StimActive}, {ErrorHandler}
ConstantscamelCase or UPPERmaxFreq, MAX_FREQ