@refaQtor said:
Thanks for your investigations on the compiler side. Local C compiling (and others) of Catalina is really really interesting; just not what I'm doing at the moment.
No worries. PLCs are not really my thing, I'm just interested in any applications that could take advantage of Catalina's unique set of features, and a PLC implementation would be a good demo.
Someone may be interested porting LDmicro (a graphical ladder logic editor that generates ".ld" files that OpenPLC can then convert to C) to the P2, so I'll include the bit I've already done as a demo in the next Catalina release.
@RossH said:
I'm just interested in any applications that could take advantage of Catalina's unique set of features
sweet. I get it. I think I'll leave Catalina on an old P1 (maybe P2, if I want to compile) hooked to VGA/kbd, make use it like a console into other things. I'll get more use to it and find more uses for it.
I have a P1 PLC, This is it. For now I just use IDEC FC6A, not too pricey, Software is good both upload and download, simulator mode too, for checking your ladder functions. I've used accroloop before now parker automation. They had a ladder program that was just "C" in the background. So I would open their ladder program with windows notepad and just "C" code it.
An IDE for propeller that could up load the eprom and display it back in spin would be genius. Anybody out there up for the challenge.
The "coil" output can be many devices though. From direct ON/OFF to SET/RESET to multiple rung devices to memory writes/copies to magic function calls. Can be expanded as development progresses.
@cgracey said:
Is there a list of expected relay-logic functions and operations that a compiler ought to handle?
as relays are the basic implementation of binary logic... all of those basics are expected, and to provide utility in the PLC world where there are data registers to act upon, there are math functions. it is useful to have them itemized, so I ask Perplexity to do that for us:
A PLC compiler should handle a wide range of relay-logic functions and operations to emulate traditional relay-based control systems while leveraging the flexibility and power of digital logic. Below is a list of expected functions and operations:
Basic Logic Operations
AND: Series-connected inputs where all conditions must be true for the output to activate.
OR: Parallel-connected inputs where any one condition being true activates the output.
NOT: Inversion of an input signal, typically represented by normally closed (NC) contacts.
NAND: Logical negation of an AND operation.
NOR: Logical negation of an OR operation.
XOR (Exclusive OR): Output is true when only one of two inputs is true.
Sequential and Memory Functions
Latching (Set/Reset): Maintaining an output state until explicitly reset, often used in start/stop circuits.
Flip-Flops: Internal memory elements for toggling states based on inputs.
Timers and Counters
On-delay timers: Output activates after a specified delay once the input condition is met.
Off-delay timers: Output remains active for a specified time after the input condition is removed.
Counters: Incrementing or decrementing counts based on input events, with preset thresholds.
Sequencers: Stepwise execution of processes based on predefined conditions.
PID control loops for process regulation.
Input/Output Handling
Reading discrete inputs (e.g., switches, sensors) and updating their status in memory.
Controlling discrete outputs (e.g., relays, solenoids) based on program logic.
Diagnostics and Monitoring
Status monitoring of inputs, outputs, and internal variables for troubleshooting.
Error detection and handling mechanisms.
Specialized Logic
Interlocks and safety circuits to ensure safe operation in industrial environments.
Combinational logic circuits combining AND, OR, NOT operations for complex conditions.
These functions allow PLCs to replicate traditional relay logic while offering enhanced flexibility and scalability. This comprehensive functionality is essential for automating machinery and processes effectively in industrial applications[1][2][3].
This screenshot from the OpenPLC IDE shows an aspect that seems like a constant arms-race - keeping up with constant new sensor/protocol products that come out with Arduino code by default.
Though there is an aspect to this PLC IDE does have a nice sort of object assembly interface that might play well as a category in OBEX. (which, I might add, has really been coming into its own with constant relevant fresh activity
and here is an outline of how a basic PLC ladder logic interpreter might work
Basic Architecture of a Ladder Logic Interpreter
A ladder logic interpreter processes ladder diagrams by scanning inputs, evaluating rungs, updating outputs, and managing timers/counters in a cyclic manner. Here's the architecture broken into functional blocks:
1. Core Components of the Interpreter
Input Scan
Reads the state of all physical and virtual inputs (e.g., sensors, switches).
Updates an Input Image Table (a memory structure that stores the current state of all inputs).
Logic Evaluation
Processes each rung in the ladder diagram sequentially (or in parallel if multiple cogs are allocated).
Evaluates logical conditions (e.g., contacts, coils) based on the Input Image Table and internal registers.
Executes instructions for timers, counters, math operations, or advanced functions (e.g., PID loops).
Output Update
Updates the Output Image Table based on the results of logic evaluation.
Writes the updated states to physical outputs (e.g., relays, actuators) or virtual outputs.
Timer/Counter Management
Manages runtime values for timers and counters.
Updates their states based on elapsed time or counts during each scan cycle.
Communication Interface
Handles external communication (e.g., Modbus RTU/TCP).
Maps internal registers to external devices for data exchange.
System Oversight
Manages STOP/RUN control, error handling, and system diagnostics.
Ensures safe operation and monitors for faults.
Execution Cycle
The interpreter operates in a continuous loop:
1. Input Scan → 2. Logic Evaluation → 3. Output Update → 4. Timer/Counter Management → Repeat
This cyclic execution ensures deterministic behavior in real-time control systems.
Ladder Logic Program Format on SD Card
The ladder logic program must be stored in a structured format that is easy to parse and process by the interpreter. A common approach is to use a binary or text-based intermediate representation of the ladder diagram.
Example Format: Text-Based Representation
A text-based format is human-readable and easy to debug. Here's an example:
"Timers" and "Counters": Total number of timers/counters used.
Rung Definitions:
Each rung specifies:
"Type": Logical operation (e.g., AND, OR) or special instruction (e.g., TIMER, COUNTER).
"Inputs": List of input references (physical inputs like I0 or internal states like T0).
"Output": Output reference (physical output like O0 or internal register like N2).
Timers/Counter Blocks:
Stores runtime information for timers (CurrentValue, PresetValue) and counters.
Registers:
Holds numerical values for math operations or other advanced functions.
Example Format: Binary Representation
For faster parsing during execution, a binary format can be used. Each rung is encoded as a fixed-size structure:
Field Name
Size
Description
Rung Type
1 byte
Type of operation (e.g., AND = 0x01).
Input Count
1 byte
Number of input references.
Output Count
1 byte
Number of output references.
Inputs
N bytes
List of input references (variable size).
Outputs
N bytes
List of output references (variable size).
Timer/Counter ID
1 byte
ID for TIMER or COUNTER rungs (if applicable).
Preset Value
4 bytes
Preset value for TIMER/COUNTER rungs.
How It Works in Execution
The interpreter reads the program file from the SD card during initialization.
It parses the rungs into an internal data structure stored in hub RAM or PSRAM.
During each scan cycle:
The interpreter evaluates each rung using its type and associated inputs/outputs.
Timers and counters are updated based on elapsed time or input conditions.
Outputs are updated based on the evaluated results.
Summary
The ladder logic interpreter processes inputs → evaluates rungs → updates outputs in a cyclic manner.
The program can be stored on an SD card in either a text-based or binary format.
A text-based format is easier to debug but slower to parse; binary formats are faster but less human-readable.
This architecture allows flexible scaling with the P2's memory and multicore capabilities while maintaining compatibility with standard ladder logic structures like rungs, timers, counters, and PIDs.
and here is a first stab at what it might look like in Spin2
Here’s an example of how a basic ladder logic interpreter could be implemented in Spin2 for the Parallax Propeller 2 (P2). This implementation will focus on processing a simple ladder logic program stored in a text-based format on an SD card. The program will include rungs, timers, counters, and outputs.
Basic Architecture in Spin2
The interpreter will:
1. Load the ladder logic program from the SD card.
2. Parse the program into an internal data structure.
3. Execute the program cyclically:
- Scan inputs.
- Process rungs.
- Update outputs.
- Manage timers and counters.
Spin2 Code
Here’s an example implementation:
```spin
CON
_clkfreq = 160_000_000 ' System clock frequency
OBJ
sd : "SmartSerialSD" ' SD card driver for file access
io : "SmartPins" ' For managing I/O pins
VAR
byte inputImage[64] ' Input image table (up to 64 inputs)
byte outputImage[64] ' Output image table (up to 64 outputs)
long timerValues[16] ' Timer current values (16 timers max)
long timerPresets[16] ' Timer preset values
long counterValues[16] ' Counter current values (16 counters max)
long counterPresets[16] ' Counter preset values
DAT
programBuffer byte 512 ' Buffer to store the ladder logic program from SD card
PUB main()
initSystem() ' Initialize system components
loadProgram() ' Load ladder logic program from SD card
repeat ' Main execution loop
scanInputs() ' Step 1: Scan inputs
processRungs() ' Step 2: Process ladder logic rungs
updateOutputs() ' Step 3: Update outputs
manageTimers() ' Step 4: Manage timers and counters
' Initialize system components
PUB initSystem()
sd.start(0) ' Start SD card driver on pin group A
io.start() ' Start I/O management
' Load ladder logic program from SD card into memory
PUB loadProgram()
sd.mount() ' Mount the SD card
if sd.openFile("ladder.txt", "r")
sd.read(@programBuffer, 512) ' Read the ladder logic program into buffer
sd.closeFile()
parseProgram(@programBuffer) ' Parse the program into internal structures
' Parse the ladder logic program into memory structures
PUB parseProgram(bufferAddr)
'' Example parsing logic for text-based format:
'' [RUNG_1]
'' Type=AND Inputs=I0,I1 Output=O0
'' Type=TIMER TimerID=T0 Preset=5000 Input=I4 Output=O2
repeat while byte[bufferAddr] <> $00 ' Loop until end of buffer
if strcomp(@bufferAddr, "RUNG_") ' Detect rung definition
parseRung(bufferAddr) ' Parse individual rung details
' Scan inputs and update input image table
PUB scanInputs()
repeat i from 0 to 63 ' Scan up to 64 inputs
inputImage[i] := io.readPin(i) ' Read each input pin state
' Process each rung in the ladder logic program
PUB processRungs()
'' This is a simplified example of rung processing.
'' Each rung type would have its own handler.
repeat i from 0 to numRungs - 1 ' Iterate through all rungs
case rungType[i]
AND: processAndRung(i)
OR: processOrRung(i)
TIMER: processTimerRung(i)
COUNTER: processCounterRung(i)
' Example: Process an AND rung type
PRI processAndRung(rungIndex)
'' Evaluate AND condition for inputs and set output state.
input1 := getInput(rungInputs[rungIndex][0]) ' Get first input state
input2 := getInput(rungInputs[rungIndex][1]) ' Get second input state
if input1 AND input2 ' Logical AND operation
setOutput(rungOutputs[rungIndex], true) ' Set output to true if both inputs are true
Execution is done by, first, running an I/O scan to write the real outputs from the logical outputs and fill logical inputs from real inputs, then, second, process the ladder using the logical I/O map. Then back round to updating the logical<->physical I/O.
So each pass of executing the ladder is done using a freeze frame of the I/O.
@evanh said:
So each pass of executing the ladder is done using a freeze frame of the I/O.
yep, in fewer words.
scanInputs() ' Step 1: Scan inputs
processRungs() ' Step 2: Process ladder logic rungs
updateOutputs() ' Step 3: Update outputs
that is how it is done, from what I've seen, in digital PLC world. and it may be a requirement for predictable logical reasoning to process between these freeze frames of In and Out. Having started in relay logic on high power LORAN transmitters from the '50s with physical time-delay relays orchestrating the bring-up process (music to my ears), when I first started working with digital PLC ladder logic I stumbled a bit on that abstraction. I wouldn't say that abstraction be tossed out, but I do consider what might be done with extra cogs available for DSP interpretation of live analog feeds.
@evanh said:
No PLC replacement here but I've used a Prop1 as a Modbus slave, driving an array of stepper motors inside a larger rotary head via four slip-rings.
@RossH OK... I've been working with OpenPLC on a different job and using different Program Organization Units (POU) in different languages all together, some aspects of the project make more sense in Sequential Function Chart and some in Ladder. I am liking OpenPLC because of the XML data has a chance of being reprocessed into something useful for a different process. I looked closer at your suggestion of LDmicro, and the fact that that has an text mode interface and remarkably little bound up in Windows stuff has piqued my interest to port something like that, and maybe add other graphical languages (even in text mode) built in... has me scurrying to finish my other job so I can dig deeper into a P2 PLC that maybe does fit in the standard "open" PLC world.
it seems doable to create a graphical IDE that creates an intermediate description of the process, and then to make a runtime that processes it (ok, the runtime is probably a challenge to make from scratch). but, on the C side, there may be more clues in the LDmicro source... https://github.com/LDmicro/LDmicro if one was inclined to port to Spin2/PASM.
or, wrap that C compile/run process of the LDmicro code in Catalina or FlexC .. the point is. there are options, and there seems to be a burgeoning market for more "open" or, at least, affordable PLC industrial control stuff.
just tumbling around some ideas in my head. The flexibility of the P2 Edge IO is a bit of a challenge when attempting to fit with equally flexible hardware.
I used to make PCBs for tiny MSP430 with the pads on the four free pins for either digital I/O, or a switching transistor, or voltage divider for analog in... then just populate each little board for purpose when I coded for a tiny application. I haven't fully figured out if there could be pods of 4 or 6 pins (of each of the 2x6 expansion headers) with a couple pins available to enable/disable certain interfaces for the external pins/ports - that maybe just digital/analog switching, or a variety of comm ports. Potentially (in this picture) the bottom remain analog/digital capable, but setup maybe 4 uart/modbus on the top pins. Perhaps there is an internal P1 on the baseboard that twiddles/configures/monitors the pins/ports of the external facing P2. Actually, I am strongly considering a sort of chassis configuring/monitoring processor with, potentially, VGA/keyboard/mouse connections to behave as a console terminal for the "PLC" P2, that could load/update the operational PLC firmware. There could remain a standard PropPlug compatible external interface to program the actual PLC P2, and the monitor console Propeller could be an option. and... while I mentioned a P1 for the console and chassis monitor, it is really shy the number of pins to monitor/configure all of the PLC pins. come to think of it, the chassis monitor and console Propeller could be a P2 and an easy option to add on just one of these units that may be ganged up to others that don't have the extra monitor.... errr, I agree, it gets a little meta quickly, and anyway, just getting some thoughts out in the daylight...
actually, probably the way to work out some of the flexiness, is to make a narrow expansion module that fits on the 2x6 headers that can have multiple features/functions configurable on the fly from software on a couple of the pins. a module like that would fit into the existing P2 edge ecosystem and be useful everywhere else.
yeah... I should think on that a bit. keep the scope reasonable and affordable and, perhaps, generally beneficial to have that board with associated OBEX code.
I stick with the "breaker" format DIN rail enclosures, because they fit perfectly in weathertight boxes like these that make tidy projects and good option for displays behind the clear weather sealed door. the "knock-outs" all around (actually, drill out) make it easy to put a weathertight compression gland to seal around wires/conduit in and out.
Hi,
since I am pondering over graphical programming for a while, I have been following this thread with great interest. Perhaps some comments:
I think the idea, that in a graphical programming system the lines between modules are "data" is the only one, that will make sense. This is good about PLC ladder logic.
I think, that for more complicated things, a text representation is much faster to write and compact to look at. This is the reason, that graphical programming is not used for complicated systems. This leads me to the conclusion that a more useful graphical system must be able to include user defined modules, which are described in text form! Use graphics to describe the overview but be free to program details in text format. LtSpice for example has this powerful mixture as the component models are in text format.
In all systems, where computer graphics is used, like CAD or maps, the concept of zooming is of significant importance. In a good map, less important details vanish if you zoom out and some others become represented by symbols. Even for example the symbol of a bolt becomes simpler if you zoom out. So some concept of importance is needed and also some concept of varying symbols. Symbols make it possible, that you can cram maximum of information onto a map and still do not overfill the picture.
I do like Puredata. In this system the graphics is the same for programming and user interface. This makes a lot of sense, if the programmer is the user. So programming - debugging - using is all the same.
At some point you mentioned, that you would like to have a self hosted system in the end. Sorry to say so, but in this case you might want to reconsider Forth as basis. The reason is that it is a very nice compromise between fast, compact and powerful and it is already there with lots of possibilities. I think most of the runtime is there! As a matter of fact, it is so far the only self hosted environment, that anybody really uses for projects. (At least as far as I know.) If Forth would be the basis, it is also thinkable, that for smaller systems P1 might be used as runtime system, which is in my experience not possible for compiled C because of lack of RAM. The possibility to scale down to P1 would be attractive for cost reasons.
@"Christof Eb." said:
Hi,
since I am pondering over graphical programming for a while, I have been following this thread with great interest. Perhaps some comments:
I, too, for many years considered pros/cons of graphical vs textual languages, drawing many of the same conclusions. Thank you for chiming in here. The issue seems far from solved.
I think the idea, that in a graphical programming system the lines between modules are "data" is the only one, that will make sense. This is good about PLC ladder logic.
I've found many necessary concepts are a difficult fit into Ladder beyond Logic and mapping to physical buttons and relays IRL... sequences, math, string handling come to mind as an odd fit that take specific self contained modules of particular vendors to manage them in any sane way.
I think, that for more complicated things, a text representation is much faster to write and compact to look at. This is the reason, that graphical programming is not used for complicated systems. This leads me to the conclusion that a more useful graphical system must be able to include user defined modules, which are described in text form! Use graphics to describe the overview but be free to program details in text format. LtSpice for example has this powerful mixture as the component models are in text format.
I agree that text is many times faster to write, particularly for find/replace sorts of operations. But the 5 (three graphical, two textual) "standard" compliant languages for industry can be mixed/matched with the, also standard, Program Organization Units (POU). Each aspect of the total problem can be bundled in the language that makes most sense. Sometimes Functional Block assemblies make more sense, with some of those blocks being, themselves, Sequences or Structured Text. OpenPLC allows a non-standard insertion of plain old Arduino/C++ code into POU. Some vendors are putting in non-standard Flow coding (like Node-Red). In the end, a critical aspect of these industrial controls is that the code (if you can even find/access it 20 years later, or have the software IDE to render it - another reason for embedding the IDE) must be easy to grok for the maintenance coders who need to adapt to changing physical systems in a facility. When dealing with customers, being able to convey and confirm with them how the system IS actually coded/functioning, is aided by the correct mental abstraction of sometimes different languages. Another reason to like OpenPLC is that, like LTSpice, the intermediate stored model/code is in XML, which makes it possible to apply XSLT, or similar, to present different views of the actual situation even beyond code.
In all systems, where computer graphics is used, like CAD or maps, the concept of zooming is of significant importance. In a good map, less important details vanish if you zoom out and some others become represented by symbols. Even for example the symbol of a bolt becomes simpler if you zoom out. So some concept of importance is needed and also some concept of varying symbols. Symbols make it possible, that you can cram maximum of information onto a map and still do not overfill the picture.
Very good points, and ones that I don't often find in these IDEs.
I do like Puredata. In this system the graphics is the same for programming and user interface. This makes a lot of sense, if the programmer is the user. So programming - debugging - using is all the same.
At some point you mentioned, that you would like to have a self hosted system in the end. Sorry to say so, but in this case you might want to reconsider Forth as basis. The reason is that it is a very nice compromise between fast, compact and powerful and it is already there with lots of possibilities. I think most of the runtime is there! As a matter of fact, it is so far the only self hosted environment, that anybody really uses for projects. (At least as far as I know.) If Forth would be the basis, it is also thinkable, that for smaller systems P1 might be used as runtime system, which is in my experience not possible for compiled C because of lack of RAM. The possibility to scale down to P1 would be attractive for cost reasons.
I'm not entirely sold on (actually, not even a little bit) on the idea that the environment for coding be coded in the same language that is being developed in the environment. Case in point: the multiple languages - some graphical, some textual - have evolved because different abstractions make sense in different places... and NONE of those abstractions for us humans are actually the thing that gets executed on the device.
As much as I like the idea of one perfect "language" environment to express easily and clearly ALL necessary concepts, and will continue to look for/attempt to make them, I'm not certain that the situation in the industrial control languages hasn't already evolved and blended into a pretty reasonable situation given the backward compatible baggage situation.
As for running the IDE aspects on a P1. sure seems like it should be possible given that all manner of compilers and visual programming languages were around on lesser hardware than a P1 back into the 80s - think the visual SmallTalk environments. in fact, I just read, though not graphical, a fantastic system built on a P1 in 2007 that did as much or more of "Task" management using Spin1 than is just getting baked into Spin2. https://www.emlia.org/portfolio/navcom_ai/nav_files.html and this pdf report in particular https://www.emlia.org/portfolio/navcom_ai/NAVCOM_AI_Report.pdf are pretty interesting on the amount of self adjusting complexity can be handled on a P1 as used for a self navigating autonomous boat/vehicle.
@"Christof Eb." errr. OK.. I'll give it another think. as I recall that the visual Smalltalk environment I'm thinking about was, itself, developed in Smalltalk. Then I re-realize and re-respect the particular meta level recursive nature of Forth and Lisp (also available, thanks to @ersmith ) and MOST IMPORTANTLY those post-fix and pre-fix languages are supremely suited for making Domain Specific Languages (DSL). Now, I'll grant you that, were an INDUSTRIAL CONTROL DSL made in exactly the standard terms of industrial control (instead of bespoke embedded systems) AND that DSL were exposed through to the user in a GRAPHICAL/TEXTUAL environment... then it might be worth more exploration and to be run on a P1 (if SDcard I/O is fast enough for a good experience shuffling through large datafiles in segments as the systems of old used to do).
Though, I do like the jazzy fonts/graphics stuff that is developing on the P2 edge; and think it is a fine idea to, perhaps, have the complete gee-whiz Parallax Propeller IDE be loadable onto a P2 Edge to be plugged into a slot as an option for the PLC stuff. HA! Better yet... maybe make a P2 Edge expansion card that jacks down over the 48-63 pins (two 2x6 expansion headers) to provide, not only the external programming/console to the primary P2 Edge, but also HDMI and two USB connections to the IDE on the expansion card equiped with an additional P2 Edge that carries the IDE.
@refaQtor said:
I looked closer at your suggestion of LDmicro, and the fact that that has an text mode interface and remarkably little bound up in Windows stuff has piqued my interest to port something like that
The stuff I ported turns out to be an earlier version of what is now a significant chunk of LDmicro. I started to look at porting the whole of LDmicro and this would be possible, if a little tedious.
As you say, most of the interface, including the actual ladder logic diagrams are simple ASCII text based, so that part should be easy to port - all it really needs is a to replace the GUI portions of the UI with something simpler.
A lot of LDmicro simply wouldn't be needed in a Propeller self-hosted version, and for the parts that are needed I'd recommend spreading them across several utility programs rather than bundling it all into one monolithic program like LDmicro does. For instance, the simulator should be split off and run separately.
I'm in the middle of preparing a new Catalina release (I found a bug that needs fixing). I'll have another look at LDmicro after that.
I suppose, if I were serious, I'd jump to something like this. Was just thinking there would be some overlap for others to use some of the industrial protected I/O and interface expansion boards outside of this situation. and smaller individual expansion boards seem more economical to develop and flexible to deploy.
@"Christof Eb." said:
At some point you mentioned, that you would like to have a self hosted system in the end. Sorry to say so, but in this case you might want to reconsider Forth as basis. The reason is that it is a very nice compromise between fast, compact and powerful and it is already there with lots of possibilities. I think most of the runtime is there! As a matter of fact, it is so far the only self hosted environment, that anybody really uses for projects. (At least as far as I know.)
True for the P1, but not for the P2. I agree the self-hosted version of the Catalina C compiler is not really all an attractive option for arbitrary C development - it's too slow when compiling large C programs. But it would be quite adequate for the size and type of C programs typically generated from Ladder Logic, especially since they won't use large chunks of the standard C libraries like stdio (which for various reasons is the real killer for the self-hosted version of Catalina C) and also because those programs can use the QUICKBUILD option, since the target file to be used by all the generated C programs will only need to be assembled once and can then be re-used for all PLC programs.
Also, remember that Catalina offers not just self-hosted C development, but also self-hosted Lua and PASM development, and for these it is already quite practical. I actually only ever write my Lua programs on the Propeller, because it is quicker and easier to do that than write them on the PC and keep transferring them over to test them. Similarly when testing new Catalina plugins - I test, modify and re-assemble them using P2ASM on the Propeller.
In fact, apart from the actual process of generating and compiling the C code generated from the Ladder Logic (which we already know Catalina can do), it might be quicker and easier to write the UI around the Ladder Logic editor in Lua - this kind of thing is what Lua excels at. And I reckon someone somewhere will already have written a suitable text-based UI toolset in Lua that we could use.
For me, that would actually make this a more interesting project, since it would have wider application than implementing a PLC.
@RossH said:
In fact, apart from the actual process of generating and compiling the C code generated from the Ladder Logic (which we already know Catalina can do), it might be quicker and easier to write the UI around the Ladder Logic editor in Lua - this kind of thing is what Lua excels at. And I reckon someone somewhere will already have written a suitable text-based UI toolset in Lua that we could use.
For me, that would actually make this a more interesting project, since it would have wider application than implementing a PLC.
hosted Lua development, accessible to user on the Propeller, is intersting to me. though, still sorting through options ... sooo many options, and not all compatible with eachother or with the future. so, still sorting this stuff out.
Yes, it can. But it requires a fair slab of XMM RAM and is quite slow - probably too slow to be much use for anything except trivial Lua programs. I compile Lua for the P1 mainly just to demonstrate what Catalina can do.
But on the P2 Lua is much more useful. And much faster, since it can run entirely out of Hub RAM. Parts of the self-hosted version of Catalina are implemented in Lua. As are parts of Catalyst. I'd rewrite the whole of Catalyst in Lua except that then it wouldn't be able to run on P1s without XMM RAM (at the moment it can run on any Propeller - P1 or P2, with or without XMM RAM).
Also, I've found (as I thought I would) a text-based UI package for Lua that I think I can use on the P2.
Comments
No worries. PLCs are not really my thing, I'm just interested in any applications that could take advantage of Catalina's unique set of features, and a PLC implementation would be a good demo.
Someone may be interested porting LDmicro (a graphical ladder logic editor that generates ".ld" files that OpenPLC can then convert to C) to the P2, so I'll include the bit I've already done as a demo in the next Catalina release.
sweet. I get it. I think I'll leave Catalina on an old P1 (maybe P2, if I want to compile) hooked to VGA/kbd, make use it like a console into other things. I'll get more use to it and find more uses for it.
I have a P1 PLC, This is it. For now I just use IDEC FC6A, not too pricey, Software is good both upload and download, simulator mode too, for checking your ladder functions. I've used accroloop before now parker automation. They had a ladder program that was just "C" in the background. So I would open their ladder program with windows notepad and just "C" code it.
An IDE for propeller that could up load the eprom and display it back in spin would be genius. Anybody out there up for the challenge.
Is there a list of expected relay-logic functions and operations that a compiler ought to handle?
It's just AND, OR and NOT on the input side.
The "coil" output can be many devices though. From direct ON/OFF to SET/RESET to multiple rung devices to memory writes/copies to magic function calls. Can be expanded as development progresses.
EDIT: Added NOT.
as relays are the basic implementation of binary logic... all of those basics are expected, and to provide utility in the PLC world where there are data registers to act upon, there are math functions. it is useful to have them itemized, so I ask Perplexity to do that for us:
A PLC compiler should handle a wide range of relay-logic functions and operations to emulate traditional relay-based control systems while leveraging the flexibility and power of digital logic. Below is a list of expected functions and operations:
Basic Logic Operations
Sequential and Memory Functions
Timers and Counters
Arithmetic and Data Handling
Advanced Control Functions
Input/Output Handling
Diagnostics and Monitoring
Specialized Logic
These functions allow PLCs to replicate traditional relay logic while offering enhanced flexibility and scalability. This comprehensive functionality is essential for automating machinery and processes effectively in industrial applications[1][2][3].
Citations:
[1] https://www.spiceworks.com/tech/tech-general/articles/ladder-logic-vs-relay-logic/
[2] https://control.com/textbook/relay-control-systems/relay-circuits/
[3] https://forum.digikey.com/t/relay-logic-for-industrial-control-panels-part-1/39441
[4] https://control.com/textbook/programmable-logic-controllers/ladder-diagram-ld-programming/
[5] https://circuitdigest.com/tutorial/introduction-to-relay-logic-control-symbols-working-and-examples
[6] https://en.wikipedia.org/wiki/Relay_logic
[7] https://www.controleng.com/articles/relay-ladder-logic/
[8] https://ladderlogicworld.com/relay-logic-vs-ladder-logic/
[9] https://www.motioncontroltips.com/choosing-between-or-combining-relays-and-plcs/
[10] https://www.allaboutcircuits.com/textbook/digital/chpt-6/programmable-logic-controllers-plc/
This screenshot from the OpenPLC IDE shows an aspect that seems like a constant arms-race - keeping up with constant new sensor/protocol products that come out with Arduino code by default.
Though there is an aspect to this PLC IDE does have a nice sort of object assembly interface that might play well as a category in OBEX. (which, I might add, has really been coming into its own with constant relevant fresh activity
bonus points for these typical desires in PLC land: (extracted from OpenPLC IDE)
and here is an outline of how a basic PLC ladder logic interpreter might work
Basic Architecture of a Ladder Logic Interpreter
A ladder logic interpreter processes ladder diagrams by scanning inputs, evaluating rungs, updating outputs, and managing timers/counters in a cyclic manner. Here's the architecture broken into functional blocks:
1. Core Components of the Interpreter
Input Scan
Logic Evaluation
Output Update
Timer/Counter Management
Communication Interface
System Oversight
Execution Cycle
The interpreter operates in a continuous loop:
1. Input Scan → 2. Logic Evaluation → 3. Output Update → 4. Timer/Counter Management → Repeat
This cyclic execution ensures deterministic behavior in real-time control systems.
Ladder Logic Program Format on SD Card
The ladder logic program must be stored in a structured format that is easy to parse and process by the interpreter. A common approach is to use a binary or text-based intermediate representation of the ladder diagram.
Example Format: Text-Based Representation
A text-based format is human-readable and easy to debug. Here's an example:
Explanation of Format
Program Metadata:
"Name"
: Program name for identification."Rungs"
: Total number of rungs."Timers"
and"Counters"
: Total number of timers/counters used.Rung Definitions:
Each rung specifies:
"Type"
: Logical operation (e.g., AND, OR) or special instruction (e.g., TIMER, COUNTER)."Inputs"
: List of input references (physical inputs likeI0
or internal states likeT0
)."Output"
: Output reference (physical output likeO0
or internal register likeN2
).Timers/Counter Blocks:
CurrentValue
,PresetValue
) and counters.Registers:
Example Format: Binary Representation
For faster parsing during execution, a binary format can be used. Each rung is encoded as a fixed-size structure:
How It Works in Execution
Summary
and here is a first stab at what it might look like in Spin2
Here’s an example of how a basic ladder logic interpreter could be implemented in Spin2 for the Parallax Propeller 2 (P2). This implementation will focus on processing a simple ladder logic program stored in a text-based format on an SD card. The program will include rungs, timers, counters, and outputs.
Basic Architecture in Spin2
The interpreter will:
1. Load the ladder logic program from the SD card.
2. Parse the program into an internal data structure.
3. Execute the program cyclically:
- Scan inputs.
- Process rungs.
- Update outputs.
- Manage timers and counters.
Spin2 Code
Here’s an example implementation:
```spin
CON
_clkfreq = 160_000_000 ' System clock frequency
OBJ
sd : "SmartSerialSD" ' SD card driver for file access
io : "SmartPins" ' For managing I/O pins
VAR
byte inputImage[64] ' Input image table (up to 64 inputs)
byte outputImage[64] ' Output image table (up to 64 outputs)
long timerValues[16] ' Timer current values (16 timers max)
long timerPresets[16] ' Timer preset values
long counterValues[16] ' Counter current values (16 counters max)
long counterPresets[16] ' Counter preset values
DAT
programBuffer byte 512 ' Buffer to store the ladder logic program from SD card
PUB main()
initSystem() ' Initialize system components
loadProgram() ' Load ladder logic program from SD card
repeat ' Main execution loop
scanInputs() ' Step 1: Scan inputs
processRungs() ' Step 2: Process ladder logic rungs
updateOutputs() ' Step 3: Update outputs
manageTimers() ' Step 4: Manage timers and counters
' Initialize system components
PUB initSystem()
sd.start(0) ' Start SD card driver on pin group A
io.start() ' Start I/O management
' Load ladder logic program from SD card into memory
PUB loadProgram()
sd.mount() ' Mount the SD card
if sd.openFile("ladder.txt", "r")
sd.read(@programBuffer, 512) ' Read the ladder logic program into buffer
sd.closeFile()
parseProgram(@programBuffer) ' Parse the program into internal structures
' Parse the ladder logic program into memory structures
PUB parseProgram(bufferAddr)
'' Example parsing logic for text-based format:
'' [RUNG_1]
'' Type=AND Inputs=I0,I1 Output=O0
'' Type=TIMER TimerID=T0 Preset=5000 Input=I4 Output=O2
repeat while byte[bufferAddr] <> $00 ' Loop until end of buffer
if strcomp(@bufferAddr, "RUNG_") ' Detect rung definition
parseRung(bufferAddr) ' Parse individual rung details
' Scan inputs and update input image table
PUB scanInputs()
repeat i from 0 to 63 ' Scan up to 64 inputs
inputImage[i] := io.readPin(i) ' Read each input pin state
' Process each rung in the ladder logic program
PUB processRungs()
'' This is a simplified example of rung processing.
'' Each rung type would have its own handler.
repeat i from 0 to numRungs - 1 ' Iterate through all rungs
case rungType[i]
AND: processAndRung(i)
OR: processOrRung(i)
TIMER: processTimerRung(i)
COUNTER: processCounterRung(i)
' Example: Process an AND rung type
PRI processAndRung(rungIndex)
'' Evaluate AND condition for inputs and set output state.
input1 := getInput(rungInputs[rungIndex][0]) ' Get first input state
input2 := getInput(rungInputs[rungIndex][1]) ' Get second input state
if input1 AND input2 ' Logical AND operation
setOutput(rungOutputs[rungIndex], true) ' Set output to true if both inputs are true
else setOutput(rungOutputs[runningindex,false)
Execution is done by, first, running an I/O scan to write the real outputs from the logical outputs and fill logical inputs from real inputs, then, second, process the ladder using the logical I/O map. Then back round to updating the logical<->physical I/O.
So each pass of executing the ladder is done using a freeze frame of the I/O.
yep, in fewer words.
that is how it is done, from what I've seen, in digital PLC world. and it may be a requirement for predictable logical reasoning to process between these freeze frames of In and Out. Having started in relay logic on high power LORAN transmitters from the '50s with physical time-delay relays orchestrating the bring-up process (music to my ears), when I first started working with digital PLC ladder logic I stumbled a bit on that abstraction. I wouldn't say that abstraction be tossed out, but I do consider what might be done with extra cogs available for DSP interpretation of live analog feeds.
Okay. Lots to chew on here.
Thanks for gathering all this info.
Sounds like the only things that would require background processing are the delay timers.
I used slip-rings only for power
Motion commands via WiFi
Craig
a thing of beauty!
@RossH OK... I've been working with OpenPLC on a different job and using different Program Organization Units (POU) in different languages all together, some aspects of the project make more sense in Sequential Function Chart and some in Ladder. I am liking OpenPLC because of the XML data has a chance of being reprocessed into something useful for a different process. I looked closer at your suggestion of LDmicro, and the fact that that has an text mode interface and remarkably little bound up in Windows stuff has piqued my interest to port something like that, and maybe add other graphical languages (even in text mode) built in... has me scurrying to finish my other job so I can dig deeper into a P2 PLC that maybe does fit in the standard "open" PLC world.
it seems doable to create a graphical IDE that creates an intermediate description of the process, and then to make a runtime that processes it (ok, the runtime is probably a challenge to make from scratch). but, on the C side, there may be more clues in the LDmicro source... https://github.com/LDmicro/LDmicro if one was inclined to port to Spin2/PASM.
or, wrap that C compile/run process of the LDmicro code in Catalina or FlexC .. the point is. there are options, and there seems to be a burgeoning market for more "open" or, at least, affordable PLC industrial control stuff.
This is an interesting discussion of make robust I/O and power for industrial use: https://www.rugged-circuits.com/10-ways-to-destroy-an-arduino
One of those, probably Instruction List, is just a textural form of Ladder.
just tumbling around some ideas in my head. The flexibility of the P2 Edge IO is a bit of a challenge when attempting to fit with equally flexible hardware.
I used to make PCBs for tiny MSP430 with the pads on the four free pins for either digital I/O, or a switching transistor, or voltage divider for analog in... then just populate each little board for purpose when I coded for a tiny application. I haven't fully figured out if there could be pods of 4 or 6 pins (of each of the 2x6 expansion headers) with a couple pins available to enable/disable certain interfaces for the external pins/ports - that maybe just digital/analog switching, or a variety of comm ports. Potentially (in this picture) the bottom remain analog/digital capable, but setup maybe 4 uart/modbus on the top pins. Perhaps there is an internal P1 on the baseboard that twiddles/configures/monitors the pins/ports of the external facing P2. Actually, I am strongly considering a sort of chassis configuring/monitoring processor with, potentially, VGA/keyboard/mouse connections to behave as a console terminal for the "PLC" P2, that could load/update the operational PLC firmware. There could remain a standard PropPlug compatible external interface to program the actual PLC P2, and the monitor console Propeller could be an option. and... while I mentioned a P1 for the console and chassis monitor, it is really shy the number of pins to monitor/configure all of the PLC pins. come to think of it, the chassis monitor and console Propeller could be a P2 and an easy option to add on just one of these units that may be ganged up to others that don't have the extra monitor.... errr, I agree, it gets a little meta quickly, and anyway, just getting some thoughts out in the daylight...
actually, probably the way to work out some of the flexiness, is to make a narrow expansion module that fits on the 2x6 headers that can have multiple features/functions configurable on the fly from software on a couple of the pins. a module like that would fit into the existing P2 edge ecosystem and be useful everywhere else.
yeah... I should think on that a bit. keep the scope reasonable and affordable and, perhaps, generally beneficial to have that board with associated OBEX code.
I stick with the "breaker" format DIN rail enclosures, because they fit perfectly in weathertight boxes like these that make tidy projects and good option for displays behind the clear weather sealed door. the "knock-outs" all around (actually, drill out) make it easy to put a weathertight compression gland to seal around wires/conduit in and out.
Hi,
since I am pondering over graphical programming for a while, I have been following this thread with great interest. Perhaps some comments:
I think the idea, that in a graphical programming system the lines between modules are "data" is the only one, that will make sense. This is good about PLC ladder logic.
I think, that for more complicated things, a text representation is much faster to write and compact to look at. This is the reason, that graphical programming is not used for complicated systems. This leads me to the conclusion that a more useful graphical system must be able to include user defined modules, which are described in text form! Use graphics to describe the overview but be free to program details in text format. LtSpice for example has this powerful mixture as the component models are in text format.
In all systems, where computer graphics is used, like CAD or maps, the concept of zooming is of significant importance. In a good map, less important details vanish if you zoom out and some others become represented by symbols. Even for example the symbol of a bolt becomes simpler if you zoom out. So some concept of importance is needed and also some concept of varying symbols. Symbols make it possible, that you can cram maximum of information onto a map and still do not overfill the picture.
I do like Puredata. In this system the graphics is the same for programming and user interface. This makes a lot of sense, if the programmer is the user. So programming - debugging - using is all the same.
At some point you mentioned, that you would like to have a self hosted system in the end. Sorry to say so, but in this case you might want to reconsider Forth as basis. The reason is that it is a very nice compromise between fast, compact and powerful and it is already there with lots of possibilities. I think most of the runtime is there! As a matter of fact, it is so far the only self hosted environment, that anybody really uses for projects. (At least as far as I know.) If Forth would be the basis, it is also thinkable, that for smaller systems P1 might be used as runtime system, which is in my experience not possible for compiled C because of lack of RAM. The possibility to scale down to P1 would be attractive for cost reasons.
Christof
I, too, for many years considered pros/cons of graphical vs textual languages, drawing many of the same conclusions. Thank you for chiming in here. The issue seems far from solved.
I've found many necessary concepts are a difficult fit into Ladder beyond Logic and mapping to physical buttons and relays IRL... sequences, math, string handling come to mind as an odd fit that take specific self contained modules of particular vendors to manage them in any sane way.
I agree that text is many times faster to write, particularly for find/replace sorts of operations. But the 5 (three graphical, two textual) "standard" compliant languages for industry can be mixed/matched with the, also standard, Program Organization Units (POU). Each aspect of the total problem can be bundled in the language that makes most sense. Sometimes Functional Block assemblies make more sense, with some of those blocks being, themselves, Sequences or Structured Text. OpenPLC allows a non-standard insertion of plain old Arduino/C++ code into POU. Some vendors are putting in non-standard Flow coding (like Node-Red). In the end, a critical aspect of these industrial controls is that the code (if you can even find/access it 20 years later, or have the software IDE to render it - another reason for embedding the IDE) must be easy to grok for the maintenance coders who need to adapt to changing physical systems in a facility. When dealing with customers, being able to convey and confirm with them how the system IS actually coded/functioning, is aided by the correct mental abstraction of sometimes different languages. Another reason to like OpenPLC is that, like LTSpice, the intermediate stored model/code is in XML, which makes it possible to apply XSLT, or similar, to present different views of the actual situation even beyond code.
Very good points, and ones that I don't often find in these IDEs.
I'm not entirely sold on (actually, not even a little bit) on the idea that the environment for coding be coded in the same language that is being developed in the environment. Case in point: the multiple languages - some graphical, some textual - have evolved because different abstractions make sense in different places... and NONE of those abstractions for us humans are actually the thing that gets executed on the device.
As much as I like the idea of one perfect "language" environment to express easily and clearly ALL necessary concepts, and will continue to look for/attempt to make them, I'm not certain that the situation in the industrial control languages hasn't already evolved and blended into a pretty reasonable situation given the backward compatible baggage situation.
As for running the IDE aspects on a P1. sure seems like it should be possible given that all manner of compilers and visual programming languages were around on lesser hardware than a P1 back into the 80s - think the visual SmallTalk environments. in fact, I just read, though not graphical, a fantastic system built on a P1 in 2007 that did as much or more of "Task" management using Spin1 than is just getting baked into Spin2. https://www.emlia.org/portfolio/navcom_ai/nav_files.html and this pdf report in particular https://www.emlia.org/portfolio/navcom_ai/NAVCOM_AI_Report.pdf are pretty interesting on the amount of self adjusting complexity can be handled on a P1 as used for a self navigating autonomous boat/vehicle.
@"Christof Eb." errr. OK.. I'll give it another think. as I recall that the visual Smalltalk environment I'm thinking about was, itself, developed in Smalltalk. Then I re-realize and re-respect the particular meta level recursive nature of Forth and Lisp (also available, thanks to @ersmith ) and MOST IMPORTANTLY those post-fix and pre-fix languages are supremely suited for making Domain Specific Languages (DSL). Now, I'll grant you that, were an INDUSTRIAL CONTROL DSL made in exactly the standard terms of industrial control (instead of bespoke embedded systems) AND that DSL were exposed through to the user in a GRAPHICAL/TEXTUAL environment... then it might be worth more exploration and to be run on a P1 (if SDcard I/O is fast enough for a good experience shuffling through large datafiles in segments as the systems of old used to do).
Though, I do like the jazzy fonts/graphics stuff that is developing on the P2 edge; and think it is a fine idea to, perhaps, have the complete gee-whiz Parallax Propeller IDE be loadable onto a P2 Edge to be plugged into a slot as an option for the PLC stuff. HA! Better yet... maybe make a P2 Edge expansion card that jacks down over the 48-63 pins (two 2x6 expansion headers) to provide, not only the external programming/console to the primary P2 Edge, but also HDMI and two USB connections to the IDE on the expansion card equiped with an additional P2 Edge that carries the IDE.
a bit more trying things on for size. same expansion board (light or dark blue in pictures), in one position, OR the other. could have a P1 on it.
the yellow/green/red ckt board position (and terminals) are in the picture just for orientation and alignment. would not be in place for our scenario
The stuff I ported turns out to be an earlier version of what is now a significant chunk of LDmicro. I started to look at porting the whole of LDmicro and this would be possible, if a little tedious.
As you say, most of the interface, including the actual ladder logic diagrams are simple ASCII text based, so that part should be easy to port - all it really needs is a to replace the GUI portions of the UI with something simpler.
A lot of LDmicro simply wouldn't be needed in a Propeller self-hosted version, and for the parts that are needed I'd recommend spreading them across several utility programs rather than bundling it all into one monolithic program like LDmicro does. For instance, the simulator should be split off and run separately.
I'm in the middle of preparing a new Catalina release (I found a bug that needs fixing). I'll have another look at LDmicro after that.
Ross.
ok.... sure, it is crammed in and over powered. but, maybe.. trying it on for size
I suppose, if I were serious, I'd jump to something like this. Was just thinking there would be some overlap for others to use some of the industrial protected I/O and interface expansion boards outside of this situation. and smaller individual expansion boards seem more economical to develop and flexible to deploy.
True for the P1, but not for the P2. I agree the self-hosted version of the Catalina C compiler is not really all an attractive option for arbitrary C development - it's too slow when compiling large C programs. But it would be quite adequate for the size and type of C programs typically generated from Ladder Logic, especially since they won't use large chunks of the standard C libraries like stdio (which for various reasons is the real killer for the self-hosted version of Catalina C) and also because those programs can use the QUICKBUILD option, since the target file to be used by all the generated C programs will only need to be assembled once and can then be re-used for all PLC programs.
Also, remember that Catalina offers not just self-hosted C development, but also self-hosted Lua and PASM development, and for these it is already quite practical. I actually only ever write my Lua programs on the Propeller, because it is quicker and easier to do that than write them on the PC and keep transferring them over to test them. Similarly when testing new Catalina plugins - I test, modify and re-assemble them using P2ASM on the Propeller.
In fact, apart from the actual process of generating and compiling the C code generated from the Ladder Logic (which we already know Catalina can do), it might be quicker and easier to write the UI around the Ladder Logic editor in Lua - this kind of thing is what Lua excels at. And I reckon someone somewhere will already have written a suitable text-based UI toolset in Lua that we could use.
For me, that would actually make this a more interesting project, since it would have wider application than implementing a PLC.
Ross.
hosted Lua development, accessible to user on the Propeller, is intersting to me. though, still sorting through options ... sooo many options, and not all compatible with eachother or with the future. so, still sorting this stuff out.
can Lua development be hosted on a P1, too?
Yes, it can. But it requires a fair slab of XMM RAM and is quite slow - probably too slow to be much use for anything except trivial Lua programs. I compile Lua for the P1 mainly just to demonstrate what Catalina can do.
But on the P2 Lua is much more useful. And much faster, since it can run entirely out of Hub RAM. Parts of the self-hosted version of Catalina are implemented in Lua. As are parts of Catalyst. I'd rewrite the whole of Catalyst in Lua except that then it wouldn't be able to run on P1s without XMM RAM (at the moment it can run on any Propeller - P1 or P2, with or without XMM RAM).
Also, I've found (as I thought I would) a text-based UI package for Lua that I think I can use on the P2.
Ross.