2016-10-11 4 views
2

Я хочу попробовать значения, которые я получаю от GPIO 4000 раз в секунду, в настоящее время я делаю что-то вроде этого:точной выборки в C++

std::vector<int> sample_a_chunk(unsigned int rate, unsigned int block_size_in_seconds) { 
    std::vector<std::int> data; 
    constexpr unsigned int times = rate * block_size_in_seconds; 
    constexpr unsigned int delay = 1000000/rate; // microseconds 
    for (int j=0; j<times; j++) { 
     data.emplace_back(/* read the value from the gpio */); 
     std::this_thread::sleep_for(std::chrono::microseconds(delay)); 
    } 
    return data; 
} 

еще в соответствии с эталонным sleep_for гарантированно ждать по крайней мере, указанное количество времени.

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

+0

Вы должны использовать службы операционной системы, чтобы делать то, что вы спрашиваете. – user3344003

+0

Невозможно поспать «точное» количество времени. Это не то, как работают компьютеры. Даже RTOS не гарантирует точные сон. Почему бы вам не понять, насколько хороши то, что у вас уже есть, прежде чем тратить время, пытаясь сделать его «лучше», когда вы не знаете, насколько хорошо это хорошо. – xaxxon

+0

Операционная система shmoperating. Вы хотите точное время, вам нужна детерминированная система, и она записывает что-либо с потоками и прерываниями. Стремитесь к хорошему времени. Удостоверьтесь, что у вас есть разрешение по таймеру в 5-10 раз больше того, что вам нужно, и достаточно низкая латентность переключения контекста, чтобы вы никогда не спали достаточно, чтобы ухаживать. – user4581301

ответ

0

Я бы использовал boost::asio::deadline_timer.

#include <vector> 

#define BOOST_ERROR_CODE_HEADER_ONLY 1 
#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 

std::vector<int> sample_a_chunk(unsigned int rate, unsigned int block_size_in_seconds) { 
    std::vector<int> data; 
    const unsigned int times = rate * block_size_in_seconds; 
    auto expiration_time = boost::posix_time::microsec_clock::local_time(); 
    const auto delay = boost::posix_time::microseconds(1000000/rate); 
    boost::asio::io_service io; 
    boost::asio::deadline_timer t(io); 

    for (unsigned int j=0; j < times; j++) { 
    expiration_time += delay; 
    data.emplace_back(/* read the value from the gpio */); 
    t.expires_at(expiration_time); 
    t.wait(); 
    } 
    return data; 
} 
+0

Ссылка только ответы бесполезные ответы, как только ссылки гнить.'boost :: asio :: deadline_timer' ссылка в порядке, потому что любой может посмотреть это, но я рекомендую расширить ответ, чтобы суммировать содержимое учебников. – user4581301

+0

Спасибо @ user4581301. Я заменил ссылки на пример кода. –

3

Я думаю, что лучшее, что вы, вероятно, можно добиться того, чтобы использовать абсолютную времени, чтобы избежать дрейфа.

Что-то вроде этого:

std::vector<int> sample_a_chunk(unsigned int rate, 
    unsigned int block_size_in_seconds) 
{ 
    using clock = std::chrono::steady_clock; 

    std::vector<int> data; 

    const auto times = rate * block_size_in_seconds; 
    const auto delay = std::chrono::microseconds{1000000/rate}; 

    auto next_sample = clock::now() + delay; 

    for(int j = 0; j < times; j++) 
    { 
     data.emplace_back(/* read the value from the gpio */); 

     std::this_thread::sleep_until(next_sample); 

     next_sample += delay; // don't refer back to clock, stay absolute 
    } 
    return data; 
} 
+1

Вы избили меня на 4 мин, ответ был практически идентичен моему (+1). Nitpicks: Я бы использовал 'stable_clock' вместо' high_resolution_clock'. В gcc 'high_resolution_clock' находится' system_clock', который может быть скорректирован. Также я не думаю, что 'sleep_until' может вернуться раньше, поэтому я не беспокоился о цикле, чтобы проверить это. Но большой элемент изображения - использовать 'sleep_until' для устранения дрейфа, на который вы попали! :-) –

+0

@HowardHinnant Я начал с stable_clock, потому что он достаточно быстро работал в моей системе, но потом я увидел * микросекунды * и задавался вопросом, могут ли отличаться часы с маленькими устройствами ...? поэтому я пошел с * high_resolution *. Я добавлю примечание. – Galik

+0

Нет, я изменил его на * устойчивый * в конце концов. Его точное время, которое требуется. – Galik

Смежные вопросы