OpenPLC Tutorial: Install, Program & Run Your First PLC
A current OpenPLC v4 tutorial covering the Editor, built-in simulator, Runtime v4, a tested first program, board targets, protocols and safety limits.
OpenPLC v4 is an open-source PLC editor and runtime toolchain. Install the current desktop Editor, create a project, select the built-in Simulator, declare one input and one output, build the project, and run the logic before connecting hardware. If you deploy to Runtime v4, connect from the Editor over HTTPS on port 8443; do not follow old v3 tutorials that expect a browser dashboard on port 8080.
Last tested against public documentation: July 25, 2026. The OpenPLC download page showed Editor v4.0.6-beta during this review. That version label, supported boards and menus can change. Use the live download page and release notes as the final authority.
This guide distinguishes three surfaces that older OpenPLC tutorials often mix together:
| Surface | What it does | Current boundary |
|---|---|---|
| OpenPLC Editor v4 | Creates, builds, simulates and deploys IEC-oriented PLC projects | Desktop downloads are published for Windows x64, macOS Intel/Apple Silicon and Linux x64; check the live matrix |
| Built-in Simulator | Runs a project without a physical PLC | Intended for logic learning and debugging, not plant commissioning |
| OpenPLC Runtime v4 | Executes a built project on standard computing hardware | Headless service; Editor connection uses HTTPS on port 8443 |
Independent publisher note: plcprogramming.io is not the OpenPLC project. We link to the project's current Autonomy and GitHub sources and identify our related browser simulator separately.
OpenPLC v4 Quick Start
Use this route for a first successful project:
- Download the current OpenPLC Editor from Autonomy's official download page.
- Verify the operating-system and architecture label before opening the installer.
- Create a new project and choose Ladder Diagram (LD) or Structured Text (ST).
- Leave the built-in Simulator selected for the first test.
- Create a cyclic task and attach the main Program POU if the project template has not already done so.
- Declare
StartPB,StopPB,RunCmdandMotorOutas Boolean variables. - Build a seal-in circuit, run it, and test start, stop and restart behavior.
- Save a known-good project copy.
- Only then select an embedded board or connect Runtime v4.
- Validate the final I/O map with outputs de-energized before connecting a load.
That sequence isolates editor, program, target and wiring faults. If the simulated program fails, hardware is not yet part of the problem.
OpenPLC Editor v4 vs Runtime v4
The Editor and Runtime are separate applications.
OpenPLC Editor v4
The Editor is the engineering environment. Current project documentation describes:
- Structured Text, Ladder Diagram, Function Block Diagram and Instruction List editors;
- Program, Function and Function Block POUs;
- variable tables and direct IEC-style locations such as
%IX0.0and%QX0.0; - cyclic task configuration;
- a built-in browser/desktop simulator;
- an embedded-board selector in the desktop application; and
- build targets for the simulator, Arduino-class boards and OpenPLC Runtime.
Sequential Function Chart support has appeared in OpenPLC generations, but do not assume every current Editor surface exposes the same language menu. Check the installed release and current documentation instead of relying on an “all five languages” claim.
OpenPLC Runtime v4
Runtime v4 is the headless execution service. The current runtime repository describes:
- a C/C++ PLC runtime core;
- a Python/Flask REST API;
- an HTTPS interface on port 8443 for Editor connections;
- Linux, Docker and multi-architecture build paths;
- TLS and authenticated management; and
- a plugin model for hardware and industrial protocols.
Runtime v4 does not provide the old v3 web dashboard. Opening https://runtime-host:8443 in a normal browser is not the configuration workflow. Configure and control v4 from the Editor or the documented platform surface.
OpenPLC v3 vs v4
OpenPLC Runtime v3 reached end of life and its original GitHub repository was archived on April 4, 2026. Runtime v4 is the current branch for a new deployment.
| Topic | Runtime v3 | Runtime v4 |
|---|---|---|
| Repository | Archived and read-only | Current Autonomy-Logic/openplc-runtime repository |
| Management | Browser dashboard commonly shown on port 8080 | Editor/API connection over HTTPS on port 8443 |
| Debug transport | Legacy Modbus TCP path | Secure WebSocket path documented by the v4 debugger |
| Installation commands | Old OpenPLC_v3 clone/install scripts |
Current Docker or v4 repository instructions |
| Use now | Maintain only when an existing system requires it | Start here for a new runtime project |
Do not combine a v3 installation command, v3 screenshot and v4 connection step. That is the main reason many copied tutorials fail.
Install OpenPLC Editor v4
Windows
At the review date, the official page listed Windows 10/11 x64. Windows on ARM was marked as not yet available.
- Open the official OpenPLC Editor download.
- Select Windows x64.
- Record the displayed version and file name in your lab notes.
- Scan the downloaded file using your normal security controls.
- Run the installer as the current user unless the installer explicitly requests elevation.
- Launch the Editor and confirm its version before creating a project.
Do not disable antivirus software or install a hand-picked collection of old Python packages. Those instructions belong to earlier Editor generations and weaken the machine without proving compatibility.
macOS
The official download page listed separate builds for Apple Silicon and Intel Macs.
- Choose the build matching Apple Silicon or Intel.
- Install using the signed package supplied by the current publisher.
- If macOS blocks the app, inspect the publisher/signature and use the operating system's normal privacy-and-security approval flow.
- Launch the Editor and run a simulator project before adding a USB target.
Linux
The official page listed a universal x64 AppImage and marked Linux ARM as not yet available on the download matrix.
- Download the current Linux x64 AppImage.
- Verify the file name/version against the download page.
- Make the AppImage executable using your file manager or a scoped
chmod +xcommand. - Launch it as a normal user.
- Test the built-in Simulator.
If you build the development Editor from source, use the requirements in the current Autonomy-Logic/openplc-editor repository. At review time, the repository requested Node.js >=22 <24; this is a contributor path, not the normal desktop installation.
Build Your First OpenPLC Program
The first program is a motor-command seal-in circuit. It deliberately controls a simulated MotorOut, not a real contactor.
1. Define the behavior
The acceptance criteria are:
- pressing Start turns
RunCmdon; - releasing Start leaves
RunCmdon; - pressing Stop turns
RunCmdoff; - Stop has priority if Start and Stop are true together; and
MotorOutfollowsRunCmd.
2. Declare the variables
Use four Boolean variables:
| Name | Type | Initial value | Role |
|---|---|---|---|
StartPB |
BOOL | FALSE | Simulated normally-open start command |
StopPB |
BOOL | FALSE | Simulated stop request; TRUE means stop |
RunCmd |
BOOL | FALSE | Internal latched run state |
MotorOut |
BOOL | FALSE | Simulated output |
Keep them unlocated in the first simulator run. Physical addresses belong to the target configuration, not the reusable control intent.
3. Ladder Diagram version
Create two branches feeding the RunCmd coil:
|----[/ StopPB ]----+----[ StartPB ]--------( RunCmd )----|
| | |
| +----[ RunCmd ]-------------------------|
|----[ RunCmd ]-----------------------------( MotorOut )---|
The normally closed logical condition NOT StopPB surrounds both the start and seal-in paths. That makes Stop dominant.
4. Structured Text equivalent
If you chose ST, use:
RunCmd := (StartPB OR RunCmd) AND NOT StopPB;
MotorOut := RunCmd;
The assignment executes every scan. Because the previous RunCmd value participates in the expression, it remains true after StartPB returns false. StopPB breaks the latch.
5. Add the program to a cyclic task
A POU that is not assigned to a running task may compile but never execute. Confirm:
- one cyclic task exists;
- the main Program instance is attached to it;
- the interval is appropriate for a simple lab; and
- there are no duplicate program instances writing the same output.
Do not copy a “1 ms is always better” recommendation. Task interval, operating system, target load and timing requirements must be measured together.
6. Build and simulate
With the Simulator target selected:
- Build the project and resolve every compiler error.
- Start the simulation.
- Set
StartPBtrue for one or more scans, then false. - Confirm
RunCmdandMotorOutremain true. - Set
StopPBtrue. - Confirm both outputs become false.
- Set Start and Stop true together.
- Confirm Stop wins.
- Stop and restart the simulation and record the initial state.
This is a complete, reproducible first test. A screenshot of a green rung is not enough; record the expected and observed value for each test case.
Add a Timer: Delayed Motor Output
To practise a stateful function block, add:
| Name | Type | Role |
|---|---|---|
StartDelay |
TON | On-delay timer instance |
MotorReady |
BOOL | Becomes true after the preset |
Structured Text:
RunCmd := (StartPB OR RunCmd) AND NOT StopPB;
StartDelay(
IN := RunCmd,
PT := T#2s
);
MotorReady := StartDelay.Q;
MotorOut := RunCmd AND MotorReady;
Test at least these cases:
- Start for less than two seconds:
MotorOutstays false. - Keep Run true past two seconds:
MotorOutbecomes true. - Press Stop:
MotorOutbecomes false without waiting for the timer. - Restart: timing begins again according to TON behavior.
The timer instance must be declared as TON; StartDelay.Q and StartDelay.ET are outputs of that stateful instance.
Run OpenPLC Runtime v4
Use the runtime when you need execution outside the Editor's built-in simulator.
Recommended Docker quick start
The current Runtime v4 repository publishes this Docker path:
docker pull ghcr.io/autonomy-logic/openplc-runtime:latest
docker run -d \
--name openplc-runtime \
-p 8443:8443 \
--cap-add=SYS_NICE \
--cap-add=SYS_RESOURCE \
-v openplc-runtime-data:/var/run/runtime \
ghcr.io/autonomy-logic/openplc-runtime:latest
For a reproducible lab or production review, pin a tested image digest/version rather than leaving latest in a permanent deployment.
Native Linux installation
The project's runtime page currently documents:
git clone https://github.com/Autonomy-Logic/openplc-runtime.git
cd openplc-runtime
sudo ./install.sh
Before running an installer with elevated privileges:
- inspect the current repository and release;
- use an isolated lab host or image;
- record the commit/tag you tested;
- review ports, created services and file locations; and
- keep a rollback or clean rebuild path.
The current service name shown by the project is openplc-runtime.service. Check it with:
sudo systemctl status openplc-runtime.service
Connect from the Editor
- Confirm the runtime host is reachable on the intended management network.
- In the Editor, select the Runtime v4 target or device connection surface.
- Enter the runtime host and port 8443.
- Complete the documented first-user/login flow.
- Build before upload.
- Upload and start the PLC from the Editor.
- Confirm the uploaded build/hash matches the project you just compiled.
- Watch selected variables in the debugger.
Runtime v4's debugger is live inspection; the current documentation says it does not provide breakpoint/step execution. Use the Simulator for controlled logic tests.
Arduino, ESP32 and Other Board Targets
The desktop Editor's current board-selection documentation describes more than 60 supported board profiles. Arduino-compatible targets compile through arduino-cli, while Runtime v4 targets use the runtime compiler/upload path.
The correct embedded workflow is:
- Open Device → Configuration in the desktop Editor.
- Select the exact board profile.
- Let the Editor obtain the required core/board definitions.
- Map IEC variables to the board's available pins.
- Review voltage, current, ADC and boot-strap constraints in the board documentation.
- Build and upload through the configured serial port.
- Test with LEDs or isolated low-energy training I/O first.
When you change boards, review every pin mapping. The control logic may remain the same, but the electrical interface does not.
Electrical boundary
Arduino, ESP32 and Raspberry Pi GPIO are logic-level electronics, not 24 V industrial I/O. Never connect a field signal, relay coil, contactor or inductive load directly unless a properly engineered interface provides:
- voltage-level conversion;
- input protection and filtering;
- output current amplification;
- flyback suppression for inductive loads;
- galvanic isolation where required;
- a suitable power supply and grounding scheme; and
- a fail-safe state for startup, reset and communications loss.
Use certified safety hardware for emergency stops and safety functions. Software running on a general-purpose board is not made safety-rated by drawing an E-stop contact in ladder logic.
I/O Addressing Without Guesswork
IEC-style located variables communicate intent:
%IX0.0— input, bit addressing;%QX0.0— output, bit addressing;%IW0— input word;%QW0— output word; and%MW0— internal memory word.
The physical or protocol mapping behind an address depends on the target and plugin. Do not reuse a v3 register table, Raspberry Pi GPIO table or Arduino pin map without checking the v4 target documentation.
Use an I/O worksheet:
| Program variable | IEC location | Target channel | Electrical state | Safe test |
|---|---|---|---|---|
StartPB |
%IX0.0 |
DI channel to verify | TRUE when pressed | Toggle with output disabled |
StopPB |
%IX0.1 |
DI channel to verify | TRUE when stop requested | Confirm stop-dominant logic |
MotorOut |
%QX0.0 |
DO channel to verify | TRUE requests run | Test with indicator before contactor |
The worksheet—not a generic address screenshot—should be reviewed against the selected board/runtime configuration.
OpenPLC v4 Protocol Support
The current OpenPLC communication matrix lists these Runtime v4 states:
| Protocol | Runtime v4 status in current documentation | Important boundary |
|---|---|---|
| Modbus server | Supported | Verify address mapping and transport |
| Modbus client | Supported | Verify polling, timeouts and failure behavior |
| Modbus RTU master | Supported | Verify serial settings and isolation |
| Siemens S7Comm server | Supported | Treat as OpenPLC's implementation, not Siemens firmware |
| OPC UA server | Supported | Configure certificates, identities and exposed variables |
| EtherCAT master | Supported through the documented plugin | Verify platform, cycle timing and slave compatibility |
| EtherNet/IP | In development | Do not plan a project around an unreleased path |
| DNP3 | Not listed as supported for v4 | Do not inherit v3 beta claims |
Arduino targets have a narrower protocol surface; the current documentation lists Modbus server mode rather than the full Runtime v4 matrix.
Modbus validation checklist
Before connecting an HMI or SCADA client:
- Confirm whether OpenPLC is the client or server.
- Record TCP/serial transport and unit identifier.
- Map one Boolean and one word end to end.
- Confirm zero-based vs one-based display notation in the client.
- Test word byte order with a known hexadecimal pattern.
- Test timeout, disconnect and reconnect behavior.
- Prevent unintended writes to safety- or motion-related variables.
- Restrict protocol access to the intended network zone.
OpenPLC Security and Production Limits
Runtime v4 adds modern management controls such as TLS and authenticated access, but those features do not make an arbitrary host, plugin or control panel production-ready.
For a serious deployment, document:
- the exact Editor and Runtime commit/version;
- operating-system image and patch process;
- user and credential ownership;
- network zones, firewall rules and permitted peers;
- plugin versions and protocol exposure;
- startup and watchdog behavior;
- I/O state during boot, stop, fault and communications loss;
- backup/restore and rollback;
- measured scan-time distribution under load;
- electrical/environmental ratings of the hardware; and
- an independent safety risk assessment.
Open source also does not mean “no obligations.” At review time, the current Editor repository displays GPL-3.0 and the Runtime v4 repository displays MIT. Review the exact repository licences and bundled dependencies for your intended distribution and commercial use.
Troubleshooting OpenPLC v4
The tutorial says port 8080, but nothing appears
You are probably reading Runtime v3 instructions. Runtime v4 listens for Editor/API connections on port 8443 and does not expose the old browser dashboard.
The Windows installer name says v3
Do not install an old OpenPLC_Editor_v3.x_Windows.exe from a copied tutorial. Start at the current official download page and record the version offered for your architecture.
The program builds but does not run
Check that:
- the Program POU is instantiated;
- the instance is assigned to a task;
- the task is enabled and cyclic;
- the selected target matches the build;
- the runtime is started after upload; and
- no second POU overwrites the same output later in the scan.
The simulator works but hardware does not
Separate the layers:
- confirm the selected board/runtime target;
- check the pin or plugin map;
- observe the program variable;
- observe the logical output;
- measure the electrical output with the load isolated;
- verify polarity and common reference; and
- then test the interface module and load.
Modbus values are shifted
Check function code, data type, zero/one-based notation, byte order and the OpenPLC variable-to-register map. Do not “fix” a one-register shift by changing every tag until the addressing convention is documented.
Runtime v4 will not start
Use the current service/container logs, not a guessed v3 log path. For native Linux, check:
sudo systemctl status openplc-runtime.service
sudo journalctl -u openplc-runtime.service
For Docker, use the container's logs and confirm port 8443 plus the required capabilities/volume were applied.
OpenPLC FAQ
Is OpenPLC free?
The current Editor and Runtime source repositories are publicly available under open-source licences. That removes a conventional per-seat editor fee, but it does not remove hardware, engineering, hosting, support, cybersecurity or licence-compliance costs. Review the exact repository and dependency licences.
Is OpenPLC v4 the current version?
Yes for new Runtime work. Runtime v3 is archived and explicitly marked end-of-life. The specific v4 Editor release can change; the official page displayed v4.0.6-beta during this review.
Does OpenPLC v4 have a web interface on port 8080?
No. That is a common v3 instruction. Runtime v4 is headless and the current documentation directs the Editor to connect over HTTPS on port 8443.
Can I simulate without hardware?
Yes. The current Editor includes a built-in Simulator. It is suitable for program logic and learning. It does not validate field wiring, electrical behavior, proprietary controller firmware or functional safety.
Which programming languages are supported?
Current Editor documentation explicitly covers Structured Text, Ladder Diagram, Function Block Diagram and Instruction List. Other OpenPLC generations and surfaces have referenced SFC; verify the exact installed Editor rather than assuming an identical language list across every release.
Can OpenPLC run on Raspberry Pi or Arduino?
OpenPLC supports standard-computing Runtime targets and many embedded-board profiles, but the exact board, architecture and compiler path must appear in the current board selector/documentation. A family name such as “Raspberry Pi” or “Arduino” is not a promise that every model is supported.
Can I use OpenPLC in an industrial machine?
Only after engineering the complete system and validating that the chosen hardware, operating system, I/O, network, environmental design and lifecycle controls meet the application's requirements. Do not use a general-purpose OpenPLC setup as a safety PLC or claim certification the selected system does not have.
Does OpenPLC support Modbus?
The current Runtime v4 protocol matrix lists Modbus server, Modbus client and Modbus RTU master support. Exact transport, mapping and target availability still require configuration and testing.
Is OpenPLC the same as a Siemens or Allen-Bradley PLC?
No. OpenPLC teaches IEC-oriented control concepts and provides its own runtime. It does not reproduce the compiler, firmware, instruction edge cases, safety functions or commissioning workflow of a proprietary controller.
Official Sources and Test Record
These primary sources were checked on July 25, 2026:
- OpenPLC Editor official download
- OpenPLC Editor v4 source repository and GPL-3.0 licence
- OpenPLC Runtime v4 product and installation page
- OpenPLC Runtime v4 source repository, Docker quick start and MIT licence
- OpenPLC Runtime v3 archived end-of-life repository
- Current board selection and compiler paths
- Current protocol support matrix
- Current project compilation path
- Current debugger behavior
- Structured Text syntax and TON example
Practise the Logic Before Installing
If you want to practise the seal-in and timer examples before downloading OpenPLC, our related browser-based PLC simulator provides lessons and scenario-based feedback. Check its versioned product facts for the current free allowance, dialect list, and access caveat.
Disclosure and limit: plcprogramming.io and PLC Simulation Software share the same publisher. The browser product is an educational simulator, not OpenPLC Editor, Runtime v4 or a hardware emulator. Use it to practise the control idea, then rebuild and validate the project in the current OpenPLC toolchain.
Related resources:


