Непрерывный мониторинг данных с использованием BackgroundWorker (c #) - PullRequest
0 голосов
/ 09 февраля 2012

Мне нужно контролировать положение вращающегося энкодера для управления двигателем постоянного тока.Чтобы не пропустить изменения в Rotary Encoder, я использовал BackgroundWorker.

Мое приложение работает не так, как ожидалось, поэтому я отлаживаю, чтобы понять, почему оно часто пропускает отметку.

Используя Console.WriteLine, я записываю состояние секундомера иЯ заметил, что поток «пропускает» или пропускает циклы, это может быть причудой записи в консоль?

Вот небольшой раздел вывода, как вы можете видеть, что разрыв составляет 190 мс:

Inside Thread. Time: 25, Position: 117, Velocity: 0
Inside Thread. Time: 26, Position: 117, Velocity: 0
Inside Thread. Time: 27, Position: 117, Velocity: 0
Inside Thread. Time: 28, Position: 117, Velocity: 0
Inside Thread. Time: 29, Position: 117, Velocity: 0
Inside Thread. Time: 30, Position: 117, Velocity: 0
Inside Thread. Time: 212, Position: 117, Velocity: 0
Inside Thread. Time: 213, Position: 117, Velocity: 0
Inside Thread. Time: 214, Position: 117, Velocity: 0
Inside Thread. Time: 215, Position: 117, Velocity: 0
Inside Thread. Time: 216, Position: 117, Velocity: 0
Inside Thread. Time: 217, Position: 117, Velocity: 0

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

    public void dcMotorMove(DCMotorSettings dcMotorSettings)
    {
        try
        {
            dcMotorSettings.Moving = true;

            Stopwatch dcMotorStopwatch = Stopwatch.StartNew();
            dcMotorStopwatch.Restart();

            int MoveState = 1;

            while (MoveState != 0)
            {
                Console.WriteLine("Inside Thread. Time: " + dcMotorStopwatch.ElapsedMilliseconds + ", Position: " + dcMotorControl.encoders[0].Position + ", Velocity: " + dcMotorControl.motors[0].Velocity);

                Thread.Sleep(dcMotorSettings.SampleRate); // Processor Rest
                if (dcMotorStopwatch.ElapsedMilliseconds > dcMotorSettings.Duration)  MoveState = 0;

            }

            dcMotorSettings.Moving = false;
        }
        catch
        {
            Console.WriteLine("Problem within dcMotorMove");
        }
    }

Ответы [ 3 ]

2 голосов
/ 09 февраля 2012

Очень маловероятно, что это проблема класса Console.

Единственная причина, по которой я могу это понять, заключается в том, что свойства, которые вы выводите на консоль (Position, Velocity), могут занять некоторое время для оценки, возможно, из-за ограничений используемого вами соединения.

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

2 голосов
/ 09 февраля 2012

Я не думаю, что здесь есть ошибка.Не существует способа организовать точное выполнение кода на виртуальной платформе (.NET), а не на ОС реального времени.Сам секундомер дает только возможность измерять временные интервалы.Ваш конкретный случай зависит от миллиона факторов (таких как текущие процессы, запущенные в системе, объем памяти и т. Д.)

1 голос
/ 09 февраля 2012

Это не причуда консоли. Попробуйте также распечатать dcMotorSettings.SampleRate.

Редактировать: Попробуйте изменить внутренний цикл на:

            Console.WriteLine("Inside Thread. Time: " + dcMotorStopwatch.ElapsedMilliseconds);
            Thread.Sleep(1);

Если эффект все еще возникает, это проблема операционной системы (или слишком большая нагрузка на систему). Если эффекта не происходит, вы комментируете код, пока не произойдет снова.

...