Programmierhilfe für mein Projekt

Hallo. ich habe folgendes vor. ich möchte selbstgelötete Kabel testen, ob beim Löten alles geklappt hat und keine Zinnbrücken zwischen einzelnen Pin's entstanden sind. Nun habe ich die Adern das einen Endes des Kabels auf eine Klemmleiste gelegt, welche dann auf 10 Pin's des Boards gehen und das andere Ende über eine D-Sub Buchse ebenfalls auf weitere 10 Kontakte des Boards gelegt. Außerdem verwende ich 10 Weitere Kontakte zur Ansteuerung von 10 LED's.
Dazu verwande ich ein Arduino Mega 2560.
Mein Gedanke war 10 Pin's als Output und 10 als Input festzulegen, also die Adern des einen Kabelendes auf Output und das andere Ende auf Input zu legen.
Nun wollte ich nacheinander ein High-Signal auf jeweils eine Ader legen und prüfen ob auch nur auf einen Eingang ein High-Signal ankommt. Dies wollte ich zudem noch über 10 LED's anzeigen lassen und im Fehlerfall den Ablauf stoppen um zu sehen zwischen welchen Pin's eine Verbindung liegt...Brauche dabei dringend Hilfe zwecks der Programmierung, oder eine Info ob das so überhaupt möglich ist.
Danke schonmal...
Robert

robert_m6789:
Mein Gedanke war 10 Pin's als Output und 10 als Input festzulegen, also die Adern des einen Kabelendes auf Output und das andere Ende auf Input zu legen.
Nun wollte ich nacheinander ein High-Signal auf jeweils eine Ader legen und prüfen ob auch nur auf einen Eingang ein High-Signal ankommt. Dies wollte ich zudem noch über 10 LED's anzeigen lassen und im Fehlerfall den Ablauf stoppen um zu sehen zwischen welchen Pin's eine Verbindung liegt...Brauche dabei dringend Hilfe zwecks der Programmierung, oder eine Info ob das so überhaupt möglich ist.

Im Prinzip müßte es "fast so" möglich sein - wenn Dir eine teilweise geringe Aussagefähigkeit des Tests ausreicht.

Zunächst zur Beschaltung und Programmlogik: Wenn es nicht sichergestellt ist, dass es keine Kurzschlüsse im Kabel gibt, dann darfst Du auf keinen Fall "10 Pin's als Output festlegen...und nacheinander ein High-Signal auf jeweils eine Ader legen".

Falls nämlich ein Kurzschluß existiert (was Du ja testen möchtest), würde der eine auf High geschaltete Output seine Ausgangsspannung mit einem auf Low geschalteten anderen Output kurzschließen, dadurch würden viel zu hohe unerlaubte Ströme durch diese beiden Pins des Mikrocontrollers fließen, so dass in der Folge mindestens diese beiden Pins ausfallen und defekt werden könnten (teilzerstörter Mikrocontroller).

Die korrekte Logik müßte so aussehen, daß nacheinander:

  • alle 20 Anschlüsse auf INPUT geschaltet werden
  • nur ein Anschluss zur Zeit wird auf OUTPUT geschaltet (19 bleiben auf INPUT)
  • und der zu diesem Anschluss gehörende Gegen-Pin (und nur der) muß seinen Pegel wechseln, wenn der Pegel des OUTPUT-Pins wechselt.

Aus demselben Grund drohende Kurzschlußgefahr dürftest Du auch nicht einen eventuellen Masseanschluss des Kabels an Ground beim Arduino anschließen, sondern Du müßtest den Masseanschluß des Kabels wie eine normale Leitung des Kabels betrachten, und müßtest beide Ende der Kabel-Masse ebenfalls an zwei Pins des Arduino anschließen und in den Leitungstest einbeziehen. D.h. mit 20 Arduino-Pins kannst Du bei einem Kabel 9 Leitungen plus Kabel-Masse = 10 Leitungen gesamt testen.

Weiterhin mußt Du berücksichtigen, dass INPUT Pins in einer Digitalschaltung nur funktionieren, wenn sie auf einen definierten Pegel gezogen werden, Du kannst einen INPUT nicht "frei in der Luft hängen" lassen oder einfach nur mit einem anderen INPUT verbinden und erwarten, dass es dann einen auslesbaren HIGH oder LOW Pegel gibt, stattdessen sind die Werte an freihängenden INPUTs unbestimmt und die Schaltung benötigt PullUp- oder PullDown-Widerstände, um den Pegel eines unverbundenen Pins auf einen bestimmten Wert (0V oder 5V) zu ziehen. D.h. Deine 20 Pins brauchen in der Schaltung auch noch 20 Widerstände, die als PullUp- oder PullDown-Widerstände an den 20 Mess-Pins geschaltet sind.

Soweit die schlechte Nachricht.
Die gute Nachricht: Atmega-Mikrocontroller haben eingebaute PullUp-Widerstände an jedem Input-Pin, die Du einfach per Software aktivieren kannst:
Statt "pinMode(testPin, INPUT);" schreibst Du einfach "pinMode(testPin, INPUT_PULLUP);" in Deinem Programm, und schon werden die PullUp-Widerstände aktiviert und Du sparst das Einlöten und Verdrahten von 20 Widerständen in Deiner Schaltung.

Dadurch verstauscht sich allerdings die Programmlogik, alle INPUT_PULLUP gesetzten Pins haben einen HIGH-Pegel von Haus aus, wenn sie nirgends angeschlossen sind, und zum Testen müßtest Du über einen OUTPUT Pin ein LOW erzeugen, damit dann der Pegel am Input auf LOW wechselt.

Alles klar soweit? Sieht für mich sehr machbar aus.

Abschließend noch zur oben von mir erwähnten "geringen Aussagefähigkeit des Tests":
Der Test hat eine sehr gute Aussagefähigkeit bei der Erkennung von Kurzschlüssen zwischen den Kabeln, diese werden zu 100% sicher erkannt. Die geringe Aussagefähigkeit bezieht sich auf die Erkennung "kalter Lötstellen", also wenn eine Verbindung nicht wirklich niederohmig verlötet ist und es einen Übergangswiderstand an einer Lötstelle gibt: Selbst bei 100 Ohm Widerstand im Kabel würde der Pegel in der Testschaltung wechseln und somit "gut" anzeigen, auch wenn es sich um sehr schlechte kalte Lötstellen mit einem hohen Übergangswiderstand handelt. Das so aufgebaute Testgerät wäre also hauptsächlich ein Gerät, das zuverlässig auf Kurzschlussbrücken testet, das aber nur wenig über die Qualität der Lötstellen aussagt.

Was mir gerade einfällt: Wenn Du einen zweistufigen Test machst, dann müßtest Du zum Testen des Kabels auch mit nur 10 Pins auskommen.

Meine Idee dazu, mit der halben Pin-Anzahl auszukommen (bei etwas umständlicherer Bedienung): Du bastelst Dir für das eine Ende des zu testenden Kabels einen "Teststecker" als Kurzschlußstecker, an dem je zwei Kabel verbunden sind: Leitung-1 mit Leitung-2, Leitung-3 mit Leitung-4, Leitung-5 mit Leitung-6 u.s.w.. Am anderen Ende des Kabels sind die 10 Leitungen mit Pins am Arduino verbunden. Das auf Leitung-1 gegebene Signal muss also auf Leitung-2 wieder zurückkommen, etc.

  1. Stufe des Tests bei abgezogenem Teststecker: Der Arduino testet jede Leitung einzeln per Output mit Pegelwechsel, der Pegel darf sich an keiner anderen Leitung ändern (Kurzschlusstest).

  2. Stufe des Tests bei aufgesetztem Teststecker: Der Arduino testet jede Leitung einzeln per Output mit Pegelwechsel, der Pegel darf sich nur an der dazugehörenden anderen Leitung ändern (Verbindungstest).

Wenn sowohl der 10-pol Kurzschlußtest (ohne Teststecker) als auch der 10-pol Verbindungstest (mit Teststecker) bestanden werden, entspricht das in der Aussagekraft dem 20-pol Test, der in einem Rutsch abgearbeitet werden kann.

Wie Du schon richtig bemerkst musst Du eigentlich nur ein Lauflicht programmieren und die andere Seite des Kabels an LEDs anklemmen. Das Lauflicht muß eben statt zwischen HIGH und LOW zwischen HIGH und HIGH-Z wechseln. Alles was Du dazu brauchst findest Du eigentlich in meinem Blog.

Wichtig ist nur beim Umschalten zwischen high und high-z über pullup zu wechseln und nicht über low.

// HIGH --> HIGH-Z
pinMode(pin, INPUT);
digitalWrite(pin, LOW);


// HIGH-Z --> HIGH
digitalWrite(pin, HIGH);
pinMode(pin, OUTPUT);

jurs:

robert_m6789:
Falls nämlich ein Kurzschluß existiert (was Du ja testen möchtest), würde der eine auf High geschaltete Output seine Ausgangsspannung mit einem auf Low geschalteten anderen Output kurzschließen, dadurch würden viel zu hohe unerlaubte Ströme durch diese beiden Pins des Mikrocontrollers fließen, so dass in der Folge mindestens diese beiden Pins ausfallen und defekt werden könnten (teilzerstörter Mikrocontroller).

Würden hierbei Dioden Abhilfe schaffen?

Ist es denn Möglich während einem Programmablauf meine Pin's zwischen Input und Output wechseln zu lassen?

ja, jederzeit und so oft Du willst.
Grüße Uwe

wie, wenn ich fragen darf :slight_smile:

äh?
mit pinMode() oder Arduino Playground - PortManipulation
Grüße Uwe

robert_m6789:
Ist es denn Möglich während einem Programmablauf meine Pin's zwischen Input und Output wechseln zu lassen?

Oh, oh, das hört sich nach extrem wenigen Programmierkenntnissen an.

Anbei sende ich Dir mal einen Entwurf für einen Kabeltester, der seine Ergebnisse über den seriellen Monitor ausgibt.

So wie der Quelltext gemacht ist, zunächst mal als Kabeltester für 6 Leitungen, bzw. Masseleitung plus fünf weitere Leitungen.

Eine Erweiterung auf eine höhere Anzahl zu testender Leitungen ist extrem einfach. Bei Bedarf einfach die Deklaration für die Pins an der Eingangsseite und der Ausgangsseite des Kabels, wo jetzt 6 Pins stehen auf die gewünschte Pinanzahl erweitern:

// Pins, die mit den Kabelenden am Anfang und am Ende des Kabels verbunden sind
byte pinsKabelAnfang[]= {3,4,5,6,7,8};
byte pinsKabelEnde[] = {9,10,11,12,14,15};

Wichtig: Den LED-Pin 13 an Arduinos bitte NICHT als Pin zum Leitungstest verwenden und auch die Pins 0 und 1 (Serial RX/TX) beim UNO-Board als Hardware-Serial NICHT zum Testen von Leitungen verwenden! Es können dagegen die Analog-Pins A0 bis A5 problemlos auch zum Leitungstesten verwendet werden.

Der von mir gemachte Code erkennt und unterscheidet folgende Fehler in der Verkabelung:
KEINEVERBINDUNG ==> Eine Leitung der Eingangsseite ist nicht angeschlossen
FALSCHEVERBINDUNG ==> Eine Leitung der Eingangsseite ist falsch angeschlossen (z.B. Kreuzverbunden mit falschem Pin)
KURZSCHLUSS ==> Eine Leitung der Eingangsseite bildet einen Kurzschluss

Bei einwandfreier Verkabelung wird OK bei jeder Leitung angezeigt, die Aussagekraft bei Verkabelungsfehlern ist allerdings unter Umständen ein bischen verquer, weil nur von der Eingangsseite her getestet wird und die Logik zum Anzeigen von Verkabelungsfehlern könnte man noch verbessern.

Na ja, Du willst ja auch noch was zu tun haben. Z.B. den Code, der das Testergebnis jetzt über die serielle Schnittstelle ausgibt dann auf einem LCD-Display oder mit Hilfe von LED-Statusanzeigen ausgeben, damit das Gerät keinen PC-Anschluß benötigt, wenn es verwendet wird.

Code "Leitungstester":

// Leitungstester by "jurs" for German Arduino forum
enum ergebnis {FEHLERFREI, KURZSCHLUSS, KEINEVERBINDUNG, FALSCHEVERBINDUNG };

// Pins, die mit den Kabelenden am Anfang und am Ende des Kabels verbunden sind
byte pinsKabelAnfang[]= {3,4,5,6,7,8};
byte pinsKabelEnde[] = {9,10,11,12,14,15};


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  if (sizeof(pinsKabelAnfang)!=sizeof(pinsKabelEnde))
  {
    Serial.println("Konfiguration fehlerhaft!");
    Serial.println("Deklaration korrigieren: pinsKabelAnfang[] und pinsKabelEnde[]");
    Serial.println("Anzahl der Leitungen muss gleich sein!");
    while(true==true); // Stopp mit Endlosschleife
  }  
}

void setOutputPin(byte pinNumber)
{ // Zuerst in einer Schleife alle Pins auf INPUT_PULLUP setzen
  for (int i=0;i<sizeof(pinsKabelAnfang);i++)
  {
    pinMode(pinsKabelAnfang[i],INPUT_PULLUP);
    pinMode(pinsKabelEnde[i],INPUT_PULLUP);
  }
  // Zuletzt den einen Pin auf Output setzen
  pinMode(pinNumber,OUTPUT);
}


void DoOneTest()
{
  ergebnis result;
  byte errorOtherPin;
  Serial.println();
  Serial.println("################################################");
  Serial.println("#                    KABELTEST                 #");
  Serial.println("################################################");
  for (int i=0;i<sizeof(pinsKabelAnfang);i++) // Alle Leitungen testen
  {
    result=FEHLERFREI; // erstmal Fehlerfreiheit annehmen
    // Funktionsaufruf, um zu testenden Pin als einzigen auf OUTPUT zu setzen
    setOutputPin(pinsKabelAnfang[i]);
    digitalWrite(pinsKabelAnfang[i], LOW); // den zu testenden Pin LOW setzen
    // Zuerst testen, ob der Gegenpol verbunden ist
    if (digitalRead(pinsKabelEnde[i])!=LOW)
    {
        result=KEINEVERBINDUNG;
        errorOtherPin=i;
    }
    // Dann in einer Schleife auf falsche Verbindungen testen:
    for (int j=0;j<sizeof(pinsKabelEnde);j++)
    {
      if (j!=i && digitalRead(pinsKabelEnde[j])==LOW)
      {
        result=FALSCHEVERBINDUNG;
        errorOtherPin=j;
      }  
    }
    // Zuletzt in einer Schleife auf Kurzschluss testen:
    for (int j=0;j<sizeof(pinsKabelAnfang);j++)
    {
      if (j!=i && digitalRead(pinsKabelAnfang[j])==LOW)
      {
        result=KURZSCHLUSS;
        errorOtherPin=j;
      }  
    }
    Serial.print("Leitung : ");
    Serial.print(i);
    switch (result)
    {
      case FEHLERFREI: Serial.println(" OK");break;
      case KURZSCHLUSS:Serial.print(" KURZSCHLUSS mit Leitung ");Serial.println(errorOtherPin);break; 
      case KEINEVERBINDUNG:Serial.print(" KEINE VERBINDUNG mit Leitung ");Serial.println(errorOtherPin);break; 
      case FALSCHEVERBINDUNG:Serial.print(" FALSCHE VERBINDUNG mit Leitung ");Serial.println(errorOtherPin);break;  ;
    }
  }
  Serial.println("Test beendet.");
  Serial.println();
}

void loop() {
  DoOneTest();  // Einen Kabeltest machen
  delay(10000); // 10 Sekunden Pause machen
}

@jurs:
du hast eindeutig viel zu viel Zeit... :wink:

Super Programm, spitzenmäßig dokumentiert. Aber lernen wird er auf diese Art wenig. Sicher kann er den Code studieren und dank deiner zahlreichen Kommentare nachvollziehen, was das Programm tut oder nicht tut - aber er muss es nicht...

[quote author=Marcus W link=topic=149759.msg1126621#msg1126621 date=1361384672]
@jurs:
du hast eindeutig viel zu viel Zeit... ;)[/quote]

Na ja, hier lag eindeutig ein Notfall vor: Der OP wollte 10 Pins an seinem Arduino gleichzeitig als OUTPUT schalten, einen davon mit abweichendem Pegel, und die Pins an ein Kabel anschließen, von dem er nicht weiß, ob es einen Kurzschluß hat. Also quasi seine Arduino-Outputs mit hoher Kurzschlußgefahr betreiben. Da ist es ja geradezu eine Verpflichtung, ihn nicht sehenden Auges in den Kurzschluß und damit die vermutliche Teilzerstörung seines Controllers laufen zu lassen.
:wink:

Wie bereits oben geschrieben: Zufrieden bin ich nur mit der "Alles OK" Meldung. Die Kabel-Fehlermeldungen im Fehlerfall sind noch stark verbesserungswürdig und insbesondere bei Mehrfachfehlern in der Verkabelung nicht unbedingt zielführend bei der Fehlerbeseitigung. Ist mehr ein Schnellschuß.

Das ist ja ihm selbst überlassen, wie viel oder wie wenig er aus dem Studium von fremdem Code herauszieht.

Und wenn es nur wenig ist, z.B. "baue keine Kurzschlüsse zwischen Pins die auf OUTPUT gesetzt sind" oder "halte die loop()-Funktion kurz und übersichtlich", "nutze Unterfunktionen", oder "die Wahl einer geeigneten Datenstruktur ist hilfreich bei der Wartung des Programms", dann ist es diesmal eben nur wenig.

Er braucht sich aus jedem fremden Code, den er sich näher ansieht, nur einen einzige neue Fertigkeit beim Programmieren seines Arduino abschauen, und trotzdem lernt er was. Rom wurde schließlich auch nicht an einem Tag erbaut.

Ich glaub ja unser guter Jurs macht das andersherum: erst Kommentare als Ablaufskize schreiben, dann den Code nachpflegen ...

Liebe Grüße

Dirk

Dann schauen wir mal...aufjedenfall funktioniert das Programm, also schonmal danke jurs. Auch ein Dankeschön an alle anderen Hilfen.
Muss zugeben das ich auf diesem Gebiet komplett neu bin und mit dieser Art der Programmierung noch nie zu tun hatte.

robert_m6789:
Dann schauen wir mal...aufjedenfall funktioniert das Programm, also schonmal danke jurs.

Na bitte, dann kann's ja direkt losgehen mit Kabeltesten!

robert_m6789:
Muss zugeben das ich auf diesem Gebiet komplett neu bin und mit dieser Art der Programmierung noch nie zu tun hatte.

Eventuell kannst Du Dir dann ja das eine oder andere aus dem Code für Deine zukünftigen Programme und Programmänderungen abschauen. Z.B. dass man mit "enum" sowas wie "sprechende Konstanten" definieren kann, die einem im Code stehend eventuell mehr sagen, als wenn stattdessen nur Zahlen wie 0,1,2,3 stehen.

Oder dass es meinem Programm, obwohl beispielhaft zum Testen von 6 Leitungen geschrieben, eigentlich vollkommen egal ist, wieviele Leitungen damit getestet werden, weil die Schleifenzähler nicht auf 6 hartcodiert sind. Also nicht:
for (int j=0;j<6;j++)
Sondern bei mir im Code steht:
for (int j=0;j<sizeof(pinsKabelEnde);j++)
Die Größe des byte-Arrays "pinsKabelEnde" entspricht immer genau der Anzahl der Pins (=Leitungen), die man in das Array reingeschrieben hat, d.h. wenn man dort oben im Programm mehr Pins reinschreibt für einen Leitungstester mit 8, 10 oder 20 Leitungen, weiß der Schleifenzähler trotzdem genau, wie viele Leitungen er in der Zählschleife abklappern muß. So daß man aus demselben Code einen Kabeltester mit beliebiger Leitungsanzahl machen kann, einfach indem man nur die Pins bei pinsKabelAnfang und pinsKabelEnde im Quellcode einträgt und sonst überhaupt keine Änderungen am Code vorzunehmen braucht.

Wenn Dir im Code irgendwas unklar ist, einfach fragen!