   for (auto &p : digiPins) {
     p.updateLed(blink);
     p.updateSwitch();
-  }
+    shiftLeds |= p.getOnOffBits();
+  }
+  serialShiftWrite(shiftLeds);
 }
 
 // commands like: ^L{GR}{id}={val}$

  m_lastLedState = nval;
}

void digitalPin::updateLed(const bool blink) const {
  uint8_t nstate;
  if (m_pinOn>0) {
    nstate = (m_lastLedState & 0x01) ? HIGH : LOW;
    if (nstate==HIGH && (m_lastLedState & 0x02) && blink) {
      nstate = !digitalRead(m_pinOn);
    }
//Serial.print("L"); Serial.print(gPin); Serial.print(nstate);
    digitalWrite(m_pinOn,nstate);
  }
  if (m_pinOff>0) {
    nstate = (m_lastLedState & 0x10) ? HIGH : LOW;
    if (nstate==HIGH && (m_lastLedState & 0x20) && blink) {
      nstate = !digitalRead(m_pinOff);
    }
//Serial.print("R"); Serial.print(rPin); Serial.print(nstate);
    digitalWrite(m_pinOff,nstate);
  }
}

class analogInPin {
  public:
    analogInPin(const uint8_t id, const uint8_t pin, const int threshold);
    void update();
  private:
    const uint8_t m_id, m_pin;
    const int m_threshold;
    int m_lastAValue { 0 };
};

analogInPin analogInPins[] = {
  analogInPin(0,A0,2),  // throttle
  analogInPin(1,A1,2)	  // timewarp
};

analogInPin::analogInPin(const uint8_t id, const uint8_t pin, const int threshold) :
	m_id(id), m_pin(pin), m_threshold(threshold)
{
}

void analogInPin::update() {
	// map to the range of the analog out
	int aValue = map(analogRead(m_pin), 0, 1023, 0, 255);
	// is it different enough from the last reading?
	if (abs(aValue-m_lastAValue)>m_threshold) {
		if (aValue<m_threshold) {
			aValue = 0;
		}
		if (aValue>255-m_threshold) {
			aValue = 255;
		}
    // dump status
	Serial.print("P");
	Serial.print(m_id);
	Serial.print("=");
	Serial.println(aValue,HEX);
	m_lastAValue = aValue;
  }
}

class analogOutPin {
  public:
    analogOutPin(const uint8_t id, const uint8_t pin);
    void updateState(const uint8_t val) const ;
    const uint8_t getId() const { return(m_id); }
  private:
    const uint8_t m_id, m_pin;
};

analogOutPin::analogOutPin(const uint8_t id, const uint8_t pin) :
	m_id(id), m_pin(pin)
{
}

void analogOutPin::updateState(const uint8_t val) const {
	analogWrite(m_pin,val);
}

analogOutPin analogOutPins[] = {
  analogOutPin(0,10),	// g-force
  analogOutPin(0,11)  // electrical power
};

// blinker control
unsigned long lastBlink = 0;
const unsigned long blinkInterval = 500;

// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// serial port
#define SERIAL_SPEED 115200

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(SERIAL_SPEED);
  // set timeout to 200ms

    }
}

void checkSerialInput() {
  if (Serial.available()>0) {
    const uint8_t c = Serial.read();
    if (c == 'L') {
	    handleSerialInputLed();
	  }
  }
}

void loop() {
  checkSerialInput();
  updatePins();
  delay(100);
}

