РЕШЕНО Помогите поправить код

Тема в разделе "Флудилка", создана пользователем Ariadna-on-Line, 16 апр 2025.

  1. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Вроде ничего особенного, но уже мозги свернул. Функция таймера. При входе в нее потенциометр всегда в положении нуля. В функции 3 моды - поэтому задействованы 2 флага (глобальные булевы переменные). В исходном - обе фальсе.
    1я мода - вход. На экране сообщение - крутни потенциометр до максимума. Крутнули до максимума. Переход ко 2й моде. Вывод на дисплей положения потенциометра и ожидание его остановки. По окончанию проверки неподвижности- считаем это установленным значением и переход на 3ю - моду - собственно обратный счет, исполнение неких действий и возврат в 1ю моду.
    Код (Text):

    // функция таймера (0) OK
    void Timer() {

      int Check    = 0;
      int CurRotor = 0;   // Текущее значение потенциометра
      int Rotor    = 0;   // Запомненное значение предыдущее
    //---------
     if ((TimerFlag == false && SetFlag == false))   {    //  ВХОД В 1ю МОДУ  // Если флаги в исходном положении -

        CurRotor = analogRead(pinPot);                // читаем потенциометр.
        delay(2);
     if (CurRotor >= 1000) {                          // Если он в правом положении
        TimerFlag = true;                             // - переходим ко второму шагу
        }
      char buf_g[strlen_P(TimerMess) + 1];            // Выделим буфер достаточной длины
      strcpy_P(buf_g, TimerMess);                     // Копируем строку в буфер

        tape = "";
        tape += utf8rus(buf_g);
        Run();                                        // Выводим бегущей строкой "Таймер - крути вправо."
      }                                                   // ЗДЕСЬ ВСЁ ОК
    //---------
     if ((TimerFlag == true) && (SetFlag == false)) {
        CurRotor = analogRead(pinPot);                   // Читаем и выводим положение
        delay(2);                                        // потенциометра.

        tape = "";
        tape += CurRotor;
        Screen();                                        // Выводим на дисплей
        Serial.println(CurRotor);                 // ВСЁ ОТЛИЧНО, НО
    //---------
     if (CurRotor == Rotor) {                      // ОТСЮДА И ДАЛЬШЕ - не исполняется // Если потенциометр неподвижен
        Check ++;                                        // Считаем время неподвижности
        Serial.println(Check);
      }
    //---------
     if (Check >= 10000) {                          // Если потенциометр неподвижен
        SetFlag = true;                                  // долго - считаем это ЗАДАНИЕМ
      }                                                  // и переходим к следующему шагу.
    //---------
     if (CurRotor != Rotor) {                       // Если потенцилметр сдвинулся
        Check = 0;                                       // начинаем проверку заново
        Rotor = CurRotor;                                // Запоминаем новое положение
      }                                                  // потенциометра
    //---------
     }
    //---------
      else {}
    //---------
     if ((TimerFlag == true) && (SetFlag == true)) {

        char buf_g[strlen_P(CountMess) + 1];     // Выделим буфер достаточной длины
        strcpy_P(buf_g, CountMess);              // Копируем строку в буфер

        tape = "";
        tape += buf_g;
        tape += CurRotor;
        Screen ();
        CurRotor--;
     
     if (CurRotor <= 0) {
        Check     = 0;
        TimerFlag = false;
        SetFlag   = false;
        Rotor     = 0;
        Melody();
        }
      }
     }
     
    Я понимаю что засада во вложенных IF-ах. Но никак не могу выкрутиться. С уважением.
    ПС. А че это у нас исчезли кнопки КОДА и СПОЙЛЕРА ???
     
    Последнее редактирование: 16 апр 2025
  2. Asper Daffy

    Asper Daffy Иксперд

    Неправильно понимаете. Проблема в организации программы. При такой организации в ней чёрт ногу сломит и всё равно ничерта не разберётся. Перепишете её нормально, как пишутся автоматы и будет Вам счастье.

    А так ... код неполный и сказать по нему ничего нельзя.
     
  3. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Нет. Просто сглупил. Сделал локальные переменные. А код сделан так, чтобы всегда выскакивать в главный цикл. И при входе в функцию они инициализировались в ноль. Сделал их глобальными и все заработало. Блин полдня потратил ))))
     
  4. Asper Daffy

    Asper Daffy Иксперд

    Да, нет, Вы "сложно" сглупили. Ошибок там овердохрена. Вам кажется, что
    просто потому, что Вы тестировать не умеете.

    И да, решение
    в общем случае очень плохое. Каждая глобальная переменная - грабли. Для заведения каждой надо иметь очень веские основания, здесь их нет. Это Вам кажется, что завёл глобальную переменную и полегчало - да полегчало временно, но граблей добавилось.

    А по поводу «исправил последнюю ошибку», запомните: в программировании есть такой Закон Брукса: «Всякая найденная в программе последняя ошибка, на самом деле является предпоследней» (в оригинале: «Every last bug you found is actually the penultimate»)
     
    Последнее редактирование: 17 апр 2025
  5. ИгорьК

    ИгорьК Гуру

    Сделав переменные локальными, вы поступили правильно. Но (видимо, кода нет) для вашего случая нужно еще применить для локальных переменных квалификатор static. Разберитесь с ним и будет вам радость и веселье.

    @Asper Daffy , нельзя не согласиться, все обязаны знать и думать одинаково. Хилых, по-спартански, - в ров :)
     
    Ariadna-on-Line нравится это.
  6. DetSimen

    DetSimen Гуру

    Ну да, "В коде было 8 ошибок, 5 из них исправили, осталось 9"
     
    Ariadna-on-Line нравится это.
  7. parovoZZ

    parovoZZ Гуру

    не обязательно, если функция внутри имеет вечный цикл или есть замыкание. Примерами служит функция main и задачи в ОС. Тогда переменные и локальные и без статик.
     
    ИгорьК нравится это.
  8. ИгорьК

    ИгорьК Гуру

    Кода нет, только предположения. static здесь самое очевидное.

    Совершенно не представляю замыкания в Сях плюс плюс. Что почитать?

    Или вы имеете в виду создание класса?
     
  9. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Очевидно это локальное (программистское) следствие закона Мэрфи. )))
    Да я все на Протеус надеюсь. Он "тестирует." )))))
    Спасибо. Вы меня подняли на следующую ступень опыта.)))
    ПС. Кода мне не жалко. Но стоит ли забивать сервер мало-полезным хламом, хотя и работающим.
     
    Последнее редактирование: 18 апр 2025
    ИгорьК нравится это.
  10. ИгорьК

    ИгорьК Гуру

    Спасибо. Если знаю чем помочь - помогу. А учить правильной жизни - зряшное дело.
     
    Ariadna-on-Line нравится это.
  11. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Код (Text):
    //-------------------------------------------------
    // функция таймера (0) OK
    void Timer() {

    static boolean TimerFlag = false;
    static boolean SetFlag   = false;

     if ((TimerFlag == false && SetFlag == false)) {  // Если флаги в исходном положении -

      char buf_g[strlen_P(TimerMess) + 1];            // Выделим буфер достаточной длины
      strcpy_P(buf_g, TimerMess);                     // Копируем строку в буфер
     
        tape = "";
        tape += utf8rus(buf_g);
        Run();                                        // Выводим слово "Таймер - крути вправо."

        CurRotor = analogRead(pinPot);                // читаем потенциометр.
        delay(2);
     if (CurRotor > 1000) {                           // Если он в правом положении
        TimerFlag = true;                             // - переходим ко второму шагу
        }
      }
    //---------
     if ((TimerFlag == true) && (SetFlag == false)) {

        CurRotor = analogRead(pinPot);                   // Читаем и выводим положение
                                                                              // потенциометра.
        tape = "";
        tape += CurRotor;
        Screen();                                        // Выводим на дисплей
    //---------
     if (CurRotor == Rotor) {                            // Если потенциометр неподвижен
        Check++;                                         // Считаем время неподвижности
        delay(100);                                      //- примерно 5 секунд
      }
    //---------
     if (Check >= MaxCheck) {                            // Если потенциометр неподвижен
        SetFlag = true;                                  // долго - считаем это ЗАДАНИЕМ
      }                                                  // и переходим к следующему шагу.
    //---------
     if (CurRotor != Rotor) {                       // Если потенцилметр сдвинулся
        Check = 0;                                       // начинаем проверку заново
        Rotor = CurRotor;                                // Запоминаем новое положение
      }                                                  // потенциометра
     }
    //---------
     if ((TimerFlag == true) && (SetFlag == true)) {

        char buf_g[strlen_P(CountMess) + 1];     // Выделим буфер достаточной длины
        strcpy_P(buf_g, CountMess);              // Копируем в буфер строку "Счёт : "

        tape = "";
        tape += utf8rus(buf_g);
        tape += CurRotor;
        Screen ();
        CurRotor--;
        delay(Interval);                             // интервал счета
    //---------
     if (CurRotor < 0) {
        Check     = 0;
        TimerFlag = false;
        SetFlag   = false;
        Rotor     = 0;
        Melody();
        }
      }
     }
    //-------------------------------------------------
     
    Здесь попал в конкретно-арифметический затык. В Протеусе всё ОК, в реале оцифровка скачет в пределах 4ед. Соответственно проверка неподвижности потенциометра не срабатывает, перехода к третьему шагу - собственно к работе таймера, не происходит. Вопрос - как ввести сглаживающий фильтр ? Цель кода сделать установку таймера до 1000 секунд. Желательно с точностью не хуже 5 секунд.
    ПС. Введение аппаратного фильтра в схеме - почти не помогает.
    ППС. Буду благодарен за пример кода.
    Точно. Как там у Остапа Бендера и Ко. "Не учите меня жить. Лучше ......... дайте ключи от квартиры где деньги лежат... "
     
    Последнее редактирование: 18 апр 2025
  12. Asper Daffy

    Asper Daffy Иксперд

    Вот тут есть ссылка на программу генерации кода фильтра и написано как поправить ошибку в коде, который эта программа генерит. В итоге всё работает, я часто этими фильтрами пользуюсь.

    https://arduino.ru/forum/programmirovanie/kompilyatsiya-kodov-winfilter-v-arduino-ide
     
    DetSimen нравится это.
  13. Asper Daffy

    Asper Daffy Иксперд

    У нас разное понимание "помощи". По мне, сказать "впиши вот сюда волшебное слово" - это ни разу не помощь.

    Вы слышали вот эту песенку? Послушайте, и подумайте над текстом.

    https://rutube.ru/video/b343f08a1d3a3b70a2c290d2b3feabdc/
     
  14. parovoZZ

    parovoZZ Гуру

    Перейти на 8-ми битный режим ацп, поставить внешний опорник, создать программный триггер Шмитта, применить медианный фильтр и так далее.
     
  15. parovoZZ

    parovoZZ Гуру

    Как аппаратный фильтр улучшит характеристики ацп? Правильный ответ - никак. Надо 10 бит на выходе? Ставь 12-ти битный ацп.
    Создатели cd-audio быстро поняли - для 16-ти битного качества звука надо 18 бит.
     
  16. parovoZZ

    parovoZZ Гуру

    На плюсах же есть безымянные функции (лямбды)? Вот туда и читайте.
     
    ИгорьК нравится это.
  17. ИгорьК

    ИгорьК Гуру

    "Практика, критерий истины":

    Лично мне этого достаточно:
    ----------------------------------------

    Вы всего на год старше меня, но до сих пор не понимаете, что поучениями и нравоучениями ничего в мире не изменить.

    Я вам в ответ ничего советовать не буду. Это бесполезно.

    Знаю, что вы отлично разбираетесь в теме МК, языка и т.д. Но сейчас это уже спорное достоинство: AI делает это все равно лучше вас. Тогда что остается нам, людям?
     
    Ariadna-on-Line нравится это.
  18. Asper Daffy

    Asper Daffy Иксперд

    Что именно "это" AI делает лучше меня?
     
    Feofan и DetSimen нравится это.
  19. parovoZZ

    parovoZZ Гуру

    ускорить процесс оно может, но не заменить. Также ничего нового оно выдумать не может.
     
    ИгорьК нравится это.
  20. ИгорьК

    ИгорьК Гуру

    Учит жить только когда его об этом попросят :)
     
    Ariadna-on-Line нравится это.