CSC231 arduino loop new.pde

From dftwiki3
Jump to: navigation, search

(c)--D. Thiebaut 03:10, 7 November 2008 (UTC)


//
// arduino-loop.pde
// D. Thiebaut
// 11/6/08
// This program runs an endless loop on the Arduino, waiting
// for commands of the type "w d 13 1" (write a 1 on Digital 
// Pin 13), or "r d" (read digital pins).

// -------------------------------------------------------------
// GLOBALS
// -------------------------------------------------------------
char buffer[256];
int len;
char *operation;
char *mode;
char *pin;
char *state;

// -------------------------------------------------------------
// PROTOTYPES
// -------------------------------------------------------------
void resetAll();
int process();
int writePin( char mode, int pin, int state );
int readPins( char mode );

// -------------------------------------------------------------
// SETUP: initializes port and buffer
// -------------------------------------------------------------
void setup() {
    Serial.begin(9600); 
    resetAll();
}

// -------------------------------------------------------------
// RESETALL: clears the buffer and the globals
// -------------------------------------------------------------
void resetAll() {
    buffer[0] = '\0';
    len       = 0;
    operation = mode = pin = state = 0;
}

// -------------------------------------------------------------
// LOOP: main workhorse.  Called repeatedly.  Gets chars from 
//       the arduino, and processes it when \n received
// -------------------------------------------------------------
void loop() {

    int c;
    c = Serial.read();

    // nothing received, nothing to do
    if (c==-1) return;
    
    // \n terminator received, process message
    if ( c=='\n' ) {
        if ( process() ) {
	   Serial.println( "Error" );
	}
        resetAll();
        return;
    }
         
    // something received, but not \n. add to buffer
    buffer[ len++ ] = c;
    buffer[ len ] = '\0';
}

// -------------------------------------------------------------
// MYSTRTOK: equivalent to C strtok function that doesn't seem
//           supported by arduino.  Given a pointer to a string
//           p, returns a pointer q past p that points to a char
//           that is not a space.  If cannot find one, return
//           NULL.
// -------------------------------------------------------------
char* mystrtok( char* p, int skipNonBlank ) {
    char* q=p;
    if ( skipNonBlank ) {
        for ( ; *q != ' ' && *q != '\0'; q++ );
        if ( *q=='\0' ) return NULL;
    }
    for ( ; *q != '\0' && *q==' '; q++ );
    if ( *q == '\0' ) return NULL;
    if ( *q == ' ' ) return NULL;
    return q;
}

// -------------------------------------------------------------
// PROCESS: if we're here it's because we have received a message
//          from the UBUNTU PC.
// -------------------------------------------------------------
int process() {
    char *p;
    int len = strlen( buffer );
    int intPin;
    int intState;

    //Serial.print( "buffer = " );
    //Serial.print( buffer );
    
    //--- if message less than 3 chars long, return ---
    if ( len < 3 ) {
        resetAll();
        return 1; //error
    }

    //--- get the operation: 'w' or 'r'.  Do some error checking---
    operation = mystrtok( buffer, 0 );

    if ( ( !operation || (*operation!='r' && *operation!='w') ) 
         || ( ( *operation=='r' && len < 3 ) ||( *operation=='w' && len < 7 ) ) ) {
        resetAll();
        return 1; // error
    }

    //--- get the mode: 'd' or 'a' and do some error checking ---
    mode = mystrtok( operation + 1, 0 );
    if (  !mode || ( *mode!='a' && *mode!='d' ) ) {
        resetAll();
        return 1; // success
    }

    //--- if operation is 'r' read the pins ---
    if ( *operation == 'r' ) {
        readPins( *mode );
        resetAll();
        return 0; // success
    }

    //--- if not, operation is 'w', then get pin # and state ---
    pin = mystrtok( mode + 1, 0 );
    if ( !pin ) {
        resetAll();
        return 1; // error
    }
    intPin = atoi( pin );
    if ( intPin < 2 || intPin > 13 ) {
        resetAll();
        return 1; // error
    }
    
    //--- get the state of the output pin ---
    state = mystrtok( pin+1, 1 );
    if ( !state ) {
        resetAll();
        return 1; // error 
    }
    intState = atoi( state );
    if ( intState < 0 || intState > 1 ) {
        resetAll();
        return 1; // error
    }
    
    //--- write the state to the pin in question ---
    writePin( *mode, intPin, intState );

    resetAll();
    return 0;
}

// -------------------------------------------------------------
// WRITEPIN: depending on mode, writes the state to the pin
// -------------------------------------------------------------
int writePin( char mode, int  intPin, int intState ) {
    if ( mode=='d' )
        digitalWrite( intPin, intState );
    if ( mode=='a' )
        analogWrite( intPin, intState );
    //delay( 50 ); // 0.05 sec
    //Serial.println( "OK" );
    return 0;
}

// -------------------------------------------------------------
// READPINS: read the status of all the pins and returns it as
//      a string.
// -------------------------------------------------------------
int readPins( char mode ) {
  int i;
  if ( mode=='d' ) {
        Serial.print( "d " );
        for ( i=2; i<14; i++ ) {
            Serial.print( digitalRead( i ) );
            Serial.print( ' ' );
        }
  }
  if ( mode=='a' ) {
        Serial.print( "a " );
        for ( i=0; i<6; i++ ) {
            Serial.print( analogRead( i ) );
            Serial.print( ' ' );
        }
  }
  Serial.println();
  return 0;
}