Bei Chips mit wenigen GPIO's kommt man schnell an die Grenze, wenn man mehrere Pins benötigt. Ich wollte einen 4fach-Schalter entwickeln, bei dem man die Ausgänge auch per Schalterdruck von  Hand steuern kann. Dazu benötige ich 4 Eingänge (Taster) und 4 Ausgänge (SSR-Relais). Das ist mit dem ESP8266 nicht lösbar. Dann erinnerte ich mich an einen früheren Versuch, bei dem ich mehrere Taster über den Analogeingang abgefragt habe. Beim ESP8266 hat man einen Anlogeingang 0...1,0V zur Verfügung.

 

Hardware

Die Speisespannung des ESP8266 beträgt 3,3V, man muß also die Maximalspannung der Schaltung auf unter 1,0V herunterteilen. Zudem sollen mehrere gleichzeitige Tastendrücke erkannt werden. Nach einem ersten Ansatz, der R2R-Methode, welche auch bei Digital-/Analogkonvertern eingesetzt wird, stellte sich heraus, dass man zu viele Widerstände benötigt. Schließlich gelang ein Schaltungsdesign, bei dem man pro Taster nur einen Widerstand benötigt:

Tasterabfrage

Der Trick ist, die Widerstandswerte in einer Binärabstufung 1-2-4-8... auszuwählen. Dadurch sind auch Kombinationen erkennbar. Die Formel für diesen Mehrfachspannungsteiler wurde in Excel eingegeben, um die sich ergebenden Spannungen bei unterschiedlichen Tastenkombinationen zu berechnen und sich die Abfrage-Schwellwerte ausgeben zu lassen.

 

Programm

Bei vier Tastern muß man 16 Abfragen auf Schwellwerte verwenden:

int analogIn;                                               // Values from ADC

//--------------------------------------------------------------------------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  delay(3000);                                              // Wait for serial port
  Serial.println("Demo LDR03");
}

//--------------------------------------------------------------------------------------------------------------------------------
void loop() {
  analogIn = analogRead(A0);                                 // Read analog input A0
  Serial.println(analogIn);
  if(analogIn <= 44) Serial.println("Button 1, 2, 3, 4 pressed");
  else if(analogIn > 44 && analogIn <= 143) Serial.println("Button 2, 3, 4 pressed");
  else if(analogIn > 143 && analogIn <= 231) Serial.println("Button 1, 3, 4 pressed");
  else if(analogIn > 231 && analogIn <= 325) Serial.println("Button 3, 4 pressed");
  else if(analogIn > 325 && analogIn <= 416) Serial.println("Button 1, 2, 4 pressed");
  else if(analogIn > 416 && analogIn <= 491) Serial.println("Button 2, 4 pressed");
  else if(analogIn > 491 && analogIn <= 560) Serial.println("Button 1, 4 pressed");
  else if(analogIn > 560 && analogIn <= 601) Serial.println("Button 4 pressed");
  else if(analogIn > 601 && analogIn <= 641) Serial.println("Button 1, 2, 3 pressed");
  else if(analogIn > 641 && analogIn <= 706) Serial.println("Button 2, 3 pressed");
  else if(analogIn > 706 && analogIn <= 768) Serial.println("Button 1, 3 pressed");
  else if(analogIn > 768 && analogIn <= 834) Serial.println("Button 3 pressed");
  else if(analogIn > 834 && analogIn <= 899) Serial.println("Button 1, 2 pressed");
  else if(analogIn > 899 && analogIn <= 952) Serial.println("Button 2 pressed");
  else if(analogIn > 952 && analogIn <= 1002) Serial.println("Button 1 pressed");
  else if(analogIn > 1002) Serial.println("No button pressed");
  
  delay(1000);
}

Das Einlesen und Auswerten dauert zwischen 150 und 570 Mikrosekunden. Das Programm befindet sich im Downloadbereich.