Высоту высоких объектов, например, деревьев обычно измеряют с помощью гипсометра. Хотя есть много альтернатив, но гипсометр является одним из наиболее распространенных вариантов. Его принцип работы сводится к тригонометрии. И в данном материале мы сделаем свой гипсометр на основе Arduino.

Высота рассчитывается путем измерения стороны и угла в треугольнике, состоящем из вершины и низа дерева и гипсометра. Угол измеряется с помощью клинометров (инклинометров). Показания углов отображаются оптически или в цифровом виде. Расстояние между деревом и зрителем обычно измеряется с помощью измерительных лент, ультразвуковых или лазерных методов.
В данном проекте используется аналогичный принцип. Шаговый двигатель используется для расчета угла, ультразвуковой датчик HC-SR04 используется для расчета базы (расстояния между объектом и устройством), а Arduino используется для вычисления высоты с использованием этих данных.
Схема подключения компонентов гипсометра на основе Arduino следующая:

Код программы для гипсометра на основе Arduino приведен далее.
#include <CheapStepper.h>
const int trigPin = 2;
const int echoPin = 3;
const int increment = 7;
const int decrement = 8;
bool calibrationMode = false;
float angle = 0.00;
int x = 0;
CheapStepper stepper(9, 10, 11, 12);
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(increment, INPUT_PULLUP);
pinMode(decrement, INPUT_PULLUP);
Serial.begin(9600);
stepper.setRpm(20);
}
void loop() {
if (calibrationMode == false) {
Serial.println("Arduino is in measurement mode");
while (calibrationMode == false) {
while (digitalRead(increment) == 0 && angle <= 90.00) {
stepper.moveCCW(1);
delay(10);
x++;
angle = x/11.3;
}
while (digitalRead(decrement) == 0 && angle >= 0.00) {
stepper.moveCW(1);
delay(10);
x--;
angle = x/11.3;
}
angle = (angle > 90.00) ? 90.00 : angle;
angle = (angle < 0.00) ? 0.00 : angle;
float base = getDistance();
float tanAngle = tan(((angle > 90.00) ? 90.00 : angle) * 0.0174533);
float height = base * tanAngle;
Serial.print("Base: ");
Serial.print(base);
Serial.print("cm ");
Serial.print("Angle: ");
Serial.print((angle > 90.00) ? 90.00 : angle);
Serial.print("deg ");
Serial.print("Tan: ");
Serial.print(tanAngle);
Serial.print(" ");
Serial.print("Height: ");
Serial.print(height);
Serial.println("cm");
delay(500);
checkCalibration();
}
}
else if (calibrationMode == true) {
Serial.println("Set the angle of the motor to 0 degrees using the switches\nAfter that, press both the switches together");
while (calibrationMode == true){
while (digitalRead(increment) == 0 && digitalRead(decrement) == 1) {
stepper.moveDegreesCCW(1);
delay(50);
}
while (digitalRead(decrement) == 0 && digitalRead(increment) == 1) {
stepper.moveDegreesCW(1);
delay(50);
}
checkCalibration();
}
angle = 0;
Serial.println("Calibration successful!");
}
}
float getDistance() {
long duration;
float distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.0343 / 2;
return distance;
}
void checkCalibration () {
if (digitalRead(increment) == 0 && digitalRead(decrement) == 0) {
delay(1000);
calibrationMode = !calibrationMode;
}
}
© digitrode.ru