数字负载秤是现代工程和设计的另一个奇迹。是的,我们谈论的是我们在大多数杂货店和其他地方经常看到的体重秤,但你有没有想过体重秤是如何工作的?为了回答这个问题,在这个项目中,我们将看看称重传感器及其工作原理。最后,我们将使用 HX711 重量传感器构建一个基于 Arduino 的便携式负载秤,它可以测量高达 10 公斤的重量。
这台称重机非常适合本地商店,他们在那里批量包装物品。与商业产品一样,我们的体重秤将有一个归零按钮,可将秤清零。此外,它具有设置重量进行测量的选项,当测量重量达到设定重量时,蜂鸣器快速响起,当设定重量等于测量重量时停止。这样,用户只需听到声音就可以打包,而不必看显示器。由于这是一个非常简单的项目,我们将使用 Arduino 和应变计称重传感器等组件非常轻松地构建它。所以,事不宜迟,让我们开始吧。
Arduino称重机工作
该项目的主要部件是一个称重传感器和HX711 称重传感器放大器模块。如您所见,一侧标有十公斤。另外,您会注意到称重传感器上方有某种白色保护胶,并出现了四种不同颜色的电线,将在本文后面揭开白色保护胶下面的秘密以及这些四色电线的功能。
称重传感器是将力或压力转换为电输出的传感器。它有两个侧面,比如说右侧和左侧,它是由铝块制成的。正如你所看到的,材料的中间通过放一个大孔变薄了。这就是为什么当负载放置在安装侧时会发生变形的点。现在想象一下,右侧传感器安装在底座上,左侧是放置负载的位置,由于中间的巨大孔,这种配置会使应变仪称重传感器变形。
当负载放在称重传感器的负载侧时,顶部会受到拉力,而底部会受到压力。这就是铝条在左侧向下弯曲的原因。如果我们测量这种变形,我们可以测量施加在铝块上的力,这正是我们要做的。
现在,问题仍然是白色保护胶里面是什么?在这种保护胶里面,我们会发现一个非常薄的弹性元件,叫做应变仪。 应变计是用于测量应变的组件。如果我们仔细观察这个组件,我们可以看到两个连接焊盘,然后我们有一个重复偏转的导线图案。该导线具有确定的电阻。当我们弯曲它时,电阻值会改变吗?因此,将应变片的一侧安装并固定在一个地方,如果我们在铝棒的另一侧放置一个重物,这将迫使应变片弯曲,从而导致电阻发生变化。这实际上是如何发生的?应变片的导电图案是用铜做的,这根导线会有一定的面积和长度,所以这两个单元会给出导线的电阻。导线的电阻与电流的流动相反。现在很明显 如果这条线的面积变小了 更少的电子可以通过意味着更低的电流。现在,如果我们增加面积,它将增加导体的电阻。如果对该线施加一些力,这将拉伸该区域,同时它会变小,电阻会增加。但是这种电阻变化非常小。如果我们拉伸应变片,电阻会增加,如果我们压缩它,电阻会变小。为了测量力,我们需要测量阻力。直接测量电阻并不总是可行的,因为变化非常小。因此,我们可以轻松地测量电压,而不是测量电阻。因此,在这种情况下,我们需要将仪表输出从电阻值转换为电压值。如果对该线施加一些力,这将拉伸该区域,同时它会变小,电阻会增加。但是这种电阻变化非常小。如果我们拉伸应变片,电阻会增加,如果我们压缩它,电阻会变小。为了测量力,我们需要测量阻力。直接测量电阻并不总是可行的,因为变化非常小。因此,我们可以轻松地测量电压,而不是测量电阻。因此,在这种情况下,我们需要将仪表输出从电阻值转换为电压值。如果对该线施加一些力,这将拉伸该区域,同时它会变小,电阻会增加。但是这种电阻变化非常小。如果我们拉伸应变片,电阻会增加,如果我们压缩它,电阻会变小。为了测量力,我们需要测量阻力。直接测量电阻并不总是可行的,因为变化非常小。因此,我们可以轻松地测量电压,而不是测量电阻。因此,在这种情况下,我们需要将仪表输出从电阻值转换为电压值。阻力会越来越低。为了测量力,我们需要测量阻力。直接测量电阻并不总是可行的,因为变化非常小。因此,我们可以轻松地测量电压,而不是测量电阻。因此,在这种情况下,我们需要将仪表输出从电阻值转换为电压值。阻力会越来越低。为了测量力,我们需要测量阻力。直接测量电阻并不总是可行的,因为变化非常小。因此,我们可以轻松地测量电压,而不是测量电阻。因此,在这种情况下,我们需要将仪表输出从电阻值转换为电压值。
我们可以在惠斯通电桥的帮助下做到这一点。如果电桥是平衡的,我们将应变计放置在惠斯通电桥中,中间点的电压应该为零(之前我们已经建立了一个项目,其中我们描述了惠斯通电桥的工作原理,如果你想你可以检查一下了解有关该主题的更多信息)。当应变片改变其电阻时,会使电桥失衡,电压也会发生变化。因此,这就是惠斯通电桥将电阻变化转换为电压值的方式。
但是这个电压变化还是很小的,所以要增加它,我们需要使用HX711模块。HX711 是一个 24 位差分 ADC,通过这种方式,我们可以测量非常小的电压变化。它将给出从 0 到 2 的指数 24 的值。
基于 Arduino 的称重机所需的组件
为了使这个项目尽可能简单,我们使用了非常通用的组件,您可以在任何本地爱好商店中找到这些组件。下图将让您了解组件。此外,我们还有下面列出的物料清单 (BOM)。
称重传感器(我们使用的是 10 kg 称重传感器)
HX 711 功放模块
Arduino纳米
I2C LCD 16X2 – I2C 兼容
1k电阻-2个
LED -2Nos
蜂鸣器
普通PCB
7.4V电池(如果你想要它便携)
LM7805稳压器
基于 Arduino 的称重机 - 电路图
称重传感器有四根电线,分别是红、黑、绿和白。此颜色可能因制造商而异,因此最好参考数据表。红色接HX711板子的E+,黑色接E-,白色接A+,绿色接A-,Dout,板子时钟分别接D4和D5。将按钮的一端连接到 D3、D8、D9,另一端接地。我们有 I2C LCD,所以将 SDA 连接到 A4,将 SCL 连接到 A5。将 LCD、HX711 和 Arduino 的地连接到地,同时将 VCC 连接到Arduino的 5Vpin 。所有模块都在 5V 下工作,因此我们添加了一个LM7805 稳压器。如果您不希望它便携,您可以使用 USB 电缆直接为 Arduino 供电。
在虚线穿孔板上制作电路
我们已将所有组件焊接在一个普通的点状穿孔板上。我们使用母头将 Arduino 和 ADC 与电路板焊接,我们还使用电线连接所有按钮和 LED。完成所有焊接过程后,我们已确保从 LM7805 输出正确的 5V。最后,我们设置了一个开关来打开/关闭电路。一旦我们都完成了,它看起来像下面的图像。
为基于 Arduino 的称重机构建外壳
如您所见,称重传感器有一些螺纹,因此我们可以将其安装在底板上。我们将使用 PVC 板作为秤的底座,为此,我们首先从 PVC 板上切割出 20*20 厘米的正方形和四个 20*5 的矩形。然后使用硬胶,我们把每一块都粘起来,做成一个小外壳。
请记住,我们没有固定一侧,因为我们需要在其上放置按钮、LED 和 LCD。然后我们在秤的顶部使用了一块塑料板。在永久设置此设置之前,我们需要确保从地面到称重传感器有足够的空间,以便它能够弯曲,所以我们在称重传感器和底座之间放置了螺钉和螺母,我们还添加了称重传感器和顶部之间的一些塑料垫片。我们使用圆形塑料板作为平衡的顶级智能。
然后我们将LCD、LED和按钮放在前面板上,所有东西都用长绝缘线连接。完成布线后,我们将前面板倾斜地粘在主底座上,这样我们就可以很容易地从 LCD 读取值。最后,我们将主开关连接到天平的一侧,就是这样。这就是我们为体重秤制作身体的方式。
您可以根据自己的想法进行设计,但请记住将称重传感器放置在图像中。
Arduino称重机 - 代码
由于我们现在完成了数字秤的构建过程,我们可以进入编程部分。为了方便编程,我们将使用 HX711 库、EEPROM 库和LiquidCrystal 库。您可以从官方 GitHub 存储库下载HX711 库,或者转到工具》包含 库》管理 库,然后使用关键字HX711搜索库,下载库后,将其安装到 Arduino ide 中。
首先,我们需要校准称重传感器并将该值存储在 EEPROM 中,为此,转到文件 》 示例 》 HX 711_ADC, 然后选择校准代码。在上传代码之前,将天平放在稳定的平面上。然后将代码上传到 Arduino 并打开串行监视器。然后将波特率更改为 572600。现在监视器要求称重,为此我们需要按 t 并输入。
现在,我们需要将已知重量放在天平上,在我的例子中,即 194gm。放置已知重量后,在串行监视器上输入重量,然后按 Enter。
现在,串行监视器询问您是否要将值保存在 EEPROM 中,因此请键入 Y 选择是。现在我们可以在串行监视器上看到重量。
该项目的主要代码,我们从 HX711 库的示例草图开发。您可以从下面下载该项目的代码。
在编码部分,首先,我们添加了所有三个库。HX711 库用于获取称重传感器值。EEPROM是Arduino ide的内置库,用于将值存储在EEPROM中,LiquidCrystal库用于l2C LCD模块。
#include
#include
#include
然后为不同的引脚定义整数并分配值。HX711_ADC 称重传感器功能用于设置 Dout 和时钟引脚。
常量 int HX711_dout = 4;
常量 int HX711_sck = 5;
诠释 tpin = 3;
HX711_ADC LoadCell(HX711_dout, HX711_sck);
常量 int calVal_eepromAdress = 0;
长 t;
常量 int Up_buttonPin = 9;
常量 int Down_buttonPin = 8;
浮动按钮PushCounter = 0;
浮动 up_buttonState = 0;
浮动 up_lastButtonState = 0;
浮动 down_buttonState = 0;
浮动 down_lastButtonState = 0;
在设置部分,我们首先启动了串口监视器,这只是为了调试。然后我们定义了引脚模式,所有按钮都定义为输入。在 Arduino PULL UP 功能的帮助下,我们通常将引脚设置为逻辑高电平。因此,我们不想为此使用任何外部电阻器。
pinMode(tpin,INPUT_PULLUP);
pinMode(6,输出);
pinMode(12,输出);
pinMode(Up_buttonPin,INPUT_PULLUP);
pinMode( Down_buttonPin , INPUT_PULLUP);
以下代码行用于设置 I2C LCD。首先,我们使用LCD.print()函数显示欢迎文本,两秒钟后,我们使用lcd.clear ()清除显示。也就是说,一开始,显示器显示ARDUINO BALANCE作为欢迎文字,两秒钟后,它会清除并显示测量重量。
液晶显示器();
液晶背光();
lcd.setCursor(0, 0);
lcd.print("ARDUINO 平衡");
lcd.setCursor(0, 1);
lcd.print("让我们测量一下");
延迟(2000);
lcd.clear();
然后开始使用loadCell.begin()函数从称重传感器读取值,之后,我们读取校准值的 EEPROM,我们使用EEPROM.get()函数来完成。也就是说,我们已经使用校准草图将值存储在 EEPROM地址中,我们只需重新获取该值。
LoadCell.begin();
EEPROM.get(calVal_eepromAdress,calibraTIonValue);
在循环部分,首先,我们使用LoadCell.update( )检查来自称重传感器的任何数据是否可用,如果可用,我们读取并存储该数据,为此,我们使用LoadCell.getData()。接下来,我们需要在 LCD 中显示存储的值。为此,我们使用了LCD.print()函数。另外,我们打印设定的重量。设置重量是在按钮计数器的帮助下设置的。这在上一节中解释了。
if (LoadCell.update()) newDataReady = true;
if (newDataReady)
{
if (millis() > t + serialPrinTInterval) {
float i = LoadCell.getData();
lcd.setCursor(0, 0);
lcd.print("设置 wei:");
lcd.setCursor(9, 0);
lcd.print(buttonPushCounter);
lcd.setCursor(14, 0);
lcd.print("GM");
lcd.setCursor(0, 1);
lcd.print("重量:");
lcd.setCursor(9, 1);
lcd.print(i);
lcd.setCursor(14, 1);
lcd.print("GM");
接下来,我们设置皮重值,为此,首先,我们使用 digitalRead()函数读取皮重按钮的状态,如果状态低,我们将该重量去皮为零。该体重秤的去皮功能是将读数归零。例如,如果我们有一个装有东西的碗,那么净重将是碗的重量 + 东西的重量。如果我们在装东西之前用称重传感器上的碗按下去皮按钮,篮子的重量将被抵消,我们可以单独测量东西的重量。
if (digitalRead(tpin) == LOW) {
LoadCell.tareNoDelay();
现在,我们需要设置不同指示的条件,例如设置蜂鸣器的延迟和 LED 状态。我们使用if 条件来做到这一点,我们总共有三个条件。首先,我们计算设定重量和测量重量之间的差值,然后将该值存储在变量 k 中。
浮动 k = buttonPushCounter-i ;
1.如果设定重量和测量重量的差值大于等于50gms,蜂鸣器会延迟200毫秒(慢)发出蜂鸣声。
if ( k >= 50 )
{
digitalWrite (6, HIGH);
延迟(200);
数字写入(6,低);
延迟(200);
}
2.如果设定重量与测量重量的差值小于 50 克且大于 1 克,蜂鸣器会延迟 50 毫秒(更快)发出蜂鸣声。
if ( k < 50 && k > 1 )
{
digitalWrite (6, HIGH);
延迟(50);
数字写入(6,低);
延迟(50);
}
3、当计量重量等于或大于设定值时,绿灯亮,蜂鸣器和红灯灭。
if(i>=buttonPushCounter)
{
digitalWrite (6, LOW);
数字写入(12,高);
}
我们还有两个 void 函数 () 用于设置设定重量(用于计算按钮按下)。
每按一次设定值增加10gms的功能。这是通过使用 Arduino 的digitalRead功能来完成的,如果引脚为低电平,这意味着按钮被按下,并且该值将增加 10gms。
up_buttonState = digitalRead(Up_buttonPin);
if (up_buttonState != up_lastButtonState) {
if (up_buttonState == LOW) {
bPress = true;
buttonPushCounter = buttonPushCounter + 10;
}
相似地,
checkdown 用于每按一次将设定值减少 10gms。
down_buttonState = digitalRead(Down_buttonPin);
if (down_buttonState != down_lastButtonState) {
if (down_buttonState == LOW) {
bPress = true;
buttonPushCounter = buttonPushCounter - 10;
}
这标志着编程部分的结束。
这种基于 Arduino 的电子秤非常适合测量高达 10 公斤的重量(我们可以通过使用更高额定的称重传感器来增加这个限制)。这与原始测量结果的准确度为 99%。
#include
#include
#include
LiquidCrystal_I2C lcd(0x27, 2, 16);
HX711_ADC LoadCell(HX711_dout, HX711_sck);
常量 int HX711_dout = 4; //mcu > HX711 输出引脚
常量 int HX711_sck = 5; //mcu > HX711 sck管脚
诠释 tpin = 3;
常量 int calVal_eepromAdress = 0;
长 t;
常量 int Up_buttonPin = 9; // 按钮所连接的引脚
常量 int Down_buttonPin = 8;
浮动按钮PushCounter = 0; // 按钮按下次数的计数器
浮动 up_buttonState = 0; // 向上按钮的当前状态
浮动 up_lastButtonState = 0; //向上按钮的前一个状态
浮动 down_buttonState = 0; // 向上按钮的当前状态
浮动 down_lastButtonState = 0; //向上按钮的前一个状态
布尔 bPress = 假;
无效设置(){
序列号.开始(57600);
延迟(10);
序列号.println();
Serial.println("开始...");
pinMode(tpin,INPUT_PULLUP);
pinMode(6,输出);
pinMode(12,输出);
pinMode(Up_buttonPin,INPUT_PULLUP);
pinMode( Down_buttonPin , INPUT_PULLUP);
液晶显示器();
液晶背光();
lcd.setCursor(0, 0);
lcd.print("ARDUINO 平衡");
lcd.setCursor(0, 1);
lcd.print("让我们测量一下");
延迟(2000);
lcd.clear();
LoadCell.begin();
浮动校准值;// 校准值(参见示例文件“CalibraTIon.ino”)
校准值 = 696.0;// 如果要在草图中设置校准值,请取消注释
#如果定义(ESP8266)|| 定义(ESP32)
//EEPROM.begin(512); // 如果您使用 ESP8266/ESP32 并想从 eeprom 获取校准值,请取消注释
#万一
EEPROM.get(calVal_eepromAdress,calibraTIonValue); // 如果要从 eeprom 获取校准值,请取消注释
稳定时间长 = 2000;// 加电后的精度可以通过增加几秒钟的稳定时间来提高
布尔_皮重=真;//如果您不希望在下一步中执行去皮,请将其设置为 false
LoadCell.start(稳定时间,_皮重);
if (LoadCell.getTareTimeoutFlag())
{
Serial.println("超时,检查 MCU>HX711 接线和引脚名称");
而(1);
}
别的
{
LoadCell.setCalFactor(校准值);//设置校准值(浮点数)
Serial.println("启动完成");
}
}
无效循环(){
静态布尔 newDataReady = 0;
常量 int serialPrintInterval = 0; //增加值以减慢串行打印活动
// 检查新数据/开始下一次转换:
if (LoadCell.update()) newDataReady = true;
// 从数据集中获取平滑值:
如果(新数据就绪)
{
if (millis() > t + serialPrintInterval) {
浮动 i = LoadCell.getData();
Serial.print("Load_cell 输出值:");
序列号.println(i);
新数据就绪 = 0;
t = 毫秒();
lcd.setCursor(0, 0);
lcd.print("设置 wei:");
lcd.setCursor(9, 0);
lcd.print(buttonPushCounter);
lcd.setCursor(14, 0);
lcd.print("GM");
lcd.setCursor(0, 1);
lcd.print("重量:");
lcd.setCursor(9, 1);
lcd.print(i);
lcd.setCursor(14, 1);
lcd.print("GM");
}
}
清理();
checkDown();
如果(数字读取(tpin)==低){
LoadCell.tareNoDelay();
}
// 检查最后一次去皮操作是否完成:
if (LoadCell.getTareStatus() == true) {
lcd.clear();
lcd.print("去皮完成");
延迟(1000);
lcd.clear();
}
浮动 i = LoadCell.getData();
浮动 k = buttonPushCounter - i;
如果 ( k < 50 && k > 1 )
{
数字写入(6,高);
延迟(50);
数字写入(6,低);
延迟(50);
}
如果 ( k >= 50 )
{
数字写入(6,高);
延迟(200);
数字写入(6,低);
延迟(200);
}
if (i >= buttonPushCounter)
{
数字写入(6,低);
数字写入(12,高);
}
别的
{
数字写入(12,低);
}
}
无效检查()
{
up_buttonState = digitalRead(Up_buttonPin);
// 比较 buttonState 和之前的状态
if (up_buttonState != up_lastButtonState)
{
// 如果状态已经改变,增加计数器
如果(up_buttonState == LOW)
{
bPress =真;
// 如果当前状态为 HIGH,则按钮从关闭变为打开:
buttonPushCounter = buttonPushCounter + 10;
}
}
// 将当前状态保存为上一个状态,以备下次循环使用
up_lastButtonState = up_buttonState;
}
无效 checkDown()
{
down_buttonState = digitalRead(Down_buttonPin);
// 比较 buttonState 和之前的状态
if (down_buttonState != down_lastButtonState)
{
// 如果状态已经改变,增加计数器
如果(down_buttonState == LOW)
{
bPress =真;
buttonPushCounter = buttonPushCounter - 10;
}
}
// 将当前状态保存为上一个状态,以备下次循环使用
down_lastButtonState = down_buttonState;
}