Quick Start Example
In this example we want to turn a light on with the capture of a button press, and then turn the light off when the button is released. We will have a single input for our button ('Button') and a single output for the light ('Light'). If you were to code this in Python, it might look something like this:
import time
while True:
print('WaitState entered')
# turn off output
Light.off()
# wait until button is pressed
while Button.false():
time.sleep(.01)
print('OnState entered')
# turn on output
Light.on()
# wait until button is false
while Button.true():
time.sleep(.01)
# go back to beginning
In Pynapse, instead of using a while loop, we define things called States that can call upon specified methods that we call Slot Methods and Asset Methods when certain hardware events occur. Pynapse knows the current State and is constantly polling the inputs directly from the hardware in a tight loop. When a hardware event occurs that has a matching Slot Method in the current State, that Slot Method gets triggered. The result of this is simplicity in how your state machine is coded - instead of using embedded while loops and conditional statements, you can simply use States and integrated Slot Methods and Asset Methods to issue commands and move from one state to another depending on what events have occurred on the hardware or outputs of code calculations.
Here is a table of important definitions of terms you will see throughout this example and in the Pynapse manual:
For the quick start example, we are going to demonstrate how to perform our Light on/off task in two ways: the first is going to use the initial 'Always' State in Pynapse; the second is going to show you how to use multiple States to switch between active pieces of code and perform certain tasks based on captured hardware events.
Using the Always State
The special State called 'Always' runs on every polling loop regardless of what the Pynapse active State is. In our example, we can take advantage of this special State by just focusing on writing code that triggers based on hardware events and not worrying about the Pynapse State machine. Since the 'Always' State is present in the Pynapse Source by default, all we write are Slot Methods and Asset Methods:
# Pynapse Source #
class Always: #StateID = 0
def s_Button_rise():
p_Output.Light.turnOn()
print('Light is on!')
def s_Button_fall():
p_Output.Light.turnOff()
print('Light is off!')
A high-level translation of this code would read as follows:
In the Always State, if the 'Button' input true (button is pressed), then turn the 'Light' output on and print "Light is on!"; if the 'Button' input is false (button is released), then turn the 'Light' output off and print "Light is off!".
Here is the same translation using Pynapse terminology:
As mentioned, Pynapse is constantly polling the hardware for events that trigger methods inside of the current active State (Always). In this case, we've defined two Slot Methods 's_Button_rise' and 's_Button_fall' which are part of the Input Assets. The 's_Button_rise' Slot Method triggers when the button is pressed (Button input changes to true) and the 's_Button_fall' triggers when the button is released (Button input changes from true to false). When the button press is detected, Pynapse internally executes the Output Pynapse Asset Method (Light.turnOn), which toggles the output logic signal from low to high. When the button is released, the Light.turnOff Asset Method is executed.
Note
If the button was released first (e.g you were pressing down the button as you went to run-time then let go) the 's_Button_fall' Slot Method would trigger first. These Slot Methods are independent functions that are beholden only to detected hardware events - they do not influence each other.
Important
All Pynapse Slot Methods start with s_
and all Pynapse Assets start with p_
. Remembering
these two prefixes makes it easy to use code completion inside the
Pynapse Code Editor to see all the available Slots and Assets right inside the
editor and quickly find what you are looking for.
After we test this code (right-click 'Main' → 'Test') and go to run-time, you will see the Light output toggle on and off with the pressing or release of the Button input.
Using Multiple States
This example was entirely coded in the Always State. Now, we'll take advantage of Pynapse's built-in State Machine. Using multiple Pynapse States has major advantages at runtime, especially as your paradigm increases in complexity. You get a visual indicator of what State you are in for behavior monitoring and the State changes are timestamped and recorded in the data tank synchronized with the rest of your data. There are some other debugging features you get at run-time as well, discussed in more detail in Run-Time and Debugging.
Here we define three states: Always, WaitState and LightOn. When moving to run-time (Standby, Preview, or Record mode) Pynapse enters the Always State and the 's_Mode_recprev' Slot Method is triggered. This is a Synapse Control Slot Method that detects when Synapse has changed mode from Idle to Preview or Record. Once 's_Mode_recprev' is triggered the 'p_State.switch(WaitState)' Asset Method is executed. This key asset tells Pynapse to move to a new State.
# Pynapse Source #
class Always: #StateID = 0
def s_Mode_recprev():
p_State.switch(WaitState)
Now, just like in the first example that only used the Always State, we monitor hardware events and wait for the Input (Button) to become true, wherein another switch Asset Method is executed and we move to our third State (LightOn).
Note
While WaitState is our active State a release of the button will not do anything since there are no Slot Methods in WaitState that detect falling-edge hardware events.
class WaitState: #StateID = ?
def s_State_enter():
p_Output.Light.turnOff()
print('Light is off!')
def s_Button_rise():
p_State.switch(LightOn)
Finally, we enter the LightOn State. As we enter, the 's_State_enter' Slot Method is triggered and the 'p_Output.Light.turnOn' Asset Method is executed. As you can see, coordinating output events to State changes is a simple way to write conditional events in the Pynapse State Machine. Similarly to the WaitState, Pynapse will continue polling until the 's_Button_fall' Slot Method is triggered by a button release, wherein we switch back to WaitState and the Output (Light) is turned off.
class LightOn: #StateID = ?
def s_State_enter():
p_Output.Light.turnOn()
print('Light is on!')
def s_Button_fall():
p_State.switch(WaitState)
Important
Notice there were no while
loops used in these examples. In Pynapse you should almost never
write while
loops. Its polling loop handles this for you. All of your methods should return
immediately so the polling loop can continue executing.