事故报告仅用于总结经验教训,提高安全防控水平。禁止转载、演绎及任何非善意的应用。
发动机测试采集卡问题分析
Space航天2024/11/29原创 航天技术 IP:青海
中文摘要
发动机采集卡问题分析与总结
关键词
推理采集卡发动机测试

这次主要是回复Merlin-1D文章:939753

这次试车是我和Merlin同步设计的发动机,并进行试车,本次的采集卡主要是由我设计的,下面先看几张图片

IMG20241005111457.jpgIMG20241013011403.jpgIMG20241013011408.jpg



这会儿嘉立创打不开了,就暂时不展示原理图了

这次的采集卡主控是nano上面同种328p的芯片,并采用了nrf作为数据传输,传感器的采集芯片是hx711芯片,采集版在发送数据的同时并将数据同步采集到SD卡中,但是我的发动机在点火之后,后期处理数据的时候发现数据波动太小了,连着把试车台都推动了,结果采集的数据只有21牛左右😭,具体的试车视频且看我朋友的那篇文章,推力是明显很大的,工作时间1~2s

下面是本次基于arduino ide编写的程序代码:


#include <SD.h>
#include <HX711_ADC.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
RF24 radio(6, 7);  // CE, CSN引脚
File file;
const byte address[6] = "0000";
const byte address2[6] = "Space.ST";
const int HX711_dout = 5;  //接HX711 dout
const int HX711_sck = 4;   //接 HX711 sck
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_calVal_eepromAdress = 0;
float a = 0;
float i;
int time = 0;
int period = 1000;
unsigned long timenow = 1000;
unsigned long time2 = 0;
void setup() {
  Serial.begin(115200);
  pinMode(3, INPUT_PULLUP);  //设置复位按键
  pinMode(8, OUTPUT);        //设置蜂鸣器输出
  pinMode(2, INPUT_PULLUP);
  if (!radio.begin()) {
    Serial.println("NRF初始化失败");
    while (1) {
      digitalWrite(8, 1);
      delay(500);
      digitalWrite(8, 0);
      delay(500);
    }
  }
  if (!SD.begin()) {
    Serial.println("SD初始化失败");
    while (1) {
      digitalWrite(8, 1);
      delay(500);
      digitalWrite(8, 0);
      delay(500);
    }
  }
  radio.setPALevel(RF24_PA_MIN);  // 设置为最大发射功率
  Serial.println("准备...");
  float calibrationValue;

  calibrationValue = 30.61;  //校准值根据实际情况进行修改

#if defined(ESP8266) || defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266 and want to fetch this value from eeprom
#endif
  //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch this value from eeprom

  LoadCell.begin();
  //LoadCell.setReverseOutput();
  unsigned long stabilizingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration factor (float)
    Serial.println("Startup is complete");
  }
  while (!LoadCell.update());
  Serial.print("Calibration value: ");
  Serial.println(LoadCell.getCalFactor());
  Serial.print("HX711 measured conversion time ms: ");
  Serial.println(LoadCell.getConversionTime());
  Serial.print("HX711 measured sampling rate HZ: ");
  Serial.println(LoadCell.getSPS());
  Serial.print("HX711 measured settlingtime ms: ");
  Serial.println(LoadCell.getSettlingTime());
  Serial.println("Note that the settling time may increase significantly if you use delay() in your sketch!");
  if (LoadCell.getSPS() < 7) {
    Serial.println("!!Sampling rate is lower than specification, check MCU>HX711 wiring and pin designations");
  }
  else if (LoadCell.getSPS() > 100) {
    Serial.println("!!Sampling rate is higher than specification, check MCU>HX711 wiring and pin designations");
  }
  file = SD.open("test.txt", FILE_WRITE);
  if (file) {
    file.println("            ");
    file.println("            ");
    file.println("以上数据作废 ");
    file.println("开始记录新数据:");
    file.close();
  }
}

void loop() {
  unsigned long timenow2 = millis();
  static boolean newDataReady = 0;
  const int serialPrintInterval = 500;  //increase value to slow down serial print activity
  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;
  if (newDataReady) {
    i = LoadCell.getData();
  }
  if (digitalRead(2) == 1) {
    if (timenow2 - time2 >= timenow) {
      time2 = timenow2;
      time++;
    }
    file = SD.open("test.txt", FILE_WRITE);
    file.print(i / 1000 * 9.8);  //单位转换N
    file.print("   ");
    file.print(time);
    file.println("s");
    file.close();
    Serial.print(i);
    radio.openWritingPipe(address);
    radio.write(&i, sizeof(i));
    Serial.print("g");
    Serial.print(" ");
    Serial.print(i / 1000 * 9.8);
    Serial.print("N");
    radio.openWritingPipe(address2);
    radio.write(&time, sizeof(time));
    Serial.print(" ");
    Serial.print(time);
    Serial.println("s");
  } else {
    time = 0;
    LoadCell.tareNoDelay();
  }
  if (digitalRead(3) == 0) {
    LoadCell.tareNoDelay();
    digitalWrite(8, 1);
    delay(500);
    digitalWrite(8, 0);
    time = 0;
    file = SD.open("test.txt", FILE_WRITE);
    if (file) {
      file.println("            ");
      file.println("            ");
      file.println("以上数据作废 ");
      file.println("开始记录新数据:");
      file.close();
    }
  }
}

attachment iconsketch_sep16a.zip1.76KBZIP0次下载

以上是发送端的代码


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
static const unsigned char PROGMEM sh[]{
  0x04, 0x00, 0xFF, 0xE0, 0x80, 0x20, 0x12, 0x00, 0x0A, 0x00, 0x22, 0x00, 0x12, 0x00, 0xFF, 0xE0,
  0x04, 0x00, 0x09, 0x80, 0x30, 0x40, 0xC0, 0x20, /*"实",0*/
};
static const unsigned char PROGMEM shi[]{
  0x00, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x97, 0xE0, 0x90, 0x40, 0xF0, 0x40, 0x92, 0x40, 0x91, 0x40,
  0x91, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x01, 0xC0, /*"时",1*/
};
static const unsigned char PROGMEM zui[]{
  0x3F, 0x80, 0x20, 0x80, 0x3F, 0x80, 0x20, 0x80, 0xFF, 0xE0, 0x48, 0x00, 0x7B, 0xC0, 0x49, 0x40,
  0x79, 0x40, 0x4C, 0x80, 0xF9, 0x40, 0x0A, 0x20, /*"最",0*/
};
static const unsigned char PROGMEM da[]{
  0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFF, 0xE0, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00,
  0x11, 0x00, 0x11, 0x00, 0x20, 0x80, 0xC0, 0x60, /*"大",1*/
};
static const unsigned char PROGMEM shi2[]{
  0x00, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x97, 0xE0, 0x90, 0x40, 0xF0, 0x40, 0x92, 0x40, 0x91, 0x40,
  0x91, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x01, 0xC0, /*"时",0*/
};
static const unsigned char PROGMEM jian[]{
  0x4F, 0xE0, 0x20, 0x20, 0x00, 0x20, 0x5F, 0xA0, 0x50, 0xA0, 0x50, 0xA0, 0x5F, 0xA0, 0x50, 0xA0,
  0x50, 0xA0, 0x5F, 0xA0, 0x40, 0x20, 0x40, 0xE0, /*"间",0*/
};
static const unsigned char PROGMEM tong[]{
  0x9F, 0x80, 0x44, 0x80, 0x03, 0x00, 0x1F, 0xC0, 0xD2, 0x40, 0x5F, 0xC0, 0x52, 0x40, 0x5F, 0xC0,
  0x52, 0x40, 0x52, 0xC0, 0x40, 0x00, 0xBF, 0xE0, /*"通",0*/
};
static const unsigned char PROGMEM xin[]{
  0x40, 0x00, 0x2F, 0x80, 0x04, 0x80, 0x04, 0x80, 0xE4, 0x80, 0x2F, 0x80, 0x24, 0x80, 0x24, 0x80,
  0x24, 0x80, 0x34, 0xA0, 0x24, 0x60, 0x04, 0x20, /*"讯",1*/
};
static const unsigned char PROGMEM zhong[]{
  0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x7F, 0xC0, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x7F, 0xC0,
  0x44, 0x40, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, /*"中",2*/
};
static const unsigned char PROGMEM duan[]{
  0x10, 0x20, 0x55, 0xC0, 0xB9, 0x00, 0x91, 0x00, 0xFD, 0xE0, 0x91, 0x40, 0xB9, 0x40, 0xD5, 0x40,
  0x91, 0x40, 0x91, 0x40, 0xFD, 0x40, 0x02, 0x40, /*"断",3*/
};
static const unsigned char PROGMEM guo[]{
  0xFF, 0xE0, 0x80, 0x20, 0xBF, 0xA0, 0x84, 0x20, 0x84, 0x20, 0xBF, 0xA0, 0x85, 0x20, 0x84, 0xA0,
  0xFF, 0xE0, 0x80, 0x20, 0xFF, 0xE0, 0x80, 0x20, /*"国",1*/
};
static const unsigned char PROGMEM zhi[]{
  0x10, 0x20, 0x50, 0x20, 0x7D, 0x20, 0x91, 0x20, 0xFF, 0x20, 0x11, 0x20, 0x7D, 0x20, 0x55, 0x20,
  0x55, 0x20, 0x54, 0x20, 0x5C, 0x20, 0x10, 0xE0, /*"制",2*/
};
static const unsigned char PROGMEM zao[]{
  0x82, 0x00, 0x52, 0x00, 0x1F, 0xC0, 0x22, 0x00, 0xC2, 0x00, 0x7F, 0xE0, 0x40, 0x00, 0x5F, 0xC0,
  0x50, 0x40, 0x5F, 0xC0, 0x40, 0x00, 0xBF, 0xE0, /*"造",3*/
};
static const unsigned char PROGMEM zan[]{
  0x20, 0xC0, 0xFB, 0x00, 0x52, 0x00, 0x7B, 0xE0, 0x12, 0x40, 0xFA, 0x40, 0x14, 0x40, 0x3F, 0x80,
  0x20, 0x80, 0x3F, 0x80, 0x20, 0x80, 0x3F, 0x80, /*"暂",0*/
};
static const unsigned char PROGMEM ting[]{
  0x11, 0x00, 0x1F, 0xE0, 0x20, 0x00, 0x27, 0xC0, 0x64, 0x40, 0xA7, 0xC0, 0x20, 0x00, 0x2F, 0xE0,
  0x28, 0x20, 0x27, 0xC0, 0x21, 0x00, 0x23, 0x00, /*"停",1*/
};
static const unsigned char PROGMEM deng[]{
  0x42, 0x00, 0x7B, 0xE0, 0x94, 0x80, 0x04, 0x00, 0x7F, 0xC0, 0x04, 0x00, 0xFF, 0xE0, 0x01, 0x00,
  0xFF, 0xE0, 0x21, 0x00, 0x11, 0x00, 0x07, 0x00, /*"等",0*/
};
static const unsigned char PROGMEM dai[]{
  0x11, 0x00, 0x21, 0x00, 0x47, 0xC0, 0x91, 0x00, 0x2F, 0xE0, 0x60, 0x80, 0xAF, 0xE0, 0x20, 0x80,
  0x24, 0x80, 0x22, 0x80, 0x20, 0x80, 0x23, 0x80, /*"待",1*/
};
static const unsigned char PROGMEM jie[]{
  0x22, 0x00, 0x21, 0x00, 0x2F, 0xE0, 0xF4, 0x40, 0x22, 0x80, 0x2F, 0xE0, 0x31, 0x00, 0xEF, 0xE0,
  0x22, 0x40, 0x26, 0x40, 0x21, 0x80, 0x6E, 0x60, /*"接",2*/
};
static const unsigned char PROGMEM shou[]{
  0x12, 0x00, 0x92, 0x00, 0x92, 0x00, 0x93, 0xE0, 0x94, 0x40, 0x9A, 0x40, 0x92, 0x40, 0xB2, 0x80,
  0xD1, 0x00, 0x92, 0x80, 0x14, 0x40, 0x18, 0x20, /*"收",3*/
};
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
RF24 radio(6, 7);  // CE, CSN
const byte address[6] = "0000";
const byte address2[6] = "Space.ST";
int size = 12;  //中文字体大小
float a = 0;    // 初始化a
int time = 0;   // 初始化time
float b;
float c;
void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  Serial.begin(115200);
  if (!radio.begin()) {
    Serial.println("初始化失败");
    return;
  }
  Serial.println("初始化成功");
  radio.setPALevel(RF24_PA_MIN);
  radio.openReadingPipe(0, address);
  radio.openReadingPipe(1, address2);
  radio.startListening();  // 开启接收模式
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3c);
  oled.clearDisplay();
  oled.setTextSize(1);
  oled.setTextColor(1);
  for (int progress = 0; progress <= 100; progress++) {
    oled.clearDisplay();
    oled.setCursor(20, 0);
    oled.print("@Space-Traveler");
    oled.drawBitmap(39, 17, zhong, size, size, 1);
    oled.drawBitmap(52, 17, guo, size, size, 1);
    oled.drawBitmap(65, 17, zhi, size, size, 1);
    oled.drawBitmap(78, 17, zao, size, size, 1);
    oled.fillRect(10, 55, progress + 10, 10, 1);  // Draw progress bar
    oled.setCursor(25, 39);
    oled.print("Progress: ");
    oled.print(progress);
    oled.print("%");
    oled.display();
  }
  delay(1000);  // Wait for a second at the end
}
void loop() {
  b = a / 1000 * 9.8;
  if (c < b) { c = b; }
  uint8_t pipe;
  if (radio.available(&pipe)) {  // 使用whatPipe函数检查哪个管道有数据
    if (pipe == 0) {
      radio.read(&a, sizeof(a));
    } else if (pipe == 1) {
      // 读取数字数据
      radio.read(&time, sizeof(time));
    }
    oled.clearDisplay();
    oled.drawBitmap(0, 0, sh, size, size, 1);
    oled.drawBitmap(13, 0, shi, size, size, 1);
    oled.setCursor(25, 5);
    oled.print(":");
    oled.setCursor(30, 5);
    oled.print(b);
    oled.println("N");
    oled.drawBitmap(0, 20, zui, size, size, 1);
    oled.drawBitmap(13, 20, da, size, size, 1);
    oled.setCursor(25, 25);
    oled.print(":");
    oled.setCursor(30, 25);
    oled.print(c);
    oled.println("N");
    oled.drawBitmap(0, 40, shi2, size, size, 1);
    oled.drawBitmap(13, 40, jian, size, size, 1);
    oled.setCursor(25, 45);
    oled.print(":");
    oled.setCursor(30, 45);
    oled.print(time);
    oled.println("s");
    oled.display();  // 确保在显示新数据之前调用oled.display()
    Serial.print(b);
    Serial.print("N");
    Serial.print(" ");
    Serial.print(time);
    Serial.println("s");
    if (digitalRead(2) == 0) { c = 0; }
    if (digitalRead(3) == 0) {
      while (1) {
        oled.drawBitmap(100, 15, zan, size, size, 1);
        oled.drawBitmap(100, 28, ting, size, size, 1);
        oled.display();
        if (digitalRead(2) == 0) {
          digitalWrite(2, 1);
          delay(200);
          return;
        }
      }
    }
  } else {
    oled.clearDisplay();
    oled.drawBitmap(38, 25, tong, size, size, 1);
    oled.drawBitmap(51, 25, xin, size, size, 1);
    oled.drawBitmap(64, 25, zhong, size, size, 1);
    oled.drawBitmap(77, 25, duan, size, size, 1);
    oled.display();
  }
}

attachment iconsketch_sep28b.zip2.04KBZIP0次下载

以上为本次试车Mcu使用的所有代码


从我朋友那篇文章里原视频中,他的数据是采集到了的,120N左右(与理论推理偏差过大)

在试车之前已经调过校准了,目前不能断定也不能否决,是采集率的问题,虽然接收端的采集率只有20赫兹,但只是数据接收的速度过慢,但发送版的那部分数据采集是完全按照80赫兹进行工作,接收也可能是因为我额外加了oled作为显示,结果导致速率过慢了😓,这个是先前测试过的,但是为了方便观看就画蛇添足的加了一个

但这不能说明发送板采集有问题


目前暂时没有找到具体原因,测试之前,发送端的采集率达到80赫兹(不排除硬件问题),至于目前原因暂未找到,我们会进一步的进行查找和排除问题,另外如果我们的代码逻辑问题,希望大佬们能够指出


来自:航空航天 / 航天技术特殊话题:事故报告动手实践:实验报导
0
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也

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

所属专业
上级专业
同级专业
文件下载
加载中...
{{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)}}