Skip to content

Instantly share code, notes, and snippets.

@gitlarryf
Last active August 4, 2020 17:46
Show Gist options
  • Save gitlarryf/70032db06201dda0dbbe1df6573a7ee8 to your computer and use it in GitHub Desktop.
Save gitlarryf/70032db06201dda0dbbe1df6573a7ee8 to your computer and use it in GitHub Desktop.
MVI69E-LDM Sample code in the Neon Programming Language.
#############################################################################################################################
# File : backplane_sample.neon
# Author : Larry Frieson
# Desc : This file contains sample code for the MVI69E-LDM module in the Neon programming language.
# Date : 11/11/2019
#
# Copyright (C) 2019 ProSoft Technology, Inc. All rights reserved.
#
# Revision History:
# 11/11/2019 17:43:18 LEF - created.
#
#############################################################################################################################
IMPORT mvi69
IMPORT sys
VAR bpHandle: mvi69.MVI69Handle
VAR moduleInfo: mvi69.MVI69ModuleInfo
VAR ioConfig: mvi69.MVI69IoConfig
VAR spHandle: mvi69.NVI69Handle := mvi69.OpenPort(mvi69.SERIAL_PORT_COM1, 9600, 8, 0, 1, mvi69.SERIAL_CONFIG_RS485)
mvi69.WriteSerial(spHandle, “This is RS485!”)
mvi69.CloseHandle(spHandle)
VAR LastRunMode: Number := -1
FUNCTION RunMode(m: Number): String
CASE m
WHEN mvi69.MVI69_RUN_MODE DO
RETURN "RUN"
WHEN mvi69.MVI69_PROGRAM_MODE DO
RETURN "Program"
WHEN OTHERS DO
RETURN "Unknown"
END CASE
END FUNCTION
VAR Read_Buffer: Array<Number> := []
VAR Write_Buffer: Array<Number> := []
# Offset into the read buffer
LET Offset: Number := 0
# Timeout to wait for scan (in milliseconds)
LET Timeout: Number := 1000
###########################################################################################################
#
# open_backplane(void)
# Input:
# none
#
# Output:
# The global MVI69_Handle is set if successful.
#
# Description:
# Opens a connection to the backplane driver, allow access to some of the module hardware
# including backplane communication.
#
###########################################################################################################
FUNCTION open_backplane()
VAR result: Number := mvi69.MVI69_ERR_UNKNOWN
# set module information object
moduleInfo.VendorID := 309 # ProSoft
moduleInfo.DeviceType := 12 # Communications Adapter
moduleInfo.ProductCode := 6112 # EDS product code LDM
moduleInfo.MajorRevision := 1 # Major revision 1
moduleInfo.MinorRevision := 1 # Minor revision 2
moduleInfo.Name := "Neon-LDM"
result = mvi69.SetModuleInfo(bpHandle, moduleInfo)
IF result <> MVI69_SUCCESS THEN
print("MVI69 Set Module info failed: \(result)")
sys.exit(1)
END IF
# open access to backplane/hardware driver
result := mvi69.Open(OUT bpHandle)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 open failed: \(result)")
sys.exit(1)
END IF
result := mvi69.GetIOConfig(bpHandle, OUT ioConfig)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 Get IO config failed: \(result)")
sys.exit(1)
END IF
print("IO Config: Input (Mapped words) \(ioConfig.MappedInputWords)")
print("IO Config: Output (Mapped words) \(ioConfig.MappedOutputWords)")
print("IO Config: Received msg size(words) \(ioConfig.MsgRcvBufSize)")
print("IO Config: Sent Msg Size(words) \(ioConfig.MsgSndBufSize)")
# make sure that the input and output sizes are not bigger than our buffer.
IF ioConfig.MappedInputWords > mvi69.MVI69_MAX_INPUT_WORDS THEN
ioConfig.MappedInputWords := mvi69.MVI69_MAX_INPUT_WORDS
END IF
IF ioConfig.MappedOutputWords > mvi69.MVI69_MAX_OUTPUT_WORDS THEN
ioConfig.MappedOutputWords := mvi69.MVI69_MAX_OUTPUT_WORDS
END IF
# Read the Module information
result := mvi69.GetModuleInfo(bpHandle, OUT moduleInfo)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 Get Module Info failed: \(result)")
sys.exit(1)
ELSE
print("\nModule Information:")
print("::Vendor ID : \(moduleInfo.VendorID)")
print("::Device Type : \(moduleInfo.DeviceType)")
print("::Product Code : \(moduleInfo.ProductCode)")
print("::Major Rev. : \(moduleInfo.MajorRevision)")
print("::Minor Rev. : \(moduleInfo.MinorRevision)")
print("::Serial No. : \(moduleInfo.SerialNo:x)")
print("::Name : \(moduleInfo.Name)")
END IF
END FUNCTION
###########################################################################################################
#
# main program
# Input:
# argv - list of arguments.
#
# Description: This program
# - establishes communication with the CompactLogix Controller.
# - Reads a block of data from the controller,
# and writes that block back to the controller.
#
###########################################################################################################
FUNCTION main(argv: Array<String>)
VAR result: Number := 0
VAR run_mode: Number := 0
VAR scan_count: Number := 0
VAR Last_Read_Data_Sample: Number := -1
VAR transfer_size: Number := 0
print("\nProgram Initialization....")
#| ** NOTE: Currently, we don't need to setup the signal handlers. Maybe in the future.
Today, the user just calls mvi69.Signal() to get a signal value, IF one has
been raised.
# set up special event handlers.
signal(SIGSEGV, sigquit_handler)
signal(SIGQUIT, sigquit_handler)
signal(SIGINT, sigquit_handler)
signal(SIGTERM, sigquit_handler)
|#
# print version info and exit if requested.
IF argv.size() > 1 THEN
IF (argv[1][0] = "-" AND (argv[1][1] = "h" OR argv[1][1] = "H")) THEN
print("\n Usage:\n Backplane_Sample\n Communicates over the backplane transferring the output")
print("\n block back to the input block.\n There are no parameters.")
sys.exit(1)
END IF
END IF
# open access to backplane and hardware
open_backplane()
# echo back copy is limited by the smaller of the input or output image size
IF ioConfig.MappedInputWords > ioConfig.MappedOutputWords THEN
transfer_size := ioConfig.MappedOutputWords
ELSE
transfer_size := ioConfig.MappedInputWords
END IF
# initialize LEDs
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_OK, mvi69.MVI69_LED_STATE_GREEN)
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_CFG, mvi69.MVI69_LED_STATE_GREEN)
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_P1, mvi69.MVI69_LED_STATE_OFF)
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_P2, mvi69.MVI69_LED_STATE_OFF)
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_BP, mvi69.MVI69_LED_STATE_OFF)
mvi69.SetLED(bpHandle, mvi69.MVI69_LEDID_NET, mvi69.MVI69_LED_STATE_GREEN)
print("\nProgram Running....")
# main task loop, stay here forever
REPEAT
# read the scan mode from the backplane.
result := mvi69.GetScanMode(bpHandle, OUT run_mode)
IF result <> MVI69_SUCCESS THEN
print("MVI69 Get Scan Mode failed: \(result)")
sys.exit(1)
END IF
IF run_mode <> Last_Run_Mode THEN
print("\nRun mode changed from \(RunMode(Last_Run_Mode)) to \(RunMode(run_mode))")
Last_Run_Mode := run_mode
END IF
# wait for the the next input (output does exactly the same thing) scan.
result := mvi69.WaitForInputScan(bpHandle, Timeout)
IF result <> mvi69.MVI69_ERR_TIMEOUT THEN
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 wait for scan failed: \(result)")
sys.exit(1)
END IF
# read the current scan count
result := mvi69.GetScanCounter(bpHandle, OUT scan_count)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 Get Scan Counter failed: \(result)")
sys.exit(1)
END IF
#read connected data from module
result := mvi69.ReadOutputImage(bpHandle,
Offset,
IO_Config.MappedOutputWords,
OUT Read_Buffer)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 Read Output Image failed: \(result)")
sys.exit(1)
END IF
# play with data block
# if the data changed in the output from controller, copy it back to the controller.
# otherwise decrement it down to zero
IF Read_Buffer[2] <> Last_Read_Data_Sample THEN
# there is new output data, so just copy the new output data to the input area.
FOR i := 0 TO transfer_size * 2 DO
Write_Buffer[i] := Read_Buffer[i]
END FOR
Last_Read_Data_Sample := Read_Buffer[2]
ELSE
# decrement the input (ie write) data
FOR i := 1 TO transfer_size DO
IF Write_Buffer[i] > 0 THEN
DEC Write_Buffer[i]
END IF
END FOR
END IF
# put the scan count in the first element of the buffer
Write_Buffer[0] := scan_count MOD 5000
# print the scan count every 5000 scans, just so we can see things are working.
#IF Write_Buffer[0] = 0 THEN
# print("Scan count is \(scan_count)")
#END IF
# write data back to controller input image
result := mvi69.WriteInputImage(bpHandle,
Offset,
IO_Config.MappedInputWords,
Write_Buffer)
IF result <> mvi69.MVI69_SUCCESS THEN
print("MVI69 Write Input Image failed: \(result)")
sys.exit(1)
END IF
END IF # if not timeout
UNTIL mvi69.Signaled() = mvi69.SIG_INT # main program loop
END FUNCTION
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment