Brushed ESC Overvoltage Failures

Written 2017-10-26

Tags:Motors ESC 

A brushed DC motor ESC(Electronic Speed Controller) is a relatively simple device with only a few things to do, so it is interesting to consider what might happen when one is taken outside of its designed operating parameters. Today I needed some cheap ESCs to run on higher voltage than designed, and one of them did not quite make it.

An ESC has at most a few subsystems:

They usually only fail from overvoltage in a few different ways:

Today we connected two ESC to first 12V, then 24V, and attempted to drive a 1980s industrial robot. The first ESC, a 10A Hobbypower Rc ESCa, is designed for up to 8.4V and uses an IRFS3006 H-bridge. At 12 volts, the little controller was able to smoothly accelerate our robot, though it was a bit slow. BEC output remained steady at 6V. The second ESC, a 60A Hobbywing Quicrun, is designed for 12V systems and performed admirably with little lag or ramp-up, however due to the larger current drivers it could brown out our test supply if the robot were commanded to move too quickly.

At 24V the plot thickens. The Quicrun ESC functions just fine. However the Hobbypower ESC failed catastrophically at 24V, destroying the ESC, receiver, and an innocent servomotor. Postmortem indicates that the BEC failed, shorting the 24 volt battery voltage into the BEC output. Once the BEC output rose above 6V, the failure cascaded to the reciever, which connects to more servos, destroying them as well.

Reviving an old Seiko TT4000SC

Written 2017-10-26

Tags:Motors TT4000SC Seiko 

Someone dropped off an old industrial robot at Hammerspace. After a while stored in the back, and a move to a new location, thisisradionick and I decided to get it running.

The Seiko TT4000SC consists of two major components, a 4-axis robot(Z,shoulder,elbow,wrist), and a control box. Our control box had a sticker noting that the RAM battery had been replaced about 10 years after it was manufactured, and never again. Our first plan was to set up the control box, but since our RAM battery was long dead, it simply reported a large number of errors, including being uncertain what model it was attached to. Since the robot model appears to have no semiconductors to speak of, I suspect the model number was a setting in the RAM, and bringing this robot back to full operation will require repeating some of the inital programming steps that had occured in the 1980s. Needless to say, spare TT4000SC factory programmers are in short supply. We do plan to work on the control box separately, but decided to crack open the robot case to see what was inside.

Each axis consists of a 24V motor, encoder, reduction gear box, encoder, end-stops, and linkage. After Craig was able to help us order a Japanese Airplane Electronics connector, we tapped directly into the motors:

Eventually we could design our own control boards or use OpenServo, but for today we used remote control boat ESCs, which should be good enough for getting a fruit ninja game ready for Maker Faire.

Critical Mass Cotcha

Written 2017-10-26

Tags:Bicycle USB Power Charger Cotcha DCDC 

My bike has a headlight with a huge battery pack and a DC barrel plug. My friend Bill Swearingen had an awesome idea to take an ESP8266, add a li-po battery and a charger, and load it with a firmware claiming to be a free internet hotspot. When people connect, their phones suggest clicking here to sign in, at which point they are directed to an advertisement to SecKC, the local monthly security meetup.

By replacing the filesystem image, the following is now displayed on any phones attempting to connect to my bicycle looking for internet:

KC Critical Mass Advert

Linduino

Written 2017-10-21

Tags:Arduino Linux 

For an upcoming project, I needed to learn how to program the Arduino IDE to build a sketch for a new hardware platform. This all became possible when Arduino IDE 1.5 abstracted the way platforms are implemented, and even implemented their basic Arduinos in the same way.

To teach myself, I created a native Arduino core, targetting the local Linux userspace using gcc. Linduino is the result of my work. It does need a new name, as Linduino is the name Linear Tech chose for their Arduino boards, but I did not have anything better.

In effect, it compiles the current sketch using bog-standard compiler settings to create an executable for the local machine. The core currently consists of a few support components, including serial I/O using stdio, and timers using gettimeofday.

Linduino is not quite an Arduino emulator. It does not emulate the AVR 8-bit instruction set, and it does not emulate GPIOs, SPI, I2C, and several other bits of Arduino proper. Yet, it is useful for prototyping Arduino algorithms without uploading to a board. In the future it might be expanded by moving to windows ncurses and spending some screen real estate showing GPIO state and allowing other inputs.

Binary Multiplication Tricks

Written 2017-10-15

Tags:Multiplication Optimization Math Logic 

This is a rambly math post. Sean Anderson's Bit Twiddling Hacks is full of interesting uses of multiplication to manipulate bits, but some of the examples use multiplication that isn't immediately clear. At some point in my software development career, there was a moment where I understood how multiplication worked, and the day before then I didn't. This post is an attempt to explain how I use multiplication for bit and byte twiddling, as opposed to scalar arithmetic multiplication. In particular, I'm going to focus on multiplication with one constant, and tricks for determining the right constant to use.

Multiplication Algorithms

There are a number of different multiplation algorithms, each more or less useful in different circumstances. When learning multiplication as a child, I remember the Grid Method, Long Multiplication, and Peasant Method. These all work great, but a derivative of Peasant Method, Shift and Add is a good model for digital multiplication.

Shift-and-add multiplication model

Shift-and-add treats multiplication as a loop over all the bits in one multiplicand and multiplies one bit at a time by the multiplier. Results are accumulated at each step. Digitally, a 1xN-bit multiplier can be implemented with an N-bit adder and a mask. A*B is equivalent to If(A) This function implements an 8x8=>16 bit multiplier using a 1xN bit multiplier and 16-bit accumulator.


uint16_t mult8( uint8_t a, uint8_t b )
{
uint16_t accum = 0;
for( unsigned i = 0; i < 8; ++i ) //For every bit in B
    if( b & ( 1 << i ) ) //If corresponding bit
        accum += ( a << i ); //shift-accumulate to multiply
return accum;
}

While not particularly well suited to hardware-implementation(long, wide adders are complicated), when unrolled, N-bit multiplication can be implemented with N shifters(holding 'A'), a set of N masks, each combining a bit of 'B' with the corresponding shifter output, and the output of each mask fed into an N-input adder. The concept scales to arbitrary length integers with more shifts and a wider adder. In short, we can treat multiplication as a bit-vectorized shift & add accumulator.

By the Grace of Boole, Let us Compute

Multiplying by 16

To multiply by a power-of-two, we need only set the corresponding bit in the multiplier. So for B=16, shifter number 4 needs activated, and no others.

        00000000 | B & ( 0 << 0 )
       000000000 | B & ( 0 << 1 )
      0000000000 | B & ( 0 << 2 )
     00000000000 | B & ( 0 << 3 )
    AAAAAAAA0000 | B & ( 1 << 4 )
   0000000000000 | B & ( 0 << 5 )
  00000000000000 | B & ( 0 << 6 )
 000000000000000 | B & ( 0 << 7 )
               +
---------------------------------
     AAAAAAAA*10

Multiplying by 10

To multiply by B=10, we represent 10 as 2+8, and correspondingly activate B shifters 1 and 3. This is equivalent to adding 2*B + 8*B:

        00000000 | B & ( 0 << 0 )
       AAAAAAAA0 | B & ( 1 << 1 )
      0000000000 | B & ( 0 << 2 )
     AAAAAAAA000 | B & ( 1 << 3 )
    000000000000 | B & ( 0 << 4 )
   0000000000000 | B & ( 0 << 5 )
  00000000000000 | B & ( 0 << 6 )
 000000000000000 | B & ( 0 << 7 )
               +
---------------------------------
     AAAAAAAA*10

Multiplying by 255

To multiply by B=255, every bit is set in B, so we just add all 8 inputs:

        AAAAAAAA | B & ( 1 << 0 )
       AAAAAAAA0 | B & ( 1 << 1 )
      AAAAAAAA00 | B & ( 1 << 2 )
     AAAAAAAA000 | B & ( 1 << 3 )
    AAAAAAAA0000 | B & ( 1 << 4 )
   AAAAAAAA00000 | B & ( 1 << 5 )
  AAAAAAAA000000 | B & ( 1 << 6 )
 AAAAAAAA0000000 | B & ( 1 << 7 )
               +
---------------------------------
    AAAAAAAA*255

Some simple bit twiddling

Now that we understand our swiss-army chainsaw of shift-accumulation:

Repeat a 2-bit pattern 4-times

Bit-repeating a pattern is as simple as multipling by 85(0b01010101):
        000000Aa | B & ( 1 << 0 )
       000000000 | B & ( 0 << 1 )
      000000Aa00 | B & ( 1 << 2 )
     00000000000 | B & ( 0 << 3 )
    000000Aa0000 | B & ( 1 << 4 )
   0000000000000 | B & ( 0 << 5 )
  000000Aa000000 | B & ( 1 << 6 )
 000000000000000 | B & ( 0 << 7 )
               +
---------------------------------
        AaAaAaAa

Repeat an n-bit pattern m(power-of-two)-times

As seen above, repetition of a pattern by a power-of-two can be done by scaling with a bit-pattern of (n-1) zeros followed by 1 one. We can use ( 255 )/( 2^n - 1 ) to synthesize it . In C we might use the following to generate a C-integer-sized repetition pattern:
#define REPEATER(n) ( ~0 / ( ( 1 << n ) - 1 ) )
You'll actually see the equivalent of REPEATER(8), ~0UL/255, on 5 of Sean Anderson's collection of bit-twiddling hacks.

Compiler optimizations for constant multipliers

On many architectures, a shift and an add is faster or encodes smaller than a multiply. With this knowledge, compilers often replace constant-multiplies with shifts and adds when that input can be represented with just a few bits set, or just a few bits cleared.

Multiplying by three:

To multiply by three, we can simply add A to A<<1.

        000000AA | B & ( 1 << 0 )
       000000AA0 | B & ( 1 << 1 )
      0000000000 | B & ( 0 << 2 )
     00000000000 | B & ( 0 << 3 )
    000000000000 | B & ( 0 << 4 )
   0000000000000 | B & ( 0 << 5 )
  00000000000000 | B & ( 0 << 6 )
 000000000000000 | B & ( 0 << 7 )
               +
---------------------------------
             A*3 = A*2+A

It is trivial to extend this to fit multiplication by any number of set bits

Multiplying by seven:

Instead of multiplying by seven, we could add A + A<<1 + A<<2. Or...we could also take A<<3 - A. Both are equivalent, but the second is usually complies shorter:

        000000AA | B & ( 1 << 0 )
       000000AA0 | B & ( 1 << 1 )
      000000AA00 | B & ( 1 << 2 )
     00000000000 | B & ( 0 << 3 )
    000000000000 | B & ( 0 << 4 )
   0000000000000 | B & ( 0 << 5 )
  00000000000000 | B & ( 0 << 6 )
 000000000000000 | B & ( 0 << 7 )
               +
---------------------------------
             A*7 = A*8-A

     000000AA000 | B & ( 1 << 3 )
        000000AA | B & ( 1 << 0 )
               -
---------------------------------
           A*8-A

Older