Множественные операторы if else для светодиодов с дистанционным управлением

У меня есть скетч, который вычисляет простое расстояние от устройства до ближайшей заданной координаты GPS (всего их 3), и я хотел бы, чтобы светодиоды в полосе неопикселей загорались в соответствии с близостью местоположения.

Мне удалось заставить его работать только с одним светодиодом 5 мм и простым оператором if (shortestDist < 10), затем digitalWrite(ledPin, HIGH); - иначе светодиод низкий. Но я хочу использовать неопиксельную полосу с 7 светодиодами для освещения в соответствии с различными критериями расстояния.

В своей попытке здесь я попытался заставить определенные светодиоды загораться на расстоянии 50, 30 и 10 метров, но это не работает должным образом, и это довольно грубый подход, как и мои "навыки" кодирования. :D

Мне также нужна помощь в том, как сделать какое-то сокращение для конкретной настройки светодиодной ленты в зависимости от расстояния - например, на расстоянии 50 м 2 красных светодиода, 5 светодиодов выключены, на расстоянии 30 м 5 красных светодиодов, 2 светодиода выключены и так далее.

Надеюсь, кто-то может помочь новичку :D В настоящее время не все светодиоды отключаются, когда расстояние превышает 50 метров.

void loop()
{

while (ss.available() > 0)
    gps.encode(ss.read());
if (gps.location.isUpdated())
{
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
}
else if (millis() - last > 1000)
{
    Serial.println();
    if (gps.location.isValid())
    {
        double shortestDist;
        for (int i = 0; i < 3; ++i)
        {
            double distanceToDest =
                TinyGPSPlus::distanceBetween(
                    gps.location.lat(),
                    gps.location.lng(),
                    positions[i].lat,
                    positions[i].lon);
            if (!i || distanceToDest < shortestDist)
                shortestDist = distanceToDest;
        }
        Serial.print(F("Next in range = "));
        Serial.print(shortestDist, 2); // десятичный
        Serial.println(" m");
        
        if (shortestDist < 50)   
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50); 
        }

        else if (shortestDist < 30)
        {                  
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(250, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(250, 250, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);  
        }  

        else if (shortestDist < 10)
        {                  
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(250, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(250, 0, 250));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 250, 0));
          pixels.setPixelColor(6, pixels.Color(250, 0, 0));
          pixels.show();
          delay(50);  
        } 

        else
        {                  
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 0, 0));
          pixels.show(); 
          delay(50); 
        }                          


    }
    if (gps.charsProcessed() < 10)
        Serial.println(F("No GPS data."));
    last = millis();
    Serial.println();        
}

, 👍-1

Обсуждение

у вас есть логическая ошибка в вашем коде... else if (shortestDist < 10) никогда не будет выполняться... подумайте о том, что вы говорите своей программе делать, @jsotola

Я переставил «иначе, если shortestDist», выбрав «если самое большое значение shortestDist», иначе, если меньшее значение, и оно работает, насколько я вижу, оно ведет себя правильно., @Varonne

тогда вы не опубликовали свой реальный код... подумайте об этом... какой оператор if будет выполняться, когда shortestDist = 5?, @jsotola

поместите операторы serial.print внутри блоков if для целей отладки, @jsotola

@jsotola Я не знаю, как опубликовать здесь полный код, кроме pastebin - https://pastebin.com/BWVjdr1S - это работает, и светодиоды включаются и выключаются, как и должны. Посмотрите, если у вас есть время, дайте мне знать, есть ли лучший способ отформатировать его, так как вы можете сказать, что я не очень хорошо разбираюсь в этом: D, @Varonne

код в pastebin отличается от кода в вашем вопросе ... вы уже разместили код в своем вопросе ... почему вы сказали, что не знаете, как размещать код?, @jsotola


1 ответ


0
  • Обычные недорогие модули GPS, как правило, сообщают о местоположении, которое в хороших условиях колеблется примерно на 5 метров. Многие факторы влияют на точность GPS и эту неопределенность. Некоторые из них перечислены здесь. Реализовать функцию порога расстояния в 10 метров может быть проблематично, если только условия не будут благоприятными.

  • Подумайте о том, чтобы ограничить использование оператора "если" тестирует больше. Например, используйте "if ((shortestDist <= 50) && (shortestDist > 30))" вместо "если (shortestDist < 50)". Продолжите аналогичным образом с другим "если" тесты. В противном случае, как только shorttestDist меньше 50, только 1-й "if" тест выполняется, так как он станет истинным и останется верным, и ни одно из других "этих" тесты будут рассмотрены.

  • Рассмотрите возможность использования только mills(). В опубликованном коде используется delay() & millis(). Вызов delay() — это нормально, но использование millis() почти всегда лучше. Однако следует избегать смешивания двух.

  • Возможно, логика в коде неверна. Похоже, что данные GPS только обрабатываются, и индикаторы обновляются, когда информация GPS недоступна (не новая).

  • При написании встроенного ПО всегда учитывайте источники аппаратных проблем. Многие находят маленькие батареи проблематичными при мгновенных требованиях к току. Аккумуляторы с малым номиналом в ампер-часах более склонны к падению напряжения при сильном токе. Например, когда процессор управляет реле или активирует датчик.

,

Спасибо за вклад - я буду использовать это с шагом 10 м на радиоуправляемой лодке, это просто концептуальный тест, а радиоуправляемая машина движется так медленно, что это должно быть хорошо. Я могу попробовать с 15 м, я думаю, что это должно быть хорошо, так как я сделал тест ходьбы и GPS-координаты на улице и был вполне удовлетворительным. Одна вещь, которую я заметил с моим текущим «решением» IF - светодиоды, которые я вызываю на полосе в определенных критериях IF, загораются, но они мигают и ритмично, так что это может быть что-то еще, если (millis () - последний > 1000), @Varonne

Для светодиодов. Я бы рекомендовал создать версию вашего кода, которая изменяет светодиод с фиксированной и ожидаемой скоростью. Вам нужно отделить любые неожиданные эффекты GPS, которые могут сбить вас с пути. Для GPS. Чтобы получить представление о шуме GPS в вашем окружении (деревья, здания, местоположение, погода и т. д.), запишите данные стационарного GPS за день. Это даст вам хорошее представление о том, что вы можете ожидать, и, возможно, идеи о том, как смягчить любой шум для вашего конкретного приложения., @st2000

Далее, некоторые здесь напишут код и опубликуют его. Я чувствую, что это не так помогает, как ОП, выясняющий код для себя. Тем не менее, вот несколько вещей, которые я заметил. Вы используете задержку() и миллис(). Вызов delay() — это нормально, но использование millis() почти всегда лучше. Тем не менее, следует избегать смешивания 2. Ваша логика может быть неверна. Похоже, вы обрабатываете информацию GPS и обновляете светодиоды только тогда, когда информация GPS недоступна (не новая). При написании встроенного ПО всегда учитывайте источники аппаратных проблем. Многие находят маленькие батареи проблематичными при мгновенных требованиях к току., @st2000

Я решил добавить несколько из этих комментариев к ответу, так как это может помочь другим, кто сталкивается с этим вопросом/ответом., @st2000