Деление с плавающей запятой возвращает «inf» и 0

Я новичок в Arduino и делаю ультразвуковой проект, в котором проверяю скорость звука. Мой код ниже, и по какой-то причине это то, что возвращает последовательный порт:

Это измеренная скорость звука: inf м/с. Это измеренная скорость звука: 0 м/с Это измеренная скорость звука: 0 м/с и т.д...

Вот мой код. Мы очень признательны за любую помощь :)

int trig = 13;
int echo = 11;
float target_distance = 0.3;
float recieved;
float speed_of_sound;

void setup() {
    Serial.begin(9600);
    pinMode(trig, OUTPUT);
    pinMode(echo, INPUT);
}

void loop() {
    digitalWrite(trig, LOW);
    delayMicroseconds(2000);
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);

    recieved=pulseIn(echo, HIGH);
    recieved = recieved*1000000.0;
    speed_of_sound = (2*target_distance)/recieved;
    Serial.print("This is the measured speed of sound: ");
    Serial.print (speed_of_sound);

    Serial.println("m/s");
    delay(3000);
}

, 👍2

Обсуждение

Что вы ожидаете от деления 0,6 на 1000000 * какое-то значение?, @Vaibhav


1 ответ


Лучший ответ:

1

Предполагая, что скорость звука порядка 330 м/с, вы ожидаете путь туда и обратно к цели и обратно длится около 1,8 мс. Затем

recieved = pulseIn(echo, HIGH);

должен дать значение, близкое к 1800, и

recieved = recieved * 1000000.0;

должен сделать received примерно равным 1,8 × 109. Затем

speed_of_sound = (2*target_distance)/recieved;

дает скорость звука 3,3 × 10−10. Это правильное значение, если вам нужна эта скорость в метрах в пикосекунду, но это не соответствует тому, что ваша программа печатает «м/с» после значения.

Serial.print() в Arduino довольно тупой с плавающей запятой числа. По умолчанию печатаются две цифры после запятой, независимо от порядка числа. Таким образом, что-либо меньше 0,005 печатается как «0».

Я не совсем понимаю, почему вы получили ∞ на первом цикле. Выглядит как pulseIn() пропустил импульс и вернул ноль, и в этом случае скорость рассчитывается как 0,6 ÷ 0 = ∞.

Решение состоит в том, чтобы вычислить received как

recieved = pulseIn(echo, HIGH) * 1e-6;

Это можно запомнить, подумав, что количество (время прохождения туда-обратно) числовое значение (pulseIn(echo, HIGH)), умноженное на единицу (1e-6, что означает «микросекунды»).

,

хороший, исчерпывающий ответ. (проголосовали), @Duncan C

Ах, математическая ошибка... как неловко. Я предположил, что это мой код. Спасибо, что нашли время, чтобы помочь! Я только что изменил ошибочную строку на: recieved = recieved/1000000, и, если не считать первой строки «inf», теперь она работает хорошо., @ThisUsernameHasBeenTaken

@ThisUsernameHasBeenTaken: сканирование доступных таблиц данных не выявило никаких аномалий, связанных с первым измерением. Я бы применил практический подход к этому, запустив устройство один раз во время setup() и проигнорировав этот результат., @JRobert