所有教程由网友发布,仅供参考,请谨慎采纳。科创不对教程的科学性、准确性、可靠性负责。
Arduino&水火箭开伞航电的制作
暮羽要摸鱼2023/08/16原创 航空技术 IP:广东
中文摘要
水火箭开伞+高度记录
Abstract
Water rocket parachute opening + altitude record
关键词
水火箭火箭气压开伞Arduino

前段时间整火箭航电时惊奇的发现我家一共就3楼高,这点高度根本无法测试我的开伞功能(气压开伞)索性又弄了个水火箭以测试航电的开伞。

但水火箭也是需要开伞的啊!开始的时候本打算使用延时开伞的,但后来感觉掐时间太麻烦了,太低级了,所以索性用Arduino写了个气压开伞程序直接一劳永逸。

后来发现水火箭圈子里的开伞大多是机械延时开伞和开伞全靠运气的额----(最高点下落气流冲击开伞)😂,再加上很多小白(我也是小白😆)都不知道开伞咋整,所以我才发这篇帖子让大家学习参考一下。


—————————————————————————————————————————

1、程序思路

程序的思路好还是挺简单的,就是判断加速度值大于某个值的时候判断发射,然后程序判断下降高度达到下降高度的时候执行开伞动作。


2、所需硬件

Arduino nano 主控是328P的

MPU6050

BMP280

四针0.96OLED

舵机

1k电阻

LED

按钮

1692157610131.png


3、接线


Arduino——MPU6050

3V3——VCC

GND——GND

A4——SDA

A5——SCL


Arduino——BMP280 //程序里可以改

3V3——VCC

GND——GND

D13——SCL

D12——SDA

D11——CSB

D10——SDO


Arduino——0.96OLED

3V3——VCC

GND——GND

A4——SDA

A5——SCL


Arduino——舵机

5V——红色

GND——黑色OR棕色

信号线D9——黄色OR橙色OR白色


Arduino——复位按钮

D3——按钮

GND——按钮


Arduino——指示灯OR继电器OR各种各样的开关管

信号线D6——LEDOR开关脚

接其他自己看着办



微信图片_20230816120955.png


微信图片_20230816092627.jpg


5、程序

#include <Adafruit_Sensor.h>  
#include <Adafruit_BMP280.h> 
#include <basicMPU6050.h> 
#include "U8glib.h" 
#include <Servo.h>
#include <math.h>
#include <Wire.h> 
#include <SPI.h> 
//以上库文件没有的话直接在IDE的库管理里面搜索就能找到了


Servo myservo;
basicMPU6050<> imu;
float H,P_init,H_K,H_P,G_P_X,G_P_Y,G_P_Z,G_Z,H_Z=0;
uint8_t angle;
bool G=0;





uint8_t ON = 0; //开伞舵机角度
uint8_t OFF = 90; //未开伞舵机角度
uint8_t OPEN_H = 2; //下降多少米开伞
uint8_t G_OPEN_Init = 4;//判断发射加速度值
uint8_t Reset = 3; //设置复位按钮引脚
uint8_t LED = 6; //设置LED信号引脚
uint8_t Servo_P = 9; //设置舵机信号引脚
/*定义BMP280引脚*/
#define BMP_SCK 13   //SCL引脚 
#define BMP_MISO 10   //SDO引脚
#define BMP_MOSI 12   //SDA引脚
#define BMP_CS 11     //CSB引脚
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);  






/////////////////////////////////////////////////////////////////////////
//1. 结构体类型定义
typedef struct 
{
    float LastP;//上次估算协方差 初始化值为0.02
    float Now_P;//当前估算协方差 初始化值为0
    float out;//卡尔曼滤波器输出 初始化值为0
    float Kg;//卡尔曼增益 初始化值为0
    float Q;//过程噪声协方差 初始化值为0.001
    float R;//观测噪声协方差 初始化值为0.543
}KFP;//Kalman Filter parameter

//2.  定义卡尔曼结构体并初始化参数
KFP KFP_height={0.008,0,0,0,0.05,0.3};

/**
 *卡尔曼滤波器
 *@param KFP *kfp 卡尔曼结构体参数
 *   float input 需要滤波的参数的测量值(即传感器的采集值)
 *@return 滤波后的参数(最优值)
 */
 float kalmanFilter(KFP *kfp,float input)
{
     //预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差
     kfp->Now_P = kfp->LastP + kfp->Q;
     //卡尔曼增益方程:卡尔曼增益 = k时刻系统估算协方差 / (k时刻系统估算协方差 + 观测噪声协方差)
     kfp->Kg = kfp->Now_P / (kfp->Now_P + kfp->R);
     //更新最优值方程:k时刻状态变量的最优值 = 状态变量的预测值 + 卡尔曼增益 * (测量值 - 状态变量的预测值)
     kfp->out = kfp->out + kfp->Kg * (input -kfp->out);//因为这一次的预测值就是上一次的输出值
     //更新协方差方程: 本次的系统协方差付给 kfp->LastP 为下一次运算准备。
     kfp->LastP = (1-kfp->Kg) * kfp->Now_P;
     return kfp->out;
}
/////////////////////////////////////////////////////////////////////////




//void draw(void);
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
void draw(){//OLED显示数据
 u8g.drawStr(0, 20, "REAL:");
 u8g.drawStr(0, 40, "MAX:");
 u8g.drawStr(0, 60, "MAX_G:");
  u8g.setPrintPos(64,20);
 u8g.print(H_K,1);
 u8g.setPrintPos(64,40);
 u8g.print(H_Z,1);
 u8g.setPrintPos(80,60);
 u8g.print(G_Z,1);
}


void Init_Referencepressure()
{
  for(char i=0;i<20;i++)
  {
    H_P+=(bmp.readPressure())/100;
    delay(50);
  }
  P_init=H_P/20;
  H_P=0;
}

void setup() {
  Serial.begin(9600);     //设置波特率
  bmp.begin();
  imu.setup();
  imu.setBias();
  Init_Referencepressure();
  u8g.setFont(u8g_font_fub14);//设置字体和字号
  myservo.attach(Servo_P);
  myservo.write(OFF);
  pinMode(LED,OUTPUT);
  pinMode(Reset, INPUT_PULLUP); //按钮引脚设置为输入上拉模式
}

void loop() {
  bool Reset_State = digitalRead(Reset);
  H_K=kalmanFilter(&KFP_height,bmp.readAltitude(P_init));
  G_P_X=abs(imu.ax());
  G_P_Y=abs(imu.ay());
  G_P_Z=abs(imu.az());
 
  if(G_Z<G_P_X){G_Z=G_P_X;}
  if(G_Z<G_P_Y){G_Z=G_P_Y;}
  if(G_Z<G_P_Z){G_Z=G_P_Z;}
  if(H_Z<H_K&&G==1){H_Z=H_K;}
  if(G_P_X>=G_OPEN_Init || G_P_Y>=G_OPEN_Init || G_P_Z>=G_OPEN_Init){G=1;}

  if((H_K<H_Z-OPEN_H)&&G==1)//判断下降X米开伞
  {
    digitalWrite(LED,HIGH);
    myservo.write(ON);
  }

  if(Reset_State==0)//复位按钮按下
  {
    G=0;
    G_Z=0;
    H_Z=0;
    Init_Referencepressure();
    myservo.write(OFF);
    digitalWrite(LED,LOW);
  }

  u8g.firstPage();  
  do {
     draw();
  } while( u8g.nextPage() );
 }

attachment icon 气压开伞+高度显示.ino 4.02KB INO 163次下载

OLED上自下而上显示的是

实时高度

飞行最大高度

最大加速度


6、是啥好呢?

本程序与模块进行了多次上箭实践,无一开伞失败😅

降落伞仓参考:水火箭建造 - 侧面部署 2 (XXXXXXXXXXXXXXXXXXXXX)

bilbil上也有人搬运:水火箭降落伞装置设计_哔哩哔哩_bilibili

WeChat_20230816123736.mp4  点击下载

(那人不是我哈是我弟🤫

微信图片_20230816124514.jpg

59.6😆


水火箭的射高可以覆盖50~150的高度,而且一个2L的可乐瓶装上尾翼带上250g的设备使用22毫米的全口径发射器动力段可以加速到35m/s ,这是一个用来验证火箭航电的良好平台。

7、注意

箭体航电仓上要钻出几个保持静压的孔

不要让高速气流直接吹在BMP280模块上


本人对用此程序发射火箭所带来的后果不承担任何法律责任。


欢迎各位老师对这个程序进行改良。

程序中有不足之处请各位老师指点,谢谢!



+1  学术分    虎哥    2023/10/22 设计采用现代研发的一般方法,效果尚可。
来自:航空航天 / 航空技术严肃内容:教程/课程
6
 
9
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
codingxile
1年4个月前 IP:北京
924217

感觉喷推火箭也可以借鉴一下

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
暮羽要摸鱼作者
1年4个月前 IP:广东
924223
引用codingxile发表于1楼的内容
感觉喷推火箭也可以借鉴一下

无非就多个数据记录,(直接写SD卡里或无线数传)要是只是拿来开伞再看个高度也OK。

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
Candyday
1年2个月前 修改于 1年2个月前 IP:中国
926010

感谢分享


引用
评论
2
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
2007
9个月26天前 IP:台湾
930007

請問為何我做出來0.96oled不會亮


引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
飞友一只
5个月15天前 IP:浙江
934018

可以用金属舵机代替塑料舵机


引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
Jonas_Y
11天15时前 IP:辽宁
940315

震惊了,比我做嵌入式的同事搞的还规范。


引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

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

所属专业
上级专业
同级专业
暮羽要摸鱼
进士 学者 机友 笔友
文章
9
回复
126
学术分
1
2019/12/17注册,1时58分前活动

不知道 不知道 布吉岛 咕咕咕~

主体类型:个人
所属领域:无
认证方式:身份证号
IP归属地:广东
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

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