code works fine when .tv_usec is replaced with .tv_sec
need more accuracy seconds to at lest to decimal points
wording if this my be an issue with the pis clock
code eventually to be used to calculate bpm but currently used to calculate time between clicks
gboolean tapTemp(GtkButton *button, gpointer user_data)
{
//errorMsg = bmp;
if(tapdown)
{
tapdown = false;
clock_gettime(CLOCK_REALTIME, &beetTime);
time_difference = beetTime.tv_nsec;// - start_time;
bpm = time_difference - start_time; //time_difference;
errorMsg = bpm;
}
else
{
tapdown = true;
clock_gettime(CLOCK_REALTIME, &beetTime);
start_time = beetTime.tv_nsec;
errorMsg2 = start_time;
}
}
tv_nsec will wrap back to zero every second - to make a continually incrementing time combine with tv_sec, e.g. thistime = beetTime.tv_secs+0.001*(beetTime.tv_nsec/1000000) to get the nearest millisecond.
Related
So I'm trying to create an energy meter device which will read power every minute and then send it every 5 minutes through a LoRa server, using an MKR 1300 arduino. The problem is that as of now the hardware is removing a few milliseconds on the delay and so the time in the server ends up being p.e:
10:50:30
10:50:30
10:50:30
... 2 hours later
10:50:29
10:50:29
...
10:49:59
The code looks like this:
#include <MKRWAN.h>
#include "EmonLib.h"
LoRaModem modem;
String appEui = "1234567891011121";
String appKey = "ffffffffffffffffffffffffffffffff";
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
double totalWatt;
int time_running;
int sending;
int totalKW;
int DELAY = 60000; // millis
void setup() {
Serial.begin(115200);
if (!modem.begin(EU868)) {
Serial.println("Failed to start module");
while (1) {}
};
Serial.print("Your module version is: ");
Serial.println(modem.version());
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
Serial.println("Connecting");
int connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Serial.println("Something went wrong; are you indoor? Move near a window and retry");
while (1) {}
}
Serial.println("Connected");
modem.minPollInterval(60);
analogReadResolution(9);
emon1.current(1, 53);
emon2.current(2, 53);
emon3.current(3, 53);
time_running = 0;
randomSeed(analogRead(A4));
}
void loop() {
unsigned long StartTime = millis();
totalWatt = 0;
unsigned long delay_send = 0;
int sending = 0;
double Irms1 = emon1.calcIrms(600);
if (Irms1 < 0.3) Irms1 = 0;
double Watt1 = Irms1 * 230;
double Irms2 = emon2.calcIrms(600);
if (Irms2 < 0.3) Irms2 = 0;
double Watt2 = Irms2 * 230;
double Irms3 = emon3.calcIrms(600);
if (Irms3 < 0.3) Irms3 = 0;
double Watt3 = Irms3 * 230;
totalWatt = Watt1 + Watt2 + Watt3;
totalKW = totalKW + totalWatt/1000;
if (time_running == 5) { //15 para 15 mins
double IrmsTotal = Irms1 +Irms2 + Irms3;
String msg = "{\"id\":\"avac_aud1\",\"kW\":"+String(totalKW)+", \"current\":"+String(IrmsTotal)+"}";
int err;
modem.beginPacket();
modem.print(msg);
err = modem.endPacket(true);
if (err > 0) {
//message sent correctly
time_running = 0;
totalKW = 0;
} else {
Serial.println("ERR");
time_running = 0;
}
}
time_running = time_running + 1;
if ((millis() - StartTime) > DELAY){
delay(10);
return;
} else{
delay(DELAY-(millis() - StartTime));
return;
}
}
I tried adding a variable ARD_DELAY (not shown above) to the code that in that last delay would subtract 7 to 8 milliseconds to try and fix this, but apparently, it only made it worse (now it removes 1 second every 1 hours instead of 2 hours) so today I'll try to add those 7 to 8 millis and see if it works, but I would really like to know why the heck this is happening because from what I can see from my code the delay should always account for the processed time including the data sending time.
Question is, how precise is your clock at all...
Still, I personally would rather go with the following approach:
#define DELAY (5UL * 60UL * 1000UL) // or whatever is appropriate...
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-5-min task...
}
Edit: combined 1-min and 5-min task:
Variant 1:
#define DELAY_SHORT (1UL * 60UL * 1000UL)
#define DELAY_LONG (5UL * 60UL * 1000UL)
static unsigned long timestampS = millis();
static unsigned long timestampL = timestampS;
if(millis() - timestampS > DELAY_SHORT)
{
timestamp += DELAY_SHORT;
// run the every-1-min task...
}
if(millis() - timestampL > DELAY_LONG)
{
timestamp += DELAY_LONG;
// run the every-5-min task...
}
Variant 2:
#define DELAY_1M (1UL * 60UL * 1000UL)
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-1-min task...
static unsigned int counter = 0;
if(++counter == 5)
{
counter = 0;
// run the every-5-min task...
}
}
Instead of trying to measure a start time and adding delay depending on that, you could keep track of the timing for your next cycle.
unsigned long next_cycle = DELAY;
...
void loop() {
...
delay( next_cycle - millis() );
next_cycle += DELAY;
}
If you also want to adjust for any time the program spends on initialization or similar, you can next_cycle = millis() + DELAY; before you enter your loop.
What would be the best way to add a chronometer because this type of chronometer that I invented makes my game snake advance in 1 second and its really slow
void timer()
{
int g = 1;
int h = 0;
while (g != 0)
{
Sleep(1000);
h = h + 1;
gotoxy(50, 1); printf("Tiempo: %d",h);
}
}
Some pseudo-code to give you an idea of how it could be done:
time_type last_time = now(); // Initialize to the current time
// Main game loop
forever
{
// Do other game-related things...
// Now handle things that should be done on regular intervals
time_type current_time = now();
time_diff_type difference = current_time - last_time;
if (difference > 2 second)
{
// Do things that should be done every two seconds
}
if (difference > 1 second)
{
// Do things that should be done every second
}
last_time = current_time;
}
For the time_type and now functions, use the functionality in std::chrono.
For example, to get the current time do e.g.
auto current_time = std::chrono::system_clock::now();
And with a newer compiler and a using namespace std::literals::chrono_literals; you could actually use e.g. 1s as a second:
auto difference = current_time - last_time;
if (difference > 1s) { /* Code here... */ }
The above is valid C++ code.
I do not know how to make stable timer.
Timer did should work every 4ms.
I did use normal event timer in "WndProc()", "CreateTimerQueueTimer()",own timer using "std::chrono::high_resolution_clock" and all timers are unstable. Of course I use one. Sometimes they are calculated at the appointed time or sometimes they are too slow what make my program not smooth. Operations are not complicated is add some integers.
CreateTimerQueueTimer()
if (!CreateTimerQueueTimer(&hLogicTimer, hTimerQ, (WAITORTIMERCALLBACK)Window::LogicThread, NULL, 0, 4, NULL)) return -1;
Window::LogicThread() function.
void Window::LogicThread()
{
Window::StartRender = false;
SC->CalculateActors();
Window::StartRender = true;
}
Own function timer called by new thread.
bool Window::LogicThread()
{
typedef std::chrono::high_resolution_clock Time;
auto start = Time::now();
const auto constWait = 4000000;
while (!Window::TerminaterThread)
{
std::this_thread::sleep_for(std::chrono::nanoseconds(constWait - std::chrono::duration_cast<std::chrono::nanoseconds>(Time::now() - start).count()));
start = Time::now(); //calculate operation time and sleep thread
Window::StartRender = false;
SC->CalculateActors();
Window::StartRender = true;
}
return true;
}
I'm trying to use the given code within steptimer.h to set up code that will run every two seconds. However with the code below, timer.GetTotalSeconds() always returns 0.
Unfortunately there isn't much information readily available on StepTimer.h (at least I believe due to a lack of useful search results), so I was hoping someone might be able to shed some light as to why the timer isn't recording the elapsed seconds. Am I using it incorrectly?
Code from Game.h, Game.cpp and StepTimer.h are included below. Any help is greatly appreciated.
From Game.cpp:
double time = timer.GetTotalSeconds();
if (time >= 2) {
laser_power++;
timer.ResetElapsedTime();
}
Initialised in Game.h:
DX::StepTimer timer;
From Common/StepTimer.h:
#pragma once
#include <wrl.h>
namespace DX
{
// Helper class for animation and simulation timing.
class StepTimer
{
public:
StepTimer() :
m_elapsedTicks(0),
m_totalTicks(0),
m_leftOverTicks(0),
m_frameCount(0),
m_framesPerSecond(0),
m_framesThisSecond(0),
m_qpcSecondCounter(0),
m_isFixedTimeStep(false),
m_targetElapsedTicks(TicksPerSecond / 60)
{
if (!QueryPerformanceFrequency(&m_qpcFrequency))
{
throw ref new Platform::FailureException();
}
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw ref new Platform::FailureException();
}
// Initialize max delta to 1/10 of a second.
m_qpcMaxDelta = m_qpcFrequency.QuadPart / 10;
}
// Get elapsed time since the previous Update call.
uint64 GetElapsedTicks() const { return m_elapsedTicks; }
double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); }
// Get total time since the start of the program.
uint64 GetTotalTicks() const { return m_totalTicks; }
double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); }
// Get total number of updates since start of the program.
uint32 GetFrameCount() const { return m_frameCount; }
// Get the current framerate.
uint32 GetFramesPerSecond() const { return m_framesPerSecond; }
// Set whether to use fixed or variable timestep mode.
void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; }
// Set how often to call Update when in fixed timestep mode.
void SetTargetElapsedTicks(uint64 targetElapsed) { m_targetElapsedTicks = targetElapsed; }
void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
// Integer format represents time using 10,000,000 ticks per second.
static const uint64 TicksPerSecond = 10000000;
static double TicksToSeconds(uint64 ticks) { return static_cast<double>(ticks) / TicksPerSecond; }
static uint64 SecondsToTicks(double seconds) { return static_cast<uint64>(seconds * TicksPerSecond); }
// After an intentional timing discontinuity (for instance a blocking IO operation)
// call this to avoid having the fixed timestep logic attempt a set of catch-up
// Update calls.
void ResetElapsedTime()
{
if (!QueryPerformanceCounter(&m_qpcLastTime))
{
throw ref new Platform::FailureException();
}
m_leftOverTicks = 0;
m_framesPerSecond = 0;
m_framesThisSecond = 0;
m_qpcSecondCounter = 0;
}
// Update timer state, calling the specified Update function the appropriate number of times.
template<typename TUpdate>
void Tick(const TUpdate& update)
{
// Query the current time.
LARGE_INTEGER currentTime;
if (!QueryPerformanceCounter(¤tTime))
{
throw ref new Platform::FailureException();
}
uint64 timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart;
m_qpcLastTime = currentTime;
m_qpcSecondCounter += timeDelta;
// Clamp excessively large time deltas (e.g. after paused in the debugger).
if (timeDelta > m_qpcMaxDelta)
{
timeDelta = m_qpcMaxDelta;
}
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
timeDelta *= TicksPerSecond;
timeDelta /= m_qpcFrequency.QuadPart;
uint32 lastFrameCount = m_frameCount;
if (m_isFixedTimeStep)
{
// Fixed timestep update logic
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
// from accumulating over time. Without this clamping, a game that requested a 60 fps
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
// accumulate enough tiny errors that it would drop a frame. It is better to just round
// small deviations down to zero to leave things running smoothly.
if (abs(static_cast<int64>(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000)
{
timeDelta = m_targetElapsedTicks;
}
m_leftOverTicks += timeDelta;
while (m_leftOverTicks >= m_targetElapsedTicks)
{
m_elapsedTicks = m_targetElapsedTicks;
m_totalTicks += m_targetElapsedTicks;
m_leftOverTicks -= m_targetElapsedTicks;
m_frameCount++;
update();
}
}
else
{
// Variable timestep update logic.
m_elapsedTicks = timeDelta;
m_totalTicks += timeDelta;
m_leftOverTicks = 0;
m_frameCount++;
update();
}
// Track the current framerate.
if (m_frameCount != lastFrameCount)
{
m_framesThisSecond++;
}
if (m_qpcSecondCounter >= static_cast<uint64>(m_qpcFrequency.QuadPart))
{
m_framesPerSecond = m_framesThisSecond;
m_framesThisSecond = 0;
m_qpcSecondCounter %= m_qpcFrequency.QuadPart;
}
}
private:
// Source timing data uses QPC units.
LARGE_INTEGER m_qpcFrequency;
LARGE_INTEGER m_qpcLastTime;
uint64 m_qpcMaxDelta;
// Derived timing data uses a canonical tick format.
uint64 m_elapsedTicks;
uint64 m_totalTicks;
uint64 m_leftOverTicks;
// Members for tracking the framerate.
uint32 m_frameCount;
uint32 m_framesPerSecond;
uint32 m_framesThisSecond;
uint64 m_qpcSecondCounter;
// Members for configuring fixed timestep mode.
bool m_isFixedTimeStep;
uint64 m_targetElapsedTicks;
};
}
Alrighty got what I wanted with the code below. Was missing the .Tick(####) call.
timer.Tick([&]() {
double time = timer.GetTotalSeconds();
if (time >= checkpt) {
laser_power++;
checkpt += 2;
}
});
Just fixed an integer checkpt to increment by 2 each time so that it runs every 2 seconds. There's probably a better way to do it, but it's 3.30am so I'm being lazy for the sake of putting my mind at ease.
I am designing a time class that will only perform an action after a predefined time but I still cannot figure out the way to reset the time. Is that anyway to reset the time back to zero or temporarily stop and resume the time?
so, my goal is to reset the time each time the condtion A meets so that it won't screw up delayTime function that it still keep the previous time and end up wrong time calculation.
if ( condition A )
{
if ( time.delayTime( 5.0f ) )
{
doActionA();
}
}
TimeClass.h
#ifndef _TIMECLASS_H_
#define _TIMECLASS_H_
#include <windows.h>
class TimeClass
{
public:
TimeClass();
~TimeClass();
bool delayTime( float second );
float getSecond();
void reset();
private:
float getGameTime();
float currentTime;
UINT64 ticks;
float time;
float timeAtGameStart;
UINT64 ticksPerSecond;
};
#endif
TimeClass.cpp
#include "TimeClass.h"
TimeClass::TimeClass()
{
// We need to know how often the clock is updated
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticksPerSecond) )
ticksPerSecond = 1000;
// If timeAtGameStart is 0 then we get the time since
// the start of the computer when we call GetGameTime()
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
float TimeClass::getGameTime()
{
// This is the number of clock ticks since start
if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) )
ticks = (UINT64)timeGetTime();
// Divide by frequency to get the time in seconds
time = (float)(__int64)ticks/(float)(__int64)ticksPerSecond;
// Subtract the time at game start to get
// the time since the game started
time -= timeAtGameStart;
return time;
}
bool TimeClass::delayTime( float second )
{
currentTime = getGameTime();
static float totalTime = second + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = second + getGameTime();
return true;
}
else
{
return false;
}
}
float TimeClass::getSecond()
{
currentTime = getGameTime();
static float totalTime = 1 + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = 1 + getGameTime();
return currentTime;
}
else
{
return currentTime;
}
}
void TimeClass::reset()
{
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
TimeClass::~TimeClass()
{
}
Standard Library
As already stated simply use the std::chrono::high_resolution_clock. If you use the Visual C++ Compiler there is an actual bug report on the resolution of the high_resolution_clock and it's NOT the same as the QueryPerformanceCounter.
Example
auto t1 = std::chrono::high_resolution_clock::now();
// Do something
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
double dt = duration.count();
TimeClass
The main problem you're facing right now is that you are using static variables. You are looking for a way to reset the static variable from another function than the delayTime. If you would introduce member variables to get rid of the static variables it would make things a lot easier (Note: static variables within functions are bad practice as they are holding the state => bad for multi-threading). Well what about something like this:
class Event {
std::chrono::high_resolution_clock::time_point lastEventOccurred;
double timeBetweenEvents;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastEventOccurred(std::chrono::high_resolution_clock::now()) { }
bool ready() {
auto currentTime = std::chrono::high_resolution_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastEventOccurred).count();
if(elapsedTime > timeBetweenEvents) {
reset();
return true;
} else
return false;
}
void reset() {
lastEventOccurred = std::chrono::high_resolution_clock::now();
}
};
Usage:
Event evtDelay = Event(5.0);
if(condition A) {
if(evtDelay.ready()) {
doActionA();
}
} else if(condition B) {
evtDelay.reset();
}
Another approach would be to use a capturing state and an update method. As I can see you are using this for a game so the updating could be done in the update method of your game. Assuming the event would have a state like {Active, Inactive} and a member for the elapsed time, every time you call update you add the elapsed time since the last update call if the state is Active. Therefore the ready function would only check if the elapsed time is greater than the defined threshold.
class Event {
std::chrono::high_resolution_clock::time_point lastUpdateCall;
double timeBetweenEvents;
double elapsedTime;
bool active;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastUpdateCall(std::chrono::high_resolution_clock::now())
, elapsedTime(0.0)
, active(true) { }
bool ready() {
return elapsedTime >= timeBetweenEvents;
}
void reset() {
elapsedTime = 0.0;
}
void setActive(bool state) {
active = state;
}
void update() {
auto currentTime = std::chrono::high_resolution_clock::now();
if(active) {
auto dt = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastUpdateCall).count();
elapsedTime += dt;
}
lastUpdateCall = currentTime;
}
};
From your questions it is not quite clear what exactly you want to achieve: clock resetting, pausing/resuming, interval measuring, or timed triggers, or all of this. So I will just describe all of this. =)
Just to make it clear
do not use static variables in member functions (methods), it makes your code harder to understand and error-prone. Instead use class member variables (fields)
do not store time in (milli)seconds float format. I has too low precision. Even double is not recommended. Instead, store it in API-native format: some kind of CPU ticks: let's wrap it in struct time_point and convert to float only when user asks for it:
struct time_point
{
LARGE_INTEGER value;
};
The functions you'll need from your underlying API are:
function to get current time: let's call it
private:
time_point now(); // Here you wrap QueryPerformanceCounter() or `boost::chrono::...::now();` stuff
functions to reinterpret difference (time duration) between two time_point to usable units (such as nanoseconds long long of (milli)seconds float)
private:
float Duration(const time_point& from, const time_point& to); // Here you divide by frequence
(also, you can make time_point class and make this functions members)
All other functions can be API-agnostic.
Following this design, you can abstract out underlying API from user and make your app more portable.
Resetting
Is that anyway to reset the time back to zero
But, wait, you've already implemented "reset the time back to zero":
void TimeClass::reset()
{
//timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
(timeAtGameStart = 0; commented as it non needed)
You just saying that start is now(), so difference between start and now() becomes zero.
Stopping and resuming
or temporarily stop and resume the time?
you can achieve "time stop/resume" effect by:
adding bool isPaused member varible (don't forget to init it to false in constructor)
adding timePaused member varible (of type of your time units: time_point in my case)
altering your getGameTime() function: when paused it will return timePaused instead of current time
and of course, introducing Pause()/Resume() functions
Here is example code (naming is a little different to yours)
void Pause()
{
if (!isPaused)
{
timePaused = clock::now();
isPaused = true;
}
}
void Resume()
{
if (isPaused)
{
isPaused = false;
start -= clock::now() - timePaused;
}
}
float Now() const
{
if (isPaused)
{
return Duration(start, timePaused);
}
return Duration(start, clock::now()); // basically it is your getGameTime()
}
Delta (basic interval measuring)
Sometimes you will want to know how much time passed between some places in your program. For example, to measure FPS in game, you will need to know delta time between frames.
To implement this we will need members:
time_point prevTick; // time of previous tick
time_point currTick; // time of current tick
void Tick() // user must call it each frame
{
prevTick = currTick;
currTick = clock::now();
}
const float GetDelta() const // user must call it to know frame time
{
return Duration(prevTick, currTick);
}
Stopwatch (advanced interval measuring)
Now, we need to have some kind of timed trigger. It is a good idea to separate this triggerfrom timer, so:
you can have multiple trigger with different start time and different trigger intervals
all of this triggers must be independent from each other
global clocks will not be altered, so all triggers remain valid
So let's wrap it to class:
class Stopwatch
{
private:
float m_Interval;
float m_Time;
float m_PrevTime;
public:
Stopwatch(float interval_ms = 1000.0f) :
m_Interval(interval_ms),
m_Time(0.0f),
m_PrevTime(m_Time)
{}
float GetRefreshInterval() const { return m_Interval; }
void SetRefreshInterval(float interval_ms) { m_Interval = interval_ms; }
// Update as frequent as possible
inline void Update(float dt)
{
m_Time += dt;
}
// Check if time interval reached
inline bool IsAboutTime()
{
if (m_Time >= m_Interval)
{
m_PrevTime = m_Time;
m_Time = 0.0f;
return true;
}
return false;
}
// exact value of last interval
inline float GetLastTime() const
{
return m_PrevTime;
}
};
Usage example:
Stopwatch stopwatch(5000.0f); // will trigger each 5 seconds
...
stopwatch.Update(timer.GetDelta()); // GetDelta() returns time difference between update frames
if ( condition A )
{
if ( stopwatch.IsAboutTime() )
{
doActionA();
}
}
Another possible ways to design stopwatch are:
inherit from clock
pass current time to IsAboutTime() so no need to Update()
Happy coding! =)