#1 2016-11-04 13:00:39

Saddamko
Учасник
Зареєстрований: 2016-10-20
Повідомлень: 23

Ультразвуковой измеритель расстояния и температуры на Ардуино ds18B20,

Собрал я его года три назад, исправно работает, иногда даже бывает полезен, когда нужно измерить размеры комнаты, проема двери или  еще чего-нибудь.

Работает очень точно. Расстояние, которое можно измерить не очень большое - уверенно меряет до 4-х метров.

Использованный в устройстве датчик HC-SR04 содержит ультразвуковой излучатель и приемник, по времени отклика от предмета перед датчик определяется расстояние с достаточно высокой точностью.

Дальность измерения - примерно до 5 метров.  Подключив к Arduino
данный датчик и,  цифровой индикатор LCD 1602 (HD44780) по шине i2c,  а самое главное, засунув все это в коробочку, а не оставив в виде макета, получил удобное и надежное устройство. Поскольку измерять приходится редко, чтобы уж не перевести устройство в разряд бесполезно валяющихся, добавил в него измеритель температуры на ds18B20.

После запуска поочередно выводит показания температуры и расстояния, что видно на двух картинках ниже:

us1.jpg
us5.jpg




Так устройство выглядит спереди - кнопка включения, приемная и передающая часть датчика, дырочка под лазерный диод и кнопка его включения, которые просто попутно поместились в коробочке. Прилепил я этот лазер, чтобы удобней было целиться в препятствие, к которому измеряем расстояние:

us2.jpg

"Кишочки" - все обильно сдобрено пластиковым клеем из термопистолета. Видно, что  LCD 1602 (HD44780) я использовал с припаяным к нему переходником, позволяющим управлять индикатором по i2c и уменьшить число проводов к индикатору.
Схема подключения индикатора к Ардуино по I2C:
1602i2c_2.jpg

Почитать подробней можно на https://lesson.iarduino.ru/page/urok-4- … k-arduino/
us3.jpg
Желтый цилиндрик слева - это упомянутый лазерный диод, запитано все от батарейки "Крона" 9в, поскольку потребляемый ток устройством минимальный,  штатных стабилизаторов питания на Ардуино вполне достаточно для понижения питания. Я вот смотрю на черную кляксу пластика в левом нижнем углу на снимке ниже, к которой идут провода, и кажется, я все-таки там поставил стабилизатор напряжения на 7805

us4.jpg



Выглядит все ужасно, наверно самое полезное в описании - код, из которого можно какие-то кусочки использовать у себя в проектах. Мопед Код не мой, автор там указан, я немножко просто все собрал в кучу из разных источников.

#include <LiquidCrystal.h>
#include <OneWire.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Ultrasonic.h>

/*
 * HCSR04Ultrasonic/examples/UltrasonicDemo/UltrasonicDemo.pde
 *
 * SVN Keywords
 * ----------------------------------
 * $Author: cnobile $
 * $Date: 2011-09-17 02:43:12 -0400 (Sat, 17 Sep 2011) $
 * $Revision: 29 $
 * ----------------------------------
 */


#define TRIGGER_PIN  10
#define ECHO_PIN     9

OneWire ow  (2); // on pin 10
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27,16,2);   /* Задаем размерность дисплея. 
При использовании LCD I2C модуля с дисплеем 16х4 ничего в коде изменять не требуется, cледует только заменить цифру отвечающую за количество сторок */

int pos = 0;    // variable to store the servo position 

void setup()
  {
  Serial.begin(9600);

  
  lcd.init();                       // Инициализация lcd             
  lcd.backlight();                  // Включаем подсветку
  // Курсор находится в начале 1 строки
  lcd.print("Temperature and");       // Выводим текст
  lcd.setCursor(0, 1);              // Устанавливаем курсор в начало 2 строки
  lcd.print("Ultrasonic mtr.   ");     // Выводим текст
  delay (1000); 
  lookUpSensors();
  delay (1000);
  }

void loop()
  {
  int led = 13;
  float cmMsec, inMsec;
  long microsec = ultrasonic.timing(); 

  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  inMsec = ultrasonic.convert(microsec, Ultrasonic::IN);
 //inMsec= int(inMsec);
  myLCDclear();
  lcd.setCursor(0, 0);
  lcd.print("Ultrasonic      "); 
  lcd.setCursor(0, 1);
  lcd.print("dist.(cm:)");
  lcd.print (cmMsec);
  delay (2000);
  Temp ();
  delay (2000);
 }
  
  
 void Temp ()
 {
 byte i;
 byte present = 0;
 byte type_s;
 byte data[12];
 byte addr[8];
 float celsius, fahrenheit;
 
 if  (! ow.search  (addr)) {
 ow.reset_search  ();
 delay  (250);
 return;
 }
 
 
 ow.reset  ();
 ow.select  (addr);
 ow.write  (0x44,1); // start conversion, with parasite power on at the end
 
 delay  (1000); // maybe 750ms is enough, maybe not
 // we might do a ow.depower  () here, but the reset will take care of it.
 
 present = ow.reset  ();
 ow.select  (addr); 
 ow.write  (0xBE); // Read Scratchpad

 
 for  (i = 0; i < 9; i++) { // we need 9 bytes
 data[i] = ow.read  ();
 }
 

 // convert the data to actual temperature

 unsigned int raw =  (data[1] << 8) | data[0];
 if  (type_s) {
 raw = raw << 3; // 9 bit resolution default
 if  (data[7] == 0x10) {
 // count remain gives full 12 bit resolution
// raw =  (raw & 0xFFF0) + 12 — data[6];
 }
 } else {
 byte cfg =  (data[4] & 0x60);
 if  (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
 else if  (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
 else if  (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
 // default is 12 bit resolution, 750 ms conversion time
 }
 celsius =  (float)raw / 16.0;
 fahrenheit = celsius * 1.8 + 32.0;
 myLCDclear();
 lcd.setCursor(0, 0);
 lcd.print  ("Temperature =");
 lcd.setCursor(0, 1);
 lcd.print  (celsius);
 lcd.print  (" C, ");
 lcd.print  (fahrenheit);
 lcd.println  (" F   ");
} 


 
 void lookUpSensors(){
  byte address[8];
  int i=0;
  byte ok = 0, tmp = 0;
  //start the search
  lcd.setCursor(0, 0);
  while (ow.search(address)){
    tmp = 0;
    //0x10 = DS18S20
    if (address[0] == 0x10){
      lcd.print("This is a DS18S20: ");
      tmp = 1;
    } else {
      //0x28 = DS18B20
      if (address[0] == 0x28){
        lcd.print("This is a DS18B20: ");
        tmp = 1;
      }
    }
    lcd.setCursor(0, 1);
    //display the address, if tmp is ok
    if (tmp == 1){
      if (OneWire::crc8(address, 7) != address[7]){
        lcd.println("but it doesn't have a valid CRC!");
      } else {
        //all is ok, display it
        for (i=0;i<8;i++){
          if (address[i] < 9){
            lcd.print("0");
          }
          lcd.print(address[i],HEX);
          if (i<7){
            lcd.print("");
          }
        }
        lcd.println("");
        ok = 1;
      }
    }//end if tmp
  }//end while
  if (ok == 0){
    lcd.println("No devices were found");
  }
}

void myLCDclear()
{
  lcd.setCursor(0, 0);
  lcd.print  ("                           ");
  lcd.setCursor(0, 1);
  lcd.print  ("                           ");  
}

Остання редакція Saddamko (2016-11-06 15:55:36)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму