7-Segment Timer

Hallo Leute,
ich möchte mit dem Arduino Mega 2560 R3 einen Timer programmieren.
Dazu habe ich bisher folgenden Code geschrieben: http://ni112677_4.vweb17.nitrado.net/dl/timer.txt.
Allerdings fehlt der gesamte Void Teil.

Taster sollen als Input fungieren
[+1min/+10min/+30min/+45min/+60min // -1min/-10min/-30min/-45min/-60min // Start // Reset]
[+Zeit // -Zeit // Start // Reset].

Durch die "+/- Zeit" Taster soll Zeit hinzugefügt oder entfernt werden und auch Live auf den 7-Segment Anzeigen wiedergegeben werden
Durch den "Start" oder auch Weiter Taster soll der Countdownvorgang gestartet werden oder wenn der Countdownvorgang gestoppt wurde ihn fortsetzen.
Durch den "Reset" oder auch Stop Taster soll während des Countdownvorganges der Countdownvorgang gestoppt werden und sonst die Zeit resettet werden.

Als Output sollen die einzelnen Segmente der 7-Segment-Anzeigen (6x) angesprochen werden (also nicht binär).

Könnt ihr mir dabei helfen?

Vielen Dank schon mal im Vorraus

MfG
B_A_K_

Wofür, um Himmels Willen, brauchst du den Mega? :astonished:
2x 74HC595 kaskadiert und gut ist. da kannst du an jeden 595 eine 7-Segmentanzeige inklusive Dezimalpunkt anschließen. Oder einen SAA1064, der langt sogar für 4 Anzeigen :smiley:
Preislich kommst du auf alle Fälle günstiger, als mit dem Mega. Der 595 kostet 31 Cent, das Stück und der SAA1064 um die 2€. Einen UNO kannst du sogar durch einen “nackten” ATMEGA328 ersetzen. Oder halt mit einem ProMini, da ist schon alles unbedingt Notwendige mit drauf.
Den 2560 kannst du nicht ohne die Platine betreiben. Somit ist der Mega mit diesem Projekt dauerhaft blockiert.

Gruß Gerald

Man kann die Anzeige auch per Hand multiplexen:

http://codeandlife.com/2012/02/24/7-segment-multiplexing-with-uln2003-pnp-transistors/

P.S.: Das ist AVR Code für einen ATtiny, aber man kann das auch leicht auf den Arduino umschreiben.

nix_mehr_frei:
Wofür, um Himmels Willen, brauchst du den Mega? :astonished:

Ich habe einen Mega 2560 Zuhause rumliegen bzw. geschenkt bekommen und möchte mit ihm einen Timer bauen.

nix_mehr_frei:
2x 74HC595 kaskadiert und gut ist. da kannst du an jeden 595 eine 7-Segmentanzeige inklusive Dezimalpunkt anschließen. Oder einen SAA1064, der langt sogar für 4 Anzeigen :smiley:

Die Frage war ob man mir beim Coden helfen kann und nicht ob es bessere Wege gibt.

nix_mehr_frei:
Preislich kommst du auf alle Fälle günstiger, als mit dem Mega. Der 595 kostet 31 Cent, das Stück und der SAA1064 um die 2€. Einen UNO kannst du sogar durch einen "nackten" ATMEGA328 ersetzen. Oder halt mit einem ProMini, da ist schon alles unbedingt Notwendige mit drauf.

Das mit dem Preis hat sich ja eh erledigt, aber ich brauche für alle 7-Segment-Anzeigen + Taster 54 Ein-bzw. Ausgänge.

nix_mehr_frei:
Den 2560 kannst du nicht ohne die Platine betreiben. Somit ist der Mega mit diesem Projekt dauerhaft blockiert.

Ich habe vor den Time auf nem Breadboard aufzubauen, also nicht anlöten.

Serenifly:
P.S.: Das ist AVR Code für einen ATtiny, aber man kann das auch leicht auf den Arduino umschreiben.

Meinst du diesen Code?:

#define SEG_ALL 0x7F
#define SEG_A 1
#define SEG_B 2
#define SEG_C 4
#define SEG_D 8
#define SEG_E 16
#define SEG_F 32
#define SEG_G 64

// display given digit in seven-segment display
void display(uint8_t n) {
    switch(n) {
        case 0: PORTD = SEG_ALL-SEG_G; break;
        case 1: PORTD = SEG_B+SEG_C; break;
        case 2: PORTD = SEG_ALL-SEG_F-SEG_C; break;
        case 3: PORTD = SEG_ALL-SEG_F-SEG_E; break;
        case 4: PORTD = SEG_F+SEG_G+SEG_B+SEG_C; break;
        case 5: PORTD = SEG_ALL-SEG_B-SEG_E; break;
        case 6: PORTD = SEG_ALL-SEG_B; break;
        case 7: PORTD = SEG_A+SEG_B+SEG_C; break;
        case 8: PORTD = SEG_ALL; break;
        case 9: PORTD = SEG_ALL-SEG_E; break;
        default:PORTD = 0; break;
    }
}

Und wenn müsste er dann so aussehen?:

int SEG_A = 1;
int SEG_B = 2;
int SEG_C = 4;
int SEG_D = 8;
int SEG_E = 16;
int SEG_F = 32;
int SEG_G = 64;

void display(uint8_t n) {
    switch(n) {
        case 0: PORTD = SEG_ALL-SEG_G; break;
        case 1: PORTD = SEG_B+SEG_C; break;
        case 2: PORTD = SEG_ALL-SEG_F-SEG_C; break;
        case 3: PORTD = SEG_ALL-SEG_F-SEG_E; break;
        case 4: PORTD = SEG_F+SEG_G+SEG_B+SEG_C; break;
        case 5: PORTD = SEG_ALL-SEG_B-SEG_E; break;
        case 6: PORTD = SEG_ALL-SEG_B; break;
        case 7: PORTD = SEG_A+SEG_B+SEG_C; break;
        case 8: PORTD = SEG_ALL; break;
        case 9: PORTD = SEG_ALL-SEG_E; break;
        default:PORTD = 0; break;
    }
}

Wenn nein wie müsste er richtig sein?

MfG

B_A_K_

B_A_K_:
aber ich brauche für alle 7-Segment-Anzeigen + Taster 54 Ein-bzw. Ausgänge.

Wenn man das multiplext eben nicht. Dann braucht man nur Segment-Pins für eine Anzeige - also 7 oder 8 - und einen weiteren Pin pro Ziffer um einen Transistor anzusteuern. Also bei 6 Ziffern 13-14 Pins.

Siehe auch hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:7-Segment-Anzeige#Mehrere_7-Segment_Anzeigen.28Multiplexen.29

Meinst du diesen Code?: Und wenn müsste er dann so aussehen?:

Die main Methode ist z.B. auf dem Arduino loop()

Dann musst du die Port Pins richtig zuweisen. Das ist nicht unbedingt Port D. Das Pinout dazu ist hier:
http://www.pighixxx.com/pgdev/Temp/ArduinoMega_b.png
An der Doppelbuchsenleiste sind da mehrere Ports die durchgehend sind und keine Sonderfunktionen haben. z.B. A oder C

Diese Art die Pins anzusprechen ist hier erklärt:

Die Ansteuerung der Transistoren ist das gleiche. Das ist auch nicht unbedingt Port B. Da kannst du aber auch digitalWrite() verwenden. Wenn man da die Pins in einem Array abspeichert und dann schrittweise über das Array iteriert ist das auch nicht mehr Code. Sowas:

const byte numberOfDigits = 6;
const byte transistorPins[] = { 8, 9, 10, ... };
byte currentdigit = 0;

digitalWrite(transistorPins[currentDigit], HIGH);     //PNP aus
//Segement ausgeben
currentDigit = (currentDigit + 1) % numberOfDigits;
digitalWrite(transistorPins[currentDigit], LOW);    //PNP an

Direkte Port Manipulation ist hier nicht unbedingt nötig. Für die Segmente ist es allerdings einfacher.

Dann darfst du nicht Timer0 verwenden, da da schon millis() drauf läuft. Damit kann man sich aber einfach einen Sekunden-Takt erzeugen, statt wie in dem Code mit Timer1.

Um den Multiplex-Takt zu erzeugen, kannst du einfach MsTimer2 verwenden:
http://playground.arduino.cc/Main/MsTimer2
Dann musst du das nicht per Hand einstellen

Damit kannst du ganz einfach alle x ms eine Funktion aufrufen in der das steht was da in TIMER0_OVF_vect (Timer0 Overflow Interrupt) gemacht wird. Also nur jeweils die nächste Ziffer berechnen, die aktuelle Anzeige ausschalten, die neue Ziffer ausgeben und dann die nächste Anzeige einschalten.

Und da der Code nur für 2 Ziffern ist, wird die Berechnung der aktuellen Ziffer bei 6 Ziffern ein wenig anders.

Am besten du machst dir selbst Gedanken darüber, was da jeweils gemacht werden muss anstatt stur den Code zu kopieren. Das sind nämlich nur ein paar Schritte die sich ständig wiederholen :slight_smile:

Bei den Transistoren vielleicht mal schauen ob du Displays mit gemeinsamer Kathode oder Anode hast. Das mit den PNPs ist für gemeinsame Anode.