【问题标题】:Serial communication not working when class is instantiated in Arduino Environment在 Arduino 环境中实例化类时串行通信不起作用
【发布时间】:2014-12-24 15:00:29
【问题描述】:

我正在尝试为我的 Arduino Mega 编写代码,以使用 c++ 样式库与 ADXL345 加速度计进行通信。 这是我的 Accelerometer.h 文件:

#include <Wire.h>
#define ADXL345 (0x53) // I2C Address of ADXL345 accelerometer

struct Acceleration
{
    float x;
    float y;
    float z;
};

class Accelerometer
{
  public:
    Accelerometer(void);              // Constructor
    Acceleration readData(void);                  // Read sensor data
  private:
    char buffer[6];   // Buffer to store data (x, y, z: LSB and MSB of each)
    char DATA_FORMAT; // Address of DATA_FORMAT Register
    char POWER_CTL;   // Address of POWER_CTL Register
    char DATAX0;      // Address of X-Axis LSB Data
    char DATAX1;      // Address of X-Axis MSB Data
    char DATAY0;      // Address of Y-Axis LSB Data
    char DATAY1;      // Address of Y-Axis MSB Data
    char DATAZ0;      // Address of Z-Axis LSB Data
    char DATAZ1;      // Address of Z-Axis MSB Data
    void writeToAccelerometer(char address, char value);
    void readFromAccelerometer(char address, int numOfBytes);
};

这是我的 Accelerometer.cpp 文件:

#include "Accelerometer.h"
#include <Wire.h>

Accelerometer::Accelerometer()
{
  Wire.begin();                                // Initialize I2C bus
  writeToAccelerometer(DATA_FORMAT, 0x01);     // +/- 4g range 
  writeToAccelerometer(POWER_CTL, 0x08);       // Measurement Mode

  DATA_FORMAT = 0x31;      // Address of DATA_FORMAT Register
  POWER_CTL   = 0x2D;      // Address of POWER_CTL Register
  DATAX0      = 0x32;      // Address of X-Axis LSB Data
  DATAX1      = 0x33;      // Address of X-Axis MSB Data
  DATAY0      = 0x34;      // Address of Y-Axis LSB Data
  DATAY1      = 0x35;      // Address of Y-Axis MSB Data
  DATAZ0      = 0x36;      // Address of Z-Axis LSB Data
  DATAZ1      = 0x37;      // Address of Z-Axis MSB Data
}

void Accelerometer::writeToAccelerometer(char address, char value) 
{
  Wire.beginTransmission(ADXL345); // start transmission to ADXL345 
  Wire.write(address);             // send register address
  Wire.write(value);               // send value to write
  Wire.endTransmission();          // end transmission
}

void Accelerometer::readFromAccelerometer(char address, int numOfBytes)
{
  Wire.beginTransmission(ADXL345); // start transmission to ADXL345 
  Wire.write(address);             // send register address
  Wire.endTransmission();          // end transmission

  Wire.beginTransmission(ADXL345);          // start transmission to ADXL345
  Wire.requestFrom(ADXL345, numOfBytes);    // request some bytes from device

  int i = 0;
  while(Wire.available())           // while there is data
  { 
    buffer[i] = Wire.read();        // receive a byte and save it in the buffer
    i++;
  }
  Wire.endTransmission();           // end transmission
}

Acceleration Accelerometer::readData()
{
  Acceleration R;
  readFromAccelerometer(DATAX0, 6);          // Read data from sensor

  // Merge of data and conversion to int format
  int x_acceleration = (((int)buffer[1]) << 8) | buffer[0];
  int y_acceleration = (((int)buffer[3]) << 8) | buffer[2];
  int z_acceleration = (((int)buffer[5]) << 8) | buffer[4];

  R.x = x_acceleration*0.0078;
  R.y = x_acceleration*0.0078;
  R.z = x_acceleration*0.0078;

  return R;
}

我在我的 Arduino 草图中使用这个库和这段代码:

#include <Wire.h>
#include "Accelerometer.h"

Accelerometer accel;
Acceleration Racc;

void setup()
{
  Serial.begin(9600);   // Start serial for outbut at 9600 bps
}

void loop()
{
  Racc = accel.readData();

  // Print data
  Serial.print("ACCELERATION - X: ");
  Serial.print( Racc.x );
  Serial.print(" G / Y: ");
  Serial.print( Racc.y );
  Serial.print(" G / Z: ");
  Serial.print( Racc.z );
  Serial.print(" G\n");

  delay(100);
}

此代码编译无误。但是,由于 Accelerometer 类的实例化,串行通信无法正常工作(我在串行监视器中看不到任何文本)。当我删除代码的类实例(只让代码中的串行通信)时,我可以看到串行监视器中打印的内容。

有人知道发生了什么吗?我将不胜感激。

【问题讨论】:

    标签: c++ arduino


    【解决方案1】:

    由于 ADXL345 可以运行 SPI 或 I2C,因此需要对其进行配置。在您尝试将其用作 I2C 的情况下,ADXL345 的 CS 需要连接到 3.3V

    如果 CS 引脚高电平连接到 VDD I/O,则启用 I2C 模式。 CS引脚 应始终将高电平连接到 VDD I/O 或由外部驱动 控制器,因为如果留下 CS 引脚,则没有默认模式 未连接。因此,不采取这些预防措施可能会导致 无法与部件交流。

    在您上面的代码中,我没有看到任何配置为输出以驱动 CS 的引脚。

    根据我的经验,当 I2C (wire.h) 库未正确连接到设备时,它可能会阻塞。这与您在此处描述的症状相似。


    您可能希望针对其他人引用您的代码,例如https://github.com/jenschr/Arduino-libraries/tree/master/ADXL345。它似乎完全支持 I2C 上的 ADXL345 的许多功能

    【讨论】:

    • 我可能还想为“while(Wire.available())”添加一个最大超时,这样它就不会永远阻塞。如果 I2C 不能正常工作。
    • 感谢您的回答。我犯了一个愚蠢的错误——在为 DATA_FORMAT 和 POWER_CTL 赋值之前,我在构造函数中调用了 writeToAccelerometer 方法。我解决了这个问题(之前完成了作业),但它仍然无法正常工作。关于 CS 的这种考虑,我将引脚 53 定义为输出并设置为 digitalWrite(53, HIGH);。这够了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多