Difference between revisions of "Experimenting with Stepper Motors as Rotary Encoders using a PIC running BoostC Project"

From OpenCircuits
Jump to navigation Jump to search
(New page: = Experimenting with Stepper Motors as Rotary Encoders using a PIC running BoostC Project = '''EARLY DRAFT - NOT READY''' *Name: Experimenting with Stepper Motors as Rotary Encoders Pr...)
 
 
(19 intermediate revisions by the same user not shown)
Line 2: Line 2:
  
  
'''EARLY DRAFT - NOT READY'''
+
'''Almost done, needs some detail completed, should be useful as stands, email if you have questions'''
  
  
*Name: Experimenting with Stepper Motors as Rotary Encoders Project
+
*Name: Experimenting with Stepper Motors as Rotary Encoders using a PIC running BoostC Project
*Status: early draft -- do not read
+
*Status: works in my lab
 
*Technology: PIC microcontroller with code in BoostC  
 
*Technology: PIC microcontroller with code in BoostC  
 
*Author: russ_hensel ( where you can find an email address to reach me )
 
*Author: russ_hensel ( where you can find an email address to reach me )
 
*Summary: A PIC16F877A project that operates a stepper motor as an encoder Runs with a PC running a terminal program.
 
*Summary: A PIC16F877A project that operates a stepper motor as an encoder Runs with a PC running a terminal program.
 +
*Last revision Dec 19 2008
 +
*Archive zip file see Download below.
  
 +
Rotary encoders are devices that allow electronic measurement of rotation.  You can find a lot of information by Googling “rotary encoder”.  Many are optical with a partly transparent wheel rotating and being read by 2 pairs of led and photo detectors.  Most of the old ball based mice had 2 optical rotary encoders to measure motion in the x and y direction.  You can take these old guys apart to get at the encoders.  Stepper motors can also be used as rotary encoders.  When rotated the motors act as generators and generate the two out of phase waves that are the standard output of encoders (at least after the waves are squared up).  If turned very slowly the output signal drops to a very low voltage and you can miss steps; so these guys are not perfect.  A nice feature of the motors is that they often have a very nice feel in your hands especially if you put a nice knob on them.  Other multi phase motors, like disk drive motors, are reputed to work as well, and often have enough mechanism on them to use as a knob.  The output of the encoder can be used as a volume control, tuning device or whatever.
  
Last revision Dec 09 2008 – Early Draft.
+
This project describes just enough software and hardware to let you experiment with stepper motors as encoders to use as a jumping off point for a more complete project.
Archive zip file ( none ) includes: nothing Email me for file, will be posted eventually.
 
  
  
Platform: PIC16F877A using BoostC connected via rs232 to a PC running a terminal program, or as an alternative running a Java program developed especially to control the PIC ( still under development ). The PIC chip is supplemented with a MAX232 chip and a ULN2003 driver.
 
  
 +
Platform: PIC16F877A using BoostC connected via rs232 to a PC running a terminal program, or as an alternative running a Java program developed especially to control the PIC ( still under development ). The PIC chip is supplemented with a dual op amp connected as two schmidt triggers, there is of course a stepper motor.
  
Example:
 
  
{| class="wikitable"
 
|-valign="top"
 
! Command
 
! Meaning
 
<!------------------------------->
 
|-valign="top"
 
|v<cr>
 
|Get the version make sure the command interface is running, usually takes 2 tries to initialize, this is a bug which I have not fixed yet.
 
<!------------------------------->
 
|-valign="top"
 
|t10<cr>
 
|Set the step delay to 10 ms
 
<!------------------------------->
 
|-valign="top"
 
|p1<cr>
 
|Select permutation 1
 
<!------------------------------->
 
|-valign="top"
 
|d+<cr>
 
|Set direction forward
 
<!------------------------------->
 
|-valign="top"
 
|g400<cr>
 
|Go for 400 steps – full turn on many motors
 
<!-------------------------------
 
|-valign="top"
 
|
 
|
 
<!-------------------------------
 
|-valign="top"
 
|
 
|
 
  
<!------------------------------->
+
== Hardware ==
  
|}
+
The output of the stepper motor can be quite small if the motor is turned slowly, or quite high if turned fast.  To deal with the high output we used 2 diodes one to the positive rail and one to the negative rail.  To avoid two power supplies a voltage divider across a single 5 volt power supply is used and the center of the divider is considered as ground for the input.  To deal with low voltage inputs the full gain of an op amp is used, this will take a small voltage and boost it to either +5 volts ( if the op amp can reach the positive voltage rail ) or 0 volts.  Since the op amp is powered on 5 volts its output cannot get so high as to damage the PIC.  My first circuit worked just like this and produced junk for output.  Apparently a lot of noise crept in near the transition between the voltages, this despite that the signals did not look too bad on an oscilloscope.  To avoid this I added some positive feedback to make the circuit a Schmidt trigger.  The feedback makes the circuit less sensitive, but dramatically improved the success of the device.  Decreasing the the feedback will make the circuit more sensitive but may bring the noise back, increasing the feedback resistor decreases the feedback.
  
 +
In the schematic only 1 of the two Schmidt triggers is shown.  Note that the stepper motor has 4 coils, only two are used.  It does not matter which the first coil is, but then next one must be one of the three that is 90 degrees out of phase with the first.  If you have scope with xy input, plot the two signals.  When the motor is rotated the plot should rotate around the corners of a square.
  
== Hardware ==
+
The PIC part is the circuit is like that of [[PIC based Stepper Motor Dancing Analog Clock]] or [[Stepper Motor Tester]] Use the inputs as specified in the software.
  
I have used a PIC 16F877A for the project, but pretty much any PIC with a uart and another 4 free I/O lines should do. To increase the drive to the motor I used a ULN2803 which is simply an array of Darlington transistors and diodes to be used as a low side switch for each motor winding. There are other similar chips around or discrete devices can be used. I run the pic, on 5 volts, and a larger voltages for the stepper, up to the limit of the driver. ( the UNL2803 is good for 50 v at .5 amp as a switch ) and the rating of the stepper motor. If you have a high power motor you may want a driver with more guts, Just put in some substitute. Coil drive is on or off there is no PWM involved here. Note that the hardware has substantial uncommitted resources. You could easily drive another motor for example. Also some of you may want to put some pull up or down resistors on some of the uncommitted resources. Instead of this board you could use the circuit from the [[PIC based Stepper Motor Dancing Analog Clock]], the main difference is that that circuit does not use the MAX232 chip, it relies on an off board level shifter ( makes it easy to shift the level shifter from project to project while saving some money and board space )
 
  
 
=== Schematic ===
 
=== Schematic ===
Line 69: Line 38:
  
  
Parts  -- this is not up to date, working on it
+
Parts  -- this is not up to date, working on it, but mostly correct.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 78: Line 47:
 
|-valign="top"
 
|-valign="top"
 
|Power supply
 
|Power supply
|Not shown, you need two dc voltages, one for the PIC at 5 volts, and another with the right voltage for the motors.  There is a suitable power supply in the [[PIC based Stepper Motor Dancing Analog Clock]]
+
|Not shown, 5 volts, you can use a higher voltage with a voltage regulator.  There is a suitable power supply in the [[PIC based Stepper Motor Dancing Analog Clock]]
 
<!-------------------------------->
 
<!-------------------------------->
 
 
|-valign="top"
 
|-valign="top"
 
|PIC16F877A
 
|PIC16F877A
|My favorate 16 series part, relatively lots of memory and pins.  Bigger than you need, but only about 8 bucks.  Try with an 18 series part, should not be hard and will leave you more up to date.  Let me know.
+
|My favorate 16 series part, relatively lots of memory and pins.  Bigger than you need, but only about 8 bucks.  Try with an 18 series part, should not be hard and will leave you more up to date.  Let me know.  Other parts of the PIC circuit not discussed here.
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
|MODE_1...MODE_6 = Rotory Switch connections
+
|Stepper Motor
|I used an old Radio Shack 12 position switch only 6 of them are used here.  You could use seperate pushbuttons, the advantage is that the position of the rotory switch indicates which mode you are in, else you may want an led for each one, perhaps using another bunch of ports.
+
|I used a salvage one I had lying around.
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
Line 94: Line 62:
 
<!-------------------------------->
 
<!-------------------------------->
 
|-valign="top"
 
|-valign="top"
|Pull Up/Down Resistors
+
|Power supply splitting resistors, form a pseodo ground at about 2.5 volts.
|10k more or less
+
|100 more or less
 +
<!-------------------------------->
 +
|-valign="top"
 +
|RIN
 +
|about 5 to 10 K 
 
<!-------------------------------->
 
<!-------------------------------->
 
|-valign="top"
 
|-valign="top"
|CQ1, CQ2 = capicators for the crystal
+
|RFB
|about 20 pf seems to work, see the PIC16F877A manual
+
|feedback resistor should be about 4 times higher than the input resistor
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
Line 105: Line 77:
 
|
 
|
 
<!--------------------------------
 
<!--------------------------------
|-valign="top"
 
|xx
 
|
 
<!-------------------------------->
 
 
|-valign="top"
 
|-valign="top"
 
|Q = crystal
 
|Q = crystal
Line 124: Line 92:
 
|RRA2, RRA3  = Pull up resistors
 
|RRA2, RRA3  = Pull up resistors
 
|10K more or less
 
|10K more or less
<!-------------------------------->
+
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
 
|C_BP  = By Pass Cap.
 
|C_BP  = By Pass Cap.
Line 133: Line 101:
 
|10K more or less
 
|10K more or less
 
<!--------------------------------
 
<!--------------------------------
|-valign="top"
 
|
 
|
 
<!-------------------------------->
 
|-valign="top"
 
|DRIVER  = Low side switch for motor coils.
 
|Driver chip for stepper.  ULN2803.  Good for up to .5 amp 35 volts I think.  Could use discrete transistors ( possibly darlingtons ) if you want higher current. Also see not on stepper power.
 
<!-------------------------------->
 
 
|-valign="top"
 
|-valign="top"
 
|RMC  = Pull up resistor for master clear ( pull down with push button switch to reset ).
 
|RMC  = Pull up resistor for master clear ( pull down with push button switch to reset ).
 
|10k more or less
 
|10k more or less
<!-------------------------------->
+
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
 
|PUSH_BUTTON_SWITCH  = Reset
 
|PUSH_BUTTON_SWITCH  = Reset
 
|Push to reset the processor.  Mine was from salvage.
 
|Push to reset the processor.  Mine was from salvage.
<!-------------------------------->
+
<!--------------------------------
|-valign="top"
 
|STEPPER_POWER
 
|This voltage needs to be adjusted for the voltage of you stepper motor.  Lower voltage motors, like 5 volt motors, often require more current than the driver chip can supply.  You may need to change this to an array of power transistors for high currents.  Make sure that 5 volts is enough to turn them on and perhaps add a current limiting resistor to the base drive.  MOSFETS can be good, but not all switch on at 5 volt drive.
 
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
Line 172: Line 129:
 
|
 
|
 
|
 
|
<!-------------------------------->
 
|-valign="top"
 
|VPLUS_VDD = Positive power
 
|To the 5 volt power.  Note stepper power is normally a different supply and often a higher voltage.
 
<!-------------------------------->
 
|-valign="top"
 
|G1  = Ground connection
 
|Not show, add one to connect the power supply.
 
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
Line 188: Line 137:
 
|  =
 
|  =
 
|
 
|
<!-------------------------------->
 
|-valign="top"
 
|MOUNT_1...4
 
|Mounting holes
 
 
<!--------------------------------
 
<!--------------------------------
 
|-valign="top"
 
|-valign="top"
Line 213: Line 158:
 
|-valign="top"
 
|-valign="top"
 
|Report version
 
|Report version
|v
+
|v<cr>
 
|Version of the PIC software something like:  
 
|Version of the PIC software something like:  
 
Serial Stepper Test ver July 4 2008
 
Serial Stepper Test ver July 4 2008
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
|Set direction
+
|Reset
|d+
+
|r<cr>
d-
+
reset the counters and the log of the encoder. Response something like "Reset Count"
|plus for forward, minus for back
 
Direction set.
 
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
|Where = Request motor position
+
|Log report
|w
+
|l<cr>
|Step taken since power on.
+
|Report the log of data. A series of binary numbers, comma delimited.
Signed int.
 
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
Line 234: Line 176:
 
|r
 
|r
 
|Delimited by commas something like:
 
|Delimited by commas something like:
Dir +1, Permutation 1, Stepper Pos 80, Step Delay Us = 300 .....
 
<!------------------------------->
 
|-valign="top"
 
|Go for a number of steps
 
|gnnn
 
|go for a number of steps ( max. about 30,000 ) Direction set with d.
 
Responds with "g starting<cr>" when rotation begins, then with "g done<cr>" when done.  May be stopped early with stop command.
 
<!------------------------------->
 
|-valign="top"
 
|Set the time delay between steps in ms ( max 255 )
 
|tnnn
 
|Reports delay set.  nnn = 0 to 255
 
<!------------------------------->
 
|-valign="top"
 
|Micro second delay in addition to to the ms delay.
 
|unnnn
 
|Reports delay set. Ok to use values nnn = as high as 5000 us.
 
<!------------------------------->
 
|-valign="top"
 
|Set the permutation of the motor wires.
 
|pn
 
|Set the permutation, find the value that works for your motor. ( n = 0 to 5 ) Responds with the permutation set.
 
<!------------------------------->
 
|-valign="top"
 
|Special command 1, Spin the motor in an interesting way. 
 
|x1
 
|Motor spins responds with "x special done<cr>" when it is done.  May be stopped with the stop cammand.
 
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
|Special command 2, Vibrate the motor first a lot then less and less to stop
+
|Position of the encoder
|x2
+
|p<cr>
|responds with "x special done<cr>" when it is done
+
|report the position of the encoder, and other counts of encoder activity.
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
 
|Stop  
 
|Stop  
 
|!
 
|!
|Should almost immediately stop long running commands like Go or x1 or x2. Responds with Stopped<cr> when stoped ( wich should be quick ).
+
|Should almost immediately stop long running commands of which there are currently noneResponse Stopped.
 
<!------------------------------->
 
<!------------------------------->
 
|-valign="top"
 
|-valign="top"
Line 288: Line 203:
  
 
== Microcontroller Program Design ==
 
== Microcontroller Program Design ==
I no longer have the patience for assembly language. I have moved on to C in particularly BoostC, see link below. I like this compiler it has both a free version with some restrictions and a very reasonably priced full version. Writing in C should make the program fairly easy to read. Most of the design should be evident by reading the program, however a few notes here may help.
+
There are several different ways the software can work: 
 +
 
 +
*Simple polling when the encoder is checked as often as you can get to it.
 +
 
 +
*Timer driven interrupt programming where the encoder is checked based on some timer.
 +
 
 +
*Interrupt driven programming where changes in the encoder output trigger the interrupt ( I have not worked this one out here )
 +
 
 +
The software remembers the last state of the encoder and compares it to the current state: one of the following must be true:
 +
 
 +
*There is no change which we take to indicate that there is no rotation ( true if we have not missed any changes ).
  
The idea is to put each activation sequence in a table and then step through that table and activate the corresponding port bits and thus stepper coils. The four wires can be activated in a total of 6 different ways, one table corresponds to each permutation. The particular table to use is set using the permutation command ( p ).
+
*There is a change indicating a positive or negative rotation of one step ( which we add or subtract from our step count )
  
The series of wires to energize is specified in the arrays StepperStepsN where N is the number of the wire permutation. Each step just increments its way through the array wrapping around the the beginning and the end.  
+
*There is a change but it does not correspond to a one step rotation, this can happen when we miss a step or when the hardware sends bad data. It can easily happen any time rotation speed drops so low that the hardware cannot detect the rotation, or when the rotation speed starts up and our old rotation state is not accurate.  The software counts this as an error.
  
Commands are received via an interrupt driven routine, the main loop checks each time around to see if a complete command has been received. Because commands are only interpreted in the main loop all commands are ignored until the program returns to the main loop. The exception to this is the stop command which will terminate a g or x command and return to the main loop quickly. RS232 transmission is not driven by an interrupt and so during transmission from the pic no stepping takes place.  Commands which do not result in motion execute very quickly, most of the time is for communications.
+
All variables are unsigned, this keeps speed up. Since the rotation is bi-directional the reset of the count is to a middle value for the range of the variable 32000.
  
Currently drive to the motor is half step drive. This gives twice as many steps per revolution as is labeled on the motor. I plan later to let you select half step, full step or wave drive. See the links below for more information.
+
The software also logs the data received any time it changes, this is limited to about 100 changes because a whole byte is use for logging, with a little packing of data 400 changes could be recorded.
 +
 
 +
Control of the software is via the serial communications library that I have described in other articles. It yields a command driven interface described above.
  
 
==== Compiling ====
 
==== Compiling ====
Line 303: Line 230:
 
Memory Usage Report
 
Memory Usage Report
  
*RAM available:368 bytes, used:139 bytes (37.8%), free:229 bytes (62.2%),  
+
*RAM available:368 bytes, used:248 bytes (67.4%), free:120 bytes (32.6%),  
*Heap size:229 bytes, Heap max single alloc:95 bytes
+
*Heap size:120 bytes, Heap max single alloc:95 bytes
*ROM available:8192 words, used:2118 words (25.9%), free:6074 words (74.1%)
+
*ROM available:8192 words, used:1239 words (15.2%), free:6953 words (84.8%)
  
I think you could contract the program a bit to get under the 2K free compiler limit.
+
The program seems to be safely under the 2K free compiler limit.
  
  
  
 +
== Other Things to Try/Additions/Changes/Modification ==
  
 +
* The 877A is way overkill for this project unless you make it do a bit more.  Note that only 2 input pins plus the serial lines are really used.
  
== Other Things to Try ==
+
* There is nothing magic about the dual op amp I had around, lots of others should work, there are also IC schmidt triggers.  Some PIC input ports have schmidt triggers on their inputs.  Op amps are good for many other things so nice to have around.  You can tweak the parameters of a op amp schmidt trigger in a way you cannot with other circuits. [[Basic_Circuits_and_Circuit_Building_Blocks#Schmitt_Trigger]]
  
== Additions/Changes/Modification ==
+
* Optimize the code especially in countEncoder()
  
* The 877A is way overkill for this project unless you make it do a bit more.  Note that only 2 input pins plus the serial lines are really used.
+
* Read multiple encoders.
  
* There is nothing magic about the dual op amp I had around, lots of others should work, there are also IC schmidt triggers.  Some PIC input ports have schmidt triggers on their inputs.  Op amps are good for many other things so nice to have around.  You can tweak the parameters of a op amp schmidt trigger in a way you cannot with other circuits. [[Basic_Circuits_and_Circuit_Building_Blocks#Schmitt_Trigger]]
+
* Optical encoders are easier to read, signals do not depend so much on rotational speed, try using them.
  
* Optimize the code especially in countEncoder()
+
* Use as a control element in a larger project, aming a laser.
  
 
== Possibly useful links ==
 
== Possibly useful links ==
Line 332: Line 261:
 
Rotary Encoder
 
Rotary Encoder
 
http://www.webx.dk/oz2cpu/20m/encoder.htm
 
http://www.webx.dk/oz2cpu/20m/encoder.htm
 +
 +
[http://home.clear.net.nz/pages/joecolquitt/stepper_as_encoder.html  Stepper Motor As Rotary Encoder]
 +
 +
[http://www.instructables.com/id/HDDJ_Turning_an_old_hard_disk_drive_into_a_rotary/ HDDJ: Turning an old hard disk drive into a rotary input device]
  
 
Using a disk drive motor as encoder:
 
Using a disk drive motor as encoder:
 
Inexpensive rotary encoder
 
Inexpensive rotary encoder
 
http://users.tkk.fi/~jwagner/electr/rotary-enc/
 
http://users.tkk.fi/~jwagner/electr/rotary-enc/
 +
 +
[http://home.clear.net.nz/pages/joecolquitt/stepper_as_encoder.html Stepper Motor As Rotary Encoder]  seems to be same as [http://www.piclist.com/techref/io/sensor/pos/enc/stepper_as_encoder.htm Stepper Motor As Rotary Encoder] this seems to give a nice trick to greatly improve the sensitivity of the motor as encoder.  Might want to try this.
  
 
Info on steppers:
 
Info on steppers:
Line 344: Line 279:
 
Stepper motors  
 
Stepper motors  
 
http://www.allaboutcircuits.com/vol_2/chpt_13/5.html
 
http://www.allaboutcircuits.com/vol_2/chpt_13/5.html
 +
 +
Rotary Encoders
 +
http://www.ubasics.com/adam/electronics/doc/rotryenc.shtml
  
 
More info on steppers:
 
More info on steppers:
Line 356: Line 294:
 
SourceBoost Technologies
 
SourceBoost Technologies
 
http://www.sourceboost.com/
 
http://www.sourceboost.com/
 
 
  
 
== Download ==
 
== Download ==
  
pending, not at: [http://home.comcast.net/~russ_hensel/OC/StepperTest_v1.zip Version 1 zip file: StepperTest_v1.zip]
+
At: [http://home.comcast.net/~russ_hensel/OC/StepperTest_v1.zip Version 1 zip file: StepperTest_v1.zip]  To check for more recent versions email me: [[russ_hensel]]
  
 
== Comment, Questions, Contributions? ==
 
== Comment, Questions, Contributions? ==
  
 
Email me [[russ_hensel]], or use the talk page for this topic.  All feedback is welcome.
 
Email me [[russ_hensel]], or use the talk page for this topic.  All feedback is welcome.
 +
 +
[[category:projects]]

Latest revision as of 09:56, 3 January 2011

Experimenting with Stepper Motors as Rotary Encoders using a PIC running BoostC Project[edit]

Almost done, needs some detail completed, should be useful as stands, email if you have questions


  • Name: Experimenting with Stepper Motors as Rotary Encoders using a PIC running BoostC Project
  • Status: works in my lab
  • Technology: PIC microcontroller with code in BoostC
  • Author: russ_hensel ( where you can find an email address to reach me )
  • Summary: A PIC16F877A project that operates a stepper motor as an encoder Runs with a PC running a terminal program.
  • Last revision Dec 19 2008
  • Archive zip file see Download below.

Rotary encoders are devices that allow electronic measurement of rotation. You can find a lot of information by Googling “rotary encoder”. Many are optical with a partly transparent wheel rotating and being read by 2 pairs of led and photo detectors. Most of the old ball based mice had 2 optical rotary encoders to measure motion in the x and y direction. You can take these old guys apart to get at the encoders. Stepper motors can also be used as rotary encoders. When rotated the motors act as generators and generate the two out of phase waves that are the standard output of encoders (at least after the waves are squared up). If turned very slowly the output signal drops to a very low voltage and you can miss steps; so these guys are not perfect. A nice feature of the motors is that they often have a very nice feel in your hands especially if you put a nice knob on them. Other multi phase motors, like disk drive motors, are reputed to work as well, and often have enough mechanism on them to use as a knob. The output of the encoder can be used as a volume control, tuning device or whatever.

This project describes just enough software and hardware to let you experiment with stepper motors as encoders to use as a jumping off point for a more complete project.


Platform: PIC16F877A using BoostC connected via rs232 to a PC running a terminal program, or as an alternative running a Java program developed especially to control the PIC ( still under development ). The PIC chip is supplemented with a dual op amp connected as two schmidt triggers, there is of course a stepper motor.


Hardware[edit]

The output of the stepper motor can be quite small if the motor is turned slowly, or quite high if turned fast. To deal with the high output we used 2 diodes one to the positive rail and one to the negative rail. To avoid two power supplies a voltage divider across a single 5 volt power supply is used and the center of the divider is considered as ground for the input. To deal with low voltage inputs the full gain of an op amp is used, this will take a small voltage and boost it to either +5 volts ( if the op amp can reach the positive voltage rail ) or 0 volts. Since the op amp is powered on 5 volts its output cannot get so high as to damage the PIC. My first circuit worked just like this and produced junk for output. Apparently a lot of noise crept in near the transition between the voltages, this despite that the signals did not look too bad on an oscilloscope. To avoid this I added some positive feedback to make the circuit a Schmidt trigger. The feedback makes the circuit less sensitive, but dramatically improved the success of the device. Decreasing the the feedback will make the circuit more sensitive but may bring the noise back, increasing the feedback resistor decreases the feedback.

In the schematic only 1 of the two Schmidt triggers is shown. Note that the stepper motor has 4 coils, only two are used. It does not matter which the first coil is, but then next one must be one of the three that is 90 degrees out of phase with the first. If you have scope with xy input, plot the two signals. When the motor is rotated the plot should rotate around the corners of a square.

The PIC part is the circuit is like that of PIC based Stepper Motor Dancing Analog Clock or Stepper Motor Tester Use the inputs as specified in the software.


Schematic[edit]

Schematic


Parts -- this is not up to date, working on it, but mostly correct.

Part Details
Power supply Not shown, 5 volts, you can use a higher voltage with a voltage regulator. There is a suitable power supply in the PIC based Stepper Motor Dancing Analog Clock
PIC16F877A My favorate 16 series part, relatively lots of memory and pins. Bigger than you need, but only about 8 bucks. Try with an 18 series part, should not be hard and will leave you more up to date. Let me know. Other parts of the PIC circuit not discussed here.
Power supply splitting resistors, form a pseodo ground at about 2.5 volts. 100 more or less
RIN about 5 to 10 K
RFB feedback resistor should be about 4 times higher than the input resistor

Command Interface[edit]

All commands ( except stop should be terminated with a carriage return ) Note that the command interface is not very smart, giving parameters that are out of range my blow the whole program up. If so reboot the PIC. Do not send a new command ( except stop ) until earlier commands have been completed ( actually you can get ahead some if you are careful )


Command Code Notes, PIC Response
Report version v<cr> Version of the PIC software something like:

Serial Stepper Test ver July 4 2008

Reset r<cr>

reset the counters and the log of the encoder. Response something like "Reset Count"

Log report l<cr> Report the log of data. A series of binary numbers, comma delimited.
Report on all parameters r Delimited by commas something like:
Position of the encoder p<cr> report the position of the encoder, and other counts of encoder activity.
Stop ! Should almost immediately stop long running commands of which there are currently none. Response Stopped.
Other, not understood commands xxx Responds with "!Bad Command = xxx" if the command is not understood.


Notes on terminal program set up.

  • Baud rate should be 19.2K 8N1
  • Most terminal programs can be set to treat a carriage return as a carriage return line feed. Do it.

Some terminal programs will not transmit in lower case ( all our commands are lower case ) unless specially set to do so. Set it to allow lower case.

Microcontroller Program Design[edit]

There are several different ways the software can work:

  • Simple polling when the encoder is checked as often as you can get to it.
  • Timer driven interrupt programming where the encoder is checked based on some timer.
  • Interrupt driven programming where changes in the encoder output trigger the interrupt ( I have not worked this one out here )

The software remembers the last state of the encoder and compares it to the current state: one of the following must be true:

  • There is no change which we take to indicate that there is no rotation ( true if we have not missed any changes ).
  • There is a change indicating a positive or negative rotation of one step ( which we add or subtract from our step count )
  • There is a change but it does not correspond to a one step rotation, this can happen when we miss a step or when the hardware sends bad data. It can easily happen any time rotation speed drops so low that the hardware cannot detect the rotation, or when the rotation speed starts up and our old rotation state is not accurate. The software counts this as an error.

All variables are unsigned, this keeps speed up. Since the rotation is bi-directional the reset of the count is to a middle value for the range of the variable 32000.

The software also logs the data received any time it changes, this is limited to about 100 changes because a whole byte is use for logging, with a little packing of data 400 changes could be recorded.

Control of the software is via the serial communications library that I have described in other articles. It yields a command driven interface described above.

Compiling[edit]

The zip file contains the entire source bootst project. Unzip into a directory and open in source boost. Set the target to 16F877A. See the comments in the program header for other setup before compiling. After compiling my compiler reports something like:

Memory Usage Report

  • RAM available:368 bytes, used:248 bytes (67.4%), free:120 bytes (32.6%),
  • Heap size:120 bytes, Heap max single alloc:95 bytes
  • ROM available:8192 words, used:1239 words (15.2%), free:6953 words (84.8%)

The program seems to be safely under the 2K free compiler limit.


Other Things to Try/Additions/Changes/Modification[edit]

  • The 877A is way overkill for this project unless you make it do a bit more. Note that only 2 input pins plus the serial lines are really used.
  • There is nothing magic about the dual op amp I had around, lots of others should work, there are also IC schmidt triggers. Some PIC input ports have schmidt triggers on their inputs. Op amps are good for many other things so nice to have around. You can tweak the parameters of a op amp schmidt trigger in a way you cannot with other circuits. Basic_Circuits_and_Circuit_Building_Blocks#Schmitt_Trigger
  • Optimize the code especially in countEncoder()
  • Read multiple encoders.
  • Optical encoders are easier to read, signals do not depend so much on rotational speed, try using them.
  • Use as a control element in a larger project, aming a laser.

Possibly useful links[edit]

This program uses my: Serial Communications Library -- BoostC and 16F877A

More information on serial communications with microcontrollers: Microcontroller Serial Communications Articles

A project using a stepper motor as a rotary encoder: Rotary Encoder http://www.webx.dk/oz2cpu/20m/encoder.htm

Stepper Motor As Rotary Encoder

HDDJ: Turning an old hard disk drive into a rotary input device

Using a disk drive motor as encoder: Inexpensive rotary encoder http://users.tkk.fi/~jwagner/electr/rotary-enc/

Stepper Motor As Rotary Encoder seems to be same as Stepper Motor As Rotary Encoder this seems to give a nice trick to greatly improve the sensitivity of the motor as encoder. Might want to try this.

Info on steppers: Encoder Implementation http://www.seattlerobotics.org/encoder/jun97/encoding.html

Info on steppers: Stepper motors http://www.allaboutcircuits.com/vol_2/chpt_13/5.html

Rotary Encoders http://www.ubasics.com/adam/electronics/doc/rotryenc.shtml

More info on steppers: Basic Stepping Motor Control Circuits http://www.cs.uiowa.edu/~jones/step/circuits.html

A free terminal program, I like this much better than hyperterminal: Welcome to our Free Download/New Products Page! http://www.rs485.com/psoftware.html

BoostC – I think the free version is enough to compile the program: SourceBoost Technologies http://www.sourceboost.com/

Download[edit]

At: Version 1 zip file: StepperTest_v1.zip To check for more recent versions email me: russ_hensel

Comment, Questions, Contributions?[edit]

Email me russ_hensel, or use the talk page for this topic. All feedback is welcome.