7segmentanzeige mit millis()

Ich will eine multigeplexte 7segmentanzeige mit millis steuern, jedoch habe ich das Problem, das beide Segmentanzeigen den Wert von der ersten Anzeigen.

#include <Wire.h>
const int Elemente[] = { 8, 7, 6, 5, 4, 3, 2 };
const int Anzeige1 = 9;
const int Anzeige2 = 10;
int score1 = 2;
int score2 = 0;
int pause = 3;
unsigned long aktuell = 0;
int endmillis = 0;
int endmillis2 = 0;

//                x:    0  1  2  3  4  5  6  7  8  9
const int Status_a[] = {1, 0, 1, 1, 0, 1, 1, 1, 1, 1};
const int Status_b[] = {1, 1, 1, 1, 1, 0, 0, 1, 1, 1};
const int Status_c[] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1};
const int Status_d[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 1};
const int Status_e[] = {1, 0, 1, 0, 0, 0, 1, 0, 1, 0};
const int Status_f[] = {1, 0, 0, 0, 1, 1, 1, 0, 1, 1};
const int Status_g[] = {0, 0, 1, 1, 1, 1, 1, 0, 1, 1};

void setup() {
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
  for (int x = 0; x < 7; x++) {
    pinMode(Elemente[x], OUTPUT);
  }
  pinMode(Anzeige1, OUTPUT);
  pinMode(Anzeige2, OUTPUT);
}



void loop() {
  unsigned long aktuell = millis();
  while ((aktuell - endmillis) >= pause) {
    aktuell = endmillis;

    Anzeige(score1);
   
      digitalWrite(Anzeige2, LOW);
      digitalWrite(Anzeige1, HIGH);
      Serial.println(score1);
      Serial.println(score2);


      while ((aktuell - endmillis) >= pause) {
        aktuell = endmillis;

        Anzeige(score2);
      
          digitalWrite(Anzeige2, HIGH);
          digitalWrite (Anzeige1, LOW);
          Serial.println(score1);
          Serial.println(score2);
        
      
    }
  }
}


void receiveEvent(int howMany) {

  score1 = Wire.read();
  score2 = Wire.read();

}

void Anzeige(int Ziffer) {

  digitalWrite(Elemente[0], Status_a[Ziffer]);
  digitalWrite(Elemente[1], Status_b[Ziffer]);
  digitalWrite(Elemente[2], Status_c[Ziffer]);
  digitalWrite(Elemente[3], Status_d[Ziffer]);
  digitalWrite(Elemente[4], Status_e[Ziffer]);
  digitalWrite(Elemente[5], Status_f[Ziffer]);
  digitalWrite(Elemente[6], Status_g[Ziffer]);

}

Warum verteilst Du das gleiche Thema auf 2 verschiedene Threads?
Sollen wir Dir jede Antwort doppelt schreiben oder lieber überhaupt nicht antworten?

Gruß Tommy

Ich dachte ich eröffne ein neuen Thread, da es sich ja um ein anderes Problem handelt, ich kann aber auch im gleichen Thread weitermachen.

Mit freundlichen Grüßen
Timrich

@Mod: Bitte zusammenlegen.

Wir sollten im ersten Thread bleiben.

Gruß Tommy

Du baust innerhalb von Loop meherere blockierende Schleifen mit while:

while ((aktuell - endmillis) >= pause) {

Da sollte eher das while durch if ersetzt werden.

Gruß Tommy

Ich habe jetzt meine while-schleifen durch if-Bedingungen ersetzt, jedoch funktioniert es immer noch nicht.

#include <Wire.h>
const int Elemente[] = { 8, 7, 6, 5, 4, 3, 2 };
const int Anzeige1 = 9;
const int Anzeige2 = 10;
int score1 = 0;
int score2 = 0;
const int pause = 30;
unsigned long aktuell = 0;
int endmillis = 0;
int endmillis2 = 0;

//                x:    0  1  2  3  4  5  6  7  8  9
const int Status_a[] = {1, 0, 1, 1, 0, 1, 1, 1, 1, 1};
const int Status_b[] = {1, 1, 1, 1, 1, 0, 0, 1, 1, 1};
const int Status_c[] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1};
const int Status_d[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 1};
const int Status_e[] = {1, 0, 1, 0, 0, 0, 1, 0, 1, 0};
const int Status_f[] = {1, 0, 0, 0, 1, 1, 1, 0, 1, 1};
const int Status_g[] = {0, 0, 1, 1, 1, 1, 1, 0, 1, 1};

void setup() {
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
  for (int x = 0; x < 7; x++) {
    pinMode(Elemente[x], OUTPUT);
  }
  pinMode(Anzeige1, OUTPUT);
  pinMode(Anzeige2, OUTPUT);
}



void loop() {
  unsigned long aktuell = millis();

  if (aktuell - endmillis >= pause) {
    endmillis = aktuell;

    digitalWrite(Anzeige2, LOW);
    digitalWrite(Anzeige1, HIGH);
    Anzeige(score1);


    if (aktuell - endmillis >= pause) {
      endmillis = aktuell;
      digitalWrite(Anzeige2, HIGH);
      digitalWrite (Anzeige1, LOW);
      Anzeige(score2);
    }
  }
}




void receiveEvent(int howMany) {
  score1 = Wire.read();
  score2 = Wire.read();


}

void Anzeige(int Ziffer) {

  digitalWrite(Elemente[0], Status_a[Ziffer]);
  digitalWrite(Elemente[1], Status_b[Ziffer]);
  digitalWrite(Elemente[2], Status_c[Ziffer]);
  digitalWrite(Elemente[3], Status_d[Ziffer]);
  digitalWrite(Elemente[4], Status_e[Ziffer]);
  digitalWrite(Elemente[5], Status_f[Ziffer]);
  digitalWrite(Elemente[6], Status_g[Ziffer]);

}

Mit freundlichen Grüßen
Timrich

endmillis sollte auch unsigned long sein. Sonst fällt mir im Moment nichts auf.
Wie hast Du die Segmente verschaltet?
Wie steuerst Du die einzelnen Ziffern an? Ich hoffe nicht, durch direktes LOW des Arduino-Ausgangs.

Da wäre ein Schaltbild ganz brauchbar. Bleistiftzeichnung genügt. Bitte kein Fritzing.

Gruß Tommy

Hier ein Schaubild, ich kann nicht sehr gut Zeichen, deswegen ist es nicht besonders schön.
edit: das Bild war zu groß um es reinzuposten deswegen wurde es entfernt.
Ich werde im nächsten post das Bild anhängen

HIer jetzt das Schaubild

compressjpeg.zip (1.18 MB)

Mit delay habe ich es geschafft das Programm zum laufen zu bringen, jedoch muss ich es mit millis() machen, da der Rest vom Programm mit millis() funktioniert.

#include <Wire.h>
const int Elemente[] = { 8, 7, 6, 5, 4, 3, 2 };
const int Anzeige1 = 9;
const int Anzeige2 = 10;
int score1 = 0;
int score2 = 0;
const int pause = 30;
unsigned long aktuell = 0;
unsigned long endmillis = 0;
int endmillis2 = 0;

//                x:    0  1  2  3  4  5  6  7  8  9
const int Status_a[] = {1, 0, 1, 1, 0, 1, 1, 1, 1, 1};
const int Status_b[] = {1, 1, 1, 1, 1, 0, 0, 1, 1, 1};
const int Status_c[] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1};
const int Status_d[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 1};
const int Status_e[] = {1, 0, 1, 0, 0, 0, 1, 0, 1, 0};
const int Status_f[] = {1, 0, 0, 0, 1, 1, 1, 0, 1, 1};
const int Status_g[] = {0, 0, 1, 1, 1, 1, 1, 0, 1, 1};

void setup() {
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
  for (int x = 0; x < 7; x++) {
    pinMode(Elemente[x], OUTPUT);
  }
  pinMode(Anzeige1, OUTPUT);
  pinMode(Anzeige2, OUTPUT);
}



void loop() {
  unsigned long aktuell = millis();
  Anzeige(score1);
  delay(3);
  digitalWrite(Anzeige2, HIGH);
  digitalWrite(Anzeige1, LOW);


  Anzeige(score2);
  delay(3);
  digitalWrite(Anzeige2, LOW);
  digitalWrite (Anzeige1, HIGH);
}




void receiveEvent(int howMany) {
  score1 = Wire.read();
  score2 = Wire.read();


}

void Anzeige(int Ziffer) {

  digitalWrite(Elemente[0], Status_a[Ziffer]);
  digitalWrite(Elemente[1], Status_b[Ziffer]);
  digitalWrite(Elemente[2], Status_c[Ziffer]);
  digitalWrite(Elemente[3], Status_d[Ziffer]);
  digitalWrite(Elemente[4], Status_e[Ziffer]);
  digitalWrite(Elemente[5], Status_f[Ziffer]);
  digitalWrite(Elemente[6], Status_g[Ziffer]);

}

timrich01:
HIer jetzt das Schaubild

Dann mach das Bild kleiner, als zip hier posten, ist eine schlechte bis keine Lösung.
Mobilisten können das nicht sehen.

Hier nochmal als kleinere Version

Wohin gehen P9 und P10? und wie groß sind die Widerstände?

Dann stelle uns doch mal den Sketch mit delay() hier rein, evtl. verstehen wir dann Deinen Ablauf besser.
Überigens ist png (wie auch jpg) schon selbst komprimiert, da bringt ein Zippen kaum etwas bzw. das File wird manches Mal sogar größer.

Gruß Tommy

p9 und p10 gehen direkt zu den digital pins 9 und 10 , die widerstände sind 47ohm.
Der Sketch mit delay ist schon angehängt.
Mit freundlichen Grüßen
Timrich

Ok, hatte ich übersehen.

Da Du selbst multiplext, muss das alles sehr schnell gehen. Da ist jedes delay schädlich.

  digitalWrite(Anzeige2, HIGH);
  digitalWrite(Anzeige1, LOW);
  Anzeige(score1);
  
  digitalWrite (Anzeige1, HIGH);
  digitalWrite(Anzeige2, LOW);
  Anzeige(score2);

Probier mal. Das muss immer so schnell wie möglich hintereinander erfolgen.

Ansonsten sind mir die Ströme etwas hoch, auch wenn es gemultiplext wird.

5V - 2,1V (rot) = 2,9V / 47 Ohm = 61 mA pro Segment und noch schlimmer - alles Segmente einer Ziffer gehen auf einen Pin. Bei der 8 sind das alle 7 Segmente, also 431 mA pro Segmentpin.

Das wird Dein Arduino nicht allzulange mitmachen, dann gibt er im günstigen Fall noch Rauchzeichen oder stirbt leise.

Also die Ziffern solltest Du über einen Transistor schalten und dann natürlich LOW und HIGH auf den Ziffernausgängern tauschen.

Ansonsten gibt es auch IC für 7-Segmentanzeigen, die intern den Wert speichern, das wird einfacher.

Gruß Tommy

Ok, ich werde etwas höhere Widerstände nehmen, ich hatte da an 100 ohm bzw 220 ohm widerstände gedacht, reicht das aus?

Zum ursprünglichen Problem zurück. Ich habe das Problem mittlerweile gelöst. Der Fehler den ich gemacht habe, war, dass durch das "if" millis() immer nur durch score 1 gelaufen ist und danach wieder von vorne. Dadurch kam der code nie zu score 2.

Hier das Problem gelöst:

#include <Wire.h>
const int Elemente[] = { 8, 7, 6, 5, 4, 3, 2 };
const int Anzeige1 = 9;
const int Anzeige2 = 10;
int score1 = 0;
int score2 = 0;
const long pause = 3;
unsigned long aktuell = 0;
unsigned long endmillis = 0;
int wechsler = 0;


void setup() {
  Wire.begin(8);
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
  pinMode(Anzeige1, OUTPUT);
  pinMode(Anzeige2, OUTPUT);
}



void loop() {
  aktuell = millis();
  if ((aktuell - endmillis >= pause) && (wechsler == 0)) {
    endmillis = aktuell;
    wechsler = 1;
    Anzeige(score1);

    digitalWrite(Anzeige2, LOW);
    digitalWrite(Anzeige1, HIGH);
  }

  if ((aktuell - endmillis >= pause) && (wechsler==1)) {
    
    endmillis = aktuell;
    wechsler = 0;
    Anzeige(score2);

    digitalWrite(Anzeige2, HIGH);
    digitalWrite (Anzeige1, LOW);

  }
  
}

void receiveEvent(int howMany) {
  score1 = Wire.read();
  score2 = Wire.read();


}

void Anzeige(int Ziffer) {

  digitalWrite(Elemente[0], Status_a[Ziffer]);
  digitalWrite(Elemente[1], Status_b[Ziffer]);
  digitalWrite(Elemente[2], Status_c[Ziffer]);
  digitalWrite(Elemente[3], Status_d[Ziffer]);
  digitalWrite(Elemente[4], Status_e[Ziffer]);
  digitalWrite(Elemente[5], Status_f[Ziffer]);
  digitalWrite(Elemente[6], Status_g[Ziffer]);

}

Vielen Dank für eure Hilfe!
Mit freundlichen Grüßen
Timrich

Gut, dass Du das Problem für Dich lösen konntest. Ich würde Dir trotzdem empfehlen, die Ziffern über einen Transistor oder einen logic level mosfet zu schalten.

Um auf der sicheren Seite zu sein, sollten es >= 150 Ohm sein. Es kann das gleiche Segment ja bei beiden Anzeigen leuchten.

Gruß Tommy

Ok, danke. Werde dann die 220ohm widerstände benutzen.
Mit freundlichen Grüßen
Timrich

Da brauchst Du trotzdem Transistoren auf den gemeinsamen Anoden/Kathoden verwenden.
Grüße Uwe