Exploring ESP32

I recently got three ESP-WROOM-32 Dev Boards in from AliExpress, in anticipation of my next electronics project. A few months back, we built our Syrian hamster a large cage, based on a video by ErinsAnimals (see below for the tutorial we followed).

ErinsAnimals video tutorial on how to build a three-tiered hamster cage, which we built for our Syrian hamster Latte.

Now, this cage is amazing. Before this, we had a terrily small cage for the hamster, which meant she showed all manner of bad behavior. She was stressed and dissatisfied, and needed larger living space. When we moved apartments, we also wanted to give her a more fitting place to live. The cage is amazing, but due due its size, it also blocks quite some light inside. Tracy thought it’d be a cool idea if we could install some LED lighting inside. At its simplest, it is just for us to have light inside to ease cleaning. Potentially, however, we could use RGB lights to even simulate a day/night-cycle for Latte. She gets some from the natural light in our room, of course, but because the cage is built out of wood pieces, it also blocks a lot of light.

So, the lighting part is for me to solve. I figured to have a look at ESP32 uC to see if that can help me solve this problem. It has WiFi capabilities, which would mean I could somehow figure out how to control the lights from our mobile phones, or have it check the time or perhaps lighting values, or something along those lines. I bought three of these from AliExpress, to give me the most flexibility. If I end up with the most expensive solution, I’ll wire up each section of the cage individually; however, it should be quite possible to control the entire cage with just one controller (though Tracy does not want any wires available for Latte to nibble on).

My first challenge will be to figure out how I can program this thing. I see online that there are options to use the Arduino IDE to program the thing, which is likely to be the easiest route. Apparently, the microUSB connector on the board allows me to communicate with it via UART. I also noticed that the board has some familiar pin functions (MISO, MOSI, SCLK), which seem familiar to how I used AVRDUDE to program the ATtiny. However, AVRDUDE is focused on the AVR uC family, so I don’t quite know yet how to approach this. So, step one is learning how to communicate with this board. Step two will be getting a standard blinky example working (Ahh, blink, the “Hello, world!” of the electronics hobby). I look forward to learning more!

I use Arch, BTW

This week was a holiday for me, fortunately. Technically, my work doesn’t offer standard holidays, except for the usual summer break in university education. However, after the merger with another local university, our new colleagues brought with them a lovely cultural shift: the assumption that the education-free weeks are holidays. So many of them take this as just a right, that our employer has basically given up and accepted this is a holiday week for educational staff. Part of that, I suspect, is the fact that 1 in 5 employees in education suffers from some sort of burn-out, according to the Dutch national statistics centre, CBS (at the top of that first graph, “Onderwijs” means “Education”). I imagine that this certain lax attitude towards the enforcement of certain policies is just considered risk management – the potential damage of formally enforcing this as not being a holiday would likely outweigh the financial benefits of having teaching staff available during this week.

So, I finally had some time and energy on my hands to do some things I’d been looking forward to for a while. One of which was to transfer my desktop PC over to Arch from Manjaro Linux. I’d originally kept my main PC on Manjaro based on the idea that I wanted a PC that just worked without much fuss, and assumed that personally maintaining Arch would cause more issues than having a more curated OS. Ironically, over time, my Manjaro-based desktop ended up having issues more often than my Arch-based laptop. Every so often, an update to Manjaro would prevent me from logging in to the X Server (an update to NVidia drivers would end up conflicting with lightdm-slick-greeter, or reset a configuration file), and I’d be left fixing that. Alternatively, I’d set things up exactly the way I wanted to on my laptop, and when I’d go back to using my desktop, I realized that it had a different setting or program that I did not prefer at all. So, with some more time on my hands, it was time for a change.

As I’d written before, I’ve installed Arch Linux a number of times over the past years, so the installation itself wasn’t that much of a problem. I was, of course, irrationally worried that I’d irreparably mess something up but that’s just usual nerves; the reality is that very little in Linux is irreparable. In fact, the process was surprisingly smooth and easy. Particularly given how Linux separates out files in its system hierarchy, it was incredibly easy to change the OS and still keep my old files and even installed games. So, now I finally fully run Arch Linux as a main driver, and I’m happily configuring and customizing when I want and as I see fit.

Pomodoro r2 – Update 5

I figured that my design was pretty much as done as I could make it, so I posted it on /r/PrintedCircuitBoard to see about getting some feedback. As always, the electronics subreddits tend to be quite wholesome and education, and full of supportive people willing to help out. Thankfully, they gave me a lot of good feedback, as you can see below:

The Reddit thread where I got my advice

I was happy to learn that KiCAD automatically takes thermal relief for pads into account, as before this thread I had no idea what this was. The other major thing I learned was that there is no reason not to increase trace thickness if you can. And, finally, I learned that there was such a thing as a decoupling capacitor to smoothe out power delivery to a microcontroller, and so I added one (and after advice moved it closed to the microcontroller). That all resulted in a slightly changed design. Furthermore, I solved my issue with the footprints by simply taking a digikey footprint directly from a component I am intending to buy, so that the problem solves itself. I am very excited to come to a close to this project, and seeing it in action!

An update of the board based on feedback from Reddit.

FreeCAD Modelling

So, today, I made my first thing in FreeCAD. When I was testing out some footprints and components for the Pomodoro Timer PCB, I noticed that none were exactly the type of buzzer that I had. Seeing as how my buzzer is pretty much a simple cylinder, I figured it was the perfect object to try and model in FreeCAD. In the end, I’d end up both with a working 3D model to use in KiCAD, as well as some basic experience with FreeCAD.

After quite some fiddling to get things working, and some initial experiments, I finally produced the part in 3D with exact measurements:

A FreeCAD model of the buzzer that I use

Importing that into KiCAD was actually super easy. There was literally a button to just locate any type of .step file and import it as the 3D model for a part that I had selected. So, happily, I put that part on my board. And, to my surprise, it unveiled a hidden error:

The pins didn’t fit!

When I checked the fit of the part, I could see that the actual pins didn’t fit! That sure would have been an issue had I ordered the PCB! I measured twice, and then another time; I checked my measurements in FreeCAD, and everything worked out well. The only outcome could be that the footprint in KiCAD wasn’t correct. Good thing to catch at this stage.

Pomodoro r2 – Update 4

So, I’ve reworked the PCB into what I expect to be the final revision. I eventually decided to add the coin cell battery holder on the PCB itself after all, because it would be a little fiddly to add a holder for two AAs on the back. I’d have to either mess around with glueing it on the back (and making sure that the PCB matches the size), or figure out some kind of screw mounting. Since I don’t have a proper glue gun yet and project box making is something I still have to learn, I figured this was a decent enough solution after all on the level that I’m currently at.

The PCB with components added. Apparently, there’s still no buzzer 3D image, despite it just being a squat cylinder.

As you can see above, the result of adding the battery holder is that the entire PCB is now a little wider and less high, as I shuffled components around slightly. Another thing I noticed was that the pins of the ISP had no significant marking for orientation. I had a look at how it was marked on my USB programmer and noticed that this was done on the back (probably to save space), and that seemed like a good practice to follow. All in all, I’m quite pleased with this final design. Before I do go ahead and order it, I do want to test it out on a breadboard; after all, you never know when you’ve made some silly design error.

So, next step will be to order the components. While waiting for them to arrive, I can rewrite the code already to fit the ATtiny84, so that I can test it as soon as everything is in.

Pomodoro r2 – Update 3

I had a quick look at the schematic I made, and spotted a quick mistake there. I had tied the buzzer to the reset line, as I figured that pin would only be used when reprogramming the ATtiny84. However, I neglected to notice that the pin is an active-low pin, meaning that it resets when the signal is low; as a result, the pin has to be tied high – i.e. the buzzer would be on a constant high line. Whoops! So, that was an easy fix, fortunately.

A circuit schematic for the Pomodoro timer, showing an ATtiny84 linked to a number of LEDs, an ISP programmer, and a buzzer. The schematic indicates the whole set is powered by a 3-volt battery.
Figure 1: A slight adjustment to the schematic

I don’t have an ATtiny84 yet, but I’ve been testing the interrupts with an ATtiny13. It turns out that there’s a Watchdog function, which is quite easy to implement. I read through a good post on low-power mode for the ATtiny13 which explained it quite well. That post is the third in a series of three, of which the second one also nicely explains timers in general. As it turns out, trying to program it in low-power mode won’t really matter that much for my project.

The basic idea is that the timer is a separate structure within the microchip, that keeps timing regardless of whether the code runs. That’s why it can interrupt the code at any point, freeze it, do its Interrupt Service Routine, and get back to the code. It’s a great way to have a microchip respond to a button input no matter what it’s going, or to have a chip go into low-power sleep mode until it has to do its job (for example, taking a temperature measurement once per hour). The timers work on a microprocessor-level of speed, so we’re talking mHz here; consequently, most interrupts I’ve seen are in the order of seconds. Though my circuit only cares about minutes, I’m going to have to default to waking the chip up every second for a countdown. Still, though, that must save some power, right? Well, yes and no. It saves some energy on that low-power state microchip. And in the meantime, there will be a handful of LEDs on almost constantly – the power usage of the microchip pales in comparison.

Nevertheless, I’m going to reprogram the code to use the timers, and downclock the microchip. Not particularly because it will generate a massive powersave, but because I want to learn and this is quite a simple project to test this out on. Plus, any little bit helps, right? While at this point I could reconsider my choice of LEDs over an LCD screen (considering the LEDs are a big power drain anyway), I don’t think I will. I want to finish the project, and if I keep revising it, it may end up never being done. So, with that in mind, I started testing KiCAD’s PCB builder.

While the interface is somewhat arcane – there’s many options, shortcuts, jargon-filled terms, and so on – the process is actually quite simple. Mostly just a case of dragging a component from place to place, and then clicking along a path to put connections in. After some fiddling, I was easily done. On top of that, I saw that there was a 3D viewer built-in – score! So, this is my current version:

You can see that there was no 3D image for the buzzer, but otherwise I’m quite pleased. I took pin headers as a placeholder for the small putton and switch that I’ll be using in the bottom right. On the left, there’s two pin headers that I used as a placeholder for the battery. My main problem is still that I want a rechargeable solution for power – I just don’t feel like throwing away coin cell after coin cell. So, I figured, this way, for now, I can at least hook up whatever battery solution I end up with. If I don’t install it on the board directly, I might actually just include two notches on the sides of the board for me to slide in a rubber band and hook some battery back on the back.

Pomodoro r2 – Update 2

I’ve reworked the schematic to include the ATtiny84, and decided to just put a switch in there for the audio. After all, it either needs to attract your attention, or it doesn’t. There’s little sense in dimming it. If needed, I can always finagle a resistor in there during prototyping to check.

A circuit diagram showing the schematic for the second revision of the Pomodoro timer. It is a tangle of wires and components.
Figure 1: Pomodoro Timer, Rev 2.

I’m not particularly happy with how many lines cross in this schematic, but overall I still think it’s fairly legible. This time, I made sure to include a good footprint for each component in KiCad as well. I hope that’ll help me construct a good PCB later on, if I choose to do so. The one component I was struggling with a bit was the battery. I want to include it on the back somehow, but I’m not sure how. I’m pretty sure I can’t just glue it to the back (I mean, can’t I?), so I’m still thinking what to do about that.

Either way, it’ll be time to order some components soon for this build. In the meantime, I can look to adjusting the programming.

Pomodoro r2 – Update 1

Today, I did some research on my Pomodoro revision 2 specifications, and have come to some valuable conclusions. The main one being that my idea to control the brightness of all the LEDs via PWM, sadly, won’t work. Apparently, to use PWM with timer interrupts on an AVR, you need to use dedicated output pins to do so. When exploring the possible μCs that I could use to rework the Pomodoro timer, I settled on the ATtiny84. That μC has just enough pins, belongs to the AVR family, so my program will need minimal adjustment, and I have a fairly good idea on how to downclock it to save power. However, it only has four possible pins to use for PWM, as you can see below.

A schematic showing the pinouts of the ATtiny 24/44/84 family of microcontrollers. Each pin has an overview of all its functions next to it.
Figure 1: The pin-out schematic for the ATtiny84

Now, to be fair, I don’t even know exactly if all four can be used equally for single PWM signals, or if they need do be used in pairs. Regardless, even if they could all be used, that would still leave me one short even if I just wanted to adjust only the timing LEDs. So, easily said, I’ll scrap that off my list; it was an optional feature in any case. That makes for the second feature to be scrapped (I already concluded that the LCD screen would raise my voltage requirements).

I’ve also reconsidered my choice of the coin cell battery, opting instead for two rechargeable batteries. Firstly, I want to move towards more rechargeable power in any case (sustainability is important to me), and this offers me an easy way to do that without immediately having to learn about USB charging in a project. While I want to learn about that, it seems a little overkill for this project. Plus, I figure that including the battery holder on the back of the board somehow may actually provide it with something of a stand.

My first experiments with the volume control for the beeper were successful, but not particularly satisfying. Using a potentiometer, I could adjust the volume; however, it took so little resistance for the beeper to mute, that most of the potentiometer was wasted. I’ll have to test out a range of resistance values to see what makes a relevant value of potentiometer to use. If I can’t find a satisfactory value, I may also just use a switch to make a mute button. I mean, it’s either there to attract your attention, or it isn’t, right?

That leads to the following update to the feature list:

  • Include a 3v coin cell battery; and
  • Include 2 1.5v rechargeable batteries; and
  • Rewrite the program to run off a type of ATtiny an ATtiny84; and
  • Rework the program to use timer interrupts.
  • Change the LEDs to a single LCD screen; and
  • Add a volume control for the beeper; and
  • Add a brightness control for the lights.

Pomodoro r2

I didn’t quite feel settled with my current Pomodoro project. I’d worked up the prototype, and I’m happy it works (despite it being sloppy), but I also think there were several points for improvement left. Or, at the very least, it just didn’t feel done. I figure that the minimal specification to call it a working prototype is to have a battery included, so that it is fully self-sufficient, rather than it is now (which requires either hooking up a battery ad-hoc, or connecting it to USB via the ISP programmer). As I was brainstorming what I wanted to do with it, I came up with the following list:

  • Include a 3v coin cell battery; and
  • Rewrite the program to run off a type of ATtiny; and
  • Rework the program to use timer interrupts.

Now, I thought before of changing the μC around, but at the time, I wasn’t really sure of the what and how. Thankfully, thanks to some helpful YouTube videos, now I do, and it seems reasonable to rework the schematic to not waste the full potential of an ATMega328p on a program which needs about half of the pins. A major thing I learned from the Assembly tutorial is that you can drastically reduce power consumption by working with timer interrupts rather than using a sleep function. Considering I want the project to become more portable, getting the most out of the 3V cell seems like a great idea.

As I was thinking of those, I thought of a few other options that might be interesting. I separated these, however, because the ones in the first list are what I’d consider necessary to call the project done, these would be interesting additional features to add:

  • Change the LEDs to a single LCD screen; and
  • Add a volume control for the beeper; and
  • Add a brightness control for the lights.

The first would be cool, though I’m not sure if it will fit the project. The major issue with it is that a very cursory glance of LCD screens seems to imply that they need a 5V power source, and my intention is to keep the project small, light, and to get as much as I can out of the LEDs. While I want to get an LCD screen and play around to learn about I2C, that may be a thing for a later project.

The other two, however, shouldn’t be too difficult. The beeper I have on there is quite loud, which is good, but I can imagine there’s occasions where I’d want a more subtle notification (plus, my wife will be grateful for less noise too). I could either just install a slide switch to turn it off or on, or perhaps I can put in a potentiometer for more fine-tuned control. The latter will take some experimentation, which will be fun in and of itself.

The brightness control is something that I’d also want to experiment with. Clearly, having a potentiometer for each individual LED would be needlessly complex, let alone that it would result in inconsistent brightness of LEDs. Rather, I would want to handle that directly from the μC. Now, I’ve been reading a bit about PWM signals, and that would seem to fit the bill. Given that my project uses 11 pins (9 LEDs, a buzzer, and a button), adding power and ground, means I have to use a DIP-14 package; i.e. there would be one pin open. What I could explore is if I can use a potentiometer there to control the μC PWM duty cycle. Not only would that mean I can control the brightness, but unlike using resistors to do so, this method would actually also save power and match my original goal of having a low-powered portable device.

I know nothing about PWM aside from the broad concept, so that would be an interesting thing to learn about. That would mean that revising this project would teach me about both timer interrupts and PWM signals – score! On top of that, I do enjoy how that would make the control of the device consistent: a single push button to control pauses and resets, and two potentiometers to control the amplitude of the output (whether soundwaves or lightwaves).

If I only manage to add the battery and have it at that, I think I’ll leave it as a perfboard prototype. If I do the other points as well, I think I’ll see about designing it as a PCB, and having it manufactured somewhere to get a final product. That’d be bonus points for practicing PCB design and soldering!

Headphone Repair Incoming?

Quite some time back, my pair of ATH-M50x’s broke down, and I had resigned myself to buying a new pair of headphones. That’s been an agonizing struggle, since this pair has lasted me for quite a few years; so, naturally, I’m assuming (demanding?) that the next pair I buy should last me another decade or so. So, for weeks now, I’ve been going back and forth over several types, and causing Tracy quite some grief as I want to talk out the minutiae of things she has absolutely no interest in.

This morning, I had the spontaneous idea to open the headphones up and have a peek inside. After all, they were already broken – what could it really hurt? So, I carefully start opening it up, and taking my multimeter to it. I deduce that the cable is actually fine and so are the wires inside the headset. In fact, the only fault I can find is in the right speaker. A foolish idea dawns on me. Could I just repair this headset on my own? A quick browse on Aliexpress shows me that I could get a replacement audio driver for about €16. Sure, it won’t be the Audio-Technica brand driver but it’s 45mm with 35Ohm impedance (well, that’s what it’s advertised as – this is Aliexpress we’re talking about), which is exactly what the headset uses.

We’re talking a difference between €16 and ~€200 here; even if I can’t manage to fix the headset, the cost/benefit of giving it a try is absolutely worth it. Particularly if I can get another couple of years out of the thing. So, perhaps in a month or so (that’s when the package should be arriving), I might be writing about a successful repair. Or at least an interesting failure.