Raspberry pi,C++ 计时函数,对值的操作?

Raspberry pi, C++ chrono function, operations on values?

我开始使用 C++ 和 "chrono" 函数,我想用它来获取电机的速度。

为此,我有一个连接到电机的编码轮,一个光耦合器用于收集编码轮产生的方波信号。

因此,我的 raspberry pi 收到一个方波信号,其速度取决于电机速度。

我使用 chrono 函数尝试计算方波信号频率的持续时间。 我实现了每个信号的持续时间(几乎)为 7 毫秒。 我想通过公式 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的"value"存储在"object"... 我怎样才能简单地将它从那里取出并放入一个标准变量中,这样我就可以用它进行除法、乘法和做任何我想做的事情?

这是 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.

我会让 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 1s 除以 result 得到频率:

using namespace std::chrono_literals;

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

Howard Hinnant 指出,从 C++14 开始,您可以通过将股息从基于整数的持续时间 1s 更改为基于双精度的持续时间 1.0s,并使用 auto:

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

Demo