You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Arduino Uno与Adafruit电机盾v2时LIS3DH加速度计输出空值求助

排查LIS3DH在Adafruit Motor Shield v2共存时输出空值的问题

看起来你遇到的是典型的多设备共存时的资源冲突或电源/时序问题——毕竟电机驱动和传感器都依赖I2C总线,而且电机运行时的电流波动很容易影响敏感的传感器。结合你说的“简易电机代码里传感器正常”,我整理了几个优先级最高的排查方向:

1. 调整初始化顺序,优先确保传感器完成I2C注册

Adafruit Motor Shield v2和LIS3DH默认都用I2C通信,但电机驱动的初始化可能会占用总线或者干扰传感器的初始化流程。试试把LIS3DH的初始化放在电机 shield 之前,让传感器先完成总线注册,再启动电机驱动:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_Sensor.h>

// 先声明传感器对象
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
// 再声明电机 shield 对象
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);

void setup() {
  Serial.begin(9600);
  
  // 先初始化传感器
  if (!lis.begin(0x18)) { // 根据你的LIS3DH SDO引脚调整地址,0x18是SDO接地的默认值
    Serial.println("Couldnt start LIS3DH!");
    while (1);
  }
  lis.setRange(LIS3DH_RANGE_2_G);
  
  // 再初始化电机 shield
  if (!AFMS.begin()) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  myMotor->setSpeed(150);
}

2. 排查电源稳定性,避免电机电流干扰传感器

电机启动时的大电流会拉低电源电压,很可能导致LIS3DH因供电不足无法正常通信:

  • 确保Motor Shield v2使用外部独立电源给电机供电(不要只靠Arduino的USB供电),并且外部电源的地和Arduino的地连接在一起(必须共地)。
  • 如果LIS3DH当前接的是Arduino的5V引脚,试试改接3.3V引脚(LIS3DH原生支持3.3V供电),避开电机电流波动影响传感器的电源回路。
  • 可以在LIS3DH的VCC引脚和GND之间并联一个100uF电解电容+0.1uF陶瓷电容,滤除电源噪声。

3. 替换阻塞式电机控制,给传感器留足读取时间

如果你的电机控制代码用了delay()或者阻塞式的编码器计数循环,会导致LIS3DH的读取请求被长时间延迟,最终超时返回空值:

  • 把阻塞式逻辑改成非阻塞式(用millis()代替delay(),或者用中断处理编码器计数),确保传感器读取代码能定期执行:
unsigned long previousMillis = 0;
const long motorRunDuration = 2000; // 电机运行2秒
bool motorRunning = false;

void loop() {
  unsigned long currentMillis = millis();
  
  // 非阻塞电机控制逻辑
  if (motorRunning && currentMillis - previousMillis >= motorRunDuration) {
    myMotor->run(RELEASE);
    motorRunning = false;
  }
  
  // 定期读取传感器数据
  sensors_event_t event;
  lis.getEvent(&event);
  Serial.print("X: "); Serial.print(event.acceleration.x);
  Serial.print(" Y: "); Serial.print(event.acceleration.y);
  Serial.print(" Z: "); Serial.println(event.acceleration.z);
  
  delay(100); // 短延迟不影响,避免频繁打印占用串口
}

4. 扫描I2C总线,确认两个设备都能被检测到

用I2C扫描工具验证总线通信是否正常,确保电机 shield 和LIS3DH都能被识别:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial); // 等待串口连接
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16) Serial.print("0");
      Serial.print(address,HEX);
      Serial.println(" !");
      nDevices++;
    }
  }
  if (nDevices == 0) Serial.println("No I2C devices found\n");
  else Serial.println("done\n");
  delay(5000); // 每5秒扫描一次
}

如果其中一个设备没被检测到,检查接线(比如LIS3DH的SDA/SCL是否接对Arduino的A4/A5),或者确认设备地址是否被修改过(Motor Shield默认0x60,LIS3DH默认0x18/0x19)。


内容的提问来源于stack exchange,提问作者Luke Matkovic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:16:26