View Full Version : Servo Controller HELP!

Cyrus

03-31-2007, 08:24 AM

Hi guys,

I am doing a project for school and I need to get a servo to interface in matlab, namely simulink. I want to be able to command the servo within my PID loop.

I just bought this http://www.parallax.com/detail.asp?product_id=28823·which hooks up to the USB. I know I have to open the com port for this device in matlab, but im not exactly sure what else has to be done to get it to work.

Can someone help me out, PLEASE?http://forums.parallax.com/images/smilies/freaked.gif

I will be using a single standard fuaba servo.

Cheers,

Cyrus

Cyrus said...

...

I am doing a project for school and I need to get a servo to interface in matlab, namely simulink. I want to be able to command the servo within my PID loop.

I just bought this http://www.parallax.com/detail.asp?product_id=28823·which hooks up to the USB. I know I have to open the com port for this device in matlab, but im not exactly sure what else has to be done to get it to work.

...

I will be using a single standard fuaba servo.

...

You need to create the equivalent matlab outputs to the ones found in

http://www.parallax.com/dl/docs/prod/motors/ServoControllerManualRevBv2_4.pdf

(assuming that you are connecting the servo directly to the matlab system's hardware/software).

This is the documentation for the·serial port version of the Parallax Servo Controller, but it is the one with a description of the commands you need to know about (the outputs you need to have the matlab send to the PSC). The "Position" command is the only one that may be a bit tricky to formulate.

PAR

Cyrus

04-03-2007, 02:26 PM

I got my PSC in, but I cant communicate with it using matlab. Please help!

I can get it to work using the user interface PCI software though.

Here is what I assumed.

Baud 2400

no parity

two stop bits

eight data bits

terminator 'CR'

COM4

But when I try to open it, I dont think its connecting.

clear

clc

% opens the COM1 serial port and sends a series of commands to a servo

ser = serial('COM4');

set(ser, 'BaudRate', 2400,'StopBits',2);

set(ser,'Terminator','CR','Parity','none');

set(ser, 'DataBits', 8); % set data bits to 8

set(ser, 'StopBits', 2);

fopen(ser); % open the serial port connection

fprintf(ser,'!SCVER?$0D');

PLEASE HELP!?

Cyrus

04-05-2007, 05:55 AM

OK, I got it working in HYPERTERMINAL,

CAN someone help me figure out how to send it servo commands?

I gave it the command

!SC 0 0 500.LOWBYTE 2500.HIGHBYTE, $OD

but nothing happened. Where do you command the servo position pulsewidth?

Mike Green

04-05-2007, 06:11 AM

You can't use ".LOWBYTE" or ".HIGHBYTE" in the actual text of the command. For that matter, the only thing you can have literally is the "!SC". In the case of the bytes that follow the "!SC" or any of the other commands, you need to have the actual 8-bit byte value sent. What you need to send is a sequence of 8 bytes. The first is the numeric value of "!", the second is the numeric value of "S", the third is the numeric value of "C", then two bytes with a numeric value of zero. If you want a servo position of 1500, the next byte is the numeric value of the lower 8 bits of 1500. The byte after that is the numeric value of the upper 8 bits of 1500. Lastly is the number 13 (or $0D or the return character).

The PBasic compiler in compiling a SEROUT statement for a Stamp processor, will do this process for you if you put "!SC",0,0,x.lowbyte,y.highbyte,$0D in the square brackets of a SEROUT statement after you set the variable x to 1500.

To do the equivalent in MATLAB, you'll have to study the manual on serial transmission and formatting. I'm afraid I don't know MATLAB.

Cyrus

04-05-2007, 11:07 AM

Mike Green said...

You can't use ".LOWBYTE" or ".HIGHBYTE" in the actual text of the command. For that matter, the only thing you can have literally is the "!SC". In the case of the bytes that follow the "!SC" or any of the other commands, you need to have the actual 8-bit byte value sent. What you need to send is a sequence of 8 bytes. The first is the numeric value of "!", the second is the numeric value of "S", the third is the numeric value of "C", then two bytes with a numeric value of zero. If you want a servo position of 1500, the next byte is the numeric value of the lower 8 bits of 1500. The byte after that is the numeric value of the upper 8 bits of 1500. Lastly is the number 13 (or $0D or the return character).

The PBasic compiler in compiling a SEROUT statement for a Stamp processor, will do this process for you if you put "!SC",0,0,x.lowbyte,y.highbyte,$0D in the square brackets of a SEROUT statement after you set the variable x to 1500.

To do the equivalent in MATLAB, you'll have to study the manual on serial transmission and formatting. I'm afraid I don't know MATLAB.

Ok, so I need to send a series of 8-bits at a time.

Here is a quick example I will try in matlab to see if it works or not. I can, for instance, give it the input command !SCVER?$0D

That means that I should give it, in binary:

100001-1010011-1000011-1010110-1000101-1010010-0111111-0100101-0110000-1000100

Where the - is for clarity and is equivalent to !SCVER?$0D

Is this what you mean?

Post Edited (Cyrus) : 4/5/2007 5:52:30 PM GMT

Mike Green

04-05-2007, 11:13 AM

Assuming that MATLAB uses C conventions

fprintf(ser,"!SC%c%c%c%c%c",0,0,mod(x,256),fix(x/16),13)

This might work, I'm not sure, but it'd be close.

Cyrus

04-05-2007, 11:17 AM

Ill give your advice a shot Mike,

BTW I edited my post above after you posted. And a BIG THANKS for taking time out to help me! Your a life saver!

Cyrus

04-05-2007, 11:37 AM

I tried it but it did not work.

What does the 'mod' and 'fix' subroutines do?

Cyrus

04-07-2007, 03:04 PM

im using your commands but nothings happening, any thoughts mike?

I am able to ask it the version in matlab....but I cant send it commands.

fprintf(ser,'!SCVER?'); does work

output=fscanf(ser,'%s',ser.BytesAvailable) <-reads the output from the board

But this yields no results...

string=sprintf('!SC%c%c%c%c',0,0,mod(x,256),fix(x/16))

·I assume that your x inside of the mod and fix commands is where I should put in my Pulse value x->1250, for example.

According to matlab:

" MOD··· Modulus after division.

··· MOD(x,y) is x - n.*y where n = floor(x./y) if y ~= 0.· If y is not an

··· integer and the quotient x./y is within roundoff error of an integer,

··· then n is that integer.· By convention, MOD(x,0) is x.· The input

··· x and y must be real arrays of the same size, or real scalars.

··· The statement "x and y are congruent mod m" means mod(x,m) == mod(y,m).

··· MOD(x,y) has the same sign as y while REM(x,y) has the same sign as x.

··· MOD(x,y) and REM(x,y) are equal if x and y have the same sign, but

··· differ by y if x and y have different signs."

"FIX··· Round towards zero.

··· FIX(X) rounds the elements of X to the nearest integers

··· towards zero."

Is Matlabs mod and fix doing the same things as your mod and fix? If not, this might be the problem!

Post Edited (Cyrus) : 4/7/2007 7:10:30 AM GMT

Mike Green

04-07-2007, 10:39 PM

1) sprintf is not the same as fprintf. A zero byte will terminate a string and you need to transmit zero bytes. fprintf should do this properly.

2) FIX throws away the fractional portion of a number and that's what I want to do after dividing by 256. I just want the quotient. The 16 should also be 256 ... I thought I had corrected that.

3) MOD should give the remainder after division (in this case by 256). Essentially, I'm trying to get the lower 8 bits and upper 8 bits of the value for the servo pulse width.

Again, I don't know MATLAB and this isn't a MATLAB support forum. You should get help from your instructor or some kind of MATLAB forum since this is a MATLAB programming problem, not something with the servo controller.

Guzzman

07-17-2007, 06:50 PM

Hi Cyrus,

I'm using the serial version PSC on my COM1 through Matlab. The problems with matlab are device and string handling.

If the COM port isn't set up properly it won't work. I also found out that the fprintf() has problems with the '!', so I use

the sprintf() to generate the string and fwrite() to transmit it.Here is some code I use with our students for setting up the

COM port :

% Delete all instances that are connected to the COM ports

a = instrfind;

delete(a);

clear;

%Connect to the PSC on COM1

ComPort = serial('COM1');

fclose(ComPort);

% setup parameters

set(ComPort,'BaudRate',2400,'Databits',8,'Parity', 'none', 'StopBits',2)

fopen(ComPort);

% create string for the PSC, terminate with $0D

str = sprintf('!SCVER?\r');

% write to PSC

fwrite(ComPort,str);

% read reply string from PCS

str = fscanf(ComPort,'%c',3);

disp(str);

This displays 1.4 in my Matlab window.

To position your servo you should determine the hi and lo byte of the position, in my case servoPos:

servoPos = 300;

chan = 0;

sramp = 0;

% calculate lo and hi byte values

hiByte = floor(servoPos/256);

loByte = servoPos - hiByte * 256;

% display servoPos value

str = sprintf('servoPos = %6d Lo = %3d Hi = %3d', servoPos, loByte, hiByte);

disp(str);

% create string for the PSC, terminate with $0D

str = sprintf('!SC%c%c%c%c\r',chan,sramp,loByte,hiByte);

% write to PSC

fwrite(ComPort,str);

Good luck !