AsyncSerial

Author:
Written by Michael Krzyzaniak at Arizona State University's School of Arts, Media + Engineering in Fall of 2012. mkrzyzan@asu.edu
Version:
1.1 beta (November 30th 2012)
Includes:
"ext.h"
"ext_obex.h"

Introduction

     _                           ____            _       _ 
    / \   ___ _   _ _ __   ___  / ___|  ___ _ __(_) __ _| |
   / _ \ / __| | | | '_ \ / __| \___ \ / _ \ '__| |/ _` | |
  / ___ \\__ \ |_| | | | | (__   ___) |  __/ |  | | (_| | |
 /_/   \_\___/\__, |_| |_|\___| |____/ \___|_|  |_|\__,_|_|
              |___/    
 

Discussion

An external object for Max/MSP on Mac OSX that interfaces with serial devices. This is intended to provide more useful functionality than the built-in [serial] object. Namely, [AsyncSerial] listens for incoming data on a separate thread and spits it out whenever it arrives. It does not need to be polled. This is similar to how UDPReceive works. Similar care must be taken when dealing with multithreaded Max-patches. [AsyncSerial] can also have its input buffer flushed, which is necessary when sending commands to a device and awaiting a reply. [AsyncSerial] can also be put in and out of 'canonical' input mode, in which data is only spit out once a newline char '\n' is received, which is useful for parsing text-based replies. [AsyncSerial] also allows users to set VMIN and VTIME, as described in the unix manual, sub verbo 'termios':

man termios

[AsyncSerial] cannot be polled using 'bang', because, depending on VMIN, VTIME and ICANON, that could cause the main thread to hang.

[AsyncSerial] can either output received data as a sequence of bytes, as [serial] does, or as a list of text symbols, which is useful with canonic input processing.

for help using [AsyncSerial] from within Max/MSP, consult async-serial.maxhelp, which should have come with this file.



Groups

standard Max SDK functions

Group members:

asyncSerial_new
asyncSerial_free
asyncSerial_assist

 

private from Max/MSP

Group members:

asyncSerial_write
asyncSerial_read
asyncSerial_listenThread
asyncSerial_signalHandler
asyncSerial_binOut
asyncSerial_asciiOut

 

public to Max/MSP

Group members:

asyncSerial_open
asyncSerial_close
asyncSerial_print
asyncSerial_int
asyncSerial_setBaud
asyncSerial_flush
asyncSerial_listen
asyncSerial_setInputMode
asyncSerial_setOutputMode
asyncSerial_printPorts

Functions

asyncSerial_new
asyncSerial_free
asyncSerial_assist
asyncSerial_open
asyncSerial_close
asyncSerial_print
asyncSerial_int
asyncSerial_setBaud
asyncSerial_flush
asyncSerial_listen
asyncSerial_setInputMode
asyncSerial_setOutputMode
asyncSerial_printPorts
asyncSerial_write
asyncSerial_read
asyncSerial_listenThread
asyncSerial_signalHandler
asyncSerial_binOut
asyncSerial_asciiOut

asyncSerial_new


void* asyncSerial_new (
    t_symbol *s,
    long argc,
    t_atom *argv);  
Parameters
argv

[AsyncSerial] takes two optional arguments which are the name of the serial port to open (eg /dev/cu.usb-serial-1234), and the baud rate. the default baud is 9600, and either arguments can be changed later.

Return Value

the new object

Discussion

create a new object


asyncSerial_free


void asyncSerial_free (
    t_asyncSerial *x);  
Parameters
x

the [AsyncSerial] object to operate upon.

Discussion

destroy object


asyncSerial_assist


void asyncSerial_assist (
    t_asyncSerial *x,
    void *b,
    long m,
    long a,
    char *s);  
Parameters
x

the [AsyncSerial] object to operate upon.

Discussion

show help from with Max/MSP


asyncSerial_open


success_t asyncSerial_open (
    t_asyncSerial *x,
    t_symbol *name);  
Parameters
x

the [AsyncSerial] object to operate upon.

name

the path to the serial port, to open (eg /dev/cu.usb-serial-1234)

Return Value

SUCCESS or FAILURE. upon FAILURE, an error message is posted to the 'Max Window'

Discussion

If there is already a serial port open, close it and wait one second. Then attempt to open the specified port.


asyncSerial_close


void asyncSerial_close (
    t_asyncSerial *x);  
Parameters
x

the [AsyncSerial] object to operate upon.

Discussion

If there is a serial port open, close it and restore its settings so it can be used by another program.


asyncSerial_print


void asyncSerial_print(
    t_asyncSerial *x,
    t_symbol *s,
    long argc,
    t_atom *argv);  
Parameters
x

the [AsyncSerial] object to operate upon.

s

the format string describing the contents of argv

argc

the number of elements in argv

argv

the argument vector

Discussion

Format data as ASCII chars and send it to the serial port.


asyncSerial_int


void asyncSerial_int(
    t_asyncSerial *x,
    long n);  
Parameters
x

the [AsyncSerial] object to operate upon.

n

the data to send

Discussion

Send binary data to the serial device. [AsyncSerial] sends one byte at a time, so this method is intended to receive messages in the range 0 ~ 255 Larger values will be sent in newtork byte order (most significant bit first), in as few bytes are required t encode the entire number. For example 1234 will be sent as [4, 210], because ((4 << 8) & 210) = 1234. Negative values are sent as 2s compliment equivalents.


asyncSerial_setBaud


success_t asyncSerial_setBaud (
    t_asyncSerial *x,
    int baud);  
Parameters
x

the [AsyncSerial] object to operate upon.

baud

the baud rate to use. This method does not perform boundry checking so the user is responsible for passing a meaningful value.

Return Value

SUCCESS or FAILURE. upon FAILURE, an error message is posted to the 'Max Window'

Discussion

Set the baud rate for communication with the currently open serial device, and remember this value so it can be used subsequent calls to "asyncSerial_open". The defaut baud rate for a new object is 9600.


asyncSerial_flush


success_t asyncSerial_flush (
    t_asyncSerial *x);  
Parameters
x

the [AsyncSerial] object to operate upon.

Return Value

SUCCESS or FAILURE. upon FAILURE, an error message is posted to the 'Max Window'

Discussion

Flush the serial receive buffer. This deletes data that has been received by the operating system but not yet spit out by the [AsyncSerial] object.


asyncSerial_listen


success_t asyncSerial_listen (
    t_asyncSerial *x,
    bool shouldListen);  
Parameters
x

the [AsyncSerial] object to operate upon.

shouldListen

true to start listening, false to stop.

Return Value

SUCCESS or FAILURE. upon FAILURE, an error message is posted to the 'Max Window'

Discussion

Start or stop listening asynchronously for incoming data. New objects start listening upon creation.


asyncSerial_setInputMode


success_t asyncSerial_setInputMode(
    t_asyncSerial *x,
    int vtime,
    int vmin,
    bool icanon);  
Parameters
x

the [AsyncSerial] object to operate upon.

vtime

milliseconds

vmin

byte count

icanon

true for canonical input processing, false for non-canonical

Return Value

SUCCESS or FAILURE. upon FAILURE, an error message is posted to the 'Max Window'

Discussion

set the input processing mode. see the UNIX manual sub verbo 'termios' for a more detailed description, and more information about how the paramaters interact.


asyncSerial_setOutputMode


void asyncSerial_setOutputMode(
    t_asyncSerial *x,
    bool isBinary);  
Parameters
x

the [AsyncSerial] object to operate upon.

isBinary

1 for asyncSerial_binOut or 0 for asyncSerial_asciiOut;

Discussion

set the output function to either asyncSerial_binOut or asyncSerial_asciiOut.


asyncSerial_printPorts


void asyncSerial_printPorts(
    t_asyncSerial *x);  
Parameters
x

the [AsyncSerial] object to operate upon.

Discussion

print a list of serial ports to the Max window.


asyncSerial_write


int asyncSerial_write (
    t_asyncSerial *x,
    void *data,
    int numChars);  
Parameters
x

the [AsyncSerial] object to operate upon.

data

a buffer containing data to be sent

numChars

the number of valid bytes in data

Return Value

the number of bytes sucessfully sent to the device

Discussion

send data to the serial device


asyncSerial_read


int asyncSerial_read (
    t_asyncSerial *x,
    void *data,
    int numChars);  
Parameters
x

the [AsyncSerial] object to operate upon.

data

a buffer containing data to be sent

numChars

the number of valid bytes in data

Return Value

the number of bytes sucessfully read from the device

Discussion

read data from the serial device


asyncSerial_listenThread


void* asyncSerial_listenThread (
    void *x);  
Discussion

the main run loop for listening for incoming serial data.


asyncSerial_signalHandler


void asyncSerial_signalHandler(
    int sig);  
Discussion

catch signals sent to the serial listen thread, so that the program does not exit when the tread is killed.


asyncSerial_binOut


void asyncSerial_binOut (
    t_asyncSerial *x,
    void *buffer,
    int numValidBytes);  
Discussion

send received data out of the left outlet as binary data, ie as sequence of chars sent out one at a time. This function is not called directly, but via a pointer that selects the output function.


asyncSerial_asciiOut


void asyncSerial_asciiOut(
    t_asyncSerial *x,
    void *buffer,
    int numValidBytes);  
Parameters
numValidBytes

the total capacity of the buffer must be at least one larger than the number of valid bytes, so that this method can scribble in '\0' if necessary.

Discussion

send received data out of the left outlet as a list of symbols. Input is broken into pieces based on the location of spaces, packed into a list, and sent out. Even numbers are put in the list as symbols, so in Max, [fromsymbol] has to be used to convert them to numbers, if desired. This is particularly useful with canonic input processing. This function is not called directly, but via a pointer that selects the output function.