Forum: Projekte & Code PWM 12V Lampendimmer (Tiny26)


von Stefan G. (steg13)


Angehängte Dateien:

Lesenswert?

hier ein Anfängerprojekt:
über 2 Tasten kann die Helligkeit einer 12V Glühbirne gesteuert werden.

/*
;PWM mit Einstellung von a über 2 Tasten
;
; ================================================
;                   TINY26
; ================================================
;                 __   __
;   PWM-Aus  PB0 |1  |_| 28| PA0 Taste
;            PB1 |2   A  27| PA1 Taste
;            PB2 |3   T  26| PA2
;            PB3 |4   M  25| PA3
;            VCC |5   E  24| GND
;            GND |6   L  23| AVCC
;            PB4 |7      22| PA4
;            PB5 |8   A  21| PA5
;            PB6 |9   T  20| PA6
;   RESET    PB7 |10  m  19| PA7
;                |_________|
;
;
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define F_CPU    4000000      //Interner Taktgenerator auf 4MHz gestellt
                              //FUSE-BIT CKSEL2 und CKSEL3 gesetzt
#define TCCR1A  _SFR_IO8(0x30)
#define PWM1B   0
#define PWM1A   1
#define FOC1B   2
#define FOC1A   3
#define COM1B0  4
#define COM1B1  5
#define COM1A0  6
#define COM1A1  7

#define TCCR1B  _SFR_IO8(0x2F)
#define CS10    0
#define CS11    1
#define CS12    2
#define CS13    3
#define PSR1    6
#define CTC1    7

uint8_t a=10; //Pulspausenverhältnis

void Pause(void) //etwa 0,5s
{ uint8_t i;
  uint8_t j;

  for(i=0;i<30;i++)
  {
    for(j=0;j<250;j++) {}
}}

int main()
{

DDRB  = 0xFF; // PORTB als Ausgang schalten
DDRA  = 0;    // PORTA als Eingang
PORTA = TCCR1A|=(1<<0)|(1<<1); // PULLUP für Tasten Bit 0 und 1

TCCR1A|=(0<<COM1A1)|(1<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<FOC1A)|(0<<F 
OC1B)|(1<<PWM1A)|(1<<PWM1B);//  enable TimerA
TCCR1B|=(1<<CTC1)|(0<<PSR1)|(0<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10); 
// Vorteiler Timer A
/*Vorteiler
CS13 CS12 CS11 CS10
 0    0    0    1   CK
 0    0    1    0   CK/2
 0    0    1    1   CK/4
 0    1    0    1   CK/16
 0    1    1    1   CK/64 */

OCR1B=0x00; // unten immer 0
OCR1C=240;  // Max Zählwert CK/Vorteiler/f (interner Oscill. 
4.000.000Hz)
OCR1A=a;  // oben a(%) * OCR1C (z.B. 50% Puls-Pausenverhältnis)
//Beispiel f=1000Hz

for(;;) //Abfrage der Tasten
  {

  if(bit_is_clear (PINA,0)){
  if(a<220){
    a=a+10;
    OCR1A=a;
  };
  }

  if(bit_is_clear (PINA,1)){
    if(a>10){
    a=a-10;
    OCR1A=a;
  };
  }

  Pause();
  }
}

von unsichtbarer WM-Rahul (Gast)


Lesenswert?

Interessantes Konstrukt:
>PORTA = TCCR1A|=(1<<0)|(1<<1); // PULLUP für Tasten Bit 0 und 1

Warum das:
OCR1C=240;  // Max Zählwert CK/Vorteiler/f (interner Oscill
OCR1A=a;  // oben a(%) * OCR1C (z.B. 50% Puls-Pausenverhältnis)

Zumindest ist a kein % von OCR1C, sondern "pro 241".

Wie entprellst du die Tasten? (Man könnte den Timer "misbrauchen"...)

> (0<<..)
ist sehr sinnlos und verwirrt höchstens beim "flüchtigen" Lesen.

Die Defines sollte man sich eigentlich auch sparen können, weil sie in 
der io.h zum Tiny26 vorhanden sein sollten.

Sonst aber ein nettes Anfängerprojekt.

von Stefan G. (steg13)


Lesenswert?

stimmt alles, danke für die Hinweise.
Neue Version:

/*
;PWM mit Einstellung von a über 2 Tasten
;
; ================================================
;                   TINY26
; ================================================
;                 __   __
;   PWM-Aus  PB0 |1  |_| 28| PA0 Taste
;            PB1 |2   A  27| PA1 Taste
;            PB2 |3   T  26| PA2
;            PB3 |4   M  25| PA3
;            VCC |5   E  24| GND
;            GND |6   L  23| AVCC
;            PB4 |7      22| PA4
;            PB5 |8   A  21| PA5
;            PB6 |9   T  20| PA6
;   RESET    PB7 |10  m  19| PA7
;                |_________|
;
;
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define F_CPU    4000000      //Interner Taktgenerator auf 4MHz gestellt
                              //FUSE-BIT CKSEL2 und CKSEL3 gesetzt

uint8_t a=10; //Pulsverhältnis zu 240

void Pause(void) //etwa 0,5s
{ uint8_t i;
  uint8_t j;

  for(i=0;i<30;i++)
  {
    for(j=0;j<250;j++) {}
}}

int main()
{

DDRB  = 0xFF; // PORTB als Ausgang schalten
DDRA  = 0;    // PORTA als Eingang
PORTA = (1<<0)|(1<<1); // PULLUP für Tasten Bit 0 und 1

TCCR1A|=(1<<COM1A0)|(1<<PWM1A)|(1<<PWM1B);// enable TimerA
TCCR1B|=(1<<CTC1)|(1<<CS11)|(1<<CS10);    // Vorteiler Timer A
/*Vorteiler
CS13 CS12 CS11 CS10
 0    0    0    1   CK
 0    0    1    0   CK/2
 0    0    1    1   CK/4
 0    1    0    1   CK/16
 0    1    1    1   CK/64 */

OCR1B=0x00; // unten immer 0
OCR1C=240;  // Max Zählwert CK/Vorteiler/f (interner Oscill. 
4.000.000Hz)
OCR1A=a;  // oberer Wert  (z.B. a=120 -> 50% Puls-Pausenverhältnis)

for(;;) //Abfrage der Tasten alle 0,5s (Pause)
  {

  if(bit_is_clear (PINA,0)){
  if(a<220){
    a=a+10;
    OCR1A=a;
  };
  }

  if(bit_is_clear (PINA,1)){
    if(a>10){
    a=a-10;
    OCR1A=a;
  };
  }

  Pause();
  }
}


von Karl heinz B. (kbucheg)


Lesenswert?

Wenn ich auch noch darf:

Ein aggressiv optimierender Compiler, lässt dir
davon:
1
void Pause(void) //etwa 0,5s
2
{ uint8_t i;
3
  uint8_t j;
4
5
  for(i=0;i<30;i++)
6
  {
7
    for(j=0;j<250;j++) {}
8
}}

nichts übrig.
Für Warteschleifen, gibt es die <util/delay.h>
und dort die Funktionen _delay_ms und _delay_us.

Achtung: Beide haben Obergrenzen, abhängig vom
Quarztakt. Du wirst die _delay_ms also in
eine Schleife packen muessen.

von Karl heinz B. (kbucheg)


Lesenswert?

Und noch was:
Wenn du für Anfänger schreibst, was grundsätzlich
zu begrüssen ist, dann achte auf deine Code-Formatierung.
Deine Einrückungen da oben sind alles andere als konsistent.
1
  };
2
  }

Der ';' ist überflüssig.

1
for(;;) //Abfrage der Tasten alle 0,5s (Pause)
2
  {
3
4
  if(bit_is_clear (PINA,0)){

Entscheide dich, wo du die { platzierst. Entweder
in der selben Zeile am Ende oder in einer neuen Zeile
drunter. Wenn neue Zeile, dann entweder unter dem Statement
oder eingerückt.
Aber nicht 3 verschiedene Stile in einer Source!

Das wichtigste an einem { } Setzungs- und Einrückstil ist
nicht wie er konkret aussieht, sondern dass man ihn konsequent
durchzieht.

von Benedikt K. (benedikt)


Lesenswert?

Nun mal zur Hardware: In der Schaltung fehlt ein Pufferelko für die 12V. 
Einige 100 bis 1000uF mit nicht allzuhohem ESR sollten es schon sein. 
Sowas ist bei PWM Pflicht. Ebenso der 100nF vor und hinter dem 5V Stabi 
(bzw. ein Elko davor).
Ebenso sollte an den Reset Pin ein kleiner Kondensator gegen Masse.

Der Mosfet Treiber dagegen ist vorbildlich.

von Stefan G. (steg13)


Angehängte Dateien:

Lesenswert?

Danke euch.

Ich habe jetzt doch den Timer zur zyklischen Tastaturabfrage benutzt

Version 3:


/*
;PWM mit Einstellung des Tastgrades über 2 Tasten
;
; ================================================
;                   TINY26
; ================================================
;                 __   __
;   PWM-Aus  PB0 |1  |_| 28| PA0 Taste
;            PB1 |2   A  27| PA1 Taste
;            PB2 |3   T  26| PA2
;            PB3 |4   M  25| PA3
;            VCC |5   E  24| GND
;            GND |6   L  23| AVCC
;            PB4 |7      22| PA4
;            PB5 |8   A  21| PA5
;            PB6 |9   T  20| PA6
;   RESET    PB7 |10  m  19| PA7
;                |_________|
;
;
*/

#define F_CPU    1000000      // Interner Taktgenerator auf 1MHz 
gestellt
                              // FUSE-BIT CKSEL1,CKSEL2 und CKSEL3 
gesetzt
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>

/*********** VARIABLEN **********/

uint8_t a=10;                 // Pulsverhältnis zu 240


/*********** FUNKTIONEN **********/

void timer0_init(void){      // timer 0 Zyklus zur Tastenabfrage
  TCCR0  |= (1 << CS02) | (0 << CS01) | (1 << CS00);// Prescaler Timer 0 
auf 1024 stellen
  TIMSK  |= (1 << TOIE0);                           // Overflow 
Interrupt enable
}

void timer1_init(void){      // timer 1 als PWM einstellen
  TCCR1A|=(1<<COM1A0)|(1<<PWM1A)|(1<<PWM1B);// enable Timer 1
  TCCR1B|=(1<<CTC1)|(1<<CS11)|(1<<CS10);    // Vorteiler Timer 1 hier 4
                                            /* Vorteilereinstellung:
                                             CS13 CS12 CS11 CS10
                                               0    0    0    1   CK
                                               0    0    1    0   CK/2
                                               0    0    1    1   CK/4
                                               0    1    0    1   CK/16
                                               0    1    1    1   CK/64 
*/

  OCR1B=0x00;                 // unten immer 0
  OCR1C=240;                  // max Zählwert
  OCR1A=a;                    // oberer Wert  (z.B. a=120 -> 50% 
Puls-Pausenverhältnis)
}


/*********** INTERRUPTS **********/

SIGNAL (TIMER0_OVF0_vect)     // bei Überlauf (255->0) wird dieser Int. 
ausgelöst)
{
  if(bit_is_clear (PINA,0)){  // wenn Taste gedrückt
    if(a<220){                // und max-wert noch nicht erreicht
      a=a+10;                 // erhöhe max-wert
      OCR1A=a;                // Toogle-wert Timer 1
    }
  }

  if(bit_is_clear (PINA,1)){  // wenn Taste gedrückt
    if(a>10){                 // und min-wert noch nicht erreicht
      a=a-10;                 // erniedrige min-wert
      OCR1A=a;                // Toogle-wert Timer 1
    }
  }

  TCNT0 = 100;                // Timer zählt nun nur noch von 155 bis 
255 (also 100 Takte)
}

/*********** HAUPTPROGRAMM **********/

int main(){
  DDRB  = 0xFF;               // PORTB als Ausgang schalten
  DDRA  = 0;                  // PORTA als Eingang
  PORTA = (1<<0)|(1<<1);      // PULLUP für Tasten Bit 0 und 1

  timer0_init();              // timer 0 Zyklus zur Tastenabfrage
  timer1_init();              // timer 1 als PWM einstellen

  sei();                      // Interrupts einschalten

  for(;;){                    // tue nichts Endlosschleife
  }
}

von unsichtbarer WM-Rahul (Gast)


Lesenswert?

Du fragst du Tasten jetzt zwar in der Timer-ISR ab, due entprellst sie 
aber immer noch nicht. Dazu musst du den aktuellen Zustand der Tasten 
mit dem letzten vergleichen. Wenn die beiden über eine bestimmte Zeit 
gleich bleiben, ist die Taste in einem stabilen Zustand.

von Stefan G. (steg13)


Lesenswert?

Das verstehe ich nicht.
Tastenprellen ensteht doch nur beim Drücken oder?
Die Taste bleibt aber gedrückt bis die gewünschte Heligkeit eingestellt 
ist.
Etwa alle 0,5s wird abgefragt ob eine Taste gedrückt ist und 
entsprechend das Puls/Pausenverhältnis geändert.
Was soll da passieren ohne Entprellung?

von Benedikt K. (benedikt)


Lesenswert?

Ich "entprelle" meine Taster genauso: Einfach den Taster alle 10-100ms 
abfragen. Man erhält nun eine Information ob der Taster gedrückt ist 
oder nicht. Prellt der Taster noch, kann die Information falsch sein 
(was aber nicht weiter stört), denn spätestens beim nächsten Abfragen 
stimmt es. Die Fehlinformation kann keinen zusätzlichen Tastendruck 
bewirken, denn entweder war die Fehlinformation eine 0 oder 1, also 
entweder wurde der eine Zustand zu früh erkannt, oder zu spät.
Ich setze allerdings immer ein Bit, das bedeutet das der Taster gedrückt 
wurde (oder es immer noch ist).

In diesem Fall hier, kann man auf ein Entprellen eigentlich aber 
komplett verzichten.

von Karl heinz B. (kbucheg)


Lesenswert?

> Was soll da passieren ohne Entprellung?

In diesem konkreten Fall nichts. Das liegt daran, dass
es völlig Wurscht ist, ob der µC eine oder zwei Dimmstufen
zu hoch oder zu niedrig liegt. Die Wartezeit von 0.5
Sekunden tut ihr übriges. Allerdings ist 0.5 Sekunden
meist nicht akzeptabel. Im Grunde benutzt du ja die
0.5 Sekunden eigentlich als 'Taste-immer-noch-gedrückt-
Aktion-wiederholen' Timer. Und es gibt natürlich Benutzer
die mal ganz schnell den Taster antippen und wieder
loslassen. In weniger als 0.5 Sekunden. Wenn er Pech
hat, passiert dieser Tastendruck dann in der Zeit
in der der µC grade nicht hinsieht :-)

Anders ist es, wenn wirklich jeder Tastendruck zählt
und der Benutzer einen ganz bestimmten Wert einstellen
muss. Es ist einfach lästig, wenn du kurz auf die
Taste drückst und der µC zählt deine 7-Segment Anzeige
um 2 Einheiten hoch, weil er durch das Prellen die
Sequenz 000000001101111111000000 für den kurzzeitigen
Tastendruck eingelesen hat.

von Stefan G. (steg13)


Angehängte Dateien:

Lesenswert?

Alles richtig und auch wichtig was ihr sagt.

Ich habe ja erst vor ein paar Wochen mir C angefangen.
Vorher habe ich einiges in Ass. geschreiben.

Das PWM war mein 2. Projekt, gleich nach einer blinkenden LED.
Ich wollte es anderen Anfängern zur Verfügung stellen, damit die weiter 
dran rumbasteln. Man ist ja manchmal froh wenn erst mal was 
funktioniert, das man dann anpassen kann.

Die SW hat noch einige Nachteile. z.B wenn ich eine höhere Taktrate 
nehme, geht die Tastenabfrage zu schnell.

Ihr könnt ja gerne hier mal ein paar Codeauschnitte reinstellen, wie man 
es besser machen kann. Dann kann jeder an dem Projekt lernen, weil es ja 
recht überschaubar ist und trotzdem PWM und Timerinter. benutzt.

Ausserdem hielt ich es für wichtig, mal eine funktionierende 
MOSFET-Ansteuerung hier zu verewigen.

Ich hänge hier gerade mal noch die Eagle-Datei dran.
Mit ISP-Stecker

von Karl heinz B. (kbucheg)


Lesenswert?

> Die SW hat noch einige Nachteile. z.B wenn ich eine höhere Taktrate
> nehme, geht die Tastenabfrage zu schnell.
> Ihr könnt ja gerne hier mal ein paar Codeauschnitte reinstellen,
> wie man es besser machen kann


Für die Tastenabfrage gibt es eigentlich nur eine Antwort:

http://www.mikrocontroller.net/articles/Entprellung

Das Teil ist absolut genial.
Unterscheidet zwischen:
  Taste kurz gedrückt
  Benutzer ist auf der Taste eingeschlafen.

Ich würds so machen ( C-Skizze )
1
#define LED_PORT PORTB
2
#define LED_PIN  ( 1 << PINB1 )
3
4
uint8_t PWMCounter;
5
volatile uint8_t LEDValue;
6
7
//
8
// Der Interrupt implementiert die PWM
9
// Ein Zähler läuft von 0 bis 100 durch
10
// Liegt der Zähler unter dem Schwellwert einer Led, so wird
11
// die Led eingeschaltet. Liegt er darüber wird die Led ausgeschaltet.
12
// Durch Verändern das Schwellwertes kann also das Verhältnis
13
// der An-Zeit zur Aus-Zeit einer Led eingestellt werden. Je
14
// laenger eine Led in so einem Zyklus eingeschaltet ist,
15
// desto heller erscheint sie uns.
16
// Die Zyklen muessen natuerlich schnell genug erfolgen, ansonsten
17
// sehen wir nur ein Blinken.
18
//
19
SIGNAL( TIMER0_OVF0_vect )
20
{
21
  //
22
  // Den Zaehler erhoehen. Hat er 100 erreicht (entspricht
23
  // 100 PWM Stufen), dann wieder bei 0 anfangen
24
  //
25
  PWMCounter++;
26
  if( PWMCounter == 101 )
27
    PWMCounter = 0;
28
29
  //
30
  // Muss die LED ein oder ausgeschaltet sein?
31
  //
32
  if( LEDValue < PWMCounter )
33
    LED_PORT |= LED_PIN;     // Led ein
34
  else
35
    LED_PORT &= ~ LED_IN;    // Led aus
36
}
37
38
39
int main()
40
{
41
  LEDValue = 0;     // Led aus
42
43
  // Code zur initialisierung des Timers
44
45
  while( 1 ) {
46
    //
47
    // Die LED etwas heller stellen. Ist der Endwert erreicht
48
    // dann wieder bei ganz Dunkel anfangen
49
    //
50
    if( LEDValue == 100 )
51
      LEDValue = 0;
52
    else
53
      LEDValue++;
54
55
    _dealay_ms( 20 );    // etwas warten
56
  }
57
}

Das Wichtiste an diesem Code ist, dass dieser Code die eigentliche
PWM von einer ev. Auswertung von Tasten, die in main() gemacht
werden würde, trennt. Letztendlich ist es ja für die PWM
völlig egal, wie der Vorgabewert zustandekommt. Bei einer
Meiner Anwendungen hab ich zb. ein Schema aus Hellzeit, Dunkelzeit,
HellHelligkeit, DunkelHelligkeit. Alle 4 Parameter werden mit
Zufallszahlen zur Laufzeit berechnet. Der Effekt ist, dass eine
Ansammlung von 60 Leds völlig unabhängig voneinander vor sich
hinblinken. Mal heller, mal dunkler. Mal sieht es aus wie Sterne
die in einer kalten Winternacht funkeln, mal sieht es aus wie
die Blitzlichtgewitter in einem Sportstadion.

von Stefan M. (Gast)


Lesenswert?

@kbucheg: Deine Anwendung würde mich mal interessieren. Ich bin gerade 
dabei einen Sternenhimmel zu bauen, da sollen die "Sterne" dann auch 
funkeln. Ich habe aber bisher noch nicht die richtigen Parameter dafür 
gefunden. Hast Du da welche parat?

Auch die Ansteuerung würde mich interessieren. Wie steuerst Du 60 LEDs 
unabhängig voneinander?

mfg, Stefan.

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Mega8, 12 Mhz
Daran eine Schieberegisterkette aus 595 + Treiber

Ich benutzte den CTC Modus um den Grundtakt zum raustakten
in die Schieberegister zu kriegen.

Jede Led durchläuft einen Zyklus
1
         Zyklusbegin                           Zyklusende
2
            |                                      |
3
            |                                      |
4
            v                                      v
5
6
Helligkeit
7
^
8
|           ------------------------+
9
|                                   |
10
|                                   |
11
|                                   |
12
|                                   |
13
|                                   |
14
|                                   +---------------
15
|
16
|
17
|
18
+---------------------------------------------------->  Zeit

Der erste Teil des Zyklus ist die 'Hellphase', der zweite
die 'Dunkelphase'.

Für jede Phase sind variabel:
  * die Zeitdauer
  * die Helligkeit

Jede der beiden Variablen folgt einer Gleichung
  Wert = Konstant + zufälliger Anteil

Halte ich den zufälligen Anteil klein, so wirkt sich nur
der konstante Anteil aus und alle LED's verhalten sich gleich.
Je höher ich den zufälligen Anteil wähle, desto größer sind
die Unterschiede von einer Led zur nächsten.

Für jede Led gibt es einen Zähler, der von der maximalen Zeit
(Hell + Dunkel) auf 0 herunterzählt. In der Idle Time, wenn also
der Prozessor nichts anderes zu tun hat, werden sukzessive
alle Zähler überprüft, ob einer davon 0 geworden ist. Wird
so einer aufgefunden, so werden dieser Led neue Werte
verpasst. Das heist die Zeiten wird nicht exakt eingehalten.
Das spielt aber keine grosse Rolle, denn ob die Led jetzt
1/100 Sekunde länger den vorhergehenden Zustand einhält
oder nicht, spielt keine Rolle.

Übrigens: Hell und Dunkelphase muss nicht heissen, dass
die Led in der Hellphase heller sind als in der Dunkelphase :-)
Eine lange Hellphase, in der die Led auf 5% sind und eine sehr
kurze aber helle Dunkelphase gibt auch einen netten Effekt.

Anbei mal das Pgm. Das ganze ist so ausgelegt, dass ich alle
Parameter über die UART verändern kann.
?   Hilfe
i   info über die momentane Einstellung.
g   Die Zyklus ab bzw. einschalten

Ein Besonderheit ist die Verarbeitung von Zahlen. Es wird
zuerst die Zahl angegeben und dann erst die Operation die
damit gemacht werden soll. Um also die konstante Helligkeit
in der Hellphase zu ändern, gebe ich ein:
30o

o ist dabei das Kommando um den konstanten Anteil der Helligkeit
den neuen Wert (in dem Fall 30) zu setzten.

Dazu kommt dann noch ein Bedienteil, der aus ebenfalls einem
Mega8, LCD und 3 Tastern besteht. Die Steuerung über die UART
werde ich beibehalten. Der Steuerteil sitzt hinter der abgehängten
Decke und den Bedienteil möchte ich natürlich bequem in Griffhöhe
haben.

Die Elektronik ist soweit fertig (der eigentliche Rechner für
das Bedienteil muss noch gebaut werden, gestern hab ich die
Platine gemacht, die LCD+Taster Platine ist fertig). Eine erste
Version seiner Programmierung läuft auch schon. Dann brauch
ich nicht mehr mit dem Laptop an den Himmel ran um damit zu
spielen.
Der Deckenaufbau ist soweit auch erledigt, LED eingebaut, der
Steuerrechner hängt noch aus dem Loch in der Decke (damit ich noch
an die RS232 rankomme).
Jetzt kommt der Aufbau der ganzen 'Wandgehäuse'.
Vielleicht mach ich noch ein Video von dem Teil 'in Action'

von Karl H. (kbuchegg)


Lesenswert?

Hier das angekündigte Video

http://www.youtube.com/watch?v=fVBiRZZLLCA

Ich hoffe mal das klappt. Ist meinerstes Video bei YouTube :-)

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Hm, tut's nicht...
1
This is a private video. If you have been sent this video, please make sure you accept the sender's friend request.

von Karl H. (kbuchegg)


Lesenswert?

Ich habs mal auf 'public' gesetzt.

von Michael Wilhelm (Gast)


Lesenswert?

@ Karl heinz,

if( LEDValue == 100 )
      LEDValue = 0;
    else
      LEDValue++;

    _dealay_ms( 20 );

Das macht man aber eigentlich nicht, oder? Wenn das Programm 
umpfangreicher wird, kann durchaus LEDValue = 100 übergangen werden. 
Dann muss ein ganzer Zyklus vergehen, damit das wieder greift. Besser:

if( LEDValue > 99 )
...

MW

von Karl heinz B. (kbucheg)


Lesenswert?

> kann durchaus LEDValue = 100 übergangen werden.

Im Moment kann das nicht passieren.
Das ist die einzige Stelle an der LEDValue geändert wird.

Das ist Code aus der main() Schleife. Die Idee dahinter
ist es, eine kleine Testanwendung zu haben, damit man
auch sieht, dass die LED gedimmt wird. In dem Fall
durchläuft sie eine Helligkeitsrampe. In einer realen
Applikation wird man dafür ja sowieso was anderes machen,
daher hab ich keinen besonderen Aufwand getrieben.

von Fabian B. (fabs)


Lesenswert?

Hallo Karl-Heinz,
was für Treiber hast du denn benutzt hinter den hc595?
Hast du das Projekt denn jetzt finalisiert? Wärest du bereit zu teilen? 
;-)

Gruß
Fabian

von Carsten H. (carsten29)


Lesenswert?

Gibt es von diesem Projekt einen Schaltplan ?

Das wäre echt super !!


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.