Serial Controlled Variable Speed Motor





Introduction: Serial Controlled Variable Speed Motor

Control the speed of a small DC motor with nothing but the serial port on your computer, a single MOSFET, and some trivial software. (The MOSFET and the serial port make up the "speed control"; you'll still need a motor and an appropriate power supply for that motor; while the serial port can provide the voltage to turn a mosfet on and off, it can't supply the current needed by a typical motor.)

Step 1: Look at the Circuit

We're going to do Pulse Width Modulation using a generic N-channel power MOSFET connected to the Transmit data pin from the computer's rs232 port. When the serial port is idle, the pin will sit at the "1" state, which by the time it's translated to rs232, is something like -12V (depending on drivers, it might be closer to -9V or -5V), and the transistor will be quite OFF. When we transmit "0" bits on the serial port, the rs232 pin will go to +12V or so, which is enough to turn on most mosfets pretty well.

If we transmit a lot of "0" bis in a row, the motor will be close to fully ON and the motor will run fast. If we transmit mostly "1" bits, the motor will run more slowly.

Step 2: Wire It Up

Since there's only a single component and only a few connections, you can just add wires "freeform."
MOSFETs are static sensitve, so be a little bit careful, but very little is critical.

Step 3: Set Up Files With PWM Values

One way to control the motor without having to write ANY software is to prepare some files containing appropriate bytes (with more or less 0 bits), and simply COPY them to the COM port where you have the motor connected. I prepared several files (using emacs, but whatever works for you is fine):

  • 0.pwm:: contains 5000 NULL characters (control-space on most keyboards)[br] This is about as close to "full speed" as we'll be able to get with this technique.
  • 1.pwm:: contains 5000 control-A characters (ascii 01) (one "1" bit per char)
  • 3.pwm:: contains 5000 control-C characters (ascii 03) (two "1" bits per char)
  • 7.pwm:: contains 5000 control-G characters (ascii 07) (three "1" bits per char)
  • 15.pwm:: contains 5000 control-O characters (ascii 15) (four "1" bits per char)
  • 31.pwm:: contains 5000 control-_ characters (ascii 31) (five "1" bits per char)
  • 63.pwm:: contains 5000 "?" characters (ascii 63) (six "1" bits per character)
  • 127.pwm:: contains 5000 DEL characters (ascii 127) (seven "1" bits per character)

(Now that I've drawn pictures, you'll notice that the actual bit patterns aren't ideal. Since rs232 serial transmits LSB first, we really want to shift in zeros instead of ones. An excercise for the student!)

Step 4: Play With DOS: Configure Your COM Port and Copy the Files

9600 bps is a common bitrate. It matches nicely to "about" one byte per millisecond, so in this case it corosponds to a PWM frequency of 1000Hz, which I think ought to be ok for smallish motors. You can experiment with different bit rates to see how things work, which is one of the advantages of this method.

Create a DOS (or "Command prompt") window (assuming you're using a windows OS), and configure
your com port like:

mode com1: 9600,n,7,1"

That tells the comm port to run at 9600bps, and send 7 bits in each character (to match up with our 7 different bit-lengths.) The "n" means NO parity, so those will be the only data bits. The "1" means there will be one "stop" bit, which will prevent us from turning the motor all the way on (oh well.)

So now you can turn on the motor with commands like:

copy 0.pwm com1:

Since we're sending 5000 characters at about 1 per millisecond, the motor should turn on at close to full speed for about 5 seconds. If you want less than 5 seconds, make a shorter file. Similarly, you can do:

copy 127.pwm com1:

to run the motor at the lowest possible speed. With the setup I had, the motor wouldn't turn at all with anything "slower" than 31.pwm, but YMMV (I think I had a 12V motor running off 5V of batteries.)

The COPY command lets you string files together, so if you want your motor to speed up and then slow down again, you can do something like:

copy 31.pwm+15.pwm+7.pwm+0.pwm+7.pwm+15.pwm+31.pwm com1:

Step 5: Control the Motor From a Program

If you're writing a program, you can probably open COM1: as a file and simply write to it as if it were any other file. Being able to time the periods that the motor is on by outputting a particular number of characters would seem to be very handy. Don't forget that the system is very likely to buffer the characters that you send to the serial port, so just because a WRITE call returns doesn't mean that the motor has finished doing whatever you told it to. Since we don't do anything "fancy" with the com port signals, you shouldn't have to investigate the arcane options that it might support. (although, if you can figure out how to send a BREAK sequence to the com port, that's a continuous "0" state, and will drive the motor ALL the way on; more than sending continuous 0 characters.)

If your programming language doesn't let you output to COM1:, you may still be able to control the motor by "calling" DOS to do copy commands.

(OK. I've downloaded Microsoft's Visual Basic Express 2005 (which is free) and managed to tie a horizontal scroll bar to the motor speed, controlled via the serial port. zip attached. It's probably got more than it needs to duplicate the program on your system, but I couldn't figure out exactly which bits were needed. The program is both simplified and made more difficult to understand (sorry) by being multi-threaded. One thread does nothing but output to the serial port, and the main thread reads the scroll bar and updates info used by the serial thread.)

Step 6: Experiment!

If things are basically working, this provides an awful lot of room for experimentation.

  • Fix my bit patterns!
  • Does the bitrate matter much?
  • Do you have to control the width of "on" and "off" pulses, or is simply controling their ratio sufficient?
  • If you only have to control the ratio, you can consider multi-character sequences at higher bit rates to get more speed levels. Outputing 0 followed by 127 would be about half on.
  • This should work for dimming flashlight bulbs, too.



    • Science of Cooking

      Science of Cooking
    • Microcontroller Contest

      Microcontroller Contest
    • Spotless Contest

      Spotless Contest

    We have a be nice policy.
    Please be positive and constructive.




    This is a nice idea indeed. I just would like to controll (dim) several lights this way. Is this also possible with a usb to parralell converter? so i can manage at least 8 lights?

    Hi, just wondering if you can help? I tried your circuit using a mosfet from Freetronics and connected it according to their diagram (using GDS etc, because your diagram varied slightly to theirs).. I have a small relay connected to the mosfet, but after trying it, nothing happened, so I swapped the serial Ground & TxD pins and it worked... kinda. The problem is that its kinda working backwards - the relay is always energised (its on, cos I can hear it click right away) and when I send a command to the com/serial port, it switches it off instead. It's almost like the mosfet is working backwards - but im guessing i've just made a dumb mistake... any help would be appreciated. ohhh ignore the Arduino board thing in the pic, im just connecting it to my PC. thanks heaps...


    A relays is to slow to switch high frequency's. The mosfet will stay high all the time then. The mosfet handles high frequencies so that it switches on and of very fast, and with that the engine goes faster or slower if the frequency on the rs232 port is changing. So remove the relay and choose the right mosfet that can handle the power from the engine, but also switches at the voltage from the RS232 port.

    Which MOSFET, exactly? A P-channel mosfet will in fact behave essentially "opposite" an N-channel mosfet...

    can i have the codes for this?thank you!

    They should be right there in step 5 in the file...


    i tried this design using a desktop instead, an IBM P3 model 300PL, it didnt work, whenever i type copy 0.pwm com1:, the dos prompts writes " WRITE FAULT ERROR WRITING DEVICE COM1" 
    abort, retry, ignore, fail?

    in order it to work, i wired the 9pin dsub as  a null it worked..

    to make a 9pin null modem..
    connect pins 3 to 2, pins 7 to 8, pins 1,4,6 and 9...

    now connect gate of mosfet to pin 2 and 3, and ground wire to pin 5...

    it works great...

    have a nice experiments..

     great! will try this, hope it will work on my laptop using a usb to serial port cable..

    i used this for my pc tube light and giant cooling fan

    I founded one on old graphics card!