Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Arduino-дальномер и цифровой уровень: пошаговое руководство

Обзор

Устройство совмещает ультразвуковой дальномер (HC-SR04), акселерометр MPU6050 (угол наклона), LCD 16×2 и одну кнопку для управления. Четыре режима:

  1. Выбор единиц измерения (см, дюймы, метры, футы).
  2. Измерение расстояния с сохранением двух последних значений.
  3. Вычисление площади по двум перпендикулярным измерениям.
  4. Цифровой уровень: тангаж (Pitch) и крен (Roll) относительно горизонта.

Arduino-дальномер и цифровой уровень: пошаговое руководство
Arduino-дальномер и цифровой уровень: пошаговое руководство
Arduino-дальномер и цифровой уровень: пошаговое руководство
Arduino-дальномер и цифровой уровень: пошаговое руководство

Схема и PCB

Схема: HC-SR04 (Trig/Echo), MPU6050 (I2C), LCD (параллельно), кнопка с подтяжкой, делитель напряжения для контраста LCD. Плата спроектирована в EasyEDA, заказ в JLCPCB.

Arduino-дальномер и цифровой уровень: пошаговое руководство
Arduino-дальномер и цифровой уровень: пошаговое руководство

Сборка корпуса

Корпус из прозрачного акрила 5 мм (верх 4 мм под LCD). Вырез под LCD — дрель + пила + рашпил. Отверстия под ультразвуковой датчик, кнопку, тумблер — фрезерными коронками. Эпоксидный клей, верхняя крышка на болтах/гайках. Питание — крона 9 В.

Arduino-дальномер и цифровой уровень: пошаговое руководство
Arduino-дальномер и цифровой уровень: пошаговое руководство

Программный код

Библиотеки: Wire.h (I2C), LiquidCrystal.h. Переменные: режимы (program), единицы (unitSelect), буферы измерений.

Инициализация

#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
const int MPU = 0x68;
#define trigPin 8
#define echoPin 9
#define selectButton 10

int16_t AcX, AcY, AcZ;
long duration; float distance;
int program = 0; float d=0, d1=0, d2=0, area=0;
int axis = 0, angle = 0, unitSelect = 0;
String unit = "cm";

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true);
  lcd.begin(16, 2);
  pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(selectButton, INPUT_PULLUP);
}

Главный цикл: машина состояний

void loop() {
  switch (program) {
    case 0: // Выбор единиц
      lcd.setCursor(0,0); lcd.print("Select Unit: "); lcd.setCursor(13,0); lcd.print(unit); lcd.print(" ");
      if (digitalRead(selectButton) == 0) {
        if (unitSelect == 0) { unit = "in"; unitSelect = 1; }
        else if (unitSelect == 1) { unit = "m"; unitSelect = 2; }
        else if (unitSelect == 2) { unit = "ft"; unitSelect = 3; }
        else if (unitSelect == 3) { unit = "cm"; unitSelect = 0; }
        delay(500);
        if (digitalRead(selectButton) == 0) { program = 1; lcd.clear(); delay(500); }
      }
      break;

    case 1: // Дальномер
      distance = getDistance();
      lcd.setCursor(0,0); lcd.print("Dist: "); lcd.print(distance); lcd.print(" "); lcd.setCursor(14,0); lcd.print(unit);
      lcd.setCursor(0,1); lcd.print("d:"); lcd.setCursor(8,1); lcd.print("d:");
      if (digitalRead(selectButton) == 0) {
        if (d == 0) { lcd.setCursor(0,1); lcd.print("d: "); lcd.setCursor(2,1); lcd.print(distance); d=1; delay(100); }
        else if (d == 1) { lcd.setCursor(8,1); lcd.print("d: "); lcd.setCursor(10,1); lcd.print(distance); d=0; delay(100); }
        delay(500);
        if (digitalRead(selectButton) == 0) { program=2; d=0; lcd.clear(); delay(500); }
      }
      break;

    case 2: // Площадь
      distance = getDistance();
      lcd.setCursor(0,0); lcd.print("Area: "); lcd.print(area); lcd.setCursor(12,0); lcd.print(unit); lcd.print("^2");
      if (d == 0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); }
      else if (d == 1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); }
      else if (d == 2) { lcd.setCursor(6,0); lcd.print(area); }
      if (digitalRead(selectButton) == 0) {
        if (d == 0) { lcd.setCursor(0,1); lcd.print("d1: "); lcd.setCursor(3,1); lcd.print(distance); d=1; d1=distance; delay(100); }
        else if (d == 1) { lcd.setCursor(9,1); lcd.print("d2: "); lcd.setCursor(12,1); lcd.print(distance); d=2; d2=distance; area=d1*d2; delay(100); }
        else if (d == 2) { lcd.clear(); d=0; area=0; delay(100); }
        delay(500);
        if (digitalRead(selectButton) == 0) { program=3; d=0; lcd.clear(); delay(500); }
      }
      break;

    case 3: // Уровень (Pitch/Roll)
      Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false);
      Wire.requestFrom(MPU, 6, true);
      AcX = Wire.read()<<8 | Wire.read();
      AcY = Wire.read()<<8 | Wire.read();
      AcZ = Wire.read()<<8 | Wire.read();

      if (axis == 0) { // Pitch (вокруг Y)
        angle = atan(-1 * AcX / sqrt(pow(AcY,2) + pow(AcZ,2))) * 180 / PI;
        lcd.setCursor(0,0); lcd.print("Pitch");
      } else { // Roll (вокруг X)
        angle = atan(-1 * AcY / sqrt(pow(AcX,2) + pow(AcZ,2))) * 180 / PI;
        lcd.setCursor(0,0); lcd.print("Roll ");
      }
      lcd.setCursor(0,1); lcd.print("Angle: "); lcd.print(abs(angle)); lcd.print(" "); lcd.setCursor(10,1); lcd.print("deg");
      if (digitalRead(selectButton) == 0) {
        if (axis == 0) axis = 1; else axis = 0; delay(100);
        delay(500);
        if (digitalRead(selectButton) == 0) { program=0; lcd.clear(); delay(500); }
      }
      break;
  }
}

Функция измерения расстояния с конвертацией единиц

float getDistance() {
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2; // см
  if (unitSelect == 1) { distance = distance; unit = "cm"; }
  else if (unitSelect == 2) { distance *= 0.393701; unit = "in"; }
  else if (unitSelect == 3) { distance *= 0.01; unit = "m"; }
  else if (unitSelect == 0) { distance *= 0.0328; unit = "ft"; }
  return distance;
}

Формулы углов взяты из Application Note Freescale Tilt Sensing Using a Three-Axis Accelerometer. Кнопка переключает Pitch/Roll, долгое нажатие — выход в меню единиц.

Полный код

/* DIY Digital Range Measurer and Spirit Level
   by Dejan Nedelkovski, www.HowToMechatronics.com */
// ... (полный листинг, объединяющий все части выше)

Заключение

Компактный прибор «все в одном» на одной плате, с интуитивным одно-кнопочным интерфейсом. Полезен для быстрых замеров и выравнивания. Файлы проекта (EasyEDA, код) открыты.

Производственный процесс

  1. Сборка DCC-командной станции для модельной железной дороги на Arduino с бесплатным приложением
  2. Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
  3. Создание анимации и игр на LCD 16×2 с Arduino UNO
  4. Детектор аудиочастот на Arduino: измеряем пик громкости с высокочувствительным модулем
  5. Собираем свой Tamagotchi на Arduino: цифровой питомец своими руками
  6. Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
  7. Сборка вольтметра на Arduino с дисплеем Nokia 5110 — Пошаговое руководство
  8. Сборка надежного таймера обратного отсчета на Arduino с 7-сегментным дисплеем SparkFun
  9. Управление Arduino Uno из Python 3: команды через последовательный порт и демонстрация с LED
  10. Сборка компактного FM-радио на Arduino Nano и RDA5807M