关于SMBus write_i2c_block_data用法及蠕动泵I2C故障的技术问询
Hey there, let's work through your I2C pump issues— I've been in your shoes trying to get Python talking to finicky microcontroller-based devices, so I get the frustration!
smbus.SMBus.write_i2c_block_data First, let's clear up the confusion around this function. The signature is straightforward once you know what each parameter is for:
bus.write_i2c_block_data(slave_address, cmd, data)
Here's what each argument means:
slave_address: The 7-bit I2C address of your device (you've got this right with0x67).cmd: A single 8-bit integer (0-255) that acts as a command/register byte. Most I2C devices use this to know what to do with the data that follows— it might be a register address, an operation code, or a fixed value required by the device's firmware. This is NOT part of your ASCII command string (that's where you went wrong!).data: A list of 8-bit integers (0-255) — this is the actual payload you want to send. For your ASCII commands, each element should be the ASCII value of a character in your string (e.g.,'L'becomes76,','becomes44, etc.).
Looking at your code, your string_to_intlist function has a bug: it's converting each character into a nested list instead of a flat list of integers. That's why you ended up with weird data being sent. A much simpler way to convert your ASCII command to the right data format is:
# Convert 'L,1' to [76, 44, 49] data_bytes = [ord(char) for char in 'L,1']
So a corrected function to send your commands might look like this (note: you'll need to confirm the correct cmd value from your pump's docs— I'm using 0x00 as a placeholder):
import smbus import time bus = smbus.SMBus(1) slave_address = 0x67 def send_pump_command(cmd_string): # Convert ASCII string to list of ASCII integer values data_payload = [ord(c) for c in cmd_string] # Send the data— replace 0x00 with the actual cmd byte required by your pump bus.write_i2c_block_data(slave_address, 0x00, data_payload) # Test LED control send_pump_command('L,1') time.sleep(0.5) send_pump_command('L,0') time.sleep(0.5)
The fact that the LED flashes but then the pump locks up (and can't be detected by i2cdetect) points to a few likely issues:
Mismatched I2C Frame Format: Your pump's firmware is expecting a specific structure for I2C messages, and you're sending something it can't handle. For example, maybe the
cmdbyte needs to be a fixed value (like 0x01 for LED commands) instead of the first character of your string. When it gets an unexpectedcmdvalue, the firmware crashes or enters an infinite loop.- Fix: Dig up the pump's official I2C communication docs (this is non-negotiable!). It should tell you exactly what the
cmdbyte should be, and how to package your ASCII commands. If you don't have the docs, try common default cmd values like0x00or0x01when sending your data.
- Fix: Dig up the pump's official I2C communication docs (this is non-negotiable!). It should tell you exactly what the
Buggy Firmware Error Handling: Many cheap microcontroller-based devices have minimal error handling. If your pump receives malformed data (like the nested lists your original code was sending), its I2C peripheral might get stuck in a bad state.
- Fix: Power-cycle the pump to reset it. Then send strictly formatted data using the corrected code above.
Electrical Connection Problems: I2C is super sensitive to bad grounding. Even if the Arduino is powering the pump, if the Raspberry Pi and pump aren't sharing a common ground, communication will get garbled, leading to the pump locking up.
- Fix: Connect the GND pin of the Raspberry Pi to the GND of the pump (and Arduino, if it's part of the circuit). Double-check that SDA and SCL lines aren't swapped. If your I2C bus is long, add 4.7kΩ pull-up resistors to both lines (though the Pi usually has these built-in).
Unresponsive I2C Device: Some devices don't respond to
i2cdetectbecause they only react to specific command bytes, not the general probe thati2cdetectuses. That's why your pump might work briefly but not show up in the scan.- Fix: Don't rely solely on
i2cdetect— test with your corrected command code first, and check if the pump responds as expected.
- Fix: Don't rely solely on
内容的提问来源于stack exchange,提问作者Kwang2846

