WHEN I WORKED ON A PROJECT: ‘We should not be afraid to start over’ – an interview with David Markesic, Senior Embedded Software Engineer
How do you know when a return to launch is the right step? In order to bring a project to completion effectively and on schedule, what is the best approach to not lose perspective during the course of the project?
Read an interview with David Markesic, our Senior Embedded Software Engineer based in the Zagreb office since 2021. In a chat led by Marija Jurina, our Employer Branding Specialist, David spills the beans on his journey in this field, the lessons learned, and why sometimes it’s okay to hit the reset button on a project.
Marija Jurina: Hi David, so great to have you sharing knowledge and experience. To start with, how long have you been working as an Embedded Engineer and how did you end up in this area of IT?
David Markesic: Hi, thanks for inviting me, happy to be here and share my career path. This year, it will be 8 years working as an embedded engineer. Initially, I started working as a hardware engineer but I always dabbled in embedded software with the aim of bringing the hardware to life. This passion grew organically during my career and soon progressed to full embedded software development.
I understand that in one of your previous projects you encountered an interesting challenge of communication between the 3G modem and microcontroller (MCU). To share a real-life example, can you elaborate on what was the initial idea and the need in this case?
Yes, I would be happy to elaborate. The initial idea was to use a 3G modem as a source of wake-up for MCU over the internet. To briefly elaborate – the 3G modem had to keep the connection to the internet alive while the MCU was offline and only wake-up the MCU on connection error or wake-up request. The reason lies in the fact that we needed to reduce battery power consumption while the device was off. MCU was only used to configure mobile network internet connection and connection to the server used for wake-up requests. Communication (configuration and data exchange) was done using AT commands. For proper configuration of the 3G modem, which would cover all use cases, a fairly complex configuration sequences with a lot of different decisions based on the responses of 3G modem was needed. Thus, I was tasked with creating a proper parser for AT commands that could handle all of the complexities of the use case.
What was needed to simplify the decision-making based on the responses from the 3G modem?
3G modem communication was done over UART using AT commands. In order to properly configure 3G modem to maintain a reliable internet connection the parser had to handle complex sequences of AT commands that needed to be sent, received, and processed. In this case, the response was strings which contained a mix of strings and numbers. Thus, the parser I developed needed to fulfill a dual function – on one hand, it had to be able to parse the numbers in the strings to native numbers (integers) and also to be able to perform string extraction from the responses.
What was distinctive in the architecture of the parser that you developed?
I would say that the distinction would be that the parser did not try to use pattern matching or regular expressions (regex) on strings but rather it scanned responses character by character. This approach enabled me to avoid time-expensive operations with strings until there was a need for string processing. In this way, instead of performing string extraction only the indexes were stored.
After tokenisation, there were several different steps. First, the name was recognised followed by the response type, after which the data extraction and conversion was done if needed.
It is worthwhile mentioning that in this way we also gained an inbuilt comprehensive error checking of received responses. Basically, since the parser iterates over a list of tokens it knows what kind of tokens to expect or rather which tokens are valid based on the specification of AT commands and responses for the 3G modem thus enabling easier handling of errors. These steps coupled with the API for composing of AT commands enabled us to easily create and modify the command sequences for rapid development and a more agile approach to the problems that were discovered along the line. One thing that I want to mention is that the API for reading data from responses and API for composing commands formed a quasi-programming language well suited for AT command processing.
What was most time-consuming in the process of finding the solution?
The most time-consuming thing was trying to create a robust sequence of commands that would cover all of the different use and edge cases and the steep learning curve regarding mobile networks. Additionally, one of the big challenges was also the fact that the first attempt of communication with a 3G modem was done using simple response processing utilising the inbuilt functions, which simply matched formats of expected responses and returned parameters in string format. This greatly affected and complicated data processing and decision-making. The analysis of the use case and the requirements led me to conclude that the sequence itself was too complex and possible changes in the future would be very hard to handle if we relied solely on the inbuilt functions. In essence, the initial method was both too simple for the use case and not future-proof. Thus, after careful consideration, it was decided that the method of string matching should be abandoned and a different approach should be researched and ultimately implemented. To make the method as robust as possible and also future-proof, it was decided that the best way forward would be to replace the old approach with the string tokenisation approach, which I outlined above.
What could have helped earlier in the development process to speed things up?
I believe that it would have been beneficial to be more specific and detailed in the composition of requirements so that the software architecture planning could be done more effectively. A good basis in the form of clear and concise requirements is crucial for the planning and ultimately speed of the development process. From my experience, good preparation, focus on edge cases, and diligent research, with consideration of both the limitations of the inbuilt functions and future full-proofing while seemingly time-consuming result in a shorter development process overall.
Thank you for talking and sharing! If you could give one piece of advice to your fellow developers on how to find solutions more easily, what would it be?
I would say that we should always consider the end goal, of course. But also, ideas from other areas of IT may sometimes be applicable if adjusted to our problems, so definitely think outside the box and try to keep up with different research and ideas as much as possible.
Also, from experience, we should not be afraid to start over. It is sometimes more beneficial to abandon the current approach no matter how far in the development process it is, and try a different road that will address identified problems, enable easier maintenance, and incur less technical debt.
Are you looking for new career opportunities? Check out the open positions in Croatia!
About the author