抱歉,来晚了—arduino的火箭气压开伞及姿态数据记录系统发布!
擺渡犯賤2014/11/09喷气推进 IP:广东
       其实这个开伞系统我几个星期前就应该发布了,不过由于我发现有一些地方需要改进以及测试不是很严谨,再加上蛋疼的期中考试,所以就推到现在了。。。
       对了,感谢下@彩虹之巅,因为看了他的帖子后我学习了很多,这个系统中有些代码也是他的。

下面引用他的声明:
--------------------------
此版程序作为自己发射火箭测试用,将一些保险验证代码都去掉了,所以一开始定义的一些变量常量没用到,最简单的才是最可靠的。经实际发射,证实此程序识别开伞点可靠。用这个程序请让火箭在发射架上(一定要用发射架,防止火箭在打开电源后发射前倾倒导致意外开伞)就位后再打开系统供电电池电源(9V电池盒自带开关,火箭上掏个小洞对着电池盒上开关,发射前用牙签拨开开关就行),电源打开后由于系统要加载以及要识别SD卡,所以过五秒后再点火。
另外,这个小程序开源,大家想用就用,不反对将此程序用于利润低于30%的商业行为,同时欢迎有兴趣的朋友对这个程序进行改良。另外用此程序发射火箭的朋友请遵守国家的相关法律,本人对用此程序发射火箭所带来的后果不承担任何法律责任。
--------------------
*/
      另外本人接触arduino及编程也就几个星期,如有问题,求轻拍!
       先说说这个系统的优点吧:
         1.气压定高开伞,高度,气压,温度,三轴角度及加速度数据采集(这些都是必须的)。
         2.造价便宜,也就5,60来块。
         3.发射完火箭后还可以把模块拆下来弄别的玩(前提是你用得扩展版)。
         4。。。
       再说说这个系统不完美的地方:
         1.体积有点大,重量有点重,接线比较乱。
         2.不适于新手,需要有一定的电子编程基础。
         3.地面气压高度的问题还在,虽然不影响系统的功能,但是每次发射前都要重新写入高度,比较麻烦。
         4。。。

/*    
    注意!
1.一定要保证线路牢固不松,可以用洞洞板弄一个扩展板插上去,这样既牢固又可以方便取下原件干别的。
2.开伞高度设置在下面的代码里,可以自己去修改,气压高度量程-500~9000m。
3.弄好设备测试时,可以去坐电梯上下模拟,很方便,因为是测气压所以不用担心什么。
4.开伞高度是海平面高度,而不是相对你所在地面的高度,在发射之前一定要用arduino测好高度重新写入(测到的高度加上你要开伞的高度,比如我现在测的地面气压高度是-38m,想23m时开伞,那就输入-15m!)
5.火箭准备发射打开设备时,一定要观察arduino的“LED”灯是否在闪烁,没有的话是有故障!
*/
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面正文
           一.理论
           其实气压开伞的原理,用我的这一张图来说明吧:
IMG20141027174916.jpg
大家应该会很容易明白的。
现在说说接线吧
    
/*
使用设备:
arduino Nano
mpu6050
bmp085或bmp180
sd卡模块
9v电池
线路连接:
sd卡:
5v=5v
sdcs/cs/dat2=d4
mosi/di/dat3=d11
sck/clk/=d13
miso/dat0/d0=d12
gnd=gnd
mpu6050:
int=d2
vcc=3v3
gnd=gnd
scl=a5
sda=a4
bmp085/180:
gnd=gnd
3.3=3v3
scl=a5
sda=a4
继电器:
in=d3
vcc=5v
gnd=gnd
供电:
gnd=gnd
vin=9v(6~12v)
*/
2014-11-08-163.jpg
尽量使用扩展板 2014-11-08-176.jpg
2014-11-08-165.jpg
下面代码,大家不要直接复制。
#include "Wire.h"
#include "I2Cdev.h"
#include "BMP085.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "SD.h"
//导入库文件
BMP085 barometer;
float temperature;
float pressure;
float altitude;
int a;
int b;






               int high=-15;//在这把数字改成你想要开伞的海平面高度(m)





const int chipSelect = 4;  //设定SD_CS接口
int32_t lastMicros;bool blinkState = false;
int OPEN;
#define LED_PIN 13//设定led数据灯
//mpu6050设置----------------------
#define Vertical_acceleration_judgment_value 15 //设置加速度为多少时判断火箭为已发射的值,经验值为15.
#define Launched 1                              //用来描述火箭状态为已发射.
#define Not_launched 0                          //用来描述火箭状态为尚未发射.
#define The_correct_flight_angle_limit_of_rocket 30 //设置火箭正常发射的角度极值
unsigned long time;
int16_t ax, ay, az;//三轴加速度
int rocket_status;                              //该变量代表火箭当前的状态,分别为未发射或已发射。
float inclination[3];                           //箭体三轴倾角,是一个数组,inclination[0]  inclination[1]  inclination[2] 分别代表三个轴的倾角
int zz,yy,Current_rocket_inclination;                 //该变量代表火箭与地平线的倾角.zz和yy是后加上去了,三个轴都采集了,可以再现火箭整个飞行过程中的箭体三维姿态。
int16_t Vertical_acceleration;                  //火箭垂直加速度,用来判断火箭是否已发射.
int last_rocket_inclination=0;                  //上一次通过传感器获得的火箭倾角.
//下面为计算三轴角度的一些中间变量
MPU6050 mpu;        
uint8_t a1;
uint16_t a2;
uint16_t a3;
uint8_t a4[64];
Quaternion a5;
VectorFloat a6;
//上面为计算三轴角度的一些中间变量


void setup()
{
    OPEN=0;
    XXXXXXXgin();
    XXXXXXXXXgin(115200);
    Init_MPU_6050();                                    //初始化MPU6050.
    rocket_status=Not_launched;                         //将火箭状态初始化为未发射.
    XXXXXXXXXXXXitialize();
    pinMode(3,OUTPUT);  //设定继电器为d3口
    digitalWrite(3,LOW);//继电器初始化
    pinMode(LED_PIN, OUTPUT);//LED初始化
    XXXXXgin(chipSelect);
    int a=0;
    int b=0;
  
}


void loop() {
    zz=Get_Current_Rocket_Inclination(0);
  yy=Get_Current_Rocket_Inclination(2);
  Current_rocket_inclination=Filter_Current_Rocket_Inclination(1);//取得火箭当前的倾角,参数这里取值为1,代表X轴.
  Vertical_acceleration=XXXXXXtAccelerationX()/2048;//还是因为传感器安装位置的关系,火箭垂直轴为X轴。这里表示的是当前火箭的垂直加速度,程序里用作判断火箭是否已经发射。其实就是表示X轴的当前加速度
  
    XXXXXXXXXXXXtControl(BMP085_MODE_TEMPERATURE);
    lastMicros = micros();
    while (micros() - lastMicros < XXXXXXXXXXXXtMeasureDelayMicroseconds());
    temperature = XXXXXXXXXXXXtTemperatureC();
    XXXXXXXXXXXXtControl(BMP085_MODE_PRESSURE_3);
    while (micros() - lastMicros < XXXXXXXXXXXXtMeasureDelayMicroseconds());
    pressure = XXXXXXXXXXXXtPressure();
    altitude = XXXXXXXXXXXXtAltitude(pressure);
    File dataFile = SD.open("data.txt",FILE_WRITE);
    if (dataFile)
    { XXXXXXXXXXXint("X.Y.Z.A.C.P.H");//写入x,y,z轴数据,以及加速度,温度,气压,高度
      XXXXXXXXXXXint(",");
XXXXXXXXXXXint(int(Current_rocket_inclination),DEC);  //将箭体倾角数据写入文件
      XXXXXXXXXXXint(",");
      XXXXXXXXXXXint(int(yy),DEC);  
      XXXXXXXXXXXint(",");
      XXXXXXXXXXXint(int(zz),DEC);  //箭体姿态的另外两个轴数据写入文件
      XXXXXXXXXXXint(",");
      XXXXXXXXXXXint(float(Vertical_acceleration),DEC);   //将火箭垂直加速度写入文件
      XXXXXXXXXXXint(",");  
      XXXXXXXXXXXint(float(temperature),DEC);  //温度
      XXXXXXXXXXXint(",");
      XXXXXXXXXXXint(float(pressure),DEC);  //气压
      XXXXXXXXXXXint(",");
      XXXXXXXXXXXintln(float(altitude),DEC);  //高度
      XXXXXXXXXXXose();
      blinkState = !blinkState;
      digitalWrite(LED_PIN, blinkState);
    }
    
    
    
     if(altitude>=high+2)//防止上升阶段误开伞
{ a=1;}

      if (a==1)//判断是否在下降阶段
             { if(altitude<=high)
         b=1;}
  
      if (a+b==2 )//判断高度开伞
            { digitalWrite(3,HIGH);//继电器打开
      if(OPEN==0)
           { File dataFile = SD.open("data.txt",FILE_WRITE);
              if (dataFile)
               {XXXXXXXXXXXintln("Opened");   //在数据文件中写入开伞的标记点
                 XXXXXXXXXXXose();}
                        OPEN=1;}
                                    }
}
int Filter_Current_Rocket_Inclination(int b)
{
  int temp;
  temp=Get_Current_Rocket_Inclination(b);
  if(temp==0)
     {
       return last_rocket_inclination;
     }
  else
     {
       last_rocket_inclination=temp;
       return last_rocket_inclination;
     }
}
/*上面的函数是过滤传感器传回的无效值,参数b可以为0,1,2,分别代表传感器的Z,X,Y三个轴,本程序中取X轴,如果用其它轴来判断,则部分程序需要相应的修改*/
  

float Get_Current_Rocket_Inclination(int c)
{
    float rocket_inclination=0;
    a1=XXXXXXtIntStatus();
    a3=XXXXXXtFIFOCount();
    if (a1&0x02)
         {
          while (a3<a2) a3=XXXXXXtFIFOCount();
          XXXXXXtFIFOBytes(a4, a2);
          a3-=a2;
          XXXXXXsetFIFO();
          XXXXXXpGetQuaternion(&a5, a4);
          XXXXXXpGetGravity(&a6, &a5);
          XXXXXXpGetYawPitchRoll(inclination, &a5, &a6);
          rocket_inclination=inclination[c]*180/M_PI;
          return rocket_inclination;
         }
}
/*上面的函数是通过传感器来获得当前X轴与地平线的倾角数据,由于不可知的原因,获得的数据可能有噪点,不能拿来直接使用,需要进行适当的过滤.参数c可以为0,1,2,分别代表传感器的Z,X,Y三个轴,本程序中取X轴,如果用其它轴来判断,则部分程序需要相应的修改*/    

void Init_MPU_6050()
{
    XXXXXXitialize();
    XXXXXXtFullScaleGyroRange(3);
    XXXXXXtFullScaleAccelRange(3);
    XXXXXXtDLPFMode(6);
    XXXXXXtDHPFMode(1);
    XXXXXXpInitialize();
    XXXXXXtDMPEnabled(true);
    a2 = XXXXXXpGetFIFOPacketSize();
}
/*上面的函数是对MPU6050进行初始化和一些必要的设置*/

二.实践
其实我原计划是准备用火箭测试的,不过由于考试和广州这多变的天气只好取消,变成电梯测试了。。。
视频地址XXXXXXXXXXXXXXXXXX/v_show/id_XXXXXXXXXXXXXXXXml
捕获3_副本.jpg 捕获5_副本.jpg 捕获4_副本.jpg
回去导入数据 捕获.jpg 捕获2_副本.jpg
感觉挺不错的。
三.下载
库文件
attachment icon 库文件.zip 152.94KB ZIP 157次下载
代码
attachment icon arduino_bmp085_mpu6050.txt 9.03KB TXT 176次下载
来自:航空航天 / 喷气推进
17
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
51区总管
10年2个月前 IP:山西
730045
提个问题,两个传感器都是IIC通信的,那么主机是哪台,如何发送数据?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
擺渡犯賤作者
10年2个月前 IP:广东
730046
引用 51区总管:
提个问题,两个传感器都是IIC通信的,那么主机是哪台,如何发送数据?
是这些吗?
XXXXXXXXXXXXXXXXXX/from=1006442a/bd_page_type=1/ssid=0/uid=0/pu=usm%400%2Csz%401320_1001%2Cta%40iphone_2_4.2_3_534/baiduid=FD070E2A0BFD986DBAFEB4F764657BD0/w=0_10_arduino+sda+scl/t=iphone/l=3/tc?ref=www_iphone&lid=13109312338641246079&order=7&vit=osres&tj=www_normal_7_0_10&m=8&srd=1&cltj=cloud_title&dict=20&fm=wnor_p1&sec=42795&di=1d4451acebdf59fd&bdenc=1&nsrc=IlPT2AEptyoA_yixCFOxXnANedT62v3IEQGG_ylV2DWxiFrte4viZQRASDfuLnzFU-WadDf0sqdTbCfw3mRU7BBWrKt6sVsh7HfldPmXhhzMGhwDtsUt2q
I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既可以是主控器(或被控器),又可以是发送器(或接收器),这取决于它所要完成的功能。
XXXXXXXXXXXXXXXXXXXXXX/p/2472447225?bd_source_light=1&pn=0&
一对SDA?SCL口可以接很多I2C设备,靠不同的I2C地址来区分。详情参看Wire库的用法
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
51区总管
10年2个月前 IP:山西
730066
引用 擺渡犯賤:
是这些吗?
XXXXXXXXXXXXXXXXXX/from=1006442a/bd_page_type=1/ssid=0/uid=0/pu=usm%400%2Csz%401320_1001%2Cta%40iphone_2_4.2_3_534...
不,我的意思是MPU6050似乎就是默认主机,然后arduino为从机,而I2C通信只能有一个主机,我就不清楚BMP085的通信是怎么实现的
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
七公里垃圾站职业技术学院
10年2个月前 IP:河南
730068
我有一个疑问,在火箭高速运行的时候,气压不会变化么(流速大,气压小)
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
擺渡犯賤作者
10年2个月前 IP:广东
730196
引用 51区总管:
不,我的意思是MPU6050似乎就是默认主机,然后arduino为从机,而I2C通信只能有一个主机,我就不清楚BMP085的通信是怎么实现的
我觉得arduino是主机,传感器都是从机。具体我也不太清楚了,但是arduino的a4a5口能连接多个传感器。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
擺渡犯賤作者
10年2个月前 IP:广东
730197
引用 h13:
我有一个疑问,在火箭高速运行的时候,气压不会变化么(流速大,气压小)
是没影响的,彩虹之巅的火箭曾经用这种气压测过高度,你可以去看看。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
LShang001
10年1个月前 IP:湖南
731302
气压开伞好像不是到达某个高度开伞吧             应该是通过检测气压的变化(高度的变化) ,判断火箭是否在上升,
截取两个时间点的气压数据,当两数之差处于某个范围之内时(因传感器精度限制,差值应无限接近于0)      

则判断火箭上升速度几乎为0,即到达最高点     从而开伞
引用
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
彩虹之巅
10年1个月前 IP:江苏
731386
引用 liushang100:
气压开伞好像不是到达某个高度开伞吧             应该是通过检测气压的变化(高度的变化) ,判断火箭是否在上升,
截取两个时间点的气压数据,当两数之差处于某个范围之内时(因传感器精度限制,差值应无限接近于0)       ...
楼上正解
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
抽包包的老鹰
10年1个月前 IP:甘肃
732746
引用 h13:
我有一个疑问,在火箭高速运行的时候,气压不会变化么(流速大,气压小)
参考皮托管的静压管
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
3.14
10年1个月前 IP:四川
732775
能简化一下吗?好复杂。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
七公里垃圾站职业技术学院
9年8个月前 IP:河南
765957
库文件不管用…… 5QG63GL[Y2WAEAB5~0B(48W.jpg
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
chemistry02
8年10个月前 IP:四川
809195
@擺渡犯賤 点火头怎么连?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
chemistry02
8年10个月前 IP:四川
809196
引用 chemistry02:
@擺渡犯賤 点火头怎么连?
@擺渡犯  
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
xjmecnu
8年10个月前 IP:上海
809224
这程序写的。。。哎。。。
引用
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
玉颜州
8年10个月前 IP:北京
809428
MPU6050模块供电电压5V ,但是MPU6050芯片供电电压3.3v,模块内部有5V转3.3V的LDO.

那么MPU6050的IIC总线接2个电阻上拉到3.3v.

而ARDUINO是5V的。我想问,3.3V的IIC可以直接和5V的ARDUINO接口吗?
引用
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张云轩.学
8年10个月前 IP:山东
809685
引用 玉颜州:
MPU6050模块供电电压5V ,但是MPU6050芯片供电电压3.3v,模块内部有5V转3.3V的LDO.

那么MPU6050的IIC总线接2个电阻上拉到3.3v.

而ARDUINO是5V的。我想问,3.3V的IIC可以直接和5V的A...
用9V电池,参照彩虹之巅的航电制作教程,按照他的方法把电池与Arduino Nano连接,其他接线不变。
引用
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
擺渡犯賤
进士 笔友
文章
5
回复
53
学术分
0
2013/10/02注册,10个月1天前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}