Shop OBEX P1 Docs P2 Docs Learn Events
Converting sensor value to servo movement — Parallax Forums

Converting sensor value to servo movement

BotdocterBotdocter Posts: 271
edited 2010-12-05 05:15 in Propeller 1
I am building a robot containing a Wyse Thin XP system. it uses roborealm and i have setup the serial connection to the propeller. it is working correct. i get back the values that where send by roborealm.

Now i need to convert one of that values to servo movement. or in other words, the value is the camera resolution or a point withing that width.(320px / 2 =160 to -160). That value that is changing constantly, and has to drive the servo to steer the robot.

i attached my main file. it's not working though. all i get is -160 outputted back to roborealm and the servo starts with a quick left then right and then no movement. The servo can't be turned manually. It is still holding steady at ...-160? would be pulsewidth "1300"?

Any help is apreciated!!

RRSerial.spin

Comments

  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-03 19:11
    Does it work any differently if you use;

    SERVO.Set(ServoCh1,Heading,50)
    instead of
    SERVO.SetRamp(ServoCh1,Heading,50) ?

    Rich H
  • BotdocterBotdocter Posts: 271
    edited 2010-12-04 05:49
    It's the same. Although the the start (left/right twitch) is gone.
    If i change the -160 at the bottom of the file, to for example: 162, that is what i get back. So it is not using the value but the -160???
  • John AbshierJohn Abshier Posts: 1,116
    edited 2010-12-04 08:01
    You are starting each of the routines SerialCog Transmitter and WheelAngle in their own cogs and also calling them from main. Try removing the three cognew statements.

    John Abshier
  • BotdocterBotdocter Posts: 271
    edited 2010-12-04 08:16
    i did. it screwed up the output even more than now..

    i will try again anyway..

    thanx
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-04 09:04
    If you are having a problem with rxVal_1, say it is actually zero, then it will be changed to -160 by WheelAngle before it goes to Transmitter.

    Rich H
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-04 09:19
    Also, "scale and offset" would be appropriate for your WheelAngle routine.

    You have the values ranging from -160 to 160 that need to correspond to servo pulses of 1,300 to 1,700 with 1,500 being the center.

    If you could get by with a pulse range of 1340 to 1660 then it would be super easy;

    heading := 1500 + rxVal_1

    But to scale the 160 up to 200 you need to multiply it by 1.25. Or multiply it by 125 then divide by 100.

    heading := 1500 + ((rxVal_1 *125) / 100)

    You should be able to replace your Main loop with this;
    repeat
        SerCog
        Transmitter
        heading := 1500 + ((rxVal_1 *125) / 100)    
    
        SERVO.Set(ServoCh1,Heading,50)
    

    It is of course untested...

    Rich H
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-12-04 12:10
    Hi Botdocter,

    I want to make some comments about your code.

    As your methods SerCog, Transmitter and WheelAngle do NOT contain any loop.
    The commands cognew start a new cog executes the codeline ONE time and then stops the cog again.

    You should get the same results if you just delete the cognew-statements

    As you don't have any code below the "elses" INDENTED in the method WheelAngle
    you can simply delete the elses

    If you meant that the second-ifcondition should only be executed if the first is not true
    You would have to indent them.

    The following codelines compile but are different from the ones above and below
        IF rxVal_1 := 100
          heading := 1625
        else
        IF rxVal_1 := 120
          heading := 1650
        else
        IF rxVal_1 := 140
          heading := 1675
        else
        IF rxVal_1 := 160
          heading := 1700
     
    

    I think you wanted to code
        IF rxVal_1 > 100
          heading := 1625
        else
        IF rxVal_1 > 120
          heading := 1650
        else
        IF rxVal_1 > 140
          heading := 1675
    

    IF rxVal_1 := 140

    sets rxVal_1 to value 140
    and the if-condition will be true as every value <> 0 is true

    for the codelines
         IF rxVal_1 > -20
          heading := 1475
    

    I guess you mean value-range -20 to -40
    rxVal_1 > -20 is TRUE for -19, -18, -17, -16 etc. etc.
    I guess you wanted

    rxVal_1 < -20
    which is true for -21, -22, -23, etc. etc.

    instead of adding a lot of if-conditions you can use
    a case-statement
          0..19 : heading := 1500
          
          20..40 :heading := 1525
          
          41..60 : heading := 1550
    
          61..80 : heading := 1575
    
          81..100 : heading := 1600
    
          101..120 : heading := 1625
    
          121..140 : heading := 1650
    
          141..160 : heading := 1675
    
          161..180 : heading := 1700
    
          -20..-1 : heading := 1500  
    
          -40..-21 : heading := 1475
    
          -60..-41 : heading := 1450
    
          -80..-61 : heading := 1425
    
          -100..-81 : heading := 1400
    
          -120..-101 : heading := 1375
    
          -140..-121 : heading := 1350
    
          -160..-141 : heading := 1325
    
          -200..-160 : heading := 1300
     
    

    from the bugs you made I guess you are pretty new to programming.

    My recommendation is to add only 1 to 5 lines of code and then TESTING the code to check if it really does what you expected.
    For the testing you should hold anything constant but teh one thing you want to test

    example
    to test what does the codelines
        IF rxVal_1 > -20
          heading := 1475
    


    you should extract the codelines to a small test-program that only contains
        rxVal_1 := - 22
    
        IF rxVal_1 > -20
          serial.str(string("rxVal_1 > -20 is true"))
        else  
          serial.str(string("rxVal_1 > -20 is false"))
    

    with this testing code it will be easy to check if your code works as expected and you will be pointed straight forward to a bug
    if there is a bug.

    You may think uhh so many test-programms?!? This takes too long.
    OK it is up to you to do it the fast (but in the long run slowest) way to quickly put together all the code and then start testing with guessing around
    is the bug here ore there?

    Very old programmers -wisdom: a program does ALWAYS what you have programmed. The only thing is sometime you don't know what you really programmed
    because you thought the program should do this but in fact the program does something different. But still EXACTLY what you have programmed.

    best regards

    Stefan
  • TtailspinTtailspin Posts: 1,326
    edited 2010-12-04 14:10
    Cuz You told it to be -160
    I keep falling into this trap Myself...
    PUB WheelAngle
        rxVal_1 := rxVal_1 - 160         'Cuz You Told it to be -160
                                                    ':= "SETS"  the variable 
     
        IF rxVal_1 < 20                    ' I think You want to use == for Your IF's
          heading := 1500                  'This Line will work to set heading to 1500
        else                                   'This else is not needed 
        IF rxVal_1 > 20        'Once it has decided rxVal is either Greater then or less then 20, 
          heading := 1525               'The remaining IF statements are ignored...
        else                        'Below This Line is not used like You might want them to be 
        IF rxVal_1 > 40
          heading := 1550
        else
        IF rxVal_1 > 60
          heading := 1575
        else
        IF rxVal_1 > 80
          heading := 1600
        else
        IF rxVal_1 := 100
          heading := 1625
        else
        IF rxVal_1 := 120
          heading := 1650
        else
    
    Comments are Your best hope >>> ' <<< Document often, Walk Yourself Thru all Code.
    and F9 is your new best friend...:smile:
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-04 14:24
    Also, if you're going to use this method;
    IF rxVal_1 < 20                   
          heading := 1500                 
                                
        IF rxVal_1 > 20
          heading := 1525
    

    What will happen if the value is 20? Try this instead;
    IF rxVal_1 < 21   ' 20 or or lower                
          heading := 1500                 
                                
        IF rxVal_1 > 20         '21 or higher
          heading := 1525
    

    And...
    IF rxVal_1 := 140
          heading := 1675
    

    will not work, should be;
    IF rxVal_1 == 140
          heading := 1675
    

    Still, I think that this is a much better approach than all those IF statements;
    heading := 1500 + ((rxVal_1 *125) / 100)
    

    Rich H
  • nomadnomad Posts: 276
    edited 2010-12-05 05:15
    hi botdocter

    here is a new RRserial_1.spin

    changed: pst
    Servo32.spin
    no serial connections

    i make a short test (no servo connected) it's run

    regards nomad
Sign In or Register to comment.