'{$STAMP BS2} ' ------------------------------------------------------------------------------ serialIN CON 2 'BS2 serial receive, mac TXD (transmit) serialOUT CON 3 'BS2 serial transmit, mac RXD (recieve) serData var word ' ------------------------------------------------------------------------------ 'this stepper motor has a 7.5 degree step angle, which means 48 steps per full (360 'degree) revolution. By half-stepping the motor, we can get 96 steps per rotation. 'We are going to allow the motor to complete 3 full revolutions (1080 degrees, or 288 'steps). The motor's center position is therefore the 144th (96 + 48) step. curStep var word 'current position (0 to 287) goalStep var word 'desired position (0 to 287) ' ------------------------------------------------------------------------------ switchPin var in8 'input pin for roller switch prevSwchState var bit 'state of switch just before now switchStep1 var byte 'first stepper position where switch is closed switchStep2 var byte 'last stepper position where switch is closed ' ------------------------------------------------------------------------------ rot var bit 'flag for direction of rotation cw con 0 'clockwise rotation ccw con 1 'counterclockwise rotation speed VAR byte 'delay between steps (set to 0 for maximum speed) ' ------------------------------------------------------------------------------ Coils VAR OutB 'output to stepper coils - pins 4, 5, 6, 7 sAddr VAR Byte 'EE address of step data Step1 DATA %1000 'EEPROM data for half-stepping Step2 DATA %1100 Step3 DATA %0100 Step4 DATA %0110 Step5 DATA %0010 Step6 DATA %0011 Step7 DATA %0001 Step8 DATA %1001 ' ------------------------------------------------------------------------------ ' Initialization ' ------------------------------------------------------------------------------ DirB = %1111 'make stepper pins outputs speed = 0 'set speed prevSwchState = in8 'initialize switch curStep = 95 'initialize stepper motor to first step of middle revolution goalStep = 191 'set goal step for last step of middle revolution to initialize & find center position ' ------------------------------------------------------------------------------ ' Program Code ' ------------------------------------------------------------------------------ mainLoop: 'check switchPin ONLY during middle revolution: if switchPin <> prevSwchState and curStep >= 95 and curstep <= 191 then switchChanged afterSwitchCheck: 'check for serial input from MaxMSP: serIn 2,16468,50,afterSerialCheck,[dec serData] 'go to afterSerialCheck if no input by 50 ms 'set goalStep to latest serial input and limit it to usable range: goalStep = serData min 0 max 287 debug cr, "serData: ", serData, " goalstep: ",dec goalstep, cr afterSerialCheck: 'if goalstep is different than curStep, then take a step in appropriate direction: if goalStep > curStep then Step_CW if goalStep < curStep then Step_CCW goto mainLoop Step_CW: rot = cw GOSUB Step_Fwd GOTO mainLoop Step_CCW: rot = ccw GOSUB Step_Rev GOTO mainLoop switchChanged: prevSwchState = switchPin 'record current switchPin state if switchPin = 1 then switchClosed '[ELSE IF switchPin = 0 THEN]: <--just to remind you of how PBASIC is structured if rot = cw then cwSetStep '[ELSE IF rot = ccw THEN]: <-- reminder switchStep2 = curStep + 1 'for CCW rotation, add 1 to get the last closed-switch step 'debug "last closed step = ",dec switchStep2,cr 'a. find the total number of closed-switch steps 'b. divide by 2 to find the middle closed-switch step 'c. subtract from 143 (or 144) to find the last closed-switch step 'd. subtract 1 more since we are now on the first open-switch step curStep = 143 - ((switchStep1 - switchStep2)/2) - 1 goto afterSwitchCheck switchClosed: switchStep1 = curStep 'record first closed-switch step 'debug "first closed switch step = ", dec switchStep1, cr goto afterSwitchCheck cwSetStep: switchStep2 = curStep - 1 'for CW rotation, subtract 1 to get the last closed-switch step 'debug "last closed step = : ",dec switchStep2, cr 'a. find the total number of closed-switch steps 'b. divide by 2 to find the middle closed-switch step 'c. subtract from 143 (or 144) to find the last closed-switch step 'd. add 1 more since we are now on the first open-switch step curStep = 144 + ((switchStep2 - switchStep1)/2) + 1 goto afterSwitchCheck Step_Fwd: sAddr = sAddr + 1 // 8 'point to next step READ (Step1 + sAddr), Coils 'output step data PAUSE speed 'pause between steps curStep = curStep + 1 // 288 'increment current step - return to 0 when we reach 288 'debug " cw: ",dec curStep," " RETURN Step_Rev: sAddr = sAddr + 7 // 8 'point to previous step READ (Step1 + sAddr), Coils 'output step data PAUSE speed 'pause between steps curStep = curStep + 287 // 288 'decrement current step 'debug " ccw: ",dec curStep," " RETURN