Pin-Finder

Mit diesem Beispiel-Projekt möchten wir Ihnen zum einen den Einsatz des Port-Expanders und zum anderen die Verwendung mehrerer Erweiterungs-Platinen mit einem einzigen Digispark zeigen.

Anwendungsfall

Dabei wollen wir ein einfaches Messgerät aufbauen, das dazu dient, die einzelnen Adern eines 9poligen Sub-D Kabels zu identifizieren, wie es beispielsweise zum Anschluss von RS232-Schnittstellen verwendet wird. Hierbei hat man oft das Problem, dass man an einer Seite des Kabels einen vorkonfektionierten Stecker hat und am anderen Ende 9 einzelne Adern, die man z. B. mit einer Platine verbinden möchte. Der Pin-Finder soll anzeigen, zu welchem Pin des Steckers eine beliebige Ader gehört. Dazu bekommt der Pin-Finder eine 9polige Buchse, in die der Stecker des Sub-D Kabels gesteckt wird. Zusätzlich wird er mit einer Prüfspitze ausgestattet. Wenn nun mit der Prüfspitze eine der losen Adern berührt wird, soll das Gerät die Nummer des zugehörigen Pins im Stecker in einem LCD-Display anzeigen.

Messprinzip

Die Prüfspitze wird mit GND der Schaltung verbunden. Die einzelnen Adern werden über die Prüf-Buchse mit HIGH-Pegeln versorgt. Beim Kontakt der Prüfspitze mit einer Ader wird diese auf das GND-Potential (LOW) der Schaltung "heruntergezogen". Der Mikrokontroller soll den Low-Pegel des jeweiligen Pins erkennen und seine Nummer ausgeben. Werden gleichzeitig mehr als eine Ader auf LOW-Pegel gezogen, liegt ein Kurzschluss vor und der Controller soll eine entsprechende Meldung ausgeben.

Hardware

Hardware

Da wir insgesamt 9 Pins überwachen wollen und der Digispark nicht über so viele Eingänge verfügt, brauchen wir zusätzlich einen sog. I/O-Expander. Da als Anzeige ein LCD-Display verwendet werden soll, brauchen wir zusätzlich auch hierfür noch einen entsprechenden Erweiterungssatz. Über spezielle stapelbare Leiterplattenverbinder (die als Zubehör erhältlich sind), können diese Module einfach zusammengesteckt werden.

Im Bild rechts sehen Sie unten den Digispark, darüber den LCD-Erweiterungssatz mit dem Verbindungskabel zum Display und ganz oben den I/O-Expander, der insgesamt 8 Pins zur Verfügung stellt. Als neunten Pin verwenden wir einen der Standard-Pins des Digisparks. Über die stapelbaren Leiterplattenverbinder werden auch diese durch alle Platinen bis nach oben "durchgereicht".

Software

// --------------------------------
// Benötigte Bibliotheken einbinden
// --------------------------------
#include <TinyWireM.h>                  // I2C
#include <LiquidCrystal_I2C.h>          // LCD

// ---------------------
// Konstanten definieren
// ---------------------
#define LCD_ADDR     0x27               // I2C-Adresse für LCD-Controller
#define PORT_ADDR    0x20               // I2C-Adresse für Port-Expander

// -------------------------
// globale Variablen anlegen
// -------------------------
LiquidCrystal_I2C lcd(LCD_ADDR,16,2);   // Objekt-Instanz für LCD-Steuerung
boolean data_received = false;          // Flag zum erkennen, ob Daten
                                        // gelesen werden konnten

uint8_t actPin = 0;                     // Merker für aktuell erkannten Pin
uint8_t prevPin = 0;                    // Merker für zuletzt erkannten Pin

// --------------------------------------------------------
// Setup-Routine (wird automatisch beim Starten ausgeführt)
// --------------------------------------------------------
void setup(){
  // I2C Schnittstelle initialisieren
  TinyWireM.begin();                    
 
  // LCD-Display initialisieren
  lcd.init();                           
 
  // Hintergrundbeleuchtung anschalten
  lcd.backlight();                    

  // fixen Text ausgeben
  lcd.print(" ACT PIN:");
  lcd.setCursor(0,1);
  lcd.print("PREV PIN:");  
 
  // Port-Expander initialisieren
  writePort(PORT_ADDR, 0xff);
 
  // PIN 6 als Eingang definieren
  pinMode(5, INPUT);
 
  // internen Pull-Up-Widerstand aktivieren
  digitalWrite(5, HIGH);
}

// ------------------------------------------------------------
// Haupt-Routine (wird kontinuierlich als Schleife durchlaufen)
// ------------------------------------------------------------
void loop(){
  byte data;
  int count=0;
  int pin=0;
  int i=0;
 
  data=readPort(PORT_ADDR);

  if (data_received){
    
    // Status des Port-Expanders auswerten
    // dazu in einer Schleife alle 8 Pins durchgehen
    for (i=0; i<8; i++){
      // wurde ein Pin durch die Mess-Spitze auf LOW gezogen?
      if (bitRead(data, i)==false){
        // Pin erkannt
        pin = i + 1;
        count++;
      }
    }  
    
    // zusätzlichen Input-Pin des Digispark auswerten
    if (digitalRead(5)==LOW){
     pin = 9;
     count++;
    }
    
    // Cursor für Ausgabe positionieren
    lcd.setCursor(10, 0);
    
    // Abhängig von der Anzahl der erkannten PINs Anzeige ausgeben
    if (count==0){
      // Kein gültiger PIN erkannt
      lcd.print("NO   ");     
      actPin = 0;
    } else if (count==1){
      // genau 1 gültigen PIN erkannt
      
      // falls als ACT PIN etwas anderes angezeigt wird,
      // Anzeige löschen und aktuellen Pin ausgeben
      if (actPin != pin){
        lcd.print("     ");    // Anzeige löschen
        lcd.setCursor(10, 0);  // Cursor neu positionieren
        lcd.print(pin);        // Pin ausgeben
        actPin = pin;          // Pin speichern
      }
      
      // falls als PREV PIN etwas anderes angezeigt wird,
      // Anzeige löschen und aktuellen Pin ausgeben
      if (prevPin != pin){
        lcd.setCursor(10, 1);  // Cursor positionieren
        lcd.print("     ");    // Anzeige löschen
        lcd.setCursor(10, 1);  // Cursor neu positionieren
        lcd.print(pin);        // Pin ausgeben
        prevPin = pin;         // Pin speichern
      }
    } else {
      // mehr als ein PIN erkannt --> Kurzschluss
      lcd.print("SHORT");
    }
  }
}

byte readPort(int address) {
  byte data=0xff;
  TinyWireM.requestFrom(address,1);
  if(TinyWireM.available()){
    data=TinyWireM.receive();
    data_received=true;
    }
  else {
    data_received=false;
  }
 
  return data;
}

void writePort(int address, byte data) {
  TinyWireM.beginTransmission(address);
  TinyWireM.send(data);
  TinyWireM.endTransmission();
  delay(5);
}