Weird servo behavior, can't find it in my code
flowstate
Posts: 3
I've got a modified version of the SumoWrestler code from the Applied Robotics pack. It's been modified to use 2 Ping sensors. They are working just fine, but for some reason, the right servo seems to be freaking out randomly (most typically in a CurveRight or RotateRight maneuver). Below is the code in its entirety. Any help would be appreciated:
' -----[ Title ]--------------------------------------------------------------' Applied Robotics with the SumoBot - SumoWrestler.bs2 ' SumoWrestler.bs2 modified so that each state is contained by a ' subroutine. ' {$STAMP BS2} ' Target = BASIC Stamp 2 ' {$PBASIC 2.5} ' Language = PBASIC 2.5 ' -----[ I/O Definitions ]--------------------------------------------------- ServoLeft PIN 13 ' Left servo connected to P13 ServoRight PIN 12 ' Right servo connected to P12 qtiPwrLeft PIN 10 ' Left QTI on/off pin P10 qtiSigLeft PIN 9 ' Left QTI signal pin P9 qtiPwrRight PIN 7 ' Right QTI on/off pin P7 qtiSigRight PIN 8 ' Right QTI signal pin P8 DummyPin PIN 6 ' I/O pin for pulse-decay P6 PingPin PIN 15 ' Left Ping Sensor SIG Pin PingPin2 PIN 14 ' Right Ping Sensor SIG Pin PingLedLeft PIN 1 ' Debug LED for Left Ping Status PingLedRight PIN 0 ' Debug LED for Right Ping Status QTILeftLed PIN 3 ' Debug LED for Left QTI Status QTIRightLed PIN 2 ' Debug LED for Right QTI Status ' -----[ Constants ]---------------------------------------------------------- InConstant CON 890 ' Constant for converting Ping echo time to distance inDistance VAR Word ' Distance for left Ping inDistance2 VAR Word ' Distance for right Ping time VAR Word ' Stores ping echo time ' SumoBot maneuvers Forward CON 0 ' Forward Backward CON 1 ' Backward RotateLeft CON 2 ' RotateLeft RotateRight CON 3 ' RotateRight PivotLeft CON 4 ' Pivot to the left PivotRight CON 5 ' Pivot to the right CurveLeft CON 6 ' Curve to the left CurveRight CON 7 ' Curve to the right ' Servo pulse width rotations FS_CCW CON 850 ' Full speed counterclockwise FS_CW CON 650 ' Full speed clockwise NO_ROT CON 750 ' No rotation LS_CCW CON 770 ' Low speed counterclockwise LS_CW CON 730 ' Low speed clockwise ' IR object detectors IrFreq CON 38500 ' IR LED frequency ' -----[ Variables ]---------------------------------------------------------- temp VAR Word ' Temporary variable multi VAR Word ' Multipurpose variable counter VAR Byte ' Loop counting variable. maneuver VAR Nib ' SumoBot travel maneuver sensors VAR Byte ' Sensor flags byte qtiLF VAR sensors.BIT5 ' Stores snapshot of QtiSigLeft qtiRF VAR sensors.BIT4 ' Stores snapshot of QtiSigRight irLS VAR sensors.BIT3 ' State of Left Side IR irLF VAR sensors.BIT2 ' State of Left Front IR irRF VAR sensors.BIT1 ' State of Right Front IR irRS VAR sensors.BIT0 ' State of Right Side IR ' -----[ EEPROM Data ]-------------------------------------------------------- RunStatus DATA 0 ' Run status EEPROM byte QtiThresh DATA Word 0 ' Word for QTI threshold time ' -----[ Initialization ]----------------------------------------------------- GOSUB Reset ' 5 Second delay GOSUB Calibrate_Qtis ' Determine b/w threshold GOSUB Look_About ' Was Goto Look_About ' -----[ Main Routine ]------------------------------------------------------- DO IF qtiLF = 1 THEN ' Left qti sees line? GOSUB Avoid_Tawara_Left ' State = avoid left tawara ELSEIF qtiRF = 1 THEN ' Right qti sees line? GOSUB Avoid_Tawara_Right ' State = avoid right tawara ELSEIF irLF = 1 AND irRF = 1 THEN ' Both? Lunge forward GOSUB Go_Forward ' State = Go forward ELSEIF irLF = 1 THEN ' Just left? GOSUB Track_Front_Left_Object ' State = Track front left obj. ELSEIF irRF = 1 THEN ' Just right? GOSUB Track_Front_Right_Object ' State = Track front right obj. ELSE ' Nothing sensed? GOSUB Search_Pattern ' State = Search pattern ENDIF LOOP ' -----[ Subroutine - Reset ]------------------------------------------------- Reset: READ RunStatus, temp ' Byte @RunStatus -> temp temp = temp + 1 ' Increment temp WRITE RunStatus, temp ' Store new value for next time IF (temp.BIT0 = 1) THEN ' Examine temp.BIT0 DEBUG CLS, "Press/release Reset", CR, ' 1 -> end, 0 -> keep going "button..." END ELSE DEBUG CR, "Program running..." ENDIF RETURN ' -----[ Subroutine - Calibrate_Qtis ]---------------------------------------- Calibrate_Qtis: HIGH qtiPwrLeft ' Turn left QTI on HIGH qtiSigLeft ' Discharge capacitor PAUSE 1 RCTIME qtiSigLeft, 1, temp ' Measure charge time LOW qtiPwrLeft ' Turn left QTI off multi = temp ' Free temp for another RCTIME HIGH qtiPwrRight ' Turn right QTI on HIGH qtiSigRight ' Discharge capacitor PAUSE 1 RCTIME qtiSigRight, 1, temp ' Measure charge time multi = (multi + temp) / 2 ' Calculate average multi = multi / 4 ' Take 1/4 average IF multi > 220 THEN ' Account for code overhead multi = multi - 220 ELSE multi = 0 ENDIF WRITE QtiThresh, Word multi ' Threshold to EEPROM RETURN ' -----[ Subroutine - Servos_And_Sensors ]------------------------------------ Servos_And_Sensors: GOSUB Pulse_Servos ' Call Pulse_Servos subroutine ' Call sensor subroutine(s). sensors = 0 ' Clear previous sensor values GOSUB Read_Object_Detectors ' Call Read_Object_Detectors GOSUB Read_Line_Sensors ' Look for lines RETURN ' -----[ Subroutine - Pulse_Servos ]------------------------------------------ Pulse_Servos: ' Pulse to left servo LOOKUP maneuver, [ FS_CCW, FS_CW, FS_CW, FS_CCW, NO_ROT, FS_CCW, LS_CCW, FS_CCW ], temp PULSOUT ServoLeft, temp ' Pulse to right servo LOOKUP maneuver, [ FS_CW, FS_CCW, FS_CW, FS_CCW, FS_CW, NO_ROT, FS_CW, LS_CW ], temp PULSOUT ServoRight, temp RETURN ' -----[ Subroutine - Read_Object_Detectors ]--------------------------------- Read_Object_Detectors: PULSOUT PingPin, 5 ' Send short pulse to Ping PULSIN PingPin, 1, time ' Wait for echo inDistance = inConstant ** time GOSUB Pulse_Servos ' Called to avoid pausing/stuttering on servos IF inDistance < 12 THEN irLF = 1 HIGH PingLedLeft ELSE irLF = 0 LOW PingLedLeft ENDIF PULSOUT PingPin2, 5 ' Send short pulse to Ping PULSIN PingPin2, 1, time ' Wait for echo inDistance2 = inConstant ** time GOSUB Pulse_Servos IF inDistance2 < 12 THEN irRF = 1 HIGH PingLedRight ELSE irRF = 0 LOW PingLedRight ENDIF RETURN ' -----[ Subroutine - Read_Line_Sensors ]------------------------------------- Read_Line_Sensors: HIGH qtiPwrLeft ' Turn on QTIs HIGH qtiPwrRight HIGH qtiSigLeft ' Push signal voltages to 5 V HIGH qtiSigRight PAUSE 1 ' Wait 1 ms for capacitors READ QtiThresh, Word temp ' Get threshold time INPUT qtiSigLeft ' Start the decays INPUT qtiSigRight PULSOUT DummyPin, temp ' Wait threshold time qtiLF = ~qtiSigLeft ' Snapshot of QTI signal states qtiRF = ~qtiSigRight IF qtiLF = 1 THEN HIGH QTILeftLed ELSE LOW QTILeftLed ENDIF IF qtiRF = 1 THEN HIGH QTIRightLed ELSE LOW QTIRightLed ENDIF LOW qtiPwrLeft ' Turn off QTIS LOW qtiPwrRight RETURN ' -----[ Subroutine - Avoid_Tawara_Left ]------------------------------------- Avoid_Tawara_Left: FOR counter = 1 TO 7 ' Back up maneuver = Backward GOSUB Servos_And_Sensors NEXT FOR counter = 1 TO 7 ' Turn right maneuver = RotateRight GOSUB Servos_And_Sensors NEXT RETURN ' -----[ Subroutine - Avoid_Tawara_Right ]------------------------------------ Avoid_Tawara_Right: FOR counter = 1 TO 7 ' Back up maneuver = Backward GOSUB Servos_And_Sensors NEXT FOR counter = 1 TO 7 ' Turn left maneuver = RotateLeft GOSUB Servos_And_Sensors NEXT RETURN ' -----[ Subroutine - Go_Forward ]-------------------------------------------- Go_Forward: maneuver = Forward ' 1 forward pulse GOSUB Servos_And_Sensors RETURN ' -----[ Subroutine - Track_Front_Left_Object ]------------------------------- Track_Front_Left_Object: counter = 0 DO UNTIL (irLF = 1 AND irRF = 1) OR counter > 7 maneuver = CurveLeft ' Curve left 15 GOSUB Servos_And_Sensors counter = counter + 1 LOOP DO UNTIL (irLF = 1 AND irRF = 1) OR counter > 15 maneuver = RotateLeft ' Rotate left 30 GOSUB Servos_And_Sensors counter = counter + 1 LOOP RETURN ' -----[ Subroutine - Track_Front_Right_Object ]------------------------------ Track_Front_Right_Object: counter = 0 DO UNTIL (irLF = 1 AND irRF = 1) OR counter > 7 maneuver = CurveRight ' Curve right 15 GOSUB Servos_And_Sensors counter = counter + 1 LOOP DO UNTIL (irLF = 1 AND irRF = 1) OR counter > 15 maneuver = RotateRight ' Rotate right 30 GOSUB Servos_And_Sensors counter = counter + 1 LOOP RETURN ' -----[ Subroutine - Track_Side_Left_Object ]-------------------------------- Track_Side_Left_Object: DO UNTIL irRF = 1 OR irLF = 1 ' Rotate left maneuver = RotateLeft GOSUB Servos_And_Sensors LOOP RETURN ' -----[ Subroutine - Track_Side_Right_Object ]------------------------------- Track_Side_Right_Object: DO UNTIL irRF = 1 OR irLF = 1 ' Rotate right maneuver = RotateRight GOSUB Servos_And_Sensors LOOP RETURN ' -----[ Subroutine - Search_Pattern ]---------------------------------------- Search_Pattern: FOR counter = 1 TO 20 ' and watch all sensors maneuver = Forward ' Forward GOSUB Servos_And_Sensors IF sensors <> 0 THEN GOTO Next_State NEXT Look_About: FOR counter = 1 TO 6 ' Look right maneuver = RotateRight GOSUB Servos_And_Sensors IF sensors <> 0 THEN GOTO Next_State NEXT FOR counter = 1 TO 12 ' Look left maneuver = RotateLeft GOSUB Servos_And_Sensors IF sensors <> 0 THEN GOTO Next_State NEXT FOR counter = 1 TO 6 ' Re-align to forward maneuver = RotateRight GOSUB Servos_And_Sensors IF sensors <> 0 THEN GOTO Next_State NEXT Next_State: ' Exit point of search pattern RETURN
Comments
Try swapping sensors to see if the problem is with one of the sensors.