树莓派ADXL345设备ID与偏移值异常问题求助
Hey there, let's dig into why your new Raspberry Pi is throwing wonky ADXL345 readings while the other two work perfectly. Since you've already ruled out hardware by swapping SD cards, we can focus on software and configuration quirks that often crop up with newer Pi models.
1. Fix SPI Clock Speed Mismatch
Newer Raspberry Pis might default to a faster SPI clock speed that the ADXL345 can't keep up with, leading to corrupted data. Let's explicitly set a safe, supported clock speed (the ADXL345 works reliably up to 1MHz, so 500kHz is a solid starting point):
Modify your SPI initialization code to add the max_speed_hz setting:
spi = spidev.SpiDev() spi.mode = 3 spi.open(0, 0) spi.max_speed_hz = 500000 # Add this line to cap the clock speed
2. Verify Python & spidev Version Differences
Your script uses Python 2 syntax (like print 'Device ID...' without parentheses), so first confirm which Python version is running on each Pi:
python --version python2 --version
If your new Pi defaults to Python 3, running the script with python will throw errors—use python2 script.py instead, or update the shebang line at the top to #!/usr/bin/python2.
Next, check if the spidev library version differs between Pis:
pip2 show spidev
If the new Pi has a newer spidev version, try downgrading to match the working Pis:
pip2 install spidev==<version-from-working-pi>
3. Adjust SPI Initialization Order
While your script sets spi.mode = 3 (correct for ADXL345, which uses CPOL=1, CPHA=1), some versions of spidev behave differently if you set the mode after opening the bus. Try reordering the initialization steps:
spi = spidev.SpiDev() spi.mode = 3 # Set mode BEFORE opening the bus spi.open(0, 0) spi.max_speed_hz = 500000 spi.bits_per_word = 8 # Explicitly set 8-bit words to avoid ambiguity
4. Test with a Minimal SPI Read Script
Isolate the SPI communication to rule out issues in your full script. Create a tiny script that only reads the ADXL345 device ID:
#!/usr/bin/python2 import spidev spi = spidev.SpiDev() spi.mode = 3 spi.open(0, 0) spi.max_speed_hz = 500000 # Read device ID register (0x00) id_response = spi.xfer2([0x00 | 0x80, 0x00]) print(f"Device ID (Should be 0xe5): {hex(id_response[1])}") spi.close()
Run this on the new Pi. If it still returns wrong IDs, the problem is low-level SPI configuration; if it works, the issue is in your full script's logic (like the commented-out out variable in readadxl345—that would cause a NameError when you try to use out later).
5. Check for Hidden System Configuration Differences
Even if /etc/modules and /boot/config.txt look the same, double-check:
- SPI Enabled in raspi-config: Run
sudo raspi-config, go to Interfacing Options > SPI and confirm it's enabled. Sometimes changes toconfig.txtdon't take effect unless this is set via raspi-config. - SPI Bus Locking: Check if another process is using the SPI device with:
If anything else is accessing the bus, kill that process and retest.lsof /dev/spidev0.0 - 64-bit vs 32-bit OS: If your new Pi runs a 64-bit OS while the others use 32-bit,
spidevmight have compatibility issues. Try switching to a 32-bit Raspberry Pi OS image, or install 32-bit Python alongside the 64-bit version.
6. Fix Script Logic Errors
Looking at your readadxl345 function, the line defining out is commented out—this would cause a NameError when you try to use out later. Make sure that line is uncommented, and fix the sign-checking logic (operator precedence was off):
def readadxl345(): rx = spi.xfer2([242,0,0,0,0,0,0]) out = [rx[1] | (rx[2] << 8),rx[3] | (rx[4] << 8),rx[5] | (rx[6] << 8)] # Uncomment this! # Format x-axis (fixed sign check) if (out[0] & (1 << 15)): out[0] = out[0] - (1 << 16) # Format y-axis if (out[1] & (1 << 15)): out[1] = out[1] - (1 << 16) # Format z-axis if (out[2] & (1 << 15)): out[2] = out[2] - (1 << 16) return out
内容的提问来源于stack exchange,提问作者user75374

