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

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

  1. sanik

    sanik Гик

    Код (Text):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27,16,2);

    #define DISTx_PIN 1  //Пин фотоинтераптора х, каретка
    int posX = 0;  //Установка количества импульсов
    int prevStateX = LOW;
    int counterX = 0;// перменная сравнения поступающих импульсов

    #define DISTy_PIN 0 //Пин фотоинтераптора y, голова
    int posY = 0;
    int prevStateY = LOW;
    int counterY = 0;

    const byte PIN_POS_X = A0; //Пин потенциомера Х
    const byte PIN_POS_Y = A1; //Пин потенциомера Y
    int rewX; // переменая для замера сопротивления Х
    int rewY; // переменая для замера сопротивления У
    int a; // переменая скорости вращения двигателя 1
    int c; // переменая чтения потенциомера Х для реверса
    int d; // переменая скорости вращения двигателя 2
    int x; // переменая чтения потенциомера У для реверса

    // переменные для состояния направления двигателя
    int PinLOWx;
    int PinHIGHx;
    int PinLOWy;
    int PinHIGHy;

    const byte PIN_Rd = A2; //Пин датчика направления
    int rewerSd;//переменная для датчика направления в режиме PROGRAMM

    // кнопки
    const byte PIN_BTN_SELECT = 3;
    const byte PIN_BTN_START  = 4;
    const byte PIN_BTN_ANALOG  = 2;
    const byte PIN_BTN_PLUS  = 7;
    const byte PIN_BTN_MINUS  = 6;
    const byte PIN_BTN_SYNC  = 5;
    // драйвер двигателей
    const byte PIN_IN1 = 12;
    const byte PIN_IN2 = 13;
    const byte PIN_ENA = 11;//каретка
    const byte PIN_IN4 = 8;
    const byte PIN_IN3 = 9;
    const byte PIN_ENB = 10; //голова

    const byte MODE_INIT    = 0;
    const byte MODE_MANUAL  = 1;
    const byte MODE_SELECT_X = 2;
    const byte MODE_SELECT_Y = 3;
    const byte MODE_PROG    = 4;
    const byte MODE_SYNC    = 5;
    const byte MODE_STOP    = 6;
    byte mode = MODE_INIT;

    void setup()
    {
      Serial.begin(9600);
      lcd.init();lcd.backlight();lcd.clear();
      pinMode(DISTx_PIN, INPUT);
      pinMode(DISTy_PIN, INPUT);
      pinMode(PIN_BTN_SELECT, INPUT); //установка кнопки select
      pinMode(PIN_BTN_START, INPUT); //установка кнопки start
      pinMode(PIN_BTN_ANALOG, INPUT); //установка кнопки analog
      pinMode(PIN_BTN_PLUS, INPUT); //установка кнопки +
      pinMode(PIN_BTN_MINUS, INPUT); //установка кнопки -
      pinMode(PIN_BTN_SYNC,INPUT);
      pinMode(PIN_IN1, OUTPUT);
      pinMode(PIN_IN2, OUTPUT);
      pinMode(PIN_ENA, OUTPUT);
      pinMode(PIN_IN3, OUTPUT);
      pinMode(PIN_IN4, OUTPUT);
      pinMode(PIN_ENB, OUTPUT);
    }

    void hello()
    {
      lcd.setCursor(0, 0);lcd.print("    Hello");delay(200);
      lcd.setCursor(0, 1);lcd.print(" Slider Timelaps");delay(2000);
      lcd.clear();lcd.setCursor(0,0);lcd.print("    Analog");delay(200);
    }

    void processAnalog()
    {
      lcd.setCursor(0,0);lcd.print("    Analog  ");delay(200);
      lcd.setCursor(0,1);lcd.print("            ");delay(200);
      {
      x = analogRead(PIN_POS_X); // считываем сзначение потециомера и записываем в переменую х
      if(x <= 511) // если х меньше или равно 511 то,
      {
        a = (511 - x) * 2; // считаное показание умножаем на 2 получаем 1022 записываем в переменую а
      }
      else // иначе
      {
        a = (x - 511) * 2;
      }
      rewX = analogRead(PIN_POS_X); // читаем показания потециомера и записываем в rewX
      if (rewX > 510) // если показания меньше 520 то,
      {
        PinLOWx = HIGH;// запускаем мотор в одном направлении
        PinHIGHx = LOW;
      }
      if (rewX < 520 ) // если показания больше 520 то,
      {
        PinLOWx = LOW; // реверсим мотор
        PinHIGHx = HIGH;
      }
      else if(rewX >= 510 && rewX < 520) //иначе показания между 510 и 520 то,
      {
        PinLOWx = LOW; // останавливаем мотор
        PinHIGHx = LOW;
      }
      digitalWrite(PIN_IN3, PinLOWx);
      digitalWrite(PIN_IN4, PinHIGHx);
      analogWrite(PIN_ENB, a/4);
     
     
      c = analogRead(PIN_POS_Y);
      if(c <= 511)
      {
        d = (511 - c) * 2;
      }
      else
      {
        d = (c - 511) * 2;
      }
      rewY = analogRead(PIN_POS_Y);
      if (rewY > 510)
      {
        PinLOWy = HIGH;
        PinHIGHy = LOW;
      }
      if (rewY < 520 )
      {
        PinLOWy = LOW;
        PinHIGHy = HIGH;
      }
      else if(rewY >= 510 && rewY < 520)
      {
        PinLOWx = LOW;
        PinHIGHx = LOW;
      }
      digitalWrite(PIN_IN1, PinLOWy);
      digitalWrite(PIN_IN2, PinHIGHy);
      analogWrite(PIN_ENA, d/4);
      }
    }

    void syncronize()
    {
      rewerSd = analogRead(PIN_Rd); // читаем показания PIN_Rd и записываем значение в rewerSd
      if (rewerSd >= 540 && rewerSd <=550)// если rewerSd от 540 до 550 то,
      {
        PinLOWx = HIGH; // запускаем мотор X в одном направлении
        PinHIGHx = LOW;
      }
      if (rewerSd >= 450 && rewerSd <=460)// если rewerSd от 450 до 460 то,
      {
        PinLOWx = LOW; // реверсим мотор Х
        PinHIGHx = HIGH;
      }
      if (rewerSd >= 660 && rewerSd <=665)// если rewerSd от 660 до 665 то,
      {
        PinLOWy = HIGH;// запускаем мотор Y в одном направлении
        PinHIGHy = LOW;
      }
      if(rewerSd >= 720 && rewerSd <=730) // если rewerSd от 720 до 730 то,
      {
        PinLOWy = LOW; // реверсим мотор Y
        PinHIGHy = HIGH;
      }
     
      if (digitalRead(PIN_BTN_SYNC))//если_нажалась кнопка sunchro, то
      {
      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)//если_счетчик_достиг_максимального_значения, то
      {
        counterX = 0;//обнулить_счетчик
        analogWrite(PIN_ENB,0);  //остановить_мотор
      }
      if (posX == 0) // если значение равно 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);
      }
      if (posY == 0)
      {
        analogWrite(PIN_ENA,0);
      }
    }
    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_ANALOG))
            {
              posX = 0;
              while (digitalRead(PIN_BTN_ANALOG)) 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_ANALOG))
          {
            posY = 0;
            while (digitalRead(PIN_BTN_ANALOG)) 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);
          {
            syncronize();
            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;
        }
      }
    }
     
  2. sanik

    sanik Гик

    P9022335-2.jpg
     
    Unixon нравится это.
  3. Unixon

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

    Можете в свободной форме описать что должна делать processAnalog() ?
    Из кода неочевидно какому состоянию вашей установки соответствуют те или иные места в коде.

    Откуда берутся конкретные константы 520, 530 и т.п. ?
    Почему переменные, которые кроме processAnalog() больше нигде не используются, обявлены в самом начале?
    Чему в установке соответствуют rewX и т.п.? Что они измеряют? Т.е. понятно, что если датчик - потенциометр, то считывается напряжение от делителя и => сопротивление потенциометра. Но чему оно соответствует?
     
  4. Megakoteyka

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

    Забудьте пока про код. Распишите словами алгоритм работы установки.
    1. начало
    2. каретка поехала вперед, остановилась по условию ..., переход на шаг 3.
    3. делаем что-то еще, прекращаем по условию ...
    И так до самого конца, четко и внятно. Чем подробней, тем лучше. Чтобы мы тоже понимали суть задачи, а то ведь насоветуем неправильно и Вас только запутаем...
     
    Unixon нравится это.
  5. sanik

    sanik Гик

    processAnalog() При повороте регулятора Y (потенциометра ) от центрального положения в право каретка идет в право чем больше поворачиваю тем больше скорость, При повороте регулятора Y влево от центра каретка соответственно влево так же чем больше поворачиваю тем больше скорость. Аналогично и для поворота головы Х все больше в этом режиме ничего нет. Константы 520, 530 беруться с самодельного датчика (концевики) принцип работы как у четырех кнопок подключенных на аналоговый вход. В processAnalog() ничего не должно зависеть от void syncronize() ,
     
    Последнее редактирование: 15 окт 2013
  6. sanik

    sanik Гик

    При включении здороваемся и включаем режим аналог в этом режиме и головой Х и кареткой управляем с потенциометров, выход из режима нажатием кнопки селект сразу переходим на установку поворота головы устанавливаем сколько милиметров она повернется, если оставить 0 то голова поворачиваться не будет, если нажать кнопку аналог сброс показаний на ноль, выход нажатием кнопки селект переходим к каретке Y так же устанавливаем сколько милиметров она продвинется, так же при значении ноль, каретка не будет двигаться, выход нажатием кнопки селект переходим в ожидание нажатии кнопки старт при нажатии старт идет ожидание импульса лог1 со второй атмеги , поступил импульс каретка или голова или и то и другое продвинулась(повернулась) на заданое растояние, и дальше ждет импульса или нажатия двойного кноки аналог при нажатии первый раз моторы останавливаются пишет программ стоп ждет второго нажатия после второго нажатия переходит в режим аналог.
     
  7. Megakoteyka

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

    Перепишем это немного иначе:
    1. поздоровались, перешли в режим 2.
    2. крутим потенциометры, устанавливая желаемое положение головы и каретки. Чем больше потенциометр повернут от среднего положения, тем больше скорость поворота головы / движения каретки. По нажатию кнопки "селект" переходим в режим 3.
    3. задаем, насколько должна повернуться голова - каким образом задаем? По нажатию кнопки "аналог" сбрасываем настройки поворота головы. По нажатию "селект" переходим в режим 4.
    4. задаем смещение каретки - каким образом? По нажатию кнопки "селект" переходим в режим 5.
    5. ждем нажатия кнопки "старт". По нажатию "старт" переходим в режим 6.
    6. ждем импульс либо нажатие "аналог" По получению импульса переходим в режим 7, по получению "аналог", переходим в режим 8.
    7. крутим голову и двигаем каретку в соответствии с параметрами, полученными в режимах 3 и 4. Переходим в режим 6.
    8. ждем нажатия "аналог", по нажатию переходим в режим 1.
    Поправьте, если я неверно что-то понял.
     
  8. sanik

    sanik Гик

    Все правильно кроме 8.
    3. задаем, насколько должна повернуться голова кнопками плюс и минус одно короткое нажатие значение + или - единица длиное нажатие прибавляется или уменшается значение быстро.По нажатию кнопки "аналог" сбрасываем настройки поворота головы. По нажатию "селект" переходим в режим 4.
    4. задаем смещение каретки - кнопками плюс и минус одно короткое нажатие значение + или - единица длиное нажатие прибавляется или уменшается значение быстро. По нажатию кнопки "селект" переходим в режим 5.
    8. ждем нажатия "аналог", по нажатию переходим в режим 2.
     
  9. Unixon

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

    Этот потенциометр приводится в движение оператором вручную или механикой платформы автоматически?

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

    Вот что за название у режима "аналог"? Ни о чем не говорит и даже не подсказывает. Если это режим ручного управления, то так и нужно назвать "MODE_MANUAL".
     
  10. sanik

    sanik Гик

    1.Да потенциометр приводиться вручную

    2. Если бя хорошо разбирался в программировании- бы так и сделал как все оформлять я даже понятия не имею

    3. для меня было просто так удобней разницы ведь нету? Пусть будет "MODE_MANUAL"
     
  11. Megakoteyka

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

  12. Unixon

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

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

    Технически - нет, но вот посторонний человек из вашего кода ничего сходу не поймет. Да и сами начинаете через некоторое время путаться.
     
  13. Unixon

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

    ОК, давайте разберем ручной режим подробнее.
     
  14. Megakoteyka

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

    [​IMG]

    Вот в таком виде можете разрисовать весь алгоритм?
     
  15. sanik

    sanik Гик

    Почему нет таких статей Wirliq ? Действительно более понятно чем где либо.. Но про массивы для моего понятия сложны...
     
  16. sanik

    sanik Гик

    Думаю не справлюсь но попробую.
     
  17. Megakoteyka

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

    А это не про Wiring, это относится к любому языку программирования.
    Смотрите, как пишут примеры в книгах, в статьях - там обычно очень хороший стиль.
    Или гуглите "стандарты оформления кода".
     
  18. sanik

    sanik Гик

    У меня возник вопрос Есть возможность убрав ось головы (управление одного из мотора) освободить пины для реле и добавить код для интервалометра ? Я сейчас попытаюсь зарисовать алгоритм. И нужно ли докупать часы реального времени?
     
  19. Megakoteyka

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

    За несколько минут работы внутренний таймер далеко не убежит. Часы реального времени понадобятся если:
    а) нужно сохранять время во время отключения питания
    б) если Ваше устройство будет долго (дни, недели, месяцы, годы...) работать по расписанию, замерять большие интервалы времени и т.д. и при этом нужна большая точность.
     
  20. sanik

    sanik Гик

    Таймер будет работать в пределах от 1 секунды до 20 минут вот описал алгоритм сейчас буду пробовать зарисовать его, А вы надеюсь поможете мне все по порядку с нуля с чего начать и что и как сделать надеюсь что это не отнимет по времени еще полгода?

    1. При включении приветствие, переходим в режим 2.

    2. Крутим потенциометром, устанавливая желаемое положение каретки. Чем
    больше потенциометр повернут от среднего положения, тем больше скорость
    перемещения каретки, ожидаем нажатие кнопки select. Если каретка дошла до концевика останавливаем пока не будет повернут потенциометр в другое направление. По нажатию кнопки
    select, переходим в режим 3.

    3. Задаем, (количество импульсов с фотоитераптора) на сколько должна продвинуться каретка, нажатием кнопок plus или minus, по нажатию кнопки stop, сбрасываем настройки движения
    каретки, ждем нажатие кнопки select. Выводим значение на экран. По нажатию кнопки select,
    переходим в режим 4.

    4. Устанавливаем время (с шагом 1 сек) отсчета таймера pause нажатием, кнопок plus или minus в секундах, ждем нажатие кнопки select. Выводим значение на экран По нажатию кнопки select, переходим в режим 5.

    5. Устанавливаем время (с шагом 1 сек) отсчета таймера exposure нажатием, кнопок plus или
    minus в секундах, ждем нажатие кнопки select. Выводим значение на экран По нажатию кнопки
    select, переходим в режим 6.

    6. устанавливаем количество кадров shutter нажатием кнопок кнопок plus или
    minus, ждем нажатие кнопки select. Выводим значение на экран По нажатию кнопки
    select, переходим в режим 7.



    7.Ожидание нажатия кнопки start, ожидание нажатия кнопки stop, По
    нажатию кнопки start, переходим в режим 8. , По нажатию кнопки stop
    переходим в режим 2.

    8. Запускаем таймер pause в соответствии установленных параметров
    режимом 4., ожидание нажатия кнопки stop, по окончанию отсчета таймера
    pause, переходим в режим 9., , По нажатию кнопки stop переходим в
    режим 2.

    9. Запускаем таймер exposure в соответствии установленных параметров
    режимом 5. управляем срабатыванием реле focus ждем немного и реле shutter, уменьшаем значение счетчика количество кадров shutter на единицу заданого в режиме 6. Выводим на экран остаток кадров ,ожидание нажатия кнопки stop, по окончанию отсчета таймера exposure, отпускаем оба реле одновременно, переходим в режим 10., По нажатию кнопки stop отпускаем оба реле переходим в режим 2. При обнулении счетчика количество кадров shutter отпускаем оба реле переходим в режим 2.

    10.Запускаем таймер pause в соответствии установленных параметров режимом
    4., двигаем каретку в соответствии установленных параметров режимом 3.
    ожидание нажатия кнопки stop, ожидание срабатывание датчика направления
    каретки, останавливаем каретку в соответствии установленных
    параметров режимом 3. Переходим в режим 9. По нажатию кнопки stop
    переходим в режим 2. При срабатывание датчика направления каретки
    переходим в режим 11.

    11.Устанавливаем движение каретки в обратном направлении, двигаем каретку в соответствии установленных параметров режимом 3, останавливаем каретку в соответствии установленных
    параметров режимом 3 переходим в режим 9.
     
    Последнее редактирование: 25 окт 2013