Forum: Mikrocontroller und Digitale Elektronik MAX 7219 Leds dimmen selbst wenn OFF


von Julia Kristeva (Gast)


Lesenswert?

Hallo,

Ich steuere einen LED-grid mit 6x6Leds ueber einen Max 7219 und Atmega8 
an. Funktioniert alles bestens soweit, bis auf ein kleines Problem. Wenn 
ich alle Register auf 00 setze (alle LEDs abdrehe) dann glimmen alle 
noch ein bisschen. Ich verwende rote LEDs und fuer jede spalte einen 
vorwiderstand von 1kohm. Wo liegt das Problem? Muss ich den 
Vorwiderstand erhoehen?

danke
julia

von Thorsten (Gast)


Lesenswert?

für den 7219 brauchst du keine widerstände an den leds. datenblatt lesen 
und entprechend den strom am max einstellen.

von Julia Kristeva (Gast)


Lesenswert?

Hallo Thorsten,

Ich hab es selbst ohne Vorwiderstand probiert. Dann leuchten sie auch 
leicht, obwohl ich an alle reihen 0x00 sende. Hab jetzt den Fehler 
entdeckt anscheinend. Ich habe einen Elko jetzt noch am Ausgang vom 7805 
gegen Masse angehaengt. Es lag wohl an der Spannungsversorgung.

danke
Julia

von Julia Kristeva (Gast)


Lesenswert?

Nach kurzem Experimentieren, sehe ich leider, dass die Leds im off modus 
noch immer ein leichtes flackern produzieren?!?! woran kann es liegen, 
dass der ausgang vom MAX 7219 nicht zur gaenze auf GND geht?!

von Peter D. (peda)


Lesenswert?

Zeig dochmal Deinen Schaltplan.

Da wird nichts auf GND gelegt, die LEDs hängen direkt zwischen den 
Anschlüssen.

Und wozu die 1k Widerstände, dann glimmen die LEDs doch nur, wenn sie an 
sind.

Schau Dir doch einfach mal das Datenblatt an, da ist der Schaltplan 
drin.


Bei mir laufen die MAX7219 alle einwandfrei.

Allerdings kann es sein, daß Du ihn durch die Überspannung (fehlender 
Elko) schon geschrottet hast.


Peter

von Julia Kristeva (Gast)


Angehängte Dateien:

Lesenswert?

hi,

sorry, wollte die schematic schnell im eagle zeichnen, aber habe den 
max7219 nicht in der part-bibliothek gehabt. deshalb schnell mit stift 
und papier eingescannt.

danke
julia

von Peter D. (peda)


Lesenswert?

Versuchs mal mit Kathode an die Digits, dann klappts auch mitm Maxim.


Peter

von Julia Kristeva (Gast)


Lesenswert?

Mit den Kathoden an Digits und den Anoden an SEG leuchtet nun gar nichts 
mehr :( . Mein Programm vom Atmega8 schickt alle 500ms 0x00 und 0xff, 
also "verpolung" softwareseitig kanns nicht sein.

danke
Julia

von Magnus Müller (Gast)


Lesenswert?

Julia Kristeva wrote:
> Nach kurzem Experimentieren, sehe ich leider, dass die Leds im off modus
> noch immer ein leichtes flackern produzieren?!?! woran kann es liegen,
> dass der ausgang vom MAX 7219 nicht zur gaenze auf GND geht?!

Ich wage es arg zu bezweifeln, dass der MAX7219 das Flackern verursacht. 
Immerhin beträgt die Wiederholfrequenz 500Hz (Minimum!).

Wie wäre es, wenn du uns mal deinen Code zeigen würdest? Ich denke, dass 
der Fehler dort zu suchen ist.

Ein Tip zur Fehlersuche:

Initialisiere deinen MAX7219 wie gehabt (alle Segmente aus) und schicke 
deinen Controller in eine Endlosschleife (z.B. "for(;;);"). Wenn deine 
LEDs immer noch flackern, kannst du ja nochmal nachfragen ;)

Gruß,
Magnetus

von Julia Kristeva (Gast)


Lesenswert?

ich verwende arduino (www.arduino.cc), eine C-aehnliche sprache (nicht 
verwirrt sein ;) (atmega8 laeuft auf 8Mhz)

// define arduino pins

byte pin_max7219_dataIn =  2;
byte pin_max7219_clock  =  3;
byte pin_max7219_load   =  4;


// specify wiring pin i/o directions
void setPinModes()
{
  pinMode(pin_max7219_dataIn, OUTPUT);
  pinMode(pin_max7219_clock,  OUTPUT);
  pinMode(pin_max7219_load,   OUTPUT);
}

// define max7219 registers
byte max7219_reg_noop    = 0x00;
byte max7219_reg_digit0  = 0x01;
byte max7219_reg_digit1  = 0x02;
byte max7219_reg_digit2  = 0x03;
byte max7219_reg_digit3  = 0x04;
byte max7219_reg_digit4  = 0x05;
byte max7219_reg_digit5  = 0x06;
byte max7219_reg_digit6  = 0x07;
byte max7219_reg_digit7  = 0x08;
byte max7219_reg_decodeMode  = 0x09;
byte max7219_reg_intensity   = 0x0a;
byte max7219_reg_scanLimit   = 0x0b;
byte max7219_reg_shutdown    = 0x0c;
byte max7219_reg_displayTest = 0x0f;

// define max7219 as rows and cols (for nexus 8x8 displays)
byte max7219_row0 = 0x01;
byte max7219_row1 = 0x02;
byte max7219_row2 = 0x03;
byte max7219_row3 = 0x04;
byte max7219_row4 = 0x05;
byte max7219_row5 = 0x06;
byte max7219_row6 = 0x07;
byte max7219_row7 = 0x08;
byte max7219_col0 = 0x01;
byte max7219_col1 = 0x02;
byte max7219_col2 = 0x04;
byte max7219_col3 = 0x08;
byte max7219_col4 = 0x10;
byte max7219_col5 = 0x20;
byte max7219_col6 = 0x40;
byte max7219_col7 = 0x80;

// function to control max7219 data line
void max7219_setData(boolean value)
{
  digitalWrite(pin_max7219_dataIn, value);
}

// function to control max7219 clock line
void max7219_setClock(boolean value)
{
  digitalWrite(pin_max7219_clock, value);
}

// function to control max7219 load line
void max7219_setLoad(boolean value)
{
  digitalWrite(pin_max7219_load, value);
}

// function that puts a byte of data to the max7219
void max7219_putByte(byte data)
{
  byte i = 8;
  byte mask;
  while(i > 0) {
    mask = 0x01 << (i - 1);  // get bitmask
    max7219_setClock(LOW);   // tick
    if (data & mask){    // choose bit
  max7219_setData(HIGH); // send 1
    }
    else{
  max7219_setData(LOW);  // send 0
    }
    max7219_setClock(HIGH);  // tock
    --i;         // move to lesser bit
  }
}

// function that puts a byte of data into a max7219 register
void max7219_put(byte reg, byte data)
{
  max7219_setLoad(LOW); // begin
  max7219_putByte(reg);  // specify register
  max7219_putByte(data); // put data
  max7219_setLoad(LOW);  // latch in data
  max7219_setLoad(HIGH); // end
  max7219_setClock(LOW);   // tick
}

// function that sets brightness of the max7219
void max7219_setIntensity(byte intensity)
{
  // range: 0x00 to 0x0f
  max7219_put(max7219_reg_intensity, intensity & 0x0f);
}

// function that sets the same value for all registers of the max7219
void max7219_all(byte value){
  max7219_put(0x01, value);
  max7219_put(0x02, value);
  max7219_put(0x03, value);
  max7219_put(0x04, value);
  max7219_put(0x05, value);
  max7219_put(0x06, value);
  max7219_put(0x07, value);
  max7219_put(0x08, value);
}

// function that initializes the max7219 to use a matrix of leds
void max7219_init()
{
  max7219_put(max7219_reg_scanLimit, 0x04);   // use 5 columns
  max7219_put(max7219_reg_decodeMode, 0x00);  // using an led matrix 
(not digits)
  max7219_put(max7219_reg_shutdown, 0x01);    // not in shutdown mode
  max7219_put(max7219_reg_displayTest, 0x00); // no display test
  max7219_all(0x00);          // empty registers
  max7219_setIntensity(0x08);         // set initial brightness to dim
}

// program initialization routine
void setup()
{
  beginSerial(9600);
  setPinModes();
  max7219_init();

}

// program loop
void loop()
{
  //printString("blank\n");
  max7219_all(0x00);
  delay(500);
  max7219_all(0xff);
  delay(500);
}

von Magnus Müller (Gast)


Lesenswert?

Schön... ich sehe hier ne menge Funktionen... aber gibts da auch so 
etwas wie eine main() ???

von Magnus Müller (Gast)


Lesenswert?

...und dein "void loop()" bringt dich auch nicht ans Ziel. Von einer 
Schleife (= engl. "loop") ist dort nämlich weit und breit nichts zu 
sehen.

von Julia Kristeva (Gast)


Lesenswert?

das ist die main-function:

void loop()
{
  //printString("blank\n");
  max7219_all(0x00);
  delay(500);
  max7219_all(0xff);
  delay(500);
}

von Julia Kristeva (Gast)


Lesenswert?

die void loop() ist sowas wie eine endlosschleife for (;;)

danke fuer eure geduld!
lg
Julia

von Di P. (drpepper) Benutzerseite


Lesenswert?

[offtopic]
ich würde dir ja raten, auf c umzusteigen... :/
da hast du bei problemen auch ne chance geholfen zu werden :D
[/offtopic]

Du könntest versuchen, den ATMega8 internen SPI zu benutzen. mit 
max7219_putByte bastelst du dir das ja selber. Hättest auf diese weise 
eine fehlerquelle weniger:
1
void SPI_MasterInit(void){
2
  DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);     // set PB2, MOSI and SCK output, all others input
3
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);   // enable SPI, Master, set clock rate fck/16
4
  
5
  PORTB |= (1 << PB5)|(1 << PB2);
6
}
7
8
void max7219_Init(void) {
9
  transmit(0x0C,0x01);  // normal mode
10
  transmit(0x0A,0x08);  // set intensity 0x00 - 0x0F
11
  transmit(0x0B,0x01);  // scan digits 0,1
12
  transmit(0x09,0x00);  // no decoding
13
  transmit2dig(0,0x00);  // digit 0: all off
14
  transmit2dig(1,0x00);  // digit 1: all off
15
}
16
17
void transmit(unsigned char addr, char data) {
18
  PORTB &= ~(1 << PB2);
19
20
  SPDR = addr;               // Start transmission
21
  while(!(SPSR & (1<<SPIF)));       // Wait for transmission complete
22
  
23
  SPDR = data;               // Start transmission
24
  while(!(SPSR & (1<<SPIF)));       // Wait for transmission complete
25
26
  PORTB |= (1 << PB2);
27
}
28
29
void transmit2dig(unsigned char dig, char data) {
30
  transmit(dig + 1, data);
31
}

von Magnus Müller (Gast)


Lesenswert?

Was passiert, wenn du dein void loop() wie folgt gestaltest?
1
void loop()
2
{
3
  //printString("blank\n");
4
  max7219_all(0xff);
5
  delay(500);
6
  max7219_all(0x00);
7
  while(1);
8
}

Anmerkung: "while(1);" ist eine Endlosschleife ohne Inhalt und sollte
           auch unter arduino funktionieren.

Nach meinem Verständnis müssten nach dem Programmstart dann alle LEDs 
für 0,5 Sekunden aufleuchten, und danach allesamt abgeschaltet werden. 
Trifft das in der Praxis auch auf dein Board zu?

Gruß,
Magnetus

von Julia Kristeva (Gast)


Lesenswert?

@daniel:

super! ich moechte schon lang auf C wechseln! wuerde mir das leben 
einfacher/schwieriger machen ;) aber ich scheitere leider schon am 
verstaendniss fuer das << zeichen. weisst du ein gutes tutorial?

@magnetus

die void loop() ist bereits eine endlosschleife. die arduino sprache ist 
eine vereinfachung von c-code, die mittels wrapper dann auf den chip 
gebrannt wird. also, dieser code verursacht, dass alle leds 500ms 
leuchten und 500ms nicht:
1
void loop()
2
{
3
  //printString("blank\n");
4
  max7219_all(0x00);
5
  delay(500);
6
  max7219_all(0xff);
7
  delay(500);
8
}

das ist auch der fall, bloss leuchten sie halt noch ein bisschen, statt 
ganz off zu sein!

danke fuer eure hilfe
Julia

von Magnus Müller (Gast)


Lesenswert?

Julia Kristeva wrote:
> @magnetus
>
> die void loop() ist bereits eine endlosschleife. die arduino sprache ist
> eine vereinfachung von c-code, die mittels wrapper dann auf den chip
> gebrannt wird. also, dieser code verursacht, dass alle leds 500ms
> leuchten und 500ms nicht:

(...)

> das ist auch der fall, bloss leuchten sie halt noch ein bisschen, statt
> ganz off zu sein!

Du hast nicht ganz verstanden, was ich damit bezwecke:

Das Programm soll (zu Testzwecken) alle LEDs für die Dauer von 0,5 
Sekunden anschalten, danach wieder ausschalten und in einer 
ENDLOSSCHLEIFE VERHARREN.

Warum?

Weil:

1.) Wenn die LEDs wie gewünscht für 0,5 Sekunden aufleuchten, bedeutet
    das, dass die "delay(500);" wirklich 500ms verzögert.

2.) Wenn die LEDs danach weiterhin leicht vor sich hin flackern würde
    dies auf ein HARDWAREPROBLEM deuten. Anderenfalls wäre der Fehler
    dann doch im ursprünglichen PROGRAMMCODE zu suchen.

Gruß,
Magnetus

von Magnus Müller (Gast)


Lesenswert?

Ok... ich hab den (Hardware-) Fehler gefunden... Erklärung kommt 
gleich...

von Magnus Müller (Gast)


Lesenswert?

Peter Dannegger wrote:
> Versuchs mal mit Kathode an die Digits, dann klappts auch mitm Maxim.

Julia Kristeva wrote:
> Mit den Kathoden an Digits und den Anoden an SEG leuchtet nun gar nichts
> mehr :( . Mein Programm vom Atmega8 schickt alle 500ms 0x00 und 0xff,
> also "verpolung" softwareseitig kanns nicht sein.

Peter hat definitiv Recht. Der Sinn des Lebens eines MAX7219 besteht 
darin, (7Segment-) Displays mit gemeinsamer KATHODE anzusteuern.

Mist... Freundin ruft... muss wech... ;)

von Julia Kristeva (Gast)


Lesenswert?

@magnetus

> Du hast nicht ganz verstanden, was ich damit bezwecke:

> Das Programm soll (zu Testzwecken) alle LEDs für die Dauer von 0,5
> Sekunden anschalten, danach wieder ausschalten und in einer
> ENDLOSSCHLEIFE VERHARREN.

ah sorry, fehlleitung in meinem hirn. habs verstanden und werd es morgen
gleich ausprobieren!

> Peter hat definitiv Recht. Der Sinn des Lebens eines MAX7219 besteht
> darin, (7Segment-) Displays mit gemeinsamer KATHODE anzusteuern.

aber, sehe nicht wirklich einen Unterschied (bis auf optisch) zwischen 
einem 7-segment Display und einem LED-Grid, welches genauso gemeinsame 
Kathode besitzt. siehe mein schaltplan ;)

> Mist... Freundin ruft... muss wech... ;)
lass sie nicht warten ;)

danke trotzdem && melde mich bei erfolgen
Julia

von Julia Kristeva (Gast)


Lesenswert?

> Was passiert, wenn du dein void loop() wie folgt gestaltest?
1
void loop()
2
{
3
  //printString("blank\n");
4
  max7219_all(0xff);
5
  delay(500);
6
  max7219_all(0x00);
7
  while(1);
8
}

die leds leuchten fuer 500ms auf. danach gehen sie einen zustand ueber 
sie leicht aufleuchten in unregelmaessigen abstaenden? irgendwie siehts 
wie ein massedefekt aus? oder doch ein fehler in der schaltung?

von Julia Kristeva (Gast)


Lesenswert?

Loesung/Fehler gefunden!

hoppla zunaechst 10k widerstand nicht auf ISET sondern auf Vc. und 
magnetus hat natuerlich recht:

die gemeinsame kathoden auf DIG0-DIG8.

danke fuer eure hilfe!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.