A signalling approach to consider to minimize the PLC code required:
- Allocate a PLC array tag / file with enough integers to cover all of the momentary button bits you need for your application, plus two more for transmit counter/comparison at the end. Do not create Ignition tags for these PLC tags.
- Create a script module in Ignition that holds an array of timestamps for the number of bits needed, plus a persistent counter in a module global. Write two functions:
- A message handler that takes a bit number and sets the corresponding timestamp to some number of milliseconds in the future. 150ms or so.
- A gateway timer event function that loops through all of the timestamps, treating all in the past as 0 and all in the future as 1, packing the results bitwise into integers, appends the incremented counter, and writes them all to the PLC in a single system.opc.writeValues() call. Does not write to the last register in the array/file. Call every 100ms or so.
- Write a few rungs in the PLC to check the last integer against the second to last, run a timer while equal, then copy the Ignition counter to the last register. If/when the timer expires, 200ms or so, (broken comms), fill the array with zeros.
- In a client window, create a timer component with a 100ms period. In its actionPerformed method, use system.util.sendMessage() with a specific bit number.
- In the same client window, create a momentary button for that bit and bind its value to the timer component’s enabled property. Do not bind it to any tag.
Create as many timer/PB pairs as needed, up to the capacity of the PLC array (less the last two words), each with their own bit numbers. Use the corresponding bit in the PLC as a reliable normally-open PB.
Any lost messages, lost OPC writes, or Client GUI freezes will yield a zero bit in the PLC.