Let's Make Robots!

Here's my latest project. I liked Frits' Yellow Drum Machine so much that I decided I wanted to build one of my own. I'm working on the physical construction first -- once I have somewhere to mount the batteries and logic board, I'll glue on some drumsticks and start working on the drumming code. When my SRF05 arrives in the mail, I'll add that and start working on navigation. The last step will be adding the sampling board to record and play back sounds. Well, that's the plan, anyway :)

 


Photos

 

01.jpg

My brother is a woodworker, which is nice to have access to :)

 

02.jpg

Look at that, dadoes and everything!

 

03.jpg

The robot's "superstructure," looking much nicer than the way I first planned to make it (Frits-style -- keep adding glue until it stops moving :). Batteries go in the bottom compartment, circuit boards in the upper one, and maybe a giant speaker glued to the top :)

 

04.jpg

Gluing it up...

 

05.jpg

The base so far

 

06.jpg

The underside

 

07.jpg

The breadboarded circuit. The blue board is a Pololu Micro Dual Serial Motor Controller for the main tank tread motors, and the three transistors will each switch one of the "drumstick" motors on or off. The green wire towards the top will be for output, maybe an LCD or a speaker.

 

08.jpg

One of the "drumsticks". I found that 1/4" aluminum tubing seemed to give a bit of a ring without being too heavy.

 

09.jpg

Sure, that's clear as day, right?

 

10.jpg

Main body glued together. It's a little taller than I had imagined, but ah well.

 

11.jpg

Rear view

 


2008/04/07

 

Reworked mounting of circuit boards to free up more space, and glued on the first drumstick motor.

12.jpg

 

 


2008/04/09

 

15.jpg

Now he's got a "bass drum".

16.jpg

Bass drum motor detail

 

 


2008/04/10

 

17.jpg

He can rock out now. Similar to what I assume Frits did, I hacked a little sampling circuit board, removing the pushbuttons and soldering wires to let the microcontroller trigger the playback and record functions. Now he can record his beats and play them back in a loop while he jams along with them.

 

18.jpg

Sampling circuit board detail

 

 


2008/04/13

 

19.jpg

My first PCB! A board for the SN754410 that lets me turn the sonar left and right.

 

20.jpg

The solder side. (I need a finer tip for my soldering iron)

 

21.jpg

Fabricated a bracket to mount the SRF05 onto the motor.

 

22.jpg

Rear view

 

23.jpg

He's now mostly complete. I want to add one more drumstick up front, but otherwise everything's there.

 

24.jpg

Once I'm happy with all the circuits, I'll probably solder it all up a PCB to eliminate that rat's nest.

 

25.jpg

Underside

 


2008/04/15

After gluing on the second front drumstick, I decided that the construction was complete, and I was reasonably sure that there wouldn't be major new components added anymore. So I decided to rebuild the circuit on a PCB "shield" that would fit right onto the Arduino rather than using a breadboard with dozens of loose jumper wires running between the two. To further clean things up, I cut up a ribbon cable from the same old 486 that donated its speaker to this project, and used that to connect my PCB to all of the sensors, motors, etc around the robot. The result is a much cleaner setup, and if I want to remove the Arduino for whatever reason, I can simply pull off the two ribbon connectors, rather than having to deal with tons and tons of wires and then later having to re-figure out which wires go into which I/O sockets. It took me quite a bit of thought to come up with a layout for all of the pins that grouped common functions together and made the circuit small enough to fit on that small PCB, and I'm actually pretty proud that I managed to fit it all in. What's even more amazing is that, after spending 6 hours soldering everything up, it actually all worked perfectly! I expected there to be tons of hard-to-track-down problems after doing so much soldering in such a small space.

26.jpg

One last shot of the circuit on the breadboard . I won't lie -- the real purpose of this shot was so that if I soldered up the circuit and it didn't work, I'd have some sort of documentation of what the original circuit looked like so I wouldn't have lost everything :)

27.jpg

That's a mess. Good riddance.

28.jpg

I didn't take any pictures of the soldering process, but here's the top side of the completed board. SO much cleaner. At the bottom is the 9-pin socket for the Pololu motor controller. Above that are the three transistors and diodes for the three "drumstick" motors. The screw terminals at the top are for the motor battery supply, and the pins on either side are for the two ribbon connectors. In the background, you can see the paper where I enumerated and grouped together all of the pins I needed to connect, in order to figure out what should be close to what, etc.

 

29.jpg

Bottom side of the PCB, where all the action is.

 

30.jpg

It slides right onto the Arduino, and mates with the Arduino's I/O sockets.

 

31.jpg

 The paper where I laid out all my connections before soldering.

 


2008/04/17

With the construction done, I shifted my attention to improving the code. The coding I had done for playing drums worked pretty well for music that I hardcoded by hand, but as I started thinking ahead to how I wanted him to be able to 'write' his own drum beats, I realized that I'd need something a little more programmatical and less music-oriented. So I took a page from real drum machines, and I redid my drumming routines to get rid of the explicit calls to play notes of varying lengths. Now, instead, I just divide a measure into 8 beats, and my drum patterns are 4 measures long, so that's 32 beats per pattern. I have 4 "instruments" (bass drum, two drumsticks, and a click from the speaker), so a pattern can be represented by an array of four 32-bit long integers. When I want to play the pattern, I just loop over each bit in the integer, and play the drum if it's a 1, or don't play the drum if it's a 0. I had to do some fun bitwise math to look at individual bits from each integer, but it works, and now I just need to come up with four integers and I've got a new pattern.

I came up with some quick and dirty code to let him come up with his own patterns -- each time I measure left/center/right distance with the sonar, I stick each of those measurements into bass drum, snare, and hi-hat. It shows promise -- they actually sound pretty musical just like that. This whole 'coming up with his own patterns' thing will need some tweaking, to guide the patterns closer to musical and away from 'random banging', but it seems doable.

The part that I continue to have trouble with is the *&$king navigation. At first I thought I had found the problem when I realized that, since I had mounted my two drumsticks so far forward, my SRF05 was actually detecting those sticks most of the time when it looked left and right, so it was literally like he was wearing blinders. I cut the hot glue and re-glued the two motors angled farther back, so now that's not a problem anymore, but I still have trouble getting realistic numbers out of that sensor. Lots of times it will be like 8 inches away from a wall and pointing straight at it, and the sensor reports that the distances are something like (60 // 8 // 45) or (13 // 8 // 146) or things like that. The direction that is facing the wall head-on tends to work well, but the views to the sides seem to be completely unreliable. I added some debugging code to have it beep out the three distances through the speaker like the tracking devices in the movie Alien, with the pitch getting higher as the detected distance gets closer. That works really well for letting you know immediately how far away it thinks things are, at least relative to each other. And that has shown me that most of the time, it's getting totally incorrect numbers, which is why he can never manage to find anything to play drums on.

I know these sonar sensors have trouble when they're hitting a wall at an angle and things like that, so I'd expect little flaws every once in a while which wouldn't bother me, but this was pretty much just useless. Then I realized that one problem might be the fact that those little Solarbotics GM10 motors turn about 60 degrees in either direction, so his side views were actually getting close to looking completely sideways. That meant that, even if he's facing the wall head-on, the side views end up looking really far away, so the robot has to find himself really close to a wall before his side views can actually hit the wall:

sonar_angles.png

So I glued small plastic tabs onto the motor, to limit the rotation of the head down to only about 40-45 degrees in either direction.

32.jpg

This seems to work MUCH better. I set him down on the ground, and he quickly lined up with the wall, drove up to it, and started drumming. Awesome. Now I can move on and continue working on improving the coding. So, some final shots of the completed robot:

33.jpg

34.jpg

The sampling board didn't have any holes in it for mounting with standoffs, so I borrowed more inspiration from Frits and just hot-glued it onto the side. And he's right, a strip of glue DOES work well to hold down the loose wires. How did I survive this long without a hot glue gun?

 

35.jpg

Ahh, I like that so much better than those loose wires everywhere.

 

36.jpg

I moved the microphone away from the bass drum motor, because it was picking up the whine of the motor louder than the drumming itself.

 

 


2008/04/19

 

I give up. The little plastic tabs I glued onto the sonar motor weren't working as well as I'd hoped, plus after just a few minutes of testing, they broke off and the motor went back to  scanning its full 120-degree range. I just couldn't get the robot to find things worth playing on -- he spent all his time wandering around, snaking back and forth, never actually reaching any walls. It was especially frustrating since my 'object following' code for Harry The Discbot works so well. Harry, of course, has his "eyes" on a real servo, not a GM10 motor. So I gave up trying to get it to work with the GM10. I can certainly appreciate the pleasure of building complex things with really simple tools, but I just wasn't making progress and it wasn't being fun anymore. So a few minutes with an X-acto knife, and the GM10 is outta there. I first glued on the Hitec HS-55 micro servo that I'd bought on a whim to use on a later project. Once I started testing it though, I was surprised by how slow it was. I had just kind of assumed that, since it was such a tiny servo, it'd be really fast, but apparently it's geared down to be closer to the speed of a full-size servo. It worked just fine for locating objects, but I really wanted to try to preserve as much of the "zip" of the GM10 as possible. It probably doesn't help that the HS-55 is Hitec's "economy" model. When I looked up the specs, I found that sure enough, the speed of the HS-55 at 4.8v is 0.17 sec/60 degrees, whereas most of their nicer servos, just a few dollars more, are in the 0.12-0.14 range (and even down to 0.9-0.10 still at reasonable prices). There are $80 servos that do it in 0.04, but that's not what I'm looking for.

So I bought an HS-81, which is rated at 0.11 sec at 4.8v, brought it home, and tested it, and was much happier with the speed. It's still no GM10, but I'll happily trade a little bit of zip for actually being able to find the damn wall. So I broke out my X-acto knife AGAIN (I've gotten good at removing hot glue), removed the HS-55 and glued down the HS-81, and now we're in business. I ported over my object-following code from the Basic Stamp-powered Harry to the Arduino, spent some time adapting it to this purpose, and at last! He can actually reliably find things to drum on. Ahh.

37.jpg

With the GM10 gone, I no longer needed the motor driver PCB I spent so much time and thought making, so off that comes from the side of the robot. Ah well, I'm sure I'll find use for it in another project.

38.jpg

I've also made some more progress on his 'writing drum patterns' subroutine, so it sounds a lot more like music. I've posted a new video above showcasing his new talents. There's still work to be done, of course -- there's a slight gap between patterns for some reason, and I've got plenty of ideas for improvements to the code. But now he's finally starting to behave like a proper drum machine :) Now I'm having fun again. And I hope Frits isn't too disappointed that I gave up on the GM10 -- I'm impressed as hell that he managed to make his work so well with one. I guess I'm just not as skilled a roboticist as him :)

 


 

I'll keep updating this as I continue working.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Sweet project, maybe you and frits can have a jam fest... but anyway where did you purchase your tracks? thanks!
Chris the Carpenter's picture

First of all, tell your brother -that is a beautiful tablesaw sled. Also... Man, do I like those Diablo blades as well (best blade on the market for the money) --But... You gotta drop that Bosch table saw -they kick a ton of dust right at your face, crappy dust collection on that model, man.

www.rocketbrandcustom.com baby!!

TheCowGod's picture
Hehe, I'll pass that along. He's working on a pretty limited budget, so I think that was about as much saw as he could afford.
fritsl's picture

Oh boy, giggle, joy! I want a brother like that as well, would produce much nicer bots!!

And that thing looks heavy!?!

The drumstick looks excactly like the 2 of mine (The ones I call Snare and BassDrum) (last is often referred to as "the tail"). Did you buy and later destroy that remote-controlled TV-antena as well? That is where my alu-sticks come from :)

Tip: I drilled a small hole in the antenna-sticks, got some 2 component glue, filled some glue in the stick, pressed it down untill the hole aligned to the hole on the lever of the motor, flattended it a bit, took some wire through the hole, and twisted it.. Waited for the glue to dry, and wrapped some tape around to hide the most nasty bits / finish it up a little :) It is way strong that way.

COOL PROJECT! Cant wait to see (and hear) more!

 

PS: Rechargables!! (a must - I am sure you can get it the same place they sold you the areal :) 

/ Fritsl

TheCowGod's picture

Thanks, it's fun to be making progress on it :) Nah, it's not heavy. If anything, I was thinking I might end up adding some weight to give it some more stability. Those little Solarbotics motors have a good bit of torque -- I'll have to see if they move the robot when I start drumming on things.

Hehe, no, it didn't occur to me to destroy a TV antenna for the sticks, I just bought an aluminum tube from the hobby shop. Not as fun as destroying things :)

Thanks, I was wondering how you attached your sticks. In the one I've made so far, I just dabbed some hot glue into the stick and shoved the motor arm into it as far as it would go. It seems pretty stable, but I was thinking of drilling a hole in it for a screw or something. A wire is a good idea. I'll probably do that for the other ones, and if this one comes off, then I can redo it that way too.

Hehe, and yeah, rechargeables are definitely the way to go :) I only have 4 rechargeable AA's though, and for this project I needed 6. I've heard that you're not supposed to mix alkaline with rechargeable, so I just used all alkalines until I can go buy some more rechargeables. I need to find some rechargeable 9V batteries, but the ones they had at the store were only 150 mAh. Man, that's tiny, my AA's are about 2200 mAh.

TigPT's picture

very nice, keep the good working dude.. think you are in the good way..

 lovely picts.. thanks for sharing, and good luck with the project =P

 

PS - i just got a arduino to, i wold love if you can share how do u drive the motors with the arduino..

 i think we will need to make a H-Bridge for that, i will search for it.. i was trying to avoid to buy motors, and H-Bridge, hoping to use some VHS Record motors, or something.

TheCowGod's picture

Thanks for the kind words. Yeah, the Arduino doesn't have an onboard motor driver, so you need to build something external. It depends on how much control you need over the motor -- if you only need it to turn in one direction, you can do that with a single transistor. That's what I'm doing for the small "drumstick" motors. Wire up the motor battery across the Collector and Emitter pins and through the motor, and then switch the transistor on or off with a logic pin on the Arduino. You can use PWM to limit the speed, but of course only in one direction.

If you need to be able to move the motor in both directions, then yeah, you'll need an H-bridge of some sort. For my last robot, Harry The Discbot, I just assembled two H-bridges myself on the breadboard with four NPN-transistors (standard 2N3904-style). That works just fine, although when the logic voltage gets low, the motors slow down even if the batteries for the motors still have plenty of charge. And I'm sure there's all kinds of small details I'm missing (most H-bridge circuits I see online have diodes and capacitors and stuff), but I can move the motors in both directions with it, so it's good enough for me.

On this robot, I'm using the $23 Pololu Micro Dual Serial Motor Controller (it's the small blue 9-pin board in the breadboard picture above). It's a great solution -- takes up almost no space, and it handles all the PWM etc, so I can just send short 4-byte serial messages to tell it which of the two motors, what direction, and what speed (from 0-127 in each direction). I'll include my code for doing that below, in case you decide to go that route.

Of course, if you're trying to avoid buying anything, then you'll probably need to do something similar to the homemade H-bridge.

 

*********************

 

#include <SoftwareSerial.h>

#define MOTOR1 2
#define MOTOR2 3

#define FORWARD 1
#define REVERSE 0


byte motor_controller_pin = 3;
byte motor_controller_reset_pin = 4;

// for rx on all unidirectional software serial objects
byte unused_pin = 10;


unsigned char mc_command[4];

SoftwareSerial motor_controller = SoftwareSerial(unused_pin, motor_controller_pin);


//==========================================================================================

void setup()
{
   pinMode(motor_controller_pin, OUTPUT);
   pinMode(motor_controller_reset_pin, OUTPUT);
   pinMode(unused_pin, INPUT);

   motor_controller.begin(9600);

   mc_init();
}

//==========================================================================================

void loop()
{
   for(int i = 0; i <= 130; i += 10)
   { 
      mc_send_command(MOTOR1, FORWARD, i);
      mc_send_command(MOTOR2, FORWARD, i);

      delay(250);
   }

   delay(3000);

   for(int i = 130; i >= 0; i -= 10)
   {
      mc_send_command(MOTOR1, FORWARD, i);
      mc_send_command(MOTOR2, FORWARD, i);

      delay(250);
   }

   delay(3000);

   for(int i = 0; i <= 130; i += 10)
   {
      mc_send_command(MOTOR1, REVERSE, i);
      mc_send_command(MOTOR2, REVERSE, i);

      delay(250);
   }

   delay(3000);

   for(int i = 130; i >= 0; i -= 10)
   {
      mc_send_command(MOTOR1, REVERSE, i);
      mc_send_command(MOTOR2, REVERSE, i);

      delay(250);
   }

   delay(3000);
}


//==========================================================================================


void mc_init()
{
   // start up motor controller
   digitalWrite(motor_controller_reset_pin, HIGH);

   // let motor controller wake up
   delay(100);
}


void mc_send_command(byte motor, byte direction, byte speed)
{
   direction = constrain(direction, 0,   1);
   speed     = constrain(speed,   0, 127);

   mc_command[0] = 0x80; // start byte
   mc_command[1] = 0x00; // Device type byte
   // Motor number and direction byte
   mc_command[2] = (2 * motor) + (direction == FORWARD ? FORWARD : REVERSE);
   mc_command[3] = speed; // Motor speed (0 to 127)

   // send data
   for(int i = 0; i < 4; i++)
   { motor_controller.print(mc_command[i], BYTE); }
}


****************

 

TigPT's picture

Hi,

Thanks for all the info, i will read more about that Pololu, its sounds interesting.

Thanks for code sharing, its always nice to see how do others "think" -> "make" code, and it migth be useful if i go for Pololu, or even something close to it.

One question.. in the discobot, why did u used that H-bridge?

Isn't it a basic stamp on that board?

If it is, you just need normal PULSOUT to directly talk with the server pwm.

An example: 2 servos to make robot move forward, one servo CW, and other CCW

 Forward:
  FOR pulseCount = 0 TO 50
  PULSOUT 13, 650
  PULSOUT 12, 850
  PAUSE 20
  NEXT
  RETURN

 With this fuction you can pulsout to a servo using 1 wire only, and the other are just for VCC and GRD.

Anyway i know Basic Stamp have alot of limitations, (sutch as code, and no ADC) so i'm moving to Arduino as soon as i can controle motors with it.

 

Thanks once again, and good luck with your..

Wood Drum Machine

 

TheCowGod's picture

Hi there. Yeah, that is a Basic Stamp, but I modified those servos for continuous rotation, including removing the control boards and wiring the servo leads' black and red wires directly to the motor's terminals (white wires are left disconnected). So they look like regular motors to the board, not like servos. You're right, the BS2 is pretty limited, and it's so much nicer to have access to all of the Arduino's capabilities (hardware PWM, hardware timer, interrupts, etc).

By the way, take what I say with a grain of salt -- now that I've got the body of the robot assembled, I'm trying to get the drumsticks working, and for some reason that idea of simply using one transistor per motor isn't working. So maybe my advice isn't the best :)

Dan