Warning: this section is really lengthy, and probably would not be as helpful as the other sections. However, we faced many problems with our electronics as beginners especially with few people guiding us along. Hence, we hope that through highlighting our learning process other beginners can benefit! So read on to laugh at our incompetence or for a very long drawn explanation of why we chose certain components.


When we started RoboCup back in 2017, we were given a set of sensors / drivers that were the leftovers from whatever our seniors used. With these sensors, there was little documentation as they were usually from JoinMax (the company that produces the RCU and the motor we are currently using) and they were obsolete.

Making matters worse, a lot of them were already broken from years of use, so we were not always sure whether we were doing something wrong or whether the sensor itself was broken.

Motor Drivers

Our first challenge was to get a moving robot. To do so, at the very least we needed motor drivers and a compass. The only motor drivers we had were from JoinMax that had ports which were directly compatible with our motors (Tamiya connectors).

At that time, we had not touched Arduino programming yet, and the only time we interacted with anything similar was with LEGO in the WRO competition. Hence, we had no notion on how the Arduino controls the motor driver, and thus was clueless on how it even worked. We did not learn about the inner workings of a motor yet, thus we assumed that they were magic, that our motor could only work with motor drivers that were specifically made for it (e.g. had the same connectors). This cost us a lot of time as we went around finding this exact (very old) model of motor driver when most of them were broken already. However, looking back, this was the main reason we wanted to shift away from breakout boards and pre-made modules as we wanted to have a high level of understanding and integration within our circuits.

Learning points: All these misconceptions were cleared only when we started programming and thus started to understand how these sensors worked. Sensors cannot work without programming or wiring, so learning and doing both in tandem is essential to ensure full understanding of what you are doing. Also, do make use of the multitude of amazing resources available (for free!) on the web, or make use of your seniors and other connections to ask for help.

After moving away from the JoinMax motor drivers, we followed our seniors previous purchases to use the Pololu 18v17 motor driver. However, these were really expensive and we kept shorting them due to our negligence. To decrease the rate that we bleed money, we switched again to some cheaper Chinese VNH2SP30 breakout board (passed down from seniors also).

We then realised that the circuit on the breakout board was quite simple. Since we wanted to integrate everything in a bid to decrease unnecessary jumper cables and messiness, this was the main motivation behind our switch to surface mounted devices (SMD).

We did think about using the motor driver ICs on the Pololu motor driver (some TI DRV88xx) over the VNH5019 since the overall board size of the Pololu was tiny, however their schematics were not open sourced and the accompanying circuitry seemed much more complex.

Motor Current

After our light flickering experience and one of our batteries started bloating (presumably due to high current draw) we wanted to know exactly how much current our motors were drawing to cause that extreme power losses to the whole PCB. The VNH5019 motor driver we use has current sense functionality, and thus after the 2019 competitions we hooked that pin up to the Teensy and drove the robot around.

We found that the JoinMax motors we used drew over 10A every time it changed directions! This was with a max PWM duty cycle applied of ≈60%. Hence, after this investigation we decided to run wires outside of our PCB directly to motor drivers to prevent potential issues in our PCB.


When we were designing our first robot, we were handed an Arduino Mega and Nano to use as our µCs. We were told that the Mega was to be used as the main controller, and the Nano was there only to process the Ultrasonic Sensor’s data. However, using the Arduino Mega was way too unsuited for our usage: It cost SGD $50+ to get one, and it had too many pins which we would never need. While preparing for our 2nd RoboCup in 2018, it was one of the first things we wanted to change.

Initial Inspiration

One of the main teams that we looked up to at that time (and still do) was INPUT RCJ from Japan as they were really open with their blog which allowed us to learn a lot from them. In particular, while studying their poster we realised that they do not use an Arduino, but rather they use ST’s Nucleo boards. At that time, the concept of µCs was new to us: we thought the Arduino was just like the LEGO EV3, the only controller that we could use. However this opened up a new world of possibilities and choices, and eventually influenced our choice of µCs.

That year, the speed of the µC was important as that was the year we made the switch from IR to passive orange ball, and we didn’t know how much computing power we would need to detect it yet, thus more was better. Hence, we looked to 32 bit processors which were newer and had higher speeds. However, in that year we were still very inexperienced and thought that the Arduino IDE was the only (easy) way to program, and that was the main reason we chose the Teensy.

For our 3rd competition in 2019, the next thing to replace was the Nano: we now know that it is there to serve as a “second core”, a sub-processor, and not solely to process the ultrasonic sensor’s data. Although the Nano worked well for this purpose, we wanted to test something new for future development and use. Our first instinct was to go with ST’s Nucleo lineup as it was the first non-Arduino MCU we know of thanks to INPUT, and it was quite cheap. However, it was really huge and expensive compared to the “Blue Pill” board based upon a STM32F103C8T6. Upon further researching however, it seems to have some issues with its USB circuitry. We ended up settling on a cloned “Maple Mini” which was touted as a good alternative at roughly the same price to the blue pill.

328p Experiments

For one of our other projects, we required a very small and light PCB, hence we needed to integrate a µC directly rather than use boards like the Maple Mini. We first started with the ATMEGA328P because it was the most popular µC in the Arduino ecosystem, being used in the Uno and Nano. We referenced schematics of the Nano to figure out what external components (resistors, capacitors, etc.) the IC required. It ended up being quite a painless process, from designing to programming over ISP.

After that successful run, we decided to do the same with our 2020 robots. We chose the STM32F103 over the 328P because it was cheaper (economies of scale in china!) and apart from a few soldering issues it works well! In the future, we would definitely like to transition to smaller and cheaper µCs because the STM32F1 is overkill for our purposes, and smaller µCs with a TSSOP package are easier to solder anyways.


We did not want to program over USB for the STM32 because the proper reset circuitry was very complex. Hence, the other alternative was to use the Serial Wire Debug (SWD) interface. At this point, we programmed everything in Arduino and we did not understand the entire ARM ecosystem, and by extension what a programmer was used for. For anyone facing the same problem: a programmer / debugger is basically a USB port and serial monitor, but better since it allows you to step through code one line at a time and view values of any variables you want.

Since we only had experience in the Arduino ecosystem, despite the lack of debugging support for STM32 devices we continued using Arduino to program in 2020. However, we are hoping to eventually move away from Arduino, or to the new Arduino Pro IDE if debugging support is present there.

Spoilt µCs

We somehow managed to blow up a lot of µCs in our preparation, from the Arduino Mega to Nano to Maple Mini and Teensy. Sadly, this was enough to fill 2 full boxes of unusable µCs. Most of these accidents were caused by shorts somewhere on our robot (because we were always rushing for time we were very careless), and in some other cases we sent 5v signals to the Teensy 3.6 (which could only receive 3.3v max).


The IMU was another area that we struggled in. We first used the CMPS11 from our seniors in 2017 and 2018. However, in both those years we faced huge issues from the instability and inaccuracy, since it tended to drift by more than 10° every 90°. Sometimes this drifting even got worse after calibration. This was especially bad since it only happened at competition venues, and we could not replicate these issues in our lab.

Hence, we tried the BNO055 in 2018 for the international competition (in lightweight) after some research since it was easily available on Taobao. This worked very very well, and it was a dream come true since we faced no issues with calibration or accuracy. However, our bad luck caught up and it somehow decided to stop working a week before the competition, hanging the Teensy and making our entire robot unresponsive.

Despite this, we continued using it in 2019 because it was such a step up over the alternative CMPS11. We did try others like the MPU9250 or MPU6050, however the particular sensor board we purchased just refused to work from the very start. Anyways, from other teams like LJ Stand in 2018 it does not seem to work very well compared to the BNO055.

That was a bad choice since the same thing happened and it stopped working a week before the competitions. In an attempt to salvage our robot, we purchased Adafruit NXP Precision IMUs which were recommended by Adafruit themselves for its high accuracy. However, we soon discovered we could not use it since our only sub-µC was bogged down by other tasks like reading distance sensor values. To use this IMU, we needed dedicated µCs.

We only discovered that we needed to put the BNO055 on its own I2C line and not share it with other sensors in 2020. By then, we had bought two Adafruit IMUs a year ago while trying to salvage our 2019 robot. Hence, we decided to continue using the Adafruit IMUs for our open robot since we had the space to include dedicated µCs to process sensor fusion algorithms, and leave the BNO055 for our lightweight robot or other teams since it was simpler to use.

Circuit Boards

Our first circuit boards were copied from our seniors; at that time, we didn’t know how to make our own, and we didn’t even know what all the wires and connections meant, and so we copied our senior’s old circuits. This was seen most clearly with our “motor board”, a breakout circuit board for our motor drivers. While trying to make sense of how to control a motor driver, we referred to our senior’s circuit but failed to understand what it did, and ended up copying it wholesale. This kind-of worked at first, however as we needed to add more sensors and circuits onto our board it quickly got messy and confusing. It got to a point where we had 5 different circuit boards, all side by side with jumper wires connected between them, when they could have been easily integrated into 1 clean circuit board. This lesson was the main motivation behind our first PCB

PCB trace widths

For our 2nd year competing in 2018, we wanted to shift away from the messiness and inelegance of the past. Seeing as our senior team had made a PCB themselves in 2017, we decided to design a PCB ourselves where everything was fully integrated and we didn’t have to deal with any wires. The first design, very surprisingly, worked “fully” without any ad-hoc soldering to fix our circuit. However, our entire board was designed with 8 mil traces, the minimum trace width in SparkFun’s EAGLE DRC file. We did not realise this was a problem until we attempted to power our solenoid, slowly increasing the voltage in the boost converter until we heard a bang along with some magic smoke. This killed everything on the PCB, from the teensy to the 4 (very expensive) Pololu drivers on there.

However, apparently we did not learn from these mistakes since in 2019, some traces in our PCBs were still too thin. This resulted in every solenoid kick or every change in direction of our (very high current) motors to temporarily shut our light sensor LEDs off. Although this is not confirmed, we suspect it affected our light sensors as well, resulting in false positives after solenoid kicks.

Hence, in 2020 we did not want to repeat this mistake again. Since we did not want to spend extra on a 4 layer board for thicker trace widths, and after our motor and solenoid current investigations, we run 18AWG wires directly to high current sinks.

Solenoid Current

Similar to the motor current experiments above, we connected our solenoid to a resistor and oscilloscope to see how much power it draws. We found that it drew ≈10A of current at 60V despite having a coil resistance of ≈20Ω. We are not sure what we did wrong, but a definite conclusion is our solenoid draws a lot of power and wires should be run directly to it as well, just like the motors.

Other woes

For our 2018 beginner PCB forays, we made a number of other stupid mistakes and we hope others can learn from our example to not make these mistakes as well:

  • In 2018, for both PCBs (the first failed one and the second less failed one) we randomly laid out components and used an autorouter. This resulted in us being unable to fit everything into 2 layers (since we did not really think things through) and because we were rushing at that time, ordered a (very expensive!) 4 layered PCB for a very very simple circuit.

    For anyone looking to create a PCB for the first time as well: do not rush into things. Our 2018 PCBs were very problematic because of that. Just because a schematic is created exactly according to tested circuits does not guarantee success, do take the time to think about the board layout and positioning of components.

    As an example, do not put high powered motor drivers on the opposite side of the battery connectors, the (very thick) power traces would have to travel across the PCB and block all other signals to reach your drivers! These high powered traces running all over the place also results in interference and noise all over.

  • Another major mistake we made was not understanding the ground pour. We thought that the ground pour meant all the grounds in the circuit will automagically be connected, however that is not the case, and in our 2018 PCBs the grounds of the entire circuit (including high power ones) only converged at 1 tiny point <20mils wide.

    Do remember that a ground pour (or any polygon) is just a very fat trace which expands to take up all available area. If little area is available for traces to pass through, the ground pour will not help! This was another reason for our bad trace widths since currents did not have a good return path due to small ground pour connections.

    One tip to maximise the use of ground pours is to use vias to connect the ground pours on both layers together. This allows you to bypass any trace easily by just going through the bottom layer. Do ensure that for high current paths, multiple vias are used since a via is quite thin and may heat up / act as a bottleneck!

To gawk at my failures, take a look at the old 2018 PCB design files here!


Along with our shift away from messy wires, we also decided to use the RJ11 6P6C jack for our connections, since we wanted a keyed jack that would ensure we never plug things in the wrong way. However, this was way bigger than we anticipated, and now we’re left with way too many unused RJ11 jacks and plugs and breakout boards in our lab (oops).

Right now, we use SH1.0 connectors in some scenarios, and use normal 2.54mm spaced pins in others. We just make sure to label each pin clearly and correctly so we would not plug things in the wrong way.

Previously, we connected motors and high current wires via screw terminals. However, we experienced some incidents where wires came loose and almost got shorted together. This was especially bad since all wires connected to screw terminals were high powered! That is why we shifted to use XT60 connectors or wires soldered directly onto the PCBs for our high powered connections.

Shift to SMD

Our 2018 PCBs were a step forward compared to the (many) circuit boards of yesteryear, but they still didn’t look like PCBs we are used to seeing in our computers / electronics. This was when we decided to step into the world of SMD components, to eliminate all breakout (PCB) boards in our PCB and integrate everything into one. This allowed us to cut a lot of wires and save space.

It wasn’t easy, as we had to read through datasheets which were very foreign to us and try to understand complex terminologies when we are just trying to accomplish an easy task. Many of these datasheets also contain info that aren’t really important to us, like stability or temperature information, and it was difficult to filter out the important data from the irrelevant ones.

A tip if you are just starting out on a similar path: a good starting point is the recommended application schematic. Many times, apart from Vmax we don’t really need that much info on its characteristics, and skip right to the application schematic to reference and build our circuit from there. Attempt to understand the rationale of every component used in that application schematic, that way you can optimise the circuit specifically to your needs.

We also had a good time trying to figure out how to solder these components

Test PCB

Since it was our first time using these ICs directly without a breakout board, we were not confident that it would work on the first try. We wanted to be able to test these components, however we required a 22*20cm PCB since that was the size of our robot. “Development Kits” sold by chip manufacturers themselves were either too expensive or didn’t really exist for the ICs we were testing.

Hence, riding on JLCPCB’s USD $2 PCBs under 10*10cm, we decided to make a “test PCB” which was just a large breakout board of the various ICs we were planning to use. This proved to be useful: we found problems with our circuits, and ICs we wanted to use that weren’t suitable or just didn’t work were replaced. We have continued this practice for this year (2020), and if you are just starting out I would recommend this as well.



Apart from the I2C woes we experienced from the BNO055, we also read articles such as this describing how prone I2C is to interference. Although we have not faced any I2C interference issues apart from the BNO055, and since we needed to run many wires past high current and strong magnetic sources (motors and solenoid), we decided to play it safe and use UART as the main mode of communication between µCs.

Crosstalk on PCBs

While routing our PCBs, especially in the very dense 1st layer PCB, we run traces parallel and very close to one another to fit all the components and signals onto a 2 layered PCB. From some research, we know that this can lead to interference and crosstalk. However, we really could not get enough space to separate the traces enough. This is another reason we run 18AWG wires directly to high current sinks. From our testing so far, our signals on the 2020 PCB do not suffer from interference.