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:
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 rscasny !
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.
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.
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:
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.
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:
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:
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:
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:
Okay, enough with the theory, let us get some practice.
So assembled a pendulum-on-a-cart, but for now I'll use the pendulum encoder only.
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:
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:
Here I make one complete turn of the pendulum and wait until it stops:
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:
Wow, and again all three counters agree completely!
Now I remove the pendulum and put a cordless drill on the shaft:
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:
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.
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.
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!
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
So long story short, BB works just fine with my bot:
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.
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.
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.
I just received a replacement board from rscasny. This one is perfect. No flux stains, no solder bridges and so on. Works like a charm!
Top Comments
There is an API and it is really simple to use: Strawson Design.
So I wrote my own control code based on the API. I even installed a cross-platform compiler (also easy), but later found that it was not…
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…
Very good testing and fault diagnosis.
The board cleaning (or lack of it) is a concern.
My parents had a cordless phone which went back to the manufacturers as it wasn't working.
They claimed water damage…