Shop OBEX P1 Docs P2 Docs Learn Events
Servo + 7-Seg LED problem — Parallax Forums

Servo + 7-Seg LED problem

kidsasukekidsasuke Posts: 8
edited 2011-02-23 15:00 in BASIC Stamp
Hey everyone,

I'm currently attempting to use a servo and phototransistor to scan for a light source, lock on to it, and then present the servo's position as a hexidecimal value (0 for duration of 250, F for duration of 1250, or 0 and 180 degrees respectively. Everything else is increments). My issue is trying to figure out how to integrate the LED display with the hex value with the servo motion.

I currently have it so that an intermittent beep happens during scanning, while a bicolour LED is red. The servo stops properly when the light is found and I can make it give a duration output in the debug. However, when I was clumsily trying to figure out how to integrate the hex display (as it was asked of me by my instructor), the servo would work separately from the sound and LED, or it would move without anything else happening.

Thanks in advance for any advice!

Here's what I have so far:

Note: There's a reset switch at pin1, in case there's any confusion about that portion. I've just left what I had done so far with the LED at the top so I won't have to type it all out again if needed. The doubling up of the OUTH command is to make sure the display is refreshed each time a value is going to be presented.

' ServoLightDetectorProjectThingThatInfuriatedMeFor2HoursUntilFinallyIFiguredItOut.BS2
' This program is designed to cause a servo to sweep back and forth while making an annoying sound
' with a phototransistor attached to the horns. A cheap laser pointer is used as an object to
' detect, using RCTIME measurements to detect when the laser's light strikes the phototransistor's
' base. When the light is discovered, the servo will STOP and its position displayed in debug.

' {$STAMP BS2}
' {$PBASIC 2.5}

duration VAR Word
time VAR Word

PULSOUT 0, duration
OUTH = %00000000
DIRH = %11111111

' Lead-In to the first subroutine
DEBUG "Searching for light....", CR
PAUSE 1000
GOSUB Searching 'After displaying the debug, go to the Searching subroutine



' Searching subroutine parameters
Searching:
DO
FOR duration = 250 TO 1250 STEP 4 '250 = 0 degrees, 1250 = 180 degrees, STEP increased for speed

PULSOUT 0, duration 'Sweeping occurs, servo resets to 250 when it goes past 1250
PAUSE 1

IF duration < 316 THEN
OUTH = %11100111
ELSEIF duration > 316 THEN
OUTH = %00000000
OUTH = %10000100
ELSEIF duration > 382 THEN
OUTH = %00000000
OUTH = %11010011
ELSEIF duration > 448 THEN
OUTH = %00000000
OUTH = %11010110
ELSEIF duration > 514 THEN
OUTH = %00000000
OUTH = %10110100
ELSEIF duration > 580 THEN
OUTH = %00000000
OUTH = %01110110
ELSEIF duration > 646 THEN
OUTH = %00000000
OUTH = %01110111
ELSEIF duration > 712 THEN
OUTH = %00000000
OUTH = %11000100
ELSEIF duration > 778 THEN
OUTH = %00000000
OUTH = %11110111
ELSEIF duration > 844 THEN
OUTH = %00000000
OUTH = %11110110
ENDIF

IF IN1 = 1 THEN 'Reset switch set to pin0, locks it at 0 degrees until you let go
DO
PULSOUT 0, 250
PAUSE 20
LOOP UNTIL IN1 = 0
duration = 250 'Resets duration to 250, as it would pick up where it left off
ENDIF 'if this wasn't done.
HIGH 6 'LED is Red
LOW 7
FREQOUT 5, 100, 2 'Sound occurring during search
HIGH 2 'RC measurements are made with the phototransistor
PAUSE 1
RCTIME 2, 1, time 'Pin 2 tested
IF time < 500 THEN 'Go to subroutine Recording when light hits (Tau < 500ms)
GOSUB Recording
ENDIF

NEXT
LOOP


' Recording subroutine parameters
Recording:
PULSOUT 0, duration 'Locks servo in position it was in at the end of Searching
PAUSE 20
WRITE 1, Word duration 'Writes duration value to 1st EEPROM address
DEBUG "Light discovered!", CR 'Declares that the light was found
HIGH 7 'Turns bicolour LED green
LOW 6
FREQOUT 5, 5000, 1500, 1000 'Plays obnoxious frequency just to let you know
GOSUB Reading 'Tells it to go to subroutine Reading


' Reading subroutine parameters
Reading:
PAUSE 1000 'Pause to keep debug from just ramming through the lines
DEBUG "Reticulating splines....", CR 'Sim City joke
PAUSE 5000 'Jokingly pauses as though it has to calculate something
DEBUG CLS, "Just kidding! The servo position is the following:", CR, CR
READ 1, Word duration 'Reads from address 1 in the EEPROM for the duration value
DEBUG " ", DEC duration, CR 'Displays the duration as a decimal number

Comments

  • $WMc%$WMc% Posts: 1,884
    edited 2011-02-10 18:17
    1st off your using GOSUB with-out RETURN. Take another look in the syntax manual on the use of GOSUB and RETURN
    also DO and LOOP
    '
    2nd your using long PAUSE's This makes the STAMP wait and do nothing for the length of the PAUSE. A value of 1000 = 1 sec and 5000 = 5 sec.
    '
    There are other issues,But I would start with the above.
  • kidsasukekidsasuke Posts: 8
    edited 2011-02-17 13:47
    Thanks for the advice. Everything is now fully functional, as I've scrapped that code in lieu of a completely new one built from the ground up. I realized that the above code was full of holes. The IF/THEN arguements were replaced by a LOOKUP/LOOKDOWN index that works perfectly and is much cleaner looking than that garbled mess of ambiguities I had originally conceived. I'm even writing alternate codes just to play around with the organization of the logic and what statements lend to each other efficiently and precisely.

    My newest issues are:

    1) I haven't the foggiest how to remove data from a specific address in the EEPROM. I have to make a killswitch that not only resets the servo to 0 degrees (already accomplished), but also wipes any last-known position for the servo from the EEPROM (which is written to when the light is discovered). I have the address space set up and can write to and read from, displaying the results in a debug window. It's just a matter of finding the command and subsequent syntax for deleting/erasing data from that specific address.

    2) Forcing the servo to, upon being powered down and back up, resume from the recorded (in EEPROM address 1) position of the light that was discovered before powering down. If no light is present, then it must resume the normal subroutine of searching. I just can't figure out how to make the argument about whether or not there is data in that specific address (the rest of the arguments, such as what to do in each subsequent scenario, are well within my grasp).
  • $WMc%$WMc% Posts: 1,884
    edited 2011-02-17 15:00
    Have you looked at DATA,READ,WRITE,STORE.
    '
    Take a look in the Syntax manual under EEPROM.
    heres the link in case you don't have it
    http://www.parallax.com/Store/Books/BASICStamp/tabid/168/CategoryID/42/List/0/SortField/0/Level/a/ProductID/143/Default.aspx
    '
    You'll need a circuit to test for a power-down on the Stamp.Also a back up battery or a large CAP to keep the Stamp running long enough to send the data to the eeprom before the Stamp shuts down.
    '
    Don't think you can use eeprom like ram.Eeprom can wear-out if you try to use it like ram.
    Take a look at eeprom and overwrites.(google)
    '
    If you need a high cycle power on/off with this project, I would use some other nonvolatile storage.
    '
    If your just powering down the servos and not the Stamp then you can use something like
    '
    oldValue VAR Word
    newValue VAR Word
    '
    Just write the pos. value to oldValue before you kill the power to the servos.
    '
    Unfortunately servos can be twitchy when powered up no matter what the signal is.
    '
    I'm not really sure what your tring to do here.If need some more help post your code and we can work on it in more detail.
    '
    This is what the forums are for.
  • kidsasukekidsasuke Posts: 8
    edited 2011-02-21 10:09
    Here's the code I'm working with thus far. I've been adding and removing code like crazy to try out many different possibilities. There's even a junkpile at the bottom where I was working on things that just didn't pan out. They were left for reference so I won't make those mistakes again.

    Thanks a lot for all of your help.


    ' ServoLightDetectorProjectThingThatInfuriatedMeFor2HoursUntilFinallyIFiguredItOut.BS2
    ' This program is designed to cause a servo to sweep back and forth while making an annoying sound
    ' with a phototransistor attached to the horns. A cheap laser pointer is used as an object to
    ' detect, using RCTIME measurements to detect when the laser's light strikes the phototransistor's
    ' base. When the light is discovered, the servo will STOP and its position displayed in debug.

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    duration VAR Word
    time VAR Word
    index VAR Nib

    'READ 1, Word duration
    'IF duration > 0 THEN
    ' GOSUB LightCheck
    'ELSE
    ' GOSUB Load
    'ENDIF


    'LightCheck:
    'HIGH 2
    'RCTIME 2, 1, time
    'IF time < 500 THEN
    ' GOSUB Stuck
    'ELSE
    'GOSUB Load
    'ENDIF

    OUTH = %00000000
    DIRH = %11111111


    Load:
    DEBUG "Searching for light....", CR
    GOSUB Searching 'After displaying the debug, go to the Searching subroutine



    ' Searching subroutine parameters
    Searching:
    DO
    FOR duration = 250 TO 1250 STEP 4 '250 = 0 degrees, 1250 = 180 degrees, STEP increased for speed

    LOOKDOWN duration, <= [312, 374, 436, 498, 560, 622, 684, 750, 816, 878, 940, 1002, 1064, 1130, 1192, 1250], index
    LOOKUP index, [ %11100111, %10000100, %11010011, %11010110, %10110100, %01110110, %01110111,
    %11000100, %11110111, %11110110, %11110101, %00110111, %01100011,
    %10010111, %01110011, %01110001 ], OUTH

    PULSOUT 0, duration 'Sweeping occurs, servo resets to 250 when it goes past 1250
    PAUSE 1
    IF IN1 = 1 THEN 'Reset switch set to pin0, locks it at 0 degrees until you let go
    DO
    WRITE 1, 0
    PULSOUT 0, 250
    PAUSE 20
    LOOP UNTIL IN1 = 0
    duration = 250 'Resets duration to 250, as it would pick up where it left off
    ENDIF 'if this wasn't done.
    HIGH 6 'LED is Red
    LOW 7
    FREQOUT 5, 100, 2 'Sound occurring during search
    HIGH 2 'RC measurements are made with the phototransistor
    RCTIME 2, 1, time 'Pin 2 tested
    IF time < 500 THEN 'Go to subroutine Recording when light hits (Tau < 500ms)
    GOSUB Recording
    ENDIF
    NEXT
    LOOP


    'Recording subroutine parameters
    Recording:
    PULSOUT 0, duration 'Locks servo in position it was in at the end of Searching
    PAUSE 20
    DEBUG "Light discovered!", CR 'Declares that the light was found
    DEBUG "Writing servo position to EEPROM...", CR
    HIGH 7 'Turns bicolour LED green
    LOW 6
    FREQOUT 5, 5000, 1500, 1000 'Plays obnoxious frequency just to let you know
    PAUSE 500
    WRITE 1, Word duration 'Writes duration value to 1st EEPROM address
    GOSUB Reading 'Tells it to go to subroutine Reading


    'Reading subroutine parameters
    Reading:
    PAUSE 1000 'Pause to keep debug from just ramming through the lines
    DEBUG "Servo position is:"
    READ 1, Word duration 'Reads from address 1 in the EEPROM for the duration value
    DEBUG " ", DEC duration, CR 'Displays the duration as a decimal number

    Stuck:
    DO
    PULSOUT 0, duration
    PAUSE 20
    HIGH 2
    RCTIME 2, 1, time
    LOOP UNTIL time > 500





    'Junkpiles of attempted code
    'READ 1, Word duration 'Attempting to make it load the last known position.
    'PULSOUT 0, duration
    'PAUSE 20
    'PAUSE 3000
    'HIGH 2
    'PAUSE 1
    'RCTIME 2, 1, time
    'IF time > 500 THEN
    'GOSUB Searching
    'ELSE
    'DO
    'HIGH 7 'Turns bicolour LED green
    'LOW 6
    'FREQOUT 5, 5000, 1500, 1000 'Plays obnoxious frequency just to let you know
    'HIGH 2
    'PAUSE 1
    'RCTIME 2, 1, time
    'LOOP UNTIL time > 500
    'ENDIF

    'Remain:
    'PULSOUT 0, recorded
    'PAUSE 20
    'DEBUG "Light is still in same position...looping...", CR
    'IF time < 500 THEN
    'GOSUB Remain
    'ELSE
    'ENDIF
  • $WMc%$WMc% Posts: 1,884
    edited 2011-02-22 17:27
    I made a couple little modes to your code that should keep you from getting stuck.
    '
    You still need some more refinement but this should help.
    '
    Heres the link to the BS2 Syntax manual. Take a look at GOSUB and RETURN
    '
    http://www.parallax.com/Store/Books/BASICStamp/tabid/168/CategoryID/42/List/0/SortField/0/Level/a/ProductID/143/Default.aspx
    '
    Heres a link to StampWorks. It has some code examples of its use.
    '
    http://www.parallax.com/Portals/0/Downloads/docs/books/sw/Web-SW-v2.1.pdf
  • kidsasukekidsasuke Posts: 8
    edited 2011-02-23 13:48
    Umm...thanks for the assist, but it just loops endlessly through the subroutines. It's not looking for a light, locking on to it, recording the position, and then loading that position the next time the device is powered up. It's supposed to lock on to the light and stay there until it's powered down. Then, once it's powered back up, it's supposed to move the servo to that recorded position and wait for the light. If the light isn't there anymore, it's supposed to resume the search process.

    Thanks anyway for taking the time out of your day.
  • $WMc%$WMc% Posts: 1,884
    edited 2011-02-23 15:00
    I was just trying to show you why you were getting stuck.
    '
    Stick with it. You'll figure it out.
Sign In or Register to comment.