14695|33

9792

帖子

24

TA的资源

版主

楼主
 

使用lis3dsh加速度传感器计算倾角 [复制链接]

 
 使用3轴加速度传感器lis3dsh读取加速度数据,转换成倾角程序
单片机使用MSP430FR5969软I2C



单片机程序
  1. /*******************************************************************************
  2. * Copyright (C), 2017, XiaCheDan Tech. Co., Ltd.
  3. * FileName: main.c
  4. * Author: littleshrimp
  5. * Version : 1.0
  6. * Date:  2017-06-25 13:55
  7. * Description:
  8. * Function List: //
  9. * 1. -------
  10. * History:
  11. * <author>   <time>                <version >  <desc>
  12. * littleshrimp      2017-06-25 13:55        build this moudle
  13. ******************************************************************************/
  14. /*

  15.               MSP430FR5969
  16.             -----------------
  17.            |     P2.0/UCA0TXD|----> PC
  18.            |                 |
  19.            |                 |
  20.            |     P2.1/UCA0RXD|<---- PC
  21.            |                 |
  22.   SCL --o--|P3.5             |
  23.            |                 |
  24.   SDA --o--|P3.6             |

  25. */
  26. /*******************************************************************************
  27. *  * INCLUDES
  28. *  */

  29. #include "msp430.h"
  30. #include <stdio.h>
  31. #include <math.h>
  32. #include <stdint.h>
  33. #include "uart.h"
  34. #include "soft_i2c.h"
  35. #include "timer.h"
  36. /*******************************************************************************
  37. *  * MACROS
  38. *  */

  39. /*******************************************************************************
  40. *  * CONSTANTS
  41. *  */
  42. #define BASE64        0
  43. #define STRING        1
  44. /*******************************************************************************
  45. *  * TYPEDEFS
  46. *  */

  47. /*******************************************************************************
  48. *  * GLOBAL VARIABLES
  49. *  */

  50. /*******************************************************************************
  51. *  * EXTERNAL VARIABLES
  52. *  */

  53. /*******************************************************************************
  54. *  * EXTERNAL FUNCTIONS
  55. *  */

  56. /*******************************************************************************
  57. *  * LOCAL VARIABLES
  58. *  */
  59.   
  60. uint8_t data[3];
  61. uint16_t temp_code;
  62. float temperature;
  63. uint8_t crc;
  64. /*******************************************************************************
  65. *  * PROFILE CALLBACKS
  66. *  */

  67. /*******************************************************************************
  68. *  * LOCAL FUNCTIONS
  69. *  */

  70. /*******************************************************************************
  71. *  * PUBLIC FUNCTIONS
  72. *  */

  73.    
  74.    
  75. #define LIS3DSH_SLAVE_ADDR     (0x1E << 1)//7bit
  76. #define LIS3DSH_WHO_I_AM       0x0F
  77. #define LIS3DSH_OUT_T          0x0C
  78. #define LIS3DSH_STATUS         0x27
  79. #define LIS3DSH_CTRL_REG4      0x20
  80. #define LIS3DSH_CTRL_REG3      0x23
  81. #define LIS3DSH_CTRL_REG5      0x24
  82. #define LIS3DSH_CTRL_REG6      0x25
  83. uint8_t buf[10];
  84. void lis3dsh_init(void)
  85. {  
  86.     uint8_t data;
  87.     i2c_init();//初始化I2C
  88.     i2c_read_n_byte(LIS3DSH_SLAVE_ADDR,LIS3DSH_WHO_I_AM,&buf[0],1);
  89. //    data = 0x17;//0001:3.125Hz 0:continuous update 111:x,y,z enable
  90.     data = 0x97;//1001:1600Hz 0:continuous update 111:x,y,z enable
  91.     i2c_write_n_byte(LIS3DSH_SLAVE_ADDR,LIS3DSH_CTRL_REG4,&data,1);
  92.     i2c_read_n_byte(LIS3DSH_SLAVE_ADDR,LIS3DSH_OUT_T,&buf[1],1);
  93.     i2c_read_n_byte(LIS3DSH_SLAVE_ADDR,LIS3DSH_STATUS,&buf[2],7);
  94. }
  95. void dco_init(void)
  96. {  
  97.   // Configure one FRAM waitstate as required by the device datasheet for MCLK
  98.   // operation beyond 8MHz _before_ configuring the clock system.
  99.   FRCTL0 = FRCTLPW | NWAITS_1;

  100.   // Clock System Setup
  101.   CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
  102.   CSCTL1 = DCORSEL | DCOFSEL_4;             // Set DCO to 16MHz
  103.   CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set SMCLK = MCLK = DCO,
  104.                                             // ACLK = VLOCLK
  105.   CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
  106.   CSCTL0_H = 0;                             // Lock CS registers
  107. }
  108. int main( void )
  109. {
  110.   uint32_t i = 0;
  111.   float x = 0,y = 0,z = 0;
  112.   float ax,ay,az;
  113.   uint8_t status;
  114.   char inBuf[64];//base64缓存
  115.   char outBuf[64];//base64缓存
  116.   WDTCTL = WDTPW + WDTHOLD;//停止看门狗
  117.   PM5CTL0 &= ~LOCKLPM5;//这个是一定要加的,不然GPIO不能使用
  118.   dco_init();
  119.   lis3dsh_init();
  120.   uart_init();
  121.   while(1)
  122.   {
  123.    
  124.     i2c_read_n_byte(LIS3DSH_SLAVE_ADDR,LIS3DSH_STATUS,&buf[2],7);

  125. #if (BASE64 == 1)    //base 64输出
  126.     base64_encode((const uint8_t *)(&buf[2]),outBuf,7); //做BASE64转换
  127.     uart_tx_string(outBuf);//输出到PC
  128.     uart_tx_string("\r\n");//换行
  129. #elif (STRING == 1)       //字符串输出    status = buf[2];//status
  130.     ax = (buf[3] + (buf[4] << 8)) * 0.06 + 2;
  131.     ay = (buf[5] + (buf[6] << 8)) * 0.06 + 2;
  132.     az = (buf[7] + (buf[8] << 8)) * 0.06 + 2;
  133.    
  134.     x = atan((float)ax/(float)sqrt(ay*ay+az*az)) * 180.00 / 3.1415926;
  135.     y = atan((float)ay/(float)sqrt(ax*ax+az*az)) * 180.00 / 3.1415926;
  136.     z = atan((float)az/(float)sqrt(ax*ax+ay*ay)) * 180.00 / 3.1415926;
  137.    
  138.     if (z < 0)
  139.     {
  140.       x= 180-x;
  141.       y= 180-y;
  142.     }
  143.    
  144.     sprintf(outBuf,"angle:\tx=%.2f\ty=%.2f\tz=%.2f\r\n",x,y,z);
  145. //    sprintf(outBuf,"%d",i++);
  146.     uart_tx_string(outBuf);//输出到PC
  147.     uart_tx_string("\r\n");//换行
  148.     sleep(650);
  149. #else                      //二进制输出
  150.     outBuf[0] = 0x55;
  151.     outBuf[1] = buf[4];
  152.     outBuf[2] = buf[3];
  153.     outBuf[3] = buf[6];
  154.     outBuf[4] = buf[5];
  155.     outBuf[5] = buf[8];
  156.     outBuf[6] = buf[7];
  157.     uart_tx_bytes(outBuf,7);//输出到PC
  158. #endif
  159.   }
  160. }
复制代码


上位机演示
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Drawing.Drawing2D;
  10. using System.IO.Ports;
  11. using System.Threading;

  12. namespace 倾角演示
  13. {
  14.     public partial class Form1 : Form
  15.     {
  16.         Bitmap bmp = new Bitmap(Image.FromFile("img.png"));
  17.         SerialPort serialPort = new SerialPort();//串口
  18.         public Form1()
  19.         {
  20.             InitializeComponent();
  21.             UpdateSerialPorts();
  22.         }
  23.         void UpdateSerialPorts()
  24.         {
  25.             String[] ports = System.IO.Ports.SerialPort.GetPortNames();//获得全部串口
  26.             if (ports.Length == 0) return;//如果串口数量为0退出
  27.             comboBox1.Items.Clear();//清除原有comboBox中的数据后重新添加
  28.             comboBox1.Items.AddRange(ports);//添加串口
  29.             comboBox1.Text = ports[ports.Length - 1];//设置显示最后一个串口
  30.         }
  31.         /// <summary>
  32.         /// 以逆时针为方向对图像进行旋转
  33.         /// </summary>
  34.         /// <param name="b">位图流</param>
  35.         /// <param name="angle">旋转角度[0,360](前台给的)</param>
  36.         /// <returns></returns>
  37.         public Bitmap Rotate(Bitmap b, int angle)
  38.         {
  39.             angle = angle % 360;

  40.             //弧度转换
  41.             double radian = angle * Math.PI / 180.0;
  42.             double cos = Math.Cos(radian);
  43.             double sin = Math.Sin(radian);

  44.             //原图的宽和高
  45.             int w = b.Width;
  46.             int h = b.Height;
  47.             int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));
  48.             int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));

  49.             //目标位图
  50.             Bitmap dsImage = new Bitmap(W, H);
  51.             Graphics g = Graphics.FromImage(dsImage);

  52.             //计算偏移量
  53.             Point Offset = new Point((W - w) / 2, (H - h) / 2);

  54.             //构造图像显示区域:让图像的中心与窗口的中心点一致
  55.             Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);
  56.             Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
  57.             g.TranslateTransform(center.X, center.Y);
  58.             g.RotateTransform(360 - angle);

  59.             //恢复图像在水平和垂直方向的平移
  60.             g.TranslateTransform(-center.X, -center.Y);
  61.             g.DrawImage(b, rect);

  62.             //重至绘图的所有变换
  63.             g.ResetTransform();

  64.             g.Save();
  65.             g.Dispose();
  66.             return dsImage;
  67.         }
  68.         private void Form1_Load(object sender, EventArgs e)
  69.         {
  70.             pictureBox1.Image = bmp;
  71.         }
  72.         int i = 0;
  73.         private void button1_Click(object sender, EventArgs e)
  74.         {
  75.             serialPort.PortName = comboBox1.Text;//串口名为当前comboBox的本
  76.             serialPort.BaudRate = 115200;//速率
  77.             serialPort.DataBits = 8;//停止位
  78.             serialPort.Parity = System.IO.Ports.Parity.None;
  79.             serialPort.StopBits = System.IO.Ports.StopBits.One;
  80.             serialPort.Handshake = System.IO.Ports.Handshake.None;
  81. //            serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
  82.             serialPort.Open();//打开串口
  83.             timer1.Enabled = true;
  84.         }

  85.         private void comboBox1_DropDown(object sender, EventArgs e)
  86.         {
  87.             UpdateSerialPorts();
  88.         }
  89.         public void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
  90.         {
  91.         }
  92.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  93.         {
  94.             Application.Exit();//退出
  95.             System.Environment.Exit(0);//退出时关闭所有线程
  96.         }

  97.         private void timer1_Tick(object sender, EventArgs e)
  98.         {
  99.             float x = 0, y = 0, z = 0;
  100.             try
  101.             {
  102.                 if (serialPort.BytesToRead < 10) return;
  103.                 string str = serialPort.ReadLine();
  104.                 string[] s = str.Split('\t');
  105.                 if (s.Length >= 4)
  106.                 {
  107.                     s[1] = s[1].Replace("x=", "");
  108.                     s[2] = s[2].Replace("y=", "");
  109.                     s[3] = s[3].Replace("z=", "");
  110.                     s[3] = s[3].Replace("\r", "");
  111.                     s[3] = s[3].Replace("\n", "");
  112.                     x = float.Parse(s[1]);
  113.                     y = float.Parse(s[2]);
  114.                     z = float.Parse(s[3]);
  115.                     pictureBox1.BeginInvoke((ThreadStart)delegate
  116.                     {
  117.                         pictureBox1.Image = Rotate(bmp, (int)y);
  118.                         pictureBox1.Refresh();
  119.                     });
  120.                 }
  121.             }
  122.             catch (Exception ex)
  123.             {
  124.             }
  125.         }
  126.     }
  127. }
复制代码



最新回复

感谢楼主分享,目前正在搞这个东西。   详情 回复 发表于 2020-12-10 10:58
点赞(1) 关注(3)
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 
又开始玩430了?
 
 
 

回复

721

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
 
 
 

回复

9792

帖子

24

TA的资源

版主

4
 
dcexpert 发表于 2017-6-25 14:41
又开始玩430了?

430用起来方便
 
 
 

回复

4177

帖子

9

TA的资源

五彩晶圆(高级)

5
 
还记得ST的F072 discovery的板子上有个L3GD20,这个是个三轴的Gyro,我上次弄了一半,还没完全弄好。但是,事情多,后面就先丢一边就没有分享了。。。。
 
 
 

回复

9792

帖子

24

TA的资源

版主

6
 
huaiqiao 发表于 2017-6-26 09:46
还记得ST的F072 discovery的板子上有个L3GD20,这个是个三轴的Gyro,我上次弄了一半,还没完全弄好。但是, ...

我开始是想弄个ST的9轴或者6轴玩的,在淘宝上找了一下模块都挺贵的
样品也不太好申请
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

17

帖子

0

TA的资源

一粒金砂(初级)

7
 
 
 
 

回复

5261

帖子

239

TA的资源

管理员

8
 
迟到的顶帖,这个驱动是你自己写的吗?

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

5261

帖子

239

TA的资源

管理员

9
 
顺便推荐一下这个资源

LIS3DSH(三轴加速度计)驱动例程ver1.1
https://bbs.eeworld.com.cn/thread-544224-1-1.html
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

9792

帖子

24

TA的资源

版主

10
 
nmg 发表于 2017-7-17 11:04
迟到的顶帖,这个驱动是你自己写的吗?

只对传感器做了简单配置
 
 
 

回复

297

帖子

0

TA的资源

一粒金砂(中级)

11
 
顶一下
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

12
 
您好,楼主,可以把pc体态展示软件或者源码共享下吗,谢谢,sun.wei162@zte.com.cn
 
 
 

回复

9792

帖子

24

TA的资源

版主

13
 
JimmyKudo 发表于 2018-7-26 16:51
您好,楼主,可以把pc体态展示软件或者源码共享下吗,谢谢,sun.wei162@zte.com.cn

3.csharp demo.rar (100.02 KB, 下载次数: 73)
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

14
 
感谢蛋总
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

15
 
不是静止或者匀速运动情况下用加速度计计算角度是不准确的吧,一般不会这样计算吧
 
 
 

回复

9792

帖子

24

TA的资源

版主

16
 
381503442 发表于 2018-8-15 15:42
不是静止或者匀速运动情况下用加速度计计算角度是不准确的吧,一般不会这样计算吧

这要看希望达到什么样的精度
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

17
 
littleshrimp 发表于 2018-8-15 16:06
这要看希望达到什么样的精度

目前需要做运动手表上抬手亮屏和翻手亮屏的算法,原理上参考传感器自带的用加速度计直接计算角度然后比较旋转角度的方式,但是考虑到运动特别是跑动运动时这种方式计算的角度肯定有误差,不知道版主能否评估下这种误差是否在可接受的范围内,谢谢
 
 
 

回复

9792

帖子

24

TA的资源

版主

18
 
381503442 发表于 2018-8-15 18:47
目前需要做运动手表上抬手亮屏和翻手亮屏的算法,原理上参考传感器自带的用加速度计直接计算角度然后比较 ...

我没有相应的环境没法帮你评估不同运动模式对AWT功能的影响
你可以参考一下这个文档的第72页,尝试一下不同的配置试试
https://www.st.com/resource/en/application_note/dm00402563.pdf
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

19
 
littleshrimp 发表于 2018-8-16 10:25
我没有相应的环境没法帮你评估不同运动模式对AWT功能的影响
你可以参考一下这个文档的第72页,尝试一下 ...

你好,我用LIS2DS12三轴位移加速度推算倾角,再有外力作用下,角度和实际偏差比较大(附件拍了视频),请问如果用三轴角加速度,即陀螺仪,推算倾角是不是没有这个问题?
目前需求:一个物体常态是水平的,当这个物体倾斜大于15度(可设置)时,传感器能产生一个中断信号,我大概评估下位移加速度传感器不太好实现(需要超低功耗,mcu休眠,mems中断唤醒方式,需要mems支持配置角度达到阈值产生硬件中断),请教下,ST那款mems比较合适,陀螺仪可以做到吗?功耗有100uA以下的吗?谢谢~

LIS2DS12倾角推算.part1.rar

14 MB, 下载次数: 101

LIS2DS12倾角推算.part2.rar

8.42 MB, 下载次数: 32

 
 
 

回复

9792

帖子

24

TA的资源

版主

20
 
JimmyKudo 发表于 2018-9-4 23:32
你好,我用LIS2DS12三轴位移加速度推算倾角,再有外力作用下,角度和实际偏差比较大(附件拍了视频),请 ...

角速度传感器(陀螺仪)一搬功耗比较大,检测倾角需要很高的速率,再加上MCU处理,100uA肯定做不到
角速度传感器测倾角还存在长期漂移问题,也不是很适合
加速度传感器是测量倾角的理想选择,使用集成AWT功能的传感器还可以省去MCU的功耗
https://bbs.eeworld.com.cn/forum ... hlight=%B7%AD%CD%F3
在有振动的环境里(例如检测快递车里的快递倾斜角度)会受振动影响
解决办法可以使用大一点的量程(会牺牲分辨率),使用高一点的输出速率(牺牲功耗),再使用MCU对采集到的数据做处理(牺牲功耗)通过算法消除外力的影响,做好了功耗应该可以控制在100uA以内。
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表