GND schalten bei Common Anode

Hallo zusammen,

ich habe eine 4fach 7-Segementanzeige mit "common anode". http://img1.cdn.tradevv.com/Y201201M1186283T1G1366376/NFD-5641ABUx-21.pdf

Mittels pinMode(Dig1A, OUTPUT) und digitalWrite(Dig1A, LOW); kann ich den entsprechenden PIN auf GND ziehen und die LED leuchtet.

Wie kann ich die LED nun wieder ausschalten? Der PIN darf ja nicht GND sein, und HIGH auch nicht. Oder schaff ich mir lieber 7Segmentanzeigen mit Common Cathode an?

Wenn man den Pin auf Input schaltet (und der Pullup deaktiviert ist) ist er hochohmig:

http://forum.arduino.cc/index.php/topic,12212.0.html http://www.multiwingspan.co.uk/arduino.php?page=led9 (ganz am Ende des Codes)

Probiert habe ich das nicht, aber laut Google sollte es funktionieren.

Der PIN darf ja nicht GND sein, und HIGH auch nicht.

Wieso darf er nicht HIGH sein? Wenn Du normal verdrahtet hast, sollte das problemlos gehen. Wenn Du die Kathode auf das gleiche Potenzial setzt, wie die Anode, dann fliesst einfach kein Strom, somit ist die LED aus. Da die LED eine Diode ist, fliesst auch kein Strom in Gegenrichtung.

Thombo84: Wie kann ich die LED nun wieder ausschalten? Der PIN darf ja nicht GND sein, und HIGH auch nicht.

Warum darf der Pin nicht HIGH sein? Solange die Anode auch HIGH ist, fließt kein Strom und die LED geht aus. Normalerweise multiplext du diese Anzeigen mit je einem Transistor (z. B. PNP) an den gemeinsamen Anoden eines Digits. Ziehst du die Basis des Transistors (die über einen 2k - 3,3k Widerstand mit dem Arduino verbunden ist) auf LOW, dann kann das Digit angesteuert werden. Mit einem LOW an den Kathoden geht die Segmente an, mit einem HIGh aus.

PS: Da war wieder einer Schneller...

Bei der 4Ziffern-Anzeige hast du doch 4 Anoden zum Multiplexen. Die werden in deinem Fall auch an OUTPUT-Pins (einer davon jeweils HIGH) gelegt, oder ?

( Am besten über Transistoren, da 8*20mA doch etwas zu viel sind und du die Kathoden sonst auch nicht gleichzeitig einschalten könntest )

Packst du die Vorwiderstände auf die 8 Kathoden-Seite ?

Common Cathode ist genauso einfach/schwierig, denke ich...

Sobald dir 12 Pins direkt vom Arduino zuviel ist, aber du keinen speziellen Driver verwenden willst, brauchst du eh Schieberegister, die dann nur noch Hi / Low geschaltet werden.

Alles klar, da hatte ich dann einen Denkfehler. In diesem Projekt plane ich erstmal wirklich 12 Pins für die Anzeige zu "opfern".

Eine Frage noch am Rande: Ich lese eine Temperatur aus, und habe anschließend einen 2 stelligen Wert vom Typ "int" (als Beispiel 25) - Wie kann ich diesen Wert nun am einfachsten in "2" und "5" zerpflücken?

Gibt bestimmt cleverere Methoden, aber modulo sollte gehen

Sofern Du wirklich die Werte haben willst, so:

int value = 25;
int zehner = value / 10;
int einer = value % 10;

Wenn Zeichen (Ziffern) gewünscht sind, einfach jeweils '0' addieren.

pylon: Sofern Du wirklich die Werte haben willst, so:

int value = 25;
int zehner = value / 10;
int einer = value % 10;

Wenn Zeichen (Ziffern) gewünscht sind, einfach jeweils '0' addieren.

Vielen Dank, das mit dem teilen klappt so wunderbar. Allerdings erkennt "switch" die Zahlen nicht. Wie addiere ich die Null da passend zu ?

int tempeiner = temp % 10;
int tempzehner = temp / 10;
tempeiner = tempeiner + 0;
tempzehner = tempzehner + 0;

 switch (tempeiner) {
   CLEAR();  // Segment löschen
  case 0:    
    SEG4NULL; // Null anzeigen auf letztem Segment
    break;
  case 1:   
    SEG4EINS; // 1 anzeigen auf letztem Segment
    break;
  case 2:

Das mit dem '0' addieren war gemeint wenn du ein ASCII Zeichen willst. Alternativ 0x30 oder Dezimal 48 addieren. Halt weil '0' (die Striche bedeuten dass es ein Character ist) den ASCII Code 0x30 hat. Hat mich aber auch erst etwas verwirrt :)

Einfach 0 als Zahl addieren macht keinen Unterschied. Bei 7-Segment Anzeigen willst du aber wahrscheinlich bei der normalen Binär/BCD-Darstellung bleiben. Also weglassen.

SEG4NULL;

Was soll das machen? Wenn da eine Methode aufgerufen werden soll, muss das SEG4NULL() heißen

Das sollte eigentlich so passen… wenn du "char"s haben willst musst du die ‘0’ in Anführungszeichen setzen (der Datentyp sollte dann auch char sein):

char tempeiner = temp % 10 + '0';
char tempzehner = temp / 10 + '0';

 switch (tempeiner) {
   CLEAR();  // Segment löschen
  case '0':    
    SEG4NULL; // Null anzeigen auf letztem Segment
    break;
  case '1':   
    SEG4EINS; // 1 anzeigen auf letztem Segment
    break;
  case '2':

In diesem Fall würde ich aber auf ein Switch/Case verzwichten und stattdessen ein const bool verwenden. In dem zweidimensionalen Array sind zu jeder Ziffer die Zustände (HIGH/LOW) der Segmente gespeichert.

const bool Segment[10][7] = {
       {x,x,x,x,x,x,x}, //Segmente für Ziffer '0'
       {x,x,x,x,x,x,x}, //Segmente für Ziffer '1'
       ......  //usw.
};
const int Pins[7] = {x,x,x,x,x,x,x}; //Digitalpinnummern der Segmente

//Zugriff:
int tempeiner = temp % 10;

for (int seg = 0; seg < 7; seg++){
  digitalWrite(Pins[seg],Segment[tempeiner][seg]);
}

Um Pins zu sparen kannst du übrigens in einen BCD-zu-7-Segment Decoder investieren. Dann brauchst du nur 4 Datenleitungen für die Ziffern (die direkt 0-9 entsprechen) + Latch Enable. Für Common-Anode muss da allerdings noch ein Transistor für jeden Ausgang dazwischen (da bietet sich natürlich ULN2803 an), ist also auch recht aufwendig.

Aber wie oben schon gesagt solltest du sowieso nicht einfach den ganzen Strom über den Arduino fließen lassen (das hört sich bei dir so an als ob du die direkt ansteuerst). Also ist ein Treiber so oder so nicht verkehrt.

Seite 11: http://www.reichelt.de/index.html?;ACTION=7;LA=3;OPEN=0;INDEX=0;FILENAME=A240%252F74HC4511_74HCT4511%2523PHI.pdf

Jetzt wirds peinlich... mir fällt gerade wie Schuppen von den Augen dass ich mich anscheinend mit dem multiplexen beschäftigen sollte, es sei denn ich will auf allen 4 Segmenten dieselbe Zahl haben....

Edit: Was ich eigentlich vor habe: Ich habe einen Arduino Ethernet, dieser bekommt per POE Strom. Es soll eine SD-Karte eingebaut werden, ein DHT22 Temp+Luftfeuchtemesser. Auf dem Arduino läuft ein kleiner Webserver der die Werte des DHT22 anzeigt. Weiterhin sollen die Werte stündlich auf die SD-Karte geschrieben in eine LogDatei geschrieben werden. Diese Logdatei ist im besten Fall über den Webserver downloadbar. Die aktuelle Uhrzeit kommt per NTP. Um am Gerät auch die Luftfeuchtigkeit und die Temperatur ablesen zu können soll nun diese 4fach-7Segmentanzeige dienen. Und das ist auch mein größtest Problem.

Hier sind Schaltungen wie das aussehen soll:
http://cdn.instructables.com/FO5/9SUS/F4VNMDE6/FO59SUSF4VNMDE6.LARGE.gif


http://data.bolton.ac.uk/learningresources/elearning/moodle/C-micros/C/C7/images/4x7seg-LED-circuit.jpg

Oder hier mit PNP was wahrscheinlich korrekter ist:
http://codeandlife.com/2012/02/24/7-segment-multiplexing-with-uln2003-pnp-transistors/
(da steht auch eine schöne Lösung um die Segmente anzusteuern)

Wie gesagt gehst du dann mit den Kathoden am besten auf einen ULN2803 (dann hast du noch einen Darlington für den Punkt. Der ULN2003 hat nur 7):

Den kannst du dann immer noch direkt ansteuern, oder du hängt noch einen 4511 dazwischen. Mit einem Schieberegister sparts du noch mehr Pins, aber mit dem 4511 musst du keine Tabelle für die Segmente im Code anlegen. Geschmackssache…

Danke Serenifly für die Infos. Eine Frage dazu habe ich noch: Bei dem Bild wird mein jetziges Problem deutlich: http://cdn.instructables.com/FO5/9SUS/F4VNMDE6/FO59SUSF4VNMDE6.LARGE.gif Wenn auf der ersten Anzeige (Disp1) alle 7 LED der Segmentanzeige leuchten, (DATA1 bis DATA8) und dann Disp2 dazugeschaltet wird, dann sehe ich auf Disp2 auch alle 7 LED leuchten. Das Problem hätte ich doch auch beim Einsatz von einem 2803? Oder nicht?

Auf dem Schaltbild fehlen die Basiswiderstände an allen Transistoren und die Vorwiderstände an den Segmenten.

Du mußt zuerst die Segmente die Leuchten sollen auf LOW schalten , die nicht leuchten sollen auf H und dann einen der Disp-Transistoren ansteuern. Nach der ein-Zeit dann Disp-Transistor abschalten, die Segmente ansteuern die leuchten / nicht leuchten sollen und nächsten Disp-Transistor aktivieren usw.

Grüße Uwe

Die anderen Links haben die Widerstände meistens drin :slight_smile: Deshalb habe ich gedacht, dass das klar ist. Lediglich die Werte muss man eventuell anpassen.

Ist dir grundlegend klar wie das Multiplexen funktioniert? Anscheinend nicht so.

Du schaltest jede Ziffer nur für ein paar Millisekunden über den jeweiligen Transistor an. Dann wird auf die nächste Ziffer geschaltet. Das macht man automatisch in einem Timer. Dadurch, dass das so schnell geht sieht man den Schaltvorgang nicht und es erscheint als ein Bild (ähnlich wie beim Film oder Fernsehen). Aber es ist immer nur eine Ziffer aktiv.

Das hier ist purer AVR Code aus dem Link oben (für 2 Ziffern), aber ist auch so verständlich:

ISR(TIMER0_OVF_vect) 
{
    PORTB |= (1 << active_display); // display OFF (VCC at base)

    active_display ^= 1; // toggle between 0 and 1
    
    if(active_display == 0) // prepare next digit
        display(timer_seconds % 10);
    else
        display((timer_seconds/10) % 10);
        
        PORTB &= ~(1 << active_display); // display ON (GND at base)
}
  1. aktuelles Display aus
  2. Aufs nächste Display schalten
  3. Ziffer berechnen und auf den Datenbus schreiben
  4. Display an

Der Code wird in diesem Beispiel mit ca. 250 Hz ausgeführt. Der schaltet hier bei mit VCC aus und GND an, weil PNP Transistoren verwendet werden.