Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Periodický interval timeru

Aktivity
Avatar
Caster
Člen
Avatar
Caster:6.11.2021 12:09

Ke svému notebooku chci přes Seeeduino XIAO připojit µ-Ampérmetr a zobrazovat na něm aktuální výkon CPU na notebooku v %. Pokouším se vytvořit program v C++, který bude každých 100 ms zjišťovat aktuální výkon CPU a pomocí jednoho bytu pošle přes USB data na Seeduino XIAO, kde se hodnota předá DAC převodníku, na jehož výstupu se objeví napětí v rozsahu 0 až 3,3V (0% až 100% CPU). Na výstup DAC připojím přes odpovídající rezistor klasický analogový µ-Ampérmetr, který bude ukazovat výkon CPU na notebooku.

Seeeduino XIOA a µ-Ampérmetru je napájen přes USB z notebooku.

Program na měření výkonu CPU mám funkční, nyní zkouším jak naprogramovat jeho periodické měření.

Inspiroval jsem se zde, kde mi první verze kódu funguje, ale druhá hlásí chyby:

1>------ Sestavování zahájeno: Projekt: Timer interval, Konfigurace: Release x64 ------
1>Timer interval.cpp
1>c:\users\pe­tr\source\repos\ti­mer interval\timer interval\timer interval.cpp(26): error C2955: std::lock_guard: Použití třída šablona vyžaduje seznam argumentů šablona.
1>c:\program files (x86)\microsoft visual studio\2017\com­munity\vc\tool­s\msvc\14.16.27023\in­clude\mutex(510): note: viz deklarace: std::lock_guard
1>c:\users\pe­tr\source\repos\ti­mer interval\timer interval\timer interval.cpp(26): error C2514: std::lock_guard: Třída nemá žádné konstruktory.
1>c:\program files (x86)\microsoft visual studio\2017\com­munity\vc\tool­s\msvc\14.16.27023\in­clude\mutex(510): note: viz deklarace: std::lock_guard
1>c:\users\pe­tr\source\repos\ti­mer interval\timer interval\timer interval.cpp(50): error C2514: std::unique_lock: Třída nemá žádné konstruktory.
1>c:\program files (x86)\microsoft visual studio\2017\com­munity\vc\tool­s\msvc\14.16.27023\in­clude\mutex(137): note: viz deklarace: std::unique_lock
1>c:\users\pe­tr\source\repos\ti­mer interval\timer interval\timer interval.cpp(51): error C2664: std::cv_status std::condition_va­riable::wait_un­til(std::uniqu­e_lock<std::mu­tex> &,const xtime *): Nejde převést argument 1 z: std::unique_lock na: std::unique_loc­k<std::mutex> &.
1>Sestavení projektu Timer interval.vcxproj bylo dokončeno: CHYBA.
========== Sestavení: 0 úspěšně, 1 se nezdařilo, 0 aktuální, 0 přeskočeno ==========

Zkusil jsem:

#include <chrono>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>

class call_every
{
        std::mutex mut_;
        std::condition_variable cv_;
        std::function<void()> f_;
        std::chrono::system_clock::duration d_;
        std::chrono::system_clock::time_point run_now_;
        bool quit_;
        std::thread thr_;

public:
        ~call_every()
        {
                {
                        std::lock_guard lock{ mut_ };
                        quit_ = true;
                }
                cv_.notify_one();
                thr_.join();
        }

        template <class F>
        explicit call_every(F f, std::chrono::system_clock::duration d)
                : f_{ std::move(f) }
                , d_{ d }
                , run_now_{ std::chrono::system_clock::now() }
                , quit_{ false }
                , thr_{ &call_every::run, this }
        {
        }

private:
        void run()
        {
                while (true)
                {
                        f_();
                        run_now_ += d_;
                        std::unique_lock lock{ mut_ };
                        if (cv_.wait_until(lock, run_now_, [this]() {return quit_; }))
                                break;
                }
        }
};

#include <iostream>

int
main()
{
        using namespace std;
        using namespace std::chrono;
        call_every x{ [] {cout << "Hi" << endl; }, 5s };
        this_thread::sleep_for(15s);
}

Chci docílit: Periodicky volat funkci

 
Odpovědět
6.11.2021 12:09
Avatar
Caster
Člen
Avatar
Caster:6.11.2021 13:42

Našel jsem jednoduché řešení a přidal měření výkonu CPU ;-) .

// https://stackoverflow.com/questions/23143693/retrieving-cpu-load-percent-total-in-windows-with-c

#include <iostream>
#include <Windows.h>
#include <thread>
#include <chrono>

static float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)
{
        static unsigned long long _previousTotalTicks = 0;
        static unsigned long long _previousIdleTicks = 0;

        unsigned long long totalTicksSinceLastTime = totalTicks - _previousTotalTicks;
        unsigned long long idleTicksSinceLastTime = idleTicks - _previousIdleTicks;

        float ret = 1.0f - ((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime) / totalTicksSinceLastTime : 0);

        _previousTotalTicks = totalTicks;
        _previousIdleTicks = idleTicks;
        return ret;
}

static unsigned long long FileTimeToInt64(const FILETIME & ft) { return (((unsigned long long)(ft.dwHighDateTime)) << 32) | ((unsigned long long)ft.dwLowDateTime); }

// Returns 1.0f for "CPU fully pinned", 0.0f for "CPU idle", or somewhere in between
// You'll need to call this at regular intervals, since it measures the load between
// the previous call and the current one.  Returns -1.0 on error.
float GetCPULoad()
{
        FILETIME idleTime, kernelTime, userTime;
        return GetSystemTimes(&idleTime, &kernelTime, &userTime) ? CalculateCPULoad(FileTimeToInt64(idleTime), FileTimeToInt64(kernelTime) + FileTimeToInt64(userTime)) : -1.0f;
}


int main()
{
        for (;;) {
        printf("CPU use = %0.2f%%\n", GetCPULoad() * 100);
        using namespace std::chrono_literals;
        std::this_thread::sleep_for(1000ms);
        }
}
Editováno 6.11.2021 13:43
 
Nahoru Odpovědět
6.11.2021 13:42
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.