Category Archives: Electronics

Bluetooth

OK, so we have made the chassis with a couple of motors, a coilgun, a ball detector, and the electronic circuitry to control all of this. This makes up the “body” of our robot and what remains is the “brain”. As you should know already, the brain in our case is a Nokia smartphone. The brain needs to be constantly communicating with the body – sending movement and shooting commands and reading ball sensor and perhaps motor sensor data. As we explained in one of the first posts, we need to use the Bluetooth protocol for such communication.

We thus had to purchase a separate module and connect it to our main microcontroller (attentive readers have already seen this module in one of the pictures). There is a fairly wide variety of Bluetooth modules available out there. Our criteria for choosing a suitable one were the following:

  • The module must have an integrated implementation of the full Bluetooth protocol stack. Bluetooth is a fairly complicated set of protocols, and there are some modules which only implement parts of it. The remaining parts would have to be implemented in software (i.e. in the microcontroller) and this would make our life difficult.
  • The module must use the UART protocol. This is the default serial protocol supported by our microcontroller. Most Bluetooth modules use it anyway.
  • The module must have a readable datasheet. Debugging a no-name module with no reference manual is not something we look for.
  • The module should be reasonably priced. Although ELFA is certainly not a place to look for “reasonably priced” things, we can use the knowledge that the cheapest module there (which happens to fit the previous criteria) costs €32.50.
  • Finally, the module might have some positive reviews on the internet.
BlueSMIRF Silver
BlueSMIRF Silver

SparkFun’s BlueSMIRF Silver happened to fit all of them (especially the last one), so we ordered it and so far it has been one of the less troublesome parts of our robot. Although it does have a detailed datasheet, pretty much none of that information was even needed, because the module does most of the work itself. All the microcontroller has to do is read and write bytes over the UART pins, to which the module is attached.

To read and write over UART we borrowed the code from the Teensy UART library and added a couple of simple wrappers around the low-level uart_getchar and uart_putchar methods. After this was done, we could complete the main loop of our robot’s microcontroller:

int main() {
    // ... initialization code ...

    char buf[32];

    while (true) {
        bool success = recv_command(buf, sizeof(buf));
        if (success) execute_command(buf);
    }
}

This function, together with the interrupt handlers mentioned in the post about motor control, is essentially all there is to our main microcontroller’s code.

Serial Communication and Interrupts

If you will be implementing a similar solution, beware of one particular hidden reef. The UART communication in Atmega uses interrupts to receive bytes. That is, every time a new byte arrives on the serial port, an interrupt handler is invoked. The code in this interrupt takes responsibility of storing the received byte into a buffer for further processing. While this interrupt is in process, no other interrupts will be invoked. For example, if during the reading of a byte a motor encoder happens to send a pulse, this pulse would not get counted, simply because the controller won’t be there waiting to catch it.

This issue is even worse the other way around – if the microcontroller happens to stay “too long” in one of the other interrupts, he might simply miss an incoming byte. As a result, weird things will start happening – the command “move” might get received as “mve” or worse still, a command separator character will be missed and two commands will be concatenated into one.

There is really no good solution to this problem besides being careful and not writing code which might stay too long in an interrupt handler. At one moment we had an interrupt handler like that (the one which performed the PID computation in a timer), and it resulted in a fairly large number of communication errors. Surprisingly, the problem nearly disappeared after we rewrote the computation from 32-bit integers to 16-bit integers. It turns out that an 8-bit microcontroller can spend too much time simply adding and multiplying 32-bit numbers.

Bluetooth and Latency

A final word of warning is related to latency. Although the communication speed for a Bluetooth connection is quite good (in our case it was actually limited by the UART’s 115 kbps), the latency is not. That is, although you might easily send up to 15 000 single-character commands per second on a UART+Bluetooth connection, if you require (and wait for) a response to each command, the actual throughput can be somewhere around 30-60 commands per second.

In fact, this particular problem (and the fact that we discovered it too late to go fixing) has been one of the main reasons why our robot was somewhat “slow” during aiming in the final competition. We focused a lot on keeping the vision processing speed at 30 frames per second as this was, according to general knowledge, the hardest part to get working fast. Unknowingly, we were at the same time unreasonably wasteful in communication. Whenever robot would have the ball in the dribbler, we would query the ball sensor too often. As we would also wait for sensor query command to respond before proceeding with computation, this (rather than the dreaded vision processing!), was the reason our actual processing speed went down to about 15-20 fps every time the robot was holding the ball. Those were, however, exactly the moments when the robot was aiming for the goal and needed as high a framerate as possible.

Operating the Coilgun

Now that we’ve figured out how to operate a motor, let us describe the second important electro-mechanical component of the robot – the coilgun. Previously, we have already discussed briefly the general idea and its mechanical realization. What remains are the minor implementation details.

Recollect that the general scheme of a coilgun (somewhat simplified, of course) is the following:

Coilgun
Coilgun

In order to make this scheme operable, we must replace the switches “Enable charge” and “Enable discharge” with transistors, connected to a microcontroller. In our case we had a separate microcontroller operating the coilgun, which means that we also needed to establish communication between the main controller and the coilgun controller. The resulting scheme is then, in principle, the following:

Coilgun control
Coilgun control

The task of the coilgun microcontroller is rather simple: receive signals from the main microcontroller and set its output pins A and B accordingly. Our robot’s coilgun controller implemented essentially the following four functions:

void enableCharge() {
    set_pin(PIN_A, 1); // Enable charging of the capacitor
}

void disableCharge() {
    set_pin(PIN_A, 0); // Disable charging of the capacitor
}

void kick() {
    set_pin(PIN_B, 1); // Start discharging capacitor
    delay_ms(5);       // Wait 5ms
    set_pin(PIN_B, 0); // Stop discharge
}

void dischargeSlowly() {
    for (int i = 0; i < 20; i++) {
       set_pin(PIN_B, 1);
       delay_ms(1);       // Discharge a bit
       set_pin(PIN_B, 0); // Let the kicker be pulled back
       delay_ms(5);
    }
}

The last function (dischargeSlowly) is there to allow a graceful shutdown of the robot, where the capacitor discharges without the kicker having to jerk hard.

The communication between the main microcontroller and the coilgun may be implemented using various protocols. Originally, our coilgun PCB was meant to be controlled via the SPI protocol, but during one of the mishaps the corresponding pins burned down and we ended up using a simpler solution, where three output pins of the main controller were directly connected to the input pins of the coilgun board. A command was sent by specifying its code using the first two pins and sending a pulse on the third one.

If you will ever be making your own coilgun…

It must be noted that the coilgun was perhaps the most complicated electromechanical part of our robot and as this blog tries to make things sound as simple as possible, it sweeps some details under the carpet. If you, dear reader, for some reason, will be going to build a coilgun yourself (perhaps when taking part in one of the next Robotex/Robocups), take your time to skim through the following sites first:

Safety notes

In order for the coilgun to be capable of hitting the ball with appropriate force, it must contain a reasonably large capacitor, and large capacitors can be dangerous. A 1.5mF capacitor, when charged to 250V, stores 0.0015·250² = 93.75 Joules of energy – something comparable to an energy of a 10kg brick falling from 1 meter’s height. If such a capacitor short-circuits, all this energy can get released in a single explosion, and you do not want your fingers to be nearby. Even if your fingers are spared, your electronics can get irreparably damaged.

In order to avoid a capacitor explosion (there were at least three of those among the Tartu teams during the two months leading to Robotex), keep in mind the following:

  • You should not short-circuit a capacitor. Obviusly, this will result in an immediate discharge of all its energy, which means an explosion. Of course, no one ever short-circuits a capacitor deliberately, but it is unexpectedly easy to do it accidentally.
  • You should never physically damage a capacitor. A damaged capacitor may short-circuit internally and explode for no apparent reason later on. Hence, if a capacitor falls on concrete floor once, beware when reusing it.
  • A capacitor must be used with appropriate voltages and connected in accordance to its polarity. Invalid voltage or polarity may damage it internally, which will lead to internal short-circuit.

To be more specific, here are some educational stories:

  • Some guys were debugging their PCB using a digital oscilloscope and touched a “positive” end of the capacitor with a “ground” probe of the oscilloscope. As a result, there was a short circuit through the ground, boom.
  • Other guys were trying to fix something using a screwdriver right on a working robot with a charged capacitor. Screwdriver touches the metal cover of the robot (which most probably was connected to the “ground”. of the electronics somewhere). Next, either due to a static discharge from the screwdriver, or due to its external potential acting to inversely polarize the capacitor, the boom happens.
    In fact, touching a working robot with a metal object is a bad idea for many more reasons. The two times when our team has managed to mess up the electronics were both related to someone trying to touch a working robot with a metal object. So beware.
  • Yet other guys have attached a capacitor to their robot using just Velcro tape. The robot starts spinning, the tape does not hold, the capacitor slips off and touches some of the electronics with its terminals. No boom, but all of the electronics burned down.

 

Operating a Motor

After we have chosen the motors and motor drivers, we must connect them to a microcontroller and control their rotation. How do we do that?

The Microcontroller

In our particular case we used a microcontroller chip mounted on a custom-printed circuit board together with the motor drivers, which we ended up not using anyway. Thus, our life would have actually been easier if, instead of using that custom board, we would just buy some well-known pre-made microcontroller board. The popular choices included Arduino, Teensy, Baby Orangutan, Basic STAMP, ARM mbed, TI LaunchPad, ST Discovery, and anything else you might google up using the keyword “microcontroller development board“. Hence, for simplicity, I shall avoid details specific to our case and assume the set-up with such a separate board.

For those of you not familiar with microcontrollers, it is enough to understand that a microcontroller is a just a black-box chip with several pins (those are the metal “legs” of the chip).The microcontroller can be programmed to set output voltage on some of the pins to certain values (usually either 0V, corresponding to “bit zero” or 5V, corresponding to “bit one”). It is also possible to sense input voltage on some other pins. Those two basic operations allow the microcontroller to communicate with other devices connected to it.

So, we have to connect some output pins of the microcontroller to the motor driver. Then, by setting appropriate output voltages on those pins, we shall be telling the motor driver to operate the motor as necessary. How exactly should the motor driver chip be connected and operated is specific to each chip, but in principle the assembly for one motor might look as follows:

Motor connection
Motor connection

Controlling the Motor

In the example above (which corresponds to the driver we used), two pins (A and B) are used to tell the driver in which direction to rotate the motor. The whole code for specifying rotation direction is thus as simple as:

if (rotate_forward) {
    set_pin(PIN_A, 1);
    set_pin(PIN_B, 0);
}
else {
    set_pin(PIN_A, 0);
    set_pin(PIN_B, 1);
}

Specifying rotation speed is just a bit trickier. For that we must produce a pulse width modulation (PWM) signal on pin X. This simply means quickly switching pin’s values between 0 and 1, so that on average the value “1” is kept a given fraction of time. A “full PWM” would mean keeping pin X at “1” all the time – in this case the motors would rotate with  their maximum speed. A “null-PWM” means keeping “0” all the time. This corresponds to motors not rotating. All values inbetween are also possible. If pin X is at value 1 one third of a time, the motors will rotate with approximately a third of their maximum speed.

PWM with 1/3 duty cycle
PWM with 1/3 duty cycle

Most microcontrollers have built-in mechanisms for producing such a signal on some of the pins. We won’t delve into details of doing that – there are lots of tutorials out there already. For all practical purposes, the actual code for setting the motor speed boils down to

set_pwm_pin(PIN_X, speed); // speed = 0..255

Feedback

Are we done? No. Unfortunately, simply setting the motor rotation speed to a fixed number is not enough for precise control. For example, if we set the PWM speed inputs for both robot motors to the same value, despite all expectations, the robot will most probably not drive perfectly straight. Thus, to ensure exact control, we must constantly measure the actual rotation speed of the motor and adjust the PWM to keep the speed at a given value.

In order to measure motor rotation speed, our motor is equipped with a rotary encoder: a sensor, which generates pulses in accordance with the rotation. The faster the rotation – the more pulses are generated per second. To obtain this feedback information we first connect the motor encoder to an input pin of a microcontroller:

Motor with feedback
Motor with feedback

Next, we write a simple function that simply counts all pulses that come in on pin E:

ISR(INT0_vect) {
    pulse_count++;
}

Finally, we set up a timer interrupt that will regularly examine the current pulse_count value, compare it with some target value, and adaptively update the PWM signal on Pin X so that the target rotation speed is achieved:

ISR(TIMER0_COMPA_vect) {
    current_pulse_count = pulse_count;
    pulse_count = 0; // Reset pulse counter

    // Update pulse counter
    update_motor_speed(target_pulse_count, current_pulse_count);
}

PID controller

So how do we use the feedback and choose the appropriate PWM value to set for the motor speed in order to keep up with the target pulse count? This simple question has a whole discipline dedicated to answer it, known as control theory. The easiest answer that control theory provides us here is the PID controller.

The idea of a PID controller is generic and simple: we first measure the discrepancy between the target pulse count and the actual measured pulse count (the error):

error = (target_pulse_count - current_pulse_count);

In addition, we keep track of the error, accumulated over multiple iterations of the algorithm, and the difference between the error of the previous iteration and this iteration:

error_i = error_i + error;
error_d = error - prev_error;

The actual input to the motor driver is now computed as a linear combination of these three error values with some experimentally determined coefficients P, I and D:

new_pwm = P*error + I*error_i + D*error_d;

If the parameters are chosen well, the PID controller will magically keep the motor turning at the necessary speed.

So, to summarize the above, the update_motor_speed function may look approximately as follows:

void update_motor_speed(int target, int current) {
    error = (target - current);
    error_i = error_i + error;
    // Prevent the integral term from growing too large
    if (error_i > max_error_i) error_i = max_error_i;
    if (error_i < min_error_i) error_i = min_error_i;
    error_d = error - prev_error;
    prev_error = error;
    new_pwm = P*error + I*error_i + D*error_d;
    set_pwm_pin(PIN_X, new_pwm);
}

Our actual function was somewhat more complicated and included a couple of specific hacks and improvements, but the gist is still there.

Summary

To summarize, here is what you need to do to properly operate a motor:

  • Connect the microcontroller’s output pins to a motor driver, and the motor driver to a motor.
  • Use pins “A” and “B” (or whatever the motor driver specification requires) to set motor rotation direction.
  • Connect the motor’s rotary encoder sensor to an input pin “E” of a microcontroller.
  • Make sure the microcontroller is counting the pulses on pin “E”.
  • Set up a timer, that reads the counted pulses and updates the PWM parameters on pin “X” to match the “target_pulse_count“.

The same logic applies for the second motor.

But where do the motor direction and values of target_pulse_count come from? Those are specified by the higher logic, running in the phone, of course. We’ll get to that eventually.

 

The Motors

The parts of the robot, that have turned out to be one of the trickiest for us, were the motors. There are three motors in our robot – two for the wheels and one for the dribbler, and all of them have been causing headaches.

Choosing the Motors

The variety of motors one can choose for the wheels of a robot is staggering. How to choose the right one? Here’s how we went about it.

The first decision we had to make is whether to use a brushless vs brushed motor. The former type is typically more powerful, more expensive, and requires somewhat more experience to operate. The latter type is what most would call a “usual” motor. Having no prior experience with brushless motors and no desire to spend extra money, we went with the simpler option.

Next, we have to pick a particular motor. Two main functional characteristics play a role here:

  • Motor rotation speed – this will specify the max speed at which the robot will be capable of moving.
  • Motor torque – this will define the acceleration the robot will be capable of achieving.

The theory goes approximately as follows. Start by finding the necessary rotation speed. We know that the diameter of the wheels of our robot is 6cm. We would like the robot to be capable of moving at a maximum speed of about 1 m/s. That means, the motor must be capable of rotating with speed 1 / 0.06π ≈  5.3 revolutions per second, i.e. about 320 rpm. If we give it a little slack, we might be looking for a motor with free rotation speed of about 350-450rpm.

Next, let us compute the torque. Ideally, we might be willing for our robot to be capable of accelerating to the speed of 1m/s in about half a second, i.e. the maximum acceleration for the robot must be about 2m/s². The weight of our robot, fully assembled, is about 3kg, hence the motors will need to provide a force (F=ma) of at least 3·2 = 6 Newtons. In particular, 3 Newtons is the contribution that we expect from each motor. We also have to account for friction, and here we just blindly say we need about twice the force, i.e. 6 N from each motor. If our wheels would have a radius of 1 meter, we would need a motor with a torque of exactly 6 N·m to achieve that. Our wheels have a radius of 3cm, however, hence we would like a motor with a torque of about 6·0.03 = 0.18 N·m. Depending on the manufacturer, the motor may either be specified in terms of “rated torque” – this is a constant torque the motor is capable of providing for long periods of time, or “stall torque” – this is the maximum torque the motor provides when stalled. The stall torque is typically at least twice the rated torque, hence, according to our computations above, we might want a motor with a rated torque about 0.2 N·m or a stall torque at least 0.4 N·m.

Pololu motor
Pololu motor

After having scouted the web from end to end, we ended up ordering a pair of these and a pair of these motors from Pololu. Besides fitting our specification, the motors have a reasonable size (some alternatives were inconveniently large to fit into the robot) and have a rotary encoder built-in, which is a feature worth paying a couple of extra euros for. Pololu also sells useful accessories, such as wheels and wheel attachment hubs, which we also ordered. It turned out the attachment hubs we chose were not suitable for the 6cm Pololu wheels, though, so we ended up lathing our own wheels but still using the tires.

The Motor Driver Problem

The important feature of a motor is its stall current. This is the current that the motor consumes when stalled, i.e. exerting maximum torque. This happens when the motor is just about to start rotating, when someone prevents the motor from rotating freely (e.g., the robot has bumped into a wall) or when the robot is trying to accelerate. The motors we ordered have their stall current specified at 5A. However, the motor drivers we had to use on our motor control PCB (designed last year for Tartu’s last year’s robots), were only meant for 2.8A or smaller currents. (In case you already forgot, this post explains what is a motor driver). “Ah well, let’s just try and see what happens, maybe the drivers will just burn down”, we thought, and we tried. Unfortunately for us, the drivers did not burn down.

They kind-of worked, but worked badly. In order to run the motors at smaller speeds we had to use weird hacks, which are not worth delving into here, and in the end, the motors still wouldn’t behave predictably. After about a month of suffering and making us come up with ugly hacks, the drivers did finally burn down, and it was good. Because by that time we have already ordered a new, more powerful pair of drivers, and needed that final push to have those installed. As soon as we got the normal drivers set up, motors started working as necessary, and life became beautiful again.

Burned drivers
Burned drivers

The picture below shows the lower side of our motor control PCB. The three empty spots are the places where the three original motor drivers have been (the board was originally designed to accomodate four drivers, to be used with four-wheeled robots). One of the drivers burned down when we touched a working robot with a screwdriver (separate story). Two other ones burned for some reason later. The last driver is still sitting there, and it was used to control the dribbler motor, but eventually it also burned.

The moral of this story is simple: if you use powerful motors, use powerful motor drivers.

The Dribbler Motor Problem

As mentioned above, we were using the remaining driver to control the dribbler motor (so that it would be possible to choose the speed at which it would be rotating). However, we had bad luck with this one too. Despite the fact that the dribbler motor was not trying to consume too much current, the driver for it managed to burn down three times for no clear reason (some local gurus suspect that the motor was too “low-quality” for the driver, in the sense that its brushes produced too much spark discharges when switching). So in the end, we got tired of replacing the driver over and over and had the dribbler motor connected directly to the battery via a button. It was a very good choice and I am sorry we didn’t make it in the very beginning. So let me leave you another suggestion, dear reader: if you have a choice between a simple button and a complicated electronic microchip (such as a motor driver) strongly prefer the former!

The last remark is in order. Some of the Tartu’s other teams tried using brushless motors for the dribbler (simply because those were available), but as far as I’ve seen this has caused them way more trouble than it was worth. So if you, dear reader, plan on making a soccer robot, do not use a brushless motor for the dribbler. Just take any generic reasonably-sized brushed motor that you will find lying around in the lab, connect it with a button, and that’s it, you’re done. Tartu team Sidi had it done this way and, it seems, did not have any problem with their dribbler at all.

Once the motors are connected and running, we must somehow control them from the microcontroller. We’ll leave it as a topic of a later post.

Ball detector

One sensor that has not been mentioned previously is the “ball detector”. The ball detector helps us to easily detect when a ball has been “caught” by the dribbler and is in a position ready to be hit by the kicker.

The detector is implemented using a classical opto-isolator idea. On one side of the dribbler we put a small infrared LED, that will be constantly emitting infrared light. On the other side of the dribbler, we attach an infrared photodiode (or, to be more precise, we actually use a slightly more sophisticated breakbeam sensor). Now, whenever there is no ball in the dribbler, the sensor will be “seeing” the light from the IR led and produce an “off” (i.e. 0V) signal on one of its pins (note that a conventional photodiode would work the other way around). Whenever a ball comes into the dribbler inbetween the LED and the sensor, it will hide the light from the diode, the signal will go up to “on” (i.e. 5V), and this can be sensed by the controller.

Of course, in theory we could detect the fact that the ball is in the dribbler purely from the camera image, but having a dedicated ball detector sensor is easy and convenient.

Ball detector: IR LED
The black dot under the dribbler shaft is the infrared LED
Ball detector: Photodiode
On the other side, there is a photoelement

Coilgun

A coilgun, is the part responsible for kicking the ball. As you might remember from an earlier post, it consists of a solenoid (coil), a capacitor, a metal bar, a spring and a controller circuit.

Coilgun

The Theory

There are thousands of tiny details that must be decided upon in order to make a coilgun: you need to choose the material of the metal bar, the force of the spring, the parameters of the wire comprising the coil, the diameter and number of turns of the coil, capacity of the capacitor and its operational voltage. Ironically, despite the abundance of those details, in the end there is just one simple thing that matters: the coilgun must kick the ball strongly enough to send it to the opponent’s goal.

Understanding how each of the above parameters influences the strength of the kick requires patience and a solid knowledge of high school physics and beyond. We won’t go into this here, but here’s a brief overview of the main issues that matter:

In order for the kicker bar to jerk strongly enough, the coil must produce a strong magnetic field.  In order to produce a strong field, strong current must flow through the coil, the coil should have many turns and the turns should preferably be small. In order to produce the strong current over a long wound wire we need higher voltage and a large capacitor.

On the other hand, an excessively strong current would melt the wire, and excessively strong voltage would produce sparks, and an excessively large capacitor would be heavy, expensive and dangerous. In the end, there is a kind of balance between “small and light” and “strong and heavy”.

Although in principle it should be possible to come up with a “theoretically perfect set” of parameters which result in the lightest possible, yet functional coilgun, we went along a simpler route of reusing the practical knowledge of our predecessors and intuition:

  • We use a 1500uF capacitor to be charged at 250V. The 1500uF number comes from the fact that such a capacitor was available and the 250V number is related to the coilgun control PCB from the previous year’s Tartu teams, which we could reuse.
  • We have a coil wound of 1000 turns made of 0.4mm copper wire. The wire was chosen fairly arbitrarily and the number of turns was selected so that the total coil resistance would be somewhere around 4 Ohm. At 250V this would result in a discharge current of around 60A (a “good current for a coilgun”, according to the knowledge of local gurus).
  • The 1500uF capacitor charged to 250V can theoretically discharge at this current for at least 6ms, which turns out to be sufficient for the metal bar to make a strong kick.

The resulting coilgun works fine, but it is so strong that it could have been way lighter. If you, dear reader, happen to be in the mood for doing some exciting physics exercises, I dare you to use science and come up with a better set of coilgun parameters.

The Practice

To make the actual coil we used an old electromagnet of unknown origin (perhaps a lock or something) which was kindly provided to us by our fellow Tartu team EKRS.
Old electromagnet, disassembled
Old electromagnet, disassembled
We replaced the wire with our own (on one of the previously posted videos you may actually find a hidden moment, where Reiko is seen in the process of winding the coil using a lathe), added a metal box (which you can see being machine-milled on that same video), and attached everything to the first floor of our robot.
Coilgun in the attachment box (model)
Coilgun in the attachment box (model)
Coilgun, attached
Coilgun, attached

Unfortunately, we do not have a lot of “in progress” photos of the coilgun making. Here is, however, a nice view of the EKRS robot body together with a coilgun control PCB (same as ours), a large capacitor (ours is slightly smaller) and a coil while it was still being developed:

EKRS coilgun development
EKRS coilgun development

 Another Tartu team had their capacitor explode with a loud and scary boom. So, dear reader, please beware: large capacitors can explode easily and violently when connected incorrectly, used with invalid voltage, or damaged:

Exploded capacitor
Exploded capacitor

And finally, here’s a video demonstrating the Telliskivi coilgun in action:

Electronics

By the “electronics part” of a robot we mean everything inside the chassis needed to drive the motors and kick the coilgun. Note that the smartphone, although itself a sophisticated electronic device, is not included. If the smartphone is the “brain” of our robot, then the electronics inside the chassis is the “spinal cord”.

One might think that there is really not much to do here – indeed, all of the “hard thinking” seems to be done in the brain, and the spinal cord is there just to switch the motors on and off. How hard could it be? Pretty complicated, in fact.

Motors

The simplest DC motor (the “brushed motor“) is a device which has two wires and a rotating shaft. If you connect the wires to a battery, the motor starts rotating – pretty simple. Here’s how that would look on a diagram:

A DC motor

However, this would not be sufficient for a robot – this configuration results in a continuously rotating motor, whence we would like to be able to switch it on and off. Thus, as a bare minimum, there must be a transistor and a flyback diode to allow such switching:

Switchable motor

This is still not enough, though – such a configuration only allows to rotate the motor in one direction. In order to allow the robot to move backwards, the polarity of the battery must be switchable, and this would require more scaffolding around it – the H-bridge. Various schemes for implementing the H bridge exist, some more complicated, some less and we’ll not delve into this topic here. In any case, this will add at least four additional transistors to the schematics. Luckily enough, there are chips providing all of this motor driving logic in a single package: motor drivers. Those would typically include an H-bridge together with some other useful functions, such as current monitoring to prevent overheating.

But that’s still not all of it. The H-bridge would let us switch motor both ways, but how do we control its speed? The trick here is to use pulse width modulation (PWM) for the input signal. I.e. instead of switching the “input pin” to “on” and simply letting the motor rotate at maximum speed, we shall switch the pin on and off with high frequency. Now, if on average the pin is “on” just half of the time, the motor would rotate approximately with half the maximum speed.

Microcontroller

As a result, we need a component that will generate the PWM signal at the necessary frequency. What could it be? Certainly not the smartphone – it has no facilities for such fine-grained control and has enough other duties to attend to. Hence, we need a microcontroller – essentially an additional full-blown CPU just to drive the motors. Now using a microcontroller means that we need a way to program and communicate with it – this will add a couple of additional compulsory components to the circuit.

Bluetooth

Are we done yet? No. Remember we mentioned that the only reasonable way to communicate with the smartphone is Bluetooth. Thus, we shall need a Bluetooth communication module. This is mounted on a separate board and will be communicating with the controller using the UART protocol.

Coilgun

Are we done yet? No. Remember the coilgun? In order to make the solenoid jerk (and thus kick the ball) we need to apply voltage to the coil in the same way as we did with the motor on the first figure above. However, this time this will not be battery voltage – the battery voltage is too low to provide sufficient current. Instead, we shall have a separate large capacitor, that will discharge into the coil. Conceptually:

Coilgun in principle
Coilgun in principle

Of course, this diagram is incomplete. Once the capacitor has discharged, it has to be re-loaded again from the battery. Conceptually:

Coilgun in principle, step 2
Coilgun in principle, step 2

Finally, in order to charge the capacitor to high voltages, we shall need to convert the 11V battery voltage to something higher, perhaps 100V or so. To do that, we need a voltage transformer together with a DC to AC converter to make it work (you can only increase voltage of alternative currents). Thus, omitting some more details, the coilgun requires a circuit like the following:

Coilgun
Coilgun

The coilgun charging/discharging algorithm is probably simple enough to be implementable without the need for a separate microcontroller, however doing it using a microcontroller is so much easier that we can use one here too.

Putting it all together

Are we done yet? Well, there are still a lot of small details (a fused power regulator, an IR ball detector, Hall rotation sensors on the motors), but in general that’s it. Here’s the high-level overview of the “spinal cord” for our robot:

Telliskivi Electronics
Telliskivi Electronics

One possible indicator of the complexity of this  assembly is its price. Although we shall discuss the budget in a later post, so far just take my word for it – the configuration presented above costs somewhere around €200 or more. This assumes two reasonable motors (€30 a piece at least) and a normal battery (also at least €30), yet is still a conservative estimate, which does not even include experimentation or burned parts.