Ошибка

Тема в разделе "Arduino & Shields", создана пользователем Gbsyi, 23 окт 2015.

  1. Megakoteyka

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

    У вас переменная position объявлена, но ей нигде не присваивается значение. Зачем ее выводить в монитор и зачем она вообще нужна?
    Ваш код никогда ничего не выведет в порт, если в каждом проходе цикла будет срабатывать оператор continue. Отладочный вывод нужно писать так, чтобы в монитор выводилась информация из всх мест программы, в которых может измениться ход ее выполнения.

    Вот это запустите:
    Код (C++):
    #include <Servo.h>

    #define MOTOR_PIN  9
    #define FIRST_BUTTON_PIN 5
    #define BUTTON_COUNT  3
    #define SPEED_STEP  (255 / (BUTTON_COUNT - 1))

    Servo myServo;

    void setup()
    {
      Serial.begin(9600);
      pinMode(MOTOR_PIN, OUTPUT);
      for (int i = 0; i < BUTTON_COUNT; ++i)
        pinMode(i + FIRST_BUTTON_PIN, INPUT_PULLUP);
      myServo.attach(11);
    }

    void loop()
    {
      Serial.println("for");
      for (int i = 0; i < BUTTON_COUNT; ++i)
      {
        Serial.print("i=");
        Serial.println(i);
        if (digitalRead(i + FIRST_BUTTON_PIN))
        {
          Serial.print("continue");
          continue;
        }

        int speed = i * SPEED_STEP;

        analogWrite(MOTOR_PIN, speed);
        Serial.print("speed=");
        Serial.println(speed);
      }
      Serial.println("end for");

      myServo.write(90);
      delay(150);
      myServo.write(0);
      delay(5000);
    }
     
  2. Gbsyi

    Gbsyi Нуб

    Вот что он пишет:
    Код (Text):

    i=0
    continuei=1
    continuei=2
    continueend for
    for
    i=0
    continuei=1
    continuei=2
    speed=254
    end for
     
     
  3. geher

    geher Гуру

    Если почитать программу, то получается, что в теории при нажатии на кнопку, подключенную к пину 5, мотор должен останавливаться (скорость 0), при нажатии на кнопку, подключенную к пину 6, должен вращаться (при условии, что характеристики мотора позволяют ему стронуться с места при уровне 128 для ШИМ), а при нажатии на кнопку, подключенную к пину 7, должен вращаться еще шустрее.
    Но на практике вероятность попадания самого факта нажатия на кнопку на тот момент, когда она опрашивается, весьма невелика, поскольку большую часть времени (больше 5 секунд) программа проводит в ожидании на вызовах delay.
    Вариантов, чтобы мотор в конце концов закрутился (при условии правильной физической сборки конструкции, в смысле, если все подключено как надо), получается два.
    Или зажать кнопку секунд на шесть, дабы гарантированно совпали проверка кнопки и ее нажатость, или выкинуть delay,

    Если будет принято решение выкинуть delay.
    Поскольку на delay завязано поведение сервы, то при простом выкидывании означенных delay серва практически не будет отрабатывать. Разве что нервно дергаться (если вообще успеет отреагировать на столь быстрые изменения).
    Потому, если желательно сохранить поведение сервы, придется не просто выкинуть delay, а перевести выполнение задержки на использование вызовов millis, дабы сравнивать текущее значение, возвращаемое этой функцией, с тем, что засекли при предыдущем дергании сервы.
     
    Последнее редактирование: 25 окт 2015
  4. geher

    geher Гуру

    Если была такая строка в мониторе последовательного порта, и не было строки speed=0, а двигатель не заработал, то проблема где-то в сборке конструкции.
    Либо мотор подключен не к девятому пину (исходя из кода требуется подключать именно к нему), либо мотор подключен как-то неправильно.
    Правильное подключение предусматривает подключение не мотора напрямую, а использование какого-нибудь промежуточного управляющего устройства, например, полевого транзистора или драйвера мотора с соответствующей обвязкой (защитные диоды, конденсаторы, резисторы, дабы ничего не спалить ненароком).
     
    Последнее редактирование: 25 окт 2015
  5. Gbsyi

    Gbsyi Нуб

    20151025_214552.jpg Схему сделать не смогу так как насколько я знаю надо определенную программу, поэтому вот фото.
     
  6. Gbsyi

    Gbsyi Нуб

    Я так понял должно получиться что-то вроде этого:
    Код (Text):

      myServo.write(90);
      millis();
      myServo.write(0);
      delay(5000);

     
     
  7. Gbsyi

    Gbsyi Нуб

    Еще раз просмотрел монитор последовательного порта и обнаружил, что если нажать кнопку в момент поворачивания сервопривода печатает скорость. Вот то, что он пишет.
    Код (Text):

    for
    i=0
    continuei=1
    speed=127
    i=2
    continueend for
    for
    i=0
    speed=0
    i=1
    continuei=2
    continueend for
    for
    i=0
    continuei=1
    continuei=2
    speed=254
    end for
     
     
  8. Megakoteyka

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

    А вы понимаете, как ваш код вообще работает? Какие операторы в каких условиях будут выполняться и почему?
     
  9. geher

    geher Гуру

    Совсем не так.
    Можно, например, примерно так (писалось теоретически, возможны ошибки и опечатки):
    Код (Text):

    static int servo0=2; //2 - неопределенное состояние, 0 - серва на 90, 1 - серва на 0
    stftic unsigned long int servotime; // последнее время поворота сервы
    if (servo0)
    { // когда серва на 0 градусов или в неопределенном состоянии (когда флаг не 0)
        if ((servo0==2)||((millis()-servotime)>5000)) // если неопределенное состояние (первый раз) или если прошло 5 с после поворота на 0
        {
           servotime=millis(); // фиксируем время поворота
           myServo.write(90); // поворачиваем
           servo0=0;                // устанавливаем состояние серва на 90
        }
    }
    else
    { // когда серва на 90 грудусов
        if ((millis()-servotime)>150)) // если если прошло 150 мс после поворота на 90
        {
           servotime=millis(); // фиксируем время поворота
           myServo.write(0);  // поворачиваем
           servo0=1;               // устанавливаем состояние серва на 0
        }
    }
     
     
  10. geher

    geher Гуру

    Физическая коммутация на фото вроде верная (навскидку, глубоко не вникал, мог и пропустить что-нибудь),
     
  11. Gbsyi

    Gbsyi Нуб

    Получилось у меня, вот что:
    Код (Text):

    #include <Servo.h>

    #define MOTOR_PIN  9
    #define FIRST_BUTTON_PIN 5
    #define BUTTON_COUNT  3
    #define SPEED_STEP  (255 / (BUTTON_COUNT - 1))

     Servo myServo;
    void setup()
    {
      pinMode(MOTOR_PIN, OUTPUT);
      for (int i = 0; i < BUTTON_COUNT; ++i)
      pinMode(i + FIRST_BUTTON_PIN, INPUT_PULLUP);
     {  
     Serial.begin(9600);
     }  
      myServo.attach(11);
    }
     
    void loop()
    {
      int position;
     
      for (int i = 0; i < BUTTON_COUNT; ++i) {
      if (digitalRead(i + FIRST_BUTTON_PIN))
      continue;
     
      int speed = i * SPEED_STEP;
     
      analogWrite(MOTOR_PIN, speed);
      }
     {
      static int servo0=2;
     static unsigned long int servotime;
    if (servo0)
     {
      if ((servo0==2)||((millis()-servotime)>5000))
      {
      servotime=millis();
      myServo.write(90);
      servo0=0;  
      }
     }
     else
     { // когда серва на 90 грудусов
      if ((millis()-servotime)>150)
      {
      servotime=millis();
      myServo.write(0);
      servo0=1;
      }
      }
      }
    }
     
    Я понял, что нужно сделать немного по другому ,так как при нажатии кнопки двигается сервопривод на положение 0, вместо кручения мотора.