簡體   English   中英

Raspberry pi,C++ chrono 函數,對值的操作?

[英]Raspberry pi, C++ chrono function, operations on values?

我開始使用 C++ 和“chrono”函數,我想用它來獲得電機的速度。

為此,我有一個與電機相連的編碼輪,一個光耦合器用於收集編碼輪產生的方波信號。

因此,我的樹莓派收到一個方波信號,其速度取決於電機速度。

我使用 chrono 函數來嘗試計算方波信號頻率的持續時間。 我實現了每個信號的持續時間(幾乎)為 7ms。 我想簡單地通過公式 1/F 提取頻率(因此,1/0.007 = 142.85)。

我已經吃了一個星期的chrono功能的文檔,我仍然完全不明白......

顯然,所有答案都在這里,但我不明白,我仍然是 C++ 的初學者:( https://en.cppreference.com/w/cpp/chrono

這非常有用,但有限: https : //www.code57.com/cplusplus-programming-beginners-tutorial-utilities-chrono/

如果我理解正確,7ms 的“值”存儲在一個“對象”中......我怎么能簡單地把它從那里取出並放在一個標准變量中,這樣我就可以用它來除法、乘法和做任何我想做的事情?

這是 C++ 代碼的有趣部分:

#include <iostream>
#include <wiringPi.h>
#include <cstdio>
#include <csignal>
#include <ctime>
#include <chrono>

// global flag used to exit from the main loop
bool RUNNING = true;
bool StartTimer = false;
//int timer = 0;
std::chrono::steady_clock::time_point BeginMeasurement; //chrono variable representing the beginning of the measurement of a motor speed


//some more code in here, but nothing exceptionnal, just calling the interruption when needed


//interruption function for counting the motor speed
void RPMCounter(){
    using namespace std;
    using namespace std::chrono;

    if (StartTimer == true){
    StartTimer = false;
    steady_clock::duration result = steady_clock::now()-BeginMeasurement;
    if (duration_cast<milliseconds>(result).count() < 150){
        double freq;
        //cout.precision(4);
        std::cout << "Time = " << duration_cast<milliseconds>(result).count() << " ms" << '\n';
// I would like the next line to work and give me the frequency of the detection...
        freq = 1/(duration_cast<milliseconds>(result).count()/1000);
        std::cout << "Frequency = " << freq << " Hz" << '\n';
    }
    }
    else{
    BeginMeasurement = steady_clock::now();
    StartTimer = true;
    }
}

這是我的命令提示符中的結果:

在此處輸入圖片說明

7ms 的值增加是因為我停止了電機,因此,它在停止之前轉得更慢;)

編輯 :

感謝 Howard Hinnant 和 Ted Lyngmo,我的代碼現在看起來像這樣:

void RPMCounter(){
    using namespace std;
    using namespace std::chrono;

    if (StartTimer == true){
    StartTimer = false;
    duration<double> result = steady_clock::now() - BeginMeasurement;
    if (result < milliseconds{150}){
        double freq;//= 1s / result;
        //cout.precision(4);
        std::cout << "Time = " << duration_cast<milliseconds>(result).count() << " ms" << '\n';
        freq = (1.0/(duration<double>{result}.count()/1000))/1000;
        std::cout << "Frequency = " << freq << " Hz" << '\n';
    }
    }
    else{
    BeginMeasurement = steady_clock::now();
    StartTimer = true;
    }
}

它似乎給了我一個正確的頻率。 由於我是初學者,我肯定會在一段時間內更好地理解並改進它:)(基本上,我不太確定我寫的意思......就像“::”和其他方式:) 我其余的編碼應該更基礎,讓我可以學習 C++ 的所有調整

if (duration_cast<milliseconds>(result).count() < 150){

您可以通過以下方式簡化此操作:

if (result < 150ms)

或者,如果您使用的是 C++11:

if (result < milliseconds{150})

優點是您不必將結果截斷到更精確的程度,並且代碼更易於閱讀。

freq = 1/(duration_cast<milliseconds>(result).count()/1000);

反而:

using dsec = duration<double>;  // define a double-based second
auto freq = 1/dsec{result}.count();

這也可以寫成:

auto freq = 1/duration<double>{result}.count();

無論如何,這會將result直接轉換為基於雙精度的秒數,並使用浮點運算反轉該值。 原始代碼使用整數除法導致整數結果始終向下舍入為 0。即1/10 == 0 ,而1/10. == 0.1 1/10. == 0.1

我會讓result基於double的持續時間:

auto BeginMeasurement = std::chrono::steady_clock::now(); 

// some work

// a double based duration
std::chrono::duration<double> result = std::chrono::steady_clock::now() - BeginMeasurement;

然后,您可以將duration 1sresult相除以獲得頻率:

using namespace std::chrono_literals;

double freq = 1s / result;
std::cout << freq << " Hz\n";

Howard Hinnant指出,從 C++14 開始,您可以通過將基於整數的持續時間1s的紅利更改為基於雙1.0s的持續時間1.0s ,並使用auto推導出result ,從而使您自己更容易:

auto result = std::chrono::steady_clock::now() - BeginMeasurement;
double freq = 1.0s / result;

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM