This series is meant to give a deeper look into the challenges you are likely to encounter if you decide to turn a maker project into an actual IoT product. It's based on my experience over the past two years of creating a product from scratch. If you missed part 1 you can find it here.
Last time we talked about a few of the hardware obstacles you'll run into when creating a product. In this part of the series we're going to talk about the challenges that are probably more in your wheelhouse; firmware programming.
Getting to what I call "hardware complete" is the best feeling. You're done with the back and forth of fab and assembly and, even better, you're done draining your bank account. Well, for now. You've probably been working on the firmware code all along but now you are ready to focus on it completely. This is where you are most comfortable. In the IDE or text editor of your choice beautiful keystroke follows beautiful keystroke as you hammer out features and functionality. So what could go wrong here.
If you're like most makers your original prototype firmware is probably a hot mess of glued together library code that you didn't write. It all just worked. "I'll just polish it up a bit and we should be good." It's at this point you realize those nice, open source libraries aren't as production ready as you thought. As your feature set grows you start to find the cracks. Gasp, turns out there are actually lots of bugs in this code. You go to file an issue on the repo and find that it's already logged along with 57 other issues. "WTF! Why isn't this person who works for free to support the community solving these things? I'm trying to get this product out the door. Upvote. Upvote. Upvote."
This gap actually surprised me more than it probably should have. The people at Sparkfun and Adafruit are smart and talented people. But they aren't production library maintainers. They write sample code to sell more products to makers. And that sample code largely supports simple projects and use cases. And it does so very well but you will find that most of those libraries are either not production ready or have feature gaps that you need filled. And as for everyone else out there generously writing free code for you, well, they are just normal guys and gals that wrote some code for their project. They don't know or care about your product and they too have no interest in being a free-labor library maintainer.
At this point you have two options, fix the 3rd party open source code or roll your own (there is actually a 3rd option, kinda, that we'll discuss in a minute). Your built-in programmer DNA is going to scream at you "DO IT YOURSELF! You don't want to have to figure out and fix this other person's code. Your version will be 100 times better anyway. We GOT this! ✊" And your programmer DNA may be right. Let's explore both paths.
If you have any experience at all you know this is likely to turn into a rabbit hole. You take too much pride in your own code to rush out shoddy work. You are going to write the most beautiful temperature sensor library the world has ever seen. And that's fine, but it's going to take you time, perhaps lots of it as you figure out all of the nuances and gotchas inherent in writing firmware libraries for physical devices. Be prepared for this to take longer than you expected. At the end you'll have another one of those libraries that's perfect for you. You can open source it and maybe somebody else will use it for their prototype before throwing it away when they decide to start their own product journey. The cycle continues.
You decide to fork the repo and address the things you need fixed. This is going to be like hopping into any piece of code you didn't write. The original author's style is going to be different than yours. Things that don't make sense maybe have a perfectly good reason for existing. You'll have no context unless you want to read every commit back to initial. You're going to have to go through the learning curve of assimilating another person's codebase and then fixing it. It's going to take longer than you think. In the end you fix the issues and you get back to the core firmware. That's awesome but remember that you are now the owner and maintainer of that library.
One of the first things you are going to find as you dig deeper into your firmware is that you don't have that beautiful F5 option to spin up the debugger. Line by line debugging firmware on a device is messy business even when you have all of the proper equipment. I really hope you had that schematic/PCB freelancer break out JTAG pins on your board. If not you have no option to line-by-line debug. But, now that you know that's important, let's assume that you did. Stepping through code using OpenOCD is non-trivial. At least that's been my experience. Even when I was able to step through code it exhibited weird behavior like executing several lines of code twice that weren't enclosed in a loop. Sometimes things will disconnect abruptly. Remember, you are communicating with a device across physical wires.
Oftentimes you'll find good ol' fashioned
println is the way to go. Or even more primitive on hardware devices the 'ol blink an LED 8 times to indicate a connection error and 9 times to indicate a socket error. The common theme here is that everything is going to take longer than you think it should.
As mentioned before you're probably using a fair number of open source libraries you cobbled together in your prototype. During that "just polish it up" portion of creating your product you need to look at all of the licenses on those libraries. It's very likely that one of those license will be, what I call, a virus license like GPL or AGPL. That means that you must inherit that strong copyleft license for your product and release it publicly. You may be fine with this. If so, you don't have much to worry about and you can go on your way. Feel free to skip this section as it won't apply.
Before I go further I want to be very clear that I am pro open source and improving the community. I have released many repos to the public domain to help other makers. I simply prefer to do that under more permissive licensing such as MIT or even LGPL. I don't personally agree that simply using an unchanged library that is AGPL-licensed should require that your entire project be licensed as such. But I digress, let's get back to the point of this section.
One thing I would like you to consider is that you might want your firmware to be closed source. Why? After you've spent all of that time and money we talked about in Part 1 of this series your beautiful working hardware is a few hours away from being completely reverse engineered by someone who knows what they are doing. Your hardware is a commodity that can be easily copied and reproduced. What is less easy to duplicate, although not impossible, is your firmware. As such, you may want to keep it proprietary to give you some amount of protection from copycats. Remember, this isn't a maker project, it's a product you want to sell for profit.
Let me share an example from my journey. My product contains a display. During prototyping I used a combination of libraries including a driver for the display and a graphics library to draw things on it. I soon found out that the display driver uses a GPL license which would require my firmware to inherit that same license even though I had made no changes to the library. I would have to open source my entire code as GPL just because a portion of my product used that code. That is not something I was interested in doing. Instead I wrote my own driver from scratch using example code from the display manufacturer which is unlicensed (they sell displays, not libraries). This took me the better part of two months. It was a huge time sink. Be prepared to either go with the flow of licenses you use or rewrite portions of your firmware.
Now before everyone attacks me with the classic "So you just want everyone else to write open source code so you can profit from it?" Let me clarify. I never said I wasn't willing to pay for it. Read on.
When I worked on the Microsoft Internet of Things Maker team (best job ever btw) my manager always liked to say "Borrow, Buy, Build. In that order". The idea is that when building a new project from scratch you should first try to borrow existing code a.k.a open source projects. No sense in rewriting something that another person or team of people have already done. It's the fastest and cheapest way to get moving. If there is nothing to borrow then you should look to buy. This can be in the form of software packages or cloud services that can accelerate your development process. Finally, when all else fails, you should build which essentially means write it yourself. This is by far the most time consuming and expensive option which is why it's last on the list.
In the case of my driver dilemma I ruled out borrow because of the license. I would move on to "buy" but that simply isn't an option for almost everything you need in your product firmware. Firmware isn't like software...yet. There are not hundreds of shops out there selling all of the libraries you need. I absolutely would have paid either a lump sum or some form of licensing fee for a display driver to save me the time and hassle of writing it myself. But there simply was no option to do that. Thus I was left with building it myself.
There are literally thousands of sensors and chips out there you may choose to interface with. Some may have open source libraries and some may not. What is almost certain though is that there are very limited "buy" options for any of them which means you either have to accept the license or build it yourself. Even if you accept the license there is still the issue above of finding issues or feature gaps.
One of the biggest surprises in going through this process was how mediocre most of the open source libraries are for hardware devices. From obvious bugs to simply being written in a way that doesn't lend itself to running in an embedded environment. I've seen simple sensor libraries use half the flash and memory space of a microcontroller because programmers are used to garbage collection and having near-infinite resources. Just be aware that while your cobbled together prototype "works" you may need to invest a lot more time than you think in addressing firmware issues.
That's going to do it for part 2 of this series. Next up we're going to talk about device config and how you just became a full time customer service rep.