Dynamic Variables

[[ZSpeed]]
Speed in micron/second, calculated from startup/min/max/slow section speeds in setup page. The result of dynamic speed will be used.
[[ZLiftDistance]]
Amount of lift after layer print in millimeter. The result of dynamic lifting will be used.

Control Keywords

[[LayerChange layer]]
Change current layer eg. [[LayerChange 22.1]]
[[PositionSet mm]]
Update current absolute position eg. [[PositionSet 22.1]]
[[PositionChange mm]]
Update relative position update eg. [[PositionChange -2.1]]

Action Keywords

[[DisplayLayer LayerID]]
Display any layer from current plate eg. [[DisplayLayer 10]]
[[Blank]]
Make screen blank
[[LayerSkip Value]]
For the positive values it skips a layer eg. [[LayerSkip 1]]

It skips any remaining gcode and layer tasks, and starts the next layer.

The more advanced use case example: [[LayerSkip ((100>[[TotalSolidArea]])*(1-[[SkippedLayers]])*([[LayerNumber]]>3))]]
The gcode above would cause layers to be skipped after the first 3 layers if a layer before the current one has not been skipped and the difference between the previous and the current layer is less than 100 pixels.
[[Delay Seconds]]
Put delay eg. [[Delay 1.23]]
[[WaitForDoneMessage]]
Wait for Z_move_comp message from RAMPS or similar boards
[[ResponseCheck ExpectedOK BufferSize]]
Helps syncronize fast moving SLS and laser SLA systems. It limits how many gcode will be send to RAMPS before waiting for response from RAMPS. It requires ok response from RAMPS after commands get completed and not after receiving them.
ExpectedOK integer indicates how many OK will be received from RAMPS board.
BufferSize indicates how many command should be sent out before receiving OK responses.
eg. [[ResponseCheck 1 3]]
[[Pause]]
Pause the printer, requires resume from dashboard to continue.

Communication Keywords

[[Net URL]]
Send get request to the specified URL without waiting for the result eg. [[Net http://example.com/api]]
[[NetReturn URL]]
Send get request to the specified URL and send the result to RAMPS eg. [[NetReturn http://127.0.0.1/gcode?layer=[[LayerNumber]]]]
[[Exec Command]]
Run external command without waiting for the result eg. [[Exec python my_python_script.py]]
[[ExecReturn Command]]
Run external command and send the result to RAMPS eg. [[ExecReturn python my_python_script.py]]

Hardware Keywords

[[GPIOWaitForLow]]
Wait for "wait pin" GPIO to be LOW
[[Projector Command]]
Send any command to the projector eg. [[Projector \x01\x02\x03 On]]
[[GPIOHigh GPIO]]
Makes any GPIO HIGH eg. [[GPIOHigh 12]]
[[GPIOLow GPIO]]
Makes any GPIO Low

Syncronizing Movements

nanoDLP does not have knowledge of how much time it would take to finish a movement. There are a couple of ways to solve this problem.

1. Using [[Delay Seconds]] keyword
It is possible to put delay after each movement. It is the most widely used method.
G1 Z1.1
[[Delay 1.5]]

2. Using [[GPIOWaitForLow]] keyword
To syncronize movements nanoDLP waits for pin to be LOW. At the start of movement, controllers / drivers must make this pin HIGH and at the end of movement make it LOW. Maximum delay for detection is 1ms.
G1 Z1.1
[[GPIOWaitForLow]]

3. Using [[WaitForDoneMessage]] keyword
By using the patched grbl / marlin firmwares you can achieve sync movements. After seeing this keyword nanoDLP will wait for Z_move_comp response from RAMPS.
G1 Z1.1
[[WaitForDoneMessage]]

4. Using [[ResponseCheck ExpectedOK BufferSize]] keyword
If the firmware you are using on the controller board send ok response after execution of each command, you can use this command to syncronize movements.
G1 X1.1
[[ResponseCheck 1 1]]


Crash Recovery

Using the right settings is the key to crash recovery and to benefit from nanoDLP in full potential. A way to do this is to delegate positioning to nanoDLP.
Follow the sample codes below to understand how to delegate positioning to nanoDLP. By doing so in addition to crash recovery, printer stop and other functions also will start working.

Start of Print
G90 ; Put positioning in absolute mode
G28 ; Homing
[[WaitForDoneMessage]] ; Wait until movement is completed, it requires firmwares to get patched for Z_move_comp, if you do not want to use patched firmware you can use [[Delay n.n]] instead
[[PositionSet 0]] ; Set current position on nanodlp so it could be recovered in case of failure

Before Layer
G1 Z[[LayerPosition]] ; Move to layer position
[[WaitForDoneMessage]] ; Wait for the movement to get finished
[[PositionSet [[LayerPosition]]]] ; Save layer position as the current position

After Layer
G1 Z{[[LayerPosition]]+[[ZLiftDistance]]} ; Lift to wait position
[[WaitForDoneMessage]] ; Wait for the movement to get finished
[[PositionChange [[ZLiftDistance]]]] ; Again update position

Resume Print
G90 ; Put positioning in absolute mode
G92 Z[[CurrentPosition]] Y0 X0 ; System crashed so we need to recover current position from nanodlp and set it on RAMP
G1 Z[[LayerPosition]] ; Move to layer position
...