В этой статье мы рассмотрим устройство для измерения веса на основе платы Arduino, датчика нагрузки/веса (Load Cell) и модуля усиления HX711. Наверняка вы в различных магазинах видели весы различных конструкций, которые показывают вес вещей, размещенных на их платформе. В этом проекте мы рассмотрим создание аналогичных весов со взвешивающей способностью до 40 кг. В дальнейшем этот лимит (предел) взвешивания может быть увеличен при помощи использования более мощного датчика нагрузки.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Датчик нагрузки/веса (Load cell) 40kg (купить на AliExpress).
- Модуль усиления датчика нагрузки HX711 (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Соединительные провода.
- USB кабель.
- Макетная плата.
- Болты с гайкой, каркас и база.
Датчик веса и модуль усиления HX711
Датчик веса представляет собой полупроводник, который преобразует приложенные силу или давление в электрическое напряжение. Величина этого напряжения прямо пропорциональна приложенной к датчику силе. Датчик веса имеет измеритель деформации (strain gauge), который деформируется под действием приложенной силы (давления). Измеритель деформации генерирует электрический сигнал когда в результате деформации изменяется его эффективное сопротивление. Обычно датчик нагрузки состоит из 4-х измерителей деформации, объединенных по принципу моста Уитстона (моста для измерения сопротивления). Мы в нашем проекте будем использовать датчик нагрузки, способный измерять вес тел до 40 кг, однако производятся датчики нагрузки и с другим диапазоном измеряемых весов – до 5 кг, до 10 кг, до 100 кг и более.
Но электрические сигналы, генерируемые датчиком веса, весьма слабы – всего несколько милливольт. Поэтому перед их обработкой в плате Arduino они нуждаются в усилении – и для этой цели подходит модуль усиления датчика нагрузки HX711, показанный на нижеприведенном рисунке. Этот модуль содержит чип HX711, представляющий собой высокоточный 24-разрядный аналогово-цифровой преобразователь (АЦП). HX711 имеет два аналоговых входных канала, коэффициент усиления для которых можно программировать. Таким образом, модуль HX711 усиливает слабые электрические сигналы от датчика нагрузки и затем эти усиленные и оцифрованные сигналы подает на плату Arduino для их дальнейшей обработки (извлечения информации о весе).
Датчик нагрузки соединяется с модулем усиления HX711 с помощью 4 проводов: красного, черного, белого и зеленого/синего цвета. Возможны некоторые изменения цветовой гаммы этих проводов в зависимости от производителя модуля. Для соединения этих двух компонентов нашего устройства необходимо будет сделать следующие подключения как показано на ниже приведенном рисунке:
• красный провод - к E+;
• черный провод - к E-;
• белый провод - к A-;
• зеленый провод - к A+.
Установка датчика нагрузки на платформу и базу
Этот этап вы можете пропустить и не использовать никакой платформы/основания, но лучше все таки его сделать для более удобной работы с проектируемыми нами весами. Таким образом, нам необходимо сделать каркас или платформу, на которую мы потом будем класть вещи, вес которых мы хотим измерить. База (основание) также желательна для фиксации на ней датчика нагрузки с помощью болтов. В нашем проекте мы использовали жесткий картон для изготовления каркаса и деревянную доску в качестве базы/основания. Теперь нам осталось сделать всего лишь несколько соединений и наше устройство будет готово.
Работа схемы
Схема устройства представлена на следующем рисунке.
Для подключения ЖК дисплея его контакты RS, EN, d4, d5, d6, и d7 соединяются с контактами 8, 9, 10, 11, 12 и 13 платы Arduino соответственно. Контакты DT и SCK модуля HX711 непосредственно подключаются к контактам A0 и A1 платы Arduino. Соединение датчика нагрузки с модулем усиления HX711 было описано в предыдущем разделе статьи.
Перед началом работы устройства его необходимо откалибровать. Сразу после включения питания система автоматически начинает процесс собственной калибровки. Но если вы хотите откалибровать его вручную, то для этого необходимо будет нажать соответствующую кнопку. При нажатии этой кнопки будет запускаться функция void calibrate(), описанная в следующем разделе статьи.
Для начала процесса калибровки подождите пока на экране ЖК дисплея загорится надпись “put 100g” (положите 100 грамм), после этого положите 100 грамм на датчик нагрузки и подождите. Спустя несколько секунд процесс калибровки будет закончен. После этого вы можете класть на наши самодельные весы любую вещь массой до 40 кг и на экране ЖК дисплея высветится ее вес в граммах.
В этом проекте плата Arduino управляет всем процессом. Датчик нагрузки измеряет вес и передает электрический аналоговый сигнал на модуль усиления HX711, который усиливает и превращает в цифровую форму сигнал с выхода датчика нагрузки. Затем это усиленное значение сигнала подается на вход платы Arduino, которая измеряет величину этого сигнала, конвертирует его в значение веса в граммах и показывает его на ЖК дисплее. Кнопка используется для запуска процесса ручной калибровки устройства. Структурная схема работы нашего проекта показана на следующем рисунке.
Исходный код программы
Код программы, наверное, будет немного сложен для новичков, поскольку мы не использовали в нем библиотеку для работы с модулем HX711. Мы всего лишь изучили даташит на этот модуль и программировали работу с ним вручную. Хотя ряд имеющихся в свободном доступе библиотек могут значительно упростить процесс взаимодействия с этим модулем.
В программе первым делом мы должны подключить заголовочный файл библиотеки для работы с ЖК дисплеем и определить контакты платы Arduino, к которым он подключен. Также необходимо инициализировать контакт, к которому подключена кнопка. После этого необходимо инициализировать (объявить) ряд переменных, которые потребуются нам в дальнейшем.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
#define DT A0
#define SCK A1
#define sw 2
long sample=0;
float val=0;
long count=0;
После этого мы запрограммировали ниже приведенную функцию для чтения данных с модуля HX711.
unsigned long readCount(void)
{
unsigned long Count;
unsigned char i;
pinMode(DT, OUTPUT);
digitalWrite(DT,HIGH);
digitalWrite(SCK,LOW);
Count=0;
pinMode(DT, INPUT);
while(digitalRead(DT));
for (i=0;i<24;i++)
{
digitalWrite(SCK,HIGH);
Count=Count<<1;
digitalWrite(SCK,LOW);
if(digitalRead(DT))
Count++;
}
digitalWrite(SCK,HIGH);
Count=Count^0x800000;
digitalWrite(SCK,LOW);
return(Count);
}
После этого мы инициализировали ЖК дисплей и задали направление работы (на ввод или вывод данных) для используемых контактов в функции void setup().
void setup()
{
Serial.begin(9600);
pinMode(SCK, OUTPUT);
pinMode(sw, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.print(" Weight ");
lcd.setCursor(0,1);
lcd.print(" Measurement ");
delay(1000);
lcd.clear();
calibrate();
}
Далее, в функции void loop() мы считываем данные с модуля HX711, конвертируем их в значение веса (в граммах) и передаем их на ЖК дисплей.
void loop()
{
count= readCount();
int w=(((count-sample)/val)-2*((count-sample)/val));
Serial.print("weight:");
Serial.print((int)w);
Serial.println("g");
lcd.setCursor(0,0);
lcd.print("Weight ");
lcd.setCursor(0,1);
lcd.print(w);
lcd.print("g ");
if(digitalRead(sw)==0)
{
val=0;
sample=0;
w=0;
count=0;
calibrate();
}
}
Но перед этим мы создали функцию калибровки наших весов, которая калибрует их когда на датчике нагрузки находится тело массой 100 грамм.
void calibrate()
{
lcd.clear();
lcd.print("Calibrating...");
lcd.setCursor(0,1);
lcd.print("Please Wait...");
for(int i=0;i<100;i++)
{
count=readCount();
sample+=count;
Serial.println(count);
}
..... ....
..... .....
Далее приведен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
#include <LiquidCrystal.h> LiquidCrystal lcd(8, 9, 10, 11, 12, 13); #define DT A0 #define SCK A1 #define sw 2 long sample=0; float val=0; long count=0; unsigned long readCount(void) { unsigned long Count; unsigned char i; pinMode(DT, OUTPUT); digitalWrite(DT,HIGH); digitalWrite(SCK,LOW); Count=0; pinMode(DT, INPUT); while(digitalRead(DT)); for (i=0;i<24;i++) { digitalWrite(SCK,HIGH); Count=Count<<1; digitalWrite(SCK,LOW); if(digitalRead(DT)) Count++; } digitalWrite(SCK,HIGH); Count=Count^0x800000; digitalWrite(SCK,LOW); return(Count); } void setup() { Serial.begin(9600); pinMode(SCK, OUTPUT); pinMode(sw, INPUT_PULLUP); lcd.begin(16, 2); lcd.print(" Weight "); lcd.setCursor(0,1); lcd.print(" Measurement "); delay(1000); lcd.clear(); calibrate(); } void loop() { count= readCount(); int w=(((count-sample)/val)-2*((count-sample)/val)); Serial.print("weight:"); Serial.print((int)w); Serial.println("g"); lcd.setCursor(0,0); lcd.print("Weight "); lcd.setCursor(0,1); lcd.print(w); lcd.print("g "); if(digitalRead(sw)==0) { val=0; sample=0; w=0; count=0; calibrate(); } } void calibrate() { lcd.clear(); lcd.print("Calibrating..."); lcd.setCursor(0,1); lcd.print("Please Wait..."); for(int i=0;i<100;i++) { count=readCount(); sample+=count; Serial.println(count); } sample/=100; Serial.print("Avg:"); Serial.println(sample); lcd.clear(); lcd.print("Put 100g & wait"); count=0; while(count<1000) { count=readCount(); count=sample-count; Serial.println(count); } lcd.clear(); lcd.print("Please Wait...."); delay(2000); for(int i=0;i<100;i++) { count=readCount(); val+=sample-count; Serial.println(sample-count); } val=val/100.0; val=val/100.0; // put here your calibrating weight lcd.clear(); } |
Видео, демонстрирующее работу схемы
Также можете посмотреть еще одно достаточно подробное видео (на английском языке) как собрать весы на основе платы Arduino.
4 030 просмотров
А если на экране жк экрана только один символ появляется, вместо всей строки, то надо скачать последнюю версию LiquidCrystal_I2C и заменить библиотеку , удалив старую.
Да, можно попробовать такой вариант
У меня модуль экрана с кнопками с отдельным i2c преобразователем сигнала по команде lcd.backlight() зажигается и сразу тухнет. Для моего модуля эта команда оказалась командой выключения подсветки. Приходится включать подсветку командой lcd.setBacklight(0), соответственно выключать обратной lcd.setBacklight(1). Кажется приблизительно так была команда.
Показывает давление сферического коня в вакууме
Ну это тоже полезная информация )). Используемый в этой статье датчик - самый популярный сейчас для измерения веса. При помощи отладки проекта по частям можно попытаться найти на каком этапе у вас происходит ошибка
100г вообще не чувствовал, переделал совсем по другому, теперь работает. От авто калибровки отказался
Если не секрет, что переделали? Поделитесь опытом. Это поможет другим посетителям нашего сайта, которые будут реализовывать данный проект
Да взял просто пример, да прикрутил дисплей, требовалось измерять тягу моторов ESC
#define DT A1
#define SCK A0
#include "HX711.h"
#include
//#include
#include
//#include
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
float calibration_factor = 8.8; // калибровка!
float units;
float ounces;
HX711 scale;
void setup() {
Serial.begin(9600);
scale.begin(DT, SCK);
scale.tare(); //Сбрасываем на 0
scale.set_scale(calibration_factor); //Применяем калибровку
lcd.init(); // initialize the lcd
lcd.clear();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
delay(1000);
lcd.clear();
lcd.print(" Motor thrust");
lcd.setCursor(0, 1);
}
void loop() {
lcd.setCursor(0, 1);
for(int i = 0;i < 10; i ++) units =+ scale.get_units(), 10; // усредняем показания считав 10 раз
units / 10;
ounces = units * 0.035274;
//lcd.print("TIAGA ");
lcd.print(" ");
lcd.print(ounces, 2);
lcd.print("g");
delay(100);
lcd.print(" ");
scale.power_down(); // put the ADC in sleep mode
//lcd.clear();
scale.power_up();
}
Ну тоже неплохо. Спасибо что поделились секретом своего успеха