Forum: Mikrocontroller und Digitale Elektronik AtTiny13 PWM Lauflicht


von Martin S. (crocodile)


Lesenswert?

Hallo Zusammen,

bin neu hier und Einsteiger in der Programmierung überhaupt.
Ich versuche seit einiger zeit ein Rotierende licht in C (ähnlich wie 
Knight rider überlappende lauflicht) mit AtTiny13 und 6 LED’s zu 
Programmieren. Aber ohne erfolg. Bitte um Hilfe hier zu erfahrener 
Programmierer.
                             Tiny13
                           ________
Gnd ----<I---------------_I          I_ vdd
Gnd ----<I---------------_I          I_ ---------------I>----gnd
Gnd ----<I---------------_I          I_ ---------------I>----gnd
                          I          I  --------------I>----gnd
                  Gnd     I_________I

Gruss
crocodile

: Verschoben durch Moderator
von hans (Gast)


Lesenswert?


von Flo (Gast)


Lesenswert?

Hast du Vorwiderstände für die LEDs eingebaut ?

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Hallo crocodile,

so schonmal garnicht!
1. LED nicht vom uC treiben sondern gegen GND schalten
2. Vorwiderstand an die LED's

mfg Rene

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rene Schube schrieb:

> 1. LED nicht vom uC treiben sondern gegen GND schalten

Mit welcher Begründung?

> 2. Vorwiderstand an die LED's

It depends.  Wenn der ATtiny13 mit maximal 3 V betrieben wird, geht's
problemlos auch ohne Vorwiderstände.  Bei 5 V allerdings nicht mehr.

von Martin S. (crocodile)


Angehängte Dateien:

Lesenswert?

Hallo,

Danke für die Schnelle Antworten. Also so sieht jetzt mein Schaltplan 
aus:

Danke

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nicht sinnvoll.  Der Betriebsstrom der LED müsste am 1-kΩ-Widerstand
reichlich 20 V abfallen lassen.  Dafür muss man an der Basis des
Transistors nochmal 0,7 V mehr einspeisen.  Das kann der Controller
nicht, da er ja mit einer viel geringeren Spannung betrieben wird.

Warum willst du das alles mit 24 V betreiben?  Der größte Teil der
zugeführten Energie wird dann in Vorwiderständen verheizt.

Was gefällt dir an der weiter oben geposteten Lösung nicht?

Du kannst beim ATtiny13 übrigens nur 5 Pins frei benutzen, der 6.
ist der /RESET-Pin.  Den kann man zwar auch als (schwachen) Ausgang
definieren, aber das ist eine Einbahnstraße: danach ist der Controller
nicht mehr per ISP programmierbar.

von Hermann G. (df2ds)


Lesenswert?

Das ist aber eine Schaltstufe mir Strombegrenzung! Wenn du wirklich ca. 
20mA durch die LED schicken willst, muss der 1K-Widerstand an die 
Kollektorseite des Transistors (unmittelbar vor oder hinter der LED).

Bei der hier beschriebenen Schaltung steigt bei durchgeschaltetem 
Transistor wegen des Spannungsabfalls am 1K-Widerstand das 
Emitterpotenzial an, bis es ca. 0,7V unter der Spannung an der Basis 
ist. Bei VCC=3V ist das also bei ca. 2,3mA der Fall)

Die ATTinys können ca. 20mA treiben (sowohl als Quelle als auch als 
Senke). Eine Transistor-Treiberstufe ist daher nicht zwingend 
erforderlich. In jedem Fall sollte man aber den maximalen Strom 
begrenzen, also

ATTiny-Port-----|R|---LED---GND

oder (klassisch) mit invertierter Logik:

ATTiny-Port-----|R|---LED---VCC

Viel Erfolg!
  Hermann

von Martin S. (crocodile)


Lesenswert?

Hallo,

Also es muss kein 24V sein. Da oben genante lösung auch ok. aber die 
überlappung ist nicht so optimal und es ist in Bascom geschrieben. 
Wollte halt in C was machen.

habe nicht gewusst das mann RESET pin nicht Programmieren kann. es ist 
aber auch ok wenn die nur 5 LED's sind.

Es soll am end effeckt ein Lauflicht in rundumlicht umgewandelt werden.

so ähnlich wie untere beispiel, es ist ein lauflicht aber halt mit 
schöne überlappung.

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

Danke

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Martin Star schrieb:
> Da oben genante lösung auch ok. aber die
> überlappung ist nicht so optimal und es ist in Bascom geschrieben.

Das ändert doch aber nichts daran, dass du die Hardware 1:1 genau
so bauen kannst.  Vielleicht findest du auch noch jemanden, der
dir für die BASCOM-Lösung ein Hexfile zum Ausprobieren compiliert,
dann weißt du, dass die Hardware funktioniert.

von Martin S. (crocodile)


Lesenswert?

Hi,

also mein Hardware ist fertig und leuft einigemasen mit rotary2.asm
aber sehr schnell.

Hat Jemand ne idee wie ich noch lagsamer rotieren kann.


Beitrag "AVR-Lauflicht"

Danke

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Hat Jemand ne idee wie ich noch lagsamer rotieren kann.

Den CPU-Takt mit dem clock prescaler anders teilen als derzeit.

von Martin S. (crocodile)


Lesenswert?

Hi,

Danke für schnelle Antwort aber wenn du mit DELAY meinst, das habe ich 
schon ausprobiert und auf maximal auf 255 gesetzt. es ist trodsdem zu 
schnell.

Danke

von Christian T. (shuzz)


Lesenswert?

Ich glaube, Jörg meint Du sollst den Tiny einfach mit niedrigerem Takt 
laufen lassen.
Wenn ich mich nicht täusche laufen die Dinger ab Werk mit 8MHz internem 
Oszillator. Den kann man durch setzen der FuseBits nochmal um den Faktor 
acht runterteilen, so dass dann im Endeffekt noch 1MHz übrig bleibt. 
Ergebnis: Das Lauflicht läuft nur noch mit 1/8 der vorherigen 
Geschwindigkeit.

von wait (Gast)


Lesenswert?

..nimm statt "Delay" , "WAIT" ..

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christian T. schrieb:
> Den kann man durch setzen der FuseBits nochmal um den Faktor
> acht runterteilen,

Wobei die CKDIV8-Fuse ja nur den clock prescaler auf 1:8 voreinstellt
statt 1:1.  Man kann ihn aber auch zur Laufzeit beliebig zwischen
1:1 und 1:256 (in Zweierpotenzen) umschalten.

Vielleicht ja einfach mal einen Blick ins Datenblatt riskieren,
Abschnit "System Clock and Clock Options", Unterabschnitt "System
Clock Prescaler"?  Ich weiß, RTFM gilt in Zeiten des Internet als
altmodisch, hilft aber manchmal. ;-)

von Martin S. (crocodile)


Lesenswert?

Hallo Leute,

ich muss sagen bis jetzt läuft es PRIMA.
wisst ihr wie ich die Logik invertieren kann?
ich meine jetzt rotiert eine LED und die anderen sind aus. Möchte gern 
alle LED's an sind und die rotierende LED aus ist.

Danke

von Martin S. (crocodile)


Lesenswert?

Was meint ihr was ich hier anderes schreiben muss damit die Logik 
invertieren kann?

.include "tn13def.inc"

.def TEMP   = r16
.def STORE  = r17     ; contains port value for the current LED
.def STORE2 = r18     ; contains port value for the next LED
.def OUTER  = r19     ; fading counter
.def INNER  = r20     ; PWM counter

.equ DELAY = 150

    ; I/O setup
    ; =========
    ldi TEMP, 31      ; switch PB0..PB5 to output
    out DDRB, TEMP

    ldi STORE,  30    ; load start value (LED0 on)
    ldi STORE2, 29    ; load next value (LED1 on)

LOOP:
    inc  INNER         ; increment the inner counter
    cpi  INNER, DELAY  ; have we reached the maximum value?
    brne GO_ON         ; if yes, increment the outer one

    clr  INNER         ; reset inner counter
    inc  OUTER         ; increment outer counter
    cpi  OUTER, DELAY
    breq NEXT_PHASE    ; if it overflows, go to the next LED

GO_ON:
    cp   INNER, OUTER   ; inner > outer?
    brsh THIS_LED       ; if yes, the current LED needs to be on

    out  PORTB, STORE2  ; else the next one
    rjmp LOOP           ; and start over

THIS_LED:
    out  PORTB, STORE   ; switch on current LED
    rjmp LOOP           ; and start over

NEXT_PHASE:
    clr  OUTER          ; reset counter
    mov  STORE, STORE2  ; next LED

    lsl  STORE2         ; shift current value
    ori  STORE2, 1      ; the lsl makes the lsb 0, we need a 1
    sbrs STORE2, 5      ; do we need to wrap around?
    ldi  STORE2, 30     ; if yes, load the initial value
    andi STORE2, 31     ; mask bit 5 to 7

    rjmp LOOP           ; and start over

von Karl H. (kbuchegg)


Lesenswert?

Ich geb zu, die Logik in diesem Programm ist nicht ganz ohne. Ganz im 
Gegenteil ist die sogar ziemlich tricky.

Nichts desto trotz: Wenn du das Tutorial von Anfang an durchgemacht 
hättest, würdest du auf eine Lösung kommen.
Die Ausgabe selbst auf die LED wird immer mit einem kompletten OUT 
gemacht.
D.h. einfach das was ausgegeben werden soll in ein anderes Register 
umkopieren, alle Bits umdrehen (*) und dann erst dieses Zwischenergebnis 
ausgeben. In ein anderes Register deswegen umkopieren, damit diese 
Invertierung nicht die restliche Programmlogik durcheinander bringt.

Die Modifikation ist nicht besonders schwer und man muss dazu noch nicht 
einmal die restliche Programmlogik verstehen.

(*) Die Instruktion COM  macht das

von Martin S. (crocodile)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ich geb zu, die Logik in diesem Programm ist nicht ganz ohne. Ganz im
> Gegenteil ist die sogar ziemlich tricky.
>
> Nichts desto trotz: Wenn du das Tutorial von Anfang an durchgemacht
> hättest, würdest du auf eine Lösung kommen.
> Die Ausgabe selbst auf die LED wird immer mit einem kompletten OUT
> gemacht.
> D.h. einfach das was ausgegeben werden soll in ein anderes Register
> umkopieren, alle Bits umdrehen (*) und dann erst dieses Zwischenergebnis
> ausgeben. In ein anderes Register deswegen umkopieren, damit diese
> Invertierung nicht die restliche Programmlogik durcheinander bringt.
>
> Die Modifikation ist nicht besonders schwer und man muss dazu noch nicht
> einmal die restliche Programmlogik verstehen.
>
> (*) Die Instruktion COM  macht das

Hi,

also, ich würde gerne was du vorgeschlagen hast machen aber habe keine 
ahnung vom Programmierung. Ich bitte euch um eine Lösung. wo soll ich 
dieser COM befehl schreiben damit ich den Leuchtbild invertieren kann.

Danke

von Karl H. (kbuchegg)


Lesenswert?

Martin Star schrieb:

> Hi,
>
> also, ich würde gerne was du vorgeschlagen hast machen aber habe keine
> ahnung vom Programmierung.

Ich geh mal davon aus, dass du Modellbauer bist und dich eigentlich nur 
das Ergebnis interessiert und nicht das Programmieren
1
    ...
2
3
GO_ON:
4
    cp   INNER, OUTER   ; inner > outer?
5
    brsh THIS_LED       ; if yes, the current LED needs to be on
6
7
    mov  STORE2, TEMP                             ; <-----
8
    com  TEMP                                     ; <-----
9
    out  PORTB, TEMP    ; else the next one       ; <-----
10
    rjmp LOOP           ; and start over
11
12
THIS_LED:
13
    mov  STORE, TEMP                              ; <----
14
    com  TEMP                                     ; <----
15
    out  PORTB, TEMP    ; switch on current LED   ; <----
16
    rjmp LOOP           ; and start over
17
18
    ...

Das sollte es eigentlich tun. Die mit <----- markierten Zeilen wurden 
geändert.

von Martin S. (crocodile)


Lesenswert?

> Ich geh mal davon aus, dass du Modellbauer bist und dich eigentlich nur
> das Ergebnis interessiert und nicht das Programmieren
>
> [/avrasm]
>
> Das sollte es eigentlich tun. Die mit <----- markierten Zeilen wurden
> geändert.

Hallo,

da hast du völlig recht das ich ein Modellbauer bin. aber habe schon 
interesse an Programiereung. Die assembler code für mich sind wie 
"Bahnhof"
ich verstehe überhaupt nichts. Kann nur im VisualBasic was schreiben.

aber respect du hast wirklich gut eingeschätzt.

das Programm sieht jetzt so aus und funktioniert nicht so ganz, alle 
LED's bleiben an und Rotieren nicht mehr.

bitte um Hilfe.

.include "tn13def.inc"

.def TEMP   = r16
.def STORE  = r17     ; enthält Port-Wert für die aktuelle LED
.def STORE2 = r18     ; enthält Port-Wert für die nächsten LED
.def OUTER  = r19     ; fading Zähler
.def INNER  = r20     ; PWM Zähler

.equ wait = 250       ; Rotation geschwindikkeit

    ; I/O setup
    ; =========
  ldi TEMP, 30      ; switch PB0..PB5 to output
    out DDRB, TEMP
    ldi STORE,  30    ; Last Startwert (LED0 on)
    ldi STORE2, 29    ; Last nächste wert (LED1 on)

LOOP:
    inc  INNER         ; innere zähler Incrementieren
  cpi  INNER, wait  ; haben wir den maximalen WERT ereeicht?

  brne GO_ON         ; wenn ja, erhöhe die äußere

    clr  INNER         ; innere Zähler zurücksetzen
    inc  OUTER         ; erhöhe äußere(outer) Zähler
    cpi  OUTER, wait
    breq NEXT_PHASE    ; wenn es überläuft, gehe zur nächsten LED

GO_ON:
    cp   INNER, OUTER   ; inner > outer?
    brsh THIS_LED       ; if yes, the current LED needs to be on

    mov  STORE2, TEMP                             ; <-----
    com  TEMP                                     ; <-----
    out  PORTB, TEMP    ; else the next one       ; <-----
    rjmp LOOP           ; and start over


THIS_LED:
    mov  STORE, TEMP                              ; <----
    com  TEMP                                     ; <----
    out  PORTB, TEMP    ; switch on current LED   ; <----
    rjmp LOOP           ; and start over



NEXT_PHASE:
    clr  OUTER          ; Zähler zurücksetzen
    mov  STORE, STORE2  ; nechste LED

    lsl  STORE2         ; aktuelle wert verschieben
    ori  STORE2, 1      ; die lsl macht die lsb 0, brauchen wir eine 1
    sbrs STORE2, 5      ; Rotieren
    ldi  STORE2, 30     ; Wenn Ja, Lade interne Wert
    andi STORE2, 31     ; Maske Bit 5 bis 7

    rjmp LOOP           ; und von vorne beginen


DANKE

von Karl H. (kbuchegg)


Lesenswert?

Martin Star schrieb:

> das Programm sieht jetzt so aus und funktioniert nicht so ganz, alle
> LED's bleiben an und Rotieren nicht mehr.
>

Argh. Man sollte wirklich alles testen ehe man posted :-)


>     mov  STORE2, TEMP                             ; <-----

Anders rum
      mov  TEMP, STORE2

> THIS_LED:
>     mov  STORE, TEMP                              ; <----

und nochmal
      mov  TEMP, STORE


Sorry

von Martin S. (crocodile)


Lesenswert?

Hallo,

ich möchte mich bei euch sehr danken. Das Programm läuft wie geschmiert.

Vielen Dank.

Gruss
Martin

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.