极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 42749|回复: 12

入手一款9轴模块,试验成功,效果不错,完美替换原来的串口6050模块!

[复制链接]
发表于 2015-1-26 23:57:56 | 显示全部楼层 |阅读模式
本帖最后由 GeekBoy 于 2015-1-26 23:57 编辑

        各位朋友,大家好,小弟新人,请多多关照。我是打算做平衡小车的,一直想找一款合适的传感器,用来测小车的姿态角度。
        之前试过6050的DMP,感觉效果不行。最近网上大家用的比较多的一款串口的6050模块,尝试了一下。有一个很大的问题就是Z轴的漂移问题,当然测量倾角的效果还是很好的,就是方向角有问题,放在那里不动还好,运动起来,就会有累积误差,只能用短时间内的两个角度只差算小车转了多少角度,店主说6050模块没有磁场,不可避免会出现累计误差,虽然理论上说小车的平衡不依赖于方向角,但是方向角一直测不准,对于我这种追求完美的偏执狂来说,总觉得是个遗憾。
        好在现在9轴的JY-901模块出来了,据说能解决Z轴漂移的问题。赶紧定了一片。今天刚到手,第一感觉是做工很真的精致,元件布局密度很大,几乎没有空的空间了,据店主说新款的为了保持和原来的串口6050的兼容性,封装和体积都是一样大小的,但是要布下比原来的串口6050模块多一倍的元件,只能采用4层板工艺了。看上去确实比原来的好很多,更精致了。

        不过店主并没有公开硬件的方案,个人觉得应该还是MPU6050+磁力计的方案,不知道各位前辈有何高见。


        软件不再是原来单一的曲线显示了,现在还加入了仪表盘和三维显示,接上线测试了一下,测到的数据能够很好地跟踪模块姿态的变换,不过刚开始的时候,方向角总是感觉不太准有些误差,后来跟店主请教后,发现是没有校准的问题,昨晚磁场校准以后,果然没有再出现方向不准的问题了。精度确实很好。比DMP好太多了。大家可以看我的测试数据。
        可能是磁场传感器都会有零偏误差的原因,而且这个初始误差还不小,足矣影响方向角的测量。陀螺仪的校准比较简单,点了校准按钮以后,等等数据不再变化即可。但是磁场的校准就比较麻烦一些了,在此也跟大家分享一下:点击磁场校准按钮以后,先绕X轴转动360度,再绕Y轴转360度,再绕Z轴转360度,然后再随意转动几下,知道显示的偏移值不再改变为止。原理是这样的:磁场传感器需要检测传感器在当前磁场环境中的最大值和最小值,然后去平均就是该轴的零点误差。因为地磁场是恒定的,比如X轴测到的最大值是700,最小值是-500,但实际上测到的都是地磁场,所以,X轴的零偏就是(700-500)/2=100,也就是说,修正以后,X的最大值是600,最小值是-600,这样两边就一致了。所以磁场校准需要寻找三个轴分别的最大值和最小值,因此需要分别绕三轴转360度。
        连电脑测试以后,又马上测试了一下连接arduino,我用的是Arduino Uno R3极客版,个人感觉比原版的Uno R3好用,我的Win8系统现在可以直接用了,原版的UnoR3驱动怎么都装不上,每次都得去找个XP电脑才行。最主要的是极客的价格是原版的1/3,很划算,嘻嘻。。。
        JY901对Arduino的支持很好,店主提供了Arduino的库函数,根据说明的方法安装以后,就可以再Arduino的菜单下面看到Demo了。

        店主提供了IIC的和串口的Demo,小弟都分别作了测试。先说串口连接,JY901的VCC接5V,GND接GND,JY901的TX接UnoR3的TX->1,JY901的RX线不用接。

        注意给UnoR3下载程序的时候,一定要先把TX线断开,然后再下载程序,下载完成后,再接上TX线。因为UnoR3下载程序用的也是这个串口,如果接上JY901以后,JY901会持续给模块发送数据,这样就会干扰UnoR3的程序下载。串口的代码如下:
[pre lang="arduino" line="1" file="JY901Serial.ino"]#include <Wire.h>
#include <JY901.h>

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  //print received data. Data was received in serialEvent;
  Serial.print("Time:20");Serial.print(JY901.stcTime.ucYear);Serial.print("-");Serial.print(JY901.stcTime.ucMonth);Serial.print("-");Serial.print(JY901.stcTime.ucDay);
  Serial.print(" ");Serial.print(JY901.stcTime.ucHour);Serial.print(":");Serial.print(JY901.stcTime.ucMinute);Serial.print(":");Serial.println((float)JY901.stcTime.ucSecond+(float)JY901.stcTime.usMiliSecond/1000);
               
  Serial.print("Acc:");Serial.print((float)JY901.stcAcc.a[0]/32768*16);Serial.print(" ");Serial.print((float)JY901.stcAcc.a[1]/32768*16);Serial.print(" ");Serial.println((float)JY901.stcAcc.a[2]/32768*16);
  
  Serial.print("Gyro:");Serial.print((float)JY901.stcGyro.w[0]/32768*2000);Serial.print(" ");Serial.print((float)JY901.stcGyro.w[1]/32768*2000);Serial.print(" ");Serial.println((float)JY901.stcGyro.w[2]/32768*2000);
  
  Serial.print("Angle:");Serial.print((float)JY901.stcAngle.Angle[0]/32768*180);Serial.print(" ");Serial.print((float)JY901.stcAngle.Angle[1]/32768*180);Serial.print(" ");Serial.println((float)JY901.stcAngle.Angle[2]/32768*180);
  
  Serial.print("Mag:");Serial.print(JY901.stcMag.h[0]);Serial.print(" ");Serial.print(JY901.stcMag.h[1]);Serial.print(" ");Serial.println(JY901.stcMag.h[2]);
  
  Serial.print("Pressure:");Serial.print(JY901.stcPress.lPressure);Serial.print(" ");Serial.println((float)JY901.stcPress.lAltitude/100);
  
  Serial.print("DStatus:");Serial.print(JY901.stcDStatus.sDStatus[0]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[1]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[2]);Serial.print(" ");Serial.println(JY901.stcDStatus.sDStatus[3]);
  
  Serial.print("Longitude:");Serial.print(JY901.stcLonLat.lLon/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLon % 10000000)/1e5);Serial.print("m Lattitude:");
  Serial.print(JY901.stcLonLat.lLat/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLat % 10000000)/1e5);Serial.println("m");
  
  Serial.print("GPSHeight:");Serial.print((float)JY901.stcGPSV.sGPSHeight/10);Serial.print("m GPSYaw:");Serial.print((float)JY901.stcGPSV.sGPSYaw/10);Serial.print("Deg GPSV:");Serial.print((float)JY901.stcGPSV.lGPSVelocity/1000);Serial.println("km/h");
  
  Serial.println("");
  delay(500);
}

/*
  SerialEvent occurs whenever a new data comes in the
hardware serial RX.  This routine is run between each
time loop() runs, so using delay inside loop can delay
response.  Multiple bytes of data may be available.
*/
void serialEvent()
{
  while (Serial.available())
  {
    JY901.CopeSerialData(Serial.read()); //Call JY901 data cope function
  }
}[/code]
        步骤很简单,首先初始化串口,然后在串口中断里面调用JY901的数据处理函数即可。其实大部分都是在打印输出,数据解析都是在库里面完成的。非常简洁明了。测试结果如下:
        IIC的接线方法也很简单,接上VCC和GND以后,将JY901的SCL和SDA分别接上UnoR3的SCL和SDA上面即可。

        IIC的程序如下:
        [pre lang="arduino" line="1" file="JY901IIC.ino"]#include <Wire.h>
#include <JY901.h>

void setup()
{
  Serial.begin(9600);
  JY901.StartIIC();
}

void loop()
{
  //print received data. Data was received in serialEvent;
  JY901.GetTime();
  Serial.print("Time:20");Serial.print(JY901.stcTime.ucYear);Serial.print("-");Serial.print(JY901.stcTime.ucMonth);Serial.print("-");Serial.print(JY901.stcTime.ucDay);
  Serial.print(" ");Serial.print(JY901.stcTime.ucHour);Serial.print(":");Serial.print(JY901.stcTime.ucMinute);Serial.print(":");Serial.println((float)JY901.stcTime.ucSecond+(float)JY901.stcTime.usMiliSecond/1000);
            
  JY901.GetAcc();
  Serial.print("Acc:");Serial.print((float)JY901.stcAcc.a[0]/32768*16);Serial.print(" ");Serial.print((float)JY901.stcAcc.a[1]/32768*16);Serial.print(" ");Serial.println((float)JY901.stcAcc.a[2]/32768*16);
  
  JY901.GetGyro();  
  Serial.print("Gyro:");Serial.print((float)JY901.stcGyro.w[0]/32768*2000);Serial.print(" ");Serial.print((float)JY901.stcGyro.w[1]/32768*2000);Serial.print(" ");Serial.println((float)JY901.stcGyro.w[2]/32768*2000);
  
  JY901.GetAngle();
  Serial.print("Angle:");Serial.print((float)JY901.stcAngle.Angle[0]/32768*180);Serial.print(" ");Serial.print((float)JY901.stcAngle.Angle[1]/32768*180);Serial.print(" ");Serial.println((float)JY901.stcAngle.Angle[2]/32768*180);
  
  JY901.GetMag();
  Serial.print("Mag:");Serial.print(JY901.stcMag.h[0]);Serial.print(" ");Serial.print(JY901.stcMag.h[1]);Serial.print(" ");Serial.println(JY901.stcMag.h[2]);
  
JY901.GetPress();
  Serial.print("Pressure:");Serial.print(JY901.stcPress.lPressure);Serial.print(" ");Serial.println((float)JY901.stcPress.lAltitude/100);
  
JY901.GetDStatus();
  Serial.print("DStatus:");Serial.print(JY901.stcDStatus.sDStatus[0]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[1]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[2]);Serial.print(" ");Serial.println(JY901.stcDStatus.sDStatus[3]);
  
JY901.GetLonLat();
  Serial.print("Longitude:");Serial.print(JY901.stcLonLat.lLon/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLon % 10000000)/1e5);Serial.print("m Lattitude:");
  Serial.print(JY901.stcLonLat.lLat/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLat % 10000000)/1e5);Serial.println("m");
  
JY901.GetGPSV();
  Serial.print("GPSHeight:");Serial.print((float)JY901.stcGPSV.sGPSHeight/10);Serial.print("m GPSYaw:");Serial.print((float)JY901.stcGPSV.sGPSYaw/10);Serial.print("Deg GPSV:");Serial.print((float)JY901.stcGPSV.lGPSVelocity/1000);Serial.println("km/h");
  
  Serial.println("");
  delay(500);
}[/code]
        也很简单,初始化串口,然后开始IIC通信,读取需要的数据,再打印输出即可。同样很简洁。
        总结一下:个人觉得IIC更好用一些,首先下载程序不用再拔线了,另外数据可以根据需要读取,不像串口是被动接受的,总是会经常进入中断里面去收取数据。浪费CPU的时间。另外空出来的宝贵的串口就可以拿来连接别的设备啦。
        附实验所使用的材料清单及TB传送门:
        JY901模块:http://item.taobao.com/item.htm?id=43511899945
        底板:http://item.taobao.com/item.htm?id=36003529849
        Uno R3极客版:http://item.taobao.com/item.htm?id=36173468818
        公对母杜邦线:http://item.taobao.com/item.htm?id=36179524617
        通过实验觉得这个模块还是很好用的,精度很高,资料也非常齐全,现在希望我的平衡小车能够快点站起来,后续再来和大家分享。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 1 +2 +50 +50 收起 理由
lawrencedon + 2 + 50 + 50 赞一个!

查看全部评分

回复

使用道具 举报

发表于 2015-1-27 10:10:38 | 显示全部楼层
这个传感器模块的数据接口是邮票孔,还要自己做板子引出针脚,
不知价格是多少,想搞一块玩玩,之前想做四轴飞行器,有感觉太烧钱了!所以就没做
年后再想想
回复 支持 反对

使用道具 举报

发表于 2015-1-27 11:29:39 | 显示全部楼层
买了硬件好久,一直放着,多谢楼主的资料,我试试看
回复 支持 反对

使用道具 举报

发表于 2015-1-27 12:26:16 | 显示全部楼层
感谢分享~ 图文并茂,很好滴帖子啊~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-27 14:56:42 | 显示全部楼层
潇洒哥 发表于 2015-1-27 10:10
这个传感器模块的数据接口是邮票孔,还要自己做板子引出针脚,
不知价格是多少,想搞一块玩玩,之前想做四 ...

是邮票孔的,不过有配的底板,我买的时候老板送底板了,邮票孔比较方便焊接到自己的板子上面,还是不错的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-27 14:59:20 | 显示全部楼层
潇洒哥 发表于 2015-1-27 10:10
这个传感器模块的数据接口是邮票孔,还要自己做板子引出针脚,
不知价格是多少,想搞一块玩玩,之前想做四 ...

这个分带气压的和不带气压的,不带气压的是98,带气压的是128.我做的小车,弄气压的没用,就搞了个不带气压的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-27 15:00:14 | 显示全部楼层
lawrencedon 发表于 2015-1-27 12:26
感谢分享~ 图文并茂,很好滴帖子啊~

谢谢鼓励!
回复 支持 反对

使用道具 举报

发表于 2015-1-28 21:10:23 | 显示全部楼层
如果不急的话还是要研究下里面的细节!
回复 支持 反对

使用道具 举报

发表于 2015-8-27 10:28:55 | 显示全部楼层
请问  楼主用过里面的气压计吗,为什么我的气压计数值不变化。基本只测1次
回复 支持 反对

使用道具 举报

发表于 2015-10-29 16:21:25 | 显示全部楼层
楼主你好,我用IIC通信的时候函数通过不去是什么问题呢会?
回复 支持 反对

使用道具 举报

发表于 2015-10-29 17:26:56 | 显示全部楼层
我也想入手一块3轴模块,
三轴轴陀螺仪ENC-03MB三轴加速度MMA7361自平衡智能车 姿态传感器
想问问楼主,这个模块怎么样?
小弟不才,还望多指教

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2015-11-27 05:32:31 | 显示全部楼层
顺子 发表于 2015-10-29 17:26
我也想入手一块3轴模块,
三轴轴陀螺仪ENC-03MB三轴加速度MMA7361自平衡智能车 姿态传感器
想问问楼主,这 ...

这个模块有点老了
回复 支持 反对

使用道具 举报

发表于 2017-1-9 17:34:41 | 显示全部楼层
你好楼主,有没有 测试过通过Arduino iic连接多个陀螺仪的情况
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 20:13 , Processed in 0.047054 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表