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

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

  1. sanik

    sanik Гик

    Если такое и произойдет что одолжу то все равно мне придется обьяснять человеку как она работает.:)
    Какие неясности спрашивайте я отвечу.
     
  2. lerik2703

    lerik2703 Оракул

    все 13 сторонниц листать не хотеться так что если повторюсь не пинать :) с начало хочу спросить 11 пунктов это уже окончательный алгоритм программы ?
     
  3. sanik

    sanik Гик

    Алгоритм исправил полностью во всех страницах только что перечитывал всю ветку вот еще разок скину

    Алгоритм контроллера.

    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.
     
  4. lerik2703

    lerik2703 Оракул

    хорошо бы новой веткой запустить чтоб вносимые изменения оставались а первом посте!и так начинаем со 2-го параграфа!как вращать мотор в зависимости от потенциометра вы вроде разобрались!не понятно что делать с мотором когда нажата кнопка селект ?допустим доехала карета до середины повернули ручку обратно до середины нажали кнопку селект или не трогая ручку нажали селект!
     
  5. sanik

    sanik Гик

    Со вторым параграфом не понятно как датчик задействовать, остальное все нормально. При нажатии кнопки селект где бы не находилась каретка она едит к первому датчику в этот момент потенциометры отключаются скорость управления равна pin_ENABLE, 150 на всем этапе програмного режима.
     
  6. sanik

    sanik Гик

    На данный момент код выглядит так. Парковка каретки у меня прописана
    Код (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 2
    // номера пинов мотора
    #define pin_A 10
    #define pin_B 11
    #define pin_ENABLE 12
    // пин потенциометра
    #define pin_dist A1
    //пин реле
    #define pin_foc 8
    #define pin_shot 9
    // пин датчика концевиков
    #define pin_Rd A2
    // пин фотоинтераптора
    #define pin_pos 13
    // максимальные значения
    #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();

    }

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

    void hello()
    {
      lcd.setCursor(5, 0);lcd.print("Hello");delay(200);// установка курсора, печать надписи, задержка на 200 мс.
      lcd.setCursor(0, 1);lcd.print(" Slider Timelaps");delay(2000);
      lcd.clear();// очистка дисплея.
    }
    void RunMotor1()
    {
    digitalWrite (pin_A, LOW);
    digitalWrite(pin_B, HIGH);
    digitalWrite(pin_ENABLE,a/4);
    }
    void RunMotor2()
    {
      digitalWrite (pin_A, HIGH);
      digitalWrite(pin_B, LOW);
      digitalWrite(pin_ENABLE,a/4);
    }
    void StopMotor()
    {
      digitalWrite(pin_ENABLE, LOW);
    }  
    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 >= 510 && potValue <= 520)// если potValue в пределах [510; 520] - остановить мотор
        {
          a = (511 - potValue) * 2;
        }
        else
        {
          a = (potValue - 511) * 2;
        }
        StopMotor();
        if(potValue < 510)// если potValue в пределах (0; 510) - крутить в направлении 1
        RunMotor1();
        if(potValue > 520)// если potValue в пределах (520; 0) - крутить в направлении 2
        RunMotor2();
        control = analogRead(pin_Rd);// чтение кнцевика
        if(control>= 540 && control <= 550)// если положение 1
        // запрещаем крутить мотор в направлении 1
        if(control>= 450 && control <= 460)// если положение 2
        //запрещаем крутить мотор в направлении 2
        Serial.println("Каретка установлена! Переходим к шагу 3");
        if(bouncerBtnSelect.read() == HIGH)// проверяем, нажата ли кнопка
        currentStep = STEP3_GET_POSITION;
       
        break;
     
        case STEP3_GET_POSITION:
        lcd.setCursor(0,0); lcd.print("Setting position");
        // гоним каертку на исходную позицию
        RunMotor1();
        for(a = 25 ; a <= a; a+=30) // плавный разгон
        a *= 4; // так как значение а на пине делим на 4 соответсвено умножаем на 4
        //читаем датчик концевик, и останавливаем каретку в крайней позиции
        control = analogRead(pin_Rd);
        if(control>= 540 && control <= 550)
        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)
          {
            Serial.println("Установлено положение каретки! Переходим к шагу 4");
            currentStep = STEP4_GET_PAUSE;
          }
          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)
          {
            Serial.println("...! Переходим к шагу 5");
            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)
          {
            Serial.println("...! Переходим к шагу 6");
            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);
          // отсчет таймера pauseValue
          // время вышло
          {
            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
          }
          break;
          case STEP9_EXP:
          lcd.setCursor(0,0); lcd.print("Start shooting");
          lcd.setCursor(0,1);lcd.print("shut shots");lcd.print(shootValue);
          digitalWrite (pin_foc, HIGH);
          // задержка 20 мс.
          digitalWrite (pin_shot, HIGH);
          // отсчет таймера 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
          }
          break;
          case STEP_10MOT:
          // отсчет таймера pauseValue
          control = analogRead(pin_Rd);
          if(control>= 540 && control <= 550)// если положение 1 - крутить в направлении 1
          for(a = 25 ; a <= a; a+=30) // плавный разгон
          a *= 4; // так как значение а на пине делим на 4 соответсвено умножаем на 4
          RunMotor1();
          if(control>= 450 && control <= 460)// если положение 2 - крутить в направлении 2
          for(a = 25 ; a <= a; a+=30) // плавный разгон
          a *= 4; // так как значение а на пине делим на 4 соответсвено умножаем на 4
          RunMotor2();
          // сброс счетчика на 0
          //считаем количество импульсов
          // время вышло
          // StopMotor();
          {
            currentStep = STEP9_EXP; //Переходим к шагу 9
          }
          if(bouncerBtnStop.read() == HIGH)
          StopMotor();
          lcd.setCursor(0,0);lcd.print("    Manyal  ");
          lcd.setCursor(0,1);lcd.print("Stop shooting");
          {
            currentStep = STEP2_GET_POTS; //Переходим к шагу 2
          }
          break;
      }
    }
     
  7. lerik2703

    lerik2703 Оракул

    это как?
     
  8. sanik

    sanik Гик

    Вобщем допустим что потенциометр выкручен влево или в право, каретка едет, в этот момент нажал кнопку селект все управление от потенциометров отключается и мотор с плавным ускорением с шагом 30 (a = 25 ; a <= a; a+=30) едет на исходную касается датчика и останавливается, дальше идет регулировка параметров.
     
  9. lerik2703

    lerik2703 Оракул

    тогда не понятен смысл вращения потенциометра и всего шага если каретку все равно паркуется автоматически !?
     
  10. sanik

    sanik Гик

    В контролере два режима ручной и автоматический при включении запускается ручной режим для простого видео, тупо гоняем каретку туда сюда, датчик защищают от ударов о края и если отавил потенциометр вывернутым и отвлекся на другое то датчик не даст порвать ремень ли спалить драйвер. Когда нужно снять таймлапс кнопкой селект переключаем режим на автоматический задаем параметры и запускаем программу. Старт интервальной съемки начинаем с края. Теперь есть смысл? Получаем два в одном.
     
  11. sanik

    sanik Гик

    Хочу спросить что дальше то делать все что я смог то сделал. Сижу жду кода вы появитесь.
     
  12. lerik2703

    lerik2703 Оракул

    да понял вы решили не париться с меню и навигацией а тупо переключать режимы последовательно ИМХО не очень удобно :)
    теперь с кодом
    digitalWrite(pin_ENABLE,a/4);
    как я понял вы пытаетесь на этом выходе получить ШИМ сигнал?
     
  13. sanik

    sanik Гик

    Посмотрел урок Джереми про прерывания решил заняться фотоитераптором, завел переменные. А что задавать в функции swap () ? И как правильно расписать её?

    Код (Text):
    // пин фотоинтераптора
    int posInt = 0;

    void setup()
    {
    attachInterrupt(posInt, swap, RISING);
    }

    volatile int posValue  = 0; // значение положения каретки
    int pulse = 0; // значение счетчика фотоитераптора

    void swap() // функция прерывания
    {
    }
     
  14. sanik

    sanik Гик

    Да, для управления скоростью.
     
  15. lerik2703

    lerik2703 Оракул

  16. lerik2703

    lerik2703 Оракул

    вам не кажется что вы торопите события ?у вас и до этого ошибок полно!
     
    Последнее редактирование: 25 окт 2013
  17. lerik2703

    lerik2703 Оракул

    Код (Text):

    int posInt = 0;// пин фотоинтераптора
    volatile int pulse = 0 ;//считаем импульсы с фотоинтераптора
    void setup()
    {
      attachInterrupt(posInt, swap, RISING);
    }

    //volatile int posValue  = 0; // значение положения каретки
    //int pulse = 0; // значение счетчика фотоитераптора

    void loop()
    {

      if (pulse == 127)
      {
        //мы сделали оборот )))
      pulse=0;// можем обнулить счетчик
      }

    }

    void swap() // функция прерывания
    {
      pulse++; //при поступлении импульса увеличиваем счетчик на 1

    }
     
     
    Последнее редактирование: 25 окт 2013
  18. Unixon

    Unixon Оракул

    <буквоедство>

    Опять какие то левые идентификаторы полезли... "swap" - это перестановка. Что функция с чем меняет местами? Ничего. Назовите ее handleInt0() хотя бы что ли. Хоть будет понятно зачем оно нужно.

    sanik, не "фотоитераптор", а "фотоинтерраптор", от слова "interrupt" - прерывать, прерывание. т.е. фото-прерыватель.

    </буквоедство>

    Зачем "pulse==127" ? Сделайте в обработчике pulse = (pulse + 1) & 0x7f;
     
    Megakoteyka нравится это.
  19. lerik2703

    lerik2703 Оракул

    для наглядности а то побитовые операции в тупик совсем загонят :rolleyes:
     
  20. Megakoteyka

    Megakoteyka Оракул

    Поддержу. Правильная терминология важна. Правильное именование переменных и функций - тем более!
    Название переменной должно отвечать сути хранимых в ней данных.
    Название функции должно отвечать сути ее работы.
    Существуют даже списки общепринятых сокращений, используемых в именах.

    Сравните 2 варианта:
    Код (Text):
    int Summa(int a, int b)
    {
      return a + b;
    }
    и
    Код (Text):
    int Function_1(int a, int b)
    {
      return a + b;
    }
    Какой из них читается понятней?