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.

International Waters is Released

A friend of mine, Capybarbarian, has just released his third adventure, called International Waters, for The Sprawl RPG. He was kind enough to run it for me and a few others in a playtest session, and it was a lot of fun.

Figure 1: The cover for International Waters – if you play The Sprawl, I can recommend it. If you like cyberpunk, I can recommend it. Heck, I can just recommend it outright!

It’s a cyberpunk adventure, in which your crew is hired to retrieve a person from a ship that’s been stranded somewhere due to corporate tomfoolery. When we played it, we chose a route of violence – I looked forward to seeing how Capybarbarian would deal with our crazy approach, and he GM’d it quite nicely. The end result for us was an action-packed module that had an enticing background – a setting that hinted at so much more behind it. That was with us doing our best to ignore the plot points, to stress his module and put it through the wringer. There’s a wonderfully intricate world that’s behind it all and, honestly, all of us wanted to replay it right after we finished to find out more about it.

As I’ve gotten used to, his work is thoroughly researched, with a lot of references to real-world events, cultures, and situations. I can thoroughly recommend you give it a try.

Capybarbarian’s three available modules can be found for sale here.

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!

Learning About Debugging

I was reading a Reddit post on how Guido van Rossum stated he wanted to make Python work faster when I came across a comment chain where somebody joked that you can make any program faster by using fewer print() statements. A reply quipped “How else am I supposed to debug my programs?”. I’m assuming it was a joke for them, but this is certainly a weakness on my part. Since I’m self-taught, I find myself using standards that make sense to me, but would be bad practice for a formally taught individual. In this case, that’s using the print() statement to help me debug by running the program and seeing what I end up with, tweaking that, running it again, and so on.

The Reddit thread includes a comment chain where somebody jokes about using fewer print() statements.

Fortunately, though, somebody in the replies provided a serious answer to the quip: debuggers and logging. Because I use Linux, I’ve gotten quite familiar with log files – any time something doesn’t work, you have to check a log file to see where the problem lies. Without log files, you’re utterly confused; with log files, you’re a quick Internet search away from your answer. However, I never applied logging in my own programs. Firstly, they’re often so small that they’re easy to review without a log file; secondly, I just didn’t know how. It’s still bad practice, though.

Fortunately, one person linked to a really solid explanation of how debuggers work from last year’s PyCon:

A video by Nina Zakharenko explaining debugging in Python

It was so enlightening to watch – she described exactly how I muck around debugging my programs, using print() statements to analyze my output, adjusting it, and so on. Clearly, my bad habit was a common amateur move that happened often enough for her to be motivated to tell people about this debugger. Not only does it look like a good habit to build, the way she explains it makes it just so easy that I don’t see why I never bothered to use it in the first place.

A little bit of experience

When I started this blog, I mainly did it as an outlet for my thoughts. I wanted to have a place to put my experiences, and since I’d started moving away from most social media, this was still a good place to send things out that weren’t specifically targeted at somebody (come to think of it, I do seem to write to somebody, even if that is an abstract idea of a somebody). However, when I posted about the last revision of the pomodoro timer yesterday, I started scrolling back to see what my earliest posts about it. What an experience to see the progress, not just in the design but also just in my ability to build things! Yesterday, I had the satisfaction of seeing a neatly completed product but, today, I have the joy of seeing the advancement in my own skills. A lovely little benefit to blogging.

In any case: have a look at the before-and-after yourself:

Just compare that to the second revision:

And to think there’s only really a few months between these versions!

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).

Calculators Have Come a Long Way

I recently purchased a Casio FX-82MS for future use in the exam for the Dutch amateur radio licensing (technically not a license, but let’s just use that word for the ease of writing). The exam involves some electronics calculations, and while most seem easy enough to do without a calculator (they all tend to be tidy powers of numbers, or neat fractions), it still seems like a good idea to have a tool around in case you need it.

I have to say, calculators have come such a long way even since when I was a kid. I remember in elementary school we had a relatively basic calculator that could do most average arithmetic that you needed. Near the end of high school, the TI-83 was released, which we needed for the advanced mathematics classes. It was mindblowing to have a calculator that could make graphs for you. Ironically, though, given the types of maths we did, it was usually more convenient to just visually verify what we already saw in the equations.

The FX-82MS now just has so many simple features that are small quality of life changes. It’s so much more conventient to work with fractions on this thing than it used to be. There’s more memory scrolling buttons than I’m used to, and an easier menu interface to change some basic settings, and so on. It seems like the advances have mainly been in UI, but what wonderful advances they are.

Edit: Of course, after having bought this one, I discover that there is an even cooler calculator on offer: the Casio FX-991EX, that even has built-in converter functions for binary, decimal, and hexadecimal. D’Oh!