Counting Resets

After finishing the basic effects I wanted to be able to switch the effects easily. Of course I could do so with the help of the serial connection but this would always require a computer. An additional input switch though would rob me of one of the LEDs. Also it would require an external part. No really cool. But then it occurred to me. The Blinkenlight Shield already has some switch. The reset switch. By changing the fuses the reset pin could be used as an input. Unfortunately this would have a significant downside. It would render the bootloader inoperable and it would require a high voltage programmer for subsequent flashing. So not really an option as well.

But then I wondered what if I could count the number of resets?

Digging through the avr-gcc documentation I figured that something like

uint8_t reset_counter __attribute__ ((section (".noinit")));
void setup() {
    ++reset_counter;
}

should do the trick. It places the variable „reset_counter“ in the „noinit“ section. Then it will not be initialized at start up of the program / sketch. Unfortunately this does not work 100% reliable. It works without boot loader but some boot loaders seem to clear the memory before they start the sketch. Of course I could just fix the boot loader but then I would always have the issue that someone might complain about my code although the boot loader is the cause for the failure.
So I needed some other place to put my counter through resets. After trying almost any register I figured that EEPROM will be the only reliable means.

//
//	www.blinkenlight.net
//
//	Copyright 2011 Udo Klein
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program. If not, see http://www.gnu.org/licenses/


#include <EEPROM.h>

uint8_t get_next_count(const uint8_t count_limit) {
	uint8_t count = (EEPROM.read(0) + 1) % count_limit;
	EEPROM.write(0, count);
	return count;
}

void setup() {
    uint8_t count = get_next_count(20);

	for (uint8_t pin = 0; pin < 20; ++pin) {
		pinMode(pin, OUTPUT);
		digitalWrite(pin, pin == count);
	}
}

void loop() { }

As the video demonstrates the sketch will count how often the reset switch gets pushed.

Unfortunately EEPROMs will not last forever. So this approach raises the issue of EEPROM wear and how to deal with it. We investigate the answer with the experiment on wear leveling.

4 Responses to Counting Resets

  1. The whole of EEPROM should be capitalized 😛
    It stands for Electrically Erasable Programmable Read Only Memory.

  2. James Jones says:

    Looking up EEPROM.h, it would seem that read returns a uint_8, so the result it returns will be between 0 and 255 (inclusive), not between -128 and 127; you’d have to cast the result to a signed eight-bit type to get -`1, so I don’t think the additional % is necessary.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.