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
stringvariableText; cannot be used as an array
FIXP32-bitFixed point: 16-bit signed integer + 8-bit decimal
BYTEARRAYvariableByte 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