Matlab Text Formatting

This week I provide two example programs to get groups programming the servos and solenoids of the musical instrument project. These programs contain a way for Matlab to write strings of characters (character arrays) to the computer's COM1 serial port so that the servo controller gets the commands. However, some more detailed explanation of the "fprintf" statement, which writes these strings, is provided below.

Remember that you can always type "help fprintf" to Matlab's prompt and it will give you a one-page description of syntax. You can also type "doc fprintf" for more generous documentation.

If you use fprintf with just a string in single quotes, Matlab will print the content on the screen when the program is run:

fprintf('servo controller is on-line.\n');

Note that the two characters "\n" count as a newline character, exactly as if the computer had hit the return key after typing the string. This odd nomenclature is a holdover from the C programming language.

If you need to get input from the user, put a string in single quotes inside the "input" function and it will print out the string as a prompt, storing the user's input in the variable you name (type "help input" or "doc input" for more info):

nsolenoids = input('Enter number of solenoids to test: ');

If the information you need from the user is not a number, but rather a string, put the 's' designation in the second place in the input command:

filename = input('Enter name of file: ', 's');

Sometimes you need to read data from a file or from the serial port. In this case use "fscanf" like this:

stringdata = fscanf(ser, '%s'); % read a line of string data from the serial port

If you need a string typed out to have the contents of a variable in it, use the "%d" symbol as a placeholder for integers, "%f" for real numbers (those with decimals in them), and "%s" for strings:

fprintf('SV%d M0\n', index); % "index" is a variable that counts integers
fprintf('The average is %f\n', mean(alldata)); % "alldata" is an array of numbers
fprintf('The name of the file is %s\n', filename); % "filename" is an array of characters

If the "fprintf" command has a variable that corresponds to an open file (created via "fopen") or to the serial port (created via the "serial" command), then the content is written there instead of on the screen:

outfile = fopen(filename,'w'); % "outfile" holds the coordinates of the open file
fprintf(outfile, '%d %f %s\n', count, mean(alldata), comment); % "comment" is a string array
fprintf(ser,'PS%d\n', yndex);

If you just have a simple string to type out to the screen, you can use the "disp" command:

disp('End of program');

Don't forget to fclose any open files or serial ports before the program finishes:

fclose(ser);

So, putting all this together, if you wanted to read in a string of musical notes and their durations in tenths of a second from a file, you could use something like this:

filename = input('Enter name of file from which to read musical score: ', 's');
infile = fopen(filename, 'r');
scorestring = fscanf(infile,'%s');
n = length(scorestring); % calculate number of characters for later use
notes = scorestring(1:2:n); % assume every other character is a note name
durations = scorestring(2:2:n); % assume every other character is a note duration in 0.1 sec intervals (0.9 sec max)
for index = 1:length(durations)
    if (notes(index) == 'A') fprintf(ser,'PC1 PC2 PC3 PS4\n'); end
    if (notes(index) == 'B') fprintf(ser,'PC1 PC2 PS3 PS4\n'); end
    if (notes(index) == 'C') fprintf(ser,'PC1 PS2 PS3 PS4\n'); end
    if (notes(index) == 'D') fprintf(ser,'PS1 PS2 PS3 PS4\n'); end
    duration = str2num(durations(index)); % convert string digit into number digit
    pause(duration * 0.1); % hold note for corresponding number of seconds
end
fclose(infile); % remember to close the file or it may be locked by the system
fclose(ser); % remember to close the serial port when you are done with it

Other really useful functions for you to check out are the "find" command, which returns the index of every element of an array or matrix that meets some condition, and the "eval" command, which runs whatever Matlab command is in its argument string. Here are some examples:

indicies = find(scorestring >= 'a'); % find indices of all alphabetical characters
notes = scorestring(indicies); % pull out the alphabetical characters themselves and put them in the "notes" string array

inputstring = input('Enter name of file or type 0 to skip: ');
if (inputstring(1) ~= '0')
    infile = fopen(inputstring, 'r');
    fopen(infile);
end
fclose(infile); % remember to close the file when you are done with it

For more information about communicating in Matlab with data acquisition devices, serial ports, etc., visit http://www.swarthmore.edu/NatSci/ceverba1/Class/MatlabDAQprocs.html