Состояние 3D принтера, как получить программно?

Андрей362
Идет загрузка
Загрузка
10.10.2017
864
6
Вопросы и ответы
Привет всем. Возникла проблема, необходимо контроkлировать текущее состояние 3д принтера, а именно: понять выполняет он сейчас перемещение по осям или находится в простое.

Например отправляю команду G0 X100 F50, то есть перемещаюсь по оси Х до координаты 100 мм с медленной скорость (50 мм/мин), необходимо привязать событие в ПО к моменту когда закончится перемещение в эту точку.

Есть ли какая-нибудь команда G-кода, возвращающая что-то типо состояние занят/свободен? или может кто-нибудь знает как по-другому программными средствами контроллировать?

Использую принтер с прошивкой Marlin.
Ответы на вопросы

Ответы

10.10.2017 в 15:50
0

ну так он пока едет другие команды не выполняет, приедет в точку начнет выполнять следующую команду, вот тут и будет ваш код. а еще он при простое шлет 'wait' на компорт. хотя вот про марлин не знаю. но репитер точно шлет.

10.10.2017 в 16:05
0

Все прошивки передают wait или что-то подобное при простое. Однако, работать с портом может одновременно только одна программа, если он уже занят сервером печати, то получить ответ от принтера может только он.

10.10.2017 в 16:30
0

Я просматриваю все сообщения, и wait отсутствует, возможно это включаемая настройка?

11.10.2017 в 01:29
0

А busy или ok шлёт? busy - ждёт команду. По умолчанию марлин что-то шлёт каждые 5 секунд простоя (и да, эту опцию можно отключить в конфигурации)

11.10.2017 в 05:50
0

надо копать начиная с этой функции в файле Marlin_main.cpp

#if ENABLED(HOST_KEEPALIVE_FEATURE)

  /**
   * Output a 'busy' message at regular intervals
   * while the machine is not accepting commands.
   */
  void host_keepalive() {
    const millis_t ms = millis();
    if (host_keepalive_interval && busy_state != NOT_BUSY) {
      if (PENDING(ms, next_busy_signal_ms)) return;
      switch (busy_state) {
        case IN_HANDLER:
        case IN_PROCESS:
          SERIAL_ECHO_START;
          SERIAL_ECHOLNPGM(MSG_BUSY_PROCESSING);
          break;
        case PAUSED_FOR_USER:
          SERIAL_ECHO_START;
          SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_USER);
          break;
        case PAUSED_FOR_INPUT:
          SERIAL_ECHO_START;
          SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_INPUT);
          break;
        default:
          break;
      }
    }
    next_busy_signal_ms = ms + host_keepalive_interval * 1000UL;
  }

#endif //HOST_KEEPALIVE_FEATURE

при этом статус 'занято' может принимать несколько значений

#if ENABLED(HOST_KEEPALIVE_FEATURE)
  enum MarlinBusyState {
    NOT_BUSY,           // Not in a handler
    IN_HANDLER,         // Processing a GCode
    IN_PROCESS,         // Known to be blocking command input (as in G29)
    PAUSED_FOR_USER,    // Blocking pending any input
    PAUSED_FOR_INPUT    // Blocking pending text input (concept)
  };
#endif

11.10.2017 в 13:05
0

В общем один из способов контроля состояния перемещения я нашёл исходя из команды M114, на возврат от которой получаем текущие координаты и координаты в которые перемещение происходит. Путём их сравнения можно понять достиг требуемой точки или нет (то есть происходит движение или находится в простое).

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

  public void GetDelayTest() //делает задержку потока пока принтер не вышел в заданную координату
        {
            string ReadedLine; //строка для чтения команд с порта
            char[] delimiterChars = {':', ' ', ':', ' ',':', ' ', ':', ' ', ':', ' ', ':', ' ', ':', ' ',}; //разделители строки, подробнее на MSDN в описании метода Split
           
            string[] words; //массив для полученных после операции Split

            bool ReadPosition=false;
            bool done=false;

            string CurrentX='';
            string NeedX='';

            string CurrentY='';
            string NeedY='';

            string CurrentZ='';
            string NeedZ='';

            SendingCommand = 'M114
';

            
            while (done==false)
            { 
            PositionerPort.Write(SendingCommand);

                    while (ReadPosition==false)
                    { 
                        ReadedLine =PositionerPort.ReadLine();
                        //Пример прочитанной строки :     X:50.00 Y:0.00 Z:0.00 E:0.00 Count X: 17.00 Y:0.00 Z:0.00 
                    
                        words = ReadedLine.Split(delimiterChars);
                        if (words[0]=='X'Шутливо //это проверка является ли прочитанная строкой подходящей нам
                        {
                            ReadPosition =true; //заканчиваем чтение строк
                            CurrentX=words[11]; //считывыем текущий Х
                            NeedX=words[1]; //считывыем необхдоимый Х

                            CurrentY=words[13];//считывыем текущий Y
                            NeedY=words[3]; //считывыем необхдоимый Х

                            CurrentZ=words[15]; //считывыем текущий Z
                            NeedZ=words[5]; //считывыем необхдоимый Х
                        } 
                        else
                        {
                        Thread.Sleep(100); //задержка 100 мс, чтобы слишком часто порт не опрашивало
                        }             
                    }
                    if (CurrentX==NeedX && CurrentY==NeedY && CurrentZ==NeedZ) //если текущая координата совпадает с ребуемой
                    {
                    done=true; //заканчиваем задержку
                    }
                    else
                    {
                    ReadPosition=false; //обратно начинаем читать строки 
                    }
               }
        }

Опробовал, всё работает нормально. Хотя вижу сразу недостаток в том, что если от принтера придёт другая команда, то она будет прочитана и проигнорирована, пока не придёт ответ именно от команды M114. Решается данный недостаток  более качественным парсингом приходящих команд.

Для написания комментариев, пожалуйста, авторизуйтесь.

Читайте в блогах

Накладка охлаждения

Рокстеди

Вешалок хватит всем

Добрый зубастый пес

Варварский самопал

Шлем Эхо, сериал "Бракованная партия"