Shop OBEX P1 Docs P2 Docs Learn Events
Parallax Servo Controller with Propeller SPIN — Parallax Forums

Parallax Servo Controller with Propeller SPIN

JimTheProgrammerJimTheProgrammer Posts: 44
edited 2008-07-08 19:12 in Propeller 1
Is there anyway one could use the Parallax Servo Controller with the Propeller using the SPIN language?
I hate to waste a good servo controller since I upgraded to the propeller.
I have tried to make use of the BS2 Functions by Martin Hebel in the objects but to no avail.

·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-05 02:19
    The PSC accepts serial input and the Propeller can produce that using any of several serial I/O drivers from the ones in the BS2 compatibility library to the FullDuplexSerial driver.· Make sure the PSC is connected properly and you're using the proper Baud for the PSC.

    You'll need a 1K current limiting resistor between the Propeller and the PSC in the output line from the PSC and it would be a good idea to use one in the input line to the PSC as well.· Because the PSC is a 5V device, its output lines can damage the Propeller's input circuitry without some current limiting resistance.
  • stampedstamped Posts: 68
    edited 2008-07-03 11:16
    I am also using the PSC (serial). The issue that I am having is every time I turn it on the servos continuously rotate (they are parallax continuous rotation servos) without any commands being sent to the PSC. Any commands I send are ignored. The LED is always on on the PSC.

    I have the following;

    - a 10k from Prop to pin 0
    - 4.7k from Prop pin 0 to VDD (5v) - pull-up
    - Black servo lead to PSC directly to prop VSS
    - Separate battery pack connected to the PSC
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2008-07-03 14:47
    Stamped,

    The PSC green LED should not be on all the time…The default power-on condition is that all output channels will be pulsed at 1.5ms (center position) until other commands are received. As for a pull-up resistor, that only serves to complicate things as your fighting a pulling battle on both sides of the resistor. The PSC has an internal pull-up already, so that’s not needed. Being non-inverted (true), the default idle state of the serial line is high. The problem is that with the series resistor you may not be able to assert the serial line low enough to be a zero on the PSC side. This is because in addition to the internal pull-up you’re fighting the additional pull-up implied by the LED connected directly between the serial line and the PSC VDD. So when you assert the line low, the LED causes a pull-up. Since you have the series resistor this complicates things. I know I covered all of this before and I will try to find my old thread to see what I cam up with for a solution. In the meantime, I would try powering the PSC without anything connected to its serial line and see if it centers the servos. As a side note, non-calibrated CR servos may in fact start spinning when they should be stopped.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Mike GreenMike Green Posts: 23,101
    edited 2008-07-03 15:08
    Since I posted the last message, I've been reminded that the PSC has a problem with the Propeller in that there's an LED that is connected to the serial input line. If you use a series resistor between the Propeller I/O pin and the PSC input, the Propeller can't force the input to logic low because the LED is pulling it up to +5V. If you leave out the series resistor, you can damage the Propeller because of the voltage / current from the LED and +5V. You could use an NPN transistor between the PSC and the Propeller. A 2N3904 would work fine. Connect the emitter to ground, the collector to the PSC serial input, the base through a 1K resistor to the Propeller I/O pin.

    The transistor inverts the logic signal, so you need to use the mode parameter in FullDuplexSerial or the equivalent mode parameter for the BS2 SEROUT functions to invert the serial output information.
  • stampedstamped Posts: 68
    edited 2008-07-03 23:21
    Thanks Chris and Mike. I read through some previous threads in the Prop forum and could not see why the servos would be rotating continuously.

    Chris: When I remove the connection to the serial line from the Prop the servos stop rotating. From a "cold state" when I power up the device the servos move slightly (when the Prop serial pin is not connected).

    Mike: I saw some previous threads and was cautious with regards to the 5v line from the Servos and put the resistor in as is noted in "protecting the prop". Thanks for the tip regarding the NPN transistor. I will try this out tonight.
  • stampedstamped Posts: 68
    edited 2008-07-05 06:27
    I tried the setup that Mike noted with the transistor(2N2222) (and changed the servos to normal servos, not continuous rotation) and I found the following;

    The green light now comes on, on the PSC board when I send a serial message. My code is as follows;

    ' Note: servo_cont is Extended_FDSerial"
    servo_cont.start(0, 0, 0, 2400)    ' Note the mode is 0, which seems contrary to Mikes advice. When set to 1, I get no response from the PSC
    servo_cont.str(string("!SCVER?"))  
    servo_cont.tx($0D)
    
    



    I get back "!SCVER" - unsure why this is so and not the version number?

    When I try to send any positioning commands, the servo does not respond.
    When sending any commands the green light stays on permanently.

    Code for the positioning:

    servo_cont.str(string("!SC"))
    servo_cont.tx(0)               ' Servo ID
    servo_cont.tx(20)               ' Ramp
    servo_cont.tx(1200)             ' Posn
    servo_cont.tx($0D)              ' CR
    
    



    Any ideas from here?
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-05 10:10
    hello stamped,

    your call of the servo_cont.start-command

      servo_cont.start(0, 0, 0, 2400)
    
    



    defines Rx-Pin AND Tx-Pin to be P0 so the receving routine looks on the sending state of the sending PIN
    and "receives" what is sended out

    if you take a look into the sourcecode of the start-method
    
      Pub Start (RXpin, TXpin, Mode, Baud)
    
    



    first Parameter is the RX-Pin
    second parameter is the Tx-PIN

    i want to explain a little bit how i found this

    you received "!SCVER" which is almost the same like you sended out "!SCVER?" (additional "?" at the end)
    i was asking myself "looks like an echo". Does the PSC send an echo if the command is wrong?
    I took a look into the manual - there's nothing mentioned about echoing.
    Where could the echo come from ? wrong connection of the PINs ? Shortcut between Rx and Tx-pin?

    Then i was looking again on your code. servo_cont.start(0, 0, 0, 2400) - hm three parameters a zero ?
    wasn't two of the parameters Rx and Tx-Pin?
    taking a look into the sourcecode of Extended_serial
    yes it is !

    For further developing: make ONE change at a time testing out this change. Then the next. By this way you keep the area
    where an error could be as small as possible which makes it easier to find the error.

    Without having seen the error in the code i would have done this

    Testing every part of the system separately

    testing the serial comport of my PC:
    with a closed-loop TX-Pin directly connected to Rx-pin
    sending out something with the terminalsoftware should be echoed immediatly

    testing does a terminalsoftware communicate with the PSC?

    sending the "!SCVER?" command via terminalsoftware does the PSC answer?

    testing is there a shortcut between Rx and TX-Pin
    connecting the cable but NOT the PSC running the testsoftware
    is something received?

    testing what is the propeller sending out
    connecting ONLY the tx-pin with a PC running a terminalsoftware
    checking what does the terminalsoftware receive?

    testing what does the propeller receive from the terminalsoftware ?
    connecting ONLY the Rx-pin of the propeller with a PC
    writing a short testprogram just echoing what has been received or a loop waiting
    for a special command like "XXYY" and then toggle a LED

    depending on wich HARDWARE pin would be the Rx / Tx-Pin on one of the two cases you
    wouldn't receive something.

    Maybe already looking at your code for this test
    "Ok Rx-Pin is 0 ...receiving is working"
    "Tx-Pin is 0 too ?? you would have found it

    best regards

    Stefan

    Post Edited (StefanL38) : 7/5/2008 10:24:28 AM GMT
  • stampedstamped Posts: 68
    edited 2008-07-05 10:59
    thanks for the response Stefan. I agree that the rx and tx lines may cause an issue. That said I am not sure how one could read from the PSC any other way?

    Aside from the rx / tx issue the fact the servo does not move is unexplained. Also note I have in my tests set the rx line in the initialization to -1 but this made no difference. The servos did not move.

    Ps; apologies for any typos as I am responding from my iPhone.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-05 18:47
    hello stamped,

    sorry now i took a close look into the manual of the psc. It uses the SAME PIN for sending AND receiving.

    For this special and unusual situation the standard-use of a fullduplex serial driver like FullDuplexSerial.spin or Extended_FD-Serial.spin is not possible.
    The IO-pin of the Tx-Pin is set as an Output. The IO-Pin of the Rx-Pin is set as an input. But ONE pin cannot be Output and Input at the SAME time.
    FullDuplexserial expects TWO DIFFERENT Pin-numbers for Tx and Rx. Because the IO-mode of both Pins is set to Output/input statically at initialisation.

    The PSC has only ONE pin for sending and receiving.
    This makes it nescessary to change the IO-Mode of the PIN always for and back
    between Output (low resistance of the IO-Pin) and Input (high resistance of the IO-Pin).

    You have to use the basicstamp-equavelent routines for the propeller.
    There you have the routines serout_str and SERIN_STR. These routines set the IO-mode of the IO-PIN DYNAMICALLY and new everytime they were called

    So you can transfer the basicstamp example from the PDC-manual to SPIN using the BS2-Functions.spin

    Another idea might be to modify the assembler-routines of FullDuplexSerial:
    if Tx-Pin and Rx-Pin are the same number change the mode of the PIN dynamically inside the "ping-pong multitasking" that always jumps between receiving and transmitting

    I'm not sure if this could work because the switching from high to low resistance will happen will received databits are still high.

    best regards

    Stefan

    Post Edited (StefanL38) : 7/5/2008 7:17:03 PM GMT
  • TimmooreTimmoore Posts: 1,031
    edited 2008-07-05 18:57
    Try Simple_serial at http://obex.parallax.com/objects/183/ it has support for rx and tx being the same pin
  • stampedstamped Posts: 68
    edited 2008-07-06 05:04
    I have tested out the Simple_Serial object and I get back garbage from the PSC when querying for the version number as noted above.

    Apart form the fact that I cannot get the version number, I have not been able to get the Prop to communicate with the PSC and have any servos move. I am seeing the green light flash with the serial commands, but the servos never actually move.
  • computer guycomputer guy Posts: 1,113
    edited 2008-07-06 05:38
    stamped if you are getting garbage back but the light is flashing then it might be a baud rate issue.
    Make sure that the Simple_Serial object is using the same baud rate as is set on the PSC.

    Hope this helps. smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Check out my robot using the propeller RECONAUTOR
    If you like my avatar then check this out Propeller Domed Stickers for sale

    Building Blocks To The Propeller Chip
  • stampedstamped Posts: 68
    edited 2008-07-06 05:45
    computer_guy, I am running at 2400 baud, which is the default for the PSC unit. I have not changed the baud settings and the PSC is new (first time I have used it).

    I was trying to get the version number as a way to confirm that all my setting were correct, which given the garbage return data, may well be incorrect. Anyway, I have posted the code above.
  • TimmooreTimmoore Posts: 1,031
    edited 2008-07-06 06:56
    If you are using the transistor suggested above did you set the inverted flag in simple_serial by using -2400 - note the "-"?
  • stampedstamped Posts: 68
    edited 2008-07-06 07:05
    Yes, I tried the inverted mode, but this did not make any difference. I am going to remove the PSC and put it on a separate board to see if I can trouble-shoot it a bit better.
  • stampedstamped Posts: 68
    edited 2008-07-06 10:17
    I have completed moving the PSC to a new board where I can access the components a bit better.

    May my issue be with how I am sending the data? In that I am sending the Position rather than the low and high bytes of the position?

    servo_cont.init(0, 0, -2400)
    pause_Ms(2000)
    servo_cont.str(string("!SC"))
    servo_cont.tx(0)               ' Servo ID
    servo_cont.tx(20)               ' Ramp
    servo_cont.tx(1200)             ' Posn
    servo_cont.tx($0D)              ' CR
    
    



    I changed the code to the following without any success (servo sill did not move - note I have tested multiple servos)

    servo_cont.init(0, 0, -2400)
    pause_Ms(2000)
    servo_cont.str(string("!SC"))
    servo_cont.tx(0)               ' Servo ID
    servo_cont.tx(20)               ' Ramp
    posn := 1200
    servo_cont.tx(posn.byte[noparse][[/noparse]0])             ' Posn - trying to get the low and high byte (unsure if this is how?)
    servo_cont.tx(pson.byte)
    servo_cont.tx($0D)              ' CR
    
    



    Note, I have looked at the PSC code published by Steve Norris located here: http://norrislabs.com/Projects/HexDATS/GaitHexHDATS.spin - the low and high byte idea came from this code. Unfortunately it has made no difference. I am also not getting any response when sending the !SCVER? command.

    Also note that the green light flashes on the servo controller when the serial commands are sent. If I manually turn the servo and then turn on the servo controller, the servo centers. So the PSC appears to be hooked up correctly.

    Post Edited (stamped) : 7/6/2008 11:06:54 AM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-06 12:02
    hello stamped,

    did you take a look inside the file simple_serial.spin method init ?
    There is a documentation about the different modes and how they have to be initialized.

    From what you have posted until know i cannot check if all details were right.

    As long as you did not post all your details this is searching in the fog hoping to hit the target but not knowing in which direction it is.
    Could you please attache ALL SPIN-files that are nescessary for compiling AND the circuit that you are using. This circuit should show all details.

    I go back to checking the very basic things
    - is ground of Prop and ground of PSC connected?

    - you init(0,0,-2400) which means inverted mode and for this mode there has to be a resistor 4,7kOhm as a pull-down-resistor
    from Prop-Pin to ground. But i'm not sure if it is a pull-down-resistor the symbolic and text is not clear to me
    it might be a pull-up-resistor to +3,3V

    @parallax: could you clear things up by editing the documentation of simple_serial.spin by using two SEPERATE sentences ?
    for Same-Pin (Bi-Directional) TRUE-Mode use a xxx-resistor
    for Same-Pin (Bi-Directional) INVERTED-Mode use a xxx-resistor

    i guess it's meant this way round but i'm not sure

    Do have a serial interface that can transform standard RS232-level (+-12V) from a PC down to TTL ?
    Or a basic stamp ?
    With this you could check if the PSC is responding at all by sending the commands from the basicstamp or a terminalsoftware from the PC

    After that you can be sure the PSC is still working

    Next step will be to test the propeller what does the terminalsoftware receive from the propeller?

    best regards

    Stefan
  • Matthew HayMatthew Hay Posts: 63
    edited 2008-07-06 19:26
    Ummm if it's using the same pin for both Input and Output how do you have it wired????? A transistor is only going to let the data pass one way.
  • TimmooreTimmoore Posts: 1,031
    edited 2008-07-06 19:53
    Good point. You need a mosfet transistor for bi-direction, either use one of these http://www.sparkfun.com/commerce/product_info.php?products_id=8745# or copy the circuit. You only need 1 transmit channel. Connect the prop pin to channel 1 TXI, the servo controller to channel 1 TXO
    +3.3 to LV and +5 to HV. You dont need channel 2 or the receive side of channel 1. A similar circuit is also talked about in the 5V interface thread.
    Also the curcuit will not invert so you need to remvoe the invert flag
  • stampedstamped Posts: 68
    edited 2008-07-07 09:31
    Thanks for the comments. The transistor/no response from the PSC makes sense. That said, what does not make sense is the fact that when I send commands to the unit it does not move the servo, or trigger any changes in the voltage applied to the data line (the only ray of light is the fact that the green led flashes). I think that going down the Mosfet path would be overkill for the moment and just complicate things more. First base is for me to get the servo to move by sending serial commands. I have set up the circuit as Mike suggested but I am still not getting the servo to move.

    Specifically what is the format for sending the data to the PSC, especially surrounding the High and Low byte for the servo positions.

    servo_cont.init(0, 0, -2400)
    pause_Ms(2000)
    servo_cont.str(string("!SC"))
    servo_cont.tx(0)               ' Servo ID
    servo_cont.tx(0)               ' Ramp
    posn := 1200
    servo_cont.tx(posn.byte[noparse][[/noparse]0])             ' Posn - trying to get the low and high byte (unsure if this is how?)
    servo_cont.tx(pson.byte)
    servo_cont.tx($0D)              ' CR
    
    



    I assume the above code should work if everything is wired correctly?
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-07 12:47
    hello stamped,

    to get low and highbyte of a value you have to calculate the following

      HighByte := posn / 256
      LowByte := posn - (HighByte * 256)
    
    


    best regards

    Stefan

    Post Edited By Moderator (Chris Savage (Parallax)) : 7/7/2008 2:42:28 PM GMT
  • dbpagedbpage Posts: 217
    edited 2008-07-07 22:50
    I have been successfully using the following:

    psc : "Extended_FDSerial"
    psc.start(15,15,%1100,2400) ' start psc communication service mode: open-drain/source tx/ignore tx echo on rx
    where psc uses Extended Full-Duplex Serial Object Version 1.1.0

    Transmit and receive on the same pin works fine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Dennis B. Page, Page Radio Company
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-07-08 19:12
    Hello Dennis,

    thank you for your post. I wasn't aware that Extended_FDSerial-object already can manage sending and receivig on the same PIN.

    i've learned something new.

    best regards

    Stefan
Sign In or Register to comment.