The More You Make, the More You End Up Making

Creativity has always been interesting to me, because I don’t see myself as a creative person at all. In building games, I always tended towards making the most efficient rather than the most beautiful structures. Professionally, my greatest strength is reducing the complexity of problems to more solveable issues and helping to guide others to move towards solving them. Artistically, I’ve never been able to do much at all, though I’ve tried calligraphy, playing the violin, drawing, and so on. Language seems to be my best creative skill, though not for fiction but rather for communicating clearly. All in all, I’d describe myself as quite uncreative.

One of my main issues would always be the difficulty of thinking of new ideas out of nowhere. It’s so impressive to me how somebody could look at a blank canvas and just decide what to do there. However, now with electronics, it took me just the one big project to learn the basics of electronics, and I’m starting to get more ideas. I’d run into tiny inconveniences and thought: surely, I can spend way more time solving this miniscule issue than I’d gain by just working through it? And so projects were born. Currently, I have the following ideas clunking around, with no specific timeline for when I’ll actually be working on them:

Hamstercage Lights

My current main project is to install RGB lights in all three levels of our hamstercage build. It’d both simulate a circadian rhythm for whenever we get our new hamster, and would have a manual override for when we need light. My main posts on electronics are all about this, so there’s not much new to report there.

Countdown Timer

This was inspired by the Pomodoro timer, as it’s somewhat related but for a completely different purpose. The Pomodoro timer just counts down in small half-hourish increments, to organize working time and to help remind me to take regular breaks. The Countdown Timer was born because there’d be several moments where Tracy and I are working towards a larger goal with a set deadline, such as when we originally moved over here; conversely, there’s also smaller deadlines, like deciding how much time we have until our groceries get delivered. Again, why use just a mobile phone timer when you can massively overengineer a large LED display or 7-Seg display and program it to display days, hours, minutes, and seconds?

Binary, Hexadecimal, Decimal Converter

While I was programming the Pomodoro Timer in C rather than Arduino, I started using binary and hexadecimal numbers more often to directly address memory. In particular, I’d want to set a whole register to specific bits in one go, and using hexadecimal just seems cleaner to me for some reason. What I’d end up doing is going through a datasheet, checking all the right pins for an 8-bit register, and then using a converter online to figure out what the hexademical is for that binary number. Why accept anybody else’s very convenient solution to a self-created problem when I can make it entirely more complex by spending more time? I could just make a small device that shows the same number in decimal, binary, and hexadecimal, and have several knobs or buttons so that I could change each number and the others would automatically change with it.

Bonus: Taglines For the Blog

As I was writing this, I just kept coming up with additional taglines for the blog (huh, additional task: figure out if I can have rotating taglines). Here’s a selection of my favorites:

  • Answering questions nobody asked;
  • Solving problems I created myself;
  • Solving problems nobody has;
  • Creating problems, then solving them by creating two new problems;
  • Breaking things by fixing them;
  • Fixing things by breaking them;
  • Finding out things nobody cares about;
  • Championing pointless causes;
  • Finding a problem to every solution;
  • Putting the “me” in “meaningless”.

Learning About Flux

I’ve read that flux is a useful thing to use when soldering, but I never really knew what it does or what the real uses were. I was aware that it helps solder stick, and that the usual soldering tin I used contained flux, but I just wasn’t sure exactly what it was or when to use additional Flux. The advice I read most often was when you try to solder an SMD chip, flux is really handy to drag solder pins. However, that just tells me when to use it, but not what it does. However, I saw a simple video that really drove the point home to me. It simply shows examples of soldering with and without flux, and changes some variables around so you can directly see the effect. Now that’s some educational material!

Testing Out RGB Manual Control

I’ve been thinking about how to control the hamstercage light project, and what is really needed. My first idea was to see if I could control the project via WiFi, perhaps by using an app (via Blynk, likely). However, seeing as Blynk uses a freemium model, I felt reticent to go ahead with it. After all, what if Blynk changes its terms of service? What if what I need takes a monthly payment? What if adding a second user isn’t possible? I don’t like trading ownership for convenience, so I’ve decided to abandon that idea. That did mean I had to thoroughly consider alternative controls.

As I’d considered before, I quickly settled on manual controls. After all, the idea is to automate the hamstercage lights nearly all of the time, with exceptions for when we want to see more clearly into the cage (for cleaning, or finding the hamster). Clearly, we’d be next to the hamstercage when we’d want to have direct control of the lights, ergo having manual controls makes the most sense. Doing a quick read online made me conclude that the usual means of controlling RGB leds manually is using potentiometers. Fortunately, I had a few ones lying around, so I quickly wired something up to test:

Figure 1: The breadboard test of controlling RGB lights with potentiometers

I’m breaking a bit with my usual color conventions here, as I’m using black as ground and orange as 3.3V. The WS2812B take 5V but I figured this would work well for the time being. You may notice that I also don’t have a resistor between the powerline and the WS2812B LEDs right now; that’s firstly because the setup wasn’t working when I started, so I reduced components to see when it would work, and secondly because the 3.3V certainly wouldn’t exceed it’s Vmax of 5.5V in any case.

The ESP32 has a really nice number of ADC pins (which I’ve learned stands for Analogue to Digital Convertor), so I had a bevy of choice to connect the potentiometer to. Essentially, the ESP32 compares the voltage from the middle pin of a potentiometer to 3.3V, and then outputs a value between 0 (for 0V) and 4095 (for 3.3V). Since the WS2812B takes a value between o and 255, it’s a simple case of dividing the value from the ADC pin by 4096/256=16 (The off-by-one programming mistake isn’t catching me here!). That gives me three 8-bit values to put into the RGB LED.

After some uploading problems (I had not connected the ground pin, which apparently was a problem for uploading to the chip), I had a working prototype. This setup managed to control the color decently, though I didn’t seem to get as much color variation as the FastLED library demo gave me. Moreover, the results were a little inconsistent. The cause of both issues would be the potentiometers. Firstly, the values aren’t precise, which of course the FastLED library demo does have, seeing as the values are specified in code rather than by analogue input devices. So, when I’m turning a potentiometer, the numbers go up in rather large jumps. One challenge to overcome, then, is to get a better resolution (for lack of a better word). The second problem I ran in to was that the color seemed to flicker a little, which again I attribute to the potentiometers. The potentiometers I’m using are not quite a comfortable fit in the breadboard, and I suspect that the connection they make is shoddy. I noticed that there was quite some wobble to them, and if I’d touch them, the hue would change.

All in all, then, I’d call this quite a succesful test. I have a proof of concept, in that I know I can control the colors of the LED strip using potentiometers. The follow-up is to get better control. The next test I want to do, however, is to work on the WiFi-side of things, and test out getting the current time from an NTP server. Once I’ve tested that, I’ve established all the ground principles I need to create the hamstercage light project, and I know I can start working on refining all the individual elements of it.

First Experiments with RGB and ESP32

The past few days, I’ve been experimenting with both RGB LEDs and ESP32. I’ve never worked with either before, so I wanted to get some experience with the basic functions before I dove into the more complex task of building the hamstercage lighting.

My first experiment was trying to get the RGB LEDs working. I have a strip of 60 WS2812 RGB LEDs, which are one of the apparently two common types of RGBs. The WS2812 distinguish themselves by having some manner of IC included in the strip, so that there’s a single data line in along with the power and ground, making coding quite easy. The other most common RGB strip also includes a clock signal, so that still seems fairly elementary. To get this working, I hooked it up to my Arduino Uno clone, added the FastLED library, and loaded up the first couple of examples. Everything pretty much worked without a hitch, which was great. About the most complex part was that the examples mostly used pre-defined colors (::red, for example) whereas I potentially want to use a whole host of RGB values. However, one quick online search and that was already solved.

ESP32, however, was a little more tricky than that. My first very practical problem is that the breakout board is just slightly too big for my breadboard. I can only just about fit it on one, leaving a single row of headers for additional pins. Nevertheless, that’s all we need to test the single RGB strip. The bigger issue was trying to figure out the pin-outs of this board. There seemed to be a number of potential pinouts provided online, and they just didn’t seem to work for me. In fact, nothing worked until I switched to a different example – I guess I must have messed something up in the example, causing all my other issues! Once I fixed that, the pin-out diagrams seemed to make sense again, so that was one hurdle taken.

However, somewhere in this testing, I seemed to have messed up one of my ESP32-WROOMs. I’m not too sure what’s going on, but it’s no longer registering on the USB port. However, I’d bought three of the chips (potentially for three separate parts of the cage, though I appear to not need that), so a secondary one took its place. I’m noticing that the problematic ESP32 has a rapidly blinking LED, which may be a hint to its condition. If I press the boot and enable buttons at the same time, I can upload a program again, but as soon as it’s reset, the chip seems stuck again and the LED is back to blinking rapidly. It’s possible that while I was probing the board with my multimeter, I may have shorted something, I’m assuming. However, for now this will remain a mystery.

Having tried out the basics of RGB LEDs and the ESP32, and being able to light the LED strip with any RGB value, I have two of the three fundementals ready to work on my hamster cage project. The last one is a way to control the lights. The most basic option is to provide some physical controls at the cage. This is quite sensible, as there’s no need to control the lights unless we’re at the cage doing something. The second option is to use Blynk. Blynk is some manner of visual app development program that has interface possibilities with ESP32 chips built-in. It seems like an easy way to make an app, but it also comes with a rather limiting fremium model that I’m not a fan of. We have the features that it offers right now, but how long before those become premium features? The last option is to personally write some manner of HTML interface. I’ve looked into it, and making an elementary one doesn’t seem too complex. The most difficult parts (having a slider for the RGB colors, for intance) are already worked out in basic java snippets available on countless forums. I like the home-made aspect of that, though it may make the controls a little less polished.

I’m not too sure what route I’ll end up taking but whichever route it will be, my next step has to be to control the color of the LEDs live in some form or another.

Adjusting my Knowledge of Schematics

A little while ago, I posted about learning new things about schematic design. In short, I followed a tutorial that encouraged clear schematics by using many net labels in the place of drawing out wires. In particular, they connected net labels directly to the PCB, and had everything defined separately from that. However, I’ve come to find out that this is a bit of a debate in the hobbyist electronics world. I was reading the following post on Reddit that shows an example of the discussion in the comments:

A Reddit thread where someone posts their schematic, which makes heavy use of net labels. The discussion about this in the comments was quite educational for me.

The discussion centered around the balance between clean and clear schematics. Separating everything out with net labels will certainly make schematics clean, as there will be a minimum of crossed wires or cramped symbols. However, the downside is that this will reduce clarity. I followed a suggestion in the comments and tried to trace a signal through the schematic. I have to admit, it was pretty tricky – I checked a pin, and then read the net label, followed by having to scan the schematic to find that net label again, only to see that there were two other net labels involved. As a result, it was pretty tricky to see what the internal connections were.

It seems there’s a pretty clear divide on the topic, as evident in the discussion as well. Some people will say that leaving as many wires in the schematic will aid readability, although they’ll also say a schematic should have as few crossed wires as possible. The consensus seems to be that some common sense should be applied in choosing when to use labels. In the case of this schematic, there’s an example of a label being used for no reason at all, apparently, as this person points out:

This user identifies three components that are right next to each other on the schematic, but connected via labels rather than wires.

I can wholly understand their comment here. These components were literally adjacent to each other and nothing else, and connecting them via cables would cause very little trouble at all (one connection to ground would have crossed over a signal wire but that’s it).

In the case of my Pomdoro schematic, I’m thinking that I may have doubled up on methods to clean up my schematic. For instance, I used both buses, wire labels, and global labels. I could have stuck with only wire labels, and perhaps adding buses to still draw a line but collate the five wires into one. Furthermore, it makes sense to me to separate out the power section of the schematic. It’s a functionally separate part from the main schematic. The same goes for the ISP programmer – it’s a side issue to the main function of my device. However, I’d also separated out the LEDs from the microcontroller, even though that’s the main point of my entire Pomodoro timer.

Figure 1: The Pomodoro Schematic

It’s a good lesson for when I make the hamster cage lighting system. I’m not bothering to rework this schematic again, but if I would, I now know what I’d do better.

  1. I’d edit the ATtiny84 symbol to put PB3 on the left side of the symbol. After all, it’s an input to the microcontroller, so it makes sense to me that the signal goes from left to right.
  2. I’d not use net labels for TimerLeds and PomodoroLeds, but rather use the bus wire to connect the LEDs somewhere to the right of the ATtiny84.
  3. I’d use the small versions of the symbols to create a little more space on the schematic.
  4. I’d have the wires on PA5 and PA6 connect directly to the relevant switches. Those are their main functions, after all, whereas the MISO and MOSI are secondary connections and should be branches off that.
  5. Similarly for PB3, where I’d have it connect directly to the RST label, and have the pull-up resistor be a branch upwards.

Learning About KiCad and Schematic Design

The next project I’m going to be looking into is the RGB lighting for the hamster cage project (post about the cage; post about the intended design). I’m now back at the usual first stage of my projects: experimentation. This is usually the time where I just hook things up, see how things work, and generally mess around. To give you a rough idea, my experimentation now will be getting the ESP32 to connect to the WiFi; then, I’ll try and get an LED to blink; lastly, I’ll try and get the LED to blink depending on whether I’ve sent a command over WiFi. As you can see, it’s step-by-step increasing the complexity, until I am where I need to be.

The next step, usually, is design. Once I’ve tested out all the individual bits of my final project, and I have a rough idea of how to do it, it’s the time to bring it all together. My first step is always to make a schematic in KiCad. As usual, before I start I try to learn a little bit more and apply at least one new thing before I get started. That’s why I was so happy that I found this video:

A video by Phil’s Lab, showing the full process of hardware design

I’m only about half an hour in so far, and I’ve already learned a tremendous amount about net labels and sectioning off components, as well as just some handy KiCad tricks. Just for that alone it was useful to me, and I still have two more hours of the video to go right now!

Aside from that, I wanted to find a good solution to the mess of wires I had in the Pomodoro design. The outputs for the ATtiny84 were all so close to each other, and some had to move upwards while others moved down – it ended up as a large bowl of spaghetti (a tangled, disordered mess of wires or connections are often informally called spaghetti, for obvious reasons). Yet, there are two clear bundles of data in the Pomodoro timer: the two sets of LEDs. So, I looked up how to do bus wires, leading me to this post. It’s an explanation of how to apply bus wires in KiCad, and using wire labels to connect everything together. That way, you can get a clear schematic, and KiCad can still read it and build a rat’s nest out of it.

When I learned these things, I just had to stop the video and apply this right away. The only schematic I had lying around was the pomodoro one, so I figured to just test out the process:

Figure 1: The original Pomodoro r2 schematic

Now compare the old schematic to this new one that has all the lessons applied:

Figure 2: A revised Pomodoro r2 schematic, applying net labels, bus wires, and outlines for sections

What a difference in clarity! No more crossed wires, and several subsystems are clearly separated out to their own space. I greatly prefer this schematic. The only downside I found was that the labels are later on also used in the PCBNew program to label the actual traces. Now, that may be quite a useful feature later on, but it also causes a little confusion. Take a look, for instance, at pin 7 (PA6): it’s both MOSI as well as the Pause/Reset switch. Now, since I applied the MOSI label to it to connect it to the ISP, the whole trace was called “MOSI”. However, I’d much rather apply that label only to the trace leading to the ISP, and Pause/Reset only to the trace leading to the button. Maybe that’ll be possible, maybe it won’t. More to learn!

Pomodoro r2 Working Prototype

Yesterday, I managed to solve the pause button issue that I was facing. My main problem was running two timers at the same time so that I could use one to poll the button at a much shorter interval than the second timer for the lights. It took quite some fiddling, after I first tried to use the B timers to do this. However, I couldn’t get the compare timer working on the B timer, despite it having a compare register. I’m not too sure how it works yet, but I figured that the B timer compare register is actually for other purposes (such as using it to generate output), rather than an internal timer.

After quite some fiddling, I realized a much simpler solution to my issue than trying to get a B timer working on Timer 0: I just use the A timer on Timer 1. Now, Timer 0 is 8-bit and Timer 1 is 16-bit, so at first I thought it seemed a little wasteful but, then again, what else am I using that timer for anyway? So, I rewrote the program to have an A timer poll at a very high frequency (not even using a prescaler, if I recall), and found a little script online to debounce the button. Essentially, it just involves checking if the button is pressed, waiting for 25ms, and seeing if it’s still pressed. It seems to make use of the fact that a human being physically will not be able to push and release a button in that short a timeframe, and waiting to process it will also skip over the bouncing inbetween.

That still left me with an unsolved problem: the original version of this had two options for the button: a short press was a pause, and a long press was a reset. Right now, I don’t have that implemented. It would take a greatly different approach to the problem, as I did that using Arduino’s millis() function, and I have nothing similar on this firmware. However, the way I figured it, I have an ISP interface on there anyway, so I can get to that later if that’s still so important to me. ISP is awesome!

Next up came the soldering. Now, my first designs were for a PCB, so that I could make it in a nice little package that looked cool. However, that would have involved having that made in China, waiting a few weeks, and then possibly finding out that the footprints weren’t good because I changed this or that. So, I just figured to cut some perfboard and use my newly-learned solder bridge skills to make it. It was a good thing I did too, because I found out that some things were absolutely wrong. The button I was using for pause/reset, for instance, had two pins spaced two spaces apart, though by PCB design had it as one space apart. Similarly, the buzzer was slightly different than the footprint. On top of that, the ISP pin header I’d chosen was bigger than the header pin on the PCB. So, if I had ordered the PCB, it would not have worked for me in all likelihood!

Below you can see some pictures of the finished product. You’ll notice some of the adjustments I had to make in the side-by-side of the prototype and the design. The final picture shows a working model of the Pomodoro Timer r2. I have to tell you: I am so damned proud of myself for this one. There’s things to improve, like always, but this has got to be the cleanest, most complex working product I’ve made to date. Most of all, I built this up from scratch and learned so much from doing it.

Figure 3: The topside of the finished prototype

Pause Button Problem Solving

As I posted before, I’m working on trying to get the pause button working on the pomodoro device. There were two issues: firstly, the button needed debouncing, and I had to decide whether I wanted that in hardware or software; and, secondly, I was using a interrupt for the pause button that didn’t work correctly. Specifically, the hardware interrupt I was using activated on a pin state change, resulting in two activations per press (pressing down as well as letting go). Now, there was a potential to use another hardware interrupt, but that involved some rewiring.

As far as the debouncing goes, I found out that the usual solution involves an RC network (a resistor-capacitor network), which essentially provides a bit of a buffer by smoothing out the signal. It works, but as I mentioned before, isn’t done much anymore. In a previous post, I mentioned that reducing cost was a main consideration, but a more important reason turns out to be that there is no point in doing it in hardware when you already have a microcontroller with enough space to do it in software. Or, in other words: why do it the hard way when you already have everything you need in the microcontroller? So, I’ll have to see about implementing a software solution.

As for the other issue – how to handle the button press – I’m considering not using a hardware interrupt. One problem is that the hardware interrupt would require a hardware debounce, because debouncing it in software requires a degree of waiting for it to settle, which you can’t do if your interrupt is getting interrupted because the button keeps bouncing (very Catch-22, right?). What I’m considering now is using Timer B to regularly poll the button and debounce it in software when needed. The microcontroller is running at 250kHz to begin with, to that’s plenty of time to check for a button press. With the /1024 prescaler, that still ends up at 244.140625Hz. That’s plenty of time to check for a button press, though I will need to implement around a 50ms delay to hold off the debouncing (according to my reading).

Pomodoro r2 Timer/Counter Interrupt Figured Out

I was struggling a bit with getting the timer of the ATtiny84 working correctly. After having set it up, setting a prescaler for the microchip as well as a prescaler for the timer itself, it still wouldn’t quite time to 1 second intervals as I thought it should have. It certainly was timing something, as my countdown did display, and the prescalers were working, because changing those changed the timing of the countdown, but still it didn’t turn out to be 1 second per interval. It took a lot of reading through the datasheet to solve this issue.

So, specifically, my timer ran just a little slower than 1 second. I took a stopwatch app on my phone and timed out 20 intervals (i.e. LED changes), and found that it ended up being 17% slow. Not a staggering amount, but counting for that over 25 minutes it would end up being over a minute slow per pomodoro count. Given that my current firmware somewhat skips over the first count, it would still end up okay, but that’s just sloppy programming!

The solution to my problem lay in reviewing step-by-step the process of the timer as described in the datasheet. Reading though the Timer/Counter Interrupt Mask Register 1 section explained what the Timer/Counter1 Control Register A did, which helped me relate the Timer/Counter Register to the Output Compare Register A. As you can imagine, it was a lot of juggling of registers and bits. However, going through that step-by-step helped me track down my issue. As it turns out, the Compare Match A Interrupts (OCIE0A in register TIMSK0) was dependent on the bit setting of WGM01 in register TCCR0A. In other words, I had set everything up to compare the timer to the value I’d set, except for the actual register that tells the chip to make that comparison. No wonder it didn’t work!

Reading up on the datasheet also explained why I got the exact mistimed count that I did. Without setting WGM01 in TCCR0A, the timer is in “normal” mode, where it doesn’t compare but just checks to see if its in overflow. Overflow is defined as maxing out the register at oxFF in hexadecimal, or count 256 in decimal numbers. I’d set up the prescalers so that the timer was just over a second for a full count (so 256 cycles took 1.045 seconds), which is why I needed to compare it not to 255 but to 243 cycles: 8,000,000Mhz / 32 (prescaler) = 250,000 cycles/sec. 250,000/1024 (timer prescaler) = 244.14 cycles/sec. However, we start counting at 0, so it’s a count of 243 that’s almost exactly one second. As a result, waiting for the overflow rather than the compare made my timer slow.

This leaves me with one last thing to figure out: the pause button. Last time, I mentioned that buttons are, apparently, usually polled instead of checked via interrupt. Furthermore, they are usually debounced in firmware rather than hardware. After reading more, I now know the reason for the latter. Even though the components needed for debouncing are quite cheap (we’re literally talking a couple of cents here), production rules are usually made by large companies who produce tens of thousands of boards per product. So, an addition of even a few components of a couple of cents still add up to a hefty cost when multiplied by thousands to millions of components. On top of this, each component added adds a production step, as they will need to be mounted to the board, again leading to higher costs. Firmware, on the other hand, is programmed once (hence only paid for once), and can be copied indefinitely. In my case, this just doesn’t apply, so why not hardware debounce if that meets my needs?

The other problem lies with checking the functions. In my original design, a short press pauses, but a long press reset a timer. I did that using the millis() function in Arduino, which I now realize was just a timer used to count milliseconds. However, that also involves polling that at a regular interval, whereas my goal was to have the microchip sleep most of the time to save on energy. I’ll have to figure out how to approach this. I’ve read two completely opposite points of view on this: a chip can be set to work slowly, sleeping most of the time to save as much energy in sleep states; alternatively, the chip can be set at a high frequency, so when it is awake, it does whatever it needs to as quickly as it can, so it can return to sleep as quickly as it can. Right now, I don’t know what’s best, but it’ll be fun to figure that out.

Pomodoro r2 Progress

With my ATtiny84 successfully rescued, I set to work to rewriting my Pomodoro program (is it officially firmware if it’s software for an embedded chip?) to make use of timers, as I had intended to do way back when. The goal was to reduce the power consumption of the chip by having it mostly be in sleep mode, and only occassionally turn the chip on to update LEDs (essentially, every second). With everything set up on a breadboard, I went to programming it on my desktop, to see if I could easily translate my original program from Arduino to fully C.

It was an interesting endeavor that was easier to do than I had expected it to be. I guess I picked up enough from Assembly and some C programming material to be relatively comfortable with programming the chip. It also involved a lot of datasheet referencing, as I needed to make sure to find the right registers on the chip to set prescaling and enable interrupts. Basically, I need the chip to run at a specific frequency, so that one of its timers takes exactly one second to overflow (reach its maximum count and reset to 0). Once that’s done, I could have the chip asleep except for when a second had passed (when that timer overflowed), and then quickly have it update the LEDs. For the testing of it all, it was fine to have it count per second (in fact, I clocked the chip so that it would overflow every 250ms to make it easier to see each step of the program as a whole). In the end, I’ll use a variable to check whether 60 seconds have passed, and then update the LEDs.

Most of the translation from Arduino to C was pretty easy to accomplish. Essentially, Arduino is just C with some pre-defined libraries to make it much easier to program Arduino chips. As a result, translating it over just involves finding alternatives for what Arduino had predefined. However, I did run into an interesting issue that will have me redesign the hardware a little.

Originally, my intention was to use the watchdog timer (WDT) so track the time. The watchdog timer, apparently, is designed to be used pretty much exactly for this purposes: to regularly time certain things. It doesn’t have any compare features or settings, it just overflows and lets you know when that’s happened. The datasheet as well indicated a setting that would have it overflow at 1s intervals, so, that sounds perfect, right? As it turns out, watchdog timers are notoriously imprecise. For the ATtiny84, it runs on a separate 128kHz oscillator, and when I prescaled it to the right setting, it was about 1s per overflow. That’s fine and dandy if it doesn’t matter much, but with it running slow as it did, it would accrue quite some delay across a full pomodoro, to the point of several minutes. Apparently, while it’s used for regular actions, it’s not intended to be used as an actual clock source in the sense of precise time measurement.

So, I had to retool that idea, and switch to the timer interrupt. After some initial foibles in trying to get it to work correctly, I found it almost exactly timed to 1s intervals, with a negligable deviation – about as reasonably accurate as I would want. With that solved, the rest of the reprogramming was hardly any issue at all.

Until, at least, the pause button came into view. Here, I have two problems, one of which may force me to retool things quite a bit. Firstly, I ran into the issue that the button has quite some bounce to it. That is to say, when we press it, in the timescale of our awareness, we may press it just the once; however, given that the microchip works far, far swifter than human reaction speed, it actually notices that the button is pressed and depressed several times just by the vibration of us pressing it down – i.e., it bounces. While it’s possible to debounce a switch via hardware, it’s more common to do it via software these days. The thing is, the Arduino, apparently, did this for me already; or, at least, I didn’t notice this issue in the previous build. So, I’ll have to figure out how to properly do this.

My second issue is somewhat related to the first. The interrupt I used was for pin PA6, on which I had the button there. It was a pin change interrupt, meaning that any time the pin changed from any state, the interrupt would trigger. So, pressing the button actually caused two interrupts to happen: pressing as well as depressing. That, of course, defeats the purpose of a pause button – it’d only pause while I was holding down the pin! I discovered that there is a dedicated pin for the kind of hardware interrupt I wanted (external), PB2 for the ATtiny84, but then I’d have to move quite a few things around (PORTB is where I had the three pomodoro LEDs). Nevertheless, pin PB2 allowed for a configurable hardware interrupt: either change, falling, rising, or low-level. That would at least allow me to reduce the problem of getting two interrupts for one press.

I’m not too sure yet if switching that around is the best solution, however. A quick glance online to solve my bouncing issue also showed me that most people recommend against using an external interrupt for a button press check. Firstly, for the bouncing issue, but secondly because triggering an interrupt also causes complications for registering what buttons do (apparently?). The recommended solution is what’s calling polling the button: regularly checking whether or not it’s pressed. It’s actually what I did in the original program as well, and may explain why I didn’t have the same issues there. I’m not sure how this will work out, though, as my intention was to have the microchip sleep most of the time and only activate about once per second. I’m concerned that if I poll the button only that once per second, I might end up making it non-responsive; after all, I could be pressing the button just inbetween two second counts.

I’m not too sure what to do about it yet, but it’s good that this is my major issue with the build so far, and that everything else has gone quite smoothly.