fix 🐛: SCSerial::wFlushSCS() is empty, causing TX echo to corrupt FeedBack() reads on half-duplex servo bus#5
Open
Yeah-Nah wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the vendored SCServo serial transport so read-style servo operations can work on half-duplex buses where transmitted bytes are echoed back into RX. In the context of this codebase, that supports reliable gimbal/servo telemetry on the ESP32-based robot firmware.
Changes:
- Implement
SCSerial::wFlushSCS()so it waits for queued UART bytes to finish transmitting. - Clear RX immediately after transmit to discard echoed request bytes before response parsing begins.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+75
to
+76
| pSerial->flush(); // block until TX FIFO fully drains | ||
| rFlushSCS(); // discard the echoed TX bytes from RX buffer |
Comment on lines
+75
to
+76
| pSerial->flush(); // block until TX FIFO fully drains | ||
| rFlushSCS(); // discard the echoed TX bytes from RX buffer |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SCSerial::wFlushSCS()inSCServo/SCSerial.cpphas an empty body. On hardware where TX and RX share the same physical wire (half-duplex), this causes every call toFeedBack()to fail with-1, making it impossible to read live position, speed, load, or any other state from a bus servo.Hardware
waveshareteam/ugv_base_generalGeneral_Driver/ugv_config.h):Observed symptom
The pan servo physically moves correctly when commanded via
T=133— writes work. However, theT=1001telemetry response always reports a stuck pan value of-179.9560394regardless of the servo's actual position.With
InfoPrintenabled (T=605 cmd=1), the firmware emits a continuous stream ofT=1005errors:{"T":1005,"id":2,"status":0} {"T":1005,"id":1,"status":0}This confirms
FeedBack()is returning-1on every single call. BecausegetGimbalFeedback()only updatesgimbalFeedback[].posinside theif(st.FeedBack(...) != -1)guard, the position field stays at its zero-initialised C++ default (0), andpanAngleCompute(0)computes:Root cause
SCSerial::wFlushSCS()inSCServo/SCSerial.cppis completely empty:This function is called after every outgoing packet, before reading begins. Its purpose is to:
Because it does neither, the call chain for every
FeedBack()read proceeds as follows:By the time
checkHead()executes, the UART is still transmitting. The TX echo lands in the RX buffer first. Since every SCServo request frame begins with0xFF 0xFF,checkHead()picks up those two bytes from the echo, treats them as a servo response header, and then attempts to parse the remainder — which is the rest of the outgoing request, not a servo reply. The checksum fails,Read()returns0, andFeedBack()returns-1. The servo's genuine response arrives moments later but is never read.Writes work correctly because
syncWrite()/SyncWritePosEx()only transmit and never attempt to read a response.Fix
Two lines in
SCServo/SCSerial.cpp:pSerial->flush()on Arduino/ESP32 blocks until the hardware UART has clocked out every queued byte.rFlushSCS()already exists in the class (while(pSerial->read() != -1) {}) and drains whatever is sitting in the RX buffer. After both calls the RX buffer is clean and the servo's response can be received correctly.No other files need to be changed.
Notes
rFlushSCS()is correctly implemented and does its job — the gap is only inwFlushSCS().FeedBack(),ReadPos(),ReadSpeed(), etc.) on any hardware where the TX pin echoes onto the RX pin, which is the standard wiring for a single-wire half-duplex bus.SyncWritePosEx,WritePosEx, etc.) are unaffected.