The Smart Conference Badge We Almost Failed Shipping

The Full Story of Designing and Manufacturing a Hardware-Packed PCB Badge Full of Surprises

I have never studied Electrical Engineering. Yet electronics and PCB design always fascinated me. I learned mostly through hands-on experimentation with projects such as making Angular-logo shaped beacons, guided by online tutorials and YouTube videos. Perhaps it isn’t the most effective method, but it works for me and it is fun.

For some time now I wanted to create a larger scale project, such as a smart conference badge. Something other people can have, interact with, program and extend. And then, one day, the opportunity came. This is the complete “behind the scenes” story of how a product, imagined by a team of amateur engineers, came to be.

It Always Starts With an Innocent Email…

One day the following message landed in my Inbox:

It was a friend who suggested that we build together a cool badge for a tech conference another friend was organizing. I quickly hit the reply button and typed “Sure, I’m in!”, without giving it too much thought.

Later, we set a call and Elad, the friend who sent the above mail, presented us with some ideas that he had in mind, such as using Ethernet sockets for attaching the lanyard to the badge:

An early sketch of the proposed solution

We started brain-storming and came up with an impressive list of ideas:

Setting up a Mesh Network that connects all the badges

Implementing a game that take advantage of genetic algorithms to generate a unique image for each of the participants

Embedding a Python interpreter in the badge

Developing Quiz app where the audience could use the badge to vote for questions during the talks

and the list went on and on…

After all, we had more than 8 months until the conference, and that’d be plenty of time to explore everything, wouldn’t it?

Listen To This, You Will Love It!

A month later, I met Nir, the organizer of the conference in a meetup. He told me about a crazy idea he had for the badges — what if we had a headphone jack and could broadcast audio to everyone? We could then have a headphone party using just the conference badge!

A quick googling revealed that none of the awesome DiY conference badges has explored that avenue before. I wasn’t sure if I liked this idea or hated it, but I presented it to the other team members and we decided to give it a go.

Let the Prototyping Begin…

We had a lengthy discussion about the possible hardware options, and eventually narrowed it down to two options: ESP32 or nRF52840. ESP32 is a very popular chip that is quite powerful and features WiFi, and it was more popular at the time.

The nRF52840, on the other hand, seemed better in terms of power consumption, and also supported the OpenThread Mesh network, as well as Bluetooth Low Energy Mesh. Both chips had Python support though the MicroPython project, and it seemed like JavaScript support as well, through Espruino.

We decided to go with the nRF52840, and ordered a few USB dongles featuring this chip. We also looked for a chip that would handle the audio — digital to analog conversion, as well as optionally MP3 decompression, and we found the VS1053B chip which seemed a good fit for the job. Waveshare provides an affordable breakout board for this chip, so we got one.

Promising First Attempts

The hardware arrived mid-September, and we started working on validating the software features. Our first priority was making the badges Python-programmable, in order to make it very straightforward for the participants to reprogram them after the conference.

Shortly after we got the dongles, Benny created a build of CircuitPython and its Bootloader and loaded it into the dongles. Meanwhile, I experimented with the sound hardware and even got a working proof-of-concept that would stream MP3 audio from the computer to a single dongle over Bluetooth Low Energy:

This wasn’t very straightforward, as we had to change the Bluetooth packet payload size (MTU) from the default of 23 to the maximum value of 247, in order to get the throughput required to stream the audio in real time.

Despite the fact that larger MTU is allowed since Bluetooth 4.2, it’s not widely supported, and thus I had to patch CircuitPython to allow for the larger MTU.

In addition, we also hit some issues with the hardware SPI implementation (we used SPI for communicating with the chip), so we ended up with our own bit-banged Python SPI implementation, and had to apply several optimization techniques to make sure our code executed fast enough. You can find the full story with all the technical details in a blog post I published around that time:

When we finally had the first audio streaming PoC working, we also opened an issue on the CircuitPython repository, to share the VS1053 audio driver we created. The response was short and sweet:

The Hebrew response was quite a surprise for us

We also had some fun creating a python script that would control the mouse and write something on screen whenever you plugged the dongle to your computer, using the USB-HID library for CircuitPython:

Curious how this works? Check out the source code

These HID experiments took their toll on my machine, and I even managed to get a Windows error I have never seen before:

It quickly recovered after I clicked “OK”

Meanwhile, Elad went away for a month in Hawaii for his honeymoon, I started my daily blogging challenge and applied myself to finishing the Trumpet playing robot, while Benny was abroad for some conferences. So we basically stopped working on the project for the next month.

Let There be a PCB

Mid-November we got back to work and my life-partner Ariella started designing the PCB for the project. The first iteration included just a breakout for the VS1053 chip, as it was Ariella’s first PCB design project and that chip alone required a dozen of passive components:

I love KiCad’s 3D Rendering feature!

She concluded the initial design in a few days, and we sent it to manufacturing and ordered the required components. Two weeks later, the package finally arrived:

Ariella’s first PCB (and our first iteration) has materialized!

Soldering all the components took about 2 hours of tedious hot air gun work, but surprisingly, the board worked like a charm on the first attempt!

Good news aside, we realized the conference date was getting closer — it was mid December already, and we only had 4 months left. Suddenly, it didn’t seem like a lot of time…

Led Matrix? LCD? OLED? E-Paper

We knew that we wanted some kind of display on our badge, and as time was pressing, we had to make our call. We had a tough choice between LCDs, which were full-color, cheaper, widely available and thoroughly documented, and E-Paper displays, which were much more exotic, power efficient, and retained their content even after the power was cut, but monochrome and more challenging to work with.

I had past experience with E-Paper from my In-Real-Life Chrome Dinosaur Game project

Eventually, we decided to go with the E-Paper, especially because it was more legible at day light and more unique. We also found out that reel Board, a recently released open-source badge, opted to include an E-Paper display. This gave us more confidence in our choice, and also meant that we would have a readily available schematic and code samples to rely on.

We ordered several E-Paper modules (1.5", 2.7", and 2.9") while starting to work on the second revision of the PCB. It was a major leap from the first one: in addition to the sound module, we added a micro-USB connector, a bunch of passive components and a flat-cable connector for the E-Paper panel, as well as the nRF52840 chip.

The nRF52840 requires a additional components and an antenna to work, so we went with a ready-made module from EByte, E73–2G4M08S1C. We chose it after looking at several alternatives (BMD-340, MDBT50Q, BT840 and Holyiot 18010), as it was relatively easy to solder and had a built-in ceramic Antenna. Ariella created a KiCad footprint for the EByte module, then we sent the PCB to fab, hoping for the best…

When Things Don’t Go According to Plan

On January 1st, the second board version arrived. We quickly soldered the nRF module and programmed it with a simple “Blinky”:

It seems like we did things right. But several hours later, after soldering all the components required to the display and connecting it, one of the MOSFETs on the board started to let out “magic smoke”!

Luckily, we broke out all the lines that connected the CPU with the display, so we could connect an external break-out E-Paper module to our board and verify that the driver code was working, and thus narrow down the problem to the circuit that supported the display panel.

This was really baffling though. We double-checked the schematics, and everything looked fine:

We stared at the schematic for hours trying to figure out what could go wrong…

We only had one extra MOSFET at our disposal (the one from the E-paper breakout module), and we didn’t want to fry that one as well, so we didn’t attempt to do any further experiments until we figured it out. The next day, it occurred to me — the wiring of the flat-cable socket (where the E-Paper cable connects) was reversed!

In an heroic effort to confirm my suspicions, I somehow managed to solder the socket upside down, and thus, reverse the connections:

The socket had to be hanging in the air for its pins to touch the board

I changed the MOSFET, fired up the code and it worked!

It said “Hello!”

I asked Ariella to change the wiring of the connector in the PCB schematic, and we sent the third revision for manufacturing, while also adding two NeoPixels as per Benny’s request, and a two Capacitive-touch buttons and slider that Elad really wanted to have.

Then, we finally had it — a working board with the display, the sound chip, and two NeoPixels:

Our first “useful” prototype

At that point, we were hand soldering each of the boards, which took a considerable amount of time, around 150 minutes per each board. We also had problems with getting the sound chips to work — the 44-pin QFP package was a nightmare to solder. Thus, we only made 3 functional boards, one for each of us.

Elad started working on the implementing the code for Capacitive-touch, but due to time shortage, we decided to ditch it and just use buttons for input. I quickly repurposed one of the touch pad by soldering to it a small MOSFET that controlled a vibration motor I had (top-right corner of the photo above). Thus, creeping in another cool feature into the project ;-P

Final Product Design

3 Months before our final deadline, we finally started working on the final design of the board. Elad came up with the following mock up:

This version added several more NeoPixel LEDs, changed the touch-pads to buttons, and also added a power source, SPI Flash, and an AA-battery. Reshaping the board was quite simple, as I had a tutorial at hand explaining exactly how to do that, and Ariella worked on designing the battery circuit. It is a time to thank again the reel Board project for sharing their schematics, which proved really helpful!

We tried to complete this as fast as possible, and just as we thought we finished, Elad had a brilliant idea — what if we used mechanical keyboard keys instead of buttons?

I mean, why not?

Did you spot the other “by the way” additions to the design? A power switch (which proved to be critical later), a Shitty Add-On connector (because “people might want to extend their badge”), and a standard 10-pin Cortex-M programming connector (a little hard to spot in the sketch).

Meanwhile, Elad also created a very detailed illustration of what we were building and shared it with our friend Nir, the conference organizer:

It says “Functional electronics” and “Good looking outside”

With this, our friend could be assured that we were on the right track ;-P

We sent the new design to JLCPCB for manufacturing, and this time also ordered a stencil to ease assembly, hoping to get at least 5 function boards we could develop the software on. We also managed to squeeze a small Shitty Add-On board into the order, hoping we’d be able to use it for a “Capture The Flag” (CTF) challenge:

We were a bit too optimistic :)

At the beginning of February the new boards arrived:

We tried our luck with the stencil assembly. Ami, a colleague of Benny and an experienced engineer, helped us with spreading the solder paste and placing the components:

Solder Paste 😋

Tedious manual pick-and-place

Frying the board on the hot plate

Ready for testing!

Pumped up, we programmed the chip and hoped for the best. The board powered up, the LED blinked, and we were even able to get some output on the display, use the USB port, and write to the Flash memory.

The sound however, was totally defunct — the chip wouldn’t communicate with the CPU. Since we only had one board at hand, it was hard to tell whether it was a design issue, a soldering issue, or just a defective chip.

But the most frustrating part was that we could only power up the board via the debugging port. Neither the USB port nor the Battery could be used to power the board. After a thorough investigation, we found that the voltage booster that we used, TPS610986, was the culprit. Instead of outputting 3.3V, as they spec said it’d, it gave us merely 0.7, which was too low for the board to start.

This little guy gave us so much trouble! TPS610986

Yet again, we found ourselves staring at our schematic and double-checking with the datasheet and the reel-board schematic, trying to figure out if we missed out in the circuit. We even asked Yariv Bash to take a look, but none of us could find anything suspicious.

So at that point, we had a badge that wouldn’t power up unless it was plugged, with no sound output, and we also couldn’t get the 4 NeoPixels on top to work. Terrific!

We also got feedback about the pads of the nRF module. The outer pads were too far apart and while we managed to solder them, it wasn’t very straightforward, and would probably result in some of the boards having disconnected pins. So we had to update the board design and move them pads closer:

Moving the outer pads in… Fortunately, it didn’t require too much rerouting

We had broken hardware, no software, and only a little more than 2 months for the conference. Oh, and it was Chinese new year, so China was in vacation for the next two weeks. Charming! 😬

We met again and assembled another board, this time with just the battery holder and the voltage booster chip, to try and isolate the problem. To our surprise, it worked perfectly!

Finally getting 3.3V (even a bit more)

We still have no idea what was the issue with the original board, but after we spent a few more hours assembling a second one and reworking some of the components, we also managed to get the sound chip, as well as the NeoPixels to work. Lesson learned: manual SMD assembly is very error prone! At least we were now a bit more confident in our design skills 😊

Elad and Benny, after they finally got the sound to work!

Another Honeymoon 🍯

Just before Ariella and I left for our Honeymoon in Japan, we did a few “last-minute” enhancements to the board, adding test-points (so we could reprogram the boards without having to solder a Cortex-M debug connector, if we needed), battery reverse polarity protection, and a small I2C accelerometer (because “it’s cool”, so “why not?”)

4 new test-points (top-left), reverse-polarity protection (U6), and an LIS2DH12 accelerometer chip (U7)

As soon as the factories in China resumed their operation, we ordered a batch of this new version, hoping it will be the final one.

We also started sourcing the components for the final production run of 200 units, and figured out we could cut costs if we change the E-Paper display to a different brand called “Good Display”. I mean, with this name nothing could go wrong, right?

We also contacted EByte and purchased 200 E73 nRF52 modules. They even offered to program the modules before they ship them. This meant we could have the boards shipped with a bootloader and would be able to easily program them via USB when we got them.

Elad started collecting quotes from different factories in hope to start production shortly. Meanwhile, Benny started looking into using Zephyr Project as a basis for our firmware.

Zephyr is an open source real-time operating system for Embedded IoT devices built by the Linux foundation. It has built-in support for Bluetooth Mesh and OpenThread, and even an E-Paper display driver. This is the operating system that runs on the reel-board, so we thought it would be a solid base to build on.

When I packed for the honeymoon, I managed to sneak one of the earlier boards into my luggage, so when I discovered our 10 hours flight had no functional WiFi, I took advantage of the opportunity and quickly hacked a web interface that would allow you to display your name on the badge.

I used the Canvas API to draw text next to the badge logo, then read the pixels from the Canvas, converted them to a black-and-white bitmap, and then sent them over Web Bluetooth to a piece of code I specially crafted for the badge, on top of ZephyrOS:

It says “Shakshouka”

The amazing Web app I built in one hour. It even has emoji support!

Once I landed in Japan, I pushed the new code, and set the project aside for the next 6 weeks. Well, except from occasionally answering questions from Elad and Benny, who continued to work hard to ensure that we would get the badges on time.

They received the new PCBs with the latest additions. This time, instead of trying to hand-assemble them and pondering why half of the hardware doesn’t work, they decided to take a different route and hire a professional assembly company in Israel, one with dedicated equipment and an X-Ray machines. This was quite pricey, so we only sent them 2 boards, each accompanied by 85 components for assembly.

It took another week until we got the following photo from them:

Apparently, at some point, we decided to upgrade our Flash memory from 2MB to 16MB, but we never bothered to ensure that the footprint of the larger Flash chip was the same. Oops…

After a quick discussion we decided to go back to the original 2MB flash, and Benny started to work on delivering the binary that will be programmed on the the nRF52 modules. As I mentioned above, we wanted them to have a bootloader, as well as a quick code that will test all the hardware and will give us the confidence that it works before it left the factory.

Meanwhile, Benny and Elad received the assembled boards and tested them. All the hardware worked, except for the sound — for some reason, even when soldered by professionals, this chip simply refused to talk to our CPU. With less than 6 weeks until the conference, we decided to stop investing time in trying to make the sound work, and move on to manufacturing the final boards.

When the cheaper “Good Display” E-Paper panels have arrived, we discovered that their controller chip was not supported by Zephyr. The previous Waveshare panels used a chip called SSD1673, which had a working driver in Zephyr, and was also present in the smaller “Good Display” panels. Their 2.9" panels, however, included a totally different chip called IL0373. What a joy!

IL0373 had very little documentation, which didn’t really explain which commands you need to send it in order to initialize the panel, let alone display anything to the screen. Luckily, we stumbled across the GxEPD2 Arduino library, which had a functional driver for this chip.

Benny and Michel started porting the driver into Zephyr, and at some point they got it almost working: it would display text to the screen, but the text would be garbled and unreadable. As the clock was ticking, they decided to send the code as-is to the factory, without even adding the bootloader.

Meanwhile, I was enjoying Japan:

Mochi, Yummy! 🍡

Elad sent the final code to EByte. It was just the hardware test program, without any bootloader. They programmed the nRF52 modules and sent them to the assembly factory. We wired the money to the factory, and crossed our fingers to have the boards arrive on time, as we had exactly four weeks to the conference.

A week later, they updated us that they were still in the process of sourcing the components, the PCBs were finished and they hoping to start the assembly shortly. We waited for another week, and then got a mail with a few questions about the orientation of the diodes and one of the chips.

For some reason they used a spreadsheet for the questions. Go figure..

We quickly answered them, yet we missed one crucial issue:

Can you spot what’s wrong here?

With only two weeks until the event, Elad quickly answered and told the factory that the display connector was fine, hoping that they will begin the assembly ASAP. And so they did. A few days after, we received another email from the factory, asking us to look at the E-Paper connector issue again.

This time we did notice the issue — the screen was upside down!

This meant that the panel would face the PCB rather than the user, and even worse — all the electrical connections would be reversed, rendering it totally useless!

and… we only had 9 days until the conference 😱

‎9 Days To Deadline

It was my last day in Tokyo when Elad pinged me and told me about the unexpected last-minute issue. We spent several hours trying to figure out what lead to this situation, and brainstorm possible solutions.

We traced the issue back to when we first added the display connector to the board design. We used a footprint for a part called “FH12–24S”, and ordered what we though to be a compatible part. When we hand-assembled that board, however, one of the MOSFET started to let out magic smoke and we figured out all the connections were reversed. So we reversed the footprint, thinking it was the culprit.

Apparently, that decision has now backfired, as we still had the “FH12–24S” connector in our BOM, and that connector had bottom contacts, opposed to the connectors we used for our prototype, which had top contacts. So all the connections were reversed again!

We asked the factory whether they could change the connector, but it turned out this was too late, as they already assembled all the boards at that point, and manually removing the connector from 200 boards would require a lot of work and take a considerable amount of time, time we did not have.

8 Days to Deadline

I was on my way to the airport when I got another message from Elad. The factory came up with a creative idea how to reverse the contacts, using an extender cable and female-female connector:

The proposed solution

I wasn’t 100% sure I understood how the items in the above picture would fix our problem, but we had nothing to lose, so we asked them to order these parts ASAP and try to still ship the project to us before the deadline.

7 Days to Deadline

We got the following video from the factory:

The display worked (albeit it just flashed because of the half-baked driver), so it seemed like their workaround did the trick. What a joy!

A few back-and-forth emails to explain to them that the screen blinking with garbage is actually a good sign, and to coordinate the delivery. They promised to finish everything the next day and pack it for shipping. So there still was a small chance…

6 Days to Deadline

We pinged the factory to ask if they shipped the boards and could send us the tracking number, but received no word from them. Meanwhile, I got back home and started fixing the issues with the display driver together with Benny.

Elad purchased some yarn for the lanyards and batteries for the tags:

Poor man’s lanyard

Meanwhile, Israel had almost landed on the moon:

4 Days to Deadline

Still no word from the factory. We truly hoped they shipped the package and just forgot to tell us, and we kept working on the code. The boards were programmed with just the test code, and no bootloader, so we also needed to have some way to quickly program all the 200 units when they arrived.

Elad came up with the genius idea of creating a programming jig from a clothespin:

A creative man’s programmer

And then there were three…

3 Days to Deadline

It says that the shipment is on its way

The tracking link revealed that the package was still in Hong-Kong, and should be in Israel within two days. Pretty borderline, but there was still hope!

We finished fixing the issues with the display driver and started writing the initial badge app functionality: displaying the agenda, and displaying the owner’s name (based on the code I started hacking en route to Japan):

2 Days to Deadline

We got a phone call from DHL, telling us that the package had arrived, but we needed to sign a power-of-attorney form so they could release it from customs. We drove to the DHL offices and did the paper work, and they told us they hope to complete the customs clearance by the next day.

Nir thought that wearing a shirt with the DHL colors would help to expedite the process

1 Day to Deadline

Paperwork…

Elad called DHL first thing in the morning, and they told us that they still haven’t submitted the customs papers, as they needed some more information from us. The papers were only submitted in the late afternoon, and we were told there is only a slim chance the package will be released that day.

A One-pager we prepared to explain the customs about the product

I spent the day adding more features to the code and perfecting the user interface of the control app:

Some Angular + Material Design love!

I also hacked together a small Android app that allowed us to change the color of the LEDs for everyone at once (implemented using Bluetooth Low Energy broadcasts). To make it more fun, I also added voice control using Android’s SpeechRecognizer. I haven’t done Android development for years, but Kotlin made it really easy!

Around 6pm, we drove again to the DHL offices, hoping that the package has been released. We were really lucky to get the package just a few minutes prior to closing time, and for the first time, held the final product in our hands!

A moment of great joy!

So romantic with the DHL trucks in the background

We went to the conference venue, and started a nightlong assembly and programming “party”:

The Night Before 🌛

Elad did all the manual assembly work:

We had 12 trays of displays to assemble and tape to the badges

An innovative lanyard cutting machine ✂

One batch of badges ready to be programmed

Benny and Gadi worked on tweaking the code and fixing some last issues, such as centering the QR Code displayed during the provisioning process, or persisting the owner’s name to the flash memory. Then they started programming the badges:

Programming one at a time using the improvised clothespin jig

I spent most of the night working on slides deck presenting the project. We were so busy finishing the software and dealing with all the unexpected issues we totally forgot that we had a 30-minute talk slot at the beginning of the conference.

We were really tired and had a lot of trouble programming the badges, and by 4 am we only managed to program 25 units or so. I finished the slides and went to sleep, while the other friends kept working relentlessly. To be honest, I was sure they will also fall asleep, but they were just too determined to get all the badges ready. And so they did.

It was about 7 am when the last badge was programmed and tested, just as the conference was about to start.

WE DID IT!

The Conference

The badges were a hit. Everybody loved them, and for the most part, they worked well. We included a small game where you could light up and vibrate the badges of the people around you by pushing one of the buttons on your badge, and it was fun seeing our friends interacting with each other this way.

I gave my talk, telling this story. Then I asked everybody to hold their badges up in the air, dimmed the light, and lunched the small Android app that controlled all the badges. I said “Yellow”, and a second later, all the badges lit the room with a strong yellow color. It was the most satisfying moment in the entire project!

The badge team

The attendees used our web app to display their names on the badges, and also got pretty creative with the mechanical keys:

This reminds me of “Invaders”

Elad’s badge

There was one thing that didn’t work as we expected. As soon as people left the auditorium for the first break, their names started fading out and disappearing from the badges.

We haven’t tested the E-Paper under sunlight before, and were very surprised they behaved this way. I guess this has something to do with how UV waves and electrons interact.

Anyway, we quickly found a workaround. We discovered that this issue only happens when the display is powered, so we asked everyone to switch off their badges before leaving the room. The E-Paper display retains its content even without power, and so their names were still displayed and were no longer fading out.

Faded display under sunlight

At the end of the day, we checked the usage statistics of the Web application that configured the badges, and were delighted to see it has been used almost 500 times:

3 users from Moldova? interesting…

This is just the beginning…

The conference is over, but the project isn’t over yet. Benny is working to bring better CircuitPython support to the board, and we plan to host a Hackathon where the attendees will install Python and program their badges.

I keep using my personal badge for events, such as my IoT Makers Meetups:

As you probably remember, we wanted to have a headphone party with all the badges. We haven’t finished this feature in time for the conference, but we tested the sound chips on some of the badges and they seem functional. We plan to continue working on this feature and have a “Badge Headphone Party” some time in the future.

I wrote a CircuitPython script that turns the badge into a clock

The entire design and code is open on GitHub under the MIT license. The open designs from “reel Board”, Adafruit, and Waveshare were really helpful for our project, so we decided to return the favor and contribute our work back to the community.

Overall, this was a hell of a ride, and I’m grateful I got the opportunity to work with Ariella, Elad, Benny, Nir, Gadi, and Michel, and create a functional product in time despite all the unexpected challenges we encountered.

Thank you!