При подключении второго шаговика программа перестает работать

Тема в разделе "Arduino & Shields", создана пользователем Эникей, 27 авг 2019.

  1. Эникей

    Эникей Нуб

    Для моего проекта нужно 2 шаговика, но сейчас есть только 1. Я написал часть кода для первого шаговика и решил просто его же подключить к другим пинам и написать вторую часть кода. Просто чтобы не тратить время, пока жду заказанный шаговик. Но столкнулся с проблемой: при подключении второго шаговика (stepper_speed(4, 5, 6, 7)) у меня ВЕСЬ проект перестает работать, даже функция millis() по какой-то причине не вычисляется. Всё зависает после срабатывания функции setup(). Смотрю на код, и не могу понять, в чем причина. Думал, что это связано с тем, что шаговик stepper(8, 9, 10, 11); отключен от своих пинов, я пытался убирать функцию stepper.run(), но ничего не меняется... Вообще уже всю голову сломал, не могу понять причину... Может быть библиотека CustomStepper не поддерживает несколько шаговиков? Посмотрите, пожалуйста, код. Может быть чего подскажете...
    Код (C++):
    // Видеообзоры и уроки работы с ARDUINO на YouTube-канале IOMOIO: https://www.youtube.com/channel/UCmNXABaTjX_iKH28TTJpiqA
    #define potent_pin A0               // -- пин, к которому подключен потенциометр
    #define start_button_pin 2          // -- пин с кнопкой запуска двигателя
    #define beeper_pin 3                // -- пин с пищалкой
    #define fuel_led 12                 // -- пин со светодиодом (закончилось топливо)
    #define servo_pin A1                // -- пин с сервоприводом
    #define coup_button_pin A2          // -- пин с кнопкой сцепления
    // передачи
    #define gear1 A3                    // 1st gear
    #define gear2 A4                    // 2nd gear


    #include <Servo.h>
    #include <CustomStepper.h>            // Подключаем библиотеку управления шаговым двигателем. По умолчанию настроена на двигатель 28BYJ-48-5V
    CustomStepper stepper(8, 9, 10, 11);  // Указываем пины, к которым подключен драйвер шагового двигателя
    CustomStepper stepper_speed(4, 5, 6, 7);  // Указываем пины, к которым подключен драйвер шагового двигателя
    Servo servo_fuel;

    boolean setup_steppers_forward = false; // тестирование систем (все стрелки идут вперед)
    boolean setup_steppers_backward = false; // тестирование систем (все стрелки идут назад)
    int current_rpm = 0;                   // текущие обороты двигателя
    int current_speed = 0;
    int current_acceleration = 0;          // текущее положение педали газа
    int speed_acceleration = 0;
    boolean start_button = false;          // переменная, отвечающая за нажатие кнопки запуска мотора
    boolean motor_is_up = false;           // переменная, сигнализирующая о том, что мотор запущен
    unsigned long int timer_for_motor = 0; // время, ограницивающее включение/выключение двигателя (раз в 3 секунды)
    unsigned long int beeper_start = 0; // время начала пищания при запуске системы
    //double fuel_level = 1023; // пока что значение задается в программе
    int int_fuel_level = 1023;
    long int fuel_start = millis();
    long int fuel_stop = millis();
    long int testing_led_start = 0;
    boolean led_tested = false;
    boolean coup = true; // показывает, включено ли сцепление
    byte gear = 0;
    byte gears1 = 0;
    byte gears2 = 0;
    void setup()
    {
      servo_fuel.attach(servo_pin);
      Serial.begin(9600);
      stepper.setRPM(10);                 // Устанавливаем кол-во оборотов в минуту
      stepper.setSPR(4075.7728395);       // Устанавливаем кол-во шагов на полный оборот. Максимальное значение 4075.7728395
      //
      stepper_speed.setRPM(10);                 // Устанавливаем кол-во оборотов в минуту
      stepper_speed.setSPR(4075.7728395);       // Устанавливаем кол-во шагов на полный оборот. Максимальное значение 4075.7728395
      pinMode(start_button_pin, INPUT_PULLUP);
      pinMode(beeper_pin, OUTPUT);
      pinMode(fuel_led, OUTPUT);
      pinMode(coup_button_pin, INPUT_PULLUP);
      pinMode(gear1, INPUT_PULLUP);
      pinMode(gear2, INPUT_PULLUP);
     
      beeper_start = millis();
      tone(beeper_pin, 1000);
      // зажигаем светодиоды для тестировки...
      testing_led_start = millis();
      digitalWrite(fuel_led, HIGH);
    }

    void loop()
    {
      gears1 = !digitalRead(gear1);
      gears2 = !digitalRead(gear2);
      gear = 0;
      if (gears1) gear = 1;
      if (gears2) gear = 2;
      coup = digitalRead(coup_button_pin);
      if (millis() - testing_led_start > 5000) {
        //отключаем все светодиоды
        digitalWrite(fuel_led, LOW);
        led_tested = true;
      }
      if (millis() - beeper_start > 1000) noTone(beeper_pin);
      current_acceleration = analogRead(potent_pin);
      if (stepper.isDone() and !setup_steppers_forward){
        stepper.setDirection(CCW);
        stepper.rotateDegrees(250);
        setup_steppers_forward = true;
      }
      if (stepper.isDone() and !setup_steppers_backward){
        stepper.setDirection(CW);
        stepper.rotateDegrees(250);
        setup_steppers_backward = true;
      }
      //
      //блок кода для выполнения задач, если мотор выключен (если выключен - убираем ускорение на 0, отключаем все светодиоды и тп)
      //
      start_button = !digitalRead(start_button_pin);
      if (start_button && (millis() - timer_for_motor > 3000) && !motor_is_up){
        timer_for_motor = millis();
        motor_is_up = true;
      }else if (start_button && (millis() - timer_for_motor > 3000) && motor_is_up){
        timer_for_motor = millis();
        motor_is_up = false;
      }
      if (!motor_is_up){ // выполняется, если мотор выключен
        current_acceleration = 0; // обнуляем значение на педали газа - система на неё реагировать не будет
        servo_fuel.write(0); // переводим на 0 стрелку ДУТа
        if (led_tested){ // говорит системе, протестированы ли светодиоды (если они еще не были протестированы, то НЕ выключает их
        digitalWrite(fuel_led, LOW);
        }
        //
      }
      if ((motor_is_up and current_acceleration < 80) or (motor_is_up and !coup)){ // если мото включен, и педаль газа не нажата
        current_acceleration = 80;
      }
      change_acceleration();
      if (motor_is_up and coup){
        rebind_rpm_speed();
      }
      /*
      if (stepper.isDone() and example == 1)  // Когда предыдущая команда выполнена (см. ниже), метод stepper.isDone() возвращает true
      {
        stepper.setDirection(CW);         // Устанавливает направление вращения. Может принимать 3 значения: CW - по часовой, CCW - против часовой, STOP
        stepper.rotate(1);                // Устанавливает вращение на заданное кол-во оборотов
        example = 2;
      }
      if (stepper.isDone() and example == 2)
      {
        stepper.setDirection(CCW);
        stepper.rotateDegrees(90);        // Поворачивает вал на заданное кол-во градусов. Можно указывать десятичную точность (например 90.5), но не принимаются отрицательные значения
        example = 3;
      }
      if (stepper.isDone() and example == 3)
      {
        //stepper.setDirection(CW);
        //stepper.rotate();                 // Будет вращать пока не получит команду о смене направления или пока не получит директиву STOP
      }*/

    motor_run();
    fuel_control();
    }

    void change_acceleration(){
      if (current_acceleration != 0){
        fuel_stop = millis();
        if ((fuel_stop - fuel_start)>=500){
          fuel_start = millis();
          fuel_stop = millis();
          int_fuel_level -=1;
        }
      }
      if (current_acceleration > current_rpm+10) {
        if ((current_acceleration - current_rpm)>80 or (current_rpm - current_acceleration)>80){
          stepper.setRPM(20);
        }else{
          stepper.setRPM(8.5);
        }
        if (stepper.isDone()){
          current_rpm +=1;
          stepper.setDirection(CCW);
          stepper.rotateDegrees(0.25);
        }
      }
      else if (current_acceleration < current_rpm-10) {
        if ((current_acceleration - current_rpm)>80 or (current_rpm - current_acceleration)>80){
          stepper.setRPM(19);
        }else{
          stepper.setRPM(8.5);
        }
        if (stepper.isDone()){
          current_rpm -=1;
          stepper.setDirection(CW);
          stepper.rotateDegrees(0.25);
        }
      }
    }

    void rebind_rpm_speed(){
      speed_acceleration = current_rpm * 0.125 * pow(gear, 1.125);
      if (speed_acceleration > current_speed+5) {
        /*
        if ((current_acceleration - current_rpm)>80 or (current_rpm - current_acceleration)>80){
          stepper.setRPM(20);
        }else{
          stepper.setRPM(8.5);
        }
        */

        if (stepper_speed.isDone()){
          current_speed +=1;
          stepper_speed.setDirection(CCW);
          stepper_speed.rotateDegrees(0.25);
        }
      }
      else if (speed_acceleration < current_speed-5) {
        /*
        if ((current_acceleration - current_rpm)>80 or (current_rpm - current_acceleration)>80){
          stepper.setRPM(19);
        }else{
          stepper.setRPM(8.5);
        }
        */

        if (stepper_speed.isDone()){
          current_speed -=1;
          stepper_speed.setDirection(CW);
          stepper_speed.rotateDegrees(0.25);
        }
      }
    }




    void motor_run(){
      stepper.run();                      // Этот метод обязателен в блоке loop. Он инициирует работу двигателя, когда это необходимо
      stepper_speed.run();
    }

    void fuel_control(){
      if (motor_is_up){
        //здесь будет написан алгоритм, управляющий сервиприводом/шаговиком для топлива
        servo_fuel.write(map(int_fuel_level,0,1023,0,180));
        if ((int_fuel_level < 200) && motor_is_up){
          digitalWrite(fuel_led, HIGH);
        }
        if (int_fuel_level <= 50) {
          int_fuel_level = 50;
          motor_is_up = false;
        }
        }else{
          servo_fuel.write(0);
        }
       
    }
     
  2. b707

    b707 Гуру

    CustomStepper.h - это чья-то недоделанная библиотека, на ардуино.cc про нее есть ветка - и там тоже ни у кого с двумя моторами не работает.
    А в самом коде достаточно увидеть вот эту функцию, чтобы понять, что в коде может быть что угодно
    Код (C++):
    void CustomStepper::setTimer()
    {
      this->timer = micros() + this->time;
    }
     
    DetSimen и Эникей нравится это.
  3. Эникей

    Эникей Нуб

    Догадывался, что дело в библиотеке... А чем можно её заменить? Мне по сути, нужна только функция поворота двигателя на определенный угол (в градусах) и возможность задать скорость двигателю. Стандартная библиотека stepper это сделать не позволяет...
     
  4. b707

    b707 Гуру

    не спешите. То, что библиотека глючная, вовсе не означает. что ваш код - правильный.
    неужели? а мне казалось там все это есть