I have an app that reads environmental data from a USB sensor connected to a Mac. Users are able to configure how often the app samples data and how often the app averages those samples and logs the average to a file.
I first used NSTimer
but that was wildly inaccurate, especially when the display went to sleep. I am now using a DispatchSourceTimer
but it is still losing 1 millisecond about every 21-23 seconds which is about 1 second every 6 hours or so. I'd ideally like that to be less than 1 second per day.
Any ideas how I can tune in the timer to be a little more accurate?
func setupTimer() -> DispatchSourceTimer {
let timer = DispatchSource.makeTimerSource(flags: .strict, queue: nil)
let repeatInterval = DispatchTimeInterval.seconds(samplingInterval)
let deadline : DispatchTime = .now() + repeatInterval
timer.schedule(deadline: deadline, repeating: repeatInterval, leeway: .nanoseconds(0))
timer.setEventHandler(handler: self.collectPlotAndLogDatapoint)
return timer
}
func collectPlotAndLogDatapoint() {
samplingIntervalCount += 1
let dataPoint : Float = softwareLoggingDelegate?.getCurrentCalibratedOutput() ?? 0
accumulatedTotal += dataPoint
if samplingIntervalCount == loggingInterval / samplingInterval{
let average = self.accumulatedTotal/Float(self.samplingIntervalCount)
DispatchQueue.global().async {
self.logDataPoint(data: average)
self.chartControls.addPointsToLineChart([Double(average)], Date().timeIntervalSince1970)
self.samplingIntervalCount = 0
self.accumulatedTotal = 0
}
}
}