Shop OBEX P1 Docs P2 Docs Learn Events
S2 internal Pen Lifter and a couple questions for Phil — Parallax Forums

S2 internal Pen Lifter and a couple questions for Phil

W9GFOW9GFO Posts: 4,010
edited 2012-03-15 15:23 in Robotics
First, here's the Pen Lifter, it works awesomely well if I do say so myself...

See the blog entry for more details.

attachment.php?attachmentid=76784&d=1293710893

Now for some questions;

1. The speaker makes a constant but quiet tick tick tick at about 10 hz. Is that normal?

2. Could you take a look at this code? The goal is to control the S2 using my XBee equipped remote controller. The goal is met, it does control it quite well. The problem however is that I cannot get the S2 to maintain a perfectly steady speed. It is as if every second or two the motors will stutter for just a moment even though they are receiving a steady move value.

3. Related to the above perhaps, if I stop the S2 suddenly and then very gently reverse direction, it will lurch slightly.

If I have not described the issues adequately I can put a video on YouTube.

Rich H
«1

Comments

  • Martin_HMartin_H Posts: 4,051
    edited 2010-12-30 06:14
    That is a really cool mod. I make that to my S1.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-12-30 11:42
    Rich,

    Very nice pen lifter! And a beautiful installation! (I'm amazed it all fit.) In response to your questions:

    1. No, the ticking is not normal. (At least I've never noticed it.) Does it do it all the time? What about if you don't start the audio cog?

    2. The "stuttering" you observe is related to the encoder resolution and the way wheel movements are coordinated. In the motor driver object, the motion of each wheel is monitored in relation to the other one. If one wheel should get ahead, it will not receive PWM pulses until the other wheel has caught up with it. That way, if you grip one of the wheels during a movement to slow it down, the other will slow proportionally. Now, if the motion values going to the two wheels differ by a small number, say, two (e.g. 1000 and 1002), there will be two points along the trajectory where one wheel will appear to get ahead of the other (just due to the encoder math) and will hesitate while the other "catches up". This may be the "stutter" that you notice.

    One may also notice a stutter during the drawing routines when drawing arcs. For example, when drawing a full circle, it is necessary to break it into two arcs. Sometimes the correct ending point for the first arc will not have integer coordinates, and you have to round them to integers. If, when the second arc begins, the arc radius is deemed too small for the distance to the ending point, the drawing software will move toward the ending point in a straight line, far enough to make up the extra distance, then draw the arc.

    3. The lurching you see upon reversing direction may be related to backlash in the gearbox, but I'm not sure. If you post an example program that produces this behavior, I'll have a look at it.

    -Phil
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-30 13:22
    Thanks Phil,

    I've just discovered that the ticking vanishes completely when I turn off the remote controller and returns after it has turned back on and booted up - and is in sync with the XBee TX Led on the controller.

    Looking at the well documented PASM motor code it looks like there should be something that I could do to disable the encoders, or at least the part where one is compared against the other. But since I don't really know PASM I do not know how to accomplish that.

    I doubt that the lurching is gear backlash. It only occurs after the S2 is stopped abruptly while moving at faster than half speed. As soon as it begins to move again it appears to be trying to make up some encoder counts.

    Rich H
  • NikosGNikosG Posts: 705
    edited 2010-12-30 13:54
    Hi Phil,
    Something about the problem with circles....(from LOGO Theory)
    Try this algorithm: REPEAT(36) FORWARD (5 cm or any distance) ROTATE-RIGHT (10 degrees)
    When I say Forward I mean both whees must have the same direction and velocity. If the s2 can rotate precisely 10 degrees you 'll have a perfect circle after the 36 steps.
    I have tried this method 6 years ago with a homemade robot (with very cheap DC motors with no accuracy) and I had great results.
    Unfortunately I don't have a s2 to try this but I believe that you 'll have result.

    Nikos Giannakopoulos
  • ratronicratronic Posts: 1,451
    edited 2010-12-30 22:38
    W9GFO - if you want to control the s2's wheel motors directly youself without using the s2 object or the encoders you could use something like this example
    Con                                      ''s2 direct wheel motor control                                                                            
      _clkmode = xtal1 + pll16x                                                                                                                         
      _xinfreq = 5_000_000                                                                                                                              
     
      pwm = 16                               ''pwm base io for s2                                                                                       
     
    Var                                                                                                                                                 
     
    Obj                                                                                                                                                 
     
      pw : "pwmx8"                           ''pwm object                                                                                               
     
    Pub main                                                                                                                                            
     
      pw.start(16, %00001100, 20_000)        ''start pwm object on pwm base i/o pin @ 20khz                                                             
      dira[16..17]~~                         ''set s2's motor direction control i/o pins to output                                                      
     
      repeat                                                                                                                                            
                  'left      right                                                                                                                      
        move_robot(-75,      255)            ''set s2's left wheel slow reverse, set s2's right wheel maximum forward                                   
     
     
    Pub move_robot(left_wheel, right_wheel)  ''set s2's left & right wheel motor's speed from -255 maximum reverse to 255 maximum forward, 0 = stop     
     
      left_wheel := -255 #> left_wheel <# 255                                                                                                           
      right_wheel := -255 #> right_wheel <# 255                                                                                                         
     
      ifnot right_wheel & $80_00_00_00                                                                                                                  
        outa[pwm + 1] := 1                                                                                                                              
        pw.duty(pwm + 3, right_wheel & $ff)                                                                                                             
      else                                                                                                                                              
        outa[pwm + 1] := 0                                                                                                                              
        pw.duty(pwm + 3, (0 - right_wheel) & $ff)                                                                                                       
     
      ifnot left_wheel & $80_00_00_00                                                                                                                   
        outa[pwm] := 1                                                                                                                                  
        pw.duty(pwm + 2, left_wheel & $ff)                                                                                                              
      else                                                                                                                                              
        outa[pwm] := 0                                                                                                                                  
        pw.duty(pwm + 2, (0 - left_wheel) & $ff)                                                                                                        
    
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-30 23:44
    Thanks Dave,

    Not sure why I didn't go that direction, maybe it's because I was hoping to use as much of the 'native' S2 code as possible. I think using a separate driver object is very sensible.

    Rich H
  • ratronicratronic Posts: 1,451
    edited 2010-12-31 00:19
    w9gfo - sorry i posted the wrong file - use the one thats attached in my above post now to get the motors to run the right direction
  • W9GFOW9GFO Posts: 4,010
    edited 2010-12-31 00:32
    The file you attached worked just great for me.

    Thanks,

    Rich H
  • W9GFOW9GFO Posts: 4,010
    edited 2011-01-01 02:51
    I've added a video of the pen lifter to the blog.

    Here's a direct link.

    http://www.youtube.com/watch?v=FqahLvqI-dk

    Rich H
  • ratronicratronic Posts: 1,451
    edited 2011-01-01 08:56
    That's some pretty nice scribblin! What is that controller you are using?
  • W9GFOW9GFO Posts: 4,010
    edited 2011-01-01 12:00
    Thanks!

    The controller is described in this thread.

    RIch H
  • ratronicratronic Posts: 1,451
    edited 2011-01-01 13:03
    Very cool! I missed that one.
  • ercoerco Posts: 20,256
    edited 2011-01-01 15:34
    GREAT Scribblin', Rich! I got a bad S2, turns out. I'll have to get mine swapped out before I can Scribble!
  • W9GFOW9GFO Posts: 4,010
    edited 2011-01-04 18:50
    Thanks!

    Here's another;

    Rich H
  • WhitWhit Posts: 4,191
    edited 2011-01-04 19:20
    Super cool! I thought I had done some cool scribbling...
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-04 20:10
    Rich,

    That's even better repeatability than I would've guessed possible. Did you use the drawing commands in the S2 object? Did you have to tweak the calibration coefficients? (And what's with "SAINTS"? For Whit's benefit, I hope! Go Seahawks! Not that I give a rip. It's just for editorial balance. :) )

    -Phil
  • W9GFOW9GFO Posts: 4,010
    edited 2011-01-04 20:25
    It was all done with move_to and arc_to commands. Calibration coefficients? Didn't even know there were any.

    "Saints" is for the Interlake Saints Robotics Team.

    Rich H
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-04 20:52
    W9GFO wrote:
    Calibration coefficients? Didn't even know there were any.
    No matter: it doesn't look like you need 'em!
    W9GFO wrote:
    "Saints" is for the Interlake Saints Robotics Team.
    Nice save! Um, go Saints! Yeah!

    -Phil
  • W9GFOW9GFO Posts: 4,010
    edited 2011-01-04 21:20
    Here is a larger version. By Larger, I mean the letters are scaled up four times.

    http://forums.parallax.com/entry.php?89-Parallax-S2-writes-quot-Saints-quot-in-big-letters

    And here is the code for the "A", any idea why it messed it up? It seems like it lost some encoder counts on the first two arcs.
    Pub A
    
     s2.move_to(420, 0)
     pen_down
    
     s2.begin_path
     s2.move_to(420, 416)
     s2.arc_to(544, 540, -124)
     s2.move_to(656, 540)
     s2.arc_to(780, 416, -124)
     s2.move_to(780, 0)
     s2.move_to(660, 0)
     s2.move_to(660, 180)
     s2.move_to(540, 180)
     s2.move_to(540, 0)
     s2.move_to(420, 0)
     s2.end_path
    
     pen_up
    
     s2.move_to(540, 300)
     pen_down
    
     s2.begin_path
     s2.move_to(540, 388)
     s2.arc_to(568, 420, -32)
     s2.move_to(628, 420)
     s2.arc_to(660, 388, -32)
     s2.move_to(660, 300)
     s2.move_to(540, 300)
     s2.end_path
    
     pen_up
    

    Rich H
  • WhitWhit Posts: 4,191
    edited 2011-01-06 09:18
    (And what's with "SAINTS"? For Whit's benefit, I hope! Go Seahawks! Not that I give a rip. It's just for editorial balance. :) )

    To properly scribble about my saints, you will need to scribble "Who Dat?" The church's saints are another matter.

    Great job Rich!
  • WhitWhit Posts: 4,191
    edited 2011-01-08 18:09
    Okay - Time to re-program to make it say SEA HAWKS...

    who dat??? :frown:
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-08 18:45
    Or, keeping it on-topic by giving a bow to Georgia Tech's Scribbler/S2 accessory: what a FLUKE! :)

    -Phil
  • NikosGNikosG Posts: 705
    edited 2012-03-06 12:20
    W9GFO wrote: »
    Here is a larger version. By Larger, I mean the letters are scaled up four times.

    http://forums.parallax.com/entry.php?89-Parallax-S2-writes-quot-Saints-quot-in-big-letters

    And here is the code for the "A", any idea why it messed it up? It seems like it lost some encoder counts on the first two arcs.
    Pub A
    
     s2.move_to(420, 0)
     pen_down
    
     s2.begin_path
     s2.move_to(420, 416)
     s2.arc_to(544, 540, -124)
     s2.move_to(656, 540)
     s2.arc_to(780, 416, -124)
     s2.move_to(780, 0)
     s2.move_to(660, 0)
     s2.move_to(660, 180)
     s2.move_to(540, 180)
     s2.move_to(540, 0)
     s2.move_to(420, 0)
     s2.end_path
    
     pen_up
    
     s2.move_to(540, 300)
     pen_down
    
     s2.begin_path
     s2.move_to(540, 388)
     s2.arc_to(568, 420, -32)
     s2.move_to(628, 420)
     s2.arc_to(660, 388, -32)
     s2.move_to(660, 300)
     s2.move_to(540, 300)
     s2.end_path
    
     pen_up
    

    Rich H


    Hi Rich,

    Inspired from your pen lifter I created an advanced Internal pen lifter. Althought the pen lifter lifts the pen Up and down perfect using the spin code: "s2_pen_lifter_test" it is not work in conjunction with the S2 Object. When the robot moves straight or makes arcs it is not able to move the pen up and down. I would be thankful if you could give some information about the methods "pen_up" and "pen_down" that you use in your code (above). Do you use multitasking for those methods?

    Thank you
    Nikos Giannakopoulos.
  • W9GFOW9GFO Posts: 4,010
    edited 2012-03-06 12:32
    The pen_up and pen_down methods are very simple, something like this.

    con
    pen = 1
    up = 1200

    pen_up
    servo.set(pen, up)

    It will only work this way between line segments.

    If you wanted to create dots or dashes during the line segment I think you could write a method that moves the pen based upon encoder counts - or at the minimum, time based.
  • NikosGNikosG Posts: 705
    edited 2012-03-06 14:20
    Thank you Rich,

    I had already tried your advice but nothing....
    here is the code:
    CON
       _CLKMODE = XTAL1 + PLL16X 
       _CLKFREQ = 5_000_000
     '-----------------------------
       Up    =  2080
       Down  = 1600
    
      
        ServoPen  = 5
     '----------------------------- 
    
                           
    OBJ 
    s2 : "S2"
    SERVO : "Servo32v7"    '-------------- for pen lifter
    
    PUB Main 
     
      Pen_Down '---------------------------------
    
      S2.start
       S2.button_mode(true, true) 
       S2.set_led(s2#POWER, s2#BLUE) 
       S2.start_motors 
       S2.set_speed(7) 
       S2.here_is(0,0)       
     S2.begin_path
       S2.move_to(300,0)       
    
       Pen_Up
    
       S2.move_to(600,0)       
    
       Pen_Down
       
       S2.move_to(900,0)       
       S2.move_to(900,300)       
    
        Pen_Up  
       
       S2.move_to(900,600)       
    
        Pen_Down  
       
       S2.move_to(900,900)       
       S2.move_to(600,900)       
    
       Pen_Up  
       
       S2.move_to(300,900)       
    
         Pen_Down
       
       S2.move_to(0,900)       
       S2.move_to(0,600)       
    
     Pen_Up
       
       S2.move_to(0,300)       
    
      Pen_Down
         
       S2.move_to(0,0)       
     S2.end_path
    
    PUB    Pen_up
        SERVO.Start                 ' Start servo handler
        
      
        SERVO.Set(ServoPen,Up)    ' 2400: max        600:min
      
       
     
    PUB Pen_Down
    
       SERVO.Start                 ' Start servo handler
        
     
        SERVO.Set(ServoPen,Down)    ' 2400: max        600:min
                            
    

    I'm trying to draw this square with no continues sides using my S2 but the pen stays down...


    attachment.php?attachmentid=90343&d=1331071664

    On the other hand, the following code can lift up and down the pen without problem:
    OBJ
      SERVO : "Servo32v7.spin"
    
    CON
        _clkmode = xtal1 + pll16x                           
        _xinfreq = 5_000_000 
    
        ServoCh1 = 5               ' Servo to pin 0 - 5
    
    PUB Servo32_DEMO
    
        SERVO.Start                 ' Start servo handler
        
      repeat
        ' Syntax: SERVO.Set(Pin, Width)
        SERVO.Set(ServoCh1,2080)    ' 2400: max       Pen Up
         repeat 800000               ' Wait a short bit
               
        SERVO.Set(ServoCh1,1600)    ' 1500 usec (centered)  600:min   Pen Down
         
          repeat 800000
    

    I use a Hitec Hs 55 servo connected on Pin P5 on hacker Port and the following motor characteristic
    attachment.php?attachmentid=90344&d=1331071665

    So the question is how can I make the S2 manipulate the Pen-servo while it moves using the S2 object commands?

    What goes wrong with the first code?


    Phil can you Help Please?
    320 x 269 - 4K
  • W9GFOW9GFO Posts: 4,010
    edited 2012-03-06 15:08
    You are missing Servo.start in the first program.

    edit: I see you have multiple Servo.starts. you only need to call it once at the beginning of your program.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-06 15:30
    Nikos,

    Try it without the begin_path and end_path commands, then call wait_stop before issuing a pen-up or pen-down. The reason for this is that drawing commands are semi-buffered to be executed in the background. A pen-up/draw-command/pen-down sequence is likely to be executed in rapid sequence before the draw command even has a chance to get started.

    -Phil
  • NikosGNikosG Posts: 705
    edited 2012-03-06 15:36
    Pich,
    Nothing again.....
    The servo makes only a small reaction in the first command (Pen_Down) end then nothing. It is like doesn't exist....
  • NikosGNikosG Posts: 705
    edited 2012-03-06 15:48
    Hi Phil,


    I wrote the following:
    CON
       _CLKMODE = XTAL1 + PLL16X 
       _CLKFREQ = 5_000_000
     '-----------------------------
       Up    = 1200' 2080
       Down  = 1600
    
      
        ServoPen  = 5
     '----------------------------- 
    
                           
    OBJ 
    s2 : "S2"
    SERVO : "Servo32v7"    '-------------- for pen lifter
    
    PUB Main 
    
    
     S2.start
       SERVO.Start                 ' Start servo handler
     s2.wait_stop
     Pen_Down '---------------------------------
    
      
       S2.button_mode(true, true) 
       S2.set_led(s2#POWER, s2#BLUE) 
       S2.start_motors 
       S2.set_speed(7) 
       S2.here_is(0,0)       
      
       S2.move_to(300,0)       
    
     s2.wait_stop
       Pen_Up
    
       S2.move_to(600,0)       
    
     s2.wait_stop
       Pen_Down
       
       S2.move_to(900,0)       
       S2.move_to(900,300)       
    
     s2.wait_stop
        Pen_Up  
       
       S2.move_to(900,600)       
    
     s2.wait_stop
        Pen_Down  
       
       S2.move_to(900,900)       
       S2.move_to(600,900)       
    
     s2.wait_stop
       Pen_Up  
       
       S2.move_to(300,900)       
    
     s2.wait_stop
        Pen_Down
       
       S2.move_to(0,900)       
       S2.move_to(0,600)       
    
    s2.wait_stop
     Pen_Up
       
       S2.move_to(0,300)       
    
    s2.wait_stop
      Pen_Down
         
       S2.move_to(0,0)       
      
    
    PUB    Pen_up
        
          SERVO.Set(ServoPen,Up)    ' 2400: max        600:min
      
       
     
    PUB Pen_Down
    
           SERVO.Set(ServoPen,Down)    ' 2400: max        600:min
      
    
    Unfortunatelly the problem remains.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-06 15:53
    Hmm. I wonder if the wait_stop is getting executed before motion even begins. Try inserting this before each wait_stop:
    repeat until s2.moving
    

    -Phil
Sign In or Register to comment.