Arduino + HC-SR04 s teplotní kompenzací

Pro prezentaci použití ultrazvuku pro měření vzdálenosti, konkrétně v mém případě výšky hladiny toku, jsem postavil jednoduchou konstrukci s Arduinem a HC-SR04. Pro teplotní kompenzaci jsem zvolil I2C teplotní čidlo LM75, tato teplotní kompenzace je nutná pro měření větších vzdáleností, jelikož teplota vzduchu přímo ovlivňuje rychlost šíření ultrazvukových vln (https://physics.stackexchange.com/questions/177997/how-can-the-speed-of-sound-increase-with-an-increase-in-temperature).

Použité komponenty:

  • Arduino Nano
  • HC-SR04
  • LM75
  • LCD 20×4 s I2C bacpackem

Na propojení komponent není nic zákeřného a vše funguje na první pokus. Vzdálenost od čidla je přímo zobrazena na LCD(v cm i v palcích) plus jsem přidal zobrazení teploty(když už ji měřím).

Zdrojový kód:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LM75.h>
#define trigPin 13
#define echoPin 12
#define measuring_freq 1000
#define LCD_lines_length 20
#define LCD_lines_count 4

LiquidCrystal_I2C lcd(0x27, LCD_lines_length, LCD_lines_count);
LM75 temp_sensor(LM75_ADDRESS | 0x48);

char lcd_out[20];
long previousMillis = 0;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor ( 0, 0 );
  lcd.print(F("Vyska hladiny:"));
  lcd.setCursor ( 0, 2 );
  lcd.print(F("Teplota vzduchu:"));
  Serial.println(F("Hladina,Teplota"));
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > measuring_freq) {
    float distance = get_distance(temp_sensor.temp());
    float temperature = temp_sensor.temp();
    clearLCDLine(1);
    lcd.setCursor ( 0, 1 );
    lcd.print(distance, 1);
    lcd.print(F("cm  "));
    lcd.print(distance * 0.393700787, 1);
    lcd.print(F("inch"));
    clearLCDLine(3);
    lcd.setCursor ( 0, 3 );
    lcd.print(temperature, 1);
    lcd.print((char)223);
    lcd.print(F("C  "));
    lcd.print(((temperature * 9) + 3) / 5 + 32, 1); //fahrenheit = ((celsius * 9) + 3) / 5 + 32
    lcd.print((char)223);
    lcd.print(F("F"));
    previousMillis = currentMillis;
    Serial.print(distance, 1);
    Serial.print(F(","));
    Serial.println(temperature, 1);
  }
}

float get_distance(float temp) {
  long duration;
  float distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2.0) / 29.14;
  float speedOfSound = 331.3 + 0.606 * temp;
  float compensatedDistance = (duration / 20000.0) * speedOfSound;
  return compensatedDistance;
}

void clearLCDLine(byte line)
{
  lcd.setCursor(0, line);
  for (byte n = 0; n < LCD_lines_length; n++)
  {
    lcd.print(" ");
  }
}

Použité knihovny:
LM 75 https://github.com/thefekete/LM75
I2C LCD https://github.com/marcoschwartz/LiquidCrystal_I2C

Leave a Reply