GanzBot PBR

Yes, his head is a trash can.

This was my first two-wheeled balancing robot. Built around 2004/2005. GanzBot PBR, for Pico Balancing Robot of course.

First robot where I designed my own custom PCBs. I was already that sort of stuff for work back then, but it was just starting to become affordable for hobbyists to have their own custom PCBs as well. This was still before JLCPCB.com and oshpark.com, but there were a few places offering low volume (5 piece), 2 sided, low tech boards on a 2 week turn for around $100. I definitely checked my DRC‘s and Gerbers meticulously before sending these jobs out.

Overview

  • Three custom PCBs, all with PIC MCUs:
    • Main PCB – PIC18F452 – balance control and behaviors
    • Head PCB – PIC18F252 – lights, LCD, switches
    • Motor Drive PCB – PIC18F252 and PIC16F876 – I2C comm., PWM generation, quadrature encoder decoding
  • I2C communication between main PCB and motor drive PCBs for commands and feedback
  • Surplus gearmotors off eBay
  • SMT ADXL203 accelerometer (on main PCB)
  • Surplus Segway MEMS gyro (angular rate sensor)
  • Homemade quadrature encoders on motors for position/velocity
  • Sharp IR rangers (not installed at time of these photos)
  • 24V, 20 cell, 2/3A, NiMH battery pack
  • Fine aluminum and oak construction (this was years before home 3D printers were on the scene)
  • Pinewood display stand

Bare Metal C, Fixed Point

I programmed everything in C, including the ISRs … carefully. The 18F’s ran at 10 MHz, and the 16F’s ran at 4 MHz which was fast enough.

This was pre-Arduino so this was entirely roll-your-own-code bare metal. No libraries for any peripherals, so I had to write all my own drivers, twiddling registers for the ADCs, UARTs, I2C, SPI, PWMs, timers, etc. You really get to know the chip. This was also fixed point arithmetic. I had to manage ranges and resolutions carefully, especially for filters and controller variables.

The PIC18F252 was new to me, but fortunately I was already using the PIC16F876 in a design at work. Fun stuff.

Main PCB in the torso. U7 in the middle is the ADXL203 accelerometer. U1 is the PIC18F452 MCU. Gyro is offboard and comes in on J8 (bottom left). J10, J11 (bottom right) are I2C to the custom Motor Drive PCBs.

Main PCB

The main board is a custom round PCB. Round was expensive back then for a home project. Low volume online PCB places were mostly scoring PCBs or only routing rectangular board shapes – unless you wanted to go with more expensive board house. I really wanted the round board to fit his structure, so I went for it. Advanced Circuits back then would do “3 for $33” of any shape for a reasonable area, 2 layer PCB. That’s $33 per board, not $33 for the whole set! I laid out the board and checked it a million times before releasing the Gerbers.

Main features:

  • one MCU, a PIC18F452 for control loops and behaviors
  • MCP100 reset supervisor for clean power-up
  • smack in the middle of the PCB is the SMT ADXL203 accelerometer
  • periphery has numerous 0.1″ headers for sensors
  • op-amps and low pass filters for analog sensor conditioning
  • muxes for routing the MCU’s UART around (called SCI in PIC-ese)
  • footprint for a V-Stamp speech synthesizer board
  • 4 Mbit serial flash (AT45DB041D) for datalogging
  • DB-9 connector and RS232 level shifter for offboard serial communication
  • ICSP programming header
  • 5V switching power supply module
  • relay for “soft-on” management of bus capacitor inrush current
  • charging port with diode protection
  • latching connectors for power and I2C communication to motor drive PCBs

Main Board Software

The Main Board read in the accelerometer and the angular rate sensor (gyro) as analog signals directly and performed the balance control loop. I used a complementary filter for fusion of the gyro and accelerometer data, and PID’s for the speed and pitch loops.

The really interesting part was doing it all in fixed point arithmetic though. No floating point. I had to pay careful attention to variable ranges and resolutions and underflows/overflows – especially underflow concerns with the complementary filter where corrections can take on very small values.

As mentioned earlier, this was all bare-metal C directly accessing the PIC’s registers for all the peripherals.

Custom Motor Drive PCB – I was using a now-defunct low cost EE CAD program back then that couldn’t do copper pours, only hatches. Barbaric.

Motor Drives – it takes two

Motor drives were also custom PCBs. Two identical boards installed in the robot for the left and right motors.

Main features of the motor drive PCB:

  • one PIC18F452 MCU
    • communicated with Main PCB in the torso over I2C
    • received speed commands, and replied with encoder info
    • decoded quadrature encoder signals for motor speed and position
  • 74HCT14 Schmitt Trigger IC for cleaning up the encoder signals
  • DIP switches for setting I2C address at runtime so I could use same HEX file for left and right motor drives
  • one PIC16F876 MCU
    • communicated with the on-board PIC18F452 over a custom 8 bit parallel bus
    • received speed commands and generated PWMs to drive motor bridge (LMD18200)
  • MCP100 reset supervisor for clean power-up

The PIC18F452 didn’t have enough hardware resources to generate the PWMs for the motors and also decode the quadrature encoders. That’s why I added the PIC16F876 to offload PWM generation. The PICs unfortunately only had a few timer modules back then – you had to plan your architecture carefully!

Head PCB

The head board was a custom PCB as well, but a pretty primitive one. I had it fabricated at ExpressPCB when their low cost option was a really small board and didn’t even have soldermask. Really. Even then, it was $60 for just three credit card sized boards. Hard to compare with the present day prices at places like JLCPCB.com.

Anyhow, the main features are:

  • one PIC18F452 for reading in CdS sensors and a simple user interface
  • op-amps and low pass filters for analog sensor conditioning
  • MCP100 reset supervisor for clean power-up
  • I/O for some pushbuttons
  • parallel 4 bit interface to a 2×16 LCD character display
  • drove some gimmicky eyeball LEDs

Sensors

The main head “big round” board had a evenly spaced connectors around its perimeter for sensors. Each connector had power and buffered analog input lines. That made it easy to add Sharp IR rangers pointing in multiple directions. These pics pre-date the installation of those.

Motors/Encoders/Wheels

Motors where surplus Pittman Motors off eBay (GM9434H275, 38.3:1). I chose them based on the torque-speed specs I could dig up on Pittman from the eBay pics which showed the part number luckily. They didn’t have any shaft feedback so I made my own custom quadrature encoders. First I center drilled the back of the motor shaft, crazy carefully on a lathe, then epoxied/press fit in some brass RC aircraft couplers.

I designed slotted wheels in 2D CAD and had them laser cut at Pololu, which had just started a pay laser cutting service. I glued some opto-interrupters onto the motor paying close attention to locating them appropriately to generate a 90 degree phase relationship, and suddenly I had quadrature encoders!

Motor couplers were custom made out of aluminum on a lathe. Some of my first forays into using a lathe. Worked well enough.

He had a variety of wheels over the years. It ranged from the present, big balloon, RC airplane tires to hard rubber wheels. Compliance of the tires definitely affected the dynamics and required balance control loop tuning for each.

Battery pack visible below Main PCB. It’s the white and green shrink-wrapped thing.

Batteries

LiPo’s were on the scene, but not that affordable yet, nor very trustworthy as others already discovered. Despite their non-stellar energy density, NiMH’s still have plenty of power density. They can do the job and deliver the peak currents, but for a reduced duration. I used 20 cells of the 2/3A type for a 24V, 1600 mAH pack (i.e. 38.4 WHr). Or in Tesla-speak, 2,000x smaller than the 82 KWHr pack in the November 2020 Model 3 upgrade.

The battery pack was located high up for high center of mass and a lower natural frequency. This makes pitch control easier since the inherent system dynamics are lower frequency. Though there is a torque tradeoff.

Wrap-up

Overall this was a fun project. Several years later I decided to start playing around with building a successor. That was the start of GanzBot IV, which was more of just a prototype with a breadboarded brain, though he does have a custom motor drive PCB. By then, inertial sensors, Teensy’s, motor drives, and 3D printer were commodities which made it fun to get back into balancing robots.