Shop OBEX P1 Docs P2 Docs Learn Events
Parallax Servo Controller (USB), commands?? — Parallax Forums

Parallax Servo Controller (USB), commands??

XanXan Posts: 3
edited 2008-08-26 03:32 in General Discussion
Hi!

Does anyone know where I can find a list of commands and on what form the
Parallax Servo Controller (USB) wants the commands sent to it? Im trying
to program the servo controller without any stamp.. Would be nice to controll
it by a language like C, Java or Python, and Im having a hard time finding information
about the form and neccesary commands..
Thankful for help!
//Xan

Comments

  • XanXan Posts: 3
    edited 2007-07-08 17:53
    Thanks, think Ill understand it now.. I hope..
    //Xan
  • XanXan Posts: 3
    edited 2007-07-08 18:13
    Hi again, problem has arrived..
    When I try to get a version it works without a hitch, but as soon as I try to move the servo nothing happens..
    I have foun some reference that implies that the controller should get numbers like;
    33 83 67 0 0 222 4 13
    33 83 67 -> !SC
    13 -> \r
    222 4 -> well it moves..

    This is on the form that ServoControllerManualRevBv2_4.pdf says the controller wants, so does anyone know if
    the controller wants all commands as integers or is there a way to write it like the ServoControllerManualRevBv2_4.pdf
    says; ie. "!SC" 0 0 250 1250 \r
    Hopeful someone can help..
    //Xan
  • FranklinFranklin Posts: 4,747
    edited 2007-07-08 18:43
    www.parallax.com/dl/docs/prod/motors/ServoControllerManualRevBv2_4.pdf page 5 and 6 have some sample programs.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Stephen
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-07-09 16:52
    Hello,

    The only ASCII characters the PSC should be receiving are the !SC at the beginning. All other values are raw binary data, not ASCII or HEX representations of them. You should be sending exactly 8 bytes every time. Take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • JonnyMacJonnyMac Posts: 9,215
    edited 2007-07-09 17:07
    The other thing to be aware of is that the USB PSC echoes everything set to it, so your application should ignore that or be prepared to filter it out.
  • aresotaresot Posts: 3
    edited 2007-07-27 16:23
    Im trying to do same thing using LibUSB-Win32 library[noparse]:http:[/noparse]//libusb-win32.sourceforge.net/
    I also found it usefull to run USB monitoring software (http://www.hhdsoftware.com/Products/home/usb-monitor-lite.html) to check exactly what PSCI sends to PSC.
    Anyone has code to share?

    aresot
  • stuart007stuart007 Posts: 3
    edited 2007-08-05 10:18

    I am trying to do the same thing... I need to use C++ to write basic commands to the usb servo driver.

    Using a terminal session such as minicom, I can write !SCVER? to the device and it returns 1.4, which is what the PSCI reports when asking for the version.

    I also used a program called "Advanced Serial Port Monitor" to see what the PSCI sends to the usb port...

    This is what I get when i ask for the version...

    U
    U
    !SCVER?<CR>
    !SCVER?<CR>1.4

    When I move channel 0 to 2500, I get this...

    !SC<NUL><NUL>
  • John R.John R. Posts: 1,376
    edited 2007-08-05 13:51
    You generally populate an array with the binary data. For the ASCII characters you may need to use the ASC command to convert from the character to the ASCII code, depending on how you build the array. Then you send the array out with the appropriate serial port send command.

    It won't directly go to C++, but here's some C# code I use for sending similar commands to a propeller (these are NOT PSC commands!):

            public bool SetServoPulseWidth(int Servo, int PulseWidth)
            {
                char x;
                byte[noparse][[/noparse]] Address = new byte;
                byte[noparse][[/noparse]] Pulse = new byte;
    
                if (spPort.IsOpen)
                {
                    try
                    {
    
                        Address[noparse][[/noparse]0] = (byte)Servo;
                        Pulse = (byte)(PulseWidth / 256);
                        Pulse[noparse][[/noparse]0] = (byte)(PulseWidth - (Pulse * 256));
    
                        spPort.Write("!S");
                        spPort.Write(Address, 0, 1);
                        spPort.Write(Pulse, 0, 2);
    
                        x = (char)spPort.ReadChar();
                    }
                    catch
                    {
                        return false;
                    }
                    return true;
                }
                return false;
            }
    
    



    Note that in the above code, I send the ASCII string out in the first "write" (the spPort object converts the characters to binary), the address in the 2nd, and the two byte pulse in the 3rd. I could have also sent all this out as one array. It depends on what "object" you are using for the serial port, and what commands are available for that object, and how they work.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    John R.
    Click here to see my Nomad Build Log

    Post Edited (John R.) : 8/5/2007 1:56:47 PM GMT
  • jfalconjfalcon Posts: 2
    edited 2008-03-12 01:07
    Greetings,

    I'm wondering if there are any Delphi/Pascal people in here...

    I'm having a odd time translating values into binary.· It seems like the bit string is too long and it's causing problems.

    procedure TFMain.UpdateRotorAndRadio(data: TSatData);
    var
      servoel_in, servoaz_in : Integer;
      servoel, servoaz : Integer;
      servoaz_array, servoel_array : Array of Byte;
      servoaz_string, servoel_string : AnsiString;
      servoaz_int, servoel_int : Integer;
      servoaz_bin, servoel_bin : String;
      servoaz_low, servoaz_high : Byte;
      servoel_low, servoel_high : Byte;
      servoaz_string_length : Integer;
      servoel_string_length : Integer;
      servoaz_string_ptr : PChar;
      servoel_string_ptr : PChar;
      servo_preamble : AnsiString;
      code : Integer;
      size : Word;
      myChar : AnsiChar;
      az_port : AnsiString;
      el_port : AnsiString;
      ramp_rate : AnsiString;
      char_return : AnsiChar;
      I: Integer;
    
    begin
      with data do begin
      servoaz_in := Round(azm);
      case servoaz_in of
    0..180 : servoaz := Round((servoaz_in*6)/10+1500);
        181..359 : servoaz := Round(1500-(servoaz_in*6)/10);
      end;
      servoel_in := Round(elv);
      case servoel_in of
        0..90 : servoel := Round(1500-(servoel_in*6)/10);
      end;
      if servoel < 600 then
        begin
        servoaz := 1500;
        servoel := 1500;
        end;
    
      servo_preamble := '!SC';
      az_port := IntToBin8(StrToInt('$30'));
      el_port := IntToBin8(StrToInt('$31'));
      ramp_rate := IntToBin8(StrToInt('$30'));
      char_return := Chr(13);
    
      servoaz_string := IntToStr(servoaz);
      servoaz_bin := IntToBin8(StrToInt(servoaz_string));
      servoaz_string_length := Length(servo_preamble)+Length(az_port)+
        Length(ramp_rate)+Length(servoaz_bin)+Length(char_return);
    
      servoel_string := IntToStr(servoel);
      servoel_bin := IntToBin8(StrToInt(servoel_string));
      servoel_string_length := Length(servo_preamble)+Length(el_port)+
        Length(ramp_rate)+Length(servoel_bin)+Length(char_return);
    
      GetMem(servoaz_string_ptr,servoaz_string_length);
      GetMem(servoel_string_ptr,servoel_string_length);
      StrPcopy(servoaz_string_ptr,servo_preamble+az_port+ramp_rate+
        servoaz_bin+char_return);
      StrPcopy(servoaz_string_ptr,servo_preamble+el_port+ramp_rate+
        servoel_bin+char_return);
    
    
      label12.Caption := FloatToStr(servoaz);
    code := SioPuts(Port,servoaz_string_ptr,servoaz_string_length);
        edit1.Text := servo_preamble+servoaz_bin;
      label14.Caption := FloatToStr(servoel);
        code := SioPuts(Port,servoel_string_ptr,servoel_string_length);
        edit2.Text := servo_preamble+servoel_bin;
    end;
    

    And the IntToBin8 function
    function IntToBin8(I: integer): string;
    begin
      Result := '';
      while I > 0 do begin
        Result := Chr(Ord('0') + (I and 1)) + Result;
        I := I shr 1;
      end;
      while Length(Result) < 8 do
        Result := '0' + Result;
    end;
    


    The value of servoaz and servoel is default at 1500 but can vary up and down from this number. But 1500 gives "10111011100" as the result which is 3 bits longer than it should be.

    The PSC docs mention this should be a 16 bit Word with a low side and a high side. How would I convert 1500 into two 8 bit pieces then convert them into binary?
  • PersianPatientPersianPatient Posts: 1
    edited 2008-08-26 03:32
    Dear jfalcon ,

    can you please explain me about that procedure you wrote above ? is it a component that I can use to build my own software to send commands to the servo controller ? what is the tSatData ?

    Best Regards,
    PersianPatient .
Sign In or Register to comment.