If you ship inspection results as serial strings from smart cameras or board-level cameras, this failure is familiar: the vendor's serial example runs without a single error, yet nothing arrives at the receiver. The code is usually innocent. The firmware build routes the UART to a pin pair other than the one you wired, and the silkscreen labels do not have to match it. This guide uses a well-documented case — a vision board whose UART(4) speaks on the I2C pins while the marked TX and RX pins stay dead until a newer build — to show how to find the real pin map, test the link at the bench, and decide between rewiring and updating firmware.
Why does serial output come out on the wrong pins?
A UART is a peripheral the firmware can route to several pin pairs, and the build you flash decides the pair, so silkscreen labels such as TX and RX are true only where a build actually routes a port.
In the case behind this guide, a one-line script created UART(4, 19200) and wrote a test string every second. Nothing errored. The bytes left on header pins 1 and 2 — the two everyone reads as SDA and SCL — while the harness waited on pins 3 and 4. Run the causes down in this order:
- Firmware pin map differs from the silkscreen. Probe the other candidate pair first; it is the most common answer.
- TX and RX not crossed. Swap the two wires and look again.
- No common ground. Measure continuity between camera ground and adapter ground.
- Wrong level family. Meter the idle level; a TTL line idles high at 3.3 V.
- Framing mismatch. Garbage characters mean baud, parity or stop bits; silence means wiring or map.
- Output stage disabled in the camera settings, the same failure class as a strobe output that must be enabled before it fires.
Which pins carry UART in the documented case?
The default call UART(4, 19200) transmits on J2 pin 1 (PB_9) and receives on J2 pin 2 (PB_8) — the pins silkscreened SDA and SCL — and that map still works on build 4.4.2, while pins 3 and 4 stay silent on builds before 4.3.4.
Those two pins wear two hats. They are the I2C bus by default, and UART(4) claims them whenever a script asks for port 4. The header pins silkscreened TX (pin 3) and RX (pin 4) had no serial function at all until build 4.3.4 added a second port, named LP1, on exactly those pins.
| Header pin | Silkscreen | Before 4.3.4 | 4.3.4 and later |
|---|---|---|---|
| 1 | SDA | UART(4) TX on PB_9 | UART(4) TX on PB_9 |
| 2 | SCL | UART(4) RX on PB_8 | UART(4) RX on PB_8 |
| 3 | TX | no serial function |
LP1 TX |
| 4 | RX | no serial function |
LP1 RX |
Read the table as the decision rule: on this board the port name is the pin map. UART(4) always means PB_9/PB_8; UART("LP1") always means pins 3 and 4.
How do I find the pin map my build really uses?
Read the release notes for the exact build number flashed on the camera, because the constructor you call is itself the selector: a numeric id picks the legacy fixed map and a quoted name picks the labeled-pin map.
A call written UART(4, 19200) and a call written UART("LP1", 115200) are not two spellings of one port. On this board they drive two different physical connectors, so the script and the harness have to agree on the same one. When the notes and the measurement disagree, believe the measurement, then report the discrepancy to the vendor.
import time
from pyb import UART
uart = UART("LP1", 115200) # marked pins 3/4; needs build 4.3.4 or later
while True:
uart.write("Hello World!\r\n")
time.sleep_ms(1000)
Here uart is the port object, 115200 and 1000 are integers, and the loop puts one 14-byte line on the wire each second — enough to catch with any adapter.
Which firmware build moves serial to the labeled pins?
Build 4.3.4 is the first release that routes a second UART, named LP1, onto the header pins silkscreened TX (pin 3) and RX (pin 4), and later builds such as 4.4.2 keep the UART(4) map on PB_9 and PB_8 working alongside it.
The documented upgrade path runs through the vendor's own tools: the IDE menu command Tools > Install the Latest Development Release flashes the current build, and a manual flash uses Tools > Run Bootloader with the .bin from the official release package. After the update, the port you open is the string LP1, not a number.
The decision: stay on the old build and wire to J2 pins 1 and 2 if the harness is already built and you need no I2C; update to 4.3.4 or later and use LP1 if you want the marked pins, need PB_9/PB_8 back for I2C, or are still designing the harness.
How do I test the link before blaming the code?
Put a 3.3 V USB-TTL adapter on the candidate pair, tie the grounds, and watch for a short burst once per second: a 14-byte line takes 7.3 ms at 19200 baud and 1.2 ms at 115200, so every write shows as one clean burst.
- Jumper the adapter's own TX to RX first; characters echo means the adapter is good.
- Wire camera TX to adapter RX, adapter TX to camera RX, and GND to GND.
- Open the port at 8N1 and the baud your script uses.
- Run the write loop. Bursts on PB_9/PB_8 while your harness sits on pins 3 and 4 is a map mismatch, not a dead camera.
- Bursts where you wired them move the fault to framing or the receiver; read what actually arrives.
The arithmetic, for the line Hello World!\r\n at 14 bytes: 8N1 sends 10 bits per byte (1 start + 8 data + 1 stop), so 19200 baud carries 19200 / 10 = 1,920 bytes/s, and 14 / 1,920 × 1000 = 7.3 ms per line. At 115200 baud it is 11,520 bytes/s and 14 / 11,520 × 1000 = 1.2 ms. With the 1000 ms sleep between writes, the line occupies under 1 % of the wire either way.
What wiring keeps the pins and the board alive?
These are 3.3 V logic pins: cross TX to RX, tie the grounds, and never let an RS-232 line or a 24 V industrial output touch them, because one ±12 V swing destroys the transceiver and with it the port.
TTL idles high at 3.3 V; RS-232 idles negative and swings to roughly ±12 V, so an adapter of the wrong family both inverts and overdrives the pin. For machine-length runs, RS-232 is specified to about 15 m at low baud and RS-485 to about 1,200 m at 100 kbit/s — put a proper converter between camera and long line. Wiring damage and its triage have their own guide: camera GPIO wiring: prevent damage and triage power faults.
On a machine, serial usually leaves through the camera's round I/O connector. A power-and-I/O cable that lands every core on open terminals turns that connector into screw terminals your PLC or adapter can accept. The camera power and I/O cables range covers the lengths and connector styles; the LS-CBL-0300 is an M8 8-pin male-to-open cable with eight cores and 7 m of drag-chain-rated length.
- Type
- Power and I/O cables
- Length
- 6-8 m
What if the wiring is right and there is still no data?
Work the remaining causes in order — wrong port object, framing, inverted levels, missing ground, a script that never writes — because each has a one-minute test and only the last resort replaces hardware.
- Wrong port object. You call
UART(4)but wired pins 3 and 4: the bytes are leaving on PB_9/PB_8. Probe that pair before touching the harness. - Framing. Garbage characters mean baud, parity or stop bits disagree between the ends; set both to 8N1 and the same number.
- Inverted levels. An idle-low TX line on the meter means the wrong adapter family is on the pins.
- Missing ground. Without a common reference the bytes read randomly; measure near 0 Ω between the two grounds.
- The script never writes. Print to the IDE console before the loop and confirm the write call executes each second.
If the far end is a PLC or PC rather than your adapter, identical silence comes from a receiver-side mapping fault — mapping a USB serial port to a COM port inside your PLC runtime — and code readers that go quiet the same way follow the pattern in diagnosing silent serial scan commands. When the camera has an Ethernet port, a TCP string removes pins, levels and baud from the problem entirely: smart camera OCR string output over TCP: how to send it.
How do I keep the mapping stable through the next update?
Treat the pin map as firmware, not hardware: record the build number beside the harness drawing, open the port in one helper, and re-run the bench loopback after every update before the camera goes back on the machine.
Pin the build in production, and read the release notes of any candidate update for pin-map lines; 4.3.4 changed this board's answer to "where is TX", and the next change will be written the same way. Label the harness at both ends: TX = J2 pin 1 (PB_9) below 4.3.4, TX = pin 3 via LP1 from 4.3.4. One helper keeps the choice in a single line of code:
PORT = "LP1" # marked pins 3/4; use 4 for PB_9/PB_8 on builds before 4.3.4
BAUD = 115200
uart = UART(PORT, BAUD)
PORT holds either the string name or the numeric id, BAUD is an integer, and uart is the port object the rest of the script uses — so a firmware change touches one line, not the whole program.
If this failure is pushing you toward a camera that reports over Ethernet, the camera finder filters by interface and the system configurator walks camera, lens, light and cables in order. For integration reading, start from control vision routines on a smart camera with GPIO or serial input, and the systems topic page collects the rest of this troubleshooting family.
Questions
Can I still use I2C on pins PB_9 and PB_8 while UART(4) is running?
No. UART(4) claims PB_9 and PB_8, the same physical pins the board uses as I2C SDA and SCL, so the two functions conflict. Move serial to LP1 on the marked pins 3 and 4, which needs build 4.3.4 or later, and PB_9 and PB_8 return to I2C duty; otherwise keep I2C off while the legacy port is in use.
What voltage do smart camera UART pins use?
Logic-level TTL: 3.3 V on the board in this guide, with some vision boards using 1.8 V, so the logic rail matters before you buy an adapter. Never connect these pins to an RS-232 port, whose lines swing to about ±12 V, or to a 24 V industrial output. Use a 3.3 V USB-TTL adapter or a level shifter and tie the grounds.
Why does my adapter show boot messages but no inspection data?
On camera boards that run embedded Linux, the same TTL pins often carry the boot loader and kernel console before the application starts, so boot text proves the wiring, levels and baud are right. The fault then sits above the pins: the application is writing to a different port object than the one you wired, or is not writing yet.
Should I send inspection results over Ethernet instead of serial?
If the camera has a GigE or Fast Ethernet port, usually yes: a TCP string to the PLC or PC removes pin mapping, logic levels and baud from the design and needs no adapter hardware. Keep UART when the receiver only offers a serial port, when you want a simple point-to-point wire, or when existing PLC code already expects one.
