Troubleshooting#
Symptoms, in approximate order of frequency.
The editor cannot find the device#
Search returns nothing.
Discovery is a UDP broadcast on port 33333, and broadcasts do not cross subnets. Check, in order:
Are you on the same subnet? Compare your workstation’s address with the device’s. Different subnets, a VPN, or a segmented VLAN will all defeat discovery while leaving the device perfectly reachable.
Has it finished booting? Give it a minute after power-up.
Is your host firewall dropping the reply? Some endpoint-protection suites block the inbound UDP response. Allow OpenPLC Editor through.
Wireless client isolation? Many guest and corporate Wi-Fi networks block station-to-station traffic. Use a wired connection.
The workaround is always the same: find the address another way and type it in manually.
# From the device, over an HDMI display or SSH
hostname -I
# Or sweep the subnet from your workstation
nmap -p 8443 --open 192.168.1.0/24
The device is found but will not connect#
Connection refused or times out. The runtime is not running. Try restarting the device.
Login fails. The credentials are stored on the device, not in any cloud account. If they are lost, see Recovery and Factory Reset.
The SLM-RP4 is not in the Device dropdown#
The support package is not installed, or the editor is too old.
Check the editor version. 4.3.1 or newer is required.
Open the Package Manager and check the Installed tab.
If it is not listed, install it. See Quick Start: OpenPLC.
Backplane Configuration and HAL Settings are missing#
They only appear once SLM-RP4 is selected in Device → Configuration. Select the board first.
If the board is selected and they are still missing, the package did not register its screens. Reinstall it and reopen the project.
No modules found#
No modules found in backplane after 5 retries
The base controller is alive but sees an empty bus. The SPI interface is working, so this is a wiring or seating problem rather than a configuration one. If the interface itself has been lost, the runtime reports a different error instead, covered under The backplane has stopped working entirely below.
Is the first module fully seated against the base? This is the usual cause.
Is backplane power present?
No base controller activity - check power supply
The base controller is not responding at all. Almost always a power problem rather than a module fault. Check 24 V at the terminal.
The backplane has stopped working entirely#
If no I/O works at all, rather than one module or one channel misbehaving, the SPI interface the backplane runs on has been lost.
The symptoms are:
The PLC does not run, and PLC Logs reports:
[SYNERGY] SPI: failed to open /dev/spidev6.0 at init (errno=2) [SYNERGY] SPI init failed Native plugin synergy failed to start (returned -1)
A Python program fails at
synergy_logic.Base()with:ValueError: No device found for /dev/spidev6.0
ls /dev/spidev6.0reports that the file does not exist.
The backplane uses /dev/spidev6.0, which is created by a single overlay line
in /boot/firmware/config.txt. Two things remove it.
Enabling SPI in raspi-config. The Interface Options → SPI toggle sets
dtparam=spi=on, which enables SPI0 on GPIO 7–11 (CE1, CE0, MISO, MOSI,
SCLK). The backplane’s SPI6 overlay uses GPIO 9 and 10 as its chip selects
(cs0_pin=9,cs1_pin=10). The two cannot coexist, and the backplane’s overlay is
the one that fails to load.
A system update or a reimage that rewrites config.txt and drops the
overlay line.
Identify which one it is#
ls /dev/spidev*
pinctrl get 9,10,19,20,21
grep -nE "dtparam=spi|dtoverlay=spi" /boot/firmware/config.txt
Result |
Cause |
|---|---|
|
SPI0 was enabled and is taking the pins |
No |
The overlay line is missing |
|
The interface is correct; the fault is elsewhere |
Restore it#
Edit the file:
sudo nano /boot/firmware/config.txt
If a line reads
dtparam=spi=on, comment it out with a leading#, or delete it.If the overlay line is missing, add it exactly as written:
dtoverlay=spi6-2cs,cs0_pin=9,cs1_pin=10
Save the file and reboot:
sudo reboot
If SPI was enabled through raspi-config, turning the same toggle back off has
the same effect as commenting the line out by hand. Check afterwards that the
dtoverlay line is still present.
To add the overlay line without editing the file, this appends it only when it is absent, and is safe to run more than once:
grep -q '^dtoverlay=spi6-2cs' /boot/firmware/config.txt \
|| echo 'dtoverlay=spi6-2cs,cs0_pin=9,cs1_pin=10' | sudo tee -a /boot/firmware/config.txt
It does not remove dtparam=spi=on, so check for that separately.
Keep the line outside a conditional section
config.txt can contain conditional filters such as [cm4] or [cm5], which
apply only to the hardware they name. The overlay line must sit under [all],
or before any filter, so that it always applies.
On a factory image [all] is the last section, so appending to the end of the
file is correct.
Verify after the reboot#
ls /dev/spidev*
pinctrl get 9,10,19,20,21
A working device reports both devices and these pin assignments:
/dev/spidev6.0 /dev/spidev6.1
9: op -- pd | hi // GPIO9 = output
10: op -- pd | hi // GPIO10 = output
19: a3 pd | lo // GPIO19 = SPI6_MISO
20: a3 pd | lo // GPIO20 = SPI6_MOSI
21: a3 pd | hi // GPIO21 = SPI6_SCLK
GPIO 9 and 10 are the chip selects and appear as ordinary outputs. If they
instead show SPI0_MISO and SPI0_MOSI, SPI0 is still enabled.
Then start the PLC and confirm the backplane comes up in PLC Logs:
[SYNERGY] SPI: opened /dev/spidev6.0 (mode=2, speed=1000000 Hz)
[SYNERGY] Slot 1: SLM-ACDCI-8NP-RLY8 (0x24A500E1)
[SYNERGY] Base controller initialized (1 module(s); DI=1 DO=1 AI=0 AO=0 bytes)
Never enable SPI through raspi-config on this device
The SPI toggle in raspi-config configures a different bus on different pins,
and enabling it disables backplane communication completely until the change is
undone and the device is rebooted.
The dtoverlay line is the whole SPI configuration, and it is applied at the
factory. Leave the raspi-config toggle off.
Sign-on lists the wrong modules#
The PLC Logs sign-on lines come from the modules themselves and are authoritative:
Slot 1: SLM-DCI-16NP (0x052000E2)
Slot 2: SLM-DCO-15P (0x140800E6)
If they disagree with your Backplane Configuration, the configuration is wrong. Correct it and re-upload.
Running with a mismatched configuration means your program addresses the wrong data.
An output does nothing#
Work down the chain rather than guessing.
Is the PLC running? The RGB LED should be green.
Is the variable being set? Open the debugger and watch it. If it is not changing, the problem is in your logic.
Did the module sign on? Check PLC Logs.
Does the module have field power? Discrete output modules need their own supply to switch a load. The backplane powers the module’s logic, not your load. This is the most common cause.
Sinking or sourcing? A load wired for a PNP module will not work on an NPN one, and vice versa.
Right address? Check the I/O Mapping table. Output numbering starts at
%QX0.0for the first module with outputs, which is not necessarily slot 1.
An input never changes#
Right address? Check the I/O Mapping table.
Is the field wiring correct for the module type? Sinking inputs need the circuit completed to common.
Is the signal actually present? Meter it at the terminal.
Did the module sign on?
An analog channel reads zero, always#
At sign-on, the OpenPLC Runtime sends each analog and temperature module the configuration from the project’s Backplane Configuration, or the module’s factory defaults when the project has none. The Python and C++ libraries send the factory defaults.
Channel not enabled. Channels Enabled restricts which channels are sampled. Disabled channels read zero while still occupying their addresses.
Configuration not applied. Check the PLC Logs for
Slot N (MODULE): no config available or a configuration length mismatch
warning. Set the module’s Configuration form in Backplane Configuration and
re-upload.
Analog readings are wrong by a factor of eight#
You are scaling against the wrong maximum.
The range of a raw analog count depends on the module’s Counts Scaling setting in Backplane Configuration:
Module resolution (the default): counts follow the converter, 0-8191 for a 13-bit input and 0-4095 for a 12-bit output.
Rescaled to 0 - 65535: every channel spans the full
UINTrange.
Code written for one setting and run with the other is out by a factor of roughly eight (13-bit) or sixteen (12-bit). Check the setting, then scale against the matching maximum. The Python and C++ libraries always report counts at module resolution. See Configuring the Backplane.
Temperatures are in the wrong unit#
The SLM-THM-4 defaults to degrees Fahrenheit.
Change it in Burnout Detection / Units on the module’s Configuration form and re-upload. See Configuring the Backplane.
Temperature readings are wrong but plausible#
Check the sensor type. The default is Type J; a Type K thermocouple read as Type J is linearised with the wrong curve. The error is small near ambient and grows with temperature, so it passes a bench test and fails in the process.
A temperature falls as the process heats#
The thermocouple is wired backwards. Swap the leads. Note that under ANSI colour coding the red lead is negative, which is a common source of error.
The PLC keeps stopping#
Bus fault. The HAL has detected repeated failures on a slot and applied the configured fault action. Check PLC Logs for which slot.
A module working loose is the usual cause.
Electrical noise. Check grounding and cable routing.
Cycle overrun. The driver cannot complete a scan within its configured cycle time. Raise the Bus Scan Cycle rather than the fault threshold. Masking an overrun does not make the I/O any fresher.
See HAL Settings.
Changes have no effect#
Backplane configuration, HAL settings and module configuration all live in the project and are pushed to the device on upload.
Build & Upload after changing any of them. Editing a form does not affect a running device.
If a build behaves inexplicably, try Clean Upload to discard the device’s build cache.
I/O stops working after a package update#
A package update can change the HAL driver. The device keeps running the driver it already has until you upload again.
Rebuild and re-upload. Then confirm that the modules in your backplane configuration are still present in the updated module list. See Configuring the Backplane.
Python or C++: erratic readings#
This is almost always a backplane collision. The OpenPLC Runtime holds the backplane while the PLC is running, and the direct libraries drive the same pins. Running both at once produces interleaved transactions and invalid data, with no error raised.
Stop the PLC with Stop in OpenPLC Editor, or stop the runtime from a terminal:
sudo docker stop openplc-bootloader openplc-runtime
Then power-cycle the base to clear the base controller’s state, and start one side only. See Sharing the Hardware.
Python: ModuleNotFoundError: No module named 'synergy_logic'#
The library is supplied under ~/Desktop/synergy_python and is not installed
system-wide, so it is importable only when the interpreter can find it. Run your
program from that directory, or set PYTHONPATH:
cd ~/Desktop/synergy_python
python3 my_program.py
# or, from anywhere
export PYTHONPATH=/home/slm-rp4/Desktop/synergy_python
Python: permission denied on /dev/spidev6.0#
groups
ls -l /dev/spidev6.0 /dev/gpiochip0
Add the user to the group owning the device node, then log out and back in.
C++: undefined reference to 'Synergy::init()'#
You compiled against the header but did not compile the implementation. Both
Synergy.cpp and RPi.cpp must be in the source list:
LIB=~/Desktop/synergy_cpp/lib/synergy
g++ -std=c++17 -O2 -I $LIB $LIB/Synergy.cpp $LIB/RPi.cpp myprogram.cpp -o myprogram
C++: Synergy.h: No such file or directory#
The -I path does not point at the directory containing the headers.
See C++: Building.
A service does not start at boot#
systemctl status my-controller
journalctl -u my-controller -n 100
Common causes:
Forgot
sudo systemctl enable my-controller.Forgot
sudo systemctl daemon-reloadafter editing the unit file.Relative paths in the program with no
WorkingDirectory=set.The program starts before the hardware is ready. Make it retry.
Python output buffering hiding the real error. Add
Environment=PYTHONUNBUFFERED=1.
See Running on Boot.
Reading the runtime logs#
The PLC Logs tab in OpenPLC Editor is the normal way to read the runtime’s output, and it needs no terminal access.
If the editor cannot connect, or you need more history than the tab shows, read
the logs from a terminal instead. The runtime runs as a container, so its
output comes from docker logs:
# The last 200 lines
sudo docker logs --tail 200 openplc-runtime
# Follow live
sudo docker logs -f openplc-runtime
# Only the last ten minutes
sudo docker logs --since 10m openplc-runtime
The runtime writes its own timestamps, so there is no need to add -t.
If the runtime is not starting at all, the component that supervises it keeps a separate log, which will say why:
sudo docker logs --tail 50 openplc-bootloader
If the problem persists#
Gather this before asking for help:
What the LEDs are doing.
The PLC Logs output, especially the sign-on lines.
sudo docker logs --tail 200 openplc-runtimefrom the device.sudo docker logs --tail 50 openplc-bootloader, if the runtime is not starting.Your backplane arrangement, slot by slot.
What changed immediately before the problem started.
The last item resolves more cases than any other.
Contact Synergy Logic for hardware, and the OpenPLC documentation for editor and runtime questions.