diff --git a/source/cr.boardin/cr.boardin.c b/source/cr.boardin/cr.boardin.c index 46597554f43d75dae98a5ead9ca98f65f6672208..ea6082ce4568b47e03bae6f0c7a0fea5ef74eac8 100755 --- a/source/cr.boardin/cr.boardin.c +++ b/source/cr.boardin/cr.boardin.c @@ -1,7 +1,9 @@ -/** - @file - boardin - a max object (Arduino UNO board inputs) - */ +// +// @file +// boardin - a max object (Arduino UNO board reader) +// +// written by Orly Natan, Creative Robotics Lab +// University Of New South Wales (UNSW). // Firmata-for-Max Library headers @@ -23,26 +25,36 @@ typedef struct boardin // selected pins to read void **outlets; - long pinsCount; //todo - remove? should be the sum of input attributes + long pinsCount; long pinsArray[TOTAL_IN_PINS]; long valuesArray[TOTAL_IN_PINS]; long modesArray[TOTAL_IN_PINS]; + int port_index; // boardin attributes: t_symbol *att_portname; - t_symbol *att_baudrate; + t_symbol *att_baudrate; // Sets the data rate in bits per second (baud) for serial data transmission. + // For communicating with the computer, one of these rates: 300, 600, 1200, + // 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. long att_digitalPins[TOTAL_IN_PINS], digitalPinsCount; long att_analogPins[TOTAL_IN_PINS], analogPinsCount; + int isopen; + } t_boardin; ///////////////////////// function prototypes -//// standard set +//// Max standard set void *boardin_new(t_symbol *s, long argc, t_atom *argv); void boardin_free(t_boardin *x); void boardin_assist(t_boardin *x, void *b, long m, long a, char *s); -void boardin_print(t_boardin *x); +void boardin_ports(t_boardin *x); +void boardin_pins(t_boardin *x); +void boardin_config(t_boardin *x); void boardin_bang(t_boardin *x); +void boardin_test(t_boardin *x); +void boardin_open(t_boardin *x); +void boardin_close(t_boardin *x); //privates void boardin_printAvailPorts(t_boardin *x); @@ -52,15 +64,9 @@ int boardin_getBaudRate(t_boardin *x); bool boardin_pinNumAlreadyExists(t_boardin *x, int pin); // todo - check with boardout pins (handle duplicates)? void boardin_init(t_boardin *x); void boardin_connectBoard(t_boardin *x, int len, int *pins, int *modes); -int boardin_pinDigitalRange(int pin); -int boardin_pinAnalogRange(int pin); - -//internals -t_max_err boardout_att_portname_get(t_boardin *x, t_object *attr, long argc, t_atom *argv); -t_max_err boardout_att_portname_set(t_boardin *x, t_object *attr, long argc, t_atom *argv); -t_max_err boardin_digitalPins_set(t_boardin *x, t_object *attr, long argc, t_atom *argv); // Disable editing attribute in Inspector - restrict to Read Only! -t_max_err boardin_analogPins_set(t_boardin *x, t_object *attr, long argc, t_atom *argv); // Disable editing attribute in Inspector - restrict to Read Only! - +int boardin_pinDigitalRange(int pin); +int boardin_pinAnalogRange(int pin); +void boardin_pinNumConvert(int pin, char *str); //////////////////////// global class pointer variable void *boardin_class; @@ -75,68 +81,45 @@ void ext_main(void *r) /* you CAN'T call this from the patcher */ class_addmethod(c, (method)boardin_assist, "assist", A_CANT, 0); - class_addmethod(c, (method)boardin_print, "print", 0); + class_addmethod(c, (method)boardin_ports, "ports", 0); + class_addmethod(c, (method)boardin_pins, "pins", 0); + class_addmethod(c, (method)boardin_config, "config", 0); class_addmethod(c, (method)boardin_bang, "bang", 0); - + class_addmethod(c, (method)boardin_test, "test", 0); + class_addmethod(c, (method)boardin_open, "open", 0); + class_addmethod(c, (method)boardin_close, "close", 0); + class_register(CLASS_BOX, c); /* CLASS_NOBOX */ boardin_class = c; - - // set attributes - - CLASS_ATTR_SYM(c, "portname", 0, t_boardin, att_portname); - CLASS_ATTR_LABEL(c, "portname", 0, "Serial Port"); - //CLASS_ATTR_ENUM(c, "portname", 0, ""); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "portname", NULL, NULL); - - //char* baudratestr = "\"300\" \"1200\" \"2400\" \"4800\" \"9600\" \"14400\" \"19200\" \"28800\" \"38400\" \"57600\" \"115200\""; - CLASS_ATTR_SYM(c, "baud", 0, t_boardin, att_baudrate); - CLASS_ATTR_LABEL(c, "baud", 0, "Baud Rate"); - //CLASS_ATTR_ENUM(c, "baud", 0, baudratestr); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "baud", NULL /*boardin_att_baudrate_get*/, NULL /*boardin_att_baudrate_set*/); - - // pins modes attributes (for the inspector window, read only!) - CLASS_ATTR_LONG_VARSIZE(c, "digitalPins", 0, t_boardin, att_digitalPins, digitalPinsCount, TOTAL_IN_PINS); - CLASS_ATTR_LABEL(c, "digitalPins", 0, "Digital Pins"); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "digitalPins", NULL /*boardout_digitalPins_get*/, boardin_digitalPins_set); - - CLASS_ATTR_LONG_VARSIZE(c, "analogPins", 0, t_boardin, att_analogPins, analogPinsCount, TOTAL_IN_PINS); - CLASS_ATTR_LABEL(c, "analogPins", 0, "Analog Pins"); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "analogPins", NULL /*boardout_analogPins_get*/, boardin_analogPins_set); - - // attributes order of appearance in the inspector - CLASS_ATTR_ORDER(c, "portname", 0, "1"); - CLASS_ATTR_ORDER(c, "baud", 0, "2"); - CLASS_ATTR_ORDER(c, "digitalPins", 0, "3"); - CLASS_ATTR_ORDER(c, "analogPins", 0, "4"); - post("Arduino UNO boardin object created (Reader)."); } void boardin_assist(t_boardin *x, void *b, long m, long index, char *s) { int pin = x->pinsArray[index]; + char *str; + + if(pin<14) str = ""; + else { + str = "A"; + pin -= 14; + // analog pins are numbered as: + // Arduino: A0-A5 + // Firmata: (#14-#19) + } if (m == ASSIST_OUTLET) { // outlet messages switch(x->modesArray[index]) { case MODE_INPUT: - sprintf(s, "pin D%d mode DIGITAL", pin); + sprintf(s, "pin %s%d mode DIGITAL values {0,1}", str, pin); break; case MODE_ANALOG: - pin -= 14; - // analog pins are numbered as: - // Max: 20-25 - // Arduino: A0-A5 - // Firmata: (#14-#19) - sprintf(s, "pin %d (A%d) mode ANALOG", pin+20, pin); + sprintf(s, "pin A%d mode ANALOG range [0-1023]", pin); break; default: - sprintf(s, "pin %d is INVALID", pin); + sprintf(s, "pin %s%d is INVALID", str, pin); } } @@ -147,83 +130,17 @@ void boardin_assist(t_boardin *x, void *b, long m, long index, char *s) } void boardin_free(t_boardin *x) { - - if(x == NULL) return; - - if(x->att_portname) { - - if(x->att_portname->s_thing) { - board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); - if(mgr->board_in != NULL) { // && mgr->board_in == x->board_ob) { - - //release the boardin connection - //post("disconnecting boardin object"); //debug - mgr->board_in = NULL; - int val = maxclient_disconnect(x->board_ob); // kill listener - if(val == -1) { - post("error disconnecting, %s", x->board_ob->err_msg); - return; - } - //debug - //else { - // post("boardin disconnected"); - //} - } - //debug - //else { - // post("error, boardin wasn't found"); - //} - - if(mgr->board_out == NULL) { - - // no writer board is connected, release the port altogether - post("closing the port"); //debug - int val = maxclient_shutdown(x->board_ob); // close port - if(val == -1) { - post("error shutting down, %s", x->board_ob->err_msg); - return; - } - //debug - //else { - // post("boardin shut down"); - //} - x->att_portname->s_thing = NULL; - free(mgr); - //mgr->board = NULL; - //mgr->board_in = NULL; - } - //debug - //else { - // post("boardout object found"); - //} - } - - //debug - //else { - //post("port is not in use by any other board object"); - //} - } - - //debug - //else { - //post("no portname found"); - //} - - /* - if (x->board_ob != NULL) { - free(x->board_ob); - post("board object deleted"); - }*/ + boardin_close(x); + // free allocated outlets if (x->outlets) { free(x->outlets); } - //post("boardin object deleted"); //debug + if (DEBUG) post("boardin object deleted."); //debug } - void *boardin_new(t_symbol *s, long argc, t_atom *argv) { t_boardin *x = (t_boardin *)object_alloc(boardin_class); @@ -237,44 +154,21 @@ void *boardin_new(t_symbol *s, long argc, t_atom *argv) boardin_init(x); // todo - remove, for debug x->board_ob = NULL; + x->port_index = -1; // parse input arguments to set up the board configuration if (boardin_parseArgs(x, argc, argv) == -1) { //Error - Invalid arguments - object_error((t_object *)x, "Boardin args are invalid, could not create new boardin object."); + object_error((t_object *)x, "Invalid args, could not create new boardin object."); //object_free(x); return (x); } // debug: - //if(x->att_portname && x->att_baudrate) { - // object_post((t_object *)x, "port name: %s\t rate: %d", x->att_portname->s_name, atoi(x->att_baudrate->s_name)); - //} - - // setup pins configuration as requested - int len_config = x->digitalPinsCount + x->analogPinsCount; - int pins[len_config], modes[len_config]; - - int len = 0; - // digital pins - for(int i=0; idigitalPinsCount; ++i) { - pins[len] = x->att_digitalPins[i]; - modes[len] = MODE_INPUT; - len++; - } - - // analog pins - for(int i=0; ianalogPinsCount; ++i) { - pins[len] = x->att_analogPins[i] + 14; // analog pins are numbered 14-19 corresponding to A0-A5 - modes[len] = MODE_ANALOG; - len++; - } - - - // connect to the board, and start listening thread - if(x->att_portname) - boardin_connectBoard(x, len, pins, modes); - + //if (DEBUG) + // if(x->att_portname && x->att_baudrate) { + // object_post((t_object *)x, "port name: %s\t rate: %d", x->att_portname->s_name, atoi(x->att_baudrate->s_name)); + // } // create int outlets from right to left (highest-right to 1-left) x->outlets = (void **)malloc(x->pinsCount*sizeof(void *)); @@ -294,10 +188,8 @@ void *boardin_new(t_symbol *s, long argc, t_atom *argv) } int boardin_parseArgs(t_boardin *x, long argc, t_atom *argv) { - - // get updated list of available ports - char *ports_avail[MAX_PORTS]; - int num_ports = serial_portlist(ports_avail, MAX_PORTS); + + x->port_index = -1; // set baud rate to default char str[20]; @@ -314,26 +206,22 @@ int boardin_parseArgs(t_boardin *x, long argc, t_atom *argv) { int index = portCh[0]-'a'; //object_post((t_object *)x, "port index: %d", index); - if (index >= 0 && index < num_ports) { - //strncpy(x->portname, ports_avail[index], MAX_PORT_NAME); - x->att_portname = gensym(ports_avail[index]); - if(x->att_portname->s_thing == NULL) { - // the port is not in use by other boardin/out objects - board_mgr_t *mgr = (board_mgr_t*)malloc(sizeof(board_mgr_t)); //newPortMgr(IN_BOARD); - mgr->board_out = NULL; - mgr->board_in = NULL; - mgr->board = NULL; - x->att_portname->s_thing = (t_object*)mgr; - } - //x->att_portname->s_thing = NULL; //TODO add ref to the serial port - //object_post((t_object *)x, "port name is: (%s)", x->att_portname->s_name); // debug - //object_post((t_object *)x, "port thing is: (%s)", x->att_portname->s_thing); //debug + if (index >= 0 && index <= 'z'-'a') { + x->port_index = index; i = 1; } + // check if the baud rate was entered as input + if((i)< argc && (argv+i)->a_type == A_LONG) { + long val = atom_getlong(argv+i); + sprintf(str, "%ld", val); + x->att_baudrate = gensym(str); + i = 2; + } + } // Parse DIGITAL and ANALOG pins lists - bool analogFound = false, digitalFound = false; + bool analogFound = false, digitalFound = false, rangeFound = false; x->pinsCount = 0; x->analogPinsCount = 0; x->digitalPinsCount = 0; @@ -349,30 +237,75 @@ int boardin_parseArgs(t_boardin *x, long argc, t_atom *argv) { //post("Found DIGITAL"); digitalFound = true; analogFound = false; + rangeFound = false; } // if symbol is analog else if( ! strcmp_case_insensitive(s->s_name, "@analog")) { //post("Found ANALOG"); analogFound = true; digitalFound = false; + rangeFound = false; } - // if symbol is baud - else if( ! strcmp_case_insensitive(s->s_name, "@baud")) { - //post("Found BAUD"); - digitalFound = false; + // if symbol is range + else if( ! strcmp_case_insensitive(s->s_name, "@range")) { + //post("Found RANGE"); + rangeFound = true; analogFound = false; - // check if the baud rate was entered as input - if((i+1)< argc && (argv+i+1)->a_type == A_LONG) { - // move to the next input atom for the baud rate - i++; - //x->baudrate = atom_getlong(argv+i); - } + digitalFound = false; + } + else if( ! strcmp_case_insensitive(s->s_name, "A0")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 14; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A1")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 15; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A2")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 16; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A3")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 17; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A4")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 18; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A5")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 19; + argv[i] = a[0]; + --i; } - else { // otherwise, unknown attribute symbol digitalFound = false; analogFound = false; + rangeFound = false; // error object_error((t_object *)x, "forbidden argument %s", s->s_name); //return -1; @@ -386,19 +319,14 @@ int boardin_parseArgs(t_boardin *x, long argc, t_atom *argv) { if (analogFound) { if (!boardin_pinAnalogRange(pin)) { // error - object_error((t_object *)x, "Invalid pin number %d, analog pins range [20-25]", pin); + object_error((t_object *)x, "Invalid pin number %d, analog pins range [A0-A5]", pin); return 0; } - - // if the pin is analog, then substruct PIN_OFFSET - // Digital pins [D0-D13] are numbered 0-13 indexed as 0-13 in Firmata - // Analog pins [A0-A5] are numbered 20-25 indexed as 14-19 in Firmata - pin -= PIN_OFFSET; } if (digitalFound && !boardin_pinDigitalRange(pin)) { // error - object_error((t_object *)x, "Invalid pin number %d, digital pins range [0-13]", pin); + object_error((t_object *)x, "Invalid pin number %d, digital pins range [2-13, A0-A5]", pin); return 0; } @@ -470,10 +398,250 @@ void boardin_bang(t_boardin *x){ } } -void boardin_print(t_boardin *x){ +void boardin_ports(t_boardin *x){ boardin_printAvailPorts(x); } +void boardin_pins(t_boardin *x) { + + char str[4000], str_pin[10]; + long count, *arr; + + str[0] = '\0'; + + // Digital pins + count = x->digitalPinsCount; + arr = x->att_digitalPins; + if(count) { + str[0] = '\0'; + strcat(str, "Digital pins: "); + for (long i=0; ianalogPinsCount; + arr = x->att_analogPins; + if(count) { + str[0] = '\0'; + strcat(str, "Analog pins: "); + for (long i=0; iboard_ob) { + object_post((t_object *)x, "test: board is not connected."); + return; + } + + if ( ! x->board_ob->isBoardReady) { + object_post((t_object *)x, "test: board is not ready for communication."); + return; + } + + if( ! x->isopen) { + object_post((t_object *)x, "test: board is not connected."); + return; + } + object_post((t_object *)x, "test: board is connected."); + + char *firmware = firmataclient_getfirmware(x->board_ob); + object_post((t_object *)x, "test: firmware version %s.", firmware); + object_post((t_object *)x, "test: board is ready for communication."); + + object_post((t_object *)x, "test: onboard LED will now blink 3 times."); + firmataclient_blink(x->board_ob); + + object_post((t_object *)x, "test: Done."); +} + +void boardin_open(t_boardin *x){ + if (x == NULL) return; + + if(x->isopen) { + object_post((t_object *)x, "board is already connected."); + return; + } + + if ( ! x->att_baudrate) { + // set baud rate to default + char str[20]; + sprintf(str, "%d", DEFAUTLT_BAUD); + x->att_baudrate = gensym(str); + } + if(DEBUG) object_post((t_object *)x, "baud rate %s.", x->att_baudrate->s_name); + + // get updated list of available ports + char *ports_avail[MAX_PORTS]; + int num_ports = serial_portlist(ports_avail, MAX_PORTS); + + if (x->port_index == -1) { + object_error((t_object *)x, "port not selected."); + return; + } + if(DEBUG) object_post((t_object *)x, "index of port selected %d.", x->port_index); + + if (x->port_index < 0 || x->port_index >= num_ports) { + object_error((t_object *)x, "port selected is out of bounds of available ports."); + if(DEBUG) object_error((t_object *)x, "index of port selected %d.", x->port_index); + return; + } + + // select the port + x->att_portname = gensym(ports_avail[x->port_index]); + if(x->att_portname == NULL) { + if(DEBUG) object_error((t_object *)x, "port can't be found."); + return; + } + if(DEBUG) object_post((t_object *)x, "port selected %s to open", x->att_portname->s_name); // debug + + // check for other connections + if(x->att_portname->s_thing == NULL) { + + // the port is not in use by other boardin/out objects + if(DEBUG) object_post((t_object *)x, "port has no other connections, %s", x->att_portname->s_name); // debug + board_mgr_t *mgr = (board_mgr_t*)malloc(sizeof(board_mgr_t)); + if(mgr == NULL) { + object_error((t_object *)x, "port can't be opened, Max can't allocate memory."); + return; + } + mgr->board_out = NULL; + mgr->board_in = NULL; + mgr->board = NULL; + x->att_portname->s_thing = (t_object*)mgr; + } + else { + // the port is in use by another boardin/out object + if(DEBUG) object_post((t_object *)x, "OK, port has another connection, %s", x->att_portname->s_name); // debug + } + + + // setup pins configuration as requested + int len_config = x->digitalPinsCount + x->analogPinsCount; + int pins[len_config], modes[len_config]; + + int len = 0; + // digital pins + for(int i=0; idigitalPinsCount; ++i) { + pins[len] = x->att_digitalPins[i]; + modes[len] = MODE_INPUT; + len++; + } + // analog pins + for(int i=0; ianalogPinsCount; ++i) { + pins[len] = x->att_analogPins[i]; // + 14; // analog pins are numbered 14-19 corresponding to A0-A5 + modes[len] = MODE_ANALOG; + len++; + } + + //if(DEBUG) object_post((t_object *)x, "%d pins allocated", len); // debug + //if (DEBUG) { + // for(int i=0; iisopen) { + object_post((t_object *)x, "close: board was not connected."); + return; + } + + if ( ! x->att_portname) { + object_post((t_object *)x, "close: no port selected."); + return; + } + + if(x->att_portname->s_thing == NULL) { + object_post((t_object *)x, "close: board was not connected."); + return; + } + + board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); + if(mgr->board_in == NULL) { + object_post((t_object *)x, "close: board was not connected."); + return; + } + + int err = maxclient_disconnect(x->board_ob); // kill listener + if(err == -1) { + object_error((t_object *)x, "close: error disconnecting"); + if (x->board_ob) object_error((t_object *)x, "%s", x->board_ob->err_msg); + return; + } + + x->isopen = 0; + mgr->board_in = NULL; + object_post((t_object *)x, "close: diconnected from board."); + + if(mgr->board_out == NULL) { + + // no writer board is connected, release the port altogether + err = maxclient_shutdown(x->board_ob); // close port + if(err == -1) { + object_error((t_object *)x, "close: error shutting serial port down"); + if (x->board_ob) object_error((t_object *)x, "%s", x->board_ob->err_msg); + return; + } + + if (DEBUG) object_post((t_object *)x, "close: port %s was shut down", x->att_portname->s_name); + + x->att_portname->s_thing = NULL; + maxclient_freemgr(mgr); + } + + return; +} + void boardin_printAvailPorts(t_boardin *x) { char *ports_avail[MAX_PORTS]; @@ -519,12 +687,13 @@ void boardin_init(t_boardin *x) { x->att_baudrate = NULL; x->digitalPinsCount = 0; x->analogPinsCount = 0; + x->isopen = 0; } - void boardin_connectBoard(t_boardin *x, int len, int *pins, int *modes) { if(!x || !x->att_portname || !x->att_portname->s_thing) return; + if( !pins || !modes) return; // search symbol port_name. if found, then board is already connected to by a boardout @@ -533,17 +702,52 @@ void boardin_connectBoard(t_boardin *x, int len, int *pins, int *modes) { // the pins (read) configuration. board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); + if (mgr == NULL) { + if (DEBUG) object_error((t_object *)x, "can't connect to port, internal error"); + return; + } + if(mgr->board_in != NULL) { - // error - there is already another boardin object connected - object_error((t_object *)x, "connect: port name: %s is already occupied with another boardin object!", x->att_portname->s_name); + object_error((t_object *)x, "open: port %s is already occupied with another boardin (reader) object!", x->att_portname->s_name); return; } else if(mgr->board_out != NULL) { - - //object_post((t_object *)x, "connect: boardout found"); // debug - //object_post((t_object *)x, "x->board_object=%s", x->board_ob); // debug + + if (DEBUG) object_post((t_object *)x, "open: port %s is connected to a Writer (okay)", x->att_portname->s_name); // debug + + if(mgr->board == NULL) { + object_error((t_object *)x, "open: internal error. board can't be reached on %s.", x->att_portname->s_name); + return; + } + + // check if there is any configuration conflict + if(mgr->board == NULL) { + object_error((t_object *)x, "open: can't connect the board. internal error"); + return; + } + + // check baud rate conflict (between existing and the new board) + //if(x->att_baudrate) { + // long current_rate = atol(x->att_baudrate->s_name); + // if(mgr->board->port) { + // long port_rate = mgr->board->port->baud_rate; + // if(port_rate != current_rate) { + // object_error((t_object *)x, "open: can't connect the board, baud rate conflict. "); + // object_error((t_object *)x, "port baud rate %ld, but baud %ld requested. ", mgr->board->port->baud_rate, current_rate); + // return; + // } + // } + //} + + // check if there is any configuration conflict + if (maxclient_verifyconfig(mgr->board, len, pins, modes)) { + object_error((t_object *)x, "open: can't connect the board. "); + object_error((t_object *)x, "%s", mgr->board->err_msg); + return; + } + x->board_ob = mgr->board; mgr->board_in = x; } @@ -553,51 +757,70 @@ void boardin_connectBoard(t_boardin *x, int len, int *pins, int *modes) { // requested port is not connected to by any other board object, then // create a new Arduino board object, initialise and connect to (serial) port - //object_post((t_object *)x, "NEW BOARD IS BEING CREATED"); // debug + if (DEBUG) object_post((t_object *)x, "open: port is not connected to any other board yet, establishing a new connection."); // debug char err_return[4000]; - x->board_ob = maxclient_newboard(x->att_portname->s_name, atoi(x->att_baudrate->s_name), err_return); - // verify succeful memory allocation + long rate = x->att_baudrate? atol(x->att_baudrate->s_name) : DEFAUTLT_BAUD; + x->board_ob = maxclient_newboard(x->att_portname->s_name, rate, err_return); if(x->board_ob == NULL) { // error - there is already another boardin object connected - object_error((t_object *)x, "Max could not create new boardin object."); + object_error((t_object *)x, "open: Max could not create new boardin object."); object_error((t_object *)x, "%s", err_return); return; } // debug //else { - // post("maxclient_newboard succeedded"); + //if (DEBUG) post("maxclient_newboard succeedded"); //} mgr->board = x->board_ob; mgr->board_in = x; } - //object_post((t_object *)x, "CONNECTING TO BOARD"); //debug - // start a new listener thread and // set board configuration (i.e., pin modes) as requested - int result = maxclient_connect(x->board_ob, len, pins, modes, IN_BOARD); - if( result != 0) { - object_error((t_object *)x, "Boardin couldn't connect to board."); + int err = maxclient_connect(x->board_ob, len, pins, modes, IN_BOARD); + if(err) { + object_error((t_object *)x, "open: Boardin couldn't connect to board."); + if(x->board_ob) object_error((t_object *)x, "%s", x->board_ob->err_msg); return; } // debug - //else { - // object_post((t_object *)x, "Listening thread started."); - //} + //if (DEBUG) object_post((t_object *)x, "Listening thread started."); + + + x->isopen = 1; + object_post((t_object *)x, "open: boardin is now connected."); } int boardin_pinDigitalRange(int pin) { - return ((pin < 14 && pin >=0)? 1 : 0); + return ((pin < 20 && pin >=2)? 1 : 0); } int boardin_pinAnalogRange(int pin) { - // Analog pins range: 20 [A0] .. 25 [A5] - return ((pin < 26 && pin >=20)? 1 : 0); + // Analog pins range: 14 [A0] .. 19 [A5] + return ((pin < 20 && pin >13)? 1 : 0); } +void boardin_pinNumConvert(int pin, char *str) { + if( ! str) { + str = ""; + return; + } + if(pin < 14) sprintf(str, "%d", pin); + else sprintf(str, "A%d", pin-14); + return; +} + + +// +// The Arduino board contains a 6 channel, 10-bit analog to digital converter. +// This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. +// 10 bits, pow(2, 10)=1024. +// + + diff --git a/source/cr.boardin/cr.boardin.xcodeproj/project.pbxproj b/source/cr.boardin/cr.boardin.xcodeproj/project.pbxproj index 3c2b360c451b53869ba3d1975beb587ffb9b4019..c1849b11a89e87749713a0e49623b507051e26af 100755 --- a/source/cr.boardin/cr.boardin.xcodeproj/project.pbxproj +++ b/source/cr.boardin/cr.boardin.xcodeproj/project.pbxproj @@ -9,24 +9,24 @@ /* Begin PBXBuildFile section */ 0C3533DA1F87027000671127 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C3533D91F87027000671127 /* IOKit.framework */; }; 0C3533DC1F87027E00671127 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C3533DB1F87027E00671127 /* CoreFoundation.framework */; }; - 0C74099F1FC65F6600259E45 /* firmatalib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C74099B1FC65F6600259E45 /* firmatalib.h */; }; - 0C7409A01FC65F6600259E45 /* firmatalib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C74099C1FC65F6600259E45 /* firmatalib.c */; }; - 0C7409A11FC65F6600259E45 /* serial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C74099D1FC65F6600259E45 /* serial.h */; }; - 0C7409A21FC65F6600259E45 /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C74099E1FC65F6600259E45 /* serial.c */; }; - 0C7409B11FC6620F00259E45 /* maxlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C7409AF1FC6620F00259E45 /* maxlib.h */; }; - 0C7409B21FC6620F00259E45 /* maxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C7409B01FC6620F00259E45 /* maxlib.c */; }; + 0CDDA8BF2022D13700358057 /* firmatalib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8B92022D13700358057 /* firmatalib.h */; }; + 0CDDA8C02022D13700358057 /* firmatalib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8BA2022D13700358057 /* firmatalib.c */; }; + 0CDDA8C12022D13700358057 /* maxlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8BB2022D13700358057 /* maxlib.h */; }; + 0CDDA8C22022D13700358057 /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8BC2022D13700358057 /* serial.c */; }; + 0CDDA8C32022D13700358057 /* serial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8BD2022D13700358057 /* serial.h */; }; + 0CDDA8C42022D13700358057 /* maxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8BE2022D13700358057 /* maxlib.c */; }; 22CF11AE0EE9A8840054F513 /* cr.boardin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22CF11AD0EE9A8840054F513 /* cr.boardin.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 0C3533D91F87027000671127 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 0C3533DB1F87027E00671127 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 0C74099B1FC65F6600259E45 /* firmatalib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = firmatalib.h; path = /Users/orly/Documents/MyProjects/FirmataClient/firmatalib.h; sourceTree = ""; }; - 0C74099C1FC65F6600259E45 /* firmatalib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = firmatalib.c; path = /Users/orly/Documents/MyProjects/FirmataClient/firmatalib.c; sourceTree = ""; }; - 0C74099D1FC65F6600259E45 /* serial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serial.h; path = /Users/orly/Documents/MyProjects/FirmataClient/serial.h; sourceTree = ""; }; - 0C74099E1FC65F6600259E45 /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = serial.c; path = /Users/orly/Documents/MyProjects/FirmataClient/serial.c; sourceTree = ""; }; - 0C7409AF1FC6620F00259E45 /* maxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = maxlib.h; path = /Users/orly/Documents/MyProjects/FirmataClient/maxlib.h; sourceTree = ""; }; - 0C7409B01FC6620F00259E45 /* maxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = maxlib.c; path = /Users/orly/Documents/MyProjects/FirmataClient/maxlib.c; sourceTree = ""; }; + 0CDDA8B92022D13700358057 /* firmatalib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = firmatalib.h; path = ../FirmataClient/firmatalib.h; sourceTree = ""; }; + 0CDDA8BA2022D13700358057 /* firmatalib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = firmatalib.c; path = ../FirmataClient/firmatalib.c; sourceTree = ""; }; + 0CDDA8BB2022D13700358057 /* maxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = maxlib.h; path = ../FirmataClient/maxlib.h; sourceTree = ""; }; + 0CDDA8BC2022D13700358057 /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = serial.c; path = ../FirmataClient/serial.c; sourceTree = ""; }; + 0CDDA8BD2022D13700358057 /* serial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serial.h; path = ../FirmataClient/serial.h; sourceTree = ""; }; + 0CDDA8BE2022D13700358057 /* maxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = maxlib.c; path = ../FirmataClient/maxlib.c; sourceTree = ""; }; 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = maxmspsdk.xcconfig; path = ../maxmspsdk.xcconfig; sourceTree = SOURCE_ROOT; }; 22CF11AD0EE9A8840054F513 /* cr.boardin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cr.boardin.c; sourceTree = ""; }; 2FBBEAE508F335360078DB84 /* cr.boardin.mxo */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = cr.boardin.mxo; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -48,14 +48,14 @@ 089C166AFE841209C02AAC07 /* iterator */ = { isa = PBXGroup; children = ( - 0C7409AF1FC6620F00259E45 /* maxlib.h */, - 0C7409B01FC6620F00259E45 /* maxlib.c */, - 0C74099B1FC65F6600259E45 /* firmatalib.h */, - 0C74099C1FC65F6600259E45 /* firmatalib.c */, - 0C74099D1FC65F6600259E45 /* serial.h */, - 0C74099E1FC65F6600259E45 /* serial.c */, - 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */, + 0CDDA8BD2022D13700358057 /* serial.h */, + 0CDDA8BC2022D13700358057 /* serial.c */, + 0CDDA8B92022D13700358057 /* firmatalib.h */, + 0CDDA8BA2022D13700358057 /* firmatalib.c */, + 0CDDA8BB2022D13700358057 /* maxlib.h */, + 0CDDA8BE2022D13700358057 /* maxlib.c */, 22CF11AD0EE9A8840054F513 /* cr.boardin.c */, + 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */, 19C28FB4FE9D528D11CA2CBB /* Products */, 0C3533D81F87027000671127 /* Frameworks */, ); @@ -86,9 +86,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 0C7409A11FC65F6600259E45 /* serial.h in Headers */, - 0C7409B11FC6620F00259E45 /* maxlib.h in Headers */, - 0C74099F1FC65F6600259E45 /* firmatalib.h in Headers */, + 0CDDA8BF2022D13700358057 /* firmatalib.h in Headers */, + 0CDDA8C32022D13700358057 /* serial.h in Headers */, + 0CDDA8C12022D13700358057 /* maxlib.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -163,9 +163,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C7409A21FC65F6600259E45 /* serial.c in Sources */, - 0C7409A01FC65F6600259E45 /* firmatalib.c in Sources */, - 0C7409B21FC6620F00259E45 /* maxlib.c in Sources */, + 0CDDA8C22022D13700358057 /* serial.c in Sources */, + 0CDDA8C02022D13700358057 /* firmatalib.c in Sources */, + 0CDDA8C42022D13700358057 /* maxlib.c in Sources */, 22CF11AE0EE9A8840054F513 /* cr.boardin.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/source/cr.boardin/cr.boardin.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate b/source/cr.boardin/cr.boardin.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate index 8f5b98dc28c5e863e4a54f96523f52007e3dce49..054a99eb33d1170520bbc4b43d0500097c032390 100644 Binary files a/source/cr.boardin/cr.boardin.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate and b/source/cr.boardin/cr.boardin.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/source/cr.boardin/cr.boardin.xcodeproj/xcuserdata/orly.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/source/cr.boardin/cr.boardin.xcodeproj/xcuserdata/orly.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 750d58992f4e09d4fe3129e4bc75b14e3ba7d3d6..e9cc5e8d62a9c1cc563a44560c5ca7a96ad0c3ce 100644 --- a/source/cr.boardin/cr.boardin.xcodeproj/xcuserdata/orly.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/source/cr.boardin/cr.boardin.xcodeproj/xcuserdata/orly.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -69,13 +69,73 @@ shouldBeEnabled = "Yes" ignoreCount = "0" continueAfterRunningActions = "No" - filePath = "cr.boardin.c" - timestampString = "537940299.655425" + filePath = "../FirmataClient/maxlib.c" + timestampString = "540429560.831149" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "243" - endingLineNumber = "243" - landmarkName = "boardin_new()" + startingLineNumber = "37" + endingLineNumber = "37"> + + + + + + + + + + + + + + + + diff --git a/source/cr.boardout/cr.boardout.c b/source/cr.boardout/cr.boardout.c index 3055835d7875fbeed4f4de8dfa08f6646e96f4a7..852605dd2fddc356d23fc9a209f8ed6e080ff41e 100755 --- a/source/cr.boardout/cr.boardout.c +++ b/source/cr.boardout/cr.boardout.c @@ -1,9 +1,9 @@ -/** - @file - boardout - a max object shell (Arduino UNO board outputs) - - @ingroup examples - */ +// +// @file +// boardout - a max object (Arduino UNO board writer) +// +// written by Orly Natan, Creative Robotics Lab +// University Of New South Wales (UNSW). */ // Firmata-for-Max Library headers @@ -23,22 +23,27 @@ typedef struct boardout // Arduino board connection board_t *board_ob; - // selected pins to write long pinsCount; long pinsArray[TOTAL_OUT_PINS]; long valuesArray[TOTAL_OUT_PINS]; long modesArray[TOTAL_OUT_PINS]; + int port_index; // boardin attributes: t_symbol *att_portname; - t_symbol *att_baudrate; + t_symbol *att_baudrate; // Sets the data rate in bits per second (baud) for serial data transmission. + // For communicating with the computer, one of these rates: 300, 600, 1200, + // 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. long att_digitalPins[TOTAL_OUT_PINS], digitalPinsCount; long att_servoPins[TOTAL_OUT_PINS], servoPinsCount; long att_pwmPins[TOTAL_OUT_PINS], pwmPinsCount; + int isopen; + + // hardware attributes: - t_symbol *att_pin_modes[TOTAL_OUT_PINS]; + //t_symbol *att_pin_modes[TOTAL_OUT_PINS]; } t_boardout; @@ -47,7 +52,12 @@ typedef struct boardout void *boardout_new(t_symbol *s, long argc, t_atom *argv); void boardout_free(t_boardout *x); void boardout_assist(t_boardout *x, void *b, long m, long a, char *s); -void boardout_print(t_boardout *x); +void boardout_ports(t_boardout *x); +void boardout_pins(t_boardout *x); +void boardout_config(t_boardout *x); +void boardout_test(t_boardout *x); +void boardout_open(t_boardout *x); +void boardout_close(t_boardout *x); //privates void boardout_printAvailPorts(t_boardout *x); @@ -58,18 +68,12 @@ void boardout_updatePwm(t_boardout *x, int index, int val); int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv); int boardout_getBaudRate(t_boardout *x); bool boardout_pinNumAlreadyExists(t_boardout *x, int pin); -int boardout_getBoard(t_boardout *x); int boardout_pinDigitalRange(int pin); -int boardout_pinAnalogRange(int pin); +int boardout_pinServoRange(int pin); int boardout_pinPwmRange(int pin); - -//internals -//t_max_err boardout_digitalPins_get(t_boardout *x, t_object *attr, long *argc, t_atom **argv); -t_max_err boardout_digitalPins_set(t_boardout *x, t_object *attr, long argc, t_atom *argv); -//t_max_err boardout_servoPins_get(t_boardout *x, t_object *attr, long *argc, t_atom **argv); -t_max_err boardout_servoPins_set(t_boardout *x, t_object *attr, long argc, t_atom *argv); -//t_max_err boardout_pwmPins_get(t_boardout *x, t_object *attr, long *argc, t_atom **argv); -t_max_err boardout_pwmPins_set(t_boardout *x, t_object *attr, long argc, t_atom *argv); +int boardout_getBoard(t_boardout *x, int len, int *pins, int *modes); +void boardout_init(t_boardout *x); +void boardout_pinNumConvert(int pin, char *str); void boardout_in1(t_boardout *x, long n); void boardout_in2(t_boardout *x, long n); @@ -84,7 +88,6 @@ void boardout_in10(t_boardout *x, long n); void boardout_in11(t_boardout *x, long n); void boardout_in12(t_boardout *x, long n); - //////////////////////// global class pointer variable void *boardout_class; @@ -98,7 +101,12 @@ void ext_main(void *r) /* you CAN'T call this from the patcher */ class_addmethod(c, (method)boardout_assist, "assist", A_CANT, 0); - class_addmethod(c, (method)boardout_print, "print", 0); + class_addmethod(c, (method)boardout_ports, "ports", 0); + class_addmethod(c, (method)boardout_pins, "pins", 0); + class_addmethod(c, (method)boardout_config, "config", 0); + class_addmethod(c, (method)boardout_test, "test", 0); + class_addmethod(c, (method)boardout_open, "open", 0); + class_addmethod(c, (method)boardout_close, "close", 0); class_addmethod(c, (method)boardout_in1, "in1", A_LONG, 0); class_addmethod(c, (method)boardout_in2, "in2", A_LONG, 0); @@ -116,42 +124,6 @@ void ext_main(void *r) class_register(CLASS_BOX, c); /* CLASS_NOBOX */ boardout_class = c; - // set attributes - - CLASS_ATTR_SYM(c, "portname", 0, t_boardout, att_portname); - CLASS_ATTR_LABEL(c, "portname", 0, "Serial Port"); - //CLASS_ATTR_ENUM(c, "portname", 0, ""); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "portname", NULL, NULL); - - //char* baudratestr = "\"300\" \"1200\" \"2400\" \"4800\" \"9600\" \"14400\" \"19200\" \"28800\" \"38400\" \"57600\" \"115200\""; - CLASS_ATTR_SYM(c, "baud", 0, t_boardout, att_baudrate); - CLASS_ATTR_LABEL(c, "baud", 0, "Baud Rate (analog)"); - //CLASS_ATTR_ENUM(c, "baud", 0, baudratestr); - CLASS_ATTR_ACCESSORS(c, "baud", NULL /*boardout_att_baudrate_get*/, NULL /*boardout_att_baudrate_set*/); - - CLASS_ATTR_LONG_VARSIZE(c, "digitalPins", 0, t_boardout, att_digitalPins, digitalPinsCount, TOTAL_OUT_PINS); - CLASS_ATTR_LABEL(c, "digitalPins", 0, "Digital Pins (read only)"); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "digitalPins", NULL /*boardout_digitalPins_get*/, boardout_digitalPins_set); - - CLASS_ATTR_LONG_VARSIZE(c, "servoPins", 0, t_boardout, att_servoPins, servoPinsCount, TOTAL_OUT_PINS); - CLASS_ATTR_LABEL(c, "servoPins", 0, "Servo Pins (read only)"); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "servoPins", NULL /*boardout_servoPins_get*/, boardout_servoPins_set); - - CLASS_ATTR_LONG_VARSIZE(c, "pwmPins", 0, t_boardout, att_pwmPins, pwmPinsCount, TOTAL_OUT_PINS); - CLASS_ATTR_LABEL(c, "pwmPins", 0, "pwm Pins (read only)"); - // Disable editing attribute in Inspector - Read Only! - CLASS_ATTR_ACCESSORS(c, "pwmPins", NULL /*boardout_pwmPins_get*/, boardout_pwmPins_set); - - // attributes order of appearance in the inspector - CLASS_ATTR_ORDER(c, "portname", 0, "1"); - CLASS_ATTR_ORDER(c, "baud", 0, "2"); - CLASS_ATTR_ORDER(c, "digitalPins", 0, "3"); - CLASS_ATTR_ORDER(c, "servoPins", 0, "4"); - CLASS_ATTR_ORDER(c, "pwmPins", 0, "5"); - post("Arduino UNO boardout object created (Writer)."); } @@ -171,22 +143,25 @@ void boardout_assist(t_boardout *x, void *b, long m, long a, char *s) int index = a-1; int pin = x->pinsArray[index]; + if(pin<14) str = ""; + else { + str = "A"; + pin -= 14; + } + switch(x->modesArray[index]) { + case MODE_OUTPUT: - sprintf(s, "pin D%d mode DIGITAL", pin); + sprintf(s, "pin %s%d mode DIGITAL values {0,1}", str, pin); break; case MODE_SERVO: - if(pin > 13) - sprintf(s, "pin %d (A%d) mode SERVO", pin+PIN_OFFSET, pin+PIN_OFFSET-20); - else - sprintf(s, "pin D%d mode SERVO", pin); + sprintf(s, "pin %s%d mode SERVO range [0-180] degrees", str, pin); break; case MODE_PWM: - sprintf(s, "pin D%d mode PWM", pin); + sprintf(s, "pin D%d mode PWM range [0-255]", pin); break; default: - sprintf(s, "pin D%d mode UNKNOWN", pin); - str = "UNKNOWN"; + sprintf(s, "pin %s%d mode UNKNOWN", str, pin); } } } @@ -197,79 +172,25 @@ void boardout_assist(t_boardout *x, void *b, long m, long a, char *s) void boardout_free(t_boardout *x) { - if(x == NULL) return; - - if(x->att_portname) { - - if(x->att_portname->s_thing) { - board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); - if(mgr->board_out != NULL) { // && mgr->board_out == x->board_ob) { - - //release the boardin connection - //post("disconnecting boardout object"); //debug - mgr->board_out = NULL; - //post("boardout disconnected"); //debug - } - //debug - else { - post("error, boardout wasn't found"); - } - - if(mgr->board_in == NULL) { - - // no reader board is connected, release the port altogether - //post("closing the port"); //debug - int val = maxclient_shutdown(x->board_ob); // close port - if(val == -1) { - post("error shutting down, %s", x->board_ob->err_msg); - return; - } - //debug - //else { - // post("boardout shut down"); - //} - x->att_portname->s_thing = NULL; - free(mgr); - //mgr->board = NULL; - //mgr->board_out = NULL; - } - //debug - //else { - // post("boardin object found"); - //} - } - - //debug - //else { - //post("port is not in use by any other board object"); - //} - } - - //debug - //else { - // post("no portname found"); - //} - - - //if (x->board_ob != NULL) { - // free(x->board_ob); - // post("board object deleted"); - //} - - //post("boardout object deleted"); //debug - + boardout_close(x); + if (DEBUG) post("boardout object deleted"); //debug + } void *boardout_new(t_symbol *s, long argc, t_atom *argv) { t_boardout *x = (t_boardout *)object_alloc(boardout_class); + // verify memory allocated successfully if(x == NULL) { post( "Max is out of memory, could not create new boardout object."); return NULL; } + boardout_init(x); // todo - remove, for debug + x->board_ob = NULL; + x->port_index = -1; // parse input arguments to set up object if (boardout_parseArgs(x, argc, argv) == -1) { @@ -280,17 +201,201 @@ void *boardout_new(t_symbol *s, long argc, t_atom *argv) } - // init all pin modes to DIGITAL MODE at first + /* init all pin modes to DIGITAL MODE at first for (int i = 0; i < TOTAL_OUT_PINS; ++i) { x->att_pin_modes[i] = gensym("DIGITAL"); - } + }*/ // debug: //if(x->att_portname && x->att_baudrate) { // object_post((t_object *)x, "port name: %s\t rate: %d", x->att_portname->s_name, atoi(x->att_baudrate->s_name)); //} - // connect to port (board) and set board configuration as requested + // create pin integer inlets + for (int i = x->pinsCount; i > 0; --i) { + // create int inlets from right to left (highest-right to 1-left): + intin(x, i); + } + + // boardout object is now all set up + return (x); +} + +void boardout_ports(t_boardout *x){ + boardout_printAvailPorts(x); +} + +void boardout_pins(t_boardout *x) { + + char str[4000], str_pin[10]; + long count, *arr; + + str[0] = '\0'; + + // Digital pins + count = x->digitalPinsCount; + arr = x->att_digitalPins; + if(count) { + str[0] = '\0'; + strcat(str, "Digital pins: "); + for (long i=0; iservoPinsCount; + arr = x->att_servoPins; + if(count) { + str[0] = '\0'; + strcat(str, "Servo pins: "); + for (long i=0; ipwmPinsCount; + arr = x->att_pwmPins; + if(count) { + str[0] = '\0'; + strcat(str, "PWM pins: "); + for (long i=0; iboard_ob) { + object_post((t_object *)x, "test: board is not connected."); + return; + } + + if ( ! x->board_ob->isBoardReady) { + object_post((t_object *)x, "test: board is not ready for communication."); + return; + } + + if( ! x->isopen) { + object_post((t_object *)x, "test: board is not connected."); + return; + } + object_post((t_object *)x, "test: board is connected."); + + char *firmware = firmataclient_getfirmware(x->board_ob); + object_post((t_object *)x, "test: firmware version %s.", firmware); + object_post((t_object *)x, "test: board is ready for communication."); + + object_post((t_object *)x, "test: onboard LED will now blink 3 times."); + firmataclient_blink(x->board_ob); + + object_post((t_object *)x, "test: Done."); +} + +void boardout_open(t_boardout *x){ + if (x == NULL) return; + + if(x->isopen) { + object_post((t_object *)x, "board is already connected."); + return; + } + + if ( ! x->att_baudrate) { + // set baud rate to default + char str[20]; + sprintf(str, "%d", DEFAUTLT_BAUD); + x->att_baudrate = gensym(str); + } + if(DEBUG) object_post((t_object *)x, "baud rate %s.", x->att_baudrate->s_name); + + // get updated list of available ports + char *ports_avail[MAX_PORTS]; + int num_ports = serial_portlist(ports_avail, MAX_PORTS); + + if (x->port_index == -1) { + object_error((t_object *)x, "port not selected."); + return; + } + if(DEBUG) object_post((t_object *)x, "index of port selected %d.", x->port_index); + + if (x->port_index < 0 || x->port_index >= num_ports) { + object_error((t_object *)x, "port selected is out of bounds of available ports."); + if(DEBUG) object_error((t_object *)x, "index of port selected %d.", x->port_index); + return; + } + + // select the port + x->att_portname = gensym(ports_avail[x->port_index]); + if(x->att_portname == NULL) { + if(DEBUG) object_error((t_object *)x, "port can't be found, internal error."); + return; + } + if(DEBUG) object_post((t_object *)x, "port selected %s to open", x->att_portname->s_name); // debug + + // check for other connections + if(x->att_portname->s_thing == NULL) { + + // the port is not in use by other boardin/out objects + if(DEBUG) object_post((t_object *)x, "port has no other connections, %s", x->att_portname->s_name); // debug + board_mgr_t *mgr = (board_mgr_t*)malloc(sizeof(board_mgr_t)); + if(mgr == NULL) { + object_error((t_object *)x, "port can't be opened, Max can't allocate memory."); + return; + } + mgr->board_out = NULL; + mgr->board_in = NULL; + mgr->board = NULL; + x->att_portname->s_thing = (t_object*)mgr; + } + else { + // the port is in use by another boardin/out object + if(DEBUG) object_post((t_object *)x, "OK, port has another connection, %s", x->att_portname->s_name); // debug + } + + + // set board configuration int len_config = x->digitalPinsCount + x->servoPinsCount + x->pwmPinsCount; int pins[len_config]; int modes[len_config]; @@ -315,32 +420,78 @@ void *boardout_new(t_symbol *s, long argc, t_atom *argv) len++; } - // create pin integer inlets - for (int i = x->pinsCount; i > 0; --i) { - // create int inlets from right to left (highest-right to 1-left): - intin(x, i); + //if(DEBUG) object_post((t_object *)x, "%d pins allocated", len); // debug + //if (DEBUG) { + // for(int i=0; iboard_ob, len_config, pins, modes, OUT_BOARD); + if( err ) { + object_error((t_object *)x, "open: Boardout couldn't connect to board."); + if(x->board_ob) object_error((t_object *)x, "%s", x->board_ob->err_msg); + return; } - if( ! x->att_portname) - return (x); - // create a new writing board and init - int result = boardout_getBoard(x); - if(result != 0) { - object_error((t_object *)x, "Boardout couldn't create a connection to board"); - return (x); + x->isopen = 1; + object_post((t_object *)x, "open: boardout is now connected."); +} + +void boardout_close(t_boardout *x) { + + if(x == NULL) return; + + if( ! x->isopen) { + object_post((t_object *)x, "close: board was not connected."); + return; } - result = maxclient_connect(x->board_ob, len_config, pins, modes, OUT_BOARD); - if( result != 0) { - object_error((t_object *)x, "Boardout couldn't connect to board."); - return (x); + if ( ! x->att_portname) { + object_post((t_object *)x, "close: no port selected."); + return; } - return (x); -} + if(x->att_portname->s_thing == NULL) { + object_post((t_object *)x, "close: board was not connected."); + return; + } + + board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); + if(mgr->board_out == NULL) { + object_post((t_object *)x, "close: board was not connected."); + return; + } -void boardout_print(t_boardout *x){ - boardout_printAvailPorts(x); + x->isopen = 0; + mgr->board_out = NULL; + object_post((t_object *)x, "close: diconnected from board."); + + + if(mgr->board_in == NULL) { + + // no reader board is connected, release the port altogether + int err = maxclient_shutdown(x->board_ob); // close port + if(err == -1) { + object_error((t_object *)x, "close: error shutting serial port down"); + if (x->board_ob) object_error((t_object *)x, "%s", x->board_ob->err_msg); + return; + } + + if (DEBUG) object_post((t_object *)x, "close: port %s was shut down", x->att_portname->s_name); + + x->att_portname->s_thing = NULL; + maxclient_freemgr(mgr); + } + + return; } void boardout_updatePin(t_boardout *x, int inlet, int val) { @@ -368,28 +519,24 @@ void boardout_updatePin(t_boardout *x, int inlet, int val) { post("unidentified mode selected"); // error } - //object_post((t_object *)x, "%s pin %ld: %ld", str, x->pinsArray[index], x>valuesArray[index]); //debug + if (DEBUG) object_post((t_object *)x, "%s pin %ld: %ld", str, x->pinsArray[index], x->valuesArray[index]); //debug } void boardout_updateDigital(t_boardout *x, int index, int val) { - val = (val>0? 1 : 0); + val = (val==0? 0 : 1); x->valuesArray[index] = val; int pin = x->pinsArray[index]; maxclient_toggleDigital(x->board_ob, pin, val); } void boardout_updateServo(t_boardout *x, int index, int val) { - if (val < 0) val = 0; - if (val > 170) val = 170; x->valuesArray[index] = val; int pin = x->pinsArray[index]; maxclient_moveServo(x->board_ob, pin, val); } void boardout_updatePwm(t_boardout *x, int index, int val) { - if (val < 0) val = 0; - if (val > 170) val = 170; x->valuesArray[index] = val; int pin = x->pinsArray[index]; maxclient_movePwm(x->board_ob, pin, val); @@ -402,9 +549,8 @@ void boardout_updatePwm(t_boardout *x, int index, int val) { int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv) { - // get updated list of available ports - char *ports_avail[MAX_PORTS]; - int num_ports = serial_portlist(ports_avail, MAX_PORTS); + + x->port_index = -1; // set baud rate to default char str[20]; @@ -421,20 +567,8 @@ int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv) int index = portCh[0]-'a'; //object_post((t_object *)x, "port index: %d", index); //debug - if (index >= 0 && index < num_ports) { - //strncpy(x->portname, ports_avail[index], MAX_PORT_NAME); - x->att_portname = gensym(ports_avail[index]); - if(x->att_portname->s_thing == NULL) { - // the port is not in use by other boardin/out objects - board_mgr_t *mgr = (board_mgr_t*)malloc(sizeof(board_mgr_t)); //newPortMgr(IN_BOARD); - mgr->board_out = NULL; - mgr->board_in = NULL; - mgr->board = NULL; - x->att_portname->s_thing = (t_object*)mgr; - } - //x->att_portname->s_thing = NULL; //TODO add ref to the serial port - //object_post((t_object *)x, "port name is: (%s)", x->att_portname->s_name); // debug - //object_post((t_object *)x, "port thing is: (%s)", x->att_portname->s_thing); //debug + if (index >= 0 && index <= 'z'-'a') { + x->port_index = index; i = 1; } } @@ -486,6 +620,54 @@ int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv) //x->baudrate = atom_getlong(argv+i); } } + else if( ! strcmp_case_insensitive(s->s_name, "A0")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 14; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A1")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 15; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A2")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 16; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A3")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 17; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A4")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 18; + argv[i] = a[0]; + --i; + } + else if( ! strcmp_case_insensitive(s->s_name, "A5")) { + t_atom *a = (t_atom*)malloc(sizeof(t_atom)); + if(a == NULL) return -1; + a->a_type = A_LONG; + a->a_w.w_long = 19; + argv[i] = a[0]; + --i; + } else { // otherwise, unknown attribute symbol digitalFound = false; @@ -504,15 +686,9 @@ int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv) if((servoFound || digitalFound || pwmFound) && x->pinsCount < TOTAL_OUT_PINS) { if(servoFound) { - if(boardout_pinAnalogRange(pin)) { - // if the pin is analog, then substruct PIN_OFFSET - // Digital pins [D0-D13] are numbered 0-13 indexed as 0-13 in Firmata - // Analog pins [A0-A5] are numbered 20-25 indexed as 14-19 in Firmata - pin -= PIN_OFFSET; - } - else if (!boardout_pinDigitalRange(pin)) { + if( ! boardout_pinServoRange(pin)) { // error - object_error((t_object *)x, "Invalid pin number %d, servo pins range [0-13, 20-25]", pin); + object_error((t_object *)x, "Invalid pin number %d, servo pins range [2-13, A0-A5]", pin); return 0; } } @@ -525,7 +701,7 @@ int boardout_parseArgs(t_boardout *x, long argc, t_atom *argv) if(digitalFound && !boardout_pinDigitalRange(pin)) { // error - object_error((t_object *)x, "Invalid pin number %d, digital pins range [0-13]", pin); + object_error((t_object *)x, "Invalid pin number %d, digital pins range [2-13, A0-A5]", pin); return 0; } @@ -612,37 +788,71 @@ bool boardout_pinNumAlreadyExists(t_boardout *x, int pin) { return false; } -int boardout_getBoard(t_boardout *x) { +int boardout_getBoard(t_boardout *x, int len, int *pins, int *modes) { - if(!x || !x->att_portname || !x->att_portname->s_thing) return 1; + if(!x || !x->att_portname || !x->att_portname->s_thing) return -1; + if( !pins || !modes) return -1; - // requested port is not connected to by any other board object, then - // create a new Arduino board object, initialise and connect to (serial) port + // search symbol port_name. if found, then board is already connected to by a boardin + // object (reader object), then get the pointer to that board object. Otherwise, create + // a new board object and initialise it with the requested baud rate and the rest of + // the pins (write) configuration. board_mgr_t *mgr = ((board_mgr_t *)(x->att_portname->s_thing)); + if (mgr == NULL) { + if (DEBUG) object_error((t_object *)x, "can't connect to port, internal error"); + return -1; + } + if(mgr->board_out != NULL) { - // error - there is already another boardout object connected - object_error((t_object *)x, "connect: port name: %s is already occupied with another boardout object!", x->att_portname->s_name); + object_error((t_object *)x, "open: port %s is already occupied with another boardout (writer) object!", x->att_portname->s_name); return -1; } else if(mgr->board_in != NULL) { - // there is already a boardin object connected - //object_post((t_object *)x, "connect: boardin found"); // debug - //object_post((t_object *)x, "x->board_object=%s", x->board_ob); //debug + if (DEBUG) object_post((t_object *)x, "open: port %s has another connection to boardin (okay)", x->att_portname->s_name); // debug + + if(mgr->board == NULL) { + object_error((t_object *)x, "open: can't connect the board. internal error."); + return -1; + } + + // check baud rate conflict (between existing and the new board) + //if(x->att_baudrate) { + // long current_rate = atol(x->att_baudrate->s_name); + // if(mgr->board->port) { + // long port_rate = mgr->board->port->baud_rate; + // if(port_rate != current_rate) { + // object_error((t_object *)x, "open: can't connect the board, baud rate conflict. "); + // object_error((t_object *)x, "port baud rate %ld, but baud %ld requested. ", mgr->board->port->baud_rate, current_rate); + // return -1; + // } + // } + // } + + // check if there is any configuration conflict + if (maxclient_verifyconfig(mgr->board, len, pins, modes)) { + object_error((t_object *)x, "open: can't connect the board. "); + object_error((t_object *)x, "%s", mgr->board->err_msg); + return -1; + } + x->board_ob = mgr->board; mgr->board_out = x; } else { - object_post((t_object *)x, "NEW BOARD IS BEING CREATED"); + // requested port is not connected to by any other board object, then + // create a new Arduino board object, initialise and connect to (serial) port + + if (DEBUG) object_post((t_object *)x, "open: port is not connected to by any other board object yet, establishing a new connection."); // debug char err_return[4000]; - x->board_ob = maxclient_newboard(x->att_portname->s_name, atoi(x->att_baudrate->s_name), err_return); - // verify succeful memory allocation + long rate = x->att_baudrate? atol(x->att_baudrate->s_name) : DEFAUTLT_BAUD; + x->board_ob = maxclient_newboard(x->att_portname->s_name, rate, err_return); if(x->board_ob == NULL) { // error there is already another boardout object connected object_error((t_object *)x, "Max could not create new boardout object."); @@ -659,11 +869,11 @@ int boardout_getBoard(t_boardout *x) { } int boardout_pinDigitalRange(int pin) { - return ((pin < 14 && pin >=0)? 1 : 0); + return ((pin < 20 && pin >=2)? 1 : 0); } -int boardout_pinAnalogRange(int pin) { - return ((pin < 26 && pin >=20)? 1 : 0); +int boardout_pinServoRange(int pin) { + return ((pin < 20 && pin >=2)? 1 : 0); } int boardout_pinPwmRange(int pin) { @@ -671,6 +881,19 @@ int boardout_pinPwmRange(int pin) { return ((pin==3 || pin==5 || pin==6 || pin==9 || pin==10 || pin==11)? 1 : 0); } +void boardout_init(t_boardout *x) { + + if(x == NULL) + return; + + x->pinsCount = 0; + x->att_portname = NULL; + x->att_baudrate = NULL; + x->digitalPinsCount = 0; + x->pwmPinsCount = 0; + x->servoPinsCount = 0; + x->isopen = 0; +} /* INTERNALS @@ -748,3 +971,17 @@ void boardout_in12(t_boardout *x, long n) { boardout_updatePin(x, 12, n); } +void boardout_pinNumConvert(int pin, char *str) { + if( ! str) { + str = ""; + return; + } + if(pin < 14) sprintf(str, "%d", pin); + else sprintf(str, "A%d", pin-14); + return; +} + + +// Servo.Write() writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement). + +// PWM: call analogWrite(pin, dutyCycle), where dutyCycle is a value from 0 to 255. diff --git a/source/cr.boardout/cr.boardout.xcodeproj/project.pbxproj b/source/cr.boardout/cr.boardout.xcodeproj/project.pbxproj index 688b99318e34d2149ee04be3347b6a9d31d0e00d..a304117f4ecf57583e4ec47ec43f09a26fe6ff0a 100755 --- a/source/cr.boardout/cr.boardout.xcodeproj/project.pbxproj +++ b/source/cr.boardout/cr.boardout.xcodeproj/project.pbxproj @@ -7,26 +7,26 @@ objects = { /* Begin PBXBuildFile section */ - 0C1E16A11FC50306007BF808 /* firmatalib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1E169F1FC50306007BF808 /* firmatalib.c */; }; - 0C1E16A21FC50306007BF808 /* firmatalib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C1E16A01FC50306007BF808 /* firmatalib.h */; }; - 0C7409AD1FC6607C00259E45 /* maxlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C7409AB1FC6607C00259E45 /* maxlib.h */; }; - 0C7409AE1FC6607C00259E45 /* maxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C7409AC1FC6607C00259E45 /* maxlib.c */; }; - 0C7CC1181F943B430011BFAE /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C7CC1141F943B430011BFAE /* serial.c */; }; - 0C7CC11A1F943B430011BFAE /* serial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C7CC1161F943B430011BFAE /* serial.h */; }; 0C91F5A91F73957300EF94C5 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C91F5A81F73957200EF94C5 /* CoreFoundation.framework */; }; 0C91F5AB1F73958100EF94C5 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C91F5AA1F73958100EF94C5 /* IOKit.framework */; }; + 0CDDA8CB2022D8B500358057 /* firmatalib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8C52022D8B500358057 /* firmatalib.h */; }; + 0CDDA8CC2022D8B500358057 /* firmatalib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8C62022D8B500358057 /* firmatalib.c */; }; + 0CDDA8CD2022D8B500358057 /* maxlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8C72022D8B500358057 /* maxlib.h */; }; + 0CDDA8CE2022D8B500358057 /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8C82022D8B500358057 /* serial.c */; }; + 0CDDA8CF2022D8B500358057 /* serial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDDA8C92022D8B500358057 /* serial.h */; }; + 0CDDA8D02022D8B500358057 /* maxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CDDA8CA2022D8B500358057 /* maxlib.c */; }; 22CF11AE0EE9A8840054F513 /* cr.boardout.c in Sources */ = {isa = PBXBuildFile; fileRef = 22CF11AD0EE9A8840054F513 /* cr.boardout.c */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 0C1E169F1FC50306007BF808 /* firmatalib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = firmatalib.c; path = /Users/orly/Documents/MyProjects/FirmataClient/firmatalib.c; sourceTree = ""; }; - 0C1E16A01FC50306007BF808 /* firmatalib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = firmatalib.h; path = /Users/orly/Documents/MyProjects/FirmataClient/firmatalib.h; sourceTree = ""; }; - 0C7409AB1FC6607C00259E45 /* maxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = maxlib.h; path = /Users/orly/Documents/MyProjects/FirmataClient/maxlib.h; sourceTree = ""; }; - 0C7409AC1FC6607C00259E45 /* maxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = maxlib.c; path = /Users/orly/Documents/MyProjects/FirmataClient/maxlib.c; sourceTree = ""; }; - 0C7CC1141F943B430011BFAE /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = serial.c; path = /Users/orly/Documents/MyProjects/FirmataClient/serial.c; sourceTree = ""; }; - 0C7CC1161F943B430011BFAE /* serial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serial.h; path = /Users/orly/Documents/MyProjects/FirmataClient/serial.h; sourceTree = ""; }; 0C91F5A81F73957200EF94C5 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 0C91F5AA1F73958100EF94C5 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 0CDDA8C52022D8B500358057 /* firmatalib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = firmatalib.h; path = ../FirmataClient/firmatalib.h; sourceTree = ""; }; + 0CDDA8C62022D8B500358057 /* firmatalib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = firmatalib.c; path = ../FirmataClient/firmatalib.c; sourceTree = ""; }; + 0CDDA8C72022D8B500358057 /* maxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = maxlib.h; path = ../FirmataClient/maxlib.h; sourceTree = ""; }; + 0CDDA8C82022D8B500358057 /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = serial.c; path = ../FirmataClient/serial.c; sourceTree = ""; }; + 0CDDA8C92022D8B500358057 /* serial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = serial.h; path = ../FirmataClient/serial.h; sourceTree = ""; }; + 0CDDA8CA2022D8B500358057 /* maxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = maxlib.c; path = ../FirmataClient/maxlib.c; sourceTree = ""; }; 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = maxmspsdk.xcconfig; path = ../maxmspsdk.xcconfig; sourceTree = SOURCE_ROOT; }; 22CF11AD0EE9A8840054F513 /* cr.boardout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cr.boardout.c; sourceTree = ""; }; 2FBBEAE508F335360078DB84 /* cr.boardout.mxo */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = cr.boardout.mxo; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -48,60 +48,20 @@ 089C166AFE841209C02AAC07 /* iterator */ = { isa = PBXGroup; children = ( - 0C7CC1131F907C9A0011BFAE /* include */, + 0CDDA8C52022D8B500358057 /* firmatalib.h */, + 0CDDA8C62022D8B500358057 /* firmatalib.c */, + 0CDDA8C72022D8B500358057 /* maxlib.h */, + 0CDDA8C82022D8B500358057 /* serial.c */, + 0CDDA8C92022D8B500358057 /* serial.h */, + 0CDDA8CA2022D8B500358057 /* maxlib.c */, + 22CF11AD0EE9A8840054F513 /* cr.boardout.c */, 22CF10220EE984600054F513 /* maxmspsdk.xcconfig */, - 0C7CC10E1F9079A50011BFAE /* lib */, - 0C7CC10D1F9079960011BFAE /* src */, 19C28FB4FE9D528D11CA2CBB /* Products */, 0C91F5A71F73957200EF94C5 /* Frameworks */, ); name = iterator; sourceTree = ""; }; - 0C7CC10D1F9079960011BFAE /* src */ = { - isa = PBXGroup; - children = ( - 22CF11AD0EE9A8840054F513 /* cr.boardout.c */, - ); - name = src; - sourceTree = ""; - }; - 0C7CC10E1F9079A50011BFAE /* lib */ = { - isa = PBXGroup; - children = ( - 0C7CC11C1F9487E00011BFAE /* src */, - 0C7CC11D1F9487EE0011BFAE /* include */, - ); - name = lib; - sourceTree = ""; - }; - 0C7CC1131F907C9A0011BFAE /* include */ = { - isa = PBXGroup; - children = ( - ); - name = include; - sourceTree = ""; - }; - 0C7CC11C1F9487E00011BFAE /* src */ = { - isa = PBXGroup; - children = ( - 0C1E169F1FC50306007BF808 /* firmatalib.c */, - 0C7409AC1FC6607C00259E45 /* maxlib.c */, - 0C7CC1141F943B430011BFAE /* serial.c */, - ); - name = src; - sourceTree = ""; - }; - 0C7CC11D1F9487EE0011BFAE /* include */ = { - isa = PBXGroup; - children = ( - 0C7409AB1FC6607C00259E45 /* maxlib.h */, - 0C1E16A01FC50306007BF808 /* firmatalib.h */, - 0C7CC1161F943B430011BFAE /* serial.h */, - ); - name = include; - sourceTree = ""; - }; 0C91F5A71F73957200EF94C5 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -126,9 +86,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 0C7CC11A1F943B430011BFAE /* serial.h in Headers */, - 0C1E16A21FC50306007BF808 /* firmatalib.h in Headers */, - 0C7409AD1FC6607C00259E45 /* maxlib.h in Headers */, + 0CDDA8CB2022D8B500358057 /* firmatalib.h in Headers */, + 0CDDA8CF2022D8B500358057 /* serial.h in Headers */, + 0CDDA8CD2022D8B500358057 /* maxlib.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -203,10 +163,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C7CC1181F943B430011BFAE /* serial.c in Sources */, - 0C1E16A11FC50306007BF808 /* firmatalib.c in Sources */, + 0CDDA8CE2022D8B500358057 /* serial.c in Sources */, + 0CDDA8CC2022D8B500358057 /* firmatalib.c in Sources */, + 0CDDA8D02022D8B500358057 /* maxlib.c in Sources */, 22CF11AE0EE9A8840054F513 /* cr.boardout.c in Sources */, - 0C7409AE1FC6607C00259E45 /* maxlib.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/source/cr.boardout/cr.boardout.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate b/source/cr.boardout/cr.boardout.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate index 10be9b5e8c7763be20648644703b165586ec8ae1..78894838117d71aeb6de2d59ace566a30aa3e51e 100644 Binary files a/source/cr.boardout/cr.boardout.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate and b/source/cr.boardout/cr.boardout.xcodeproj/project.xcworkspace/xcuserdata/orly.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/source/maxmspsdk.xcconfig b/source/maxmspsdk.xcconfig index 62ec65169868e91b63f8eded6d072199b69ebc72..0c126a9fad67879333eaf1f47ffe1a3e1dfadef1 100755 --- a/source/maxmspsdk.xcconfig +++ b/source/maxmspsdk.xcconfig @@ -14,9 +14,8 @@ PRODUCT_NAME = $(PROJECT_NAME) PRODUCT_VERSION = 7.0.1 ARCHS = i386 x86_64 - // Paths -C74SUPPORT = $(SRCROOT)/../c74support +C74SUPPORT = /Applications/Max.app/Contents/Resources/C74/packages/max-sdk-7.3.3/source/c74support HEADER_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" FRAMEWORK_SEARCH_PATHS = "$(C74SUPPORT)/max-includes" "$(C74SUPPORT)/msp-includes" "$(C74SUPPORT)/jit-includes" DSTROOT = $(SRCROOT)/../../cr/externals