Category Archives: Robotics

Robotics 2013-12-31

At about 1500L today the insectoid walked for its first time. It took several hours to get there. I started off by spending a while in vain trying to use my board programmer with my Mac with the parallel-to-USB adapter I had recently acquired. No such luck. I thought about just calling it a day with the accomplishment being to order a USB board programmer, but I decided that would be lame, so it was back to the ancient beast of a machine that lacks wireless… After much staring at the micro-controller’s data sheet, tinkering with the components, experimental programming, and furrowing of brow, the machine finally showed signs of life. The first walk was sort of a drunk walk and more than a little disappointing. Several iterations later, both in code and hardware, I had something that I was happy to file under A Good Day’s Work.

It had some traction issues on the tile floor.

The servo controlling the center legs doesn’t seem to have enough power to fully tilt the chassis.

And some combination of calibration issues and traction issues are causing drift to one side in the gait.

Switching to sharper movements will not by itself save the day.  An aerial view illustrates that the legs are not swinging symmetrically.

A little bit of servo calibration later and things are more symmetrical.  This is also using a simultaneous swinging of the leg pairs, with unclear consequences.

Now we’re back to non-simultenous leg movement with no apparent degradation in performance.

Some surround-shots of the action…

And finally I struck on the idea of removing the rubber feet from the center legs to counter the problem of them dragging due to inadequate lift power coming from the servo…

The code is not that complex once you understand the relevant bits of configuring the micro-controller.   The system has one 16-bit timer, one 8-bit timer, and two output channels hung off of each.  See earlier posts for more detail.  One of my main disappointments by the end of the exercise was the realization that if you’re stuck using an 8-bit timer to generate a PWM signal for a servo then even the best possible configuration of pre-scaler and TOP value does not give you much granularity which leaves you with jerky motion as your only option.  I also learned the hard way that the registers used for specifying the TOP value for counters are used constantly, not latched at configuration time, which when you consider that the only way to specify a custom value of TOP for the 8-bit output channels is to put it in one of the output-compare registers, you find that you lose one of your channels which seems a bit miserly to me.

I am relieved that everything seems to work, at least to a degree.  I feel lucky that the micro-controller I chose gave me enough leeway to do what I wanted, if not entirely beautifully.  All these years later I could probably get a much nicer one than I initially bought.  I wonder if more powerful servos would do the trick for the tilting problem.  Or maybe I need to run more power to them because the strain is overloading the batteries and causing a voltage drop?  I suppose I could test this by hooking up to a wall power supply.  In any case, there is still an infinite amount of playing to be done, but today marks a major milestone and is cause for celebration.

#include <avr/io.h>
#define F_CPU 8000000
#include <util/delay.h>

int configure_pwm() {
  DDRB = (1 << PB4) | (1 << PB3);
  DDRD = (1 << PD5);

  OCR0B = 10;
  OCR1B = 1500;
  OCR1A = 1500;

  // 16-bit timer configuration
  ICR1 = 20000;
  TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
  TCCR1B = (1 << WGM13)  | (1 << WGM12)  | (1 << CS11);

  // 8-bit timer configuration
  OCR0A  = 164;
  TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);
  TCCR0B = (1 << WGM02)  | (1 << CS02)   | (1 << CS00);

  return 1;
}

int left_pair_forward() {
  OCR1B = 1800;
  return 1;
}

int left_pair_back() {
  OCR1B = 1000;
  return 1;
}

int right_pair_forward() {
  OCR1A = 1000;
  return 1;
}

int right_pair_back() {
  OCR1A = 1800;
  return 1;
}

int tilt_left() {
  OCR0B = 8;
  return 1;
}

int tilt_right() {
  OCR0B = 12;
  return 1;
}

int pause(int duration) {
  int i = 0;
  for (i = 0; i < duration; ++i) _delay_ms(20);
}

int walk() {
  while (1) {
    tilt_right();
    pause(10);
    left_pair_forward();
    pause(50);
    right_pair_back();
    pause(50);
    tilt_left();
    pause(10);
    right_pair_forward();
    pause(50);
    left_pair_back();
    pause(50);
  }

  return 1;
}

int main(void)
{
  int i = 0;
  configure_pwm();
  walk();
}

Robotics Journal

I just now finished transferring a journal of my robotics work to this here WordPress site to co-habitate with my other blogging activities, backdating the entries accordingly.  It involved a fair amount of work but it’s done and it feels good.

Now I just have to finish the project that I started so long ago.  Going through the transfer process entailed proofing and thus re-reading everything I’ve done.  It is both heartening, seeing all of the obstacles I have surmounted, and dismaying, seeing how bursty my work on the project has been.  Hidden in the gaps are various life events and other distractions that have drawn my attention elsewhere.  The mirrored version of the robotics journal thus far could be a whole other story that remains largely unwritten.  Therein lies a collection of life lessons for me to ponder.

I think with one good day’s work I can have a walking, or at least stumbling, robot brought to life.  But the record shows that I have thought this previously.  Details, details…

Robotics 2013-07-03

Doh! It turns out that all I had to do to make the twitching servo problem go away was to wire a ground pin on the micro-controller board to the common ground for everything else. I thought that I had done the equivalent of this by having the micro-controller board’s power line’s ground going to a common ground, but I guess there is a difference between logical ground and power ground, and without getting them all to the same place the servo did not have a good reference voltage for its signal line (or something).

Of course, I didn’t figure this out without first tearing apart everything, trying to rule out shorts or burned out components, testing things in isolation, even wiring up the signal line to my oscilloscope, etc…

Live and learn… Now I just need to rig up a ribbon cable so that all three servos can be wired up at the same time, then extend the proof-of-concept code to operate all three legs in concert, and we’ll have a walking robot…

Robotics 2013-06-22

Bangs. Head. On. Desk.

Given that there was already a perfectly good program on the micro-controller for swinging a leg pair, I tried one-by-one wiring up the signal line for each servo in the hopes of validating that all the wiring was good, and… twitching. The damned servos are twitching.

Maybe the way I ran the wires is causing interference? Maybe it’s a load issue? Maybe the servos are busted or the micro-controller board has started having issues? Various Internet posts say to try putting a resistor in series with the servo, or maybe wrapping its cabling around a torus…

Argh! This is going to be a bit of debugging…

Robotics 2013-06-16

So close to having a walking robot that I can taste it… Today was equal parts assembly work and data sheet perusing.

The UPS man had dropped off a couple of 9V battery holders earlier in the week, one of which I mounted to the chassis after some soldering work. I also changed out the wiring to the DC plug I have such that the power for the micro-controller can be run to the breadboard as opposed to being directly tied to the battery (decoupling, FTW). Then I ran an assortment of wires and jumpers to power everything…

everything_mounted_and_powered

Perhaps after the next session the creation will rise and walk the earth…

I did a little digging in the micro-controller’s specs to figure out what my options are for driving all three leg pairs. It looks like pins PB2-PB4 double respectively as OC0A, OC1A, and OC1B. So, I’ll need to do some ribbon-cable magic to finish up today’s wiring exercise to get those pins linked up to the signal ports of all the servos. I figure I will use the two 16-bit timers for the side leg pairs and one of the 8-bit timers for the tilter leg pair.

Some maths have me reasonably convinced that I can make an 8-bit timer work for my purposes. A pre-scaler value of 1024 gets us to 8192 counter ticks per second. For a 50Hz signal, that means setting the roll-over for the counter (the “TOP” value) to 164. One tenth of that, ~16, is a 2ms wide pulse, and half that is ~8/1ms.

Right? We’ll find out soon…

Robotics 2013-06-08

Alright, here we go:

  • Acquire a miniature breadboard: check
  • Cut, drill, and mount another aluminum sheet to serve as additional platform space: check
  • Use double-sided tape to mount breadboard and 4-pack double-A battery holder to platform: check
  • Rig up wiring from servos to breadboard: check

Voila:

bread_board_mounted_top_view

bread_board_mounted_side_view

Remaining tasks in the home stretch to walking:

  • acquire and rig up a 9V battery holder for powering the micro-controller board
  • wire up all the necessary power and data lines to and from the breadboard
  • build out from prototype leg-controller code to drive all three leg pairs in concert

We’re almost there.

Robotics 2013-04-21

So, somehow all of this electro-mechanical jumble needs to get hooked together in a way that won’t tangle or tether. As it stands, there is no good place on the chassis to directly mount the microcontroller’s board, so we’ll need to concoct some sort of platform…

staged_board

… that can rest on top of a section of aluminum tubing that elevates it adequately…

mounted_board_rear_view

The key thing in the assembly of this apparatus was appreciating the value in a component that did not so much add structural function to the final product but rather served to make assembly far easier, specifically the lock nut that went directly beneath the platform. This nut both reduced the freedom of a sub-assembly to wobble during final assembly as well as provided a handy surface with which to execute the final assembly. The alternatives, which included trying to screw down the board as the last step or trying to run the platform-mounting screw upward instead of downward, were going to be hopelessly fiddly, a seemingly impossible task for a mere two hands.

mounted_board_top_view

In hindsight, I wish I had cut the sheet of aluminum that serves as the platform floor to be the length of the chassis so as to create more real estate to mount the rest of the components, namely a breadboard (of a miniature nature that I need to acquire) to plug everything together and a couple of battery packs to power everything. I’m debating whether I ought re-cut this piece larger and mount it at both ends of the chassis or just cut another smaller piece and tell my OCD that everything will be just fine.