bool OnTimer() { if (isRunning == false) // page disappears { return(false); // stop timer } if (settleCounter >= 0) // page just appeared { // animate needle from max to zero settleCounter -= 2; double time = 1.0 - (1.0 / SETTLE_COUNT_LIMIT * settleCounter); // count from 0..1 needleAngleDegree = Tools.EasingQuadraticInOut(time, 90, -270, 1); imgNeedle.RotateTo(needleAngleDegree, SPEEDO_UPDATE_RATE_MS); // settle down accelerometer sensor accelerometerProvider.SetSpeed(0); return(true); // restart timer until sensor/device settled from last user touch } accelerationRaw = accelerometerProvider.GetAcceleration(); speedRaw = accelerometerProvider.GetSpeed(); // inhibit negtive speed if (speedRaw < 0) { speedRaw = 0; } if (speedRaw > 1) { // let speed be higher at start, but true at end speedAdjustedForDisplay = runAdjust.GetAdjustedDisplaySpeed(speedRaw); } else { // restart detection speedAdjustedForDisplay = 0; } // do not move needle until launch is detected if (isLaunchDetected == false) { speedAdjustedForDisplay = 0; speedRaw = 0; } if (Config.Run.PeakALabelEnabled) { if (dbgLabelAccel == null) { dbgLabelAccel = new Label(); dbgLabelAccel.FontSize = 18; dbgLabelAccel.Text = "0.0 m/s^2"; layout.Children.Add ( dbgLabelAccel, Constraint.RelativeToParent((parent) => parent.Width * 0.2), Constraint.RelativeToParent((parent) => parent.Height * 0.14) ); } if (dbgLabelAccelPeak == null) { dbgLabelAccelPeak = new Label(); dbgLabelAccelPeak.FontSize = 18; dbgLabelAccelPeak.Text = "0.0 m/s^2 (peak)"; layout.Children.Add ( dbgLabelAccelPeak, Constraint.RelativeToParent((parent) => parent.Width * 0.2), Constraint.RelativeToParent((parent) => parent.Height * 0.18) ); layout.ForceLayout(); } dbgAccel = accelerationRaw; if (dbgAccel > dbgAccelPeak) { dbgAccelPeak = dbgAccel; } dbgLabelAccel.Text = dbgAccel.ToString("0.0") + " m/s^2"; dbgLabelAccelPeak.Text = dbgAccelPeak.ToString("0.0") + " m/s^2 (peak)"; } if (isDemoMode) { //labelDemoMode.Text = "speed:" + (int)speedRaw + " accel:" + (int)accelerationRaw; } // filter (smooth) data filteredSpeedForDisplay = movingAverageForDisplay.Get(speedAdjustedForDisplay); runModeProvider.Acceleration = accelerationRaw; runModeProvider.Speed = speedRaw; // animate needle needleAngleDegree = Tools.Project(filteredSpeedForDisplay, ROTATION_SOURCE_MIN, ROTATION_SOURCE_MAX, ROTATION_TARGET_MIN, ROTATION_TARGET_MAX); imgNeedle.RotateTo(needleAngleDegree, SPEEDO_UPDATE_RATE_MS); filteredSpeedForDisplayWithUnit = Tools.ToSpeedUnitF(filteredSpeedForDisplay); // 123.45 -> 123 // 0.00 -> 0 labelSpeed.Text = String.Format("{0:000}", filteredSpeedForDisplayWithUnit); if (runModeProvider.IsStarted) { if (runModeProvider.HasTimeSplitChanged) { runModeProvider.OnTimeSplit(); SetSplitTimeText(); Debug.LogToFileEventText("run split at " + runModeProvider.TimeElapsed); btnStopVehicle.IsVisible = true; btnAbort.IsVisible = false; btnAbort.Image = runModeProvider.ButtonResults; runData.Store(); // commit data of this run to database } SetStatusText(Localization.pageRunTimeTotal + ": " + runModeProvider.TimeElapsed); if (runModeProvider.IsFinished) { runModeProvider.OnFinished(); SetStatusText(runModeProvider.Status); Debug.LogToFileEventText("run stop at " + runModeProvider.TimeElapsed); btnAbort.Image = runModeProvider.ButtonResults; runData.Store(); // commit data of this run to database } } // reset run if "launch was detected" && "speed is zero" && "no results available yet" && "some time elapsed since launch" if ((runModeProvider.IsReset == true) && (filteredSpeedForDisplay < 0.1) && (IsResultAvailable() == false) && (runModeProvider.TimeElapsedF > 3)) { Debug.LogToFile("run reset at " + runModeProvider.TimeElapsed); runModeProvider.OnReset(); SetSplitTimeText(); SetStatusText(runModeProvider.Status); runData.Reset(); isLaunchDetected = false; } // swap from button "stop vehicle" to "results button" if "run finished" and "speed is zero" if ((IsResultAvailable()) && (filteredSpeedForDisplay < 0.1) && (btnStopVehicle.IsVisible)) // only once { btnStopVehicle.IsVisible = false; btnAbort.IsVisible = true; } // log data if (isLaunchDetected) { Debug.LogToFile(accelerometerProvider.GetTimeStamp(), accelerationRaw, speedRaw, gpsProvider.GetSpeed(), runData.GetDistanceFiltered(), runData.GetDistanceGps(), runData.GetHeightFiltered(), runData.GetHeightGps()); runData.AddEventSlow(gpsProvider, accelerometerProvider.GetTimeStamp(), accelerationRaw, speedRaw); } // gps icon if (isDemoMode == false) // if demo mode -> gps is always off { if ((DateTime.Now.Ticks - timeStampLastGps) > GPS_TIMEOUT) // if gps connection is bad { if (isGpsOk) // switch to bad icon, but only once { imgGps.Source = "@drawable/icn_gps_no.png"; isGpsOk = false; } } else { if (isGpsOk == false) // switch to good icon, but only once { imgGps.Source = "@drawable/icn_gps_yes.png"; isGpsOk = true; } } } return(true); // restart timer }