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

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

  1. sanik

    sanik Гик

    В смысле? Почему?
     
  2. sanik

    sanik Гик

    На тест пока не получится железо надо перепаивать и переделывать чем сейчас потихоньку и занимаюсь.:D
     
  3. lerik2703

    lerik2703 Гик

    так перемененная TimeExposure всегда будет больше exposValue !
     
  4. sanik

    sanik Гик

    Так значит надо равно ставить. Ну а практически так и делается или как то по другому? Будет соответствовать?
    Код (Text):
    if(TimeExposure == (exposValue))
     
  5. sanik

    sanik Гик

    Или скорей всего так..
    Код (Text):
    if(currentTime >= (TimeExposure + (exposValue))) // сравниваем текущий таймер с переменной exposValue
     
  6. Unixon

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

    Код (Text):
    if (currentTime >= (TimeExposure + exposValue))
     
  7. sanik

    sanik Гик

    Спасибо! Ну хоть в чем то самостоятельно разобрался :)
     
  8. sanik

    sanik Гик

    Ну вот остается разобраться как отсчитывать количество кадров после срабатывания реле digitalWrite (pin_shot, HIGH); Как записать сработало реле shootValue++; и когда значение кадров достигнуто countValue Переходим к шагу 2? Можно ли пользоваться delay(); в цикле с таймером? И вы говорили насчет фотоитерраптора "в целом не плохо но работать как задумано не будет! об этом потом.."

    Код (Text):
    #include <Bounce.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);

    // время подавления дребезга кнопок, мс
    #define DEBOUNCE_INTERVAL 20

    // номера пинов для кнопок
    #define btn_SELECT 3
    #define btn_PLUS  7
    #define btn_MINUS  6
    #define btn_START  4
    #define btn_STOP 5 // перепаять со 2
    // номера пинов мотора
    #define pin_A 10
    #define pin_B 11
    #define pin_ENABLE 12
    // пин потенциометра
    #define pin_dist A1
    boolean stop1 = false;// переменная для хранения флага концевика 1
    boolean stop2 = false;// переменная для хранения флага концевика 2
    //пин реле
    #define pin_foc 8 // пин реле фокусировки
    #define pin_shot 9 // пин реле затвора
    #define pin_Rd A2 // пин датчика концевиков
    #define pin_Pit 13 // питание фотоинтерраптора
    int posInt = 0;  // пин фотоинтерраптора, Пин 2 внешнее прерывание 0
    //Таймеры
    unsigned long currentTime;
    unsigned long TimePause,TimeExposure;
    // максимальные значения
    #define MAX_POS_VALUE  4000// для положения каретки
    #define MAX_PAUSE_VALUE  60000// для времени паузы
    #define MAX_EXPOSURE_VALUE  20000// для времени экспозиции
    #define MAX_SHOT_VALUE  4000
    // шаги алгоритма
    typedef enum STEPS {
      STEP1_HELLO,
      STEP2_GET_POTS,
      STEP3_GET_POSITION,
      STEP4_GET_PAUSE,
      STEP5_GET_EXPOSURE,
      STEP6_GET_COUNT,
      STEP7_GET_START,
      STEP8_PAUSE,
      STEP9_EXP,
      STEP_10MOT
    };

    // текущий шаг алгоритма
    STEPS currentStep = STEP1_HELLO;

    // создаем "давилки дребезга" для кнопок
    Bounce bouncerBtnSelect(btn_SELECT, DEBOUNCE_INTERVAL);
    Bounce bouncerBtnPlus(btn_PLUS, DEBOUNCE_INTERVAL);
    Bounce bouncerBtnMinus(btn_MINUS, DEBOUNCE_INTERVAL);
    Bounce bouncerBtnStart(btn_START, DEBOUNCE_INTERVAL);
    Bounce bouncerBtnStop(btn_STOP, DEBOUNCE_INTERVAL);

    void setup()
    {
      Serial.begin(9600);
      // инициализация дисплея, включаем подсветку, очищаем экран
      lcd.init();
      lcd.backlight();
      lcd.clear();
      currentTime = millis();// считываем время, прошедшее с момента запуска программы
      TimePause = currentTime; // таймер паузы
      TimeExposure = currentTime; //таймер эксозиции
      attachInterrupt(posInt, handleInt0, RISING);
      pinMode (btn_SELECT, INPUT);
      pinMode (btn_PLUS, INPUT);
      pinMode (btn_MINUS, INPUT);
      pinMode (btn_START, INPUT);
      pinMode (btn_STOP, INPUT);
      pinMode (pin_A, OUTPUT);
      pinMode (pin_B, OUTPUT);
      pinMode (pin_foc, OUTPUT);
      pinMode (pin_shot, OUTPUT);
      pinMode (pin_Pit, OUTPUT);
    }


    int potValue  = 0; // значение потенциометра 1
    volatile int pulse = 0 ;//считаем импульсы с фотоинтерраптора
    int pauseValue = 0; // значение времени паузы
    int exposValue = 0; // значение времени экспозиции
    int countValue = 0; // значение количества кадров
    int shootValue = 0; //значение счетчика кадров
    int control = 0; //значение датчика концевиков
    int posValue  = 0; // значение положения каретки
    int a;//значение скорости мотора

     
     
  9. sanik

    sanik Гик

    Вторая часть кода
    Код (Text):
    void hello()
    {
      // установка курсора, печать надписи
      lcd.setCursor(5, 0);
      lcd.print("Hello");
      delay(200);
      lcd.setCursor(0, 1);
      lcd.print(" Slider Timelaps");
      delay(2000);
      lcd.clear();// очистка дисплея.
    }
    void handleInt0() // функция прерывания
    {
      pulse++; //при поступлении импульса увеличиваем счетчик на 1
    }
    void RunMotor1(byte a)
    {
      digitalWrite (pin_A, LOW);
      digitalWrite(pin_B, HIGH);
      analogWrite(pin_ENABLE,a);
    }
    void RunMotor2(byte a)
    {
      digitalWrite (pin_A, HIGH);
      digitalWrite(pin_B, LOW);
      analogWrite(pin_ENABLE,a);
    }
    void StopMotor()
    {
      digitalWrite(pin_ENABLE, 0);
      digitalWrite(pin_A, LOW);
      digitalWrite(pin_B, LOW);
    }
    boolean limit1()
    {
      control = analogRead(pin_Rd);
      return control>= 540 && control <= 550; //есть сигнал с концевика 1
    }
    boolean limit2()
    {
      control = analogRead(pin_Rd);
      return control>= 450 && control <= 460;
    }
    void loop()
    {
      // обновление состояния кнопки
      bouncerBtnSelect.update();
      bouncerBtnPlus.update();
      bouncerBtnMinus.update();
      bouncerBtnStart.update();
      bouncerBtnStop.update();
      switch(currentStep)
      {
        case STEP1_HELLO:
        hello();
        currentStep = STEP2_GET_POTS;
        break;
     
        case STEP2_GET_POTS:
        lcd.setCursor(0,0);
        lcd.print("    Manyal  ");
        {
          potValue = analogRead(pin_dist);
          if(potValue >= 480 && potValue <= 530)
          {
            StopMotor();
          }
          else if(potValue <= 490 && !stop1)
          {
            if (stop2)//сбрасываем флаг если мотор поменял направление эквивалент выражения stop2&=!stop2;
            {
              stop2=!stop2;
            }
            RunMotor1(map(potValue, 0, 490, 255, 10));
          }
          else if(potValue >= 530 && !stop2 )
          {
            if (stop1)
            {
              stop1=!stop1;
            }
            RunMotor2(map(potValue, 530, 1023, 10, 255));
          }
          stop1 = control>= 540 && control <= 550; //есть сигнал с концевика 1
          stop2 = control>= 450 && control <= 460; //есть сигнал с концевика 2
        }
        if(bouncerBtnSelect.read() == HIGH)// проверяем, нажата ли кнопка
        currentStep = STEP3_GET_POSITION; //переходим к шагу 3
     
        break;
     
        case STEP3_GET_POSITION:
        lcd.setCursor(0,0);
        lcd.print("Setting position");
        // гоним каертку на исходную позицию
        // плавный разгон a = 25 Начальное напряжение, подаваемое на двигатель
        // a <= 150 Условие для шага. a+=30 шаг, и исходя из условия выше, шаг не может быть больше 150
        for(int x = 25; x<=150; x +=30)
        RunMotor1(x);
        delay(10);
        limit1();//читаем датчик концевик, и останавливаем каретку в крайней позиции
        StopMotor();
        // кнопка нажата и значение меньше максимально допустимого?
        if(bouncerBtnPlus.read() == HIGH && posValue < MAX_POS_VALUE)
        posValue++;
        lcd.setCursor(0,1); lcd.print("Position"); lcd.print(posValue);
        // кнопка нажата и значение больше минимально допустимого (нуля)?
        if(bouncerBtnMinus.read() == HIGH && posValue > 0)
        posValue--;
        lcd.setCursor(0,1); lcd.print("Position"); lcd.print(posValue);
        if(bouncerBtnSelect.read() == HIGH)
        {
          currentStep = STEP4_GET_PAUSE; // переходим к шагу 4
        }
        break;
     
        case STEP4_GET_PAUSE:
        lcd.setCursor(0,0);
        lcd.print("Setting interval");
        if(bouncerBtnPlus.read() == HIGH && pauseValue < MAX_PAUSE_VALUE)
        pauseValue+=1000;
        lcd.setCursor(0,1); lcd.print("Interval"); lcd.print(pauseValue/1000);
        if(bouncerBtnMinus.read() == HIGH && pauseValue > 0)
        pauseValue-=1000;
        lcd.setCursor(0,1); lcd.print("Interval"); lcd.print(pauseValue/1000);
        if(bouncerBtnSelect.read() == HIGH)
        {
          currentStep = STEP5_GET_EXPOSURE;
        }
        break;
        case STEP5_GET_EXPOSURE:
        lcd.setCursor(0,0);
        lcd.print("Setting exposure");
        if(bouncerBtnPlus.read() == HIGH && exposValue < MAX_EXPOSURE_VALUE)
        exposValue+=1000;
        lcd.setCursor(0,1); lcd.print("exp time"); lcd.print(exposValue/1000);
        if(bouncerBtnMinus.read() == HIGH && exposValue > 0)
        exposValue-=1000;
        lcd.setCursor(0,1); lcd.print("exp time"); lcd.print(exposValue/1000);
        if(bouncerBtnSelect.read() == HIGH)
        {
          currentStep = STEP6_GET_COUNT;
        }
        break;
     
        case STEP6_GET_COUNT:
        lcd.setCursor(0,0);
        lcd.print("Setting shooting");
        if(bouncerBtnPlus.read() == HIGH && shootValue < MAX_SHOT_VALUE)
        shootValue++;
        lcd.setCursor(0,1); lcd.print("num shots"); lcd.print(shootValue);
        if(bouncerBtnMinus.read() == HIGH && shootValue > 0)
        shootValue--;
        lcd.setCursor(0,1); lcd.print("num shots"); lcd.print(shootValue);
        {
          currentStep = STEP7_GET_START;//Переходим к шагу 7
        }
        break;
     
        case STEP7_GET_START:
        lcd.setCursor(0,0);
        lcd.print("Start shooting");
        if(bouncerBtnStop.read() == HIGH)
        lcd.setCursor(0,0);lcd.print("    Manyal  ");
        lcd.setCursor(0,1);lcd.print("Stop shooting");
        {
          currentStep = STEP2_GET_POTS;//Переходим к шагу 2
        }
        if(bouncerBtnStart.read() == HIGH)
        {
          currentStep = STEP8_PAUSE;//Переходим к шагу 8
        }
        break;
        case STEP8_PAUSE:
        lcd.setCursor(0,0);
        lcd.print("Start shooting");
        lcd.setCursor(0,1);
        lcd.print("shut shots");lcd.print(shootValue);
        currentTime = millis();// считываем время, прошедшее с момента запуска программы
        if (currentTime >= (TimePause + pauseValue)) // сравниваем текущий таймер с переменной TimePause
        {
          currentStep = STEP9_EXP;//Переходим к шагу 9
        }
        if(bouncerBtnStop.read() == HIGH)
        lcd.setCursor(0,0);lcd.print("    Manyal  ");
        lcd.setCursor(0,1);lcd.print("Stop shooting");
        {
          currentStep = STEP2_GET_POTS; //Переходим к шагу 2
        }
        TimePause = currentTime; // в currentTime записываем новое значение
        break;
     
        case STEP9_EXP:
        lcd.setCursor(0,0); lcd.print("Start shooting");
        lcd.setCursor(0,1);lcd.print("shut shots");lcd.print(shootValue);
        currentTime = millis();// считываем время, прошедшее с момента запуска программы
        digitalWrite (pin_foc, HIGH);
        // задержка 20 мс.
        digitalWrite (pin_shot, HIGH);
        // Отсчет кличества кадров
        // значение кадров достигнуто выставленному Переходим к шагу 2
        if (currentTime >= (TimeExposure + exposValue)) // сравниваем текущий таймер с переменной exposValue
        digitalWrite (pin_foc, LOW);
        digitalWrite (pin_shot, LOW);
        {
          currentStep = STEP_10MOT;
        }
        if(bouncerBtnStop.read() == HIGH)
        digitalWrite (pin_foc, LOW);
        digitalWrite (pin_shot, LOW);
        lcd.setCursor(0,0);lcd.print("    Manyal  ");
        lcd.setCursor(0,1);lcd.print("Stop shooting");
        {
          currentStep = STEP2_GET_POTS; //Переходим к шагу 2
        }
        TimeExposure = currentTime; // в currentTime записываем новое значение
        break;
     
        case STEP_10MOT:
        currentTime = millis();// считываем время, прошедшее с момента запуска программы
        digitalWrite (pin_Pit, HIGH);// включаем питание фотоинтерраптора
        control = analogRead(pin_Rd);
        limit1();// если положение 1 - крутить в направлении 1
        for(int x = 25; x<=150; x +=30) // плавный разгон
        RunMotor1(x);
        limit2();// если положение 2 - крутить в направлении 2
        for(int x = 25; x<=150; x +=30) // плавный разгон
        RunMotor2(x);
        if (pulse == posValue)//считаем количество импульсов,достигли значение
        {
          pulse=0; // сброс счетчика на 0
          StopMotor();
        }
        if (currentTime >= (TimePause + pauseValue)) // сравниваем текущий таймер с переменной TimePause
        StopMotor();
        digitalWrite (pin_Pit, LOW);
        {
          currentStep = STEP9_EXP; //Переходим к шагу 9
        }
        if(bouncerBtnStop.read() == HIGH)
        StopMotor();
        lcd.setCursor(0,0);lcd.print("    Manyal  ");
        lcd.setCursor(0,1);lcd.print("Stop shooting");
        digitalWrite (pin_Pit, LOW);
        {
          currentStep = STEP2_GET_POTS; //Переходим к шагу 2
        }
        TimePause = currentTime;
        break;
      }
    }
     
  10. sanik

    sanik Гик

    Я думаю наверное так при каждом входе в case STEP9_EXP: прибавляем единицу shootValue++ Это нормально будет работать?
     
  11. sanik

    sanik Гик

    Да получается разговариваю сам с собой:) Я вот вычитал задержку без delay() Может мне применить её для управления реле? Как правильно в моем коде использовать?
    Код (Text):
    #define pin_shot 9 // пин реле затвора    
    long lagMillis = 0;        // храним время последнего переключения реле
    long interval = 20;          // интервал между включением реле
    void setup()
    {
      pinMode (pin_shot, OUTPUT);
    }
    void loop()
    {
      unsigned long currentMillis = millis();
     
      //проверяем не прошел ли нужный интервал, если прошел то
      if(currentMillis - lagMillis > interval)
      {
        // сохраняем время последнего переключения
        lagMillis = currentMillis;
        digitalWrite (pin_shot, HIGH);
      }
    }
     
  12. lerik2703

    lerik2703 Гик

    Код (Text):
          stop1 = control>= 540 && control <= 550; //есть сигнал с концевика 1
          stop2 = control>= 450 && control <= 460; //есть сигнал с концевика 2
        }
        if(bouncerBtnSelect.read() == HIGH)// проверяем, нажата ли кнопка
        currentStep = STEP3_GET_POSITION; //переходим к шагу 3
    по моему где-то здесь не хватает остановки двигателя! а то ручку мы заблокировали а движок как ехал так и едет дальше,а вы куда-то все торопитесь [​IMG] все-таки программирование не любит спешки [​IMG]
     
  13. lerik2703

    lerik2703 Гик

    Код (Text):
        if (currentTime >= (TimePause + pauseValue)) // сравниваем текущий таймер с переменной TimePause
        {
          currentStep = STEP9_EXP;//Переходим к шагу 9
        }
    если переход не критичен и можно немного задержаться то можно !
     
  14. lerik2703

    lerik2703 Гик

    Код (Text):
            if (stop2)//сбрасываем флаг если мотор поменял направление эквивалент выражения stop2&=!stop2;
            {
              stop2=!stop2;
            }
            Ru
    кстати сброс флага можно и убрать как мотор поменяет направление перемененные и так получат значение false!
     
  15. sanik

    sanik Гик

    Я подумал лучше использовать такую задержку http://forum.amperka.ru/threads/Где-может-быть-ошибка-кода.2047/page-16#post-16302 Правильно ли её написал?
    Так я немного не разобрался как работают флаги и как задействовано здесь управление моторами. Записал то что вы мне посоветовали а принципа так и не понял. Как его остановить? Я думаю если просто StopMotor(); то как быть с другим направлением? Или оно будет работать?
     
  16. sanik

    sanik Гик

    Блин совсем запутался с этими флагами :(
     
  17. lerik2703

    lerik2703 Гик

    ни чем от этой не отличается! currentTime >= (TimePause + pauseValue)
    в том то и дело что что пока мотор не отъедет от концевика получиться что концевик будет давать команду стоп а регулятор пуск ...
     
  18. sanik

    sanik Гик

    Значит просто записывать так?

    stop1 = control>= 540 && control <= 550; //есть сигнал с концевика 1
    stop2 = control>= 450 && control <= 460; //есть сигнал с концевика 2
    StopMotor();
     
  19. lerik2703

    lerik2703 Гик

    нет! нам нужно условия для остановки мотора проверить!
    if (stop1 || stop2) StopMotor();
     
  20. sanik

    sanik Гик

    В итоге получается так?
    Код (Text):
        case STEP2_GET_POTS:
        lcd.setCursor(0,0);
        lcd.print("    Manyal  ");
        potValue = analogRead(pin_dist);
        if(potValue >= 480 && potValue <= 530)
        {
          StopMotor();
        }
        else if(potValue <= 490 && !stop1)
        {
          if (stop2)//сбрасываем флаг если мотор поменял направление
          {
            stop2=!stop2;
          }
          RunMotor1(map(potValue, 0, 490, 255, 10));
        }
        else if(potValue >= 530 && !stop2 )
        {
          if (stop1)
          {
            stop1=!stop1;
          }
          RunMotor2(map(potValue, 530, 1023, 10, 255));
        }
        stop1 = control>= 540 && control <= 550; //есть сигнал с концевика 1
        if (stop1 || stop2)StopMotor();
        stop2 = control>= 450 && control <= 460; //есть сигнал с концевика 2
        if (stop2 || stop1)StopMotor();
        if(bouncerBtnSelect.read() == HIGH)// проверяем, нажата ли кнопка
        currentStep = STEP3_GET_POSITION; //переходим к шагу 3
       
        break;