esp32s ADXL345调试

2019-04-17  本文已影响0人  大道至简非简

1、相关环境及组件

esp32参考前几篇文章。
https://github.com/adafruit/Adafruit_ADXL345
需要补充此库;

image.png
https://github.com/adafruit/Adafruit_Sensor
下载Adafruit_Sensor.h,复制到
image.png

adxl345是adxl335的升级版,精度更高些。
官网地址:https://www.analog.com/cn/products/adxl345.html#product-documentation
模块比对如下
https://www.analog.com/cn/parametricsearch/11175

image.png

ADXL345三轴加速度采用ADXL345芯片,具有体积小,功耗低的特点,
13位数字精度分辨能够测量超过±16g的加速度变换。
信号输出为16位数字输出,可以通过SPI与I2C接口实现信号采集。
ADXL345适用于倾斜角度测量,能够进行静态重力加速度检测。同时也适用于运动状态的追踪,测量运动或冲击过程造成的瞬时加速度。其高分辨率(4mg/LSB)使之能够感应变化小于1°的倾斜角度。
DFrobot的ADXL345三轴加速度计还内置一款LDO模块让你的加速度计能够工作于3.3~6v的工作电压之下。
传感器提供了几个特殊的功能。能够在静态或动态情况下检测是否有运动或停止出现,另外能够感知单轴的加速度值是否超出用户的设定值。检测单击/双击。如果该设备正在下降,能进行自由落体感应检测。这些功能能够被映射到两个中断输出引脚上。
在低功耗模式是用户能够基于ADXL345动作感应,进行电源管理,同时只损耗极低的功耗。

2、连接方式

image.png
image.png

对应esp32s开发板针脚如图,两个红框内容。


image.png

3、核心代码

可自行修改在mcu判断数据后上传给服务器,数据量小适合采用mqtt方式。

//adxl345相关依赖库
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>



//变量定义----------------------------bigen

//定义传感器ID,123456序号
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);


//变量定义--------------------------------end


//函数定义----------------------------bigen

//显示传感器明细信息
void displaySensorDetails(void)
{
  sensor_t sensor;
  //  获取传感器信息
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  //  传感器名称
  Serial.print ("Sensor: "); Serial.println(sensor.name);
  //  传感器版本
  Serial.print ("Driver Ver: "); Serial.println(sensor.version);
  //  传感器ID
  Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
  //  数据最大值
  Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  //  数据最小值
  Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  //  解析度
  Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" m/s^2");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}


//显示传感器数据速率
void displayDataRate(void)
{
  Serial.print ("Data Rate: ");
  switch (accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print ("3200 ");
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print ("1600 ");
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print ("800 ");
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print ("400 ");
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print ("200 ");
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print ("100 ");
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print ("50 ");
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print ("25 ");
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print ("12.5 ");
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print ("6.25 ");
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print ("3.13 ");
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print ("1.56 ");
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print ("0.78 ");
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print ("0.39 ");
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print ("0.20 ");
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print ("0.10 ");
      break;
    default:
      Serial.print ("???? ");
      break;
  }
  Serial.println(" Hz");
}

//显示重力数据精度范围
void displayRange(void)
{
  Serial.print ("Range: +/- ");

  switch (accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print ("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print ("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print ("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print ("2 ");
      break;
    default:
      Serial.print ("?? ");
      break;
  }
  Serial.println(" g");
}

//初始化串口
void setupSerial() {
  //  初始化默认串口
  Serial.begin(115200);

}

//初始化传感器
void initSensor() {
  // 启动传感器
  if (!accel.begin())
  {
    //    检测不到给予提示,可自行修改信息
    Serial.println("no ADXL345 detected ... Check your wiring!");
    while (1);
  }

  //设置传感器精度
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

}



//函数定义--------------------------------end




//主程序----------------------------bigen
void setup(void)
{
  //  初始化串口
  setupSerial();
  delay(1000);
  //  初始化传感器
  initSensor();
  delay(1000);
  //  显示传感器明细信息
  displaySensorDetails();

  //  显示传感器速度
  displayDataRate();

  //  显示传感器范围
  displayRange();

  Serial.println("");

}

void loop(void)
{
  //  定义x/y/z重力单元值
  double Axout, Ayout, Azout;
  //定义倾斜度
  double theta, psy, phi;
  //  定义偏转度
  double  roll, pitch, yaw;
  Serial.println();

  //  定义传感器事件
  sensors_event_t event;
  //  获取传感器数据
  accel.getEvent(&event);


  //获取x/y/z重力单元值
  Axout = event.acceleration.x;
  Ayout = event.acceleration.y;
  Azout = event.acceleration.z;

  Serial.print("Axout = ");
  Serial.print(Axout);
  Serial.print("\t\t");
  Serial.print("Ayout = ");
  Serial.print(Ayout);
  Serial.print("\t\t");
  Serial.print("Azout = ");
  Serial.print(Azout);
  Serial.print("\t\t");
  Serial.println();


  //计算偏离角度,公式参考原理说明
  theta = atan(Axout / (sqrt((pow (Ayout, 2.0)) + (pow (Azout, 2.0))))) * 57.29577951;
  psy =  atan(Ayout / (sqrt((pow (Axout, 2.0)) + (pow (Azout, 2.0))))) * 57.29577951;
  phi =  atan((sqrt((pow (Ayout, 2.0)) + (pow (Axout, 2.0)))) / Azout) * 57.29577951;

  Serial.print("theta = ");
  Serial.print(theta);
  Serial.print("\t\t");
  Serial.print("psy = ");
  Serial.print(psy);
  Serial.print("\t\t");
  Serial.print("phi = ");
  Serial.print(phi);
  Serial.print("\t\t");
  Serial.println();

  //计算旋转角度,公式参考原理说明
  roll = (atan2(Ayout, Azout)) * 57.29577951 + 180;
  pitch =  (atan2(Azout, Axout)) * 57.29577951 + 180;
  yaw =  (atan2(Axout, Ayout)) * 57.29577951 + 180;

  Serial.print("roll = ");
  Serial.print(roll);
  Serial.print("\t\t");
  Serial.print("pitch = ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.print("pitch = ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.println();

  //间隔1秒采集一次
  delay(1000);
}

//主程序--------------------------------end

4、测试输出

移动传感器模块效果如下:


theta = 49.58       psy = -26.35        phi = -61.79        
roll = 43.20        pitch = 148.17      pitch = 148.17      
[17:58:35.016] 
Axout = 8.24        Ayout = 3.10        Azout = -4.12       
theta = 57.97       psy = 18.60     phi = -64.92        
roll = 323.04       pitch = 153.43      pitch = 153.43      
[17:58:36.017] 
Axout = -0.12       Ayout = -6.16       Azout = -11.14      
theta = -0.53       psy = -28.93        phi = -28.94        
roll = 28.93        pitch = 89.39       pitch = 89.39       
[17:58:37.017] 
[17:58:37.027] Axout = -4.82        Ayout = -0.27       Azout = -8.94       
theta = -28.33      psy = -1.55     phi = -28.38        
roll = 1.76     pitch = 61.65       pitch = 61.65       
[17:58:38.026] 
Axout = -0.31       Ayout = 1.22        Azout = -9.96       
theta = -1.79       psy = 6.95      phi = -7.18     
roll = 353.04       pitch = 88.20       pitch = 88.20       
[17:58:39.027] 
Axout = 1.49        Ayout = 1.14        Azout = -9.73       
theta = 8.65        psy = 6.59      phi = -10.91        
roll = 353.33       pitch = 98.71       pitch = 98.71       
[17:58:40.027] 
[17:58:40.037] Axout = 2.79     Ayout = 0.51        Azout = -9.61       
theta = 16.14       psy = 2.92      phi = -16.42        
roll = 356.96       pitch = 106.16      pitch = 106.16      
[17:58:41.039] 
Axout = 3.14        Ayout = 0.75        Azout = -9.53       
theta = 18.17       psy = 4.25      phi = -18.69        
roll = 355.53       pitch = 108.22      pitch = 108.22      
[17:58:41.050] 
[17:58:42.037] 
Axout = 3.33        Ayout = 0.67        Azout = -9.38       
theta = 19.53       psy = 3.83      phi = -19.94        
roll = 355.93       pitch = 109.58      pitch = 109.58      
[17:58:43.037] 
[17:58:43.046] Axout = 2.79     Ayout = 0.82        Azout = -9.61       
theta = 16.11       psy = 4.71      phi = -16.82        
roll = 355.10       pitch = 106.16      pitch = 106.16      
[17:58:44.047] 
Axout = 1.22        Ayout = 0.67        Azout = -9.92       
theta = 6.97        psy = 3.82      phi = -7.96     
roll = 356.16       pitch = 96.99       pitch = 96.99       


5、nb_iot上报思路

esp32默认3个串口,开发板默认0串口接了usb;


image.png

采用uart1跟nb_iot sim7020连接;模块连接

//adxl345相关依赖库
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>



//变量定义----------------------------bigen

//定义传感器ID,123456序号
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

//定义通讯串口
HardwareSerial swSer(1);

//定义mqtt服务器ip和端口,ip需要用自己指定域名
extern const char    *kMqttServerAddress = "XX.XX.XX.XX";
extern const uint16_t kMqttServerPort    = 1883;


//设备mac地址
char Mac_Address[18];


//变量定义--------------------------------end


//函数定义----------------------------bigen

//显示传感器明细信息
void displaySensorDetails(void)
{
  sensor_t sensor;
  //  获取传感器信息
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  //  传感器名称
  Serial.print ("Sensor: "); Serial.println(sensor.name);
  //  传感器版本
  Serial.print ("Driver Ver: "); Serial.println(sensor.version);
  //  传感器ID
  Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
  //  数据最大值
  Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  //  数据最小值
  Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  //  解析度
  Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" m/s^2");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}


//显示传感器数据速率
void displayDataRate(void)
{
  Serial.print ("Data Rate: ");
  switch (accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print ("3200 ");
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print ("1600 ");
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print ("800 ");
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print ("400 ");
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print ("200 ");
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print ("100 ");
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print ("50 ");
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print ("25 ");
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print ("12.5 ");
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print ("6.25 ");
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print ("3.13 ");

      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print ("1.56 ");
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print ("0.78 ");
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print ("0.39 ");
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print ("0.20 ");
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print ("0.10 ");
      break;
    default:
      Serial.print ("???? ");
      break;
  }
  Serial.println(" Hz");
}

//显示重力数据精度范围
void displayRange(void)
{
  Serial.print ("Range: +/- ");

  switch (accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print ("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print ("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print ("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print ("2 ");
      break;
    default:
      Serial.print ("?? ");
      break;
  }
  Serial.println(" g");
}

//初始化串口
void setupSerial() {
  //  初始化默认串口
  Serial.begin(115200);
  delay(500);
  //  初始化串口1
  swSer.begin(115200, SERIAL_8N1, 4, 5);
  delay(1000);


}

//初始化传感器
void initSensor() {
  // 启动传感器
  if (!accel.begin())
  {
    //    检测不到给予提示,可自行修改信息
    Serial.println("no ADXL345 detected ... Check your wiring!");
    while (1);
  }

  //设置传感器精度
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

}

//获取默认mac地址作为设备标示
void getMacAddress() {
  uint8_t mac0[6];
  //  获取默认mac地址
  esp_efuse_mac_get_default(mac0);
  //  Serial.printf("Default Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac0[0], mac0[1], mac0[2], mac0[3], mac0[4], mac0[5]);
  // 把mac地址转成字符串
  sprintf (Mac_Address, "%02X%02X%02X%02X%02X%02X",  mac0[0], mac0[1], mac0[2], mac0[3], mac0[4], mac0[5]);


}

//连接mqtt服务器
void initMqtt() {

  //  发送at判断通讯设备状态
  Serial.println("AT\r\n");
  swSer.println("AT\r\n");
  ShowSerialData();
  delay(1000);
  //  作业:需要根据at返回状态判断是否执行下一步,如果连不上需要重启,重启采用 ESP.restart()命令

  //   建立mqtt通道
  Serial.println("AT+CMQNEW=\"" + String(kMqttServerAddress)  + "\",\"" + kMqttServerPort + "\",12000,1024\r\n");
  swSer.println("AT+CMQNEW=\"" + String(kMqttServerAddress)  + "\",\"" + kMqttServerPort + "\",12000,1024\r\n");
  ShowSerialData();
  delay(1000);
  //  在mqtt服务器注册设备
  Serial.println("AT+CMQCON=0,3,\"" + String(Mac_Address) + "\",600,0,0\r\n");
  swSer.println("AT+CMQCON=0,3,\"" + String(Mac_Address) + "\",600,0,0\r\n");
  ShowSerialData();
  delay(1000);
}


//发送消息
void sendMqttMsg(String msg) {
  //定义消息内容变量
  String strMsg;

  //定义临时取数据存储
  char m[1024] = "";
  for (int i = 0; i < msg.length(); i++) {
    //    堆栈取数据,转16进制,不足2位左边补0
    sprintf (m, "%X", msg[i]);
    //    逐一累加到传送字段中
    strMsg += m;
  }

  Serial.println();

  Serial.print( "AT+CMQPUB=0,\"acceler_iot/" + String(Mac_Address)  + "\",1,0,0," + strMsg.length() + ",\"" + strMsg + "\"\r\n");
  swSer.print( "AT+CMQPUB=0,\"acceler_iot/" + String(Mac_Address)  + "\",1,0,0," + strMsg.length() + ",\"" + strMsg + "\"\r\n");

  ShowSerialData();
  delay(1000);


  //  需要处理不成功情况
}


//断开连接
void disconnectMqtt() {
  //  断开mqtt连接
  swSer.println("AT+CMQDISCON=0\r\n");
  ShowSerialData();
  delay(1000);
}

//输出自定义串口返回信息
void ShowSerialData()
{
  while ( swSer.available() != 0 )
    Serial.write(swSer.read());
}





//函数定义--------------------------------end




//主程序----------------------------bigen
void setup(void)
{
  //  初始化串口
  setupSerial();
  delay(1000);
  //  获取mac地址
  getMacAddress();
  delay(1000);
  //  初始化传感器
  initSensor();
  delay(1000);
  //  显示传感器明细信息
  displaySensorDetails();

  //  显示传感器速度
  displayDataRate();

  //  显示传感器范围
  displayRange();

  Serial.println();

}

void loop(void)
{
  //  定义x/y/z重力单元值
  double Axout, Ayout, Azout;
  //定义倾斜度
  double theta, psy, phi;
  //  定义偏转度
  double  roll, pitch, yaw;

  Serial.println();

  //  定义传感器事件
  sensors_event_t event;
  //  获取传感器数据
  accel.getEvent(&event);


  //获取x/y/z重力单元值
  Axout = event.acceleration.x;
  Ayout = event.acceleration.y;
  Azout = event.acceleration.z;

  Serial.print("Axout = ");
  Serial.print(Axout);
  Serial.print("\t\t");
  Serial.print("Ayout = ");
  Serial.print(Ayout);
  Serial.print("\t\t");
  Serial.print("Azout = ");
  Serial.print(Azout);
  Serial.print("\t\t");
  Serial.println();


  //计算偏离角度,公式参考原理说明
  theta = atan(Axout / (sqrt((pow (Ayout, 2.0)) + (pow (Azout, 2.0))))) * 57.29577951;
  psy =  atan(Ayout / (sqrt((pow (Axout, 2.0)) + (pow (Azout, 2.0))))) * 57.29577951;
  phi =  atan((sqrt((pow (Ayout, 2.0)) + (pow (Axout, 2.0)))) / Azout) * 57.29577951;

  Serial.print("theta = ");
  Serial.print(theta);
  Serial.print("\t\t");
  Serial.print("psy = ");
  Serial.print(psy);
  Serial.print("\t\t");
  Serial.print("phi = ");
  Serial.print(phi);
  Serial.print("\t\t");
  Serial.println();

  //计算旋转角度,公式参考原理说明
  roll = (atan2(Ayout, Azout)) * 57.29577951 + 180;
  pitch =  (atan2(Azout, Axout)) * 57.29577951 + 180;
  yaw =  (atan2(Axout, Ayout)) * 57.29577951 + 180;

  Serial.print("roll = ");
  Serial.print(roll);
  Serial.print("\t\t");
  Serial.print("pitch = ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.print("pitch = ");
  Serial.print(pitch);
  Serial.print("\t\t");
  Serial.println();






  //  连接mqtt
  initMqtt();


  //  上报内容合成字符串,用-隔开
  Serial.println();
  Serial.printf("Axout:%d_Ayout:%d_Azout:%d_theta:%d_psy:%d_phi:%d_roll:%d_pitch:%d_yaw:%d", char(Axout), char(Ayout), char(Azout), char(theta), char(psy), char(phi), char(roll), char(pitch), char(yaw));
  Serial.println();
  String msg = "-" + String(Axout) + "-" + String(Ayout) + "-"  + String(Azout) + "-"  + String(theta) + "-"  + String(psy) + "-"  + String(phi) + "-"  + String(roll) + "-"  + String(pitch) + "-"  + String(yaw);

  //上报信息
  sendMqttMsg(msg);

  //断开mqtt服务
  disconnectMqtt();

  //间隔5秒采集一次
  delay(5000);
}

//主程序--------------------------------end

上报时间可自行调整;


image.png
作业:上报正常,接受消息为空,float类型转字符类型,在mqtt传输中有问题。

at 指令的mqtt内容只能接受16进制;

//发送消息
void sendMqttMsg(String msg) {
  //定义消息内容变量
  String strMsg;

  //定义临时取数据存储,做16进制转换
  char m[1024] = "";
  for (int i = 0; i < msg.length(); i++) {
    //    堆栈取数据,转16进制
    sprintf (m, "%X", msg[i]);
    //    逐一累加到传送字段中
    strMsg += m;
  }

  Serial.println();

  Serial.print( "AT+CMQPUB=0,\"acceler_iot/" + String(Mac_Address)  + "\",1,0,0," + strMsg.length() + ",\"" + strMsg + "\"\r\n");
  swSer.print( "AT+CMQPUB=0,\"acceler_iot/" + String(Mac_Address)  + "\",1,0,0," + strMsg.length() + ",\"" + strMsg + "\"\r\n");

  ShowSerialData();
  delay(1000);


  //  需要处理不成功情况
}
image.png

效果如图

6、效果比对

需要搭建实验环境比对建立对照组比对数据,才能建立行业的数据标准。

全文完。

上一篇 下一篇

猜你喜欢

热点阅读