Last active
August 4, 2020 17:46
-
-
Save gitlarryf/70032db06201dda0dbbe1df6573a7ee8 to your computer and use it in GitHub Desktop.
MVI69E-LDM Sample code in the Neon Programming Language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################################# | |
# 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