Out of college
I graduated in January 2014: one of the coldest winter months in Denmark. I graduated with good grades and was somewhat confident that I was ready for whatever the world had to offer. Or so I thought.
I was 26 at the time, and even though I had graduated with a B.Eng. in Electrical & Electronics Engineering, I wasn’t quite sure what I wanted to do. What I knew for sure was this: I loved to code. For my bachelor project/thesis, I developed an Arduino-based semi-automatic guitar tuner together with 2 classmates. I wrote the entire code for that project.
Now and then, I occasionally read my thesis code, and can’t help but laugh my ass off. If I were to grade the code now, I would give it a big fat F. It was crap: if I’m being completely honest with myself. Mind you, it worked (mostly), but it was crap.
The first job
A few weeks after I graduated, I spent the next 4 months sending out job applications. I was one of the very lucky ones: graduated in January, landed my first job in July that year. I remember feeling excited and overwhelmed on my first day. I freaked out when I saw the code. It was a lot of code. I had never seen so much code in one place.
I was assigned a mentor to show me the ropes, and I’ll say this: it was one of the best things that happened in my career. I had someone to show me the right and wrong way of doing things, especially coding.
The mentor: the turning point
My mentor’s name was Kent, and he was one of the seasoned developers at the company. He was very particular about doing things the right way. I remember how he would scrutinize every single line of code I wrote, and how I would get mildly annoyed whenever he pointed out something I considered trivial.
I came to understand and appreciate Kent’s mindset after I left the company almost 4 years later. Now, more than a decade into my career, I admire and appreciate Kent more than ever. Looking back, I realized he was an amazing mentor.
Lessons learned: so far
The biggest lessons I learned from Kent (and I hope you learn them too):
-
Always code to handle worst-case scenarios. Anyone can write “sunny day” code. Being able to write code to handle failures is the mark of a mature engineer.
-
Always be critical of your own code. As you code, continuously ask yourself “is there a flaw in this logic?” Make it a habit to assess the flaws in your logic. It’s a habit that will potentially save you hours of debugging.
-
Be open to criticism. Others will always review your code and you should expect both positive and negative comments.
-
Always have the mindset to do things the right way. It’s easy to hide behind “I’m under pressure” or “it’s fine as long as it works.” In my experience, hacking your way out of problems will come back to haunt you: 99.9% of the time.
-
Test, test, and test!!! You can never test enough. My advice: setup testing from day one. The longer you delay, the more difficult it becomes to integrate.
-
Never make assumptions! It is critical that you are honest about your work, skills, strengths, weaknesses, and expectations. It’s okay to say “no,” “I don’t know,” or “I’m not sure, I’ll look into it.”
-
Take responsibility, and never make excuses! My absolute personal favorite excuse: “it worked yesterday.” Don’t ever say that. Live and learn.
Key skills to build
As an embedded software engineer, you are expected to have quite an array of skills. My advice: find a good mentor, and at the very minimum, learn how to:
-
Write decent code in C (C++ too, but concentrate on C first). Understand how to use pointers. They are powerful but can spell disaster if not used properly. Pointers! Pointers! Pointers!
-
Understand software design patterns: learn to use the right design pattern for specific projects.
-
Use at least one embedded OS: I’d recommend FreeRTOS to begin with. Learn when to write bare-metal code versus multi-threaded code.
-
Use an oscilloscope/logic analyzer: vital for seeing signals in real time and debugging your code when things go wrong. Always expect things to go wrong.
-
Understand the hardware. Learn microcontroller architectures and communication protocols (UART, SPI, I2C, bit-banging), ADC, PWM, Timers, Watchdog Timers, etc.
-
Use SDKs. Virtually every microcontroller vendor has created SDKs to accelerate development. Learn how the SDK is organized and learn to use it properly.
-
Read and understand a datasheet. Datasheets can range from a few pages to thousands of pages. Develop the skill of reading them and knowing how to extract necessary information.
-
Write test code, especially in Python. Develop a tester’s mindset.
-
Use Git. It’s the de facto standard for version control these days.
-
Document code. Make it a habit to document as you go along. Learn to use Doxygen.
-
Automate repeated tasks. Develop the habit of automating repeated tasks: bash/batch scripts to build code, run tests, etc.
Conclusion
I’ll say this: I’ve learned a lot, and I’m certainly looking forward to learning so much more. I can also honestly say that embedded software development is not for the faint of heart. You will spend the rest of your career making mistakes, learning new ways of doing things (and losing your hair). Learn to love the process: that’s the best part for me.