Вага на Arduino Nano і тензодатчиках

Огляди та теми присвячені використанню тензорних датчиків ваги, тиску, барометрів, побудові електроних ваг та регулюванню тиску води
Відповісти
Аватар користувача
Arduino
Site Admin
Повідомлень: 100
З нами з: 16 травня 2017 18:18

Вага на Arduino Nano і тензодатчиках

Повідомлення Arduino »

Як зробити ваги на Ардуіно своїми руками? Опис та програмний код
Необхідно:
1. Arduino контролер (Nano, UNO ...)
2. LED module -індикатор
3. HX711 - модуль обробки даних тензодатчиків
4. Модуль - радіопередавач даних 433MHz TX

Принцип вимірювання ваги досить простий: навантаження змінює опір тензодатчиков, що закономірно виливається в зміну напруги на виході моста. Причому напруга змінюється лінійно залежно від ваги. Загалом, все добре, якби не одне але: вихідна напруга моста занадто мала, щоб вимірювати його безпосередньо АЦП Arduino. Для успіху необхідний відповідний підсилювач - з досить великим коефіцієнтом посилення, з досить малим шумом.
Це і є модуль HX711
vagy-1.jpg
Підключення тензодатчиків до модуля цифрового перетворювача HX711
Фактично цей модуль є АЦП з підсилювачем
vagy-Hx711.jpg

Код: Виділити все

#include <Arduino.h>
#include <TM1637Display.h> 
#include <HX711.h>
#include <VirtualWire.h>
#include <EEPROM.h>
//
#define DISPLAY_CLK      2    // digital pin connected to display
#define DISPLAY_DIO      3    // digital pin connected to display
#define BUTTON_MINUS_PIN 6    // digital pin connected to button
#define BUTTON_PLUS_PIN  7    // digital pin connected to button
#define SOUND_PIN       11    // digital pin connected to sound buzzer
#define RF_TX_PIN       12    // digital pin connected to RF TX 433 MHz
//
#define NumTimesIdle    5
#define NumTimesMeasure 15
//
const uint8_t SEG_CLEAR[] = {0,0,0,0};
const uint8_t SEG_DELIM[] = {SEG_G};
const uint8_t SEG_1[] = { SEG_C | SEG_D | SEG_E | SEG_G,
                          SEG_A | SEG_B | SEG_F | SEG_G,
                          SEG_C | SEG_D | SEG_E | SEG_G,
                          SEG_A | SEG_B | SEG_F | SEG_G };
const uint8_t SEG_2[] = { SEG_A | SEG_B | SEG_F | SEG_G,
                          SEG_C | SEG_D | SEG_E | SEG_G,
                          SEG_A | SEG_B | SEG_F | SEG_G,
                          SEG_C | SEG_D | SEG_E | SEG_G }; 
//
HX711 scale(A1, A0);         // A1 - DOUT , A0 - SCK
TM1637Display display(DISPLAY_CLK, DISPLAY_DIO); 
// -------------------------------------------------
// setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 0); 
// This function receives raw segment values as input and displays them. The segment data
// is given as a byte array, each byte corresponding to a single digit. Within each byte,
// bit 0 is segment A, bit 1 is segment B etc.
// segments     - array of size @ref length containing the raw segment values
// length       - number of digits to be modified
// pos          - position from which to start the modification (0 - leftmost, 3 - rightmost)
// -------------------------------------------------
// showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
// num          - number to be shown
// leading_zero - when true, leading zeros are displayed. Otherwise unnecessary digits are blank
// length       - number of digits to set
// pos          - position least significant digit (0 - lefttmost, 3 - leftmost)  
// -------------------------------------------------
//
unsigned long LastTareCheckMillis = 0;
unsigned long LastTareCheckMillisMAX = 60000;
unsigned long LastDisplayWeightMillis = 0;
unsigned long LastDisplayWeightMillisMAX = 5000;
float CurScale = 4120.f; // default 2280.f
byte  NumTimes = NumTimesIdle;
byte  WeightCounter = 0;
byte  MaxWeightCounter = 5;
float CurWeight = 0;
float MinWeight = 1; // kg
float FinishWeight = 0;
boolean seg_selector;
//
void setup() 
{
// for RF TX
vw_set_ptt_pin(RF_TX_PIN);
vw_set_tx_pin(RF_TX_PIN);
vw_setup(2000);	 // Bits per sec
pinMode(BUTTON_MINUS_PIN, INPUT);
pinMode(BUTTON_PLUS_PIN, INPUT);
pinMode(SOUND_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("");
Serial.println("A.V. SmartScales.");
CurScale = (float) EEPROMReadInt(0);
if (CurScale < 1000) { CurScale = 4426.f; }
Serial.print("CurScale = ");
Serial.println(CurScale,2);
ScalesInit();
LastTareCheckMillis = millis();
}
//
void loop() 
{
// Check buttons
if ( digitalRead(BUTTON_PLUS_PIN) )
 {
 PlayTone(SOUND_PIN,4000,50);
 CurScale = CurScale + 10;  
 Serial.print("BUTTON_PLUS. CurScale = ");
 Serial.println(CurScale,2);
 EEPROMWriteInt(0, int(CurScale));
 display.setSegments(SEG_CLEAR); // display clear
 display.showNumberDec(int(CurScale),true,4,0); 
 LastTareCheckMillis = millis();
 LastDisplayWeightMillis = millis();
 }
if ( digitalRead(BUTTON_MINUS_PIN) )
 {
 PlayTone(SOUND_PIN,4000,50);
 CurScale = CurScale - 10;  
 scale.set_scale(CurScale);
 Serial.print("BUTTON_MINUS. CurScale = ");
 Serial.println(CurScale,2);
 EEPROMWriteInt(0, int(CurScale));
 display.setSegments(SEG_CLEAR); // display clear
 display.showNumberDec(int(CurScale),true,4,0); 
 LastTareCheckMillis = millis();
 LastDisplayWeightMillis = millis();
 }
// Calculate weight
CurWeight = scale.get_units(NumTimes) * 1000 / CurScale;
if ( CurWeight > MinWeight )
 {
 NumTimes = NumTimesMeasure;
 LastDisplayWeightMillis = millis();
 if ( WeightCounter <= MaxWeightCounter )
  {
  if ( WeightCounter > 0 ) 
   {
   if ( WeightCounter < MaxWeightCounter ) 
    {
    PlayTone(SOUND_PIN, 800 + WeightCounter * 800 ,50); 
    display.setBrightness(WeightCounter + 10); // from 8 to 15
    if (seg_selector) { display.setSegments(SEG_1); } else { display.setSegments(SEG_2); }
    seg_selector = !seg_selector;
    }
   FinishWeight = FinishWeight + CurWeight; 
   }
  if ( WeightCounter == MaxWeightCounter )
   {
   PlayTone(SOUND_PIN,4000,50); delay(50);
   PlayTone(SOUND_PIN,3000,50); delay(50);
   PlayTone(SOUND_PIN,4000,50);
   FinishWeight = FinishWeight / (int)MaxWeightCounter;
   display.setSegments(SEG_CLEAR); // display clear
   display.setSegments(SEG_DELIM,1,2); // display delimiter
   display.showNumberDec(int(FinishWeight),true,2,0); 
   display.showNumberDec(int((FinishWeight - int(FinishWeight)) * 10),true,1,3); 
   Serial.print(" WEIGHT = ");
   Serial.println(FinishWeight,2);
   SendWeight();
   LastTareCheckMillis = millis();
   LastDisplayWeightMillis = millis();
   }
  }
 else { WeightCounter = (MaxWeightCounter + 1); }
 WeightCounter++;
 }
else
 {
 WeightCounter = 0;
 NumTimes = NumTimesIdle;
 FinishWeight = 0;
 if ( millis() < LastDisplayWeightMillis ) { LastDisplayWeightMillis = millis(); } // after millis() overflow
 if ( millis() - LastDisplayWeightMillis > LastDisplayWeightMillisMAX ) 
  {
  if ( LastDisplayWeightMillis != 0 ) { ScalesInit(); }
  LastDisplayWeightMillis = 0;
  }
 if ( millis() < LastTareCheckMillis ) { LastTareCheckMillis = millis(); } // after millis() overflow
 if ( millis() - LastTareCheckMillis > LastTareCheckMillisMAX )
  {
  if ( (CurWeight >= 0.01) || (CurWeight <= -0.01) )
   {  
   display.setSegments(SEG_1);
   Serial.println("Set tare...");
   ScalesInit();
   } 
  LastTareCheckMillis = millis();
  }
 } // if ( CurWeight > MinWeight )
//
Serial.println(CurWeight,3);
}

//////////////////////////////////////////////////////////////////
void PlayTone(byte tonePin, int frequency, int duration)
{
int period = 1000000L / frequency;
int pulse = period / 2;
for (long i = 0; i < duration * 1000L; i += period)
 {
 digitalWrite(tonePin, HIGH);
 delayMicroseconds(pulse);
 digitalWrite(tonePin, LOW);
 delayMicroseconds(pulse);
 }
}

void SendWeight()
{
////////// RF Send
char RFMessage[28];
String RFtemp;
// RFtemp = "Sgg.gg/";
// gg.gg - weight
RFtemp = "S";
RFtemp = RFtemp + int(FinishWeight) + ".";
if ( int((FinishWeight - int(FinishWeight)) * 100) > 9 )
 { RFtemp = RFtemp + int((FinishWeight - int(FinishWeight)) * 100); }
else
 { RFtemp = RFtemp + "0"; RFtemp = RFtemp + int((FinishWeight - int(FinishWeight)) * 100); }
RFtemp = RFtemp + "/";
RFtemp.toCharArray(RFMessage,RFtemp.length()+1);
int jj;
for ( jj = 0; jj < 5; jj++ )
 {
 delay(50);
 vw_send((uint8_t *)RFMessage, strlen(RFMessage));
 vw_wait_tx();
 }
Serial.print("RFtemp = ");
Serial.println(RFtemp);
}

void EEPROMWriteInt(int p_address, int p_value)
// This function will write a 2 byte integer to the eeprom at the specified address and address + 1
{
byte lowByte = ((p_value >> 0) & 0xFF);
byte highByte = ((p_value >> 8) & 0xFF);
EEPROM.write(p_address, lowByte);
EEPROM.write(p_address + 1, highByte);
}

unsigned int EEPROMReadInt(int p_address)
// This function will read a 2 byte integer from the eeprom at the specified address and address + 1
{
byte lowByte = EEPROM.read(p_address);
byte highByte = EEPROM.read(p_address + 1);
if ( (((lowByte << 0) & 0xFF) == 0xFF) && (((highByte << 0) & 0xFF) == 0xFF) ) return 0;
                       else return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

void ScalesInit()
{
display.setBrightness(9); // from 8 to 15
display.setSegments(SEG_CLEAR); // display clear
display.showNumberDec(0,false,1,1); 
display.setSegments(SEG_DELIM,1,2); // display delimiter
display.showNumberDec(0,false,1,3); 
scale.set_scale(CurScale);
scale.tare();
}
EssyMip
Повідомлень: 4
З нами з: 15 травня 2019 19:35
Звідки: Russia
Контактна інформація:

Вага на Arduino Nano і тензодатчиках

Повідомлення EssyMip »

Чем отличается arduino nano и обычная arduino. Вообще есть ли различия по выходам или набору фунционала?
Аватар користувача
Arduino
Site Admin
Повідомлень: 100
З нами з: 16 травня 2017 18:18

Re: Вага на Arduino Nano і тензодатчиках

Повідомлення Arduino »

EssyMip писав: 31 травня 2019 09:59 Чем отличается arduino nano и обычная arduino. Вообще есть ли различия по выходам или набору фунционала?
тут есть целый раздел по описанием контролеров. С точки зрения ВЕСОВ - нет разницы. тут про контролеры http://forum.arduinka.biz.ua/viewforum.php?f=2
Barrydup
Повідомлень: 4
З нами з: 04 липня 2019 01:22
Звідки: United Kingdom
Контактна інформація:

Вага на Arduino Nano і тензодатчиках

Повідомлення Barrydup »

У Arduino Nano есть внешний мост FTDI.
Так вот сигналы RX, TX этого моста программно перебрасываются на любые пины Ардуино
У Freaduino Micro нет внешнего моста. Но сделать из него мост скорее всего можно
только у меня нет такой платы что бы проверить
Willietog
Повідомлень: 1
З нами з: 19 березня 2023 00:16
Звідки: Toronto
Контактна інформація:

Вага на Arduino Nano і тензодатчиках

Повідомлення Willietog »

Добрый день думаю многим интересна именно работа с arduino через данную прошивку.
собственно первый вопрос я подключил к arduino датчик температуры на компе в сериал порте arduino ide все показывает прекрасно как теперь посмотреть данные на роутере?? в встроенный терминал команда cat /dev/ttyUSB0 не выдает нечего
и также можно ли в модуль ftdi подключить две или более arduino nano
Відповісти

Повернутись до “Датчики тиск, вага, висота”