Stop Watch Logic

stop watch logic

Use the Stopwatch Class (For higher precision use System.nanoTime())

Add a Start() event and Stop() event on Button Presses. You'll need to update the UI so use a Thread/Handler Combination.

This should get you started.

EDIT: Added Code. (Nice Exercise! :) )

Use the Refresh_Rate to configure how often your UI is updated.

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class Main extends Activity implements OnClickListener{

final int MSG_START_TIMER = 0;
final int MSG_STOP_TIMER = 1;
final int MSG_UPDATE_TIMER = 2;

Stopwatch timer = new Stopwatch();
final int REFRESH_RATE = 100;

Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_START_TIMER:
timer.start(); //start timer
mHandler.sendEmptyMessage(MSG_UPDATE_TIMER);
break;

case MSG_UPDATE_TIMER:
tvTextView.setText(""+ timer.getElapsedTime());
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE); //text view is updated every second,
break; //though the timer is still running
case MSG_STOP_TIMER:
mHandler.removeMessages(MSG_UPDATE_TIMER); // no more updates.
timer.stop();//stop timer
tvTextView.setText(""+ timer.getElapsedTime());
break;

default:
break;
}
}
};

TextView tvTextView;
Button btnStart,btnStop;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tvTextView = (TextView)findViewById(R.id.TextView01);

btnStart = (Button)findViewById(R.id.Button01);
btnStop= (Button)findViewById(R.id.Button02);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);

}

public void onClick(View v) {
if(btnStart == v)
{
mHandler.sendEmptyMessage(MSG_START_TIMER);
}else
if(btnStop == v){
mHandler.sendEmptyMessage(MSG_STOP_TIMER);
}
}
}

Most efficient way to implement a stopwatch?

Use performance.now() for accurate time-stamps (or fallback to new Date().getTime()) and compute the difference in UI update callbacks (via setInterval). Don't use setInterval itself to compute time - you cannot assume that setInterval calls will actually be called precisely every 1000ms.

Note I also moved the timer logic to the ngOnInit function instead of the constructor.

export class MainComponent implements OnInit {

private start: number = null;
private uiTimerId: number = null;

constructor() {
}

private updateUI(): void {

let delta = performance.now() - this.start;
this.someUIElement.textContent = delta.toFixed() + "ms";
}

ngOnInit() {

this.start = parseFloat( window.localStorage.getItem( "timerStart" ) );
if( !this.start ) {
this.start = performance.now();
window.localStorage.setItem( "timerStart", this.start );
}

this.uiTimerId = window.setInterval( this.updateUI.bind(this), 100 ); // 100ms UI updates, not 1000ms to reduce UI jitter
}

buttonClick = function() {
if( this.uiTimerId != null ) {
window.clearInterval( this.uiTimerId );
window.localStorage.removeItem( "timerStart" );
}
}
}

How to do I retrieve the current time on a stopwatch?

I figured it out. On click you have to call the text view and set text within it.

Here is an example that works in the code provided in the question, add it in the on click method:

txtView.setText(txtTimer.getText().toString());

How can I fix the stop-start process within this Javascript stopwatch-clock?

Issue with your code:

  • You start with initial value for sessionStorage as Date.now but then save difference on update.
  • You interact a lot with session storage. Any communication with external API is expensive. Instead use local variables and find an event to initialise values.
  • Time difference logic is a bit off.
    • Date.now - startTime does not considers the difference between stop action and start action.
    • You can use this logic: If startTime is defined, calculate difference and add it to start time. If not, initialise it to Date.now()

Suggestions:

  • Instead of adding styles, use classes. That will help you in reset functionality
  • Define small features and based on it, define small functions. That would make reusability easy
  • Try to make functions independent by passing arguments and only rely on them. That way you'll reduce side-effect

Note: as SO does not allow access to Session Storage, I have removed all the related code.

const outputElement = document.getElementById("outputt");
var running = false;
var splitcounter = 0;
var lastTime = 0;
var startTime = 0;

function logTime() {
console.log('Time: ', lastTime)
}

function resetclock() {
running = false;
startTime = 0;
printTime(Date.now())
applyStyles(true)
}

function applyStyles(isReset) {
startstopbutton.value = running ? 'Stop' : 'Start';
document.getElementById("outputt").classList.remove('red', 'green')
if (!isReset) {
document.getElementById("outputt").classList.add(running ? 'red' : 'green')
}
}
function startstop() {
running = !running;
applyStyles();
if (running) {
if (startTime) {
const diff = Date.now() - lastTime;
startTime = startTime + diff;
} else {
startTime = Date.now()
}

updateTimer(startTime);
} else {
lastTime = Date.now()
logTime();
}
}

function printTime(startTime) {
let differenceInMillis = Date.now() - startTime;
let {
hours,
minutes,
seconds
} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
}

function updateTimer(startTime) {
if (running == true) {
printTime(startTime)
requestAnimationFrame(() => updateTimer(startTime));
}
}

function calculateTime(milliS) {
const SECONDS = 1000; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;

let hours = Math.floor(milliS / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(milliS / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(milliS / SECONDS) % RESET;

return {
hours,
minutes,
seconds
};
}

function pad(time) {
return time.toString().padStart(2, '0');
}
.red {
background-color: #2DB37B
}

.green {
background-color: #B3321B
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" value="Start" onclick="startstop();">
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock();" />
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>

python stopwatch in IF ELSE

Let's look only at the timing logic. When you turn the relay on, you mark that start time. The "time on" measurement continues until you turn the relay off. Then the "time off" timer starts, continuing until you turn it on again.

I suspect that you're a little confused because the start and stop events are in different code blocks. First, let's measure the "relay on" time. I'll make a flag relay_is_on to notice when the relay state changes.
When the state changes, we'll take action: print the status change, reset the flag, and mark the start or stop time.

relay_is_on = False

while True:

if highest > 3:
if not relay_is_on:
# Relay is just turning on;
# process changes
print("RELAY ON")
relay_is_on = True
relay_on_start = time.time()

else:
if relay_is_on:
# Relay is just turning off;
# process changes
print("RELAY OFF")
relay_is_on = False
relay_on_end = time.time()
relay_on_interval = relay_on_end - relay_on_start

From here, you can do whatever you need to accumulate or report the relay-on intervals. Also, if you need to similarly handle relay-off times, you simply add a few lines in the converse logic.

Can you continue from here?



Related Topics



Leave a reply



Submit