Forum: Compiler & IDEs DMX empfang in C funktioniert nicht richtig.


von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community,


ich habe ein Problem mit dem Empfang von DMX in C...
Quellcode im Anhang :)

Das Programm soll folgendes tun:

Wenn der USART den Break erkennt (allso das FE Bit setzt)
sollen die ersten 10 Kanäle in ein Array geschrieben werden.
Anschließend soll im Hauptprogramm der 4.Kanal ausgewertet werden und 
eine LED entweder an oder ausgeschaltet werden.

Das Problem:

Das Programm empfängt die ersten 10 Bytes, erkennt auch den Break, aber, 
nachdem es diese 10 Bytes empfangen hat werden diese nicht mehr 
aktualisiert...

Ich bin relativer Neuling in C und auch erst 16 Jahre alt und würde 
gerne an diesem Problem weitertüfteln....

Da ich hier nicht weiterkomme, bitte ich um Unterstützung,da ich glaube 
das ich einen Denkfehler in meinem Programm habe.

Vielen Dank für Eure Bemühungen im Voraus,

Christian

: Verschoben durch User
von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Entschuldigung, falsche Datei...
Das hier ist die Richtige :)

von Karl H. (kbuchegg)


Lesenswert?

Das
1
  if(1<<FE)

ist natürlich Quatsch. Denn dieser WErt ist immer wahr.

Was du oin wirklichkeit wolltest. Du wolltest ein Register befragen, ob 
dort drinnen das bewusste FE Bit auf 1 ist oder nicht.
D.h. in der Abfrage muss sowohl der Registername als auch der Bitname 
vorkommen.

Im Grunde genommen ist das nicht anders, als wie wenn du einen 
Eingangspin abfrägst. Da schreibst du auch nicht
1
   if( 1 << PB0 )

sondern
1
  if( PINB & ( 1 << PB0 ) )
also die Kombination aus: Nimm das Register PINB her und betrachte nur 
das Bit PB0 - ist das 0 oder 1?

Und hier bei dir ist das nicht anders. Das FE Bit ist in einem 
bestimmten Register beheimatet. Daher selbes Schema: Nimm den Inhalt des 
bewussten Registers her, maskiere mit einem & alles weg bis auf das FE 
Bit und dann erhebt sich die Frage: bleibt 0 übrig (dann war auch das 
Bit 0) oder nicht (dann war das Bit 1)

Das ist vom Prinzip her da (UART) wie dort (Input-Pins) genau das 
gleiche. Immer das gleiche Schema.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

>
1
>          array[10] = '\0';
2
>


erstens ist dein Array nur 10 Elemente lang, ein array[10] existiert 
daher gar nicht.

zweitens: wozu?
Du hast es hier mit DMX Daten zu tun und nicht mit Strings. DMX Daten 
sind einfach nur Werte. Die werden nicht als String behandelt.

von Karl H. (kbuchegg)


Lesenswert?

1
...
2
int main()
3
{
4
 ...
5
6
  while(arraycomplete==1){
7
    
8
....
9
  }
10
}


nein, nicht weil arraycomplete == 1.
Die Hauptschleife läuft IMMER. Aus der kommt der µC regulär nicht mehr 
raus.
1
...
2
int main()
3
{
4
 ...
5
6
  while( 1 ) {
7
8
    if( arraycomplete == 1 )
9
    {
10
       ....
11
12
       arraycomplete = 0;
13
    }    
14
  }
15
}

: Bearbeitet durch User
von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Hmm... Habe es jetzt abgeändert...funktioniert trotzdem nicht...
Hier die geänderte Datei :)

von Karl H. (kbuchegg)


Lesenswert?

Weil ich gerade darauf gestossen bin und mich gefragt habe, ob man das 
FE Bit wirklich selbst löschen muss.

Das ist was im Datanblatt zum FE Bit steht
1
• Bit 4 – FE: Frame Error
2
This bit is set if the next character in the receive buffer had a
3
Frame Error when received. that is, when the first stop bit of the
4
next character in the receive buffer is zero. This bit is valid until
5
the receive buffer (UDR) is read. The FE bit is zero when the stop bit
6
of received data is one. Always set this bit to zero when writing to UCSRA.

richte dein spezielles Augenmerk auf den Abschnitt
1
... This bit is valid until the receive buffer (UDR) is read. ...

Das heißt: das Bit ist nur solange korrekt, bis du UDR ausliest. Danach 
gilt es nichts mehr (wahrscheinlich wird es von der Hardware mit dem 
Lesen aus UDR zurück gesetzt).
Darauf folgt aber auch: Du musst das FE Bit auslesen BEVOR du dir das 
Byte aus dem UDR holst. Nicht wie hier
1
...
2
ISR(USART_RX_vect)
3
{
4
5
Temp=UDR;
6
7
8
9
  if(1<<FE)
10
  {
11
...
erst hinterher.

Mehr Sorgfalt und weniger exzessive Leerzeilen, dafür aber konsistentere 
Einrückung und bessere Variablennamen und du hast schon mal 50% deiner 
jetzigen Probleme hinter dir gelassen.

: Bearbeitet durch User
von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Leider funktioniert es immer noch nicht...

von Karl H. (kbuchegg)


Lesenswert?

>    array[9] = '\0';

Das behebt jetzt zwar das Problem des Array Zugriffs out of bounds.

Aber die zweite Frage steht immer noch im Raum. Wozu?

Du hast hier sowieso keine Strings! DMX-Daten sind keine Strings und 
werden auch nie welche sein. Du brauchst daher diese Operation hier 
nicht. Alles was du tust ist, du zerstörst dir hier mutwillig Daten. 
Gut, das mag dir egal sein, weil du dieses Byte (den Kanal 10) sowieso 
nie brauchst. Trotzdem erhebt sich die Frage: warum zerstörst du es 
dann?
Du agierst hier wie jemand, der eine Bushaltestelle zerstört, weil er 
sowieso immer mit der Bahn fährt.

von Karl H. (kbuchegg)


Lesenswert?

Sind eigentlich die 8 Mhz gesichert?
Hast du das ausprobiert, ob der µC auch wirklich mit 8Mhz läuft? Zb 
indem man eine LED blinken lässt, abhängig von der Taktfrequenz.


Denn im Grunde machst auch du schon wieder den Kardinalfehler nummer 1. 
Du versuchst als Anfänger ein Programm zu schreiben ohne einigermassen 
vernünftige Debugmöglichkeiten zu haben. Kein Mensch weiß, ob deine UART 
auch wirklich korrekt funktioniert oder nicht. Ob die Zeichen da korrekt 
rein kommen oder nicht.
Anfänger gehen immer davon aus, dass das alles ja nicht so schwer sein 
kann und das man ja wohl so ein Programm schreiben kann, so dass es auf 
Anhieb funktioniert. Tja, wie alle anderen das eigentlich erwartet 
haben, das funktioniert nun mal nicht.

Aber egal.
Sind die 8Mhz gesichert?


Mach dir halt mal in die ISR eine Anzeige per LED rein ob
* die ISR überhaupt aufgerufen wird
* das FE Bit jemals gesetzt wird
* die 10 Bytes jemals erreicht werden


PS: du MUSST das UDR in der ISR auslesen! Auch wenn du dann mit dem Byte 
nichts machst, aber auslesen MUSST du es. Du kannst nicht einfach das 
auslesen überspringen, weil irgendwelche Vorbedingungen nicht stimmen. 
Ansonsten präsentiert dir nämlich die USART dieses Byte wieder und immer 
wieder indem es die ISR auslöst.

von Falk B. (falk)


Lesenswert?


von Christian K. (christiankarle)


Lesenswert?

Ja, die 8 MHz sind gesichert und Fuses sind richtig gesetzt.
Mir geht es nicht darum mal so auf die Schnelle ein Programm zu 
schreiben,
sondern zu verstehen wieso mein lange überdachtes Programm nicht 
funktioniert...
Außerdem bin ich eigentlich echt stolz auf das was ich da schon 
geschrieben habe...
Nur irgendwo muss ein Denkfehler sein...

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Sind eigentlich die 8 Mhz gesichert?

Das ist wichtig, dass die stimmen! Denn sonst stimmt kein einziges 
Timing. Und gerade bei UART ist alles eine Timingfrage.

Probier mal folgendes Programm aus.
1
#define F_CPU  8000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
int main(void)
7
{
8
  DDRD = 0b11111111;
9
10
  while(1){
11
12
    PORTD |=  ( 1 << PD7 );
13
    PORTD &= ~( 1 << PD2 );
14
    _delay_ms( 500 );
15
16
    PORTD &= ~( 1 << PD2 );
17
    PORTD |=  ( 1 << PD7 );
18
    _delay_ms( 500 );
19
  }
20
}

deine LED müssen im Halbsekundentakt wechselseitig blinken. Wenn sie das 
nicht tun und zb nur alle 4 Sekunden blinken, dann läuft dein µC nicht 
mit 8Mhz.

Ich trau der Sache nicht. Das haben wir hier schon zu oft erlebt, dass 
jemand Stein und Bein geschworen hat, dass seine Taktfrequenz stimmt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:

> sondern zu verstehen wieso mein lange überdachtes Programm nicht
> funktioniert...

Das mag ja alles sein. Trotzdem hast du darauf vergessen, dir Gedanken 
darüber zu machen, wie du die Dinge kontrollieren kannst.

Eine einsame LED, die am Ende einer langen Kette von Ereignissen an oder 
ausgeht, und bei der alle Zwischenstufen in dieser Kette korrekt 
ablaufen müssen, ist nun mal zu wenig, wenn es nicht funktioniert. Du 
musst in der Lage sein, die Kontrolle viel feiner zu machen, in dem du 
jede einzelne dieser Zwischenstufen kontrollieren kannst.

Man kann dazu LED nehmen, so ist das nicht. Aber man muss dabei schon 
wissen was man tut. Und da liegt eben das Problem. Speziell bei UART ist 
das nämlich nicht so einfach. Denn da erheben sich 2 Fragestellungen: 
wird die ISR überhaupt ausgelöst - sprich: arbeitet die UART. Und die 
2-te lautet: arbeitet sie richtig. Die erste kann man mit einer LED 
einfach verifizieren. Die 2.te Frage ist nur mit einer LED schon 
schwerer zu beantworten.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Also...meine LED blinkt im 0.5 sec Takt -> Fuses richtig gesetzt :)
meine USART wurde richtig Initialisiert. Habe alles beachtet...
Ich glaube auch dass, das Problem an der Anweisung arraycomplete=0;
in der Hauptschleife liegt. Generell glaube ich das an diesem Punkt 
hakt...

P.S: Benutze den ATmega8515.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Also...meine LED blinkt im 0.5 sec Takt -> Fuses richtig gesetzt :)

gut.
Das ist schon mal wichtig.

Warum ich da so rumreite - weil ich auf der anderen Seite deines 
Monitors sitze und weder sehen kann noch die Hardware zur Hand nehmen 
kann, die du vor dir hast. Ich muss mich hier über den Zustand deines 
Projekts orientieren mit nichts anderem als das was du im Posting 
erzählst. Und natürlich nehme ich da mal die häufigsten Fehlerfälle 
zuerst. 99% aller UART probleme sind immer die gleichen: die 
Taktfrequenz ist nicht die, die der Programmierer glaubt.


> Ich glaube auch dass, das Problem an der Anweisung arraycomplete=0;
> in der Hauptschleife liegt.

Nö.
Deine Hauptschleife ist zwar maximal-kompliziert geschrieben, aber sie 
ist nicht falsch.
Das Problem liegt in der ISR.

Frage: wie sind deine LED angeschlossen. (du hast doch 2 LED, eine an 
PD2 eine an PD7). Muss der Portpin auf 0 oder auf 1 gestellt werden, 
damit die LED leuchtet?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Da fällt mir noch was ein

Wer sendet eigentlich?

> Anschließend soll im Hauptprogramm der 4.Kanal ausgewertet werden

4. Kanal
Bei welcher Zählweise? Beginnend bei 0 oder beginnend bei 1

von Christian K. (christiankarle)


Lesenswert?

Um die LED anzuschalten muss der Pin auf "Low" gesetzt werden
Habe deshalb den von Ihnen gelieferten C-Code wie folgt abgeändert :

#define F_CPU  8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

int main(void)
{
  DDRD = 0b11111111;

  while(1){

    cbi(PORTD,PD7);
    _delay_ms( 500 );
    sbi(PORTD,PD7);
    _delay_ms( 500 );
  }
}

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Warum jetz eigentlich 2 Freds für dasselbe?
Beitrag "USART soll DMX Break erkennen"

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Da fällt mir noch was ein
>
> Wer sendet eigentlich?
>
>> Anschließend soll im Hauptprogramm der 4.Kanal ausgewertet werden
>
> 4. Kanal
> Bei welcher Zählweise? Beginnend bei 0 oder beginnend bei 1

Hmm. da stimmt sowieso in deiner Zählerei etwas nicht.

Denn in deinem Array hast du in der ISR abgelegt
1
Index     Bedeutung
2
--------------------
3
0         Wert der beim Break kam
4
1         DMX Startbyte, immer 0
5
2         Kanal 1
6
3         Kanal 2
7
4         Kanal 3
8
5         Kanal 4
9
6         Kanal 5
10
...

d.h. mit array[4] greifst du sowieso schon mal auf das falsche Byte zu, 
wenn du am Wert von Kanal 4 interssiert bist.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Ich wollte mein Problem noch einmal genauer schildern. Auch in 
Zusammenhang mit dem gesamten Programm :)

Tut mir leid :( Wenn jemand weis wie man den anderen Beitrag löschen 
kann dann schreibt bitte kurz wie :)

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Um die LED anzuschalten muss der Pin auf "Low" gesetzt werden

Gut.
Ich überleg mir mal was, wie wir die ISR pimpen können.

> Habe deshalb den von Ihnen gelieferten C-Code wie folgt abgeändert :

Hättest du nicht ändern brauchen.
Denn ob man zuerst einschaltet und dann ausschaltet oder zuerst 
aussschaltet und dann einschaltet, ändert ja nichts daran, dass sich ein 
Blinken ergibt. Hauptsache abwechselnd ein/aus mit der Betonung auf 
abwechselnd.

Kann es sein, dass du einen haufen Vorübungen gespritzt hast?

> Habe deshalb den von Ihnen
Wir sind hier automatisch per du.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Ja, richtig :) Diese Tabelle habe ich schon die ganze Zeit im Kopf.
Mir ist bewusst das ich Kanal "3" auswerte wenn ich array[4] schreibe :)
Senden tut ein DMX-Pult mit 24 Kanälen :) Habe dort auch den Regler 
Nummer 3 Benutzt, welcher Kanal 3 entspricht. Habe das auch schon mit 
einem gekauften DMX-Gerät getestet :)

von Christian K. (christiankarle)


Lesenswert?

Karl Heinz schrieb:
> Kann es sein, dass du einen haufen Vorübungen gespritzt hast?

Danke für das "Du" :)

Was meinst du mit Vorwissen gespritzt? :D

von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

So ist mein ATmega8515 "verkabelt" :)

von Karl H. (kbuchegg)


Lesenswert?

24 Kanäle. Gut zu wissen, denn da muss ich jetzt mal ein bischen 
rechnen.

Wenn du nichts dagegen hast, dann machen wir das ohne großartiger 
Vorüberlegung, sondern wir gehen systematisch vor. Mit einem einfachen 
Programm, welches fast nichts kann und erweitern das dann Schritt für 
Schritt, wobei jeder Schritt mit der LED kontrolliert wird.

Aber erst muss ich ein bischen rumrechnen. Denn eine LED zum debuggen 
ist nicht viel und das DMX Zeugs ist zu schnell, als das wir da mit 
statischen Anzeigen weiter kommen würden. Wir werden also das Heil im 
Blinken suchen, wobei die Blinkfrequenz vom DMX getrieben wird.

von Christian K. (christiankarle)


Lesenswert?

Ich finde es total nett das Du dir die Zeit nimmst und mir hilfst :)
Und was bedeutet Vorwissen gespritzt ? :D

von Karl H. (kbuchegg)


Lesenswert?

Ach, eines noch.
Weisst du das. Sendet dein Sender ständig oder nur wenn sich Werte 
verändern?

von Christian K. (christiankarle)


Lesenswert?

Hmm...schwer zu sagen... Das Pult hat Funktionen wie z.B. Chaser, 
Strobo, Fadetime usw. Ich denke das Ganze macht wahrscheinlich dann nur 
Sinn wenn es dauerhaft sendet, oder liege ich da falsch ?

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Ach, eines noch.
> Weisst du das. Sendet dein Sender ständig oder nur wenn sich Werte
> verändern?


Hintergrund: Ich versuch auszurechnen, mit wievieln Break pro Sekunde 
überhaupt zu rechnen ist.
Hintergrund: die erste Version soll erst mal anzeigen, ob überhaupt 
regelmässig breaks daher kommen. Ich will das aber nicht mit LED 
einschalten realisieren, weil das sonst zu schnell geht. Im Prinzip soll 
bei jedem Break die LED umgeschaltet werden. Nur geht das bei 250kBaud 
und 24 Kanälen viel zu schnell (ca 1000 mal pro Sekunde), so dass man 
erst recht nichts sieht. D.h. wir schalten die LED nur bei jedem 500.ten 
Break um.

Das funktioniert aber nur, wenn der Sender ständig sendet und nicht nur 
bei Bedarf.

von Falk B. (falk)


Lesenswert?

@ Christian Karle (christiankarle)

>Hmm...schwer zu sagen... Das Pult hat Funktionen wie z.B. Chaser,

DMX sendet duaerhaft mit einer einstellbaren Wiederholrate.

von Falk B. (falk)


Lesenswert?

@ Karl Heinz (kbuchegg) (Moderator)

>Hintergrund: Ich versuch auszurechnen, mit wievieln Break pro Sekunde
>überhaupt zu rechnen ist.

<100. Die Wiederholrate bei DMX geht theortisch zwar bis in den kHz 
Bereich, praktisch eher nicht.

>Das funktioniert aber nur, wenn der Sender ständig sendet

Tut er.

von Karl H. (kbuchegg)


Lesenswert?

OK.
erstes Programm
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
#define LED  PD7
7
8
void UART_Initialisieren()
9
{
10
  UBRRL  = 1;
11
  UBRRH  = 0;
12
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
13
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
14
}
15
16
17
int main(void)
18
{
19
  DDRD |= ( 1 << LED );
20
21
  UART_Initialisieren();
22
23
  sei();
24
  while( 1 ) {
25
  }
26
}
27
28
ISR(USART_RX_vect)
29
{
30
  static uint16_t cnt = 0;
31
32
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
33
  uint8_t nextByte = UDR;
34
35
  if( frameError ) {
36
    cnt++;
37
    if( cnt == 500 )
38
    {
39
      cnt = 0;
40
      PORTD ^= ( 1<<LED );
41
    }
42
  }
43
}

wenn der Sender tatsächlich ständig sendet (was ich nicht weiß, weil ich 
noch nie mit DMX zu tun hatte), dann sollte die LED ca alle halbe 
Sekunde umschalten.
Meine Rechnung:
Wir haben 250kBaud, d.h. 250000 Bits pro Sekunde. Pro Byte sind 11 
fällig (1 Startbit, 8 Datenbits, 2 Stoppbits), d.h. das sind rund 22700 
Bytes pro Sekunde. Der Sender hat 24 Kanäle, also ist davon auszugehen 
dass er auch nur diese 24 sendet und nicht alle 512. mit dem Startbyte 
(und unter ignorieren des Break) sind das rund 900 komplette 
DMX-Nachrichten pro Sekunde. Zwischen jeder kommt ein Break, also auch 
rund 900 Breaks pro Sekunde. Wird die LED also nach jedem 500.ten Break 
umgeschaltet, dann ist das ungefähr eine halbe Sekunde.

Das ill ich erst mal sehen. Vielleicht funkelt die LED, das wär mir noch 
egal. Vielleicht blinkt sie auch langsamerm ist mir auch noch egal 
(könnte ja sein, dass der Sender tatsächlich alle 512 Kanäle überträgt 
und nicht nur 24). Aber wenn sich gar nichts tut, dann wäre das ziemlich 
schlimm.

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:
> @ Karl Heinz (kbuchegg) (Moderator)
>
>>Hintergrund: Ich versuch auszurechnen, mit wievieln Break pro Sekunde
>>überhaupt zu rechnen ist.
>
> <100. Die Wiederholrate bei DMX geht theortisch zwar bis in den kHz
> Bereich, praktisch eher nicht.

Ah. Danke Falk.
Rein rechnerisch lande ich bei ihm bei ca 900 kompletten 24-Kanal Frames 
unter der Annahme von 0-Pausen zwischen den Frames (break erst mal 
ignoriert - du weisst was ich meine)

>>Das funktioniert aber nur, wenn der Sender ständig sendet
>
> Tut er.

Wichtige Information für mich!
Danke.

: Bearbeitet durch User
von Christian K. (christiankarle)


Angehängte Dateien:

Lesenswert?

Währe das hier eine Möglichkeit für die Verwirklichung der Idee ?
Der 2. Code ist der Richtige :)

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Währe das hier eine Möglichkeit für die Verwirklichung der Idee ?

Im Prinzip - ja

Aber sieh dir meinen Code an. Diese ganze Komplikation mit Zähler in die 
Hauptschleife und dort einen delay braucht man gar nicht.
Entweder der break kommt regelmässig, dann reicht es die LED um- zu 
schalten. oder er tut das nicht. Dann rettet dich aber auch der delay 
nicht mehr.

von Max D. (max_d)


Lesenswert?

Die meisten DMX-Sender arbeiten mit ~30 Hz Update Rate.
Dieser Wert stammt nicht von irgendeiner "offiziellen" Seite sondern aus 
Erfahrung und dem rumspielen mit verschiedenen Pulten und USB-Geräten. 
Wenn man keine extra "intelligente" oder schnelle über-hw hat, dann sind 
die 30 Hz ziemlich konsistent. Ich denke das hat damit zu tun, dass in 
preiswerteren DMX-Slaves eher schwache Controller am werkeln sind und 
die sonst überfordert sind.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Christian Karle schrieb:
>> Währe das hier eine Möglichkeit für die Verwirklichung der Idee ?
>
> Im Prinzip - ja

Fast.
Du MUSST UDR auslesen!
Da führt kein Weg drann vorbei :-)

von Karl H. (kbuchegg)


Lesenswert?

Max D. schrieb:
> Die meisten DMX-Sender arbeiten mit ~30 Hz Update Rate.

Danke Max.
(Wer sagts denn. Wenn man es braucht, dann funktioniert das Forum 
erstklassig)

Also auch mal mit
1
...
2
    if( cnt == 15 )
3
...
probieren.

> Dieser Wert stammt nicht von irgendeiner "offiziellen" Seite sondern aus
> Erfahrung und dem rumspielen mit verschiedenen Pulten und USB-Geräten.

Dann traue ich dieser Angabe mehr als dem was ich da unter optimal 
Bedingungen worst case errechnet habe.
30 macht auch irgendwo Sinn. Der Empfänger muss ja mit den Daten auch 
was machen und soooo schnell ändern sich Werte ja nicht, die ein Zuseher 
ja auch noch aufnehmen können muss.

von Karl H. (kbuchegg)


Lesenswert?

Christian, nimm aber bitte trotzdem mein Programm.
Hintergrund: Ich hab das bei mir parallel im AVR-Studio geladen und 
werde das mit dir jetzt immer weiter ausbauen. Das ist einfacher, als 
wenn ich von einer Version zur nächsten jedesmal deinen Code absuchen 
muss, was du verändert hast.

von Karl H. (kbuchegg)


Lesenswert?

Also, wie siehts aus?
"Houston, we have ignition"?

von Christian K. (christiankarle)


Lesenswert?

Also, folgendes passiert:

Das Programm wird per ISP auf den uC übertragen.
Direkt nachdem es übertragen wurde fängt die LED im 0.5 sec. Takt an zu 
blinken, ohne das der Controller mit dem DMX Pult verbunden wurde....
Nach dem Verbinden mit dem DMX-Pult passiert genau das Selbe...

: Bearbeitet durch User
von old man (Gast)


Lesenswert?

Christian Karle schrieb:
> Außerdem bin ich eigentlich echt stolz auf das was ich da schon
> geschrieben habe...

Wenn du in deinem Leben mal richtig gut sein willst, dann sollte das die 
letzte Aussage sein die du in dieser Richtung von dir gibst. Sonnst 
kannst du dich gleich in die Reihen der Spinner einordnen, die von sich 
selbst glauben die besten Programmieren auf Erden zu sein...

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Also, folgendes passiert:
>
> Das Programm wird per ISP auf den uC übertragen.
> Direkt nachdem es übertragen wurde fängt die LED im 0.5 sec. Takt an zu
> blinken, ohne das der Controller mit dem DMX Pult verbunden wurde....
> Nach dem Verbinden mit dem DMX-Pult passiert genau das Selbe...

welches Programm?
Deines oder meines

Wenn nichts angeschlossen ist, sollte da eigentlich nichts blinken.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Folgende Frage wenn der RS485 Konverter empfangen soll, muss dann nicht 
nach Schaltplan PD2 auf "Low" sein? Oder liege ich in dieser Annahme 
falsch?



-> Deine Programm

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Äh, warte mal.
Habe ich zumindest übersehen.
PD2 muss aktiv auf 0 geszogen werden, damit der Treiber auf Empfang 
gestellt wird. Keine Ahnung was der macht, wenn der Pin im Tri-State 
ist.
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
#define LED      PD7
7
#define DATA_DIR PD2
8
9
void UART_Initialisieren()
10
{
11
  UBRRL  = 1;
12
  UBRRH  = 0;
13
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
14
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
15
}
16
17
18
int main(void)
19
{
20
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
21
22
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
23
24
  UART_Initialisieren();
25
26
  sei();
27
  while( 1 ) {
28
  }
29
}
30
31
ISR(USART_RX_vect)
32
{
33
  static uint16_t cnt = 0;
34
35
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
36
  uint8_t nextByte = UDR;
37
38
  if( frameError ) {
39
    cnt++;
40
    if( cnt == 15 )
41
    {
42
      cnt = 0;
43
      PORTD ^= ( 1<<LED );
44
    }
45
  }
46
}

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Folgende Frage wenn der RS485 Konverter empfangen soll, muss dann nicht
> nach Schaltplan PD2 auf "Low" sein?

Habs auch grade gemerkt, als ich den Schaltplan noch mal studiert habe

von Christian K. (christiankarle)


Lesenswert?

Hmm...Trotzdem blinkt sie immer noch mit 2 Hz...
Ohne das etwas angeschlossen ist...

von Max D. (max_d)


Lesenswert?

Sind es vlt 1,66 Hz ?
Dann hast du dir nämlich 50 Hz einstreuungen die die FEs triggern ....

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Hmm...Trotzdem blinkt sie immer noch mit 2 Hz...
> Ohne das etwas angeschlossen ist...

Hmm.
Hast du noch eine freie LED (mit 220 Ohm Vorwiderstand), die du mal am 
RxD Eingang vom Prozessor halten kannst. Wenn nichts angeschlossen ist, 
sollte da eigentlich Ruhe herrschen.

Probehalber auch mal Pin 2 und 3 vom DMX Eingangsstecker verbinden.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Ich habe gerade noch ein ganz anderes Problem... Ich habe bemerkt das 
sich mein Controller auf einmal nicht mehr über ISP programmieren 
lässt...deswegen blinkt auch die LED...

Ich werde das beheben und mich dann sofort wieder melden :)

von Karl H. (kbuchegg)


Lesenswert?

Max D. schrieb:
> Sind es vlt 1,66 Hz ?
> Dann hast du dir nämlich 50 Hz einstreuungen die die FEs triggern ....

Hmm.
Wo könnten die her kommen? Er hat ja 75176 und damit differentielle 
Eingänge.

Spannungsversorgung?

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:

> lässt...deswegen blinkt auch die LED...

Ah, ok. Altes Programm im Flash.
Das hatten wir alle schon mal.

von Max D. (max_d)


Lesenswert?

Karl Heinz schrieb:
> Max D. schrieb:
>> Sind es vlt 1,66 Hz ?
>> Dann hast du dir nämlich 50 Hz einstreuungen die die FEs triggern ....
>
> Hmm.
> Wo könnten die her kommen? Er hat ja 75176 und damit differentielle
> Eingänge.
>
> Spannungsversorgung?

Wenn er die Eingänge offen hat, dann können da auch differentielle 
Einstrahlungen passieren (und die Treiber sind ja rel. empfindlich auf 
differentielle spannungen, beim 75176 z.b. 200 mV). Das schafft man 
locker wenn ein längeres Stück Kabel rumbaumelt.....

von Christian K. (christiankarle)


Lesenswert?

Also ich verstehe gerade die Welt nicht mehr... mein uC lässt sich nun 
gar nicht mehr per ISP programmieren... egal was ich aufspiele-> Die LED 
blinkt...

Liegt das an AVR Studio ?

von Falk B. (falk)


Lesenswert?

@ Christian Karle (christiankarle)

>Also ich verstehe gerade die Welt nicht mehr... mein uC lässt sich nun
>gar nicht mehr per ISP programmieren... egal was ich aufspiele-> Die LED
>blinkt...

Falsches HEX-File ausgewählt?

>Liegt das an AVR Studio ?

Das Problem "liegt" meistens vor der Tastatur.

von Christian K. (christiankarle)


Lesenswert?

Nein, ich habe jetzt mehrere Male darauf geachtet das es das richtige 
File ist und habe auch versch. Programme aufgespielt... Aber immer 
blinkt die LED... Ich habe das ja bestimmt schon 500 mal gemacht und 
blöd bin ich ja auch nicht...

von Falk B. (falk)


Lesenswert?

Lösche mal den AVR. Das muss gehen. Chip Erease. Dann ist Ruhe.
Kannst du wenigstens die ID noch lesen?

von Karl H. (kbuchegg)


Lesenswert?

Hmm.
Schon mal alles runtergefahren und neu gestartet?

Wenn gar nichts mehr hilft: Lötkolben auspacken und dem AVR zeigen (dem 
PC zeigen schadet auch nicht). Dann spuren die wieder. Sozusagen mit 
vorgehaltener Waffe sanft zur Mitarbeit überreden :-)

Im Ernst: irgendwo ein Kabel gerissen. Wackelkontakt, schlecht 
Verbindung im Pfostenstecker?

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

:D :D :D guter Witz :D :D :D

Ich versuche es jetzt mal noch mit meinem Laptop...

von Christian K. (christiankarle)


Lesenswert?

Also habe es jetzt hinbekommen. Es lag tatsächlich an AVR Studio es muss 
sich ein Softwarefehler eingeschlichen haben... nach der Neuinstallation 
funktioniert nun wieder alles :)

Das Programm funktioniert auch :)

1.Die LED ist an.
2.Einstecken in das Pult -> LED fängt an zu blinken:)

Sie blinkt etwas langsamer als 2Hz aber sonst ist alles perfekt :)

Noch eine Detailfrage:
Wenn ich das UDR nicht auslese, würde es dann zu einem DATA OVERRUN 
kommen ?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Also habe es jetzt hinbekommen. Es lag tatsächlich an AVR Studio es muss
> sich ein Softwarefehler eingeschlichen haben... nach der Neuinstallation
> funktioniert nun wieder alles :)
>
> Das Programm funktioniert auch :)
>
> 1.Die LED ist an.
> 2.Einstecken in das Pult -> LED fängt an zu blinken:)
>
> Sie blinkt etwas langsamer als 2Hz aber sonst ist alles perfekt :)

Ah gut.
We have lift off


Jetzt wirds spannend. Bis jetzt wissen wir ja nur, dass laufend breaks 
daher kommen. Die Frequenz 2Hz könnte passen. Auf jeden Fall langsam 
genug, dass nicht jedes empfangene Byte einen Frame Error verursacht 
haben kann, denn dann würde das viel schneller blinken. Das stimmt schon 
mal zuversichtlich.

So, wie gehts jetzt weiter?
Jetzt holen wir uns mal die nächsten 10 Bytes nach einem Break in ein 
Array und überprüfen, ob das erste davon 0 ist.
Leider haben wir keine andere Möglichkeit als von dem Wissen gebrauch zu 
machen, dass das erste Byte 0 sein muss. Eine Ausgabe auf LCD wäre mir 
persönlich lieber, aber es wird auch so gehen.

von Karl H. (kbuchegg)


Lesenswert?

Mein Vorschlag.

Die Intention ist folgende:

Es werden nach einem break die nächsten Bytes in ein Array geschrieben. 
Wenn geschrieben wird, wir auch geprüft, ob das erste Byte nach dem 
Break ein 0 Byte ist. Das Problem das wir nämlich haben ist, dass wir 
zwar momentan feststellen können, dass zwar Breaks da sind, aber wir 
wissen nicht, ob wir mit der Baudrate daneben liegen, so dass der 
Empfang gestört ist.

Aber wir wissen, dass das erste Byte nach einem Break 0 sein muss. Das 
ist von DMX so vorgeschrieben und das ist etwas das man testen kann.


Die Erwartungshaltung im Programm ist folgende:
Da in der Hauptschleife die LED immer wieder abgeschaltet wird, gibt es 
nur eine Möglichkeit, wie die LED leuchten kann. Nämlich wenn in der ISR 
das erste Zeichen nach einem Break eine 0 ist. Nur dann wird die LED 
eingeschaltet. Liegt die 0 nicht vor, oder fällt die Verbdinung aus, 
dann sorgt die Hauptschleife dafür, dass die LED wieder ausgeht.

Testszenario ist daher:
DMX Stecker ziehen. Programm laufen lassen. Die LED muss aus sein.
Stecker einstecken. die LED muss leuchten.
Stecker wieder abziehen, die LED muss ausgehen.

theoretisch könnte es sein, dass bei eingestecktem DMX Stecker die LED 
leicht flackert. Ich denke allerdings nicht, dass man das grossartig 
sehen wird. Vielleicht ein ganz kurzer Flackerer hie und da.
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
#define LED      PD7
8
#define DATA_DIR PD2
9
10
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
11
12
volatile uint8_t dmxData[10];
13
14
void UART_Initialisieren()
15
{
16
  UBRRL  = 1;
17
  UBRRH  = 0;
18
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
19
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
20
}
21
22
int main(void)
23
{
24
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
25
26
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
27
28
  UART_Initialisieren();
29
30
  sei();
31
  while( 1 ) {
32
    // Testled immer wieder abschalten, die ISR wird sie wieder einschalten
33
    // wenn der Empfang korrekt ist
34
    PORTD &= ~( 1 << LED );
35
    _delay_ms( 300 );
36
  }
37
}
38
39
ISR(USART_RX_vect)
40
{
41
  static uint8_t byteCnt = 0;
42
43
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
44
  uint8_t nextByte = UDR;
45
46
  if( frameError )
47
    byteCnt = 0;
48
49
  else
50
  {
51
    if( byteCnt < ARRAY_SIZE( dmxData ) )
52
    {
53
      dmxData[byteCnt++] = nextByte;
54
55
      if( dmxData[0] == 0 )
56
        PORTD |= ( 1 << LED );
57
    }
58
  }
59
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

autsch:
Fehler.
Die LED ist genau anders rum.
Deine LED leuchtet ja bei einer 0 am Pin.
(Da war ich jetzt in Gedanken bei einem anderen Post)


Also. Erwartungshaltung ist:

Stecker abgezogen: LED brennt
Stecker eingesteckt: LED brennt nicht

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Also praktischer Ablauf ist etwas anders :)

1: Stecker ist nicht eingesteckt-> LED ist an
2: Stecker ist eingesteckt-> LED flackert/Blinkt

Ich werde jetzt auch erst einmal versuchen den Programmtext 
nachzuvollziehen :)

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Also praktischer Ablauf ist etwas anders :)
>
> 1: Stecker ist nicht eingesteckt-> LED ist an

das ist ok. (Siehe mein letztes POsting)

> 2: Stecker ist eingesteckt-> LED flackert/Blinkt

hmm, wie stark ist das Flackern?
Ein bischen flackern ist ok. Mehr so ein Aufblitzen der LED als ein 
regelmässiges Blinken.
Das die LED überhaupt ausgeht, ist schon mal ein gutes Zeichen, denn das 
bedeutet, dass da 0-Bytes nach dem Break reinkommen.

Wenn du den delay_ms in der Hauptschleife vergrößerst, wird dann das 
Flackern weniger?

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
#define LED      PD7
8
#define DATA_DIR PD2
9
10
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
11
12
volatile uint8_t dmxData[10];
13
14
void UART_Initialisieren()
15
{
16
  UBRRL  = 1;
17
  UBRRH  = 0;
18
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
19
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
20
}
21
22
int main(void)
23
{
24
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
25
26
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
27
28
  UART_Initialisieren();
29
30
  PORTD |= ( 1 << LED );
31
32
  sei();
33
  while( 1 ) {
34
  }
35
}
36
37
ISR(USART_RX_vect)
38
{
39
  static uint8_t byteCnt = 0;
40
41
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
42
  uint8_t nextByte = UDR;
43
44
  if( frameError )
45
    byteCnt = 0;
46
47
  else
48
  {
49
    if( byteCnt < ARRAY_SIZE( dmxData ) )
50
    {
51
      dmxData[byteCnt++] = nextByte;
52
53
      if( dmxData[0] == 0 )
54
        PORTD &= ~( 1 << LED );
55
      else
56
        PORTD |= ( 1 << LED );
57
    }
58
  }
59
}

ist eine andere Variante.
Die LED muss die ganze Zeit eingeschaltet bleiben. Keine Flackerer, 
keine Helligkeitsschwankungen.
Allerdings ändert sich nichts, wenn du den Stecker abziehst, daher hab 
ich das auch nicht für den ersten Test benutzt.
Ein Test könnte höchstens sein:
Alles abschalten, DMX Stecker abziehen. µC einschalten. Die LED muss aus 
sein.
Dann den DMX Stecker anstecken. Die LED muss "sofort" leuchten. Ohne 
Flackern.
Ziehst du den Stecker danach ab, dann ändert sich am LED Zustand nichts 
mehr. Sie leuchtet weiter.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Wenn ich _delay_ms vergrößere dann nimmt die Frequenz des Blinkens der 
LED ab. Ich würde behaupten es ist ein relativ regelmäßiges Blinken...
Ich würde es als regelmäßiges Aufblitzen bezeichnen (Das wäre ja auch in 
Ordnung)

von Falk B. (falk)


Lesenswert?

Den BREAK sollte man besser so detektieren. Anderenfalls kann man sich 
durch einen Fehler im normalen Datenstrom kurzzeitig die Synchronisation 
abschießen.

1
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
2
  uint8_t nextByte = UDR;
3
4
  if( frameError && nextByte=0)
5
    byteCnt = 0;

Siehe auch

Beitrag "DMX512 Empfänger mit Relaisansteuerung für 20 Kanäle"

von Christian K. (christiankarle)


Lesenswert?

Ok, das 2.Programm funktioniert einwandfrei. Den Programmtext kann ich 
auch nachvollziehen :)

von Christian K. (christiankarle)


Lesenswert?

Ich habe das Programm noch erweitert um sicherzustellen dass, das Array 
auch aktualisiert wird wenn mehr als 1000 Datenpakete empfangen wurden 
wird
die LED ausgeschaltet :) Nur zur Überprüfung :)
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
#define LED      PD7
8
#define DATA_DIR PD2
9
10
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
11
12
volatile uint8_t dmxData[10];
13
volatile int x=0;
14
15
void UART_Initialisieren()
16
{
17
  UBRRL  = 1;
18
  UBRRH  = 0;
19
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
20
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
21
}
22
23
int main(void)
24
{
25
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
26
27
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
28
29
  UART_Initialisieren();
30
31
  PORTD |= ( 1 << LED );
32
33
  sei();
34
  while( 1 ) {
35
  }
36
}
37
38
ISR(USART_RX_vect)
39
{
40
  static uint8_t byteCnt = 0;
41
42
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
43
  uint8_t nextByte = UDR;
44
45
  if( frameError ){
46
  byteCnt = 0;
47
  }
48
  else
49
  {
50
    if( byteCnt < ARRAY_SIZE( dmxData ) )
51
    {
52
      dmxData[byteCnt++] = nextByte;
53
54
        if( dmxData[0] == 0 )
55
        {
56
          x++;
57
          if(x<1000){
58
          PORTD &= ~( 1 << LED );
59
        }
60
        if(x>1000)
61
        {
62
        PORTD |= ( 1 << LED );
63
        }
64
      }
65
    }
66
  }
67
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:
> Den BREAK sollte man besser so detektieren.


Guter Einwand.
Idee aufgegriffen.

von Karl H. (kbuchegg)


Lesenswert?

Ok, Ich denke wir sind soweit, in die Vollen zu gehen.
Sieht wohl so aus, als ob die Synchronisierung klappt und auch die 
empfangenen Daten korrekt sind.

Kanal 3 abfragen und die LED damit schalten
1
#define F_CPU 8000000
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
#define LED      PD7
7
#define DATA_DIR PD2
8
9
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
10
11
volatile uint8_t dmxData[10];
12
13
void UART_Initialisieren()
14
{
15
  UBRRL  = 1;
16
  UBRRH  = 0;
17
  UCSRC  = (1<<URSEL)|(3<<UCSZ0);
18
  UCSRB  = (1<<RXCIE)|(1<<RXEN);
19
}
20
21
int main(void)
22
{
23
  DDRD |= ( 1 << LED ) | ( 1 << DATA_DIR );
24
25
  PORTD &= ~( 1 << DATA_DIR );    // Treiber auf Empfang stellen
26
27
  UART_Initialisieren();
28
29
  sei();
30
  while( 1 ) {
31
    if( dmxData[3] < 128 )
32
      PORTD |= ( 1 << LED );
33
    else
34
      PORTD &= ~( 1 << LED );
35
  }
36
}
37
38
ISR(USART_RX_vect)
39
{
40
  static uint8_t byteCnt = 0;
41
42
  uint8_t frameError = ( UCSRA & ( 1 << FE ) );
43
  uint8_t nextByte = UDR;
44
45
  if( frameError && nextByte == 0)
46
    byteCnt = 0;
47
48
  else
49
  {
50
    if( byteCnt < ARRAY_SIZE( dmxData ) )
51
    {
52
      dmxData[byteCnt++] = nextByte;
53
    }
54
  }
55
}

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:

> die LED ausgeschaltet :) Nur zur Überprüfung :)

:-)
Das ist IMHO die richtige Einstellung.
Wir angeln uns von einem Ziel zum nächsten vor. Auch wenn das manchmal 
etwas umständlich sein mag. Aber: dadurch haben wir die Gewissheit, dass 
die Dinge funktionieren, ehe wir die nächste Schicht drauf setzen.
In Summe geht das nämlich schneller, als einen Codehaufen hinzusetzen, 
der dann nicht funktioniert und dann müssen wir erst recht wieder ganz 
unten anfangen mit Debuggen.

Und, auch ganz wichtig. Wir überlegen uns, wie jede Erweiterung getestet 
werden kann. Dazu ist es auch wichtig, vorab eine Erwartung zu haben. 
D.h. ehe das Programm läuft, sollte man sich darüber im klaren sein, was 
eigentlich passieren müsste.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Das Programm funktionier super :) Jetzt wurde ein Switch realisiert,
genau dass, das ich erreichen wollte :)

Die einzige Stelle im Programmtext die ich nicht verstehe ist

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))

Ich würde mich noch über eine kleine Erklärung hierzu freuen :)

Mein Problem würde ich somit als gelöst ansehen, ab hier denke ich, kann 
ich mir selbst über weitere Details und Funktionen Gedanken machen. Das 
Tolle ist: Ich habe jetzt verstanden wie der DMX-Empfang abläuft und 
kann endlich die Schritte bis zum fertigen Programm nachvollziehen :)

Vielen, vielen Dank Karl Heinz :)
Du hast mir sehr weitergeholfen. Ich bin Dir sehr dankbar das Du deine 
Zeit opferst um mir Dein Wissen zu vermitteln. In der heutigen Zeit sind 
Menschen wie du nur noch sehr selten, da normalerweise keiner mehr Zeit 
und Lust hat sich mit Problemen anderer zu beschäftigen.
Ich schätze das wirklich sehr!

Und noch einmal ein fettes Dankeschön von mir :)

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Das Programm funktionier super :) Jetzt wurde ein Switch realisiert,
> genau dass, das ich erreichen wollte :)

Gut.

> Die einzige Stelle im Programmtext die ich nicht verstehe ist
>
> #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))

sizeof liefert die Größe eines 'Objektes' in Bytes.
1
int data[5];

sizeof(data) würde also die Größe des Arrays in Bytes liefern. da ein 
int aus 2 Bytes besteht, wären das hier daher 10.

Ich will aber nicht wissen, wieviele Bytes das Array hat, sondern aus 
wievielen Einträgen es besteht. Dazu muss ich im Prinzip die Größe des 
Arrays durch die Größe eines Elements des Arrays dividieren. ein int hat 
2 Bytes, also ist ein int Array, das 10 Bytes groß ist 10/2 gleich 5 
Arrayelemente groß.

Wenn x ein Array bezeichnet, dann ist ein einzelnes element davon zb 
x[0]. Oder kürzer geschrieben *x (wegen der Pointer/Array Dualität)
1
sizeof(data) / sizeof(data[0])
liefert daher, die Anzahl an Array Elementen, wenn data als Array 
vorliegt. denn sizeof(data[0]) würde ja 2 ergeben, weil data[0] ja ein 
einzelner int aus dem Array ist.

Oder eben, unter Ausnutzung der Pointer/Array Dualität
1
sizeof(data)/sizeof(*data)

(Du kannst aber auch die Array-Schreibweise benutzen. Ich bin eben 
tippfaul :-)

> Mein Problem würde ich somit als gelöst ansehen, ab hier denke ich, kann
> ich mir selbst über weitere Details und Funktionen Gedanken machen. Das
> Tolle ist: Ich habe jetzt verstanden wie der DMX-Empfang abläuft und
> kann endlich die Schritte bis zum fertigen Programm nachvollziehen :)

Super.
Dann würde ich sagen: Ziel erreicht.
Sowohl bei dir als auch bei mir.
Denn für mich ist das wichtigste, dass du verstehst, wie es 
funktioniert. Das funktioniert bei weitem nicht so gut, wenn man einfach 
nur fertigen Code hinklatscht.
Gib einem Mann einen Fisch und er hat einen Tag lang zu essen. Gib ihm 
eine Angel und lehre ihn fischen und er hat sein Leben lang etwas zu 
essen.

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Ist es für Dich in Ordnung wenn ich das hier erreichte Ergebnis 
veröffentlichen würde?

Das Ziel ist Menschen wie mir den Einstieg zu erleichtern.

Ich möchte mit dem hier erreichten eine einfache 
Erklärung/Zusammenfassung für Anfänger schreiben und evtl. auf einer 
Website veröffentlichen :)

von Karl H. (kbuchegg)


Lesenswert?

Christian Karle schrieb:
> Ist es für Dich in Ordnung wenn ich das hier erreichte Ergebnis
> veröffentlichen würde?

Hab ich kein Problem damit.
Sonst wäre ich nicht hier :-)

von Paul Baumann (Gast)


Lesenswert?

Karl-Heinz schrub:
>Gib ihm eine Angel und lehre ihn fischen und er hat sein Leben lang etwas >zu 
essen.

Gib ihm ein Buch über C und er ist nach 2 Wochen reif für die 
Heilanstalt.

;-)

schnell fort hier

MfG Paul

von Falk B. (falk)


Lesenswert?

@ Paul Baumann (Gast)

>>Gib ihm eine Angel und lehre ihn fischen und er hat sein Leben lang etwas >>zu 
essen.

>Gib ihm ein Buch über C und er ist nach 2 Wochen reif für die
>Heilanstalt.

Nö. Kerngesund!!

https://www.burgerking.de/uploads/bkproductadmin/mainteaser/getraenke/produkt-hohesc.jpg

C-)

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.