In Q1 2019 I had the privilege of leading a group of ten firmware, software and system engineers doing a grounds-up redesign of the machine control firmware and software control systems for the Just Baked Kiosk. The system had been under development for over two years when it came to us, but the control system had yet to process a full load of 72 servings without a failure. After about three weeks of core requirements development and control architecture design, the full team engaged. Within six weeks we had the machine running, delivering full loads and processing multiple orders at the same time.
Just Baked Pizza Kiosk
Overall, I was very happy with how the control system development went. The team also seemed pleased with how the project had progress, and we had a delighted client. After the project completed, the lead systems engineer asked me “What is it that lets you step back and let the various team members run with stuff?” Though my approach had been a bit ad hoc, thinking back on it I was able to identify three things that allowed our team to work together efficiently, and provided me the confidence to let each team member work without me feeling the need to manage every little detail.
The kiosk almost ready to fire up some fresh, hot pizza
1. Build a Great Team
First and foremost, you must recognize that the development of a complex product is a huge job. It’s going to take a team. As the technical lead, you need to build that team. I’ve been blessed with being able to hire really great people at Simplexity. We have a highly technical interview to test that engineering candidates understand the theory, and are not just tool jockeys. We couple that with checking for personality fit. We try to pay competitively, offer a good work life balance, have offices in desirable cities, and as an engineering services company, can offer a great diversity of projects. Altogether, that’s allowed us to build a really strong team.
Once you built your team, you have to keep them happy. With engineers, that usually means giving them challenging problems and getting out of their way. This is where technical leads and project managers often run into problems. Smart people need to feel that they’re contributing their ideas to the problem’s solution. You and the team together are way smarter than you alone. You’re paying each person for their brain, let them use it. If you try to do too much yourself, tightly controlling everything everyone else is doing, you’re going to both kill yourself and drive your team crazy.
As the lead, you’re accountable for the success of the technical development. The trick is balancing the control you feel is required to deliver while allowing the freedom that will get the best out of your team. The next two tips provide some tools for striking that balance.
2. Set the Team Up for Success
If everyone is off solving problems with their own great ideas, how do you keep the design from going in a million different directions? That’s a sure way to burn up all of your schedule and budget without completing the design. This is where you take the lead. For the Just Baked Kiosk, I spent three weeks at the start of the project documenting requirements and developing an architecture for the overall control system, its software and its firmware. This was my core technical contribution to the project.
Designing and documenting a solid architecture provided the team with a framework for success. The architecture gave the team:
- A decomposition of the overall design problem into sub-problems that individual members could attack. A technical work breakdown structure if you will. Note that this breakdown allowed me to define the sub-problems as I saw fit, which in turn allowed me to define high level solution approaches, leaving the low-level solution details to the individual engineers. This did take away some of their freedom but allowed me to align the team’s efforts.
- A map for how the pieces of the solution would fit together. As each piece became a workstream for a team member, it was clear to them with whom they would need to communicate based on the interfaces between their portions of the design.
Practically, this architecture took the form of many block diagrams, identification of interfaces, and sequence diagrams for the more complex interactions. Having that in place and reviewing it with the team gave them both confidence that we could do the job, and a map of their role in the project.
3. Communicate to Build and Maintain Trust
With the project set up and tasks assigned based on the architecture, the team is off and running solving problems and generating designs. So how do you stay comfortable with how the design is progressing, and with the solutions being implemented? You must trust your team, but blind trust will get your project in trouble. You and your team members will build trust through good communications and working together to make sure you’re aligned with the chosen solution. That doesn’t mean it’s always going to be the solution you would have picked, but it should be a solution that is reasonable and one you can get behind.
I used two techniques to help me communicate with my team members, and to build confidence that their work was progressing down the right path.
The first technique was design by example. I only used this a little on the project, as it is a bit heavy handed. The design pattern that I was most adamant that we on the project was to use finite state machines for control and synchronization of the various mechanisms in the hardware. The architecture called for seven unique state machines. As we were getting started, I picked one of the state machines and implemented it myself. I then reviewed my design with one of the engineers before kicking him off on the next state machine. He and I went through a few cycles of review on his design (before implementing, see below) until I was sure he understood the nuances of the design. He then trained two more engineers in how to design and implement our state machines. In that manner I got exactly what I was after, while reducing my workload and proliferating knowledge more quickly. In each of those training and review sessions, people were working closely together to develop the solution, building trust in each other and a stronger bond as a team.
The second technique I used was to treat each component as an individual, independent design process. For each one, the responsible engineer and I would work through the following process:
- We would review the component or subsystem’s place within the architecture, discussing the interfaces and general needs of the design. This usually took between five and 15 minutes depending upon the complexity.
- The engineer would then go and capture: the design requirements for the component, their assumptions about the design, and an outline of the design approach. This typically took ten minutes to an hour.
- They would then bring that back to me for review. It was amazing how many times we would discover a major disconnect that would have cost us days of development had the engineer started implementing a solution immediately. We’d iterate the design/review process as needed, until we were aligned on the problem definition and the solution approach. The more complex the component, the more detail needed in that up-front design.
- The engineer would then implement the design, along with unit tests and make sure tests were all passing.
- They would then submit the implementation for review by me and at least one other engineer. Code reviews are much simpler when you’re reviewing implementation against design, not everything at once.
- After the code review and associated updates were complete, the code was merged to the master branch and integration testing was performed.
The process of iterative design and implementation with intervening reviews kept the communication level high, in turn keeping up trust in the team and keeping my stress low. The engineers didn’t feel micromanaged as I wasn’t defining design details and stifling creativity, but rather we had a back and forth where we could align on a design that both agreed was the best. These solutions were often more creative than any one individual would have come with alone.
Following these three tips for leading a technical project, built trust and confidence within the team. Since that project, team members have been able to take what they learned on the project and expand on it, further enhancing our company’s capabilities. I hope that you find these tips helpful in your project leadership work.