     i += 6;
     msg[i++] = 'u';
   }
-  msg[sizeof(msg)-1] = '$';
-  Serial.write(msg, sizeof(msg));
+  Serial.write(msg, i);
   Serial.send_now();
 }
 
 void shift_timing(int direction) {
-  if (bufi >= 9) shiftbuf(9); // TODO--actually do something
-}
-
-void run_command_on(Channel *ch) {
-  // TODO--actually do something
+  if (bufi >= 9) {
+    Dura my_shift = parse_time(buf + 2);
+    shiftbuf(9);
+    if (direction < 0) diminish_by(&pending_shift, my_shift);
+    else advance_from(&pending_shift, my_shift);
+  }
+}
+
+void parse_command_on(Channel *ch, char who) {
+  if (ch->disabled) {
+    halt_channels();
+    running = -1;
+    memcpy(errormsg,"inactive    ", 12);
+    errormsg[9] = who;
+  }
   for (int i = 2; i < bufi; i++) {
     if (buf[i] == '$') { shiftbuf(i+1); return; }
     if (buf[i] == '~') { shiftbuf(i); return; }

  ARM_DEMCR |= ARM_DEMCR_TRCENA;
  ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
  for (int i = 0; i < PROT; i++) protocols[i].next = 255;
  for (int j = 0; j < CHAN; j++) channels[j].protocol = 255;
  running = 0;
  blinking.s = 0;
  blinking.u = 1000;   // 1 ms delay before doing anything
  tick = micros();
  bufi = 0;
}

  if (running < 0) {
    msg[i++] = '!';
    for (int j = 0; j < errormsgN; j++, i++) msg[i] = errormsg[j];
    msg[i++] = '$';
  }
  else if (running == 0) {
    memcpy(msg + i, "000000s000000u", 14);
    i += 14;
  }
  else {
    six_in(global_clock.s, msg + i);
