很好的教程,软件代码那一段很详细,很适合新手(ps:插在单片机上的杜邦线可以在连接紧密后打一点热熔胶固定,可以防止许多因杜邦线松动而导致的问题)
谢谢您的鼓励。我其实是比较建议直接焊上
UPD1:修正了单位
UPD2:修正了代码
在 kc 上有时会出现令人担忧的一幕:有些网友因为没有条件,使用砖头、石头、小土堆等可移动物进行试车。这不仅会导致无法知晓发动机的实际推力,更有可能会导致安全事故,机毁人伤。
为了避免以上问题,一个稳固的试车台就非常必要了。
这篇文章算是自己制作的一次日记。
试车台的主体框架使用铝型材这种方便连接、强度较高的材料制作,而推力采集部分使用 Arduino Uno 开发板和 hx711 制作。
先列出所需的材料和工具清单:
材料:
3030Q 铝型材 90 mm * 5
3030Q 铝型材 150 mm * 2
3030Q 铝型材 200 mm * 2(如果你觉得 200 mm 太短,可以适当加长)
3030 转向角件(套) * 4
3030 角码(套) * 4
3030 角槽(套) * 12
3030 铝型材 120mm 铝合金把手(套)(可选)
6mm 铝型材 T 母 * 2(以下两个直径需要根据你的传感器而定)
6mm 杯头螺丝 * 2(这个螺丝的长度需要根据你的传感器而定,稍后会讲)
不锈钢扎带/铁丝若干
国产 Arduino Uno * 1
hx711 模块 * 1
40/20 kg 称架 * 1(根据你设计的发动机推力选择,尽量买大的,不然很容易坏)
Micro SD 模块 * 1
Micro SD 卡 * 1(买 1GB 以下的,太大无法读取)
读卡器 * 1
杜邦线若干(可以买比较短的,方便)
工具:
电烙铁焊接套装
内六角扳手套装
十字螺丝刀
剪钳(可使用具有类似功能的工具替代)
Arduino Uno 方口数据线(可以使用部分打印机的数据线代替)
一台可以正常运行的电脑
3D 打印机及耗材(可选)
注意:以上名字后带“(套)”的紧固件需要你购买带螺丝、螺母的完整套件,一般商家有套装选项。
需要声明的是,本试车台的框架是参照的以太LYBing的方案(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)。
准备好了这些,就可以开始制作了。
如图,进行组装。
需要注意的是传感器的固定。你需要购买你的传感器高度(mm)+8mm左右的螺柱,可以长但不可以短。
将称架的两面亚克力拆下后,传感器侧面会有一个箭头,将箭头指向前方,使用 T 母和螺丝固定。在将亚克力顶面(不带防滑垫)装回即可。
固定时把你的铁丝/不锈钢扎带穿过角码两端的孔即可。
将称架连接线的端子用剪钳剪下,再用剪钳去除四根连接线的绝缘层。可以给每根数据线上锡(方便待会焊接)。
根据你的商家提供的资料,将四根不同颜色的线焊接到 hx711 上。我这里是红 E+ 黑 E- 白 A- 绿 A+。并将排针焊接在另一端。
用杜邦线连接 hx711、Micro SD 卡模块和 Arduino Uno,如图:
如果你使用的是 Arduino Nano 等其他开发板,请自行查阅文档。
然后我们要对可怜的 HX711 做一些小手术,以启动 80 Hz 采样。
如果你是如下这种,用剪钳去除红圈位置的铜箔,断开该引脚与地的连接。并用电烙铁给蓝色标注的两个引脚连锡。
如果你是下面这种,用老铁将红色位置的 0 欧电阻移到蓝色位置上。
原因如下:
我们刚刚所做的,其实就是给 RATE 脚接上高电平,使得其输出速率为 80Hz。
供电准备一个充电宝或者使用 DC 接口锂电池。
下载如下三个文件并放在同一目录下。
打开 Arudino IDE(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 下载 Windows 版本)并打开这三个文件。
用数据线连接电脑和 Arduino,查找新出现的 COM 口,点击旁边的小铅笔。
输入“Arduino Uno”,选择并确定。
接下来进行校准。
将试车台以传感器所在底竖立。确保传感器上无其他物品。
打开 HX711.cpp,发现第六行有一句代码
#define GapValue 204204 即是校准因子,接下来记作 k。
取一个已知重量(g)的物品,重量记为 m,这里我拿我的小水杯,301 g。
打开串口监视器,波特率 115200。
打开 HX711_5kg.ino,上传代码,这里可以先不插卡。
IDE 会自动完成所需库的安装。
上传完成后等几秒钟使系统完成初始化。
在一个 5000 左右的数字后(系统校准用时 ms),应当会滚动输出大量三个一组的数据,如图:
这些三个一组的数据分别对应时间(s)重量(g)重量(N)
此时可以放上你的物品,观察重量(g)的输出,记为 w。重量可能会有波动,你可以选 10 个取平均值。
用 k*w/m 得到新的校准因子,将 HX711.cpp 第六行的 204 改为你的校准因子。
重新上传 HX711_5kg.ino 检查是否有效,你可以手动微调提升效果。
断电插入 MicroSD 卡,重启 Arduino,进行数据记录的测试。
初始化完毕后随便在台上按几下,然后再次断电,取出 MicroSD 卡用读卡器读取。
可以找到一个 data.txt 文件,打开结果应当如图。
左侧栏为时间,右侧栏为推力(N)
每次开机,Arduino 都会在该文件后追加本次的采集结果(为什么不是覆盖?要是采完误触就炸了。),以“-----”分割。
如果你的测试全部通过,恭喜你制作成功!
做个外壳,万一磕坏了怎么办!
PLA 打印上面文件即可,是用树状支撑。
但是我不推荐你用我的外壳(做得比较匆忙,甚至忘记了留引出传感器数据线的洞),因为我没有设计任何卡紧结构,你需要用热熔胶粘住。而且外壳并不美观。
Q:没有找到 Arduino 的端口/上传失败。
A:可以手动安装一下 CH340 驱动。将报错信息丢给大模型,它很快就会告诉你问题。
Q:传感器一直返回 0.00,对压力完全没有反应。
A:多半是接错了或连接不良,使用万用表(别告诉我你没有)检查端点之间的连接。如果确定没有接线问题,那就大胆认定传感器或 HX711 坏了(这两个如果操作不当很容易坏掉),我做的时候就遇到了坏的传感器,更换后立马工作。
Q:MicroSD 卡里没有数据。
A:串口里应该会返回“SD card failed!”的信息,很可能是接线问题,检查一下。如果不是,格式化一下 MicroSD。
最后,希望各位都能完成自己的研究!
哈哈哈😁,原来是这样啊,那我的代码不就白写了但是各位kcer如果做出来发现串口数据乱跳可以采用我的代码,因为加了滤波算法
新版代码,加入卡尔曼滤波算法,滤波效果相对更加优秀,只需更改原版的hx711XXXXO.ino,其他步骤同文
不过lz说“然后加了一个TF卡检测”,我代码里不本来就有一个检测吗……
hx711XXXXO.ino:
#include <Arduino.h>
#line 1 "C:\\Users\\Acer\\Desktop\\HX711_5Kg\\HX711_5Kg.ino"
#include "HX711.h"
#include <SPI.h>
#include <SD.h>
float pretime = 0;
File sdcard;
const int cspin = 10;
#line 10 "C:\\Users\\Acer\\Desktop\\HX711_5Kg\\HX711_5Kg.ino"
void setup();
#line 42 "C:\\Users\\Acer\\Desktop\\HX711_5Kg\\HX711_5Kg.ino"
void loop();
#line 10 "C:\\Users\\Acer\\Desktop\\HX711_5Kg\\HX711_5Kg.ino"
void setup()
{
Init_Hx711(); //初始化 hx711
delay(3000);
Get_Maopi(); //初始化毛皮
Serial.begin(115200);
Serial.println("HX711 done.");
pinMode (cspin, OUTPUT);
if (!SD.begin (cspin)) { // SD 初始化并检测
Serial.println("SD card failed!");
}
else {
Serial.print("SD card done.\n");
sdcard = SD.open ("data.txt", FILE_WRITE);
if (sdcard) { // 文件读写测试
Serial.println("Opened data.txt!");
sdcard.println("---------------------------------");
sdcard.println("0.00 0.00");
sdcard.close();
} else {
Serial.println("Error opening data.txt!");
}
Serial.println("Start-----------------");
}
pretime = millis ();
Serial.println (pretime);
}
const double Q = 0.001, R = 0.5;
// 过程噪声方差 q(0.001~1),观测噪声方差 r(1~10)
// 根据不同传感器需要调整这两个参数
double p = 1, k, lastp = 1, ans = 0;
// p 初始估计误差方差,k 卡尔曼增益,lastp上次估计误差方差,ans 上次估计值
double kalman (double val) { // 卡尔曼滤波
// 预测
p = lastp + Q;
// 更新
k = p / (p + R);
ans = ans + k * (val - ans);
lastp = (1 - k) * p;
return ans;
}
void loop() {
float weight = Get_Weight ();
float now = (millis() - pretime) / 1000;
if (weight < 0)
weight = 0;
weight = kalman (weight); // 卡尔曼滤波
float force = weight / 1000 * 9.8;
Serial.print (now);
Serial.print (" ");
Serial.print (weight);
Serial.print ("g");
Serial.print (" ");
Serial.print (force);
Serial.println ("N");
sdcard = SD.open ("data.txt", FILE_WRITE);
sdcard.print (now);
sdcard.print (" ");
sdcard.println (force);
sdcard.close ();
}