Dynamisch mit GND verbinden ?

Hallo Leute,

ich habe momentan ein Problem mit einer 7-Segment Anzeige (besser gesagt: ein Bauteil mit vier 7-Segment Anzeigen; den habe ich aus einem alten Receiver ausgebaut). Da ich im Internet nichts dazu finden konnte, habe ich den mal kurz analysiert, und nun weiß ich nicht so recht, wie ich diesen mit einem Arduino ansteuern soll. Funktionieren tut es so: Die Pins 1,4,5 und 12 auf dem Bauteil entscheiden, um welche 7-Segment Anzeige es geht. (1 = erste Anzeige, 4 = zweite anzeige, 5 = dritte, 12 = vierte), jenachdem welchem ich ein HIGH signal gebe. Und die restlichen Pins 2,3,6,7,8,9,10,11 sind für a,b,c,d,e,f,g der jeweiligen Anzeige.

So wie ich das probiert habe, muss ich die abcdefg Ausgänge mit GND verbinden, und so entscheide ich mich, ob diese leuchten sollen.

Im Prinzip kann ich also mit den digitalen Pins am Arduino nur sagen, welche Anzeige ich will, und müsste dann irgendwie steuern können, welche der Anzeige-Pins auf GND dürfen.

Ich bin noch ein Neuling was Elektronik angeht, und ich habe keine Idee wie ich das Problem lösen soll. Also kurz: Ich muss irgendwie entscheiden/ansteuern können, welche der Pins auf GND dürfen, und welche nicht. Vielleicht ist das auch ziemlich simpel und ich komme nicht drauf? g

Naja, ich denke mal dass die Anzige halt flimmern wird. Flimmern in einer Frequenz, die dein Auge nicht sieht. Also: Wähle anzeige 1, sag, was leuchten soll, wähle anzeige zwei, sag was leuchten soll, usw...... Und am Ende sagt dir dein Auge: Die leuchten ja alle wie gewünscht!

Hallo Pumbaa, danke für die Antwort!

Wähle anzeige 1, sag, was leuchten soll

Mir gehts primär darum, dass ich nicht weiß, wie ich (vorerst nur einer einzigen Anzeige) das "sagen" soll. Denn wie erwähnt, muss ich ja anscheinend genau die pins auf GND setzen, die ich zum leuchten bringen will. Wenn ich alle abcdefg Pins auf GND lege, leuchten alle. So wie ich das verstehe, bräuchte ich genau so viele GNDs wie ich Pins zum leuchten bringen will (und dann die möglichkeit, diese zu sperren etc.). Das geht sicherlich viel einfacher. Was muss ich also genau tun, um programmieren zu können, welche der Pins auf GND dürfen und welche nicht? Denn (anscheinend) kann ich nur so ansteuern, welche leuchten sollen.

Kann man die digitalen Pins am Arduino als GND nutzen? Oder liegen diese automatisch an GND wenn ich den Pin als INPUT deklariere? Vermutlich fehlen mir hier einfach die Elektronik-Kenntnisse.

Du kannst einem Pin sagen ob er High (+5V) oder Low (0V = GND) sein soll.

Ich würde so vorgehen, das ich mir eine Bibliothek schreiben würde, in der ich beschreibe, welche Pins High und Low sein müssen um auf der entsprechenden einer, zehner, hunderter.... Stelle die gewünschte Anzeige zu bekommen.

Vielleicht solltest du auch die Anzeige löschen, bevor du dann die nächste Zahl an der 7 Segment anzeige darstellst. So würde der übergang zur nächsten Zahl vielleicht etwas sauberer aussehen und nicht die vorherige Zahl etwas nachscheinen.

Hallo lolminator Vergiß das im Moment mit der Bibiothek schreiben. Ist für den Anfang etwas sehr kompliziert.

Du hast 4 Stellen ; jede Stelle mußt Du einzeln und nacheinander angesteuert werden.

Auf den Segmentpins mußt du Vorwiderstände schalten um den Strom zu begrenzen und auf den Stellenpins einen Transistor weil der der Strom für den Arduino zu groß ist. Schaltung wie diese. http://www.ipd.uka.de/~buchmann/microcontroller/7seg.htm Der demux ist nicht notwendig, die Transistoren können auch direkt vom Arduino angesteuert weren. Am Anfang sind alle Pins der 4 Stellen LOW so daß die Transistoren nicht leiten. Du Schaltest die Segmente die auf der ersten Stelle leuchten sollen auf Masse (LOW), und die nicht leuchten sollen auf +5V (HIGH) dann schaltest Du für eine gewisse Zeit den gemeinsamen Anschluß für die erste Stelle auf +5V (HIGH) und wartest eine gewisse Zeit (sagen wir mal 100 Hz Wiederholung bei 4 Stellen sind das dann 2,5 Milisekunden) Danach schaltest Du den gemeinsamen Anschluß für die erste Stelle wieder auf LOW und machst das gleiche für die 2. 3. und 4. Stelle und dann wieder von vorne beginnend bei Stelle 1. Es gibt spezielle Schaltungen die das machen. Der mAX7219 ist z.B. einer. Den kannst Du aber für Deine Anzeige nicht verwenden da er eine Anzeige mit gemeinsamer Katode braucht und Deine Anzeige mit gemeinsamer Anode ist. Für gemeinsame Anode kenne ich keine Schaltung. Grüeß Uwe

Hallo Leute,
vielen Dank für die Hilfe. Die digitalen Anschlüsse auf HIGH und LOW zu kippen, war der entscheidende Tipp :slight_smile:
Es läuft nun super. Ich habe mir ein paar kleine Funktionen geschrieben, denen ich nur die Zahl geben muss, und die machen den Rest :slight_smile:

Falls irgendwer Interesse am aktuellen Code hat, wieso auch immer:

/**
* 7-Segment Anzeige, mit 4 Anzeigen, und doppelpunkt dazwischen.
*/

int PIN_A = 11; //2
int PIN_B = 7; //6
int PIN_C = 3; //10
int PIN_D = 5; //8
int PIN_E = 6; //7
int PIN_F = 10; //3
int PIN_G = 2; //11
int PIN_PUNKT = 4; //9
int segmentPins[] = {PIN_A, PIN_B, PIN_C, PIN_D, PIN_E, PIN_F, PIN_G, PIN_PUNKT};
int segmentCount = 8;

int SEGMENT_1 = 12; //1
int SEGMENT_2 = 9; //4
int SEGMENT_3 = 8; //5
int SEGMENT_4 = 13; //12

int segmente[] = {SEGMENT_1, SEGMENT_2, SEGMENT_3, SEGMENT_4};

int currentDisplay = 4;

int numbers[][8] = {
                   {1, 1, 1, 1, 1, 1, 0}, //0 
                   {0, 1, 1, 0, 0, 0, 0}, //1
                   {1, 1, 0, 1, 1, 0, 1}, //2
                   {1, 1, 1, 1, 0, 0, 1}, //3
                   {0, 1, 1, 0, 0, 1, 1}, //4
                   {1, 0, 1, 1, 0, 1, 1}, //5
                   {0, 0, 1, 1, 1, 1, 1}, //6
                   {1, 1, 1, 0, 0, 0, 0}, //7
                   {1, 1, 1, 1, 1, 1, 1}, //8
                   {1, 1, 1, 1, 0, 1, 1} // 9
                 };

void displayNumber(int num) {
   for(int i = 0; i < 8; i++) {
     int signal = (numbers[num][i] == 1) ? (0) : (1);
     digitalWrite(segmentPins[i], signal);
   }
}

void displayBigNumber(int num) {
  setDisplay(4);
  displayNumber(num % 10);
  resetDisplay(4);
  
  setDisplay(3);
  displayNumber((num / 10) % 10);
  resetDisplay(3);
  
  setDisplay(2);
  displayNumber((num / 100) % 10);
  resetDisplay(2);
  
  setDisplay(1);
  displayNumber((num / 1000) % 10);
  resetDisplay(1);
}

void setDisplay(int num) {
  
  //alle segmente "loeschen"
  for(int i = 0; i < 4; i++) {
    digitalWrite(segmente[i], LOW); 
  }
  
  digitalWrite(segmente[num - 1], HIGH);
}

void resetDisplay(int num) {
  int c = currentDisplay;
  setDisplay(num);
  for(int i = 0; i < 8; i++) {
     digitalWrite(segmentPins[i], 1);
   } 
   setDisplay(c);
}

void setup()   { 
  Serial.begin(9600);
  for(int i=0; i < segmentCount; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }
  pinMode(SEGMENT_4, OUTPUT);
  pinMode(SEGMENT_3, OUTPUT);
  pinMode(SEGMENT_2, OUTPUT);
  pinMode(SEGMENT_1, OUTPUT);
  setDisplay(4);
}

void loop()                     
{
  for(int i=1234; i<9999; i++) {
    unsigned long start = millis();
    while(millis() - start < 500) {
      displayBigNumber(i);
    }
  }
}

Ich hätte es nie geglaubt, aber es macht tatsächlich Spaß, aus “Müll” etwas neues zu bauen :slight_smile: Ich habe hier noch einige Sachen rumliegen, mal sehn was ich damit alles anstellen kann g
Vielen Dank nochmals für die Hilfe.

Dein Zahlenarray kannste auch mit zehn bytes insgesamt realisieren.

B0101011010 steht dann für die einzelnen Seqmente an/aus.
Und dann mittels “<<” durchshiften und ausgeben :slight_smile:

Und int is eh fast nirgendwo bei dir notwendig.

…irgendwie ist dein Code lustig zu lesen. teils komplizierte spezialsyntax wie der Part mit “?”.
Dann aber wieder stur etwas 4x geschrieben, wo eigentlich ne Schleife sinnvoll wäre.

Hallo!

B0101011010 steht dann für die einzelnen Seqmente an/aus.

Danke, hätte mir klar sein sollen, dass man auf Microcontrollern direkt mit bits arbeiten kann =)

Und int is eh fast nirgendwo bei dir notwendig.

Wie meinst du das? Ich wollte diese Variablen ganz oben eigentlich als Konstante definieren (wie die #defines unter C), aber kA ob das auf arduino so möglich ist.

teils komplizierte spezialsyntax wie der Part mit "?".

Das ist eigentlich ziemlich simpel; sowas wie ein "eine-zeile-if". Der Code soll nur die 1en zu 0en machen, und umgekehrt (da die Anzeige ja anscheinend negiert ist).

Dann aber wieder stur etwas 4x geschrieben, wo eigentlich ne Schleife sinnvoll wäre.

Du hast absolut recht! Das war nur schnell hingeschrieben um es zu testen. btw, um die Länge des Arrays zu kriegen, reicht da sizeof(array) ?

hallo lolminator Ich glaube, daß Pumbaa weiß, daß "? :" gleichbedeutend einer "if else" - Bedingung ist. Daß was er sagen will ist daß Du einerseits diesen Kurzschreibform verwendest die man kennt und benutzt, wenn man C etwas besser kennt und anderseits den Kode wie ein C-Anfänger schreibst, der sich scheut eine Schleife zu programmieren. Dieser Kontrast zwischen einem Anfänger und anderseits einem Fortgeschrittenen C-Programmiere hat Pumbaa zu denken gegeben. Grüße Uwe

Achso, alles klar. Habe wohl nicht aufmerksam genug gelesen :) Ich programmiere schon seit einigen Jahren in C; die Programmierkenntnisse sind hier also nicht das Problem (das, was da so unschön aussieht, resultiert immer davon, dass ich schnell was austesten will, bzw. eine idee schnell umsetzen will, um zu schauen ob es funktioniert ... wer kennt das nicht ?). ;D

so wars gemeint :slight_smile:
Dazu: dachte nur: int für ne einstellige zahl is unötig. defines gehen übrigens. Also es geht wohl mehr als du dich einschränkst.

Und bytes durchshiften is schon gang und gäbe. Also, versuch was deine (mir wahrscheinlich krank überlegenen) skills hergeben. Das meiste wird gehen.