使用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
相关产品推荐
相关产品推荐

