Author Topic: How to measure elapsed time  (Read 510 times)

Nick_W

  • Full Member
  • ***
  • Posts: 215
    • View Profile
Re: How to measure elapsed time
« on: September 02, 2016, 04:39:21 pm »
Update:

I have used the new function Device.GetTimeSpan() in a couple of places now, and it seems to work well. That said, there are some drawbacks:

1) You can only use it once in each program including libraries. I have used it in a device library, which may be a problem, as that means you can't use it anywhere else (and could accidentally include the library in a program that already uses it).
2) You have to do a test for > 0 as it returns -1 if it overflows, this makes programming award.

This is an example of where i have used it:

Code: [Select]
    Shared Event AccelerometerInt1()
        Dim int_source As Byte = accel.readIntSource()
        If (int_source & MMA8652.SRC_TRANS) = MMA8652.SRC_TRANS Then
            'Transient interrupt occured
            If (accel.readTransientSource() & MMA8652.TEA) = MMA8652.TEA Then
                'Any Transient Occured
                LedGreen = True
                If ReedSwitch = False Then //If door is closed
                    //if more than 10 seconds since Knock last triggered, and more than 5 seconds since door closed
                    If (Device.Uptime() - TimeSinceKnockTriggered > 10) And (Device.Uptime() - TimeSinceDoorClosed > 5) Then
                        Dim timeSinceLastTransient As Integer = Device.GetTimeSpan()
                        'If at least two transients within 0.5 seconds
                        If timeSinceLastTransient < 500000 And timeSinceLastTransient > 0 Then
                            TimeSinceKnockTriggered = Device.Uptime()
                            MQTT.Publish("Doorknock", True)
                        End If
                    End If
                End If
                LedGreen = False
            End If
        End If
    End Event
   
    Shared Event ReedSwitchChanged()
        Thread.Sleep(500000)
        Thread.ClearHardwareEvent()
        LedGreen = True
        Dim Door_Status As Boolean = ReedSwitch
        If Door_Status = False Then
            TimeSinceDoorClosed = Device.Uptime()
        End If
        If Publish_data Then
            MQTT.Publish("Door", Door_Status)
        End If
        MQTT.BeaconPublish(dataType.DOOR, Door_Status)
        LedGreen = False
    End Event

You can see that I'm using Device.Uptime() as a coarse millis equivalent, to time events over 1 second in duration. The function Device.GetTimeSpan() is used to time sub 1 second events (this is from a door sensor program to detect door open/close and knocking).
You can see I have to test for 0, otherwise if the duration was long, the routine would return -1 and falsely trigger the door knock event. See point 2) above.

In another application, I included it in the BME280 library, like this:

Code: [Select]
    Public Sub TakeReading()
        Dim conversion_time As Integer = getConversionTime()
        If Device.GetTimeSpan() > conversion_time Then //if time since last run is more than conversion time, take new reading
            write8(REGISTER_CONTROL, temp_press_oversample) //take reading
            Thread.Sleep(conversion_time) // wait ConversionTime for reading
        End If
    End Sub

This prevents subroutines which call getTemperature() or getHumidity() (which in turn calls getTemperature()) from requesting multiple readings one after the other. If the request is generated within the timespan it takes for a reading, the request for a new reading is ignored (and the cached values will be used). This is the easiest way to do this, as the conversion time ranges from a few ms to 2.1s (using default settings it's 69ms).

I would have liked to add it to the readAll() function, which reads the values (in burst mode) from the device registers, to prevent re-reading of values already stored in the class, but see 1) above. This would save some small amount of power, but the time saving using it in the above routine is significant, so I used it there.

Assuming this is a temporary function, until a long datatype is available, it serves it's purpose. I will update my code when a real millis or micros function is available.

Thanks for implementing this so quickly.