Как выводить данные на дисплей, не прерывая работу ШД?

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем Tomasina, 27 янв 2016.

  1. Tomasina

    Tomasina Сушитель лампочек Модератор

    Хочу одновременно с работой ШД выводить на дисплей пройденное расстояние и количество оборотов.
    Но на время вывода данных ШД замирает (по звуку слышно), а мне нужно строго равномерное движение.
    Можно ли сделать отображение данных "в фоне"? Вроде в CNC на Arduino таких проблем нету. Как реализовать такое?
    Код (C++):

    #include <AccelStepper.h>
    #define DRIVER_ENA             4      // выход на клемму ENA "умного" драйвера ШД
    #define DRIVER_DIR             6      // выход на клемму DIR "умного" драйвера ШД
    #define DRIVER_PUL             5      // выход на клемму PUL "умного" драйвера ШД
    #define DRIVER_IN1             4      // выход на клемму IN1 драйвера на L298N для ДШИ200-2
    #define DRIVER_IN2             5      // выход на клемму IN2 драйвера на L298N для ДШИ200-2
    #define DRIVER_IN3             6      // выход на клемму IN3 драйвера на L298N для ДШИ200-2
    #define DRIVER_IN4             9      // выход на клемму IN4 драйвера на L298N для ДШИ200-2
    #define STEPS                  200    // задаётся количество шагов на оборот, для ШД на 1,8 градуса это 200 шагов
    #define MAX_SPEED              480.0  // максимальная скорость вращения ШД (шагов в сек) // для ДШИ200 это 480...512
    #define MIN_SPEED              2.0    // минимальная скорость вращения ШД
    #define ACCELERATION           MAX_SPEED  // ускорение ШД

    // для драйвера STEP/DIR:
    //AccelStepper stepper(AccelStepper::DRIVER, DRIVER_PUL, DRIVER_DIR);
    // для драйвера на L298N:
    AccelStepper stepper(AccelStepper::FULL4WIRE, DRIVER_IN1, DRIVER_IN2, DRIVER_IN3, DRIVER_IN4);

    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);
      Serial.begin(9600);
      stepper.setMaxSpeed(MAX_SPEED);
      stepper.setAcceleration(ACCELERATION);
      stepper.setSpeed(0);
      Serial.println("Enable Motor.");
      stepper.enableOutputs();
      stepper.moveTo(5000);
    }

    void loop()
    {    
      static unsigned long time = millis();
      stepper.run();

      if(millis() - time <500) digitalWrite(LED_BUILTIN, HIGH);
      else digitalWrite(LED_BUILTIN, LOW);

      if( millis() - time >= 1000) // вывод на дисплей (пока в Serial)
      {
        Serial.println(time/1000); // в этот момент ШД "замирает" :(
        time = millis();
      }

      if(stepper.distanceToGo() == 0)
      {
        stepper.setSpeed(0);
        stepper.stop();
        Serial.println("End.");
        Serial.println("Disable Motor.");
        stepper.disableOutputs();
      }
    }
     
     
  2. Alex19

    Alex19 Гуру

    Доброй ночи, тоже столкнулся с данной проблемой, хоть для меня она не критична шаговый стоит на мешалке компонентов.

    У меня экран ST7920_128X64, шаговый драйвер A4988 работающий как у Вас на AccelStepper. Единственный известный мне способ использование прерываний по таймеру, кстати тот же Marlin от 3D принтеров и grbl от CNC использует именно такой подход.

    Ссылка на grbl, файл для работы с шаговым - https://github.com/grbl/grbl/blob/master/grbl/stepper.c. Ссылка на Marlin - https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/stepper.cpp.

    Сам пока оставил как есть, пока проект в альфа версии, а это постоянные доделки и учет замечаний, пожеланий. Еще 2 дня тому, эта мешалка была на моторе с редуктором, который управлялся L298.
     
  3. vvr

    vvr Инженерище

    изменять какой то параметр на дисплее только при его изменении
     
  4. Onkel

    Onkel Гуру

    ну это неправильно. тут имхо два пути
    1 посылать на uart побайтно через десяток мс
    2 написать самому функцию управления шд на прерываниях по таймеру
     
  5. Tomasina

    Tomasina Сушитель лампочек Модератор

    Если отойти от UART/Serial - на дисплее (на базе ТМ1637) или OLED (на базе SSD1306) нужно отображать пройденное кареткой расстояние, а это хотя бы 1-2 раза в секунду нужно обновлять дисплей, и в это время движок замирает. Вот что имелось в виду.
     
  6. Onkel

    Onkel Гуру

    имхо имеет четко выраженный конфликт двух сторонних функций из двух библиотек. Выходов два - переписать в коде, без библиотек либо функцию управления шд, либо функцию управления дисплеем. Имхо надо посмотреть, какое прерывание задействовано в ф-ии управления дисплеем (какой таймер), и сделать функцию управления шд (а это несложная функция) на другом таймере.
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    в AccelStepper сделано так:
    Код (C++):
    // 4 pin step function
    // This is passed the current step number (0 to 3)
    // Subclasses can override
    void AccelStepper::step4(uint8_t step)
    {
        switch (step)
        {
        case 0:    // 1010
            digitalWrite(_pin1, HIGH);
            digitalWrite(_pin2, LOW);
            digitalWrite(_pin3, HIGH);
            digitalWrite(_pin4, LOW);
            break;

        case 1:    // 0110
            digitalWrite(_pin1, LOW);
            digitalWrite(_pin2, HIGH);
            digitalWrite(_pin3, HIGH);
            digitalWrite(_pin4, LOW);
            break;

        case 2:    //0101
            digitalWrite(_pin1, LOW);
            digitalWrite(_pin2, HIGH);
            digitalWrite(_pin3, LOW);
            digitalWrite(_pin4, HIGH);
            break;

        case 3:    //1001
            digitalWrite(_pin1, HIGH);
            digitalWrite(_pin2, LOW);
            digitalWrite(_pin3, LOW);
            digitalWrite(_pin4, HIGH);
            break;
        }
    }
    Вообще непонятно, зачем там все сделано через типы float, а не long. Это же сильно медленнее.
    Будем ковырять функцию управления дисплеем.
     
  8. vvr

    vvr Инженерище

    AccelStepper конечно не плохая библиотека по своим возможностям, но из-за большого количества вычислений тормознутая:)
     
  9. Onkel

    Onkel Гуру

    вы привели только часть кода, котарая лишь переключает пины (катушки шд), но при вызове ф. дисплея до этого свича НЕ ДОХОДИТ. Должен быть еще код, который эту функцию вызывает
    имхо проще переделать функцию шд