Reduced internal clock speed and debounce

Hope this is the right section for this query.

I've been using the Bounce and Prescalar libraries in the same project, and I've found that the behaviour of the Bounce library becomes erratic at low clock speeds (2MHz and 1MHz), including continuous rebounces once a button has been pressed. It works fine at 16 and 8MHz and only misses a few presses at 4MHz.

Does the state of a digital input pin become unstable at low clock speeds, or is it something to do with the Bounce library and the millis() function? I've tried modifying Bounce to scale correctly with internal clock speed, but it doesn't work any better.

Any suggestions welcome!

I have not used the Bounce library; wrote one of my own, and have used it without issue at 1MHz, FWIW:

Thanks Jack! Using your library, I am still not reliably detecting button presses. As the internal clock speed goes down, it drops from picking up every press of a rapidly-pressed button to only detecting one per second or so. It doesn't seem to matter if I rescale the debounce time or not. Does it matter that millis() returns a value scaled according to the internal clock speed?

steronydh:
Thanks Jack! Using your library, I am still not reliably detecting button presses. As the internal clock speed goes down, it drops from picking up every press of a rapidly-pressed button to only detecting one per second or so. It doesn't seem to matter if I rescale the debounce time or not. Does it matter that millis() returns a value scaled according to the internal clock speed?

millis() should return milliseconds, regardless of clock speed. If it's doing something else (why?) then yes that could be an issue, but only detecting one per second seems way out in left field.

That's odd, the Prescaler library provides the "trueMillis()" and "trueDelay()" functions because it says that they need to be rescaled according to the clock speed. Maybe I'm missing something...

I have found that using the Narcoleptic library (Google Code Archive - Long-term storage for Google Code Project Hosting.) to sleep for a second at a time, I can get the power consumption down to half what I can get through lowering the clock speed to 1MHz (~5.5mA sleeping at 16MHz vs ~11mA not sleeping at 1MHz), so I am going to try that instead. (The button debouncing was used to set up a duration before letting it run, so it's not needed most of the time.)

I wasn't aware of the Prescaler library. I have just adjusted it myself, it takes about four lines of code. My approach has been to set up entries in boards.txt for clock speeds of 1, 2, 4 and 8MHz so that sketches get compiled with the intended F_CPU. If then my hardware setup doesn't match the intended F_CPU, for example using a 16MHz crystal but I want a 2MHz system clock speed (and compiled with the 2MHz boards.txt entry), then the first thing I do in setup() is to make the appropriate prescaler adjustment.

This approach allows millis() and delay() to work properly. Also I have had no issues with my Button library.

If you don't mind sharing, tell me a little more about what you're trying to do, and which microcontroller you are using. Supply current while sleeping should be measured in µA, not mA. Using power-down sleep mode with the BOD disabled, current should be a fraction of a microamp.

I'm currently powering the whole custom board (with ATMega328) through a 7805 regulator, which I think is where most of the sleep current is going. There is an LCD screen which remains on all the time, but that won't be taking much.

My application is an "intervalometer" for triggering a camera at regular intervals for time-lapse photography. Once the time interval has been set up and a run triggered, I will put the cpu to sleep for a second, then wake up, count down by one second, trigger the camera if the countdown reaches zero, and update the LCD with the remaining countdown time and total number of images taken. The sleep duration will be calibrated so one loop lasts as near one second as possible, but it doesn't need to be totally precise.

I think if I replace the 7805 with 3 AA batteries the current consumption while it's running should be pretty low.

No doubt correct about the 7805. Which sleep mode is used, and what triggers the wake up?

I'm using the Narcoleptic library (Google Code Archive - Long-term storage for Google Code Project Hosting.). It uses SLEEP_MODE_PWR_DOWN and the watchdog timer to wake. This is my first project to use an on-board uC, and my first self-designed PCB, so I'm learning as I go with this one!

Sounds like a fun project. What is the preferred clock speed then, 1MHz? And how is it being programmed, with an ICSP programmer? I typically use ICSP for anything less than 8MHz, which means no bootloader. Below is my boards.txt entry for a 328P with factory-standard fuse settings, i.e. using the internal RC oscillator @ 1MHz as the system clock.

uno1.name=Arduino Uno ICSP @ 1MHz
uno1.upload.using=usbtinyisp
uno1.upload.maximum_size=32768
uno1.bootloader.low_fuses=0x62
uno1.bootloader.high_fuses=0xD9
uno1.bootloader.extended_fuses=0x05
uno1.bootloader.path=atmega
uno1.bootloader.file=ATmegaBOOT_168_atmega328.hex
uno1.build.mcu=atmega328p
uno1.build.f_cpu=1000000L
uno1.build.core=arduino
uno1.build.variant=standard

Thanks for the low clock speed info Jack, I'm not familiar with changing the boards.txt file and fuses (yet!). It's programmed with an FTDI-USB cable.

I've gone back to the standard 16MHz speed for simplicity as the board will only be running at full power briefly while the interval is being set up.

When the board is running the timer with 1-second sleeps and a direct 5V power supply it's averaging about 1.7mA. The LCD takes about 1.2mA so the Arduino is averaging 500uA.

Steve.