crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в [РЕШЕНО] Работа таймеров в параллельном потоке
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
BRE Дата 30.11.2009, 18:43
 
Цитата(AD @ 30.11.2009, 18:38) *
Надо как-то по-другому выкручиваться.

Попробуй делать два таймера, по одном поворачивать, по другому читать.
И все будет Ok.
AD Дата 30.11.2009, 18:38
 
Цитата(Litkevich Yuriy @ 30.11.2009, 18:29) *
Для обсуждения идей создай отдельную тему. Проблема: "Работа таймера в параллельном потоке" решена?

Можно сказать, что да. Таймер, к сожалению, тут не подходит. Надо как-то по-другому выкручиваться. Можешь закрыть. А код выкладывал, для того, чтобы это не выглядело голословно, как раз таки!
Litkevich Yuriy Дата 30.11.2009, 18:29
 
Цитата(AD @ 30.11.2009, 21:24) *
Идея, а не код.
тогда зачем ты код выкладываешь?

Для обсуждения идей создай отдельную тему. Проблема: "Работа таймера в параллельном потоке" решена?
BRE Дата 30.11.2009, 18:29
  Что делает этот код?
for(int timer_count=0; QTime::currentTime()<=finished_time;)
    {
        if(_finished) break;
        timerTicks();
        if(timer_count == 60) timer_count = 0;
        if(!timer_count) emit working_light();
        ++timer_count;
    }



Может проще запустить еще один таймер, который раз в секунду будет дергать working_light и проверять, если все повернулось останавливать таймер или всю нить.
AD Дата 30.11.2009, 18:24
 
Цитата(Litkevich Yuriy @ 30.11.2009, 18:23) *
AD, ты уже в который раз спускаешся до подробностей прикладного кода, складывается такое впечатление, что ты хочешь чтобы за тебя программу написали.

Нет. Мне бы идею подсказать, как это сделать. Идея, а не код.
Litkevich Yuriy Дата 30.11.2009, 18:23
  AD, ты уже в который раз спускаешся до подробностей прикладного кода, складывается такое впечатление, что ты хочешь чтобы за тебя программу написали.
BRE Дата 30.11.2009, 18:19
  Или делать такой изврат:
void ContinueRotation::run()
{
    connect(imitTsl, SIGNAL(continue_stop()), SLOT(exit()));
    connect(this, SIGNAL(working_light()), SLOT(workSpotlight()));

    QTimer timerReading;
    connect(&timerReading,  SIGNAL(timeout()), this, SLOT(reading()));
    timerReading.start(1000);

   QEventLoop loop;

    for(int timer_count=0; QTime::currentTime()<=finished_time;)
    {
        loop.processEvent();

        if(_finished) break;
        timerTicks();
        if(timer_count == 60) timer_count = 0;
        if(!timer_count) emit working_light();
        ++timer_count;
    }

    emit work_ending();
    _is_time_read = false;
}


Но я бы рекомендовал решить или согналы и exec, или свой цикл без сигналов.
AD Дата 30.11.2009, 18:18
  Мда... Грустно, что нельзя это сделать. Задачка в следующем, которую никак не могу решить:
В этом потоке я отправляю на COM-порт команды, которые принимает прожектор. Ну команды расшифровываются так: повернуть на столько-то вверх, на столько-то вправо, на столько-то вниз, на столько-то влево. Одновременно мне нужно принимать от прожектора команды и анализировать. Ну что оно уже повернул на столько-то.

В своем цикле у меня делается следующее:
for(int timer_count=0; QTime::currentTime()<=finished_time;)
    {
        if(_finished) break;
        timerTicks();
        if(timer_count == 60) timer_count = 0;
        if(!timer_count) emit working_light();
        ++timer_count;
    }

Имеется счетчик времени. При определенном значении этого счетчика (раз в минуту) запускается функция выдачи команд, которая и занимается отправкой команд:
writing functions
/// Слот работы прожектора - вращения в обеих плоскостях
void ContinueRotation::workSpotlight()
{
    timerTicks();
    geted_angle_elev = -1, geted_azimuth = -1;

    /// Перемещение вниз и вправо до упора
    _angle_elevation = -110 * 10, _azimuth = 170 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    _is_time_read = true;
/// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ.
    timerTicks();

    /// Перемещение вверх и влево до упора
    _angle_elevation = 10 * 10;        _azimuth = -170 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    _is_time_read = true;
/// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ.
    timerTicks();

    /// Возврат в исходное положение
    _angle_elevation = 0;        _azimuth = 0;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(_angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(_angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(_azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(_azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    timerTicks();
}

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

Функции чтения выглядят так:
reading functions
/// Получение азимута
void ContinueRotation::readAzimuth(int& geted_azimuth, double limit)
{
    if(!imitTsl) return;
    QTime begining_time(QTime::currentTime());
    while(geted_azimuth < ((limit - 1.5) * 10) || geted_azimuth > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_azimuth = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim);
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 45) break;
        msleep(10);
    }
}

/// Получение угла места
void ContinueRotation::readAngleElevation(int& geted_angle_elev, double limit)
{
    if(!imitTsl) return;
    QTime begining_time(QTime::currentTime());
    while(geted_angle_elev < ((limit - 1.5) * 10) || geted_angle_elev > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_angle_elev = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev);
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 45) break;
        msleep(10);
    }
}

/// Слот чтения из COM-порта
void ContinueRotation::reading()
{
    if(!_is_time_read) return;

    readAngleElevation(geted_angle_elev, (double)_angle_elevation / 10.);
    readAzimuth(geted_azimuth, (double)_azimuth / 10.);
    _is_time_read = false;
}


Если у кого-то возникнут идеи, как это сделать, буду благодарен. Пока никаких других идей не возникает.... :(
BRE Дата 30.11.2009, 18:09
 
Цитата(AD @ 30.11.2009, 18:07) *
Ну... я уже ведь сказал, что запускается....

А я уже ответ написал. ;)
Смотри предыдущий ответ.

Цитата(AD @ 30.11.2009, 18:07) *
qDebug() выдает ошибку:
Цитата
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDebug' (or there is no acceptable conversion)


#include <QDebug>
AD Дата 30.11.2009, 18:07
  Ну... я уже ведь сказал, что запускается.... Проблема уже немного в другом: подружить мой цикл и вызов этого таймера... А вот как это сделать?
qDebug() выдает ошибку:
Цитата
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDebug' (or there is no acceptable conversion)

Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 28.3.2024, 13:08