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.

Finally Learned to Make Solder Bridges

Yesterday, I tried my hand at soldering a new prototype HV programmer, with much success. After watching some YouTube videos on soldering, I had a strong theory on what may have been my problem in making solder bridges: I was using a rather wide tip at a high temperature, which resulted in spreading too much heat around. That’s why I kept running into issues where the surface tension kept working against me. I read a tip that lowering the iron’s heat to about 300C (some even suggested as low as 250C) would help a lot on making bridges. On top of that, I switched to my smallest tip to help reduce the heat transfer. Those two changes combined now allowed me to add some solder to existing connections without melting too much.

Figure 1: An intermediate soldering bridge

Above you can see the first tryout of making solder bridges. As you can see, some are better than others. The line on the left is quite sloppy, but still effective. I’m much more pleased with that triple row of solder bridges in the middle, for instance. Nevertheless, as I was soldering the set, I would use my multimeter to check the connection as soon as I had finished a line.

In the end, I was quite pleased with the final product. It doesn’t look as clean as I would like, but it looks neat, at least. It’s also a great first attempt at doing this properly. This is something I can build on, and I feel quite proud of myself.

Figure 4: The topside of the finished product.

The topside of the board looks quite neat, now that most of the connections are solder bridges on the underside. Apart from learning to make those solder bridges, I also improved on my method of laying jumper wires on top of the board. Partly thanks to my new wire stripper, and partly due to being a little less parsimonious, I ended up with exact straight wires. Before, I tried to cut them perfectly to size to start with. Now, rather, I strip more than I’ll need from one end, cut the insulation exactly to size, and then use a wire cutter to get the jumper. This way, I use a little more copper wire, but it’s also far easier to cut to exact size by just trimming the excess leads. There are only two things I’m less happy about: firstly, the resistor on the top-left is not flush with the board. While trying to solder it down, it slipped and I just couldn’t easily get it back down. Secondly, the LM7808 is slightly askew. It works fine, but it’s just a little sloppy.

Figure 5: A comparison of the first prototype to the second.

Clearly, when comparing the first to the second prototype, the second is much cleaner by far. For one, of course, it has fewer components, so it’s easier to look less cluttered. Secondly, though, just not having that mess of wires makes all the difference.

Now, the big downside is that I haven’t seen it confirmed to work yet. From what I can see, all the connections should have been correct. So, to troubleshoot, tomorrow I’ll first have to compare my schematic to the original version to see if I made a mistake there. Secondly, I’ll have to one-by-one check my connections to the schematic. After that, I’ll check the voltages and continuity on each connection with my multimeter to see what’s happening. If that doesn’t give me any answers, I’ll have to use my logic analyzer to see what’s happening when I press the button. (EDIT: while I previewed this post after drafting, I noticed what is the most likely issue. Pin 4 on the master IC is not connected to the ground bus – the long vertical line. Comparison the soldering job to the schematic shows this quite clearly).

However, even if it doesn’t end up working, I really am proud of the neatness of the solder job. I felt so much more comfortable doing that, and it was incredibly enjoyable to do now that it was working well. I’m sure that with more practice, I’ll get those lines looking neater and neater as time goes by.

Revising the HV Programmer

A key way I try to solve problems in general is to see where and how they can be simplified (I guess that must be a leftover from highschool math classes). After all, the fewer moving parts, the less that can go wrong. On top of that, if you keep building on a smaller thing that works and test it incrementally, you can tell when things start going wrong, which leads to a much narrower problem to solve. In the case of the HV programmer, that firstly meant to remove the secondary header. I only need to reprogram a 14-pin IC right now in any case, and I’d much rather have a working HV programmer for that, than a general one for a future use case that I don’t know about yet.

A quick retooling in KiCad leads me to the following schematic:

Figure 1: A renewed and simplified schematic

Now, ideally, if I wanted to be very specific about how I make schematics, I would much rather have the master IC to the left of the target IC, so that my input pins are always on the left and the output pins are always on the right. Ideally, I want power to run from top to bottom in a schematic, and the signal to run left to right. It just makes things easier to read for me. However, this is supposed to be a quick tool that helps me do another thing that I’d like to do, so I’m not going to polish this up too much. I’ll work on KiCad library management some other day.

Fortunately, the simplified schematic leads to a far simpler perfboard design with fewer connections:

Figure 2: The resulting design for the perfboard. Once more, a lot of solder lines on the underside

As you can see, I still chose to keep a lot of solder lines in there rather than jumper wires. For one, I think that’s something of a guideline to begin with, but secondly I also just want to learn how to do that properly. The only way to learn is to keep on trying, so I may as well start here. This time, though, I think I may want to try out soldering the lines first and only adding the components later. That’ll allow me to mess up more and throw the board away if I really ruin it. The most I can lose is some perfboard and solder, at that point.

ATtiny84 Succesfully Rescued!

Success! The HV programmer worked like a charm! For only about three Euro of additional components I threw together the basic design, replacing components where necessary (my local shop doesn’t sell microchips, as online stores has made that highly impractical for the owner). The biggest thing missing, though, was a DC jack that could be mounted on the perfboard. so, I’ll have to fumble some solution to work for my setup.

In any case, a quick upload to the ATtiny13 I’m using as HV programmer, and a quick reset of the ATtiny84 later, and the reset disable fuse is reset again! It felt amazing building my own tool to repair an issue I ran into, even if I did essentially assemble somebody else’s work.

I set to work retooling it to put on perfboard, as I’m sure this won’t be the last time fuses get screwed up. Instead of making separate reprogrammers per 8 or 14-pin chip, I figured to combine the two in one:

Figure 1: the schematic for the combined reprogrammer.

I then used KiCAD PCBNEW setup at a grid of 2.54mm with 1mm trace width to plan out my perfboard:

Figure 2: The perfboard layout made in PCBNew.

The green lines denote the back of the perfboard, and my intention is to have those be solder lines, where the red lines are jumpers on the top of the board. I’m curious to see whether that one near the LED will interfere with it too much. I’ll be testing a method to guide my solder bridges on the back using a stripped copper wire as a guide. I hope to give it a good test tomorrow to see how it works out.

Possiblity to Rescue ATtiny84?

After some searching online, I managed to find a blog post where somebody built an HV programmer to fix pretty much exactly the issue that I’ve had as well. While programming their AVR chips through a USBTiny, they accidentally set the reset disable fuse, locking themselves out of the AVR programming. They point out exactly the frustrating part of that: the microchip is perfectly fine – it absolutely works, and could be used still. It’s just that SPI programming is unavailable. Now, the post is from 2008, so the claim that there are few to no HV programmers are available might be quite outdated (I hope so, at least). I’ll first try to find a cheap programmer, but at least I now have an alternative available as well.

EDIT: In fact, I’ve found another blog post with an even easier solution. That looks like one I’ll put on a bit of perfboard, as I doubt this will be the last time I run into this problem.

First Time Working with RGB

I did some research on the upcoming challenge of making a lighting system for the hamster cage. I have to admit it was a little bit intimidating, and part of me almost wanted to avoid the challenge. There’ll be a few new elements to this: firstly, I’ve never worked with RGB LEDs before; secondly, I’ve only once actually put a project in a project box, and I wasn’t happy with the results there; thirdly, this will be something I’ll end up plugging into a socket; and, lastly, it’ll be something that needs to be used via Wi-Fi and Android phones. That’s a lot of new things all at once. Part of me wanted to chicken out and buy some pre-made thing that could only do part of what we wanted it to do.

Tracy’s preferred solution for the hamster cage is to have consistent lighting that will mimic some sort of circadian rhythm for the (future) hamster. The cage we built is rather large, and because it’s made of wood it’s also quite dark. On top of that, we’ve put it in a corner away from the windows, which makes it even darker. So, she would like to have a lighting system that mimics daylight in a way, both in color and intensity. However, it will also need to be able to be overriden manually, so that we can put it on a bright white light in case we need to check inside the cage or clean it.

I’ve been trying to do some initial research and discovered that authentic daylight imitation is quite complex, even when simplified. Now, firstly, I’m not intending to mimic actual sunlight here, so I’m already side-stepping issues of infrared and ultraviolet, and the other qualities that actual sunlight has. I’m not looking to grow crops or to take care of fish, so that’s going too far. Even when just trying to imitate the color, however, there’s a deep rabbithole of color temperatures, color perception, white balances, and so on. The minimum we really need is just to have light differ over a 24-hour period. I think I’ll see if I can play a bit with making the light blueish or greenish at night, reddish at dusk, and white at noon.

This will certainly be the biggest electronics challenge I’m tackling to date. It’s scary and exciting at the same time. So, right now, I’m looking at the following rough specifications:

  • The light should illumate the three compartments of the hamster cage
  • The light should be automatically set
  • It should be possible to manually override the light
  • The light should be powered from a socket
  • The light should simulate a day/night rhythm in intensity
  • The light should simulate a day/night rhythm through color
  • The fixtures and cabling should be neatly tucked away
  • The light should be controlled from a distance

We’ll see where we end up with the project.

ATTiny84 Issue Figured Out

I’m so glad I bought a logic analyzer a while back. It’s made figuring out the issue I was having so much easier. As I wrote the other day, my ATTiny84 no longer responded to AVRDude. I checked by programmer by uploading a basic blink test to an ATTiny13, and confirmed that the programmer itself was fine. I double-checked connections, and they are all set up. So, it was time to hook up the logic analyzer to see what was going on.

Figure 1: Standard AVRDude AVR programing initialization (the unexpected bytes are common for my setup, and I have no idea why).

I hooked up my logic analyzer to the breadboard setup to check what the ISP programming looks like and what’s happening. Using PulseView, I got the result above. The decoder tells me that the signals being sent are the standard programming enabling command, so I know that the USB programmer is sending the usual commands. Whenever I’ve used the logic analyzer, I’ve always had those unexpected bytes in the reply. I’m not sure why they show up, but I’m sure it’ll have something to do with me not setting things up correctly. Either way, I got those with a succesfull programming sequences as well, so I’m not too worried.

Figure 2: silence on the wire

It’s after the programming enable message that the interesting thing happens; or, more specifically, doesn’t happen. The reset pin gets a high signal, to ready the ATTiny84 for programming, followed by nothing. The LED being powered by the chip doesn’t even turn off as I’d expect it to do when the chip fully resets. This leads me to conclude that the reset pin just isn’t responding. That would make sense, given the AVRDude error message:

avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

This is exactly what I’m seeing, as the programmer is trying to initialize, but it seems to be failing at the reset stage. I assume the programmer would expect some kind of acknowledgement from the chip. Now, the reset pin may not be triggered, but I certainly am at this point (sorry, I couldn’t resist): just before I had this problem, the fuses were changing for some reason. My next step, therefore, is checking the datasheet for fuse settings.

And there we have it: bit number 7 is RSTDISBL, and as the footnote lists, if it is programmed, only high-voltage serial programming will work. I recall the first fuse error message saying something about fuses being set to 0, which ends up programming the Fuse High Byte bit 7 to disable the reset pin. So, I’ve locked myself out of this chip. I’ll have to learn about high-voltage programming to see if it’s worth investing in a new thing to make that work, or whether it makes more sense to just get a new chip.