In my last blog update, I was able to get the charging circuit and fuel-gauge IC working, but I wasn’t all that happy with the design of the program. The whole system was very buggy, with lots of random things happening, that I just wasn’t all that happy with.

However, I did have a system that was able to record lengths, show then later on, show the charging amount, and sleep the device.

Re-writing Code

Despite trying, I couldn’t figure out where the bugs were because the code had become far too messy!

The first thing I did was get rid of the pin change interrupts, and instead poll the pins every 15ms – in the background using Timer1 – via a function that checks all the required pins, and checks if they are pressed, have just been pressed, or have just been released. So far it works really well for me, including the debouncing. I found the code somewhere online, but I can’t remember where (if I find out, I’ll add a link).

The function code is below.

// Checking the inputs for button presses and performing the debouncing
void checkSwitches(void){
	static uint8_t previousState[NUMBUTTONS];
	static uint8_t currentState[NUMBUTTONS];
	static uint16_t lastTime;
	uint8_t index;
	uint8_t input = PIND;
	uint8_t inputCheck[] = {OFF, CHARGE, UP, DOWN, CLK, SELECT};
	if (lastTime++ < 4){ // 15ms * 4 debouncing time
	lastTime = 0;
	for (index = 0; index < NUMBUTTONS; index++){		
		if (!(input & (1 << inputCheck[index])))
			currentState[index] = 0;
			currentState[index] = 1;
		if (currentState[index] == previousState[index]) {
			if ((pressed[index] == 0) && (currentState[index] == 0)) {
			// just pressed
			justPressed[index] = 1;
			else if ((pressed[index] == 1) && (currentState[index] == 1)) {
				// just released
				justReleased[index] = 1;
			pressed[index] = !currentState[index];  // remember, digital HIGH means NOT pressed
		previousState[index] = currentState[index];   // keep a running tally of the buttons

The next thing I did was write up a much better FSM system. This involved me writing up a state / action table and a function which obtains the current event.

From the above two pieces, I was able to run through all of the states and actions without any issues. I’m still using a switch statement for the actions, rather than function pointers, but for now the system works well and I’m happy using the switch statement.

I re-wrote a few other things just to tidy up the code.

Real Time Clock

One thing I intend of doing is adding times to the laps, for a number of reasons:

  • Time / date stamping the start of each training session will be necessary for further analysis (particularly
  • Time stamping the beginning and end of every length will allow for better pace calculations as the current system rounds down each length to 1 sec.
  • It will allow for rests to be added, etc. in the near future.
  • It would potentially make it easier to upload to a computer and create something like a FITLOG file for uploading to different fitness logging systems.

However, for now, I’m not using any of those.

For now, I’m just using the CLK output from the RTC will I’ve setup to pulse at 1Hz. I then use that signal for timing the lengths, and for updating the charging screens.


I’ve created a small YouTube video showing the system in progress from start up, recording lengths, showing the history, charging, and shutting down.

Video of SwimWatch 3.3 working.