Sunday, November 13, 2011

Sparkfun Inventor's Kit Circuit-03, Spinning a Motor


Okay, here is where it gets fun and relevant to our PORPOISE marine robotics program.  The third circuit in the tutorial teaches us how to spin a small motor with the Arduino, using a 1N4001 diode, a P2N2222AG Transistor and a 10K resistor.

Once we know how to spin motors we can apply the Arduino to a basic Sea Perch to free it from its tether.

At first I couldn't find the diodes -- it turns out there are two, taped together, in the bag that has the pin headers and the flex sensors. Don't be fooled, as I was,  by the diagram in the book which shows the off center line (the band that indicates the cathode or NEGATIVE electron sending side of the diode) as white.  The one's in the package are red with black bands, corresponding to the picture on page 6 in the small electronics primer.  The book doesn't tell you that the band is the negative side (or that it is the bar at the tip of the triangle  in the schematic, not the base of the triangle, or that cathode in a diode is negative while the cathode in a battery is positive, arrrgh! See wikipedia on diodes here.  It helps to think of a cathode as "that which receives the electrons from the negative terminal of a battery" and then you will see that it makes sense to have the cathode of a diode be the negative signed side which connects to the negative rail or the anode of a battery, while an anode is an electron emitter, so that the other side of the diode emits electrons that got through the diode and sends them to the positive terminal (electron receiver, cathode) of the battery.  The conventions seem all screwed up because over a century ago people thought electricity moved from the positive side.  Doh.

You can also think of the band on the diode as a negative sign painted around the end of the diode and of the line at the tip of the triangle in the schematic symbol  as a negative sign too, indicated it should be connected to ground.

There is just one little problem with this as regards the schematic on page 12 of the booklet:  while the base of the triangle, the plus side of the diode, is correctly oriented toward the collctor of the transistor whose base is connected to the resistor which is connected to Arduino pin 9, it appears as if the negative side of the diode is connected to both the motor and the + 5 volts pin of the arduino, so it appears to be backwards!  I'm thinking  this is because the diode is being used to BLOCK current and must have something to do with the transistor in the circuit and the optional capacitor that you can put in it.

The lesson is to always check the schematic when it comes to diodes!

Reading the transistor to make sure it is the right one can require a magnifying glass, so keep that in mind! Also, be careful how you insert your transistor -- plugged in the wrong way around they can burn out instantly. The manual isn't helpful about this; it identifies the supplied P2N2222AG transistor as a (T092) but this doesn't indicate which lead is the collector, the emitter or the base.  From the Electronics Club website we see that there are three flavors of T092s -- T092A which, when looked at from below with the leads facing you and the curved side down ECB, the T092B which is EBC, and the T092C which is CBE.  According to the pattern sheet that came with CIRC-03 we must have a T092C because, when looking at the flat side of the transistor with the leads down it reads, from left to right, "collector, base, emitter".  When in doubt, look at the datasheet, like this one here.

After hooking everything up I download the code from here: http://ardx.org/src/circ/CIRC03-code.txt
which I've reproduced below (who knows, maybe their server will be down when you are reading this, or your internet connection goes out because of a storm, but you still have this up on your screen!):

/*     -----------------------------------------------------------
 *     |  Arduino Experimentation Kit Example Code               |
 *     |  CIRC-03 .: Spin Motor Spin :. (Transistor and Motor)   |
 *     -----------------------------------------------------------
 * 
 * The Arduinos pins are great for driving LEDs however if you hook 
 * up something that requires more power you will quickly break them.
 * To control bigger items we need the help of a transistor. 
 * Here we will use a transistor to control a small toy motor
 * 
 * http://tinyurl.com/d4wht7
 *
 */

int motorPin = 9;  // define the pin the motor is connected to
                   // (if you use pin 9,10,11 or 3you can also control speed)

/*
 * setup() - this function runs once when you turn your Arduino on
 * We set the motors pin to be an output (turning the pin high (+5v) or low (ground) (-))
 * rather than an input (checking whether a pin is high or low)
 */
void setup()
{
 pinMode(motorPin, OUTPUT); 
}


/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called motorOnThenOff()
 */

void loop()                     // run over and over again
{
 motorOnThenOff();
 //motorOnThenOffWithSpeed();
 //motorAcceleration();
}

/*
 * motorOnThenOff() - turns motor on then off 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOff(){
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
  
  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime);                // waits for onTime milliseconds
  digitalWrite(motorPin, LOW);  // turns the motor Off
  delay(offTime);               // waits for offTime milliseconds
}

/*
 * motorOnThenOffWithSpeed() - turns motor on then off but uses speed values as well 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOffWithSpeed(){
  
  int onSpeed = 200;  // a number between 0 (stopped) and 255 (full speed) 
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  
  int offSpeed = 50;  // a number between 0 (stopped) and 255 (full speed) 
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
  
  analogWrite(motorPin, onSpeed);   // turns the motor On
  delay(onTime);                    // waits for onTime milliseconds
  analogWrite(motorPin, offSpeed);  // turns the motor Off
  delay(offTime);                   // waits for offTime milliseconds
}

/*
 * motorAcceleration() - accelerates the motor to full speed then
 * back down to zero
*/
void motorAcceleration(){
  int delayTime = 50; //milliseconds between each speed step
  
  //Accelerates the motor
  for(int i = 0; i < 256; i++){ //goes through each speed from 0 to 255
    analogWrite(motorPin, i);   //sets the new speed
    delay(delayTime);           // waits for delayTime milliseconds
  }
  
  //Decelerates the motor
  for(int i = 255; i >= 0; i--){ //goes through each speed from 255 to 0
    analogWrite(motorPin, i);   //sets the new speed
    delay(delayTime);           // waits for delayTime milliseconds
  }
}


I copy and paste this code into my Arduino sketch first, save it, and then connect my board via USB for uploading.
When I compiled the code the first time I got errors. Rather than trying to debug, because I figured I may not have copied everything correctly, I simply went back to the website, did a select all and recopied into the sketch. Then it compiled fine.
When I uploaded the motor did nothing at first.  But by making sure the tiny motor leads were well inserted I got it to start working.

Interestingly, my motor spins for about 3 seconds, then stops for 1 second, then spins for 3, then stops for 1 and so on.  When I look at the code I notice it says:

void motorOnThenOff(){
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
  
  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime);                // waits for onTime milliseconds
  digitalWrite(motorPin, LOW);  // turns the motor Off
  delay(offTime);               // waits for offTime milliseconds
}

So everything appears to be working correctly (2500 is 2.5 seconds for the int onTime; 1000 is 1 second for the int offTime.

But eventually it stops.   Now I must look for where the command is to stop turning, otherwise this is an error... wait... no, it has started again. So there must be some delay after a certain number of spins. It seems to turn a certain number of times and then stop for about 8 seconds, then start again.

To read the code, the Arduino sketch window is nice because it greys out comments and highlights commands in different colors.

It turns out the motor on/motor off code is identical to the one used to make the LED blink in the first sketch, so that is a nice conceptual tie-in.

I can't seem to find anywhere in the code where it tells the motor to stop for 8 seconds or so. Frustrated I follow the next suggestion, comment out the first behavior and remove the comment slashes before the second behavior.

The other two behaviors are similar to what we learned to do with LEDs in the second sketch -- dim them and brighten them, only here they are controlling the speed of a motor, using "Pulse Width Modulation" or PWM.  To do this the Arduino doesn't vary the voltage of the motor, which is the typical way to control a motors speed, but rather it switches the pin off really really quickly. They say "In the comoputer world this is going from 0 to 5 volts many times a second, but in the human world we see it as a voltage. For example, if the Arduino is PWM'ing at 50% we see the light dimmed 50% because our eyes are not quick enough to see it flashing on and off. The same feature works with transistors..."


{
// motorOnThenOff();
motorOnThenOffWithSpeed();
 //motorAcceleration();
}

When I compile nothing happens. Or rather, nothing seems to happen. But when I put my ear close to the motor I can hear that it is on -- it is producing a mosquito like hum, continuously.
So I try the third behavior:

void loop()                     // run over and over again
{
// motorOnThenOff();
//motorOnThenOffWithSpeed();
 motorAcceleration();
}
This time I hear a mosquito whine that is more like a flying mosquito in that it changes in pitch and volume.


Finally I do what I did in the last sketch, I uncomment all three behaviors and compile and they run in a series.

It would be nice if they provided a little propellor so that one could actually see the motor spinning instead of relying on one's ears, but I suspect this desire will be fulfilled in the very next sketch when we get to something very useful for robotics -- control of servos!



No comments:

Post a Comment