Pages: [1]   Go Down
Author Topic: Transistor und PWM gedimmte LEDs. (flackern)  (Read 1735 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
Ich bastel grade daran 10 LEDs an den Arduino anzuschliessen die ich über PWM dimmen möchte. Solange ich nicht dimme klappt das auch. Aber sobalt ich dimme flackern die leds wenn ich die Transistoren schalte.

Ich denke das Problem liegt an meinem mangelden verständnis von Transistoren, welches ich trotz Google noch nicht verständlich in meinen Kopf legen konnte :/

Folgenden Aufbau habe ich gebastelt

//Achtung hier folgt völliges Anfängerwissen!

Ich habe 2 Digitalpins genommen um 2 Transistoen vom TYP BC238C zu schalten. Diese sind dann je mit 5 Kathoden der LEDs verbunden.
Die anoden habe ich an 5 PWMausgänge gebastelt. Pin 3 vom Arduino hat so LED 1 und 6, Pin 5 LED 2 und 7 usw.

Jetzt laufen 2 LED von links nach Rechts über das LEDfeld. An der STelle wo dann LED 5 und 6 gleichzeitig angehen müssen die Transitoren schnell geschlatet werden damit LED 1 und 10 nicht mit leuchten. Das klappt auch Prima. Nur wenn ich jetzt anfange eine oder beide LEDs zu dimmen fangen diese an zu flacken wenn sie über diese Position wo die Transistoren schnell geschaltet werden laufen.

Die Transistoren habe ich ohne Widertände an das Arduino angeschlossen, weil ich nicht wusste welche ich nehmen soll. Vieleicht liegt da der Fehler, allerdings gehe ich laut Datenblatt davon aus das er an der Base (da wo der Arduino Ausgang reinkommt 5V benötigt.
Der Emiiter liegt direkt auf GND und am kollektor hängt die Kathode von den 5 LEDs.

http://pdf1.alldatasheet.com/datasheet-pdf/view/2886/MOTOROLA/BC238C.html

mein CODE:

Code:
int LED[11]={-1,3,5,6,9,10,3,5,6,9,10};
int GND[3]={-1,12,11};
int d=1; // Die Pause in Millisek. zwischen dem  Schalten
            // (hab auch 2 und 3 probiert)  

void setup()
    for (int y=1; y<=5; y++) {
       pinMode(LED[y], OUTPUT);
       digitalWrite(LED[y], LOW);
    }

void loop(){
 
        
        int x=6; //Welche LED
        digitalWrite(GND[2],HIGH);
        analogWrite(LED[x],127); //setze ich 127  auf 255 funktioniert es!
        delay(d);
        digitalWrite(GND[2],LOW);
        digitalWrite(LED[x], LOW );
        delay(d);
        digitalWrite(GND[1],HIGH);
        analogWrite(LED[x-1],64 );
        delay(d);
        digitalWrite(GND[1], LOW);
        digitalWrite(LED[x-1],LOW );
        delay(d);
}
// Anfänger geposte aus.

Das ist jetzt nur der Code an der kritischen Stelle mit 2 LEDs. Das klappt leider schon nicht.

Oje, ne menge Text  :-X

Danke an alle die mir helfen  smiley-grin


Gruß Rafael
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

inzwischen glaube ich eher an ein timing Problem. Habe zwar immernoch keinen Basiswiderstand, Allerdings verbessert sich das flackern wenn ich an den Delays rumspiele. kann man einen Deley auch im Nanosekundenbereich setzten ?
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 236
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

das wird schwierig.
16MHz = 16 000 000 Takte pro sekunde.
Jeder dauert also 1/16000000 sekunden.
Somit 1/16 Mikrosekunde= ca.62 Nanosekunden.

Du kannst die aber mal Assemblerbefehle raussuchen.
Einer müsste soetwa wie NOP=NoOperation heißen. Der erzeugt dann deine 62ns Latenz.


Aber ich denke dein Problem liegt woanders. Habe es mir nicht ganz genau angesehen, aber du willst ja die Anoden mit PWM befeuern, und dann über die Kathoden quasi spaltenweise auswählen. (oder andersrum)


Ich glaube da liegt dein Denkfehler. (Oder bei mir...)
Wenn du nur eine einzelne damit leuchten lassen möchtest, dann geht das noch. Aber wenn du sie schnell durchschalten möchtest, dann hast du ja noch eine "zweite PWM" drübergebaut. Das schreit gerade zu nach Flackern in meinen Augen.

Versuch dich mal in die Frequenzeinstellung der PWMAusgänge hier einzulesen. Im Englishsprachigen Forum gibt's da ne nette übersicht drüber, wie man welche Frequenzen erreicht:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/4#4
Vielleicht wirds was, wenn du die PWM nur rasend schnell genug machst.
« Last Edit: December 28, 2009, 01:36:23 pm by willich » Logged

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3495
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Arduino Prescaler stehen normalerweise auf 64 --> die PWM Frequenzen sind dann etwa 500 und 250 Hz.

Jetzt wird durch die äußere Schleife nochmal eine Art PWM drübergelegt die in der Nähe von n Millisekunden liegt.

Das Ergebnis nennt sich je nachdem in welchem Umfeld man es beobachtet mal Schwebung http://de.wikipedia.org/wiki/Schwebung
mal Moiree Effekt http://de.wikipedia.org/wiki/Moir%C3%A9-Effekt.

Nanosekunden Delay auf einem 16 MhZ Chip geht nicht. Mikrosekunden schon (delayMicroseconds()).

Vermutlich wäre es aber besser das ganze Konzept zu überdenken. Was genau willst Du erreichen? Die LEDs unabhängig voneinander dimmen oder alle gemeinsam? Im zweiten Fall wäre es erheblich leichter die Kathoden zu Modulieren und die Anoden zu schalten.

Ansonsten wäre es sinnvoll die beiden Frequenzen möglichst weit auseinander zu bringen. D.h. PWM hochdrehen. Das ist nicht weiter schwierig, bringt aber das Timingverhalten von von delay() durcheinander.

In wiring.c steht:

Code:
#include "wiring_private.h"

// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)

volatile unsigned long timer0_overflow_count = 0;
volatile unsigned long timer0_millis = 0;
static unsigned char timer0_fract = 0;

SIGNAL(TIMER0_OVF_vect)
{
      // copy these to local variables so they can be stored in registers
      // (volatile variables must be read from memory on every access)
      unsigned long m = timer0_millis;
      unsigned char f = timer0_fract;

      m += MILLIS_INC;
      f += FRACT_INC;
      if (f >= FRACT_MAX) {
            f -= FRACT_MAX;
            m += 1;
      }

      timer0_fract = f;
      timer0_millis = m;
      timer0_overflow_count++;
}

Wenn Du also den Prescaler auf 1 stellst, dann wird die ISR 64 mal so oft durchlaufen. Also etwa alle 16 Mikrosekunden. --> es wäre sinnvoll die ISR gleich ganz abzustellen. Ansonsten wird Dein Arduino nur noch in der ISR rumgammeln.

Am bequemsten geht das mit "cli()".

Gruß, Udo
Logged

Check out my experiments http://blog.blinkenlight.net

0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke fuer die ausführlichen Antworten. Werd mit die infos mal in ruhe ansehen.  Das geht mir als Anfänger schon recht weit.. muss erstmal ein paar begriffe googlen. smiley

Ich habs aber auch mit meiner Methode hinbekommen. Hat was gedauert. Aber aufgeben gibts nicht smiley

Hier der Code für die Leds die am Übergang der beiden Kathodenswitche liegt:

Code:
wieLang=0;
  if (x==6) {
    for (int y=1; y<11; y++) {
    analogWrite(LED[y], fadearray[1] );
    }
    while (wieLang<=t) {
      start=millis();
      analogWrite(LED[x-1], fadearray[1] );
      analogWrite(LED[x-2], fadearray[1] );
      analogWrite(LED[x], fadearray[255] );
      delay(1);    
      digitalWrite(GND[2],HIGH);
      delay(3);
      digitalWrite(GND[2],LOW);
      analogWrite(LED[x], fadearray[1] );
      analogWrite(LED[x-1], fadearray[3] );
      analogWrite(LED[x-2], fadearray[2] );
      delay(1);
      digitalWrite(GND[1],HIGH);
      delay(3);
      digitalWrite(GND[1],LOW);
      ende=millis();
      wieLang=wieLang+ende-start;
      }  
    }
    wieLang=0;
  if (x==7) {
    for (int y=1; y<11; y++) {
    analogWrite(LED[y], fadearray[1] );
    }
    
    while (wieLang<=t) {
      start=millis();
      analogWrite(LED[x-1], fadearray[3] );
      analogWrite(LED[x-2], fadearray[1] );
      analogWrite(LED[x], fadearray[255] );
      delay(1);    
      digitalWrite(GND[2],HIGH);
      delay(3);
      digitalWrite(GND[2],LOW);
      analogWrite(LED[x], fadearray[1] );
      analogWrite(LED[x-1], fadearray[1] );
      analogWrite(LED[x-2], fadearray[2] );
      delay(1);
      digitalWrite(GND[1],HIGH);
      delay(3);
      digitalWrite(GND[1],LOW);
      ende=millis();
      wieLang=wieLang+ende-start;
      }
    welcherGND=2;
    }

Timing ist da alles. wenn ich an den delay rumspiele wird unsauber smiley

btw. warum ist die kathodepwm einfacher ?

gruß
Logged

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3495
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Naja, die Idee wäre die PWM an der Kathode wirklich durchlaufen zu lassen und nur die LEDs an und aus zu schalten. Meine Vermutung wäre, daß Du die LEDs eher im Bereich von <= 10 Hz umschalten würdest (d.h. ein gedimmtes Lauflicht). Damit wären dann alle Schwebungseffekte mehr oder weniger weg.

Vieleicht verstehe ich ja aber auch einfach nicht genau was das Ziel ist. Kannst Du das mal detailiert breit treten? Dann wird's mit den Tipps auch leichter. Allerdings: wenn es jetzt geht ist ja alles OK smiley

Ich würde mir übrigens nicht soviel Aufwand machen. Ein Seeduino Mega kostet nicht soviel und hat 14 PWM Ausgänge. Da kann man sich da Multiplexen gleich sparen. Für 2die 0 Euro mehr die das im Vergleich zum Arduino kostet ist es den Zeitaufwand nicht wert. Ausserdem gibt es auch billige Alternativen:

http://www.futurlec.com/ET-AVR_Stamp_Technical.shtml

Gruß, Udo
Logged

Check out my experiments http://blog.blinkenlight.net

0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ziel war es, ein lauflicht ala Knightrider zu basteln, welches aus 10 LEDs besteht. Dabei werden drei LEDs angeschalten. Die 1. ist auf maximaler helligkeit, die anderen sind etwas dunkler. Die laufen dann von rechts nach links.

0000000000

So in etwa. An dem Punkt wo die LEDs dann von Led 5 auf 6 angehen entsteht das Problem mit dem Multiplexing.

Es geht mir hier eher um den Lernwert als um das Projekt. D.h. hier ist der weg das Ziel, nicht das Projekt  8-)

Werd mir jetzt mal einen 3x3 LEDMatrix basteln. Da werde ich dann wieder vor der gleichen Hürde stehen. Diesmal werd ich aber die Kathoden per PWM ansteuern smiley

Hab zwar schon ein paar 74HC595 ICs hier liegen um auch ne 8er Matrix zu basteln, allerdings will ich erstmal ohne Zustazchips auskommen.

Gruß

« Last Edit: December 30, 2009, 05:29:55 am by unic » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so, kelienr nachtrag für die die auch mit LED-Matrixen rumfummeln: Wenn ich die pause zwischen den LED Schaltvorgängen (Kathode Schalten, Pause, Anode Schalten, Pause) auf delayMicroseconds(1); stelle ist kein flimmern mehr wahrzunehmen.

Allerdings muss ich dann die Leds auch mit ca. 5V befeuern damit sie nicht zu dunkel sind. Macht ungefähr 160mA pro LED. Das kommt der maximalen stromstärke der LEDS sehr nahe. Wenn ich die Microsekunde jetzt auf Millisekunden hochstelle verglühen die LEDS smiley Bei 1-10 Microsekunden hatte ich über eine Stunde dauerbetrieb keine  Opfer smiley

gruß
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 588
LumiNet rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bitte mal mal einen Schaltplan. Ich glaube, dass hier niemand eine richtige Vorstellung hat, was Du eigentlich aufgebaut hast.

Wie gross ist der Basiswiderstand oder benutzt Du wirklich noch immer keinen?

Wie gross sind die Vorwiderstände der LEDs?

Die LEDs ziehen wirklich 160mA oder habe ich das falsch verstanden?


Logged


Pages: [1]   Go Up
Jump to: