Arrow Keys Not Working, Choppy Video, I2C Error on Arducam PTZ Camera (RPi 4)

Hi everyone, I’m having trouble with my Arducam IMX477 12MP PTZ Camera (model B0167B12) on a Raspberry Pi 4B 8GB. The camera feed shows up fine in VNC viewer, but the arrow keys don’t do anything — the PTZ motors never move. The video is also really choppy and laggy.

When I press an arrow key, I get this I2C error:

File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 203, in draw_menu
    parseKey(k,focuser,auto_focus,camera)
File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 132, in parseKey
    focuser.set(Focuser.OPT_MOTOR_Y,focuser.get(Focuser.OPT_MOTOR_Y) - motor_step)
File "/home/pi/PTZ-Camera-Controller/B016712MP/Focuser.py", line 209, in set
    self.write(self.CHIP_I2C_ADDR,info["REG_ADDR"],value)
File "/home/pi/PTZ-Camera-Controller/B016712MP/Focuser.py", line 89, in write
    return self.bus.write_word_data(chip_addr,reg_addr,value)
File "/usr/lib/python3/dist-packages/smbus2/smbus2.py", line 496, in write_word_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

I also see these Qt timer warnings:

QObject::killTimer: Timers cannot be stopped from another thread
QObject::~QObject: Timers cannot be stopped from another thread

I already tried disconnecting the servo VCC and GND from the Pi to see if it was a power issue, but the arrow keys still don’t work. Is it safe to connect servo VCC directly to the Pi on this model? The scripts I’m using are FocuserExample.py and Focuser.py from the PTZ-Camera-Controller repo, using smbus2 for I2C.

Thanks for the detailed traceback — that’s really helpful. Looking at the call chain, the issue is clear:

FocuserExample.py line 132 (parseKey) tries to move the motor → Focuser.py line 209 calls set() → line 89 does write_word_data → smbus2 hits the kernel ioctl → and the I2C device returns Errno 121 (Remote I/O error).

This means the motor controller chip on the PTZ board isn’t responding on the I2C bus at all. It’s not a software config issue — the I2C transaction is failing at the hardware level. The Qt timer warnings are probably just side effects from the crash, not the root cause.

Could you post some photos of how everything is wired up? Specifically the ribbon cable connections and how the servo power lines are connected. Also, if you run i2cdetect -y 1 (or whichever bus you’re on), what addresses show up?

I’ve also sent you details via private message about a remote support option if we need to dig deeper.

Here are photos of my hardware setup:

13251
13250
13252

I’ve sent my AnyDesk ID through private message as well. Let me know what you think of the wiring.

Got the photos, thanks. I’m looking through them now. I’ve also received your message and will follow up there for the remote session. Stand by.

Okay, I tried again today and still no luck. I started suspecting the ribbon cable might be the culprit, so I replaced it with a spare — same issue, no change at all. Still getting error 121 and also saw error 5 at one point.

Here’s the full terminal output from a fresh run:

pi@raspberrypi:~ $ cd PTZ-Camera-Controller/B016712MP
pi@raspberrypi:~/PTZ-Camera-Controller/B016712MP $ python3 FocuserExample.py
[0:04:20.519947693] [1873]  INFO Camera camera_manager.cpp:330 libcamera v0.5.2+99-bfd68f78
[0:04:20.549243069] [1874]  INFO IPAProxy ipa_proxy.cpp:180 Using tuning file /usr/share/libcamera/ipa/rpi/vc4/imx477.json
[0:04:20.556340673] [1874]  INFO Camera camera_manager.cpp:220 Adding camera '/base/soc/i2c0mux/i2c@1/imx477@1a' for pipeline handler rpi/vc4
[0:04:20.556421154] [1874]  INFO RPI vc4.cpp:440 Registered camera /base/soc/i2c0mux/i2c@1/imx477@1a to Unicam device /dev/media3 and ISP device /dev/media1
[0:04:20.556466895] [1874]  INFO RPI pipeline_base.cpp:1107 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
Traceback (most recent call last):
  File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 235, in <module>
    main()
  File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 227, in main
    curses.wrapper(draw_menu,camera)
  File "/usr/lib/python3.13/curses/__init__.py", line 94, in wrapper
    return func(stdscr, *args, **kwds)
  File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 203, in draw_menu
    parseKey(k,focuser,auto_focus,camera)
  File "/home/pi/PTZ-Camera-Controller/B016712MP/FocuserExample.py", line 132, in parseKey
    focuser.set(Focuser.OPT_MOTOR_Y,focuser.get(Focuser.OPT_MOTOR_Y) - motor_step)
  File "/home/pi/PTZ-Camera-Controller/B016712MP/Focuser.py", line 209, in set
    self.write(self.CHIP_I2C_ADDR,info["REG_ADDR"],value)
  File "/home/pi/PTZ-Camera-Controller/B016712MP/Focuser.py", line 89, in write
    return self.bus.write_word_data(chip_addr,reg_addr,value)
  File "/usr/lib/python3/dist-packages/smbus2/smbus2.py", line 496, in write_word_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

Environment details:

  • libcamera v0.5.2+99-bfd68f78
  • Pipeline handler: rpi/vc4
  • Tuning file: imx477.json
  • Camera detected at: /base/soc/i2c0mux/i2c@1/imx477@1a
  • Unicam: /dev/media3, ISP: /dev/media1
  • Python 3.13

Screenshot of the terminal:
screenshot

So to recap what I’ve tried so far:

  1. Disconnected servo VCC and GND from the Pi — no change
  2. Replaced the ribbon cable — no change

Arrow keys still completely dead. Pretty stuck here.

Thanks for the detailed retest — the logs actually tell us something important now.

analysis

Notice this: the camera sensor itself initializes perfectly over I2C. libcamera finds it at /base/soc/i2c0mux/i2c@1/imx477@1a and the pipeline handler loads fine. The IMX477 sensor is talking to the Pi without any issues.

The crash only happens when the script tries to talk to the PTZ motor controller, which sits at a different I2C address (set via CHIP_I2C_ADDR in Focuser.py). That chip is the one returning Errno 121 — it’s simply not responding to any I2C transaction.

So we can narrow this down. It’s not:

  • The camera sensor (works fine)
  • The ribbon cable (you replaced it, no change, and the sensor I2C path uses the same cable and works)
  • A software or library issue (the ioctl itself fails at the kernel level)

Possible remaining causes:

  1. Faulty motor controller board — the I2C chip on the PTZ controller may be dead
  2. Insufficient power to the servo/motor controller — even though you tried disconnecting servo power, the controller board itself may not be getting enough juice through the Pi’s GPIO header
  3. I2C address mismatch or a wiring issue specific to the motor controller lines on the board

I’ve sent you a message privately about rescheduling a remote session so we can run through some live diagnostics — i2cdetect scans, voltage checks, and potentially swapping in test commands directly against the motor controller’s I2C address. That should tell us definitively whether the chip is alive at all.