BeagleBone Blue Robotics Controller Kit - Linux - Review

Table of contents

RoadTest: BeagleBone Blue Robotics Controller Kit - Linux

Author: haqreu

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: There are plenty of robotics controllers, for example, http://www.trikset.com/index_en.html

What were the biggest problems encountered?: Malfunctioning battery charger chip

Detailed Review:

Introduction

 

The robotics changed a lot during last years: we start to forget how a soldering iron looks like; things that block us today were not the same 10 or 20 years ago. The time spent on circuit boards and measuring impedance reduced greatly. Moreover, the ease of access to 3D printing and CNC machining removes many mechanical problems. Nowadays, the blocking points have much more algorithmic or computational nature.

 

Custom PCBs disappear from robots prototyping stage to be replaced by generic controllers. In this context I am looking for the ideal controller and the beaglebone is quite a good candidate. So I am really happy to be selected to test this controller, thank you !

 

The board is built for the cybernetic epoch we are living right now: it is capable of driving motors, to digest digital and analogous information (e.g. audio and video) in real time. This controller allows to create different robots able to hear, to see and to communicate. All this requires only to assemble mechanical parts, to plug periferal connectors into the board... And to program the robot!

 

Those are my expectations, let's go to the practice. First I'll describe what I made with the Beaglebone, and I'll conclude with my opinion and problems encountered.

 

Counting incremental encoders

 

One of the most basic task in robotics is odometry and incremental encoders are ubiquitous. Beaglebone claims to have 4 quadrature decoders, let us compare their behaviour with respect to other possible solutions.

 

First of all, what an incremental encoder is? Those who remember non-optical mouses know the answer. Inside of an encoder there is a perforated disk with an optocouple from both sides of the disk. If the disk rotates with a constant speed, at the phototransistor we receive a sinusoidal signal. Once thresholded, we get a square wave. By counting impluses we can determine the angle of the shaft.

 

image image

However how do we determine the direction? In fact, there are two photocouples inside the encoder, in the following schema they are located at points A and B:

image

The sensors are placed in such a way under a (constant speed) rotation they generate two square waves shifted by 1/4 of the period. It means that when the sensor A is in the middle of the cut, the sensor B is on the boundary of the cut. When the disk rotates, say, clockwise, then at the rising edge on the signal B the signal A is a logical 1. For CCW rotations at the rising edge on the signal B the signal A is zero.

 

I'll compare three ways to decode incremental decoders:

  1. Beaglebone
  2. Hardware counter HCTL-2032 drived by an arduino
  3. Arduino software counter

 

It is pretty straightforward (once you have found the pinout!) to plug an encoder to the Beaglebone, you simply need to buy an appropriate jst-connector.

imageimage

 

Warning: BeagleBone Blue works on 3.3V and my encoder generates 5V signals, so I placed a  bss138 level shifter.

 

Plugging an external hardware counter to arduino needs a considerable amount of wiring:

image

 

As for the software counter I plugged the encoder to D8 and D9 pins of my arduino Nano. Here is the source code I used:

 

volatile long angle = 0;
volatile char ABprev = 0;
const int increment[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};


ISR (PCINT0_vect) { // D8 or D9 has changed
  char AB = PINB & 3;
  angle += increment[AB+ABprev*4];
  ABprev = AB;
}


void setup() {
  pinMode(8, INPUT);  // A
  pinMode(9, INPUT);  // B
  PCICR |= (1 << PCIE0);  // interrupt will be fired on any change on pins d8 and d9
  PCMSK0 |= 3;
  ABprev = PINB & 3;
  Serial.begin(115200);
}


void loop() {
  Serial.println(angle);
  delay(100);
}

 

Above hardware counters use exactly the same algorithm of decoding, so it might be interesting to understand how the source code works. I test the code at ATmega328p (Arduino Nano v3), pins D8 and D9 correspond to two least significant bits of the port PINB. The function ISR will be called every time there is a change in these two bits. Inside the interrupt routine I store current encoder value in the variable AB:

 

  char AB = PINB & 3; // Attention, due to speed limitations we can not use digitalRead() here

 

Why do I do this? Let us return to the graph we already saw, grey dashed lines show every call to the ISR (every edge), for each call the black numbers show the state of the variable AB:

image

It is easy to see that when rotating clockwise, the variable AB changes with a 4-clocks period: 231023102310. For a CCW rotation AB is again periodic, but with another period: 013201320132. If both photosensors do not receive any light (the variable AB=2), and with an incoming interrupt AB goes to 2, it means that the encoder's shaft is rotating CW, we can increment our counter. If AB goes from 0 to 1, then we should decrement the counter. Let us draw the following table of increments:

image

Please note that the table is not completely filled. What do we place instead of interrogation marks? For example, main diagonal should not be used at all, since the interrupt is fired on any changes of AB, so the theory tells us that no 0->0 is allowed. However the life is a little bit more complicated, and if we miss few interrupts, almost anything can happen. So I propose to fill all the remaining cells with zeroes. Here we have the table from our source code:

 

int increment[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};

 

I do hope you can now fully understand the code. So, for each period on the signal A we have 4 interrupts, thus the counter will be incremented 4 times. It means that if we have a 2000 PPR (pulse per revolution) encoder, actual resolution of our readings are 8000 per rotation.

 

What happens if we have some jitter? Not likely to be found on optical encoders, but anyways, let us zoom on one rising edge:

image

The signal A is constant, so accordingly to our table at each rising edge of B we increment the counter, and for each falling edge we decrement it. At the end, if we can catch all the edges, the jitter will be filtered out. Very unlikely to be correctly processed by arduino, but no problem for hardware counters.

Okay, enough with the theory, let us get some practice.

Some practice: experiment #1

 

So assembled a pendulum-on-a-cart, but for now I'll use the pendulum encoder only.

 

image

 

Why pendulum? That's because the gravity gives us a perferct reference, every time the pendulum stops moving all the counters must show a 8000*number of rotations (I have 2000PPR encoder).

 

Here you can see all the 3 counters:

image

 

Let us start our measurements, the pendulum is not moving, I have two serial monitors for 2 arduinos and the beaglebone's counter via ssh connection:

 

image

 

Here I make one complete turn of the pendulum and wait until it stops:

image

 

All three counters show exactly 8000, as expected! Okay, now I repeat the following ten times: hit the pendulum so it makes one turn, then wait until it stabilizes itself. The friction is low, each iteration takes a couple of minutes, so here is our situation after a half an hour of measurements:

 

image

 

Wow, and again all three counters agree completely!

 

Practice, experiment #2

 

Now I remove the pendulum and put a cordless drill on the shaft:

 

image

 

Then I gradually increase the speed, stopping from time to time to check all three counters (that is why I have RPM measurements in one of the windows).

 

100 RPM - all is ok. 500 RPM again, all is ok, all three counters agree. 900 RPM: GOT IT! I stop the cordless drill:

image

Both hardware counters still agree, while software counter can not catch up on this speed. Let us check how it agrees with the theory. ATmega328p manual tells us that one (empty) ISR takes at least 10 clocks. A bit of the stack, a bit of the code inside the ISR, let us say we have 40 clocks per ISR. 8000 ISR calls for 900 RPM give us roughly 4 800 000 clocks per second. For a 16Mhz Arduino that happens to be a lot of work.

 

I continued the measurements: for 2000 RPM both hardware sensors agree. My drill can not do more, so I stopped here.

 

Let us conclude:

 

Beaglebone decoder works just fine, wiring work is minimal. However, if you do not have access to any hardware decoders, software decoding might be a solution.

 

Testing the motors:

 

Let us plug in the motor, driving the cart, and its encoder:

 

Please note that the charger led is not lit in the photo. This was a big issue, but for now I skip it, (I'll elaborate on it at the end of this post).

A little bit of tuning and voilà, the pendulum is stabilized!

 

 

Can it drive my quadruped bot?

I have a quadruped bot with 12 dynamixel ax-12a servos, and driving those can be pretty tricky. They use a half-duplex serial port. Therefore, to use with controllers like beaglebone, you need to have a separate line that will tell if you want to receive or send the data. Here is the schema from the manual:

 

GPIO's are fine, however it is extremely hard to get the timings right from a linux kernel. Here I simply used an intermediate microcontroller that is plugged into the USB port and it does the switching. However note that beaglebone has a realtime programmable unit (RPU) that was designed exactly with real time in mind. So in theory you can drive dynamixel servos without additional gear. You can also drive WS2812b LEDs image

So long story short, BB works just fine with my bot:

 

 

 

Conclusion

Documentation

Beaglebone blue is a nice robotics controller, I managed to a couple of projects with very minimal wiring and very easy programming. However, it is not for faint-hearted. First of all, the documentation is, how to put it, lacking:

I do not consider this to be a big issue since the older brothers are well documented and the community is growing rapidly.

 

Specifications

 

The board itself has nice specifications, it is very versatile and has plenty of features. If you do not need to drive big motors, it is really fine. By the way, if i try to put more than 30% of voltage into the motor that drives my inverted pendulum, the security kicks in and shuts the motor.

 

Quality

 

Here comes my-complaints-section. First of all, the board is covered with white stains from the flux being washed badly.

 

Then ontop of this it has flux that is not cleaned at all. Seems like there was a glitch in the production line and some of the solder points were done manually.

UPDATE: here I was wrong, this is not flux but conformal coating. Check the comments.

All official photos of the beaglbone blue do not have these stains, however all the other photos on the internet have exactly the same look. Check the video of the beaglebone presented at some expo, it has exactly the same stains... Going further down that road, here we have a solder bridge:

 

And here we have a cold solder joint:

This is quite disapponting, but the biggest issue I had was dead out-of-the-box battery charger chip. When I plugged 12V DC, the charging led was not lit and no voltage present at the motors. However, the voltage regulator was working fine, so I was able to do some tests with encoders while waiting for my brand new MP2615 chip to arrive.

 

Then not without struggling I desoldered the old chip and soldered the new one. And only then I was able to finish my inverted pendulum.

So in the end, I am a bit on the fence as to this controller. It certainly has nice specs that come with the poor build quality. Then again, it is a toy for geeks and not a military grade product. It is up to you to decide. The schematics of the board are published, so it allows debugging/repairing to some extent.

 

UPDATE:

I just received a replacement board from . This one is perfect. No flux stains, no solder bridges and so on. Works like a charm!

Anonymous
Parents Comment Children
  • Thank you, my mistake, point taken. However other issues remain.

  • Can you please explain me why apply conformal coating on one (the same) side of the motor drivers?

  • This I am not sure of. There is the possibility that those connections are more sensitive to moisture given the distance between those connections. This is conjecture, I don't  know why the coating was applied to those specific areas of the PCB. From the Conformal Coating.png image, I can see that this coating was applied where intended. The  coating matches the locations specified in the image.

     

    This is the first time I have seen a conformal coating on a SBC. The only other application of a conformal coating that I have seen is on an ESC from my 1/10th scale RC Stadium Truck. The specs on the ESC state that it is waterproof. Upon teardown and inspection of the ESC, the PCB was found to be completely encased in a thick layer of conformal coating.

  • I'm not sure either, but likely to prevent the higher voltage higher-current capable sources from accidentally shorting to something else. Normal BeagleBone Blacks will not have more than 5V on any part of the board. In contrast, the 'BeagleBone Black Industrial' is entirely coated, but there the reason is to protect against the environment. On the BeagleBone Blue, the reason is possibly just to prevent accidental shorts by the user.

  • TB6612FNG motor drivers have pins with V_BATT-GND voltage on both sides. One side only is protected. On the other hand, the unprotected side exposes the voltage through half-bridges, probably there is a hope (when shorted) that the transistors would die first without frying the rest of the board.