This article describes best practice usage information for each of the programming features, for descriptions on how to implement the feature see topic tutorials.
See full article here.
Place notes anywhere there is an opportunity to describe the function of a variable, event, state machine, activity program and script. This will enable you to easily remember the intent and anyone that follows up behind you to make changes can do so more easily.
Folders - Groups
Organize your programming activities into new folders you create by changing the Group Name of the object. Start the name with the tilde symbol or underscore symbol to force the folder to the top of the folder list. This is a great way of keeping user created content separate from system created folders. Which folder items are located in does not affect program execution, it is strictly for organizational clarity.
When creating variables that represent a State, use the enumeration tab and enter the state enumeration data to make it easy to follow the program and remember what each state represents. A bonus to this is you can now display the text description on the display using a Smart Text Widget. The attributes of the variable automatically transfer to the smart text widget.
Each timer runs in a separate process which uses CPU time, use them judiciously. If you need to run several different routines off of a recurring timer, share the same timer if possible. For example, create a 1000mSec User Event with a recurring timer and any action or user event that needs to be fired every second can be called from that one event rather than a new timer for each one. This greatly reduces CPU overhead and it helps organize your routines.
In this example a folder has been created for all the timed events that will share a common timer.
User events are the backbone of PowerVision programming. With a user event you can fire any system action, timer, or any other event that you wish. You can add these by clicking the plus icon on the right hand side of the actions tab, which will bring up all of the items the event can fire. You can also set events to fire when certain conditions are met, or on a timer that is either one-shot or reoccurring.
Note that actions fired in a event are called sequentially in the order in which they appear by sending a system messages for each one however that does not guarantee the application receiving the message will complete it in the same order. Visit this article for more details, Program Execution Sequence.
This is the most common way to modify the value of a variable. Multiple Calculation Events can be added to a variable to set its value to whatever the Expression equates to (see expressions section). These events must be fired by an external action. Do not fire a calculation event from its own variables "fire on change" function else you could create an endless loop. Rename each calculation event following the naming convention with a unique name to make it easy to search for.
Calculation events use expressions to calculate the value of a variable. Expressions may also be used by other applications within Powervision, the same rules will apply. These expressions can perform simple to complex math and logic operations. When called by an external event the expression will be evaluated and the variables value will be updated. Place notes in the expression to explain what and why.
Data Invalid - NaN (Not a Number)
Powervision allows variables to have a invalid value (not a number) when the "allow invalid" check box is selected. This feature is useful to differentiate between a value of 0 which is a valid value vs NAN indicating the data is invalid. An example of this would be CAN data, engine RPM could be 0 if the engine is off but it could also be 0 if no data is received. A value of NAN would allow differentiating between the two conditions using the isValid function.
CAUTION: When using variables in a expression or calculation event it is best practice to guarantee the variables are not in a NAN state before executing the calculation. If one or more variables in a calculation are abstracted back to a Invalid variable it is possible the CCM will lock up. This situation occurs primarily with J1939 data that is not received as expected. Use the isValid function to test before performing any calculations on a variable that may go invalid.
Example: if(isValid(J1939_Engine_Engine_Speed), 1, 0)
Use a state machine when a process will occupy only one state at a time and can only move in a sequential order from state 1 to state 2 to state 3, etc... until done. This can be thought of as having to wait in a state until some event happens before continuing. If the process requires being able to jump from any one state to any other in random order it will become very difficult to manage transitions between all the possible combinations and ensuring when you leave a state it does so cleanly and that all actions have completed preventing race conditions especially if you are running a loop timer in a state. In such cases it would be better to use a Activity Program or scripting.
Harder to Manage
Activity programs can be thought of as a flow diagrams composed of decision blocks and function blocks. These are best to use when the logic requires performing actions based on multiple decision branches or if you need to implement case logic . This example demonstrates using a multiple decision box on a variable with enumerations, based on the "state" of the variable different actions can be performed much like using case/switch statements. When you select the switch output Auto Create function the outputs are automatically generated based off of the variables enumeration values.
For the most complicated tasks, scripting is the most powerful solution. Everything we have seen previously is possible in scripting with the exception of timers. PowerVision uses the scripting language Angelscript, which is based off of C++. To fire a scripting event, you must simply fire a user event of the same name. You can find reference information for the PowerVision Angelscript functions, as well as the general API in the top tabs of the scripting sub-window