文号D890088
706
1
收藏
编辑文章

请教(急) 什么开发板可以上传这个程序

#include <SD.h>
#include <HX711_ADC.h>
#include <EEPROM.h>
#include <U8g2lib.h>
#include <SimpleKalmanFilter.h>  // 引入卡尔曼滤波库

// 定义常量
const int REFRESH_INTERVAL_MS = 250;  // OLED 显示屏刷新间隔,单位:毫秒
const float DEFAULT_CALIBRATION_VALUE = 88.88;  // 默认校准值
const int FILTER_SIZE = 5;  // 中值滤波窗口大小
const float SAMPLING_INTERVAL = 0.1;  // 采样间隔,单位:秒

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

float i;
float time;
float time2;
float a;  // 声明变量 a
unsigned long lastRefreshTime = 0;  // 声明变量 lastRefreshTime

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;

SimpleKalmanFilter kalmanFilter(2, 2, 0.1);  // 初始化卡尔曼滤波器

float measurementBuffer[FILTER_SIZE];  // 用于存储测量值的缓冲区
int bufferIndex = 0;  // 缓冲区索引

unsigned long lastSamplingTime = 0;  // 记录上次采样的时间

/**
 * @brief 初始化 OLED 显示屏并显示准备信息和各模块状态
 */
void initDisplayAndShowStatus() {
  u8g2.begin();

  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(0, 16, "准备中...");

  // 检查 SD 卡是否可用
  if (SD.begin()) {
    u8g2.drawStr(0, 32, "SD 卡: 正常");
  } else {
    u8g2.drawStr(0, 32, "SD 卡: 异常");
  }

  // 检查 HX711 传感器是否初始化成功
  boolean hx711Initialized = false;
  LoadCell.begin();
  unsigned long stabilizingtime = 2000;  // tare 精度可通过增加稳定时间来提高
  boolean _tare = true;                // 如果不想在下一阶段执行 tare,将其设置为 false

  LoadCell.start(stabilizingtime, _tare);  // 去掉 if 语句,因为 start 函数返回 void

  if (LoadCell.getTareTimeoutFlag()) {
    u8g2.drawStr(0, 48, "HX711: 异常");
  } else {
    u8g2.drawStr(0, 48, "HX711: 正常");
  }

  u8g2.sendBuffer();
}

/**
 * @brief 处理 HX711 传感器的初始化和校准
 * @param calibrationValue 校准值
 */
void initAndCalibrateHX711(float calibrationValue) {
  // 已在 initDisplayAndShowStatus 中进行了部分初始化,此处继续完成校准等操作
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    return;
  } else {
    LoadCell.setCalFactor(calibrationValue);  // 设置校准因子(浮点数)
    Serial.println("Startup is complete");
  }
}

/**
 * @brief 刷新 OLED 显示屏的内容
 */
void refreshDisplay() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(0, 16, "当前推力:");

  char str[10];  // 用于存储转换后的字符串
  dtostrf(kalmanFilter.updateEstimate(i / 1000 * 9.8), 6, 2, str);  // 将浮点数转换为字符串
  u8g2.drawStr(80, 16, str);  // 使用转换后的字符串

  u8g2.drawStr(0, 32, "最大推力:");
  dtostrf(a / 1000 * 9.8, 6, 2, str);  // 将浮点数转换为字符串
  u8g2.drawStr(80, 32, str);  // 使用转换后的字符串

  u8g2.sendBuffer();
}

/**
 * @brief 处理数据采集和存储的主循环
 */
void mainLoop() {
  static boolean newDataReady = false;
  const int serialPrintInterval = 500;  // 增加该值可降低串口打印活动频率

  // 检查是否有新数据/开始下一次转换
  if (LoadCell.update()) {
    newDataReady = true;
  }

  // 获取数据集中的平滑值
  if (newDataReady) {
    i = LoadCell.getData();

    // 卡尔曼滤波
    float filteredValue = kalmanFilter.updateEstimate(i / 1000 * 9.8);

    if (filteredValue > a) {
      a = filteredValue;
    }

    Serial.print("当前推力:");
    Serial.print(i);
    Serial.print("g");
    Serial.print(" ");
    Serial.print("累计最大推力:");
    Serial.print(a);
    Serial.print("g");
    Serial.print(" ");
    Serial.print("累计最大 kg:");
    Serial.print(a / 1000);
    Serial.print("kg");
    Serial.print(" ");
    Serial.print("累计最大 N:");
    Serial.print(a / 1000 * 9.8);
    Serial.print("N");
    Serial.print(" ");
    Serial.print(time);
    Serial.print(" ");
    Serial.println(time2);  // 打印数据方便调试

    // 记录数据
    unsigned long currentMillis = millis();
    if (currentMillis - lastSamplingTime >= SAMPLING_INTERVAL * 1000) {
      File file = SD.open("test.txt", FILE_WRITE);
      if (file) {
        file.print(i);  // 数据输出
        file.print("        ");
        file.print(a);  // 数据输出
        file.print("        ");
        file.print(a / 1000);  // 单位转换 kg
        file.print("        ");
        file.print(a / 1000 * 9.8);  // 单位转换 N
        file.print("        ");
        file.print(time);  // 总共数据量用以计算时间
        file.print("        ");
        file.println(time2);  // 时间输出
        file.close();
        lastSamplingTime = currentMillis;
      } else {
        digitalWrite(8, HIGH);
        delay(150);
        digitalWrite(8, LOW);
        delay(150);  // 检测 SD 卡是否丢失
      }
    }
  }

  // 处理复位键操作
  if (digitalRead(3) == LOW) {
    LoadCell.tareNoDelay();
  }

  // 处理置零状态
  if (LoadCell.getTareStatus()) {  // 置零设置
    Serial.println("Tare complete");
    digitalWrite(8, LOW);
    a = 0.0;
  } else {
    digitalWrite(8, HIGH);
  }

  // 根据时间间隔刷新显示屏
  unsigned long currentMillis = millis();
  if (currentMillis - lastRefreshTime >= REFRESH_INTERVAL_MS) {
    refreshDisplay();
    lastRefreshTime = currentMillis;
  }
}

void setup() {
  Serial.begin(57600);
  pinMode(3, INPUT_PULLUP);  // 设置复位按键
  pinMode(8, OUTPUT);        // 设置蜂鸣器输出

  initDisplayAndShowStatus();

  float calibrationValue = DEFAULT_CALIBRATION_VALUE;  // 读取校准值或使用默认值

  initAndCalibrateHX711(calibrationValue);

  File file = SD.open("test.txt", FILE_WRITE);
  if (file) {
    file.println("            ");
    file.println("            ");
    file.println("以上数据作废 ");
    file.println("开始记录新数据:");
    file.println("数据从左到右是 当前推力(g) 最大推力(g) 最大推力(kg) 最大推力(N) 数据量 时间");
    file.close();
  }
}

void loop() {
  mainLoop();
}


1
yushu
2年2个月前 IP:浙江
D890838

STEM32

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

WEIZHANGLI
机友
文章
2
回复
15
学术分
-2
2024/06/16注册,1年2个月前活动

一名初中生

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:浙江
ID: {{ user.uid }}
投诉或举报
加载中...
{{ tip }}
请选择违规类型:
{{ reason.type }}

空空如也

加载中...
回复
设为精选取消精选
评学术分
鼓励
编辑
查看历史
通过审核
移动文章
加入收藏取消收藏
退修或删除
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{ format('YYYY/MM/DD HH:mm:ss', toc) }}
回复
加入收藏取消收藏