Skip to content

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:

Term Definition
state Specially defined Python class that has #StateId = ? at the end of the class definition
method Any function defined inside a class using the def keyword
slot method Special method that Pynapse calls in response to events. Slot method names always begin with a s_ prefix
asset Special Pynapse classes that interact with inputs, outputs, states, controls, globals, and timers. Assets always begins with a p_ prefix. For reference, the list of all slot methods that these assets can trigger, and methods you can use to interact with the assets in Python, can be found in the Assets Reference section of this manual.
function General name used for any function defined outside of a class with the def keyword

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)
Next, Pynapse enters WaitState and immediately runs a specially named Slot Method called 's_State_Enter'. In this example, the s_State_Enter Slot Method turns off the Output (Light) by executing the 'p_Output.Light.turnOff' Output Asset and prints our familiar string.

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.