{"id":34,"date":"2005-11-02T13:40:41","date_gmt":"2005-11-02T18:40:41","guid":{"rendered":"http:\/\/www.tigoe.com\/pcomp\/code2\/category\/picbasic-pro\/34"},"modified":"2007-08-06T23:43:15","modified_gmt":"2007-08-07T04:43:15","slug":"stepper-motor-controller-from-analog-input","status":"publish","type":"post","link":"https:\/\/www.tigoe.com\/pcomp\/code\/picbasic-pro\/34\/","title":{"rendered":"Stepper motor controller from analog input"},"content":{"rendered":"<p>This program controls a stepper motor from an analog input. In testing it, I used a potentiometer, which gives a persistent value. An analog input that changes when it&#8217;s not contacted, like a SpectraSymbol linear or circular pot, wouldn&#8217;t work with this example.\n<\/p>\n<p>Thanks to the Fall &#8217;05 Wednesday morning class for the early experimentation on this code.<\/p>\n<p>Written in PicBasic Pro, tested on a PIC18F252<\/p>\n<p><!--more--><\/p>\n<p>To understand this example, consider four possible conditions:<\/p>\n<p><img decoding=\"async\" src=\"\/pcomp\/img\/stepper-cases.jpg\" alt=\"possible movements of a stepper from one position to another\"><\/p>\n<p>Either your new position is greater than or equal to than half a circle away from your old position, or it&#8217;s less than half a circle.  In either case, you want to move the shortest possible distance, so you have to take different routes depending on which is true.\n<\/p>\n<p>If the difference is greater than half a circle, and your new position is greater than the old one, then you move clockwise to get there fastest. If the new position is less than the old one, then you move counterclockwise to get there.\n<\/p>\n<p>If the difference is less than half a circle, and your new position is greater than the old one, then you move counterclockwise to get there fastest. If the new position is less than the old one, then you move clockwise to get there.\n<\/p>\n<p>If the distance is exactly half a circle, you can go either direction to get there, both are equidistant.<\/p>\n<pre>\n'    Analog Stepper\n'   \n'    Moves a stepper motor in response to a potentiometer\n'    attached to Analog input channel 0.  \n'\n'    This example doesn't correct for small fluctuations in the\n'    analog input, and it doesn't error correct the stepper.\n'  \n'   By Tom Igoe, 31 oct 2005\n'    updated 25 Oct. 2005   \n\n\n ' Define ADCIN parameters\nDEFINE  ADC_BITS        10     ' Set number of bits in result\nDEFINE  ADC_CLOCK       3         ' Set clock source (3=rc)\nDEFINE  ADC_SAMPLEUS    50        ' Set sampling time in uS\nTRISA = %11111111       ' Set PORTA to all input\nADCON1 = %10000010      ' Set PORTA analog and right justify result\n\n'   serial pins and constants:\ntx var portc.6\nrx var portc.7\ninv9600 con 16468\n'   LED pin:\nLEDPin var portb.0\n\n\n' total number of steps:\ntotalSteps con 100\n'   pause time between steps. Steppers have a minimum\n'   pause time, usually one or two milliseconds.\npauseTime con 10\n\n' set variables:\nadcVar var word         ' analog in reading, 0 - 1023 \nnewPosition var byte    ' stepper position from adcVar, 0 - 100\noldPosition var byte    ' previous stepper position, 0 - 100                                         \ndistance VAR BYTE       ' number of steps from old to new\nsteps VAR byte          ' counter for number of steps taken          \nstepArray VAR BYTE(4)   ' arry to hold step patterns\ni var byte              ' counter for blink subroutine\n\nclear                   ' set all variables to 0\n\nTRISC = %11110000       ' set lower pins of port to output\nPORTC = 255             ' set all pins of port high\n\n'   Stepping patterns:\nstepArray[0] = %00001010\nstepArray[1] = %00000110\nstepArray[2] = %00000101\nstepArray[3] = %00001001\n\ngosub blink\nPause 1000\n\nmain:\n    ' read analog in:   \n    adcin 0, adcVar\n    \n    ' convert to a range of 0 - 100\n    newPosition = (adcVar \/ 10) min totalSteps\n    \n    ' calculate number of steps from old to new:\n    distance = abs(newPosition - oldPosition)\n    \n    ' if we need to move:\n    if (distance &lt;&gt; 0) then\n        serout2 tx, inv9600, [dec oldposition, \" ---&gt; \" , dec newPosition, _\n            \"  Steps: \", DEC distance, 10, 13]\n        ' the choice of direction is different depending\n        ' on whether the difference is more than\n        ' half a circle or less:\n        ' If we're moving more than half a circle:\n        if (distance &gt;= totalSteps \/ 2 ) then\n            if newPosition &gt; oldPosition then\n                ' move counterclockwise\n                gosub counterClockwise\n            else\n                ' move clockwise\n                gosub clockwise\n            endif\n        ' else we're moving less than half a circle:\n        else\n            if newPosition &gt; oldPosition then\n                ' move clockwise\n                gosub clockwise\n            else\n                ' move counterclockwise\n                gosub counterCLockwise\n            endif\n        endif\n        ' update oldPosition with most recent value:\n        oldPosition = newPosition    \n    endif\n\nGoTo main \n\n\nclockwise:\n    steps = 0\n    while steps &lt; distance\n        serout2 tx, inv9600, [\"--&gt; \", DEC steps, 10, 13]\n        PORTC = stepArray[steps \/\/4]\n        steps = steps + 1\n        pause pauseTime\n    wend  \nreturn\n\ncounterClockwise:\n    steps = distance\n    while steps &gt; 0\n        serout2 tx, inv9600, [\"&lt;-- \", DEC steps, 10, 13]\n        PORTC = stepArray[steps \/\/4]\n        steps = steps - 1\n        pause pauseTime \n    wend  \nreturn\n\n\nblink:\n    serout2 tx, inv9600, [10,13,10,13, \"Start-----\", 10, 13]\n    for i = 0 to 2\n        high LEDpin\n        pause 200\n        low LEDPin\n        pause 200\n    next\nreturn\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This program controls a stepper motor from an analog input.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-34","post","type-post","status-publish","format-standard","hentry","category-picbasic-pro"],"_links":{"self":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":0,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tigoe.com\/pcomp\/code\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}