On this Neuron M103 running UniPian with EVOK 2.1.6, the xS10 never answered because EVOK never asked. The [EXTENSION_1] section in /etc/evok.conf ships commented out, so the Modbus master had no device to poll on /dev/extcomm/0/0. The Rx/Tx LEDs were dark on both units, and the Unipi Control Panel listed only the base Neuron. Removing the leading ; from every line of that block and rebooting brought EVOK and the Modbus link up. The sections below build the link hop by hop, and each one ends with the check that proves it.
Where does the Modbus request stop between EVOK and the xS10?
The Neuron is the Modbus RTU master, and EVOK is the process that generates every poll. A request starts in the EVOK Python process. EVOK looks up the device section in its config, loads the matching hardware definition, and writes a frame to the serial device. The Neuron's RS485 transceiver drives it onto the pair, and the xS10 decodes it and replies. Each hop has an observable state:
| Hop | Element | Identifier | State in this installation |
|---|---|---|---|
| 1 | EVOK service |
evok.service, /opt/evok/.../evok.py
|
active (running) |
| 2 | Device definition |
[EXTENSION_1], device_name = xS10
|
Commented out (every line prefixed with ;) |
| 3 | Serial port / Neuron UART circuit |
/dev/extcomm/0/0, circuit 1_01
|
19200 baud, parity None, stop bits One |
| 4 | Neuron RS485 transceiver | RS485 END: ON | Rx/Tx LEDs OFF |
| 5 | Twisted pair | A-A, B-B, 50 cm | Wired |
| 6 | xS10 RS485 port | DIP 1 ON, 2 OFF, 3 ON, 4 OFF, 5 OFF, 6 OFF, 7 ON | Rx/Tx LEDs OFF; power LED (red) ON; status LED (green) flashing |
The LED pattern tells you which hop to work on. A master that transmits into a broken pair or at the wrong slave address still blinks its own Tx LED. Only a master that never builds a frame leaves every LED dark.
| Neuron Tx | xS10 Rx | xS10 Tx | Neuron Rx | Where the request stops |
|---|---|---|---|---|
| Off | Off | Off | Off | Hop 2: EVOK has no active device on the port (this installation) |
| Blinks | Off | Off | Off | Hop 5: open pair, swapped A/B, wrong terminals |
| Blinks | Blinks | Off | Off | Hop 6: frames arrive but the slave ignores them (address, baud, parity, or stop-bit mismatch) |
| Blinks | Blinks | Blinks | Blinks | Link is up; if nothing is mapped, check device_name against the hardware definition |
Check: Watch the Neuron Tx LED for several seconds. Dark means the fault is upstream of the wire, and wiring changes will not fix it.
Is the software stack the one EVOK expects?
This unit runs UniPian-Neuron-OS-2019-01-07-v1.9.img with EVOK updated to 2.1.6, and config_version = 2.5 in [MAIN]. Leave config_version alone; the file marks it as not to be changed. The serial parameters in the extension block (baud_rate, parity, stop_bits) take effect only on a Unipi image. On standard Raspbian, EVOK cannot set the Unipi serial ports from the config, and you configure the UART through the API instead.
The install ran apt-get install evok before apt-get update. apt-get update refreshes only the package index. To pull the newest EVOK onto an existing install, refresh first and then install:
sudo apt-get update
sudo apt-get install evok
sudo reboot
The systemctl status evok output shows one failed pre-start step:
ExecStartPre=/bin/mv -f /etc/nginx/sites-enabled/mervis /etc/nginx/sites-available/ (code=exited, status=1/FAILURE)
That step moves a Mervis nginx site out of sites-enabled. On an EVOK-only image that site does not exist, so mv fails. The unit still reached active (running) and the EVOK nginx site was linked. The failure is cosmetic and has nothing to do with RS485.
Check: dpkg -l evok reports the installed version, and sudo systemctl status evok reports active (running) with the main python ... evok.py process listed.
Is the RS485 pair wired and terminated for a two-node bus?
The bus is a single 50 cm segment. It runs Neuron A to xS10 A and Neuron B to xS10 B, with the Neuron's RS485 END set to ON. RS485 is a differential bus, and swapping A and B inverts every bit. The slave then sees garbage and stays silent, which matches the "Tx blinks, nothing else" row above rather than the all-dark pattern seen here.
Termination belongs at the two physical ends of the segment. The Neuron is one end, and END: ON covers it. The xS10 is the other end, so set its bus-end termination according to its manual. At 50 cm and 19200 baud, reflections are negligible, and a missing terminator alone will not stop the link. Keep the pair twisted and away from mains wiring anyway. If the installation later grows to a longer run, termination at both ends matters.
Check: Disconnect power and ring out A-A and B-B end to end. Confirm there is no short between A and B, and confirm that no third conductor is landed on either terminal.
Do the xS10 DIP switches match address 1 and 19200 8N1?
The xS10 takes its Modbus slave address and serial parameters from its DIP switches. On this unit they read 1 ON, 2 OFF, 3 ON, 4 OFF, 5 OFF, 6 OFF, 7 ON. EVOK sends to the address in address using the port settings in baud_rate, parity and stop_bits. The slave must be set to the same values. A mismatch on any one of them produces frames the xS10 discards silently.
| Setting | EVOK key | Value used | Where the xS10 sets it |
|---|---|---|---|
| Slave address | address |
1 | DIP switches (decode per xS10 manual) |
| Baud rate | baud_rate |
19200 | DIP switches |
| Parity | parity |
N | DIP switches |
| Stop bits | stop_bits |
1 | DIP switches |
The link came up at address = 1, 19200/N/1 without any DIP change. That confirms the recorded switch pattern produces those settings on this module. Record it, because a second xS10 on the same port needs a different address and the same serial parameters.
Expansion modules commonly read their DIP switches only at power-up. Cycle xS10 power after changing a switch.
Check: Decode the switch pattern against the DIP table in the xS10 documentation. Confirm it gives the same address you will write into address.
Which Neuron port and circuit carry the extension traffic?
The extension sits on /dev/extcomm/0/0, associated with the Neuron UART-over-Modbus circuit 1_01 through neuron_uart_circuit. The Control Panel shows that circuit at Speed 19200, Parity None, Stopbits One. These values must agree with the baud_rate, parity and stop_bits keys in the extension block.
The Control Panel status for the base unit read S102, while the hostname is M103_2-sn465. The fix did not depend on this. The UART circuit and port path were the same either way. Note which model the Control Panel reports if you file a support case with Unipi.
Two port rules from the config file shape any later expansion:
- All devices that share a port use the port settings of the first device defined on it. The settings in
[EXTENSION_1]are inherited by every later section pointing at/dev/extcomm/0/0. A differentbaud_ratein a second section is ignored, not applied. -
neuron_uart_circuitworks only with Neuron UART-over-Modbus ports. It has no meaning for plain Linux serial devices such as/dev/ttyUSB0or/dev/ttyS0.
Check: ls -l /dev/extcomm/0/ lists the 0 node. The Control Panel UART settings for circuit 1_01 read 19200 / None / One.
Why does EVOK skip a device whose section is commented?
/etc/evok.conf is an INI-style file, and ; is its comment character. Its first line warns that # must not be used for comments. The file also puts inline comments after values, for example scan_frequency = 10 ; Optional, 10 default. The parser strips everything from the ; onward.
EVOK creates a device object only for sections that exist after parsing. The file ships with two template blocks, [EXTENSION_1] for a Neuron extension such as the xS10 and [EXTENSION_2] for a third-party Modbus device. Every line of both blocks, including the header, starts with ;. After parsing, the only active sections were [MAIN], [NEURON_1] and [OWBUS_1].
With no device bound to /dev/extcomm/0/0, EVOK had nothing to poll. It sent no frames, so the Tx LED stayed dark, and no extension circuits reached the Control Panel. EVOK does not auto-discover devices on RS485. Every slave must be declared.
Check: List the section headers the parser will see:
grep -n '^\[' /etc/evok.conf
Before the fix this returns [MAIN], [NEURON_1] and [OWBUS_1]. [EXTENSION_1] must appear before you go further.
How do I enable the [EXTENSION_1] block for the xS10?
The block needs one active line per key. Leave [EXTENSION_2] commented unless a third-party device is actually on the bus. An active section pointing at an absent slave adds timeouts to every scan of the shared port.
- Confirm the hardware definition exists. The file requires that
device_namematch a filename in/etc/hw_definitions. The shippedCUSTOM MODBUS DEVICE.yamlis an example of the naming.
Look for thels /etc/hw_definitionsxS10definition. If it is missing, EVOK cannot map the module even with a working link. - Open the config as root:
sudo nano /etc/evok.conf - Find the
;[EXTENSION_1]block. Delete the leading;from the header and from every key line under it, down tostop_bits. Leave the descriptive lines that are pure comments, such as; Note that the following settings will be inherited..., as they are. The result must read:[EXTENSION_1] global_id = 2 ; Mandatory, REQUIRED TO BE UNIQUE device_name = xS10 ; Mandatory modbus_uart_port = /dev/extcomm/0/0 ; Mandatory neuron_uart_circuit = 1_01 allow_register_access = True address = 1 scan_frequency = 10 scan_enabled = True baud_rate = 19200 parity = N stop_bits = 1 - Check
global_idagainst the other sections.[NEURON_1]already usesglobal_id = 1, so the extension takes 2, and any later device takes the next unused integer. - Set
addressto the slave address decoded from the xS10 DIP switches. Setbaud_rate,parityandstop_bitsto the module's serial settings and to the circuit1_01UART settings. - Save and exit nano:
Ctrl+O,Enter,Ctrl+X.
allow_register_access = True is optional for a Unipi extension and mandatory for third-party devices. It exposes raw Modbus registers through EVOK in addition to the mapped circuits, which is useful while commissioning. scan_frequency = 10 polls the module 10 times per second. Keep it there unless several slaves share the port and the combined scan load needs reducing.
Check: Rerun grep -n '^\[' /etc/evok.conf. [EXTENSION_1] now appears between [NEURON_1] and [OWBUS_1], and ;[EXTENSION_2] does not appear.
How do I restart EVOK and read what it logged at startup?
EVOK reads /etc/evok.conf only when it starts. A full reboot is the step that worked here:
sudo reboot
Restarting only the service also reloads the config and is faster during repeated edits:
sudo systemctl restart evok
sudo systemctl status evok
EVOK writes its log to /var/log/evok.log, and the file is cleared on every boot. Read it before the next reboot if you are chasing an intermittent fault.
The shipped log_level = ERROR suppresses the device-creation and port-open messages you want during commissioning. Raise it temporarily in [MAIN]. The allowed values are INFO, DEBUG, WARNING, ERROR and CRITICAL.
log_level = INFO ; commissioning only
Then follow the startup:
sudo systemctl restart evok
tail -f /var/log/evok.log
A malformed line in the extension block shows up here as a parse or missing-key error. Typical causes are a key left with its ;, a # used as a comment, or a device_name with no matching hardware definition. Put log_level back to ERROR once the link is stable, because verbose logging at a 10 Hz scan fills the log quickly.
Check: systemctl status evok shows active (running) after the restart. The log shows no error mentioning EXTENSION_1, xS10 or /dev/extcomm/0/0.
Are the OWFS DS2482-100 reconnect messages part of the fault?
No. They come from a different data path. The journal shows repeated lines such as:
OWFS[866]: DEFAULT: ow_reconnect.c:(72) DS2482-100 bus master reconnected
These come from the second EVOK process (PID 866), which runs OWFS for the [OWBUS_1] section. That path is I2C: owbus = /dev/i2c-1 --i2c=/dev/i2c-1:ALL addresses a DS2482-100 I2C-to-1-Wire bridge, which drives the 1-Wire hub and the single temperature sensor. It shares no hardware with the RS485 port.
| Path | Config section | Physical layer | Timing keys |
|---|---|---|---|
| xS10 extension | [EXTENSION_1] |
RS485, /dev/extcomm/0/0
|
scan_frequency = 10 Hz |
| 1-Wire sensors | [OWBUS_1] |
I2C /dev/i2c-1 → DS2482-100 → 1-Wire hub |
interval = 3 s read, scan_interval = 300 s bus scan |
The reconnects are logged every few minutes, at 18:05, 18:10, 18:12, 18:15, 18:17 and so on. They do not interrupt Modbus polling.
If the temperature value in the Control Panel updates steadily, you can leave them alone. If readings drop out, work the 1-Wire path on its own terms. Check hub power, the sensor wiring topology and cable length, and reseat the hub connection.
Check:interval, independent of whether the xS10 is connected.
How do I prove the xS10 is polled end to end?
Work back along the same hops, from the wire up to the application, after the restart:
- Physical: The Neuron Tx LED and xS10 Rx LED blink continuously at the scan rate, and the xS10 Tx and Neuron Rx LEDs blink with them. All four active means requests go out and replies come back.
-
Service:
sudo systemctl status evokreportsactive (running)./var/log/evok.logcontains no errors for the extension. - Mapping: The Unipi Control Panel lists the xS10 as an additional device next to the base Neuron, with its circuits populated.
-
API: Query EVOK's REST API on internal port 8080, or through nginx per
/etc/evok-nginx.conf. Confirm the xS10 circuits appear under the extension. Node-RED reads and writes these same EVOK circuits, so the Node-RED flow sees exactly what the API returns. -
Persistence: Reboot the Neuron once more. The xS10 must reappear in the Control Panel without further edits, which proves the change in
/etc/evok.confwas saved and parses cleanly at boot.
FAQ
How do I add an xS10 extension to EVOK on a Unipi Neuron?
Edit /etc/evok.conf with sudo nano and remove the leading ; from every line of the [EXTENSION_1] block. Keep device_name = xS10, modbus_uart_port = /dev/extcomm/0/0, a unique global_id such as 2, and the matching address, baud_rate, parity and stop_bits. Save with Ctrl+O, Enter, Ctrl+X, then reboot or restart the evok service.
Why are the Rx/Tx LEDs off on both the Neuron and the xS10?
If neither Tx LED blinks, EVOK is not polling the port at all, usually because no active extension section points at /dev/extcomm/0/0. A wiring or address fault still makes the Neuron Tx LED blink, so dark LEDs on both ends point to the config, not the cable.
How do I check which sections EVOK will actually load from evok.conf?
Run grep -n '^\[' /etc/evok.conf. Only headers without a leading ; are listed, and those are the sections EVOK creates devices for. The xS10 needs [EXTENSION_1] in that list.
How do I set baud rate and parity for a Unipi extension on the RS485 port?
Set baud_rate, parity and stop_bits in the first device section on that port, for example 19200 / N / 1. Every later device on the same port inherits these settings. The keys work only on a Unipi image; on standard Raspbian, configure the UART through the EVOK API. The xS10 DIP switches must be set to the same values.
Do the "DS2482-100 bus master reconnected" messages stop Modbus communication?
No. They come from OWFS on the I2C 1-Wire path configured in [OWBUS_1] (/dev/i2c-1), which is separate from the RS485 port. Investigate them only if 1-Wire temperature readings drop out.