Forum: Mikrocontroller und Digitale Elektronik Henne´s LED DMX Transceiver


von Peter (Gast)


Lesenswert?

Hallo Gemeinde,

ich bin neu hier und noch nicht ganz so fit in AVR ASM (ich kann noch 
nicht Digital denken :-))

Ich habe den LED DMX Transceiver von hoelscher-hi.de nachgebaut.

Besten Dank an Herrn Hoelscher für die Super Webside und den QuellCodes.

Ich möchte den 10.DMX Kanal zu einen Gesamtdimmer (für alle 8 Kanäle) 
umprogrammieren und den 9 Output weglassen.

Weglassen kein Problem...bloß wie wird programmiert das die 8 Kanäle 
nicht über den eingestellten Wert des Gesamtdimmers gehen?

Könnt ihr mir bitte einen Tip geben wie man sowas umsetzt oder wo ich 
den Wert des Gesamtdimmers r22 einbauen muss.


hier paar Codeschnipsel:

Timer0 Overflow Interrupt :

lds    tempL, PWM_FIELD
cp    tempL, PwmCnt
ror    status

rjmp  pwm_exit


pwm_exit:
  out     portA,status      ;output

  mov    tempL, PwmCnt  ;set next compare time
  lsr    tempL
  lsr    tempL
  lsr    tempL
  ldi    status, 250
  sub    status, tempL
  out    TCNT0, status

  inc    PwmCnt
  tst    PwmCnt
  brne  pwm_no_reload
  lds    tempL,(DMX_FIELD+1)  ;refresh channels
  sts    PWM_FIELD, tempL

        lds             r22,(DMX_FIELD+9)



Besten Dank für eure Hilfe.

Gruß Peter

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Kommt erstmal drauf an, was du willst:
* Die ersten 8 Dimmer sind einzeln regelbar, aber wenn der Wert von 
Kanal 10 (warum nicht Kanal 9, damit verschwendest du keinen Kanal ?) 
überschritten wird, werden die Werte der 8 Dimmer gecappt.
*Die Werte der 8 Dimmer werden mit Dimmer 10 multipliziert, damit wirkt 
Kanal 10 wie ein Summenregler, das Verhältnis der 8 Dimmer untereinander 
bleibt aber gleich.

Lösung 1 ist per Subtraktion machbar:
1
      push  PWM_10   ; ist wohl r22 bei dir, rette ihn erstmal
2
      sub   PWM_10,PWM_X  ; dein zu testender Kanal ist PWM_X
3
      pop   PWM_10
4
      brcc  nocap    ; der wert des testregister war nicht über dem Limit
5
      mov   PWM_X,PWM_10  ; dch war er, setzt ihn aufs limit

Für den 2ten Ansatz multiplizierst du den Kanal 10 mit Kanal 1 - Kanal 
8.
Ergebnis ist ein 16 bit Wert, von dem du dann nur das hohe Byte 
auswertest.

von Peter S. (schzzz)


Lesenswert?

Ein gesundes und erfolreiches neues Jahr wünsche ich allen hier im 
Forum.

Besten Dank  Matthias für die rasche Antwort.
Die DMX Kanal zuordnung ist mir erstmal Wurst es geht erstmal nur darum 
zu Verstehen wie es funzt.

Das ganze soll ne Ansteuerung für einen RGB LED Fluter werden wo ich 
über 3 DMX Kanäle die Farbe einstelle und der 4. DMX Kanal ist dann die 
Helligkeit der eingestellten Farbe. Analog den Eurolite LED Rampen

Habe dein Vorschalg auch gleich mal ausprobiert.

pwm1:  lds  tempL, PWM_FIELD
  sub   Dim_ges, tempL
  brcc  pwm2
  mov   tempL, Dim_ges


pwm2:  cp  tempL, PwmCnt
  ror  status

  lds  tempL, (PWM_FIELD+1)
  cp  tempL, PwmCnt
  ror  status

  lds    tempL, (DMX_FIELD+1)  ;refresh channels
  sts    PWM_FIELD, tempL

  lds    Dim_ges, (DMX_FIELD+9)
  sts    (PWM_FIELD+8), Dim_ges

Aber die Variante ist so toll.
Mit der zweiten komme ich noch nicht klar.
Im Tutorial steht:

mul r16, r17 ; multipliziert r16 mit r17. Beide Registerinhalte
             ; werden als vorzeichenlose Zahlen aufgefasst.
             ; Das Ergebnis der Multiplikation ist in den Registern
             ; ro und r1 zu finden.

also werte ich nur r1 aus für meien Vergleichswert nor?


  lds    tempL, PWM_FIELD
  mul    Dim_ges, tempL
  cp     r1, PwmCnt
  ror    status

habe ich das so richtig verstanden?

Ich habe auch vom Steffen H. ein Projekt gefunden was danke ich meinen 
Vorstellungen erfüllt. Aber hat die Farben fest vorgegeben.

Beitrag "[ASM] DMX512 oder SPI zu RGB Led Controller use HSV Farbraum"

aber bin dabei gescheidert es zu meinen ATMega 8515 umzuschreiben weil 
ich nicht weiß was GPIOR0 für ein Register beim ATTINY ist.

Gruß Peter

von Kartoffelbauer (Gast)


Lesenswert?

GPIO = General Purpose Input/Output
was bleibt dann übrig ?
R0 !

Frohes neues

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter Schulz schrieb:
> Das ganze soll ne Ansteuerung für einen RGB LED Fluter werden wo ich
> über 3 DMX Kanäle die Farbe einstelle und der 4. DMX Kanal ist dann die
> Helligkeit der eingestellten Farbe.

Du willst also die Multiplizier Variante, damit das Verhältnis von R, G 
und B konstant bleibt.
Peter Schulz schrieb:
> also werte ich nur r1 aus für meien Vergleichswert nor?
>
>
>   lds    tempL, PWM_FIELD
>   mul    Dim_ges, tempL
>   cp     r1, PwmCnt
>   ror    status
Ok, der 8515 unterstützt MUL, da musste ich erstmal nachschauen. Du 
brauchst hier gar nicht mehr zu vergleichen, denn du willst ja nicht 
cappen, sondern lediglich R,G und B mit dem Master multiplizieren. Also
>   lds    tempL, PWM_FIELD    ;
>   mul    Dim_ges, tempL
ist ok. Dann kommt nur noch:
    mov    PWM_FIELD,r1

Allerdings setzt das voraus, das PWM_FIELD der jeweilige Kanal ist. Um 
gleich mehrere Kanäle in einem Rutsch zu berechnen, kannst du schreiben:
1
multDMX:
2
   ldi   YL,low(PWM_FIELD+3)    ; Kanal 4 sei Masterwert
3
   ldi   YH,high(PWM_FIELD)
4
   ld    r18,Y                ; r18 hält nun Masterwert
5
   ldi   YL,low(PWM_FIELD)    ; Y wird unser Pointer ins DMX Datenfeld
6
   ldi   r24,3                ; zählt 3 Kanäle ab
7
multloop:
8
   ld    r16,Y               ; Kanaldaten
9
   mul   r16,r18             ; eigentliche Operation
10
   st    Y+,r1               ; zurückschreiben ins DMX Feld
11
   dec   r24                 ; ich sags dreimal
12
   brne  multloop
13
   ret
Wenn du die Operation direkt nach einem erfolgreichen DMX Paketempfang 
machst, sollte das so klappen, ohne das der PWM Timer davon beeinflusst 
wird. Y sollte natürlich nicht durch anderen Kram belegt sein. Das 
gleiche geht auch mit X, falls der frei sein sollte. Falls nicht, machst 
du vor der Operation noch:
    push YL
    push YH
und danach
    pop  YH
    pop  YL

Kartoffelbauer schrieb:
> GPIO = General Purpose Input/Output
> was bleibt dann übrig ?
> R0 !
>
> Frohes neues

Ganz so simpel ist das nicht. GPIOR0 ist ein neues Register für 
schnellen Zugriff, das es auf älteren AVRs noch nicht gibt. Du kannst 
stattdessen eines der üblichen Register ab r16 und höher nehmen.

von Peter S. (schzzz)


Lesenswert?

Geil Super es klappt mit den Masterdimmer...

COOL Besten DANK Matthias für deine schnelle Hilfe.

von Peter S. (schzzz)


Angehängte Dateien:

Lesenswert?

Servus Leute,

ich hab noch ein Problem.
Ich will den "manuel Chaser Mode" auf 12 Kanäle erweitern.
Original ist er auf 9CH. Wie bekomme ich noch 3CH hinzu?

Was ich rausbekommen habe ist, dass im manuel Chaser Mode immer Werte 
ins DMX_Field geschrieben werden und diese dann durch eine PWM Ausgabe 
ausgegeben werden --> also so als steuert man das Teil mit DMX bloß das 
dies intern abläuft.

Die LEDs die leuchten sollen wird in PAT 0 - 7 angeben und die werden 
vermutlich ins Z-Register eingelesen und das X-Register ist dann der 
Zeiger aufs DMX_Field so habe ichs es verstanden.

Bloß wo muss man angeben, dass DMX_Field 10-12 (das hab ich noch 
hinzugefügt) auch mit Daten gefüttert wird?

Kann mir jemand helfen?

Interressant wäre auch noch, wie er weiß zu welchen "PAT" er gehen muss.
Eingestellt wird es mit den DIP Schaltern (kein DIP Schalter auf on --> 
PAT0; DIP Schalter 1,2,3 auf on --> PAT 7)


Gruß Peter

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter Schulz schrieb:
> Interressant wäre auch noch, wie er weiß zu welchen "PAT" er gehen muss.
> Eingestellt wird es mit den DIP Schaltern (kein DIP Schalter auf on -->
> PAT0; DIP Schalter 1,2,3 auf on --> PAT 7)

Das passiert in den letzten paar Zeilen:
1
  in  ZL, PinC       ; lese DIP Schalter
2
  com  ZL             ; invertiere den Wert
3
  andi  ZL, 0b00000111  ; maskiere Pin0-Pin2
4
  ldi  tempH, 10       ; jedes Pattern ist 10 bytes lang
5
  mul  ZL, tempH  
6
  sts  StepCnt,r0    
7
;r0,r1 ist das ergebnis der Multiplikation

von Steffen H. (avrsteffen)


Lesenswert?

Peter Schulz schrieb:
> Ich habe auch vom Steffen H. ein Projekt gefunden was danke ich meinen
> Vorstellungen erfüllt. Aber hat die Farben fest vorgegeben.
Die Farben sind nicht fest vorgegeben. Man erreicht in der 
3-Kanal-Variante alle Farben. In der 2-Kanal-Variante sind es noch ca 
240 + weiß. Allerdings kann man da die Helligkeit sehr einfach regeln.

Welchen 8515 nimmst du denn? Den AT90S8515 oder den ATMEGA8515 ? Dann 
kann ich dir die Firmware umschreiben.

Peter Schulz schrieb:
> ich hab noch ein Problem.
> Ich will den "manuel Chaser Mode" auf 12 Kanäle erweitern.
Soll das heißen, du willst jetzt 12 DMX Kanäle für deine LED-PWM haben? 
Also 4 RGB-LED damit steuern? Plus einen Master-Kanal über die 4 
RGB-Kanäle?

Gruß Steffen H.

von Steffen H. (avrsteffen)


Lesenswert?

Peter Schulz schrieb:
> aber bin dabei gescheidert es zu meinen ATMega 8515 umzuschreiben weil
> ich nicht weiß was GPIOR0 für ein Register beim ATTINY ist.

Zum Testen ganz einfach:
Benenne einfach das GPIOR0 in EEDR um. Das geht bei dem AT90S8515 und 
beim ATmega8515.

von Peter S. (schzzz)


Lesenswert?

@ Matthias

Besten Dank für die Erklärung.

Wenn ich aus der 10 z.b. eine 11 mache liest er dann ja 11 BITS ein 
oder?
Da sollten ja mehr Kanäle ansprechbar sein?
Warum es immer 1BIT mehr ist als Kanäle versteh ich sowieso nicht.

dann muss ich bestimmt noch den Behl:

st    X, tempH

abändern in

st    X+, tempH

damit er weitere DMX_Fields schreibt oder vestehe ich das so richtig?



@  Steffen H.

Steffen H. schrieb:
> Welchen 8515 nimmst du denn? Den AT90S8515 oder den ATMEGA8515 ? Dann
> kann ich dir die Firmware umschreiben.

Es ist ein ATMega 8515.

Steffen H. schrieb:
> Soll das heißen, du willst jetzt 12 DMX Kanäle für deine LED-PWM haben?
> Also 4 RGB-LED damit steuern? Plus einen Master-Kanal über die 4
> RGB-Kanäle?

Jo richtig. Klingst aber so als wäre es schwer umsetzbar?

Das ganze soll eine Ansteuerung für einen RGB Fluter werden mit 324 LEDs 
und das so, dass 4 Zeilen (je 36 Rot Grün Blaue LEDs) angesteuert werden 
--> deswegen die 12 Kanäle 4 Zeilen je RGB.

10 LEDs steuer ich schon an über DMX, in meinen Testaufbau einzeln und 
über alle 10 --> Dank Matthias einen Gesamtdimmer.

Weil Herr Hoelscher dort noch einen Coolen Stand Alone Modus eingebaut 
hat der ohne DMX-Ansteuerung alleine sein Ding macht fande ich dieses 
Teil einfach genial.

Es fehlen mir halt nur noch 3 Kanäle für den Stand Alone Modus.


Steffen H. schrieb:
> Zum Testen ganz einfach:
> Benenne einfach das GPIOR0 in EEDR um. Das geht bei dem AT90S8515 und
> beim ATmega8515.
Wenn so einfach ist brauchst die Firmware nicht umschreiben.

Das werde ich mal testen

Besten Dank

von Steffen H. (avrsteffen)


Lesenswert?

Peter Schulz schrieb:
> Wenn so einfach ist brauchst die Firmware nicht umschreiben.

Ich hab es trotzdem mal gemacht, da es doch noch ein wenig anderes zu 
ändern gab.

Peter Schulz schrieb:
> Steffen H. schrieb:
>> Soll das heißen, du willst jetzt 12 DMX Kanäle für deine LED-PWM haben?
>> Also 4 RGB-LED damit steuern? Plus einen Master-Kanal über die 4
>> RGB-Kanäle?
>
> Jo richtig. Klingst aber so als wäre es schwer umsetzbar?

Ist es auch, denn bei LED's sollte die PWM Frequenz schon hoch sein, 
damit man kein flackern sieht. Bei Glühlampen reichen da 50-100Hz. 
Leider ist ein AVR mit der HSV->RGB Umrechnung schon ganz schön 
ausgelastet. Man müsste es mal ausprobieren, aber ich denke für 4-RGB 
Kanäle schafft er das nicht mehr. Außerdem kommt da ja noch die 12bit 
Software-PWM für 12-Kanäle mit zu. Man könnte allerdings je RGB Kanal 
einen tiny2313 nehmen. Das sollte sogar günstiger sein, als ein 
mega8514.



Die Methode von Matthias es über eine PDM zu machen finde ich nicht 
schlecht. Allerdings sind die Helligkeitswerte der LED auch nicht 
unserem Auge damit angepasst. Bei 50% leuchtet die LED scheinbar schon 
mit 70-80% ihrer Helligkeit.


Gruß Steffen

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Datei vergessen..

von Peter S. (schzzz)


Lesenswert?

Coooool Danke Steffen

von Peter S. (schzzz)


Angehängte Dateien:

Lesenswert?

Sorry Steffen aber irgentwie wills ni.

Habe einen neuen ATmega8515 genommen und die Fuses auf externen OC 
gestellt
(CKSEL=1111 SUT=11)

und noch Port Zuweisung angepasst

------ LED PORT ZUWEISUNG ----------------------
.equ    RGB_LED_PORT      = PORTA
.equ    RED               = 2      ; LED_ROT
.equ    GREEN             = 1      ; LED_GRUEN
.equ    BLUE              = 0      ; LED_BLAU
;------------------------------------------------
.equ  DMX_SIG_LED_PORT  = PORTD
.equ  DMX_SIGNAL_LED    = 7
;------------------------------------------------
.equ    FKT_PORT          = PORTE
.equ    FUNKTION          = 1
;------------------------------------------------

Im Debuger des AVR Studios hängt des Programm sehr lange in dieser 
Funktion:
loop_clr_ram:
      st    x+,NULL
      dec    r16
      brne  loop_clr_ram

Ist das normal?

von Steffen H. (avrsteffen)


Lesenswert?

Peter S. schrieb:
> Sorry Steffen aber irgentwie wills ni.

Ah, okay. Da war der Stackpointer noch nicht richtig initialisiert. 
Außerdem waren die Interrupt-Vektoren noch vom tiny2313.

Hab alles berichtigt. Kann es allerdings leider nicht testen. Sollte 
jetzt aber funktionieren.


Steffen

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Wieder die Datei vergessen.. schon zu spät

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter S. schrieb:
> Wenn ich aus der 10 z.b. eine 11 mache liest er dann ja 11 BITS ein
> oder?
> Da sollten ja mehr Kanäle ansprechbar sein?
> Warum es immer 1BIT mehr ist als Kanäle versteh ich sowieso nicht.

Nein, das sind keine Bits, sondern die Länge des Pattern. Jedes Pattern 
ist 10 bytes lang, und um aus der Stellung der Dipschalter die 
Startadresse des Pattern zu bekommen, muss man mit der Länge des Pattern 
multiplizieren:

Anfangsadresse = (Dipschalter*10) + Offset des Pattern im Flash. Der 
Offset ist die Adresse, an der die Patterntabellen anfangen.

In Pseudoassembler sieht das so aus:

Lade Z mit dem Offset der Pattern im Flash
Lese DIP Switch und mach daraus eine Zahl zwischen 0 und 7, dann 
multipliziere mit der Länge eines Patterns (ist dann 0 bis 70)
Addiere das Ergebnis zu Z
Z enthält jetzt die Anfangsadresse des gewünschten Pattern. Das gezeigte 
Verfahren wird z.B. auch oft benutzt, um auf Fonttabellen im Flash 
zuzugreifen. Jeder Buchstaben belegt z.B. 8 Bytes. Dann wird der 
Asciiwert des gewünschten Buchstaben mit 8 mal genommen und ist dann der 
Zeiger auf das Buchstabenmuster.

von Peter S. (schzzz)


Lesenswert?

Danke Steffen

Aber es geht trotzdem noch ni. Es reagiert nicht auf DMX Daten und die 
LEDs flackern nur komisch rum.
Hoffe ich mache dir nicht all zu viel Arbeit?

Um es einfacher zu machen bestell ich mir einen Tiny der kostet 1,30€ 
und spiel deine alte Firmware ein.

@ Matthias

Ah jetzt verstehe ich. Jetzt könnte ich ja 15 Pattern programmieren, 
weil DIPSchalter 4 noch frei ist --> cool.

Muss ich halt bloß die Adressen erweitern und wenn mehr Daten rein 
sollen die nächste Adresse nicht bei 10 (+0xA) sondern z.B. bei 15 
(+0xF) beginnen lassen und dabei den Multiplukator auf 15 setzten.

Ich glaube ich habs verstanden.

Bloß wo werden die 10 BITS bei Adresse PAT0 eingelesen? Passiert das 
hier:
1
    ldi    ZH, high(PAT0*2)  ;get next step
2
    lds    tempH, StepCnt
3
    mov    ZL, tempH
4
    lsl    ZL
5
    inc    tempH
6
    sts    StepCnt, tempH
7
    lpm    tempH, Z+
8
    sts    NewStepL, tempH
9
    lpm    tempH, Z
10
    sts    NewStepH, tempH

Und die Daten des jeweiligen .dw (Doppelwort?) stehen dann 0-7 NewStepL 
und 8-10 NewStepH richtig?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter S. schrieb:
> Und die Daten des jeweiligen .dw (Doppelwort?) stehen dann 0-7 NewStepL
> und 8-10 NewStepH richtig?

Jo, das sieht danach aus. Immer wenn ein 'lpm xxx,Z' Befehl im Spiel 
ist, werden Daten aus dem Flash von Speicheradresse (Z) gelesen.
Da Daten im Flash immer 16-bitweise adressiert werden, ist da auch immer 
noch ein 'Adresse mal 2' dabei. Also z.B.

    ldi ZL,low(Speicher << 1)    ; das schieben um 1 bit nach links
    ldi ZH,high(Speicher << 1)   ; ist eine Multiplikation mit 2

low() und high() sind praktische Makros für das high- und lowbyte einer 
16 bit Adresse.

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.