woensdag 20 januari 2010

Arduino: Controlling a DC motor

It's been a while, but I've been busy with an interesting project. I will blog about it later on. Totally unrelated is today's topic: controlling an DC motor with an Arduino. At first you might say that it is easy to power an DC motor with an Arduino. Put it on a digital pin and enable or disable the motor. But if we want different speeds you will need a different voltage. As a digital pin is only high (5v) or low (0v), the motor can either go very fast or stop. How do we fix this problem?

The short answer is quite simple actually: use pulses. By sending a pulse every x milliseconds the motor will rotate faster or slower depending on the pulse length. The longer answer, however, is a bit harder. We will need something to flat out the pulses a bit. As the pulse top is 5v and the pulse bottom is 0v, the engine will actually be turned off and on very fast. By using an capacitator we can flat out the pulse to, for example, top 3v and bottom 2.5v.

To build the following circuit we will need:
1 x An Arduino board
1 x C547B transistor
2 x 10KOhm resistors
1 x 5v DC Motor
1 x 100 MicroF Elco
2 x push-to-make buttons

This circuit will send a pulse every x milliseconds. You can control the pulse length by pressing the buttons.






Upload the following sketch to the Arduino, you will need the Metro library:


#include

#define PINBUTTON1 2
#define PINBUTTON2 3
#define PINMOTOR 8


signed int pulseTime=50;
unsigned long prevPulse = millis();

boolean inPulse = false;

Metro MotorPulse = Metro(250);


void setup ()
{
  pinMode(PINMOTOR, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  if (millis() %500 ==0)
 {
  int curbut1 = digitalRead(PINBUTTON1);
  if (curbut1==HIGH)
  {
    if (pulseTime + 5 <=100)
   pulseTime +=5;
   else
     pulseTime=100;
 Serial.print(pulseTime);
 Serial.print("\n");


  }
 
  int curbut2 = digitalRead(PINBUTTON2);
  if ( (curbut2==HIGH))
  {
    if (pulseTime - 5 >=0)
      pulseTime -=5;
    else
      pulseTime = 0;
     
 Serial.print(pulseTime);
 Serial.print("\n");


  }
 }

 
  if (!inPulse)
  {
    if (MotorPulse.check() == 1)
    {
      MotorPulse.interval(5);
      inPulse = true;
      digitalWrite(PINMOTOR , HIGH);
    }
  }
  else
  {
    if (MotorPulse.check() == 1)
    {
      MotorPulse.interval(pulseTime);
      inPulse = false;
      digitalWrite(PINMOTOR , LOW);
    }
  }
 
}




Geen opmerkingen:

Een reactie posten