Interviewing for an entry-level embedded systems engineering position

In my current position, I am often tasked to interview recent college graduates for our internships and also for our entry-level embedded systems positions. Since we are a relatively small company, we are looking for well rounded engineers with some general understanding of embedded software as well as circuit design. We need our new-hires to help designing new circuits at the schematic level, develop software for various micro-controllers and debug faulty circuit boards returned from the field.
Over the last couple of months I have interviewed dozens of candidates and I was shocked to see that the vast majority of these engineers, many coming out of prestigious universities, are unable to answer the most basic questions. I understand that job interviews can be a stressful event, but some of the most basic concepts should be second nature to anyone with an electrical/ computer engineering degree. In this post I will outline our technical interview routine, which does not differ much from other embedded systems engineering entry-level interviews. While the human-resources department is mainly interested in personality fit, the role of the technical portion of the interview, is to assess the candidate skills.

Unsolicited advice from the other side
For the young engineers out there interviewing, I have 4 general suggestions:
1- During the interview, do not drop industry-buzzwords that you don’t fully understand what they mean. For example, don’t say that you love chips manufactured by ARM. ARM does not make chips.
2- Come prepared with a portfolio with some of your work (e.g. source code, circuits, layouts, relevant blog posts) and leave a copy with the interviewers.This makes you look professional and organized.
3- In a technical engineering position no one is interested how cool the candidate was in college or how smart the candidate is for wanting to go to graduate school to learn more. In most companies there is a need for dedicated engineers to design, implement and maintain a project in its entire life-cycle. We simply have no time to train someone for a couple of months, so that they can jump-ship in six months to go to graduate school.
4- Go to interviews dressed business casual. I have noticed that the strongest candidates are usually the ones who don’t over-or-underdress.

Resume skill check
When we start the interview process, the first thing we do is re-read the skills section. If the candidate lists a particular skill, we will inevitably ask some very basic questions about it. For example, if C/C++ is listed as a skill, we generally ask the candidate to tell us the difference between C and C++. Unfortunately, only about 25% of the candidates know this.The simplest answer, as defined by the creator of C++ himself (Bjarne Stroustrup), is that C++ is C with classes.This would be the perfect time to talk about how C++ is an object oriented language and that objects allow the programer to secure (hide) data inside classes.The diligent engineer could also talk about how in C++, two functions can have the same name but different arguments (function overloading) and how variables in standard versions of C need to be declared at the start of each function. Similarly, if you do not understand the difference between Linux and Unix, do not put both on your resume.

Here are some of the commonly listed skills and some possible simple questions about them:
Matlab or Mathematica – Can you put 10 numbers in a 1D Matrix (orTable) and compute their average?
Linux – What is your Linux distribution? What command do you use to create and change a directory?
ASM – What does the command JMP do? What about MOV?
Python or Perl – Can you create a for loop that prints “hello world” 10 times?
HTML What does the and tag to?
Spice – Can you write a spice file with a circuit with a power supply and a single resistor?
Labview – Who makes Labview?

Finally, my recommendation is to avoid listing skills that you don’t fully understand what they mean. One of our candidates listed Xilinx as a software skill.This particular candidate not only did not know that Xilinx was a company, but he also could not remember the purpose of that particular piece of software (“I think it was to program some sort of chip.”).

Assessing the candidate interest in embedded systems
We are always interested in candidates with a passion for anything related to embedded systems, as these tend to be the strongest engineers. We often ask them where they buy their components, what electronics magazines they read and which websites they frequent. We also like to know what is their favorite prototyping system (e.g. arduino, raspi, beagleboard) and favorite programming language.We also like candidates to tell us about how they normally go about testing and implementing their prototypes. For example, how would they go about etching a PCB in their basement? While the answers to these questions are far from being deal-breakers, they do give us an insight about how passionate the candidate is about the field.
We also like our entry-level candidates to know a bit of whats out there. For example, what are the names of some companies that manufacture micro-controllers and the names of their products (e.g. Atmel manufactures ATmega328P which is used in the Arduino prototyping system).

The deal breakers
We have, what we like to call the “five deal breaker questions”. If candidate misses one of them, we cannot in good conscience hire them.
Question #1 – The most fundamental question regarding electrical circuit theory is how to measure current and voltage in a simple circuit. In the interview room we have a very simple circuit with a single resistor in a prototype board. After we power the circuit we give the candidate a digital multimeter and ask them to measure the voltage across, and the current through, the resistor; Voltage levels are measured by connecting the two probes across the resistor, while current is measured by opening the circuit and completing it with the multi-meter connected in series. Surprisingly about 10% of the candidates miss this question.

Question #2 – We need to know how confident the candidate is with basic circuit analysis. We draw on the board a schematic very similar to the one shown on Figure 1 and ask the candidate to determine the measured voltage across R2.


Figure 1 – Interview question: Determine the voltage across R2.

A confident engineer does not have to make any calculations.Two equal resistors in series with 10V across them, means that the voltage across just one of these resistors is 5V. The candidate can also determine this voltage by “hand”:

Ohms law implies that,
V1 = i (R1 + R2)
10 V = i (100 + 100)
So the current through R1 and R2 is 10 / 200 Amps or 20 mAmps.
VM = i (R2) = 10 / 200 * 100 = 10 / 2 = 5 Volts

One quarter of our candidates, most with degrees in electrical engineering had trouble with this question.

Question #3 – We also ask very simple practical design questions. For example, when should you use a transistor instead of a relay in a design? There are many possible answers here, and we are just looking for the basic ones. For example, you can mention that the relay, since it is an electromechanical switch, is much slower than a transistor, but it can usually carry a lot more current. Relays in general are also much bigger than transistors.

Question #4 – It is fundamental that our new hires know the purpose of basic circuit concepts. Here are the three short-answer questions we always ask:

Q:What is a servo motor?

It is a motor in which you can control the precise position of its shaft through a well-defined pulse.

Q:What is a potentiometer?

It is a resistor whose resistance can be changed by adjusting a knob, usually with a small screwdriver.

Q:What is does it mean for a signal to have 30% duty cycle?

It means the signal is in its high-state 30% of the time.

Question #5 – Finally, we always ask the candidate to explain what are the defining characteristics of an OP-AMP. Most candidates are able to tell us that the V+ and V- inputs have high impedance and they are often able to write out the (usually memorized) equations for OP- AMP circuits with a feedback loop. Unfortunately they can’t do much more than this, and the concept of the OP-AMP rail is often not understood.

We then ask the candidate to determine the output voltage of an ideal OP-AMP with a “comparator” configuration, exemplified in Figure 2.

The voltage across R1 is 15V. The two inputs V1 and V2 are compared and the output voltage will be set by the appropriate rail supply, which in this example is the one associated with the negative input (V3).


Figure 2 – Interview question: Determine the voltage across R1.

Alternatively we also ask about the purpose of the voltage follower configuration, shown in Figure 3.


Figure 3 – Voltage follower op-amp configuration: If the voltage V1 is both at the V- and VM1, what is the purpose of this configuration?

The voltage follower with an ideal OP-AMP gives simply V1 = VM1. However, because the high input impedance, the OP-AMP output (VM1) is isolated from the OP-AMP input (V1). In essence the current drawn from the circuitry connected to the output is not drawn from the signal source at the OP-AMP input, but from the OP-AMP rails.

Basic Embedded-C
We need our candidate to know how to program in C.There is no work around this one; the embedded systems engineer must know how to handle the most basic programming tasks.
Question #6 – The first programming question is always about distinguishing between the ‘=’ and ‘==’ operator (‘=’ is assignment, while ‘==’ is a comparator).
Question #7 – We then ask the candidate to write out the C-code that solves the commonly used fizzbuzz problem.The assignment is as follows:
“Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.”

While this is not a particularly hard, most of our candidates were unable to solve this assignment. Here is a possible solution:

We always ask something related to C-pointers. We understand that pointers can be a bit confusing to engineers, but the candidate must have at least a very general concept about what a pointer is.

Question #8 – Consider an integer k. How do you change its value through a pointer?

If the candidate shows confidence with pointers we normally ask slightly more advanced questions. For example,

Question #9 – What is the benefit of passing elements to a function by reference instead of by value? Can you write a small piece of code that demonstrates passing by reference?

Every time something is passed into a function by value, it is pushed down into the stack. If we are sending a structure with 10,000 members, all those members will be pushed down, needlessly using a lot of memory space.

Intermediate Embedded Systems topics
At this point we have a pretty good idea about the candidate and his abilities. If time allows we ask slightly more complex questions, allowing us to differentiate between the strongest candidates.

Question #10 – Consider the generic schematic on Figure 4. In this circuit, the solenoid L1 has been energized for a long time and suddenly we open the switch SW1. Can you foresee any problem? What can be done to fix it?


Figure 4 – Interview question: What might happens when we suddenly open SW1?

When the solenoid L1 has been energized for a long time, it behaves as if it were a short with current flowing from the positive terminal of the voltage source to its negative terminal. When the switch is opened, the inductor will attempt to resist the sudden drop of current. A large negative potential is created where there once was positive potential, and a positive potential is created where there was once negative potential. This large potential difference can cause the electrons to “arc” across the switch.
A flyback diode solves this arc problem by allowing the inductor to draw current from itself in a continuous loop until the energy is dissipated through losses in the wire and across the diode. This is shown in Figure 5.


Figure 5 – Correct location and orientation of a flyback diode.

Question #11 – What is the purpose of an H-Bridge? Can you draw a generic H-bridge schematic?

An H-Bridge is a circuit that allows us to control the direction of current flowing through a solenoid (e.g. a DC motor). Figure 6 shows how to control the direction of the current through L1 with the state of the switch SW1.


Figure 6 – Generic implementation of an H-Bridge using npn-transistors.

Question #12 – Consider the very generic circuit on Figure 7. What happens when SW1 changes states?

Whenever SW1 is open, no current will flow into the base of the Q1 npn transistor, so the bjt will be OFF. This means both inputs of the NAND gate will be pulled to ground (which is a zero binary sate). Two logic-zeros at the input of a NAND gate imply a logic-one at the output. Since the output of the NAND gate is at the same potential as V1, no current will flow through R2 and D1, which means the LED will be off.
If SW1 is closed, the Q1 bjt will be ON, and the inputs of the NAND gate will be set at logic-ones. This implies a logic-zero at the output of the NAND gate, which in turn enables current to flow through R2 and D1.


Figure 7 – Interview question: What happens to D1 whenever SW1 is pressed?

Question #13 – What is an interrupt?

An interrupt is the result of an event that tells the microprocessor to stop executing the current task, when appropriate, and execute another piece of code, called the interrupt service routine (ISR).

Question #14 – What is RS232?

RS-232 is a communication standard for a series of standards for serial binary signals. This standard defines the electrical characteristics and timing of signals, the meaning of signals, and the physical size and pin out of connectors.

  • In RS-232, user data is sent as a time-series of bits.
  • Both synchronous and asynchronous transmissions are supported.
  • The RS-232 standard defines the voltage levels that correspond to logical one and logical zero levels for the signal: valid signals are plus or minus 3 to 15 volts; the ±3 V range near zero volts is not a valid RS-232 level.
  • The devices at both ends of a RS-232 compatible cable agree on the bit transmission rate (e.g. 9600 baud, which corresponds to 9600 bits transferred per second).
  • Conclusion
    Even with a relatively straight forward interview process, with a strong emphasis on the basics, we have had a difficult time recruiting skilled recent graduates. For those looking for a entry-level position, I strongly recommend to come prepared to the interviews. Spend a couple of days solving technical exercises straight from inexpensive books such as:

  • Schaum’s Outline of Electronic Devices and Circuits, by Cathey
  • Schaum’s Outline of Basic Electricity, by Gussow
  • Practical Electronics for Inventors, by Scherz and Monk
  • In addition keep reading and subscribing to magazines such as Elektor, Make, Circuit Cellar and, of course, Nuts And Volts.

    Sending J1939 CAN-BUS messages with Sparkfun CAN-BUS Shield

    Keeping in the spirit of open-source, I have modified the libraries of the Sparkfun CAN-BUS shield. With these updated libraries we are now able to send messages using the standard identifier (11 bits) and also send messages with the extended identifier (29 bits).

    I am running the following code in Arduino UNO. Keep in mind that this particular CAN-BUS shield does not work with the Leonardo Arduino board mainly because the SPI pins were moved around. There are workarounds, but they require some understanding of the SPI protocol and how different Arduino boards are mapped. This is fairly well explained in Exploring Arduino: Tools and Techniques for Engineering Wizardry.

    Anyway, here is a simple Arduino program that continuously sends J1939 messages through the CAN network.



    Screenshot of the sample arduino CAN messages captured with the program CANviaUSB

    The updated MCP2515 libraries can be found at http://www.nunoalves.com/source/canbus_nca26_09_2012.zip. To install this library and use it with your Arduino projects just drop it in the appropriate sub-directory (e.g. ~/Documents/Arduino/libraries in macosx). For reference here is the data sheet for the MCP2515 SPI CAN transceiver. I found all the information in there.

    Finally… a big thank you to Fabian Greif and his initial efforts on the MCP2515 library.

    Automatically leveling your Castlevania character with an Arduino

    I love playing video-games. Rarely play more than 1 hour a week these days… but when possible I log in my PS3 and put some time into old school PSone games… in particular Castlevania: Symphony of the Night. Phenomenal game! The only problem… is that there is some annoying grinding component to it.

    Anyway, on the weekends I also love spending time with my son. Unfortunately, my son is 1.3 years old which means i can’t play with both at the same time. Time to optimize! I created a very simple system that repeatedly presses the same button over an over again. When the character is in an adequate location, it will repeatedly kill any enemies that are walking in his direction.


    The point? I want to play the hard bosses and skip all the grinding. This simple contraption does the job. It is not pretty (all materials used were scavenged from here and there) but it works.

    Here are two videos showing the machine in action…

    And of course the Arduino source code… Everything was made, assembled and implemented in about 15 minutes. Automation FTW!

    Start a C program when BeagleBone boots

    I’ve been spending some time lately trying to turn the BeagleBone into a “single-serving” system for my prototypes. Most of these prototypes require running some program whenever the system gets power. Before you continue, I strongly recommend you read my previous BeagleBone posts, if you start feeling a bit lost.

    So here I have a very simple circuit… 5 LEDs connected to 5 different pins (P8_3,P8_4,P8_5,P8_11,P8_12). I would like these LEDs to display a perform a simple pattern whenever the BeagleBone is turned ON. Something like the following video.

    The code for this circuit is pretty straight forward and looks like this:

    To compile and run this code, download my BeagleBone_IO library, save the above code as main.c and type the following commands:

    gcc -c BeagleBone_gpio.c
    gcc BeagleBone_gpio.o main.c -o main
    ./main

    What is neat about my code, is that it is able to trap a signal whenever the user types CONTROL+C and ends the program normally… after performing some generic BeagleBone GPIO cleanup.

    Anyway, I would like this program to run whenever my BeagleBone starts up. BeagleBone’s default OS is Angstrom Linux which uses systemd as the initialization scheduler. I am still learning about this, but according to the wikipedia entry and also to Kezhong’s Weblog, this daemon is meant to efficiently express services dependencies, by allowing more services to be launched in parallel at system startup while reducing the need to mess around with many scripts. I used to do this on ubuntu… and it was a mess.

    Anyway, I would like to declare my LED blinking program as a service. So I need to execute the following steps:

    Step #1: Create a script that will call the program that you wish you launch at boot time
    This means we need to create a file in the /usr/bin/ directory with any name. For example, assuming that our compiled LED program is in /home/root/main we can create an executable simple script called myScript.sh with the following lines of code.

    echo “#!/bin/bash” > /usr/bin/myScript.sh
    echo “/home/root/main” >> /usr/bin/myScript.sh
    chmod u+x /usr/bin/myScript.sh

    Step #2: Create the service file
    Create the file /lib/systemd/myScript.service . Actually your service name can be anything you want… not restrained to myScript.service.

    nano /lib/systemd/myScript.service

    Step #3: Write the appropriate service settings
    Your /lib/systemd/myScript.service can be for example:

    [Unit]
    Description=Run the LED pattern script
    After=syslog.target network.target

    [Service]
    Type=simple
    ExecStart=/usr/bin/myScript.sh

    [Install]
    WantedBy=multi-user.target

    Step #4: Make a symbolic link

    cd /etc/systemd/system/
    ln /lib/systemd/myScript.service myScript.service

    Step #5: Make systemd take notice of it, activate the service immediately and enable the service to be started on boot-up

    systemctl daemon-reload
    systemctl start myScript.service
    systemctl enable myScript.service

    After executing all commands on step 5, the LED program should immediately start. Try switching the BeagleBone power OFF & ON… and you will see the LED program.

    How to terminate the script that is constantly running in the background?
    If everything went okay, your script in constantly running in the background. To terminate it, you need to kill it. Use the top command and find out the process id (pid) of your looping program. As shown on the screenshot, my main pid is 13.



    Listing all jobs

    The following command will take care of terminating the job.

    kill 113

    How disable the script from starting up at the boot time?
    Just type:

    systemctl disable myScript.service

    Thanks to Piranha at the official BeagleBoard forum for guidance.

    Controlling a HD44780 LCD on a BeagleBone (Part 2)

    On the previous post I described how a HD44780 can be integrated with a BeagleBone. For this post, I created a small HD44780 library for the BeagleBone that makes the process of writing text to a LCD as easy as it was on the Arduino.

    First of all you need some files. Go to the github for this project (https://github.com/nunoalves/BeagleBone-HD44780) and place the following files into your BeagleBone:

  • beagle_gpio.c
  • beagle_gpio.h
  • beagle_hd44780.c
  • beagle_hd44780.h

    These files provide all the necessary LCD I/O. In this post we will be discussing the example_03.c and example_04.c files that are also available on that same repository.

    Once the files are on your BeagleBone, make all the appropriate connections, exactly as described on the previous post.

    Instead of describing every single function in detail, its probably easier if you look at the following code (example_03.c), which performs some very basic LCD operations.

    You can compile, and run, this code with the following commands:

    gcc -c beagle_gpio.c
    gcc -c beagle_hd44780.c
    gcc beagle_gpio.o beagle_hd44780.o example_03.c
    ./a.out

    This next sample code (example_04.c) shows how to write full strings and how to address a particular LCD position.



    Running the code from example_04.c on a BeagleBone with a HD44780 compatible LCD

    You can compile, and run, this code with the following commands:

    gcc -c beagle_gpio.c
    gcc -c beagle_hd44780.c
    gcc beagle_gpio.o beagle_hd44780.o example_04.c
    ./a.out

    Have fun!