     switch (inputBuffer[0]) {
       case 'd': { toggleDebug(); break; }
       case 'V': { processColor(); break; } // set value specified in V#FFFFFF input
-      case 'L' : { gradientLoop = true; processGradient(); break;}
+      case 'S' : { gradientLoop = true; gradientReversingMode = true;  processGradient(); break;}
+      case 'L' : { gradientLoop = true; gradientReversingMode = false;  processGradient(); break;}
       case 'G' : { gradientLoop = false; processGradient(); break;}
       case 'F' : { processFlash(); break; }
     }

}

void flash() {
  if (debugMode) { Serial.print("Flash:");}
  outputColor( flashFirstColor ? flashcol1 : flashcol2 );
  flashFirstColor = !flashFirstColor;
  if (debugMode) { Serial.print(red); Serial.print(green); Serial.println(blue); }
}

void timeoutAction() {
  if (debugMode) { Serial.println("Processing timeout."); }
  if (!recentActivity) {
    Serial.print("No recent activity for "); Serial.print(TIMEOUT); Serial.println(" seconds.");
    // maybe timeout and timeout behavior should be configurable over serial.
    // low priority, bc this will mostly be running before serial comms have
    // been established.
    gradientPulseSetup(OFF, WHITE, 2);
    gradientLoop = true;
  } 
}

void gradientPulseSetup (const int col1[3],const int col2[3], float timev) { // timev is now in seconds
  flashThread.disable();
  gradDelayPerTick = (float) timev*1000/numdivs;
  gradPercPerTick = (float) 1/numdivs;
  gradPerc = 0;
  if (debugMode) {


void outputColor( int r, int g, int b) {

  if (GROVE_DRIVER) {
    Driver.begin();
    Driver.SetColor(r, g, b);
    Driver.end();
