Skip to content

Commit 0a90c25

Browse files
filippo-bosiclaude
andcommitted
Add serial parity option (M575 F) for device/Modbus mode
Aux serial ports in device (Modbus RTU) mode previously always opened as 8N1. Some Modbus devices require parity - e.g. OnRobot grippers need 8E1 - so add an optional parity setting (#1196). - AuxDevice: store a SerialParity (none/even/odd) and apply it in SetMode by selecting Mode_8N1/8E1/8O1 when calling AsyncSerial::begin(baudRate, config). - M575: in device mode, parse the F parameter (F0 none/8N1, F1 even/8E1, F2 odd/8O1). The parameter is applied on every device-mode M575, so omitting F restores the previous behaviour (8N1) instead of retaining a previously set parity. The core (CoreN2G AsyncSerial) already defines the Mode_8E1/8O1 framing, so no core change is needed. Default stays 8N1, so PanelDue/raw modes are unaffected. Enables e.g.: M575 P1 S7 B115200 F1 (Modbus RTU, 115200, 8E1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent e98afe4 commit 0a90c25

3 files changed

Lines changed: 17 additions & 1 deletion

File tree

src/Comms/AuxDevice.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ void AuxDevice::SetMode(AuxMode p_mode) noexcept
4242
#if SUPPORT_MODBUS_RTU
4343
uart->SetOnTxEndedCallback((p_mode == AuxMode::device) ? GlobalTxEndedCallback : nullptr, CallbackParameter(this));
4444
#endif
45-
uart->begin(baudRate);
45+
AsyncSerial::UARTModes config = AsyncSerial::Mode_8N1;
46+
if (serialParity == SerialParity::even) { config = AsyncSerial::Mode_8E1; }
47+
else if (serialParity == SerialParity::odd) { config = AsyncSerial::Mode_8O1; }
48+
uart->begin(baudRate, config);
4649
mode = p_mode;
4750
}
4851
}

src/Comms/AuxDevice.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ class AsyncSerial;
3131
class AuxDevice
3232
{
3333
public:
34+
enum class SerialParity : uint8_t { none = 0, even, odd };
35+
3436
AuxDevice() noexcept;
3537

3638
void Init(AsyncSerial *p_uart, uint32_t p_baudRate) noexcept;
3739
bool IsEnabledForGCodeIo() const noexcept { return mode == AuxMode::raw || mode == AuxMode::panelDue; }
3840
void SetMode(AuxMode p_mode) noexcept;
41+
void SetSerialParity(SerialParity p_parity) noexcept { serialParity = p_parity; } // applied on next SetMode; affects device/Modbus mode only
3942
void SetBaudRate(uint32_t p_baudRate) noexcept { baudRate = p_baudRate; } // must call SetMode after calling this to actually change the baud rate
4043
void Disable() noexcept;
4144
AuxMode GetMode() const noexcept { return mode; }
@@ -91,6 +94,8 @@ class AuxDevice
9194
uint32_t baudRate;
9295
AuxMode mode = AuxMode::disabled; // whether disabled, raw, PanelDue mode or Modbus RTU mode
9396

97+
SerialParity serialParity = SerialParity::none; // device/Modbus serial parity: none=8N1, even=8E1, odd=8O1
98+
9499
#if SUPPORT_MODBUS_RTU
95100
IoPort txNotRx; // port used to switch the RS485 port between transmit and receive
96101
uint8_t *_ecv_array receivedData;

src/Platform/Platform.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,14 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS
23032303
}
23042304
}
23052305
# endif
2306+
// Serial parity for device/Modbus mode. Always applied so that omitting F restores
2307+
// the pre-existing behaviour (no parity, 8N1) rather than keeping a previous setting.
2308+
switch (gb.Seen('F') ? gb.GetLimitedUIValue('F', 3) : 0)
2309+
{
2310+
case 1: dev.SetSerialParity(AuxDevice::SerialParity::even); break;
2311+
case 2: dev.SetSerialParity(AuxDevice::SerialParity::odd); break;
2312+
default: dev.SetSerialParity(AuxDevice::SerialParity::none); break;
2313+
}
23062314
# endif
23072315
}
23082316

0 commit comments

Comments
 (0)