Arduino Nano programming in 2023, obsolescence be damned

I’m working on a little PCB for a robotics competition. It is used by the competition volunteers to time races between competing robots. Cool!

The design is based on an Arduino Nano to keep things easy…. in theory. In practice, I couldn’t get a modern (or even outdated) version of the Arduino IDE to program this thing. It’s a common theme in the forums. Anyway, as a service to my future self and any other future selves, here is how I got it working, despite Arduino’s lack of care or interest in supporting their products:

  1. Abandon using the USB interface. I tried this on 3 operating systems & 3 versions of the Arduino IDE, I could not get it to work. According to legend, sometimes it may start working after a lot of wasted time. In these rare cases, nobody seems to know how they did it.
  2. Use an ISP programmer. Hopefully yours is not the Olimex avr-isp-mk2. This is what I have, and it is effectively not supported by Arduino since version 1.5.x
  3. For Linux users with the Olimex programmer:
    1. Download the source for avrdude (get version 6.4 from http://download.savannah.gnu.org/releases/avrdude/)
    2. Extract the source archive, enter the directory
    3. Apply this patch https://www.olimex.com/Products/AVR/Programmers/AVR-ISP-MK2/resources/endpointdetect_pass1.patch
      1. cd to avrdude[…] folder
      2. patch -p0 < endpointdetect_pass1.patch
    4. ./configure && make all
  4. I recommend using the legacy 1.8.x IDE from https://wiki-content.arduino.cc/en/software. Download that, extract the archive. Newer versions of the IDE seem to hang indefinitely on a vague loading screen.
  5. Applies to Olimex programmer: Find the avrdude executable included in the arduino archive. Replace it with your new compiled one
    1. find . -name ‘avrdude’
    2. it should be at hardware/tools/avr/bin
    3. use the ln command to link your compiled avrdude into this location. This replaces their older incompatible version with your newly patched binary
      1. ln -sf /path/to/your/src/avrdude/avrdude ./hardware/tools/avr/bin/avrdude
  6. You can now run ./arduino from the Arduino legacy archive – this was enough to get it working on my end
  7. In the Arduino IDE, upload the sketch by selecting your programmer from ‘Tools > Programmer’, and upload the sketch by using ‘Sketch > Upload using programmer’

Other things you may have to do on Linux systems: install a udev rule for the Olimex programmer, and add yourself to the appropriate group (probably dialout). See Olimex link below.

If you are on Windows with the Olimex interface – compiling will be different to some degree, but ultimately you still replace the avrdude executable to fix the issue.

If you are also stuck with the Olimex interface (why am I still using this thing??), there’s much more info here: https://www.olimex.com/forum/index.php?topic=5358.0

User Group Growth and COVID-19

I’m a lifelong learner and Linux user. I enjoy teaching as a way to learn things myself; this often leads me to volunteer positions with multiple local tech clubs. Most recently, I’ve become a director at the local UNIX user’s group.

MUUG provides Manitobans with a nearby open-source software mirror. Our $20/year membership fee helps offset the associated costs. The repo mirror and our monthly newsletter are both excellent services – but the main thing that members engage with is the community element of the in-person monthly meeting.

People come from every corner of the city, and from out of town – even from bordering North Dakota and Minnesota – to watch our presentations, eat some snacks, and network with fellow enthusiasts. We are a reasonably active club with some very bright and talented members – if you need to hash out a UNIX or Linux problem in or near Winnipeg, this is the place to come.

Due to COVID-19, we are unable to run our in-person meetups, and members were no longer getting the same value they once were. Membership renewals were starting to suffer; and without membership renewals, we can’t keep our repository servers running (not forever, anyway) – so how do we keep our members engaged in the middle of a global pandemic?

Our first step was to get a virtual meeting platform up and running. To that end, we installed our own Jitsi server with a gracious hosting donation from MERLIN; in fact, the first online presentation we offered was how to install your own Jitsi server. While I won’t say it’s been a perfect experience for every member, it has overall worked very well. We have seen record attendance numbers, as it is now easier to attend the meeting (after all, we do cater to people who like to hack on computers in their basements.)

The modern MUUG presentation, ca. 2021

This approach has been successful at engaging our existing members – but how do we attract new growth to offset members we have already lost? Historically, we have relied on word-of-mouth, people putting up posters in their workspace, meetup.com, and a basic social media presence. As one of the millennials on the board, it was my sworn duty to suggest we try our hand at social media advertising.

The first step – which social networks do UNIX and Linux nerds like to use most? …we have no idea. While we agreed Twitter may be the platform with the most enthusiasts, the Twitter users among us admitted to hardly ever engaging with ads on the platform. We reasoned that Facebook is as good a platform as any to start with, as we already use it to list our events.

With board buy-in and fertile advertising ground – what are we going to advertise, exactly? We could promote our website in general – but I think most UNIX nerds in Manitoba have already seen that. To deliver the most engagement with prospective members, we elected to advertise our next monthly meeting. We usually have a presentation component as well – so we brainstormed a topical learning event that people care about: “Open source solutions for remote work”. Very apropos for 2021. I provided presentations on Jitsi and wireguard VPN, while my co-director Alberto provided a presentation on Nextcloud and Collabora.

The board settled on a $100 budget, and we opted to run the ad for 2 weeks prior to the meeting. We were able to target multiple relevant demographics, all within the geography of our choice:

  • Interests: System administrator, DevOps, Computer engineering, Network administrator, Mac OS or Linux,
  • Behaviours: Small business owners
  • Employers: Computer science
  • Job title: Unix Systems Administrator 
  • Industry: IT and Technical Services

What were the results?

  • Our ad reached just over 4000 individuals
  • 42 people replied as “going” or “interested”
  • In the period of the ad running and the event itself, we received 5 new membership applications

I don’t recall a better-attended meeting. We had over 35 people in attendance – that’s big for us! We had many newcomers from smaller cities, and we had some excellent discussions during our opening roundtable. People were enjoying themselves. That’s a success in itself.

Do 5 new members sound like a lot? It’s not a huge amount, but it covers our ad expense in the first year alone. Many members stay on for at least 2 years – so I’d call that a great first attempt! We are choosing to wait a few months before running new ad campaigns so that we can judge their efficacy in relative isolation. This helps us cut costs, and ideally, we can figure out which platform gets us the most engagement.

Thank you to Alberto, Brad, and the rest of the MUUG board and membership for working together to keep our humble club a lively one.

Laptop Repair à la Backyard Dentistry

A friend of mine had purchased a nice Alienware laptop a number of years ago (an AW15R3), and it had some serious problems. He wanted help repairing it – and in fact, he had already done a great deal of diligence in tracking down problems and solutions. Here’s how we pulled a bad tooth out of a problematic laptop, so to speak, and restored it to its former glory!

Mikes beast of a laptop was now out of warranty; the laptop would power on to a black screen and get very hot. Mike got his hands on a thermal imaging camera and got to work analyzing the problem:

Well, there was clearly a problem. Unsurprisingly, it was in the power supply circuitry. You can see just how hot this thing was running:

Yikes!

Mike managed to source a schematic for the laptop (I have no idea how, I’ve never been so lucky!) and asked for my help troubleshooting the power section and repairing this unit. I had just received my hot-air rework gun, so this came with good timing!

After some brainstorming, we reasoned that the likeliest cause (And one that would be possible to fix) was that one or more of the circled power MOSFETs had gone bad – and indeed one of them correlates to the hot spot on the motherboard:

Of course, it could be the supporting circuitry that caused the MOSFET(s) to fail in the first place. Nothing else appeared damaged, so we took the chance. We sourced the replacement parts and got to work repairing the unit. Our game-plan was to replace all of the MOSFETs circled. However – we underestimated just how much heat it takes to get the solder flowing on this multi-layer motherboard, undoubtedly with many large copper planes for the power supply:

I couldn’t tell you how long we spent trying to get one of these power MOSFETs to reflow – easily over half an hour. This is normally done with a large oven to bring the whole board up to temperature before rework. We made do with brute force and ignorance.

And so – with inadequate heat and too much force, We managed to get some of the bad parts off of the board – it became apparent that soldering something back on was out of the question. We were getting hopeless – you can see some of the copper pads lifting underneath a MOSFET die… yes, we pried the case off, and the die was still stuck to the board…

Not my proudest work….

But, wait a minute – looking at the schematic, these MOSFETs have parallel counterparts on the other side of the PCB. What’s the current capacity of these things, anyway?

These MOSFETs can each handle 24A pretty handily, and the current calculations printed in the schematic worked out to under 20A total – so, theoretically, this laptop did not need the paralleled capacity, if the calculations are to be trusted. It looks as if they were paralleled to spread out the heat a little bit, and perhaps for some added redundancy. We had removed the thermally challenged MOSFET; could this thing “just work” at this point? I was skeptical about turning the unit on, but Mike was willing to accept the risks. We soldered some of the casualties back in place (diodes) and cleaned up the desoldering mess as best we could. We reassembled the laptop, booted it into a diagnostic mode – and everything worked!

I don’t know that I’ve ever fixed something by removing a part. We effectively pulled a bad tooth out of the laptop, and the problems all disappeared. Go figure. Mike stress tested it with some intensive gaming when he got home, and the thermal issues had entirely disappeared.

So – when your laptop is misbehaving, should you go removing parts? Absolutely not. I will point out that we had an appropriate fire extinguisher present during all of our tests. Power electronics can get very – well, “explodey” – this is why we did all of our testing outside! This was only remotely advisable on account of the research and precautions that Mike and I had done (okay, it was mostly Mike!)

A big thank-you to Mike for the fun project, the hard research, and the photos. You can catch Mike Himbeault on reddit and github.

Projects from the grapevine: Bárány chair repair

Note: this blog post has been produced with permission from the client.

Update (2020-12-31): After receiving and installing the replacement parts, we have another successful repair! Here’s a video of the result:

Recently, a repair job came across my plate for some exotic test equipment: a “Bárány chair” used for testing pilots. This is one of those odd projects that comes through a friend-of-a-friend-of-a-friend. No electricians or repair technicians in the city were willing to touch this niche equipment – and I can’t blame them! I couldn’t find any information on this machine whatsoever.

Like most of you, I don’t specialize in exotic chairs – so what is a Bárány chair? From Wikipedia:

The Barany chair or Bárány chair, named for Hungarian physiologist Robert Bárány, is a device used for aerospace physiology training, particularly for student pilots.

Via Wikipedia

Here’s what the unit looks like:

The chair is motorized, with a wireless control to operate it:

The control allows the operator to adjust the rate and direction of rotation. The chair had stopped spinning, and the manufacturer was unresponsive and/or unwilling to repair the unit. It was clear from dead-end google searches that this unit is from a very limited run of a very niche product – there wasn’t an operator’s manual or service diagram to be found. Note the use of 3D printing for the remote control enclosure. If I had to guess, this probably came out of an R&D lab.

Upon arriving, the remote complained that it had no power to the base unit (“Dashes” observed). The only troubleshooting info available was listed on the side of the controller:

A quick investigation revealed that the power supply was plugged into a switched outlet, which had been turned off. Moving to a regular outlet caused the power supply to come online, and the controller sprang to life! No error code – just “00” on the two-digit readout. The chair was still not responding to the rotation settings – but when I manually spun the chair, it displayed the sensed rotation speed on its LED display. I concluded that the logic power supply and wireless communications were working. At this point, I suspected that the problem was in the motor, motor power supply, or the motor controller.

I investigated the power supply for the motor and found it to be outputting a steady 5V – which seemed unusual for a giant motorized chair. I would expect 12V or 24V for a large DC motor. I entertained the idea of adjusting the power supply to a higher voltage – could the power supply have degraded in its ten years of operation? The motor controller datasheet suggested that 6V was the minimum supply voltage, after all. Luckily I noticed that the motor controller had been modified for this application: it passes the motor power directly to the control logic. You can see a jumper wire that bypasses the 5V regulator in the image below. I expect that the 6V minimum is to accommodate the voltage drop incurred by the 5V regulator. Note, modifying off-the-shelf parts for out-of-spec operation is not a design technique that I recommend.

With this knowledge, I was reasonably confident that the entire system was designed to run at 5V, unintuitive as it may be. Good thing I didn’t adjust the power supply! I attached my scope to the control signal from the control logic to the motor controller to see what signs of life existed.

The control signal pictured above appeared to be a servo-style control signal – a carefully timed pulse controls the motor’s speed and direction. When I adjusted the speed control on the wireless remote, this control signal was unchanging. This suggested to me that the wireless receiver, control logic, and motor controller were likely all working – but receiving a “don’t spin” input signal. I turned my attention to the remote control:

And there it is – the rotary encoder for the speed control knob was split in two! One half was bolted to the plastic housing, but disconnected from the rest of the encoder. It still had an actuating “click” feel, without being electrically connected.

With the remote still disassembled, I pushed the rotary encoder back together to make a temporary connection – and the chair started spinning. If I had to guess, someone was a little too rough with this remote.

The replacement parts are ordered – with some careful soldering, I expect a successful repair and many dizzy pilots.

Evaluating PCBA Service: Custom Gameboy Cartridge Part 1

Earlier this year, I decided to design a project to evaluate Seeed Studio’s Fusion PCBA service. I didn’t have any immediate need for a PCBA, and so I found myself in the classic hobbyist situation: a solution in search of a problem.

The project needed a low parts count, a small PCB, and it had to be fun to design. I settled on a programmable Gameboy cartridge to meet my hobbyist needs. So, with Seeed Studio’s fusion PCBA parts library in hand, I fired up KiCAD and began my design journey! I began with some handy footprints from Gekkio’s awesome Gameboy footprints library, available on their GitHub: https://github.com/Gekkio/gb-hardware

Unfortunately, I had chosen the wrong footprint for the selected Flash chip, but Seeed Studio caught the issue and was able to help me correct it easily. Overall, their service was very good! I happily received my PCBA’s in a number of weeks.

Silkscreens: never miss an opportunity for a good pun.

Upon receiving the boards, I soon discovered that I did not place the mounting holes in the standard locations for a Gameboy shell. No worries though – that’s where FreeCAD and a set of calipers come in handy. Exporting a 3d rendering of the PCB from KiCAD took any guessing out of the equation:

The final result looks pretty good – I will note that a Gameboy PCB should be 0.6mm, but in my excitement, I must have accidentally selected 1.6mm. Therefore, the cartridge shell is very thin at the back, but the PCB gives it rigidity.

My development cartridge – fits like a glove

Setting up a project in STM32 Cube IDE is trivial work, however – I discovered that I had used a slightly incompatible footprint for the MCU. One of the pins is no longer available for GPIO:

Oops!

I double-checked all of the library components and indeed found that it was my mistake. That’s the price you pay for feverish hobbyist development, I suppose! Fortunately, I have GPIO to spare (At the top of the PCB), so I can do a hardware patch without any issues.

In bringing the board up, however, I have found that I am unable to get the MCU running at the intended 84 MHz – anything above 48MHz triggers hard faults in the CPU. Luckily, STM32 Cube IDE makes it trivial to configure global clock settings. I am not yet sure if this will be fast enough to meet the timing requirements of the Gameboy – I was unsure about 84MHz being fast enough. But, we will soon enough find out.

Stay tuned for hardware patching and new revisions!

Packet Loss, Python Scripts, and the Dreaded Technicolor DPC3848V

Are Youtube videos pausing more often than they used to? Do websites speed up after restarting your modem? You might be suffering from cable modem packet loss!

After switching to a popular Canadian ISP, I experienced all of the above. Packet loss is a common network problem. It can be due to poor WiFi coverage, bad cabling, and umpteen other things. But, if you are one of the unlucky souls to receive a Technicolor DPC3848V, the problem might be your cable modem itself!

Technicolor modem spotted in its natural habitat. Snail photo: Zdeněk Macháček

Searching this model number reveals many forum users reporting the same issues. Here’s the frustrating part – the problem is a function of runtime. Tech support will ask you to restart your modem, but this only fixes the problem long enough to get you off of the phone. Then it’s back to slow, laggy internet!

The main tool I used to troubleshoot this problem was an installation of smokeping, which will happily run on any raspberry pi or Linux machine on your network – it is even available in most repositories. Smokeping will constantly ping whatever hosts or IP’s you configure, and graph the results. This is important – when problems are intermittent or take hours to develop, you cant reasonably sit at a PC running the ping command all day. Let smokeping do that for you.

Once you get smokeping configured, it will give you easy to read graphs in a web interface. Here’s how a smokeping graph looks when things are running well:

…and when things aren’t running so well:

While troubleshooting this issue, I had multiple technicians come by. Important note: none of them cared one lick about my graphs. They have their company tools, and that is all that they will trust. One of them even claimed to not know what packet loss was…?! Perhaps they are asked to play dumb, for the sake of unloading these terrible modems. Who knows.

Anyways, when technicians don’t understand “packet loss”, well, things don’t progress smoothly. It took 4 separate visits to correct the issue. While this lengthy troubleshooting dragged on, I couldn’t sit idly by. I fired up my code editor, opened the developer console in firefox, loaded up the admin page for the modem, and got to work reverse-engineering the admin webpage traffic. My first goal was to automate a reboot from my PC, and I was able to get this working in a python script without too much hassle – you can see the code here. With this simple script, I used cron to reboot the machine every morning. I managed to get some basic configuration working as well – you could use it to automate changing your wireless network name & password as often as you like. See docsis.py for details.

Obviously, automating reboots is a very hacky fix – the only thing that fixed the issue permanently was insisting on a new brand of modem. Once the new modem was installed, the difference was night and day:

With my internet now working, I was able to stop reverse-engineering junky products and get back to what matters most: mindless internet consumption. Hopefully, this article helps someone – and, with any luck – that technician figured out what “packet loss” is!

Custom NES Cartridge – Harambe’s Revenge

As far back as I can remember, I’ve been fascinated with computers. This began with the venerable Nintendo Entertainment System – as a child I often dreamt of making my own NES game. This interest lasted well into my teen years, when I would read programming how-to’s from NesDev and other corners of the internet.

Later in life, I met a fellow named Brad Taylor – he was the author of many programming guides for the NES, and just happened to show up at my local hackerspace one fateful day. I had no idea this guy lived in the same country as me, let alone the same city – small world! With Brad’s NES expertise and my PCB design skills, we joined forces to make a USB reprogrammable NES cartridge. This project would be my first foray into PCBA (Printed Circuit Board Assembly), wherein a vendor does all of the component placement and soldering. This was a big deal for me!

The finished product – Raw PCB (left), mounted in cartridge shell (right)

Hardware Design

Initially, Brad and I wanted to make a PCB that could do some very ambitious things, requiring either a very capable processor, or an FPGA device. We began down this path, but soon realized that we were biting off much more than we could chew for something we had never done before. So, we decided to take a step back, and make a smaller project to verify the foundations of our design. Our final design goals were:

  • Be programmable via USB
  • Be able to play NROM format games
  • Feature nonvolatile storage (no battery required)
  • Be as cheap and easy to manufacture as possible

Component Selection

One of our design goals for this project was to make it cheap and easy to manufacture and prototype. That meant excluding BGA packages, which really limited our options. We also opted for a 2 layer PCB to keep manufacturing costs down, which made the layout more challenging than it would be on a 4 layer board.

For the memory, we used whatever was cheap and available from digikey – and could tolerate the NES’s 5V logic buses. We wound up using a SST39SF010 device (one for the PRG memory, and one for the CHR memory).

For the USB interface, I took a misstep in choosing an FTDI FT232H USB interface – I had selected it solely because I had previous experience using this chip. So, we did save some time on having to learn new tools – but at a unit price over $10 at the time, we likely could have found a cheaper option, and simply spent some time learning a new platform. Lesson learned!

One of the challenges of making an NES cartridge is interacting with the console’s lockout functionality. Luckily, the krikzz forums had a firmware load for an Attiny device, so we simply included this same chip in our design, and flashed the provided firmware onto it.

The rest of the components in this design were fairly standard, and included some generic shift registers and regulator circuitry. We used the shift registers to take serially-loaded memory data, and present it to the flash chips as a 48-bit parallel interface.

Fundraising

PCBA can be a costly service, and I didn’t want to go out-of-pocket on the order of $100’s – $1k for a hobby project. To this end, Brad and I opted to fundraise for a production run by following a crowdfunding model. We didn’t want to go as far as a kickstarter, so we solicited local tech groups (as well as friends and family) to see who would be interested in owning one of the cartridges. We received 13 orders and were able to keep the per-unit cost to around 80 dollars, which was a reasonable amount for all involved.

PCB Design, Iterations, Oversights

This design went through a number of hand-soldered prototype revisions before I placed the final order. We never did get a prototype 100% working due to the difficulty of soldering fine-pitched components, but we were reasonably confident that it would work (this later turned out to be partly incorrect).

One oversight was the control circuitry for the “read only” signal to the memory circuitry – we had assumed that the FTDI device would always provide a logic high on a particular signal, and we were using this signal to determine whether or not the device was plugged in to a USB host. This proved wrong, it only held true for a few units. We had to re-work the PCBs with a hardware patch to correct this:

Hardware patches: not as elegant as software patches

This patch takes one of the clock signals, rectifies it, and low-pass filters it to provide our “read only” signal. So instead of detecting if we are plugged in to a USB host, we now detect if we are connected to a powered-on NES. Luckily this patch saved the batch!

A more serious oversight existed in the design of the USB micro-B connector footprint. When I tested the assembled units back, they didn’t come up in dmesg… and the USB cable was getting hot to the touch. After some debugging, it turned out that the USB connector’s metal casing was shorting out the extra-long USB pads – I had designed them as such to ease manual soldering, but this was problematic for automated assembly. This was fixed by manually removing each USB connector, applying kapton tape to shield the casing from the PCB traces, and re-soldering it in place (yes, this was very tedious).

Kapton tape and tedious soldering saves the day

Software Design

Flashing Software Design

The flashing software for this design – the logic that shuffled a file from my PC to the cartridge – was simple in concept: use libftdi to connect to the USB interface, and bit-bang the memory data out through the shift register chain. I wrote a number of abstracted layers to produce the bit patterns needed for parallel memory programming, you can see a video of me testing the entire SR output chain below.

Unfortunately, I used up all of the FTDI’s I/O, and couldn’t route back a signal for the “Flash is done writing the current byte” signal. This meant I had to wait the maximum write time delay between every byte to ensure that it wrote successfully. I consider this the single largest oversight in the project, as it meant that programming an NES game (order of kB’s) would take 5 minutes or more. I did not realize just how long this would take until I had implemented and tested it. But, after a ton of testing with Brad’s cartridge reader device, we had a working unit!

The first working game on my hardware – exciting!

Game Software Design

Making and selling a cartridge is all well and good, but I can’t go shipping it with material that I had no right to distribute. To that end, I fulfilled a lifelong dream and created an NES game, Harambe’s Revenge:

I could write an entire series of blog posts on how difficult it was to write this game. And for all of my efforts – it is a very basic game. I wrote it entirely in 6502 assembly, and did the graphics myself via GIMP. I used https://github.com/pinobatch/pently for the audio playback library, and started the project with Damien Yarrick’s Project Template. Brad’s knowledge of NES programming was invaluable during my efforts.

A brief playthrough of the latest version of Harambe’s Revenge
An early version of Harambe’s Revenge running on Hardware

Lessons Learned

At the end of the day, we achieved our goals of learning to design for PCBA, and verified some design assumptions for a future board. We even successfully filled all of the orders. The most important outcomes, in my opinion:

  • Validate footprints for automated PCBA – casings can short out large hand-soldering pads
  • Bit-banging is a poor choice for programming a memory device, and while it kept monetary costs down, I wouldn’t opt for this approach again. If I were to redesign this, I would use an MCU with built-in USB functionality.
  • Start small – had we went for our initial design, there’s a large likelihood we would have not been able to complete it before losing steam. All of the work to make this ‘simple’ board took place over the course of a year!
  • Anticipate failure – we made more PCB’s than were required, as we anticipated that there would be some unit failures, and there certainly were.

Most of all – this project really drove home an important notion: projects don’t succeed on technical merit alone. There will always be difficulties – it’s not about how good your PCB layout is, or how elegant your code is. The success of a complex project comes down to perseverance and teamwork in the face of unpredictable problems. Having said that – thank you for all of your help and hard work, Brad!

Capture-the-Flag PCB: The Long Con 2019

For 2019’s iteration of The Long Con, I volunteered to help wrangle up some brain teasers for their “capture the flag” contest – a tech convention standard wherein attendees compete to solve assorted technical puzzles. As my experience with “cool stuff” mostly lives in the realm of circuit board design, I opted to contribute a circuit-board based puzzle. I think it looks pretty sharp with the silkscreen logo!

Hardware Design

As this is a small local convention, there wasn’t much budget available to go off-the-wall with technical capability – so, my three design goals were: 1. it has to look cool, 2. it has to be cheap, and 3. it has to do something neat. With these design goals in mind, I began my digikey search for an inexpensive but capable microcontroller. I settled on the attiny84a based on it’s capacitive touch capability, as well as an internal temperature sensor. These on-board sensors meant I wouldn’t need to add external sensors, which would increase the unit cost. You can get more info about the attiny84a here.

Designing the circuit board was relatively easy, based on Atmel’s design guides for capacitive sense (this is via their QTouch library). The hardest part was designing the capacitive touch sensor – I opted for the simpler rotary sensor design due to its ease of entry into KiCAD. I tried a few different ways of importing their recommended design, but couldn’t quite get it to work.

Recommended Design
What I wound up using

I had intended to use svg2mod to import the auto-generated footprint, but the polygon approximation didn’t seem to work out to a workable resolution. I didn’t feel like going any further down this rabbit hole, so I opted for the simpler design that Atmel’s documentation suggested.

The rest of the design was reasonably boilerplate MCU work – I stuck to standard components that were available from Digikey, and preferred components that exist in their KiCAD libraries. I have uploaded the KiCAD project to github, check it out!

Schematic diagram for the CTF board

KiCAD/PCBNew view of the circuit board
3D rendering of the PCB

Software Design

The software was very dependent on Atmel’s QTouch library – most of the challenge was actually in configuring their IDE to work correctly. I wrote up my experiences on their forums here. Based on this experience, I have resolved not to use Atmel components for a while… I got the feeling that Atmel Studio is a second class citizen since the Microchip buyout.

The actual software itself is not terribly complicated (or optimized) – Atmel’s QTouch library, for all of its installation issues, was easy to code with. I had wanted to configure the firmware to spend most of it’s time in a low-power sleep state, but after doing some quick calculations, the battery would last the duration of the conference on a coin cell without the low-power modes. And so, I spent no time optimizing this device for power consumption.

You can see the source code for my solution on github here. It is far from the “cleanest” code I’ve written, and was written in a time crunch. But, it did work!

Capacitive touch test

Manufacturing design

For this unit, I opted to use reflow solder techniques. I purchased a Whizoo upgrade kit to modify a toaster oven, but I did not get the parts in time. I ultimately used a thermocouple and manually rode the thermostat on my toaster oven to follow something like a soldering profile. It seemed to work reasonably well!

For flashing the firmware onto the attiny84a, I placed a contact pad that mated with a spring loaded 6-DIP connector on the back of the device. To make for an easy flashing process, I exported a 3d model from kicad and used it to make a 3d-printable jig. I had to manually line up the spring loaded connector and hot glue it in place, which was a little tedious, but worth it in the end.

3d printed programming jig, complete with “Pogo pins”
Demonstrating fit on the jig

Conclusions

The project was an overall success, and people enjoyed the challenge. Unfortunately, out of the 30 that I had tried to manufacture, only 6 worked to their fullest extent! I attribute this to my ambitious use of tiny resistor arrays – it appeared most of the failed units featured poor connections on these components, and my reflow repair skills were simply not up to the task. Luckily(?) only a couple teams got far enough in the CTF to get to the “PCB challenge”, so we were never short on units despite the poor yield.

Another conclusion – try a different MCU vendor next time, Atmel Studio/QTouch installation was a torturous experience!

Puzzle Spoiler

The general intention was for participants to look up the datasheet of the single IC to see what peripherals it had – QTouch and temperature sensing – and work from there.

Puzzle 1 – this conference takes place during the daylight savings time change. Users had to “turn back the clock” by using the capacitive rotory sensor on the clock face. 4 complete rotations would prompt the LEDs to display a byte pattern.

Puzzle 2 – the weather had just begun getting cold in Manitoba (where this conference took place). Users had to get the unit 15 degrees Celsius colder than when they plugged in the battery. This could easily be done by taking the unit outside. This was a fun puzzle to figure out from a software point of view – the calibration on the sensors was not great out of the factory, and I didn’t intend on taking multiple calibration points for each board. So, it simply looks at the temperature delta since the unit turned on instead of comparing against an absolute temperature.

3D printing a trackpoint replacement

As a chronic Linux user, I’ve been a fan of thinkpads for a while – so long, in fact, that my current thinkpad’s trackpoint has been worn to a smooth, useless nub.   Woe was I!

Luckily I have been brushing up on my FreeCAD/3D printing chops (well, ushering them into infancy), and this little part served as a good example project.

After taking some calipers to the original trackpoint, I was able to come up with a profile that I could perform a revolution on:

Performing a revolution on this yielded a rough 3d shape – applying a chamfer to the edge and adding some small spheres made for some grip and improved aesthetics:

To make it fit on the existing mount, I created a rectangular pocket by subtracting a cube from the rotated solid.  After firing up the 3d printer (and churning through 1 poor print) I had a working replacement:

It is working a lot better now!

 

If anyone else wants to print one of these, here’s a link to the .STL file.

Happy printing!

Building a Magic Mirror; Nifty Opto-Isolator Tricks

After seeing a critical mass of Magic Mirror builds online, I caved and built one as a Christmas gift for my girlfriend – I made a few innovations on top of the other builds I’ve seen, so I’ve documented them here.  I drew much of the inspiration from Dylan Pierce in particular, so be sure to check out his build log as well!  Here’s the finished product, before wall-mounting:

 

mirror2

Build Process:

As I did not have the patience to spec out my own LCD panel, I decided to purchase a used victim TV, and worked from there.  The first step was to pop the bezel off and take a few measurements:

 

20161221_002223

 

With measurements of the LCD panel itself, I was able to mount the LCD panel in a basic 2×4 frame:

20161222_203728

The LCD Panel did not have any usable mounting holes that could mate with the 2×4, so I held it in place with some small angle brackets.

20161222_210831
After installing the brackets, I realized the single-screw mounting hole would be prone to rotation – some flank screws made for a quick fix.  Also pictured: speed holes

 

20161222_211047
I eventually added small metal mending plates to sandwich the LCD bezel in the frame (not pictured)

The TV I had cannibalised did not support HDMI/CEC control via the raspi, so I patched in to the power button with an opto-isolator (Sharp PC817).  By using an opto-isolator, the raspi only “sees” an LED as the load, allowing for safe coupling between the raspi and the TV circuitry.  The pin spacing on the PC817 was conducive to patching in directly to the tactile switches.  I also replaced the TV’s “off” LED with an opto-isolator connected in the opposite direction – this lets the raspi know if the TV is on or not.  This is important, because the power button is of the on/off toggle type; the raspi wouldn’t be able to know if it was turning it “on” or “off” otherwise, it would only know that it is changing the state.

 

20161222_213606

 

Originally, I was going to power the TV on and off via cron job, until a coworker suggested putting a sensor in to turn the mirror on when someone is in front of it.  I just happened to have a spare ultrasonic sensor around, so I mounted it into the frame and wired it up via GPIO pins on the rpi:

20161224_172106

With all the electronics connected + working, I glued the fancy mirror-glass in place (Actually, it’s acrylic), and added a nice aesthetic touch with some faux-oak molding and iron-on veneer (ran out of veneer, so the bottom got the thin piece).  I measured the mirror piece to have a 0.5″ margin beyond the viewable LCD portion so that I could affix it to the LCD bezel for a tight fit.  Mirror glass was the same used by Dylan Pierce available at TAP Plastics:

20161224_231110
The notch is in place to accommodate a power cable while wall-mounted.  Also pictured: speed holes

 

The ultrasonic sensors were a bit tricky; I drilled holes in the moulding and adjusted them with a dremel.  They are by no means perfect…

20161224_231134

 

And here’s a view of the rear/electronics – the intention is that this will be wall-mounted, so I didn’t bother with a protective cover.  Zip ties were applied liberally.

20161224_231116

 

Schematic

mirror_schem
Note: The optoisolator / ultrasonic sensor circuitry was soldered onto a piece of perfboard that mated with the RPi’s GPIO header

Software

The base software installation uses raspbian jessie and MagicMirror², and raspbian packages python-gpiozero and wiringpi (i.e. install via sudo apt-get install _____).  All GPIO control code is below.

Note: all .sh and .py files live in /home/pi, the .service files live in /etc/systemd/system/, enable via:

  • cd /etc/systemd/system
  • sudo systemctl enable detect_person.service
  • sudo systemctl enable tv.service

This allows for control via, e.g. sudo service tv [start|stop].  The tv.service serves to turn on the tv during the boot process (as well as for general debugging), while the detect_person service performs the ongoing operation for person detection.   Note that the particulars in detect_person.py need to be tuned to the environment that the mirror is installed in!

I also had to play with some settings /boot/config.txt to get the right screen orientation, see the comments in that file for details.