Где может быть ошибка кода?

Тема в разделе "Arduino & Shields", создана пользователем sanik, 8 окт 2013.

  1. Unixon

    Unixon Оракул Модератор

    Да, а теперь все полностью и по правилам. :D
     
  2. sanik

    sanik Гик

    Так для чего? Мне проще словами весь алгоритм объяснить:(
     
  3. Unixon

    Unixon Оракул Модератор

    Да я в общем то не против, чтобы вы объяснили словами, но сделайте это четко. А не так как в первом посте. Вам все равно нужен будет конечный автомат. Хотите описать его словами - пожалуйста. Но следуйте правилам.
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    До сих пор одними из главных инструментов программиста, как ни странно, остаются обычный лист бумаги и карандаш ;) А при передаче мысли от одного программиста другому без этого вообще не обойтись. Пришлось познать на собственной шкуре.
     
    Festour нравится это.
  5. Unixon

    Unixon Оракул Модератор

    sanik, вот у вас в коде остался же в loop() скелет автомата. Пока по нему работете - все ОК, как только начинаете изобретать колесо - сразу в лужу садитесь. На что вам отдельный syncronize() с несогласованной логикой? Почему не используете основной switch-case в loop()?
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    И зачем после analogWrite блок кода отделен скобками - { ... } ?
    Это же не цикл и не условие :) Ошибкой это не является (компилятор просто их пропускает), но запутывает код.
     
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Код (Text):
    void loop()
    {
        //если_нажалась кнопка start, то
        {
            //запустить мотор
            //обнулить_счетчик
        }

        //если_появился_импульс_от_фотоинтераптора, то
            //увеличить_счетчик_на_1

        //если_счетчик_достиг_максимального_значения, то
        {
            //остановить_мотор
            //обнулить_счетчик
        }
    }
    И каждый кусочек кода должен работать независимо от других.
    Взаимосвязь между ними определяется только значением счетчика импульсов.
     
  8. sanik

    sanik Гик

    Это как ? Получается что, если убрать syncronize(), и вписать действие прямо в switch-case в loop() то должно все заработать?
    Алгоритм такой: При запуске девайса запускается ручное управление моторами с помощью потенциомеров, идет ожидание нажатия кнопки SELECT при нажатии ,включается меню установки импульсов датчика posX следующее нажатие SELECT установка импульсов датчика posY , следующие нажатие выход из установки и ожидание нажатия кнопки START отключается ручное управление идет ожидание сигнала SYNC от внешнего устройства при поступлении сигнала, моторы независима друг от друга вращаются на заданое количество импульсов posX, posY, (причем значения могут быть различными posX= 20 импульсам, posY=32 импульса) После остановки последнего двигателя ожидание сигнала SYNC и так по кругу пока не будет нажата кнопка ANALOG при нажатии ANALOG 2 раза выходим на ручное управление...

    Я правильно понял ?
    Код (Text):
    void loop()
    {
      switch (mode)
      {
        case MODE_INIT:
        {
          hello();
          mode = MODE_MANUAL;
          break;
        }
        case MODE_MANUAL:
        {
          processAnalog();
          if (digitalRead(PIN_BTN_SELECT))// считывание кнопки select
          {
            mode = MODE_SELECT_X;
            while (digitalRead(PIN_BTN_SELECT)) delay(1);
            posX==0;
            posY==0;
          }
          break;
        }
        case MODE_SELECT_X: //Установка количества импульсов для датчика Y
        {
          lcd.setCursor(0,0); lcd.print("    Setup X "); delay(200);
          lcd.setCursor(0,1); lcd.print("      X ");
          if (digitalRead(PIN_BTN_PLUS))
          {
            if (posX < 1023) posX++;
            while (digitalRead(PIN_BTN_PLUS)) delay(1);
            lcd.setCursor(0,1); lcd.print("      X "); lcd.print(posX);
          }
          if (digitalRead(PIN_BTN_MINUS))
          {
            if (posX > 0) posX--;
            while (digitalRead(PIN_BTN_MINUS)) delay(1);
            lcd.setCursor(0,1); lcd.print("      X "); lcd.print(posX);
          }
          if (digitalRead(PIN_BTN_SELECT))
          {
            mode = MODE_SELECT_Y;
            while (digitalRead(PIN_BTN_SELECT)) delay(1);
          }
          break;
        }
        case MODE_SELECT_Y:
        {
          lcd.setCursor(0,0); lcd.print("    Setup Y "); delay(200);
          lcd.setCursor(0,1); lcd.print("      Y ");
          if (digitalRead(PIN_BTN_PLUS))
          {
            if (posY < 1023) posY++;
            while (digitalRead(PIN_BTN_PLUS)) delay(1);
            lcd.setCursor(0,1); lcd.print("      Y "); lcd.print(posY);
          }
          if (digitalRead(PIN_BTN_MINUS))
          {
            if (posY > 0) posY--;
            while (digitalRead(PIN_BTN_MINUS)) delay(1);
            lcd.setCursor(0,1); lcd.print("      Y "); lcd.print(posY);
          }
          if (digitalRead(PIN_BTN_SELECT))
          {
            mode = MODE_PROG;
            while (digitalRead(PIN_BTN_SELECT)) delay(1);
          }
          break;
        }
        case MODE_PROG:
        {
          lcd.setCursor(0,0); lcd.print("    Programm  "); delay(200);
          lcd.setCursor(0,1); lcd.print(" Press  start "); delay(200);
          if (digitalRead(PIN_BTN_START))
          {
            mode = MODE_SYNC;
            while (digitalRead(PIN_BTN_START)) delay(1);
          }
          if (digitalRead(PIN_BTN_ANALOG))
         
          {
            mode = MODE_STOP;
            while (digitalRead(PIN_BTN_ANALOG)) delay(1);
          }
          break;
        }
        case MODE_SYNC:
        {
          lcd.setCursor(0,1); lcd.print("      start    "); delay(200);
          if (digitalRead(PIN_BTN_SYNC)) delay(1);
          {
      {
      PinLOWy = LOW;
      PinHIGHy = HIGH;
      PinLOWx = LOW;
      PinHIGHx = HIGH;
     
      digitalWrite(PIN_IN3, PinLOWx);
      digitalWrite(PIN_IN4, PinHIGHx);
      analogWrite(PIN_ENB,150);
      {
        bool currentState = digitalRead(DISTx_PIN);
        if(currentState != prevStateX)
        {
          prevStateX = currentState;
          counterX++;
          if(counterX == posX)
          {
            counterX = 0;
            analogWrite(PIN_ENB,0);
          }
        }
        digitalWrite(PIN_IN1, PinLOWy);
        digitalWrite(PIN_IN2, PinHIGHy);
        analogWrite(PIN_ENA,150);
        {
          bool currentState = digitalRead(DISTy_PIN);
          if(currentState != prevStateY)
          {
            prevStateY = currentState;
            counterY++;
            if(counterY == posY)
            {
              counterY = 0;
              analogWrite(PIN_ENA,0);
            }
          }
        }
      }
            while (digitalRead(PIN_BTN_SYNC)) delay(1);
          }
          if (digitalRead(PIN_BTN_ANALOG))
          {
            mode = MODE_STOP;
            while (digitalRead(PIN_BTN_ANALOG)) delay(1);
          }
          break;
        }
        case MODE_STOP:
        {
          lcd.setCursor(0,0); lcd.print("    Programm"); delay(200);
          lcd.setCursor(0,1); lcd.print("      stop  "); delay(200);
          if (digitalRead(PIN_BTN_ANALOG))
          {
            mode = MODE_MANUAL;
            while (digitalRead(PIN_BTN_ANALOG)) delay(1);
          }
          break;
        }
      }
      }
    }
     
    Последнее редактирование: 10 окт 2013
  9. sanik

    sanik Гик

    Как сделать обнуление счетчика, я не знаю? И если я его обнулю то как быть с повторным импульсом от кнопки PIN_BTN_SYNC?
    Я вас правильно понял?
    Код (Text):
    void loop()
    {
      if (digitalRead(PIN_BTN_SYNC))  //если_нажалась кнопка start, то
        {
          digitalWrite(PIN_IN3, PinLOWx);  //запустить мотор
          digitalWrite(PIN_IN4, PinHIGHx);
          analogWrite(PIN_ENB,150);
         Каким способом?   counterX = 0    //обнулить_счетчик
        }

      bool currentState = digitalRead(DISTx_PIN);   //если_появился_импульс_от_фотоинтераптора, то
       if(currentState != prevStateX)

       prevStateX = currentState;  //увеличить_счетчик_на_1
        counterX++;
         if(counterX == posX)
        counterX = 0;  //если_счетчик_достиг_максимального_значения, то
        {
          analogWrite(PIN_ENB,0);   //остановить_мотор
              ?????  //обнулить_счетчик
        }
    }
     
    Последнее редактирование: 10 окт 2013
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    Код (Text):
     if(counterX == posX)//если_счетчик_достиг_максимального_значения, то
     {
        counterX = 0;//обнулить_счетчик
        analogWrite(PIN_ENB,0);  //остановить_мотор
    }
    Видите разницу?
    Мне кажется, Вам следует серьезно поработать над изучением синтаксиса языка. Такое впечатление, что Вы не в полной мере понимаете то, что пишете.
     
  11. NR55RU

    NR55RU Гик

    Есть еще один хороший вариант.
    Отделить ардуино - зависимый код от того который к ардуину отношения не имеет.
    В частности вопрос использования ардуин-функций и писать независимый код на ПК, там тестировать намного проще.
    Я сейчас разрабатываю небольшой набор кода для управления платформой где полностью отгородил управляющую логику от ардуино-зависимости и связал все это объектом-посредником с определенным интерфейсом, на дуне этот объект будет работать с дуниными реальными функциями а на ПК он подставной.
    На ПК можно с такой же легкостью заменить штатные функции дуни например digitalWrite() будет выводить в консоль информацию о том что и куда пытаются записать, digitalRead() может например запрашивать с консоли ручной ввод параметров эмитируя получение данных с датчика или же будет рандомно что то генерировать.
    Позволяет очень хорошо отлаживать все на ПК а не заниматься садо-мазо с сериалом, LCD или гаданием на кофейной гуще + можно написать автоматические тесты :)
     
  12. sanik

    sanik Гик

    Вы абсолютно правы, я не совсем понимаю что написано в этих уроках что то как-то все зпутано
     
  13. sanik

    sanik Гик

    Немного разобрался но опять грабли из за чего он ругается? В том варианте чо у меня было он на это место не ругался, может я опять неправильно скобки поставил?
    Код (Text):
    {
      if (digitalRead(PIN_BTN_SYNC))//если_нажалась кнопка sunchro, то
      {
      PinLOWy = LOW;
      PinHIGHy = HIGH;
      PinLOWx = LOW;
      PinHIGHx = HIGH;

      digitalWrite(PIN_IN3, PinLOWx);
      digitalWrite(PIN_IN4, PinHIGHx);
      analogWrite(PIN_ENB, 150);
      digitalWrite(PIN_IN1, PinLOWy);
      digitalWrite(PIN_IN2, PinHIGHy);
      analogWrite(PIN_ENA, 150); //запустить мотор
      counterX = 0;//обнулить_счетчик
      counterY = 0;
      }
      bool currentState = digitalRead(DISTx_PIN);  //если_появился_импульс_от_фотоинтераптора, то
      if(currentState != prevStateX)
      prevStateX = currentState;
      counterX++;
      if(counterX == posX)//если_счетчик_достиг_максимального_значения, то
      {
      counterX = 0;//обнулить_счетчик
      analogWrite(PIN_ENB,0);  //остановить_мотор
      }
      bool currentState = digitalRead(DISTy_PIN);  //176: error: redeclaration of 'bool currentState'
    //167: error: 'bool currentState' previously declared here

      if(currentState != prevStateY)
      prevStateY = currentState;
      counterY++;
      if(counterY == posY)
      {
        counterY = 0;
        analogWrite(PIN_ENA,0);
      }
    }
     
    Последнее редактирование: 10 окт 2013
  14. sanik

    sanik Гик

    Все все таки разобрался спасибо вам огромное!!!
     
  15. Megakoteyka

    Megakoteyka Оракул Модератор

    Вы напрасно не форматируете код. Это улучшает читабельность, по отступам лучше видна логическая структура. Комментарии помогут разобраться в исходнике, когда Вы его откроете через пару месяцев.
    А для кнопки не помешало бы добавить подавление дребезга - используйте библиотеку Bounce.
     
  16. sanik

    sanik Гик

    Библиотекой я не умею пользоваться мне в этом пока не разобраться я думаю аппаратно погасить дребезг
    Код я уже полностью переписал) Еще вопросик возник , когда значение импульсов оставляешь по умолчанию, то есть posX = 0 у меня стартует двигатель, а мне надо наоборот как мне это исправить?
     
  17. sanik

    sanik Гик

    Я думаю может в начале обнулять счетчик а потом запускать мотор?
     
  18. Megakoteyka

    Megakoteyka Оракул Модератор

    Важно только, чтобы счетчик обнулился до того, как его значение потребуется в следующий раз.
    Это 2 соседние инструкции, они исполняются практически мгновенно.
    Произойдет обнуление микросекундой раньше или позже - совершенно не важно.
     
  19. Megakoteyka

    Megakoteyka Оракул Модератор

    Вот и научитесь заодно. Там же пример есть. И на форуме использование данной библиотеки обсуждалось не раз. Это проще, чем кажется.
    А что мешает сразу записать в posX желаемое число? ;)
     
  20. sanik

    sanik Гик

    Вот как раз сейчас пробую:)
    Код (Text):
    {
      if (digitalRead(PIN_BTN_SYNC))//если_нажалась кнопка sunchro, то
      {
      PinLOWy = LOW;
      PinHIGHy = HIGH;
      PinLOWx = LOW;
      PinHIGHx = HIGH;
     
      digitalWrite(PIN_IN3, PinLOWx);
      digitalWrite(PIN_IN4, PinHIGHx);
      analogWrite(PIN_ENB, 150);
      digitalWrite(PIN_IN1, PinLOWy);
      digitalWrite(PIN_IN2, PinHIGHy);
      analogWrite(PIN_ENA, 150); //запустить мотор
      counterX = 0;//обнулить_счетчик
      counterY = 0;
      }
      bool currentState = digitalRead(DISTx_PIN);  //если_появился_импульс_от_фотоинтераптора, то
      if(currentState != prevStateX)// инвертируем значение
      prevStateX = currentState; // записываем значение в currentState
      counterX++; // прибавляем единицу
      if(counterX == posX)//если_счетчик_достиг_максимального_значения, то
      if (posX == 0) // если значение равно 0,то
      {
        counterX = 0;//обнулить_счетчик
        analogWrite(PIN_ENB,0);  //остановить_мотор
      }
      bool correntState = digitalRead(DISTy_PIN);
      if(correntState != prevStateY)
      prevStateY = correntState;
      counterY++;
      if(counterY == posY)
      {
        counterY = 0;
        analogWrite(PIN_ENA,0);
      }
    }