Simple Motor Speed Control - Help Please!

What I am looking to do is control the speed of a 12vDC Motor in one direction, but I need stable and repeatable RPM Results. I have no problem getting it to work with just PWM but I realize that I will need to put a rotary encoder on the motor and somehow control it by monitoring that value and adjusting the PWM output if the motor ever see's load.

to start out with I just want to get to the point where I can just manually put a rpm value into a variable, or change that value through a potentiometer and have the motor go to the correct rpm that the value is asking for and attempt to hold it if I put load on the motor. I can work out from there. I'm not using a motor shield, or H-Bridge.. just a TIP120 transistor, like I said, only one direction, speed up and down. in the end the input will be coming from a hall sensor from another piece of equipment and the DC motor rpm will change depending on the shaft rotation from that device.

I have looked at the PID Library, and I'm sure this can be done without it, but I can't seem to find any examples without a tonne of extra's in the code that I tend to get lost in, and I honestly can't find anyone who is just doing simple one direction control.

Could you get an old mouse (ball style) an hack out it's tracking wheel/sensor?

You might do google advanced search of this and the old forum for tachometer to see how others have timed digital inputs and developed a corrosponding value.

Well - to detect the RPM, the simplest way would be to use a phototransistor/ir led slot detector pair, and a disk on the motor shaft with a hole in it that passes thru the slot. So - every pulse you sense is one revolution of the motor. Hook this up to a pin on the Arduino and use a pin-change interrupt function to update a variable based on a timed value (so you know how long it was from one event to the next); I am not sure if this will be a problem or not, or if there will be jitter due to the timer interfering with the interrupt (or vice-versa) - but that's the basic idea.

So now, in your main code, you'll have a variable that you can access (updated in the ISR) - that contains a value that approximates the RPM; actually, how long it takes for the shaft to rotate once. Convert this value to an RPM (don't do this in the ISR!). Then, compare your "set-point" RPM to this RPM; if the read value from the ISR is lower (caused by a load or other) than your set-point RPM, increase the PWM by some amount, if the value read is higher (lack of load or other), decrease it by some amount. You may or may not need to have a "window percentage" value for your comparison, to avoid oscillation.

That's the basics - I think (I've never done this - but it seems reasonable). You might want to look at PID control further, though; depending on how accurate you need it, PID might give you better accuracy, and help to prevent oscillation as well (once tuned). Note that I don't think you'll ever get "perfect" RPM timing. Something you might try, though, to increase accuracy, is to add more "slots" or "holes" to the timing disc.

One other thing: Depending on your skill, you might be able to eliminate the timing disc and detector entirely, by detecting the back-emf field "spike", which should correlate with the RPM of the motor (something to think about).

Good luck - hope this helps, or at least gives you some direction! :)