231a-ac loop.pde

From CSclasswiki
Jump to: navigation, search
//
// loop.pde
// Yang Li 
// 12/16/2008
// modified from arduino-loop.pde by D. Thiebaut
// 
// This program runs an endless loop on the Arduino, reading input
// from 2 tilt switches and writing output to an LED matrix.
// It also waits for commands of the type
// "p" (toggles playback mode on and off)
// "w d 3 1"(set variable that contains the status of pin 1 to 1)
// "r d" (write value of pin status variable to serial port)
//
// This skech also works without the assembly program. 
// It still does the interaction between LED and tilt switches,
// but the interaction will not be stored. 
// 
//(*features of reading/writing analog pins from the original
//   program are preserved but not used)
//------------------------------------------------------------
// GLOBALS
// -------------------------------------------------------------
//for communication
char buffer[256];
int len;
char *operation;
char *mode;
char *pin;
char *state;

//for Switches and LEDs
int row[4]={9,10,12,11};
int col[4]={5,6,7,8};
int sw[4]={4,3,2,13}; //since pin 1 is used by communication, use pin 13
int val[4]={0,0,0,0};

//switching from sensing mode to play mode
bool playmode=false;
// -------------------------------------------------------------
// PROTOTYPES (function headers)
// -------------------------------------------------------------
void resetAll();
int process();
int writePin( char mode, int pin, int state );
int readPins( char mode );

void changeLED(int colNum, int val);

// -------------------------------------------------------------
// SETUP: initializes port and buffer
// -------------------------------------------------------------
void setup() {
    Serial.begin(9600); 
    resetAll();
//LED setup
    for (int i=0;i<4;i++){
    	pinMode(sw[i], INPUT);		//sets switch pins as input
    	pinMode(row[i], OUTPUT);	//sets LED pins as output
    	pinMode(col[i], OUTPUT);    
  
  	digitalWrite(row[i], LOW); 	//turn on all LEDs
  	digitalWrite(col[i], HIGH);
  	}
}

// -------------------------------------------------------------
// RESETALL: clears the buffer and the globals
// -------------------------------------------------------------
void resetAll() {
    buffer[0] = '\0';
    len       = 0;
    operation = mode = pin = state = 0;
}
// -------------------------------------------------------------
// ChangeLED: alter the status of a LED
// -------------------------------------------------------------
void changeLED(int colNum,int val){
  if (val==HIGH){
    digitalWrite(colNum,LOW);
  }else{
    digitalWrite(colNum,HIGH);
  }
}

// -------------------------------------------------------------
// LOOP: main workhorse.  Called repeatedly.  Gets chars from 
//       the arduino, and processes it when \n received
// -------------------------------------------------------------
void loop() {
/*----------Native LED control---------------------*/
  	for (int i=0;i<4;i++){
		if (!playmode){
    		val[i] = digitalRead(sw[i]);  // read input value
		}    	
		changeLED(col[i],val[i]);
  	}


/*----------read next command-----------------------*/
    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;

    //--- get the operation: 'w' or 'r'.  Do some error checking---
    operation = mystrtok( buffer, 0 );
	if (*operation=='p'){
		playmode=!playmode;//toggle playmode
		resetAll();
		return 0; //success
	}

    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 < 1 || intPin > 4 ) { //use pin 1(13) 2 3 4
        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' )
	val[intPin-1]=intState; //override pin value depending on command
    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' ) {
        for ( i=0; i<4; i++ ) {
        	Serial.print(val[i]); //get pin state from val not reading
        }
  }
  if ( mode=='a' ) {
        Serial.print( "a " );
        for ( i=0; i<6; i++ ) {
            Serial.print( analogRead( i ) );
            Serial.print( ' ' );
        }
  }
  Serial.println();
  return 0;
}