Matlab?

Is anyone using MATLAB to control the USB-16 controller?

I am using the serial port I/O tools (or, rather, trying to use them) and all I get when sending commands is the lower green LED flashing and the red LED illuminated.

That’s the error signal for a baud rate that’s too high. Are you trying to use Pololu mode (with no blue jumper) or Mini-SSCII mode (with the blue jumper)? It sounds like you are actually sending data to the USB port, which is normally the biggest hurdle, so congratulations!

Can you post your M-File or the line commands you’re trying to use?

-Adam

P.S. What do you intend to do with your 16 servos?

Thanks for the reply. I’m initially trying to get things to work under Mini-SSCII mode, since the command format is more simple.

I’m trying to control 2 motors that will position a calibration microphone in order to measure the frequency responses of an array of loudspeakers.

The test MATLAB code is:


port = ‘COM7’;

serobj = serial(port);
set(serobj, ‘InputBufferSize’, 2048);
set(serobj, ‘BaudRate’, 2400);
set(serobj, ‘DataBits’, 8);
set(serobj, ‘Parity’, ‘none’);
set(serobj, ‘StopBits’, 1);

fopen(serobj);

set(serobj, ‘RecordName’, ‘robot.txt’);
set(serobj, ‘RecordMode’, ‘index’);
set(serobj, ‘RecordDetail’, ‘verbose’);
set(serobj, ‘FlowControl’, ‘hardware’);
record(serobj, ‘on’)

fwrite(serobj, [255, 0, 4]);

fclose(serobj);
delete(serobj);


The recorded output from MATLAB is:


Legend:

  * - An event occurred.
  > - A write operation occurred.
  < - A read operation occurred.
1      Recording on 27-Aug-2007 at 18:08:06.218. Binary data in little endian format.
2      > 3 uchar values.
       ff 00 04 

Assuming that your smiley face with shades was supposed to be an “8),” everything looks okay.

I tried this with a Pololu USB to Serial adapter hooked up to a Pololu Micro Serial Servo Controller (practically the same setup as your USB 16 Controller), and it worked fine, but I had to connect the RTS and CTS pins on the USB to Serial adapter to trick Matlab into thinking I had hardware flow control implemented on the receiving device. I’m not sure how this is handled on the USB 16 Servo Controller (anyone from Pololu care to chyme in?), so I would try your code with ‘FlowControl’ changed from ‘hardware’ to ‘none’.

Let me know if this does it.

-Adam

Conveniently, the flow control question was addressed yesterday in this post:

I’m not sure why any data would be getting through in that case, but I’m still betting that’s at least part of the problem.

-Adam

strange things happen when your code gets parsed into emoticons…

anyhow, thanks for the update. I set flow control to ‘none’, but still get the flashing red LED/solid yellow LED error state. I’m going to try a simple C program and try to determine if the problem is with MATLAB or the board. or me.

Hmm, that light pattern doesn’t match high baud rate error code then…

You might try a serial loop, if you have two free ports (and a null-modem cable, or some wire to connect pin 5 to 5, 3 to 2, and 2 to 3). I ran your Matlab commands again just now out one com port and into a terminal program, and the three hex values show up properly at the correct baud rate.

I’m guessing you have a problem with Matlab, or with your version of Java, which Matlab uses to access serial ports.

-Adam

Hello,

On the USB servo controller, RTS is connected to CTS and DTR is connected to DSR.

The error you are reporting is most likely caused by a framing error or other serial format error that usually occurs as a result of changing baud rates or garbage on the serial line.

Do you have access to an oscilloscope? If so, you can look at what the USB-to-serial adapter on the servo controller is outputting on the logic-level serial input pin.

- Jan

Hi Jan,

Thanks for the tip. I’ll check the board with a 'scope and see what I find. Anything in particular to look for? It might be that an error occurs when MATLAB specifies the serial port baud rate; I’ll try setting the baud rate in the system to match the setting that MATLAB specifies.

One other question: I’m using the GWS “sail winch” servo. I’m assuming that the brown wire is GND, red is +5V and orange is the data line. is this correct? Also, how much current does this servo typically draw?

Thanks,
Sharad

I think this was the problem - the system was setting the serial port to 9600 baud and MATLAB was setting it to 2400, and things got scrambled somewhere along the way. I’ll play around with it once I sort out the power supply issues (I’m using an old PC power supply that is a bit flaky) sorted.

Moral of the story: set the baud rate using the control panel and use that baud rate within MATLAB.

~Sharad

hello

first of all,i beg your pardon for my english(i’m italian),i’ll try to be clearer as possible.
i’m tring to write some functions in matlab for the commands of the mssc.
actually my problem is about command 5:set neutral.
the default value is 3000,but if i would change it,which is the range?
i mean, is it the same of absolute position 500-5500 or not?
if it’s not,which are the possible values?

thanks

Buon Giorno!
Your English is excellent, and certainly better than my high school Italian.

I don’t usually use this feature, but I’m pretty sure that the neutral position range is 500 to 5500, just like the absolute position range. The neutral position isn’t affected by the other settings: direction and range, so you should choose it using the absolute position command, command 4, and then specify it using that same absolute position and command 5.

-Adam

The neutral command is only for use with the 7-bit and 8-bit commands for low-performance microcontrollers. If you’re working on a PC, you should just use the absolute position command, and have a notion of neutral in your software. That way, if you have to swap servos, you don’t have to go through adjusting every position command for the new servo.

- Jan

thanks both of you!
i’ll try it in the next days. i hope everything will work.

bye

Hello-

I was wondering if anyone was getting “timeout” errors with matlab’s serial.fwrite command.

I’ve got this for loop that acquires data from an inertial measurement unit, does some PID calculations, then spits the output to the micro servo controller im using in ssc2 mode. It worked for 1000 iterations yesterday, several times actually, but now I’m getting these errors about 25-40 interations into the for loop… matlab just freezes up @ 25-40 iterations, and then 15s later spits out the “timeout with fwrite” error… very strange to me… anyone have any ideas?

Thanks a lot!!!
-pat

Matlab is quite finicky what with the serial ports, but that’s one error I haven’t seen before. How often are you trying to write to this port, and are you closing it in between?

Actually, could you just post your code?

-Adam

for i = 1:n
    [packet, count] = fgetl(IMU);
    while abs(count-48) > 1                     % If BytesRead(count) < BytesToRead (48), read again 
        [packet, count] = fgetl(IMU);
    end
    C = sscanf(packet, '%*3s %3i %3i %3i %3i %3i %3i %3i %3i %3i');  % Translate da data
    row = C';                                                        % Transpose da data
    data(i,:) = cat(2, row);                                         % Concatenate da data
                                                                     % Parse da data
    Yawz        = data*[0;0;0;0;1;0;0;0;0];    % Da Yaw : angular Z-rate 
    Yaw_ref     = data*[0;0;0;0;0;1;0;0;0];    % Da Yaw's electrical reference 
    Yaw   = (Yawz - Yaw_ref);                  % Actual Yaw = [Yaw] - [Yaw Reference]
    
    % ##### PIDness: #####
    k = i-1;
    cYaw = 0;                                        % Control Yaw Value :  no rotation.
    eYaw = Yaw - cYaw;                               % Error Signal
    pYaw = eYaw;                                     % Proportioned (Scaled: Error Velocity Error)
    iYaw = cumtrapz(eYaw,1)/i;                       % Calculated (Integrated: Error Z-Heading)
    dYaw= (eYaw-last_eYaw)/(.5);               % Calculated (Diferentiated: Acceleration Error)
    oYaw(i) = kp*eYaw(i) + ki*iYaw(i) + kd*dYaw(i);  % Output 
    last_eYaw = eYaw;
    act = round(127+oYaw(i));
    
    servout(SSC,0,act);
    
    clf('reset');
    hold on;
    plot(Yaw, 'b');
        plot(iYaw,'m','LineWidth',2);
        plot(dYaw, 'r','LineWidth',2);
        plot(pYaw, 'g','LineWidth',2);
        plot(oYaw, 'k','LineWidth',2);
        axis([0 i -512 512]); 
        title('Yaw', 'FontWeight', 'bold'); 
        grid on;
    drawnow
end

this^ is the loop that calls “servout” which is a function I put together to simplify the commands… here’s the code for the servout function:

function servout(obj, servoID, K)
% servoID = servo to be served
% K = value from -127 to 127 indicating the min or max position of da jawn
% 
x = 127+(K);
fwrite(obj, 255,'uint8');
fwrite(obj, servoID,'uint8');
fwrite(obj, x,'uint8');

i tried embedding the function code inside the loop itself and got same error. I’m about to give it another shot- I still don’t understand why it would work all day then stop working vbecause of this “timeout error” with fwrite…

i have a vid of it working, but i dunno how to post it…

-pat

That all looks fine to me, it sounds like there’s some sort of conflict between Matlab and the OS (Windows?) serial port drivers. I’d be interested to see your port setup code.

My first thought would be to reduce the number of individual file write commands (and thereby calls to the port drivers) per cycle by putting your data bytes in an array rather than sending them out individually:

fwrite(obj, [255,servoID,x],'uint8');

You probably want this running as fast as your computer can handle, but if you keep having this problem you might try adding a pause(seconds); command to your loop to see if Windows just needs time to catch up. If this helps, but you don’t want to leave the delay (and assuming you are using Windows) you can try setting Matlab’s processing priority higher by ctrl+alt+delete-ing to the task manager, going to the “processes” tab, right-clicking on Matlab, then “Set Priority”, then “High” or “Real-Time”. It’s a little risky, but basically this will make Windows give Matlab’s processes top priority over things like checking for updates, scanning for viruses, even moving the mouse. A friend in another lab was having freeze-up type trouble reading serial data really fast into LabView last week, and setting the priority up high solved it.

You could also try switching over to Pololu mode to use higher baud rates. There’s example code for the absolute position command in this thread.

Any luck?

-Adam

damn! you’re full of ridiculously good ideas. thanks for the help man, I’ll try upping the priority of matlab first… if i didn’t already, I gotta lot on my plate today but I’ll let you know how it turns out!

thanks again!!
-pat