Forum: Mikrocontroller und Digitale Elektronik Attiny2313 DMX Relais - Probleme


von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

einmal ein neuer Beitrag, da der andere zu alt war. :) Ich bin zwar 
nicht ganz neu beim AVR, aber trotzdem stehe ich gerade
ziemlich auf dem Schlauch und komme nicht weiter...
Ich versuche ein DMX Relais zu bauen, mit nur einem Kanal. Ich habe mir
viele Sachen dazu im Netz angesehen und mir auch den Code von Herr Radig
angeschaut und habe darauf hin etwas zusammengebaut und programmiert.
Leider scheint er das Serielle Signal nicht richtig zu erkennen. Ich 
weiss
tatsächlich nicht warum. Er bleibt immer in der Schleife bei "dmx_valid 
= 0" hängen und deswegen flackert die gelbe LED immer. Ich bekomme Ihn 
einfach nicht dazu das Signal richtig zu erkennen.
Ich habe in einem Schaltbild gesehen, das am besten noch ein 120 Ohm 
Widerstand zwischen A und B der Eingangsleitung
kommt. Den habe ich mal parallel mit in die Klemme gemacht, trotzdem
scheint er kein gültiges Signal auswerten zu können.
Fällt Euch etwas auf?

Vielen Dank

Stefan

.

von S. Landolt (Gast)


Lesenswert?

Ohne erstmal tiefer einzusteigen zu wollen - welchen Wert hat das 
Fuse-Low-Byte?

von c-hater (Gast)


Lesenswert?

Stefan schrieb:

> Fällt Euch etwas auf?

Ja, schon beim allerersten Überfliegen:
1
//############################################################################
2
//DMX Senderoutine
3
ISR (USART_RX_vect)
4
//############################################################################

Wer eine RX-ISR mit "//DMX-Senderoutine" kommentiert, dem ist definitiv 
nicht zu helfen...

von Stefan (Gast)


Lesenswert?

S. Landolt schrieb:
> Ohne erstmal tiefer einzusteigen zu wollen - welchen Wert hat das
> Fuse-Low-Byte?

0xDC

von S. Landolt (Gast)


Lesenswert?

Okay (auch wenn ich EF oder FF genommen hätte).

Was mir unklar ist: dmx_valid=1 scheint mir nur in dem Fall zu erfolgen, 
dass ein FrameError aufgetreten ist - sehe ich das richtig?

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

> Was mir unklar ist: dmx_valid=1 scheint mir nur in dem Fall zu erfolgen,
> dass ein FrameError aufgetreten ist - sehe ich das richtig?

Ja. DMX beruht darauf, dass der Start eines Datenpakets mit einem 
UART-Break markiert wird. Es gibt noch mehr Details bezüglich des 
Timing, aber für den Empfänger sind die irrelevant, der sieht nur einen 
Break, aus Sicht einer AVR-USART also einen Framing-Error, weil das 
Stopbit an der richtigen Stelle nicht auftaucht. Zur Sicherheit sollte 
man allerdings im Falle des Empfangs eines FE noch das empfangene 
Datenbyte auf Null prüfen, nur dann kann man wirklich sicher sein, dass 
ein Break gemeint war...

von Gabriel M. (gabse)


Lesenswert?

S. Landolt schrieb:
> Okay (auch wenn ich EF oder FF genommen hätte).
>
> Was mir unklar ist: dmx_valid=1 scheint mir nur in dem Fall zu erfolgen,
> dass ein FrameError aufgetreten ist - sehe ich das richtig?

Ja das stimmt, da bei DMX ein FrameError das erste Datenbit markiert.

Stimmt die eingestellte Bautrate?
Stimmt die Polung vom DMX Port?
Stimmen die Fusebits?
Ich würde das Programm mal auf das Wesentliche reduzieren und eventuell 
mal im Simulator Debuggen.

von c-hater (Gast)


Lesenswert?

Gabriel M. schrieb:

> Ja das stimmt, da bei DMX ein FrameError das erste Datenbit markiert.

Nein, es wird der Paketanfang markiert, nicht irgendein Bit. Danach 
folgt ganz stinknormale UART-Kommnikation. D.h.: das erste Bit eines 
Paketes ist, wie bei UART ganz normal, ein gewöhnliches Startbit. Erst 
dann folgt das erste Datenbit. Nämlich das niedrigstwertige Bit des 
ersten Kanals.

von Gabriel M. (gabse)


Lesenswert?

c-hater schrieb:
> Gabriel M. schrieb:
>
>> Ja das stimmt, da bei DMX ein FrameError das erste Datenbit markiert.
>
> Nein, es wird der Paketanfang markiert, nicht irgendein Bit. Danach
> folgt ganz stinknormale UART-Kommnikation. D.h.: das erste Bit eines
> Paketes ist, wie bei UART ganz normal, ein gewöhnliches Startbit. Erst
> dann folgt das erste Datenbit. Nämlich das niedrigstwertige Bit des
> ersten Kanals.


Stimmt, da habe ich mich wohl falsch ausgedrückt.

Zum Schaltplan: Wofür wird den der Optokoppler verwendet? Auf den kannst 
du ohne Probleme verzichten und Q1 direkt mit dem Attiny pin ansteuern. 
Gibt es einen Grund für die Auswahl der Pins für den DIP Schalter? Wen 
du DIP Schalter 1-8 an PB0-PB7 anschliesst kannst du Port B direkt als 
LSB für die Adresse verwenden.

von Stefan (Gast)


Lesenswert?

Gabriel M. schrieb:
> Zum Schaltplan: Wofür wird den der Optokoppler verwendet? Auf den kannst
> du ohne Probleme verzichten und Q1 direkt mit dem Attiny pin ansteuern.
> Gibt es einen Grund für die Auswahl der Pins für den DIP Schalter? Wen
> du DIP Schalter 1-8 an PB0-PB7 anschliesst kannst du Port B direkt als
> LSB für die Adresse verwenden.

Tatsächlich ist der Schaltplan gewachsen. Und ich hab dann die Switches 
nicht ganz richtig verteilt. Werde ich auf jedenfall ändern.

Den Optokoppler habe ich eigentlich meisten drin, wenn ich Relais 
schalte. Ist mehr Gewohnheit.

Ich habe gerade festgestellt das ich im "main.h" bei RelayOn und Off, 
den falschen Port manipuliert habe. Habe den jetzt auf PORTB gesetzt. 
Aber das war es auch nicht...

von c-hater (Gast)


Lesenswert?

Stefan schrieb:

> Den Optokoppler habe ich eigentlich meisten drin, wenn ich Relais
> schalte. Ist mehr Gewohnheit.

Sehr dumme Gewohnheit, völlig nutzlos. Relais nimmt man, wenn man 
irgendwas potentialgetrent schalten will. Optokoppler ebenfalls genau 
dann. Beides gleichzeitig zu benutzen ist irgendwas zwischen 
Geldverschwendung und kompletter Voll-Idiotie...

von S. Landolt (Gast)


Lesenswert?

> ... jetzt auf PORTB gesetzt ...
Und B0 auf Ausgang gesetzt?

von Stefan (Gast)


Lesenswert?

Ja, habe ich auch.

von S. Landolt (Gast)


Lesenswert?

Vielleicht wäre es sinnvoll, die beiden geänderten Dateien zu zeigen.

von S. Landolt (Gast)


Lesenswert?

Ist ein Multimeter vorhanden, um die Spannung an B0 direkt zu messen?

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

S. Landolt schrieb:
> Vielleicht wäre es sinnvoll, die beiden geänderten Dateien zu zeigen.

Hab ich angehängt.

S. Landolt schrieb:
> Ist ein Multimeter vorhanden, um die Spannung an B0 direkt zu messen?

Ja sicher. Nach der Korrektur reagiert das Relais, bzw. die LED beim 
Optokoppler auf den Tastendruck. Der ist ja um das Relais zu testen. Die 
Gelbe LED flackert immer noch.

Mir ist aufgefallen, wenn ich keinen DIP Schalter gesetzt habe, dann 
reagiert auch die Relais LED. Aber willkürlich. Und die blaue und gelb 
gehen auch an und aus. Aber nicht definiert. Ich hatte schon gedacht der 
Tiny hätte ein Problem und habe den ausgetauscht. Aber der zweite macht 
genau das selbe.

von S. Landolt (Gast)


Lesenswert?

> ... DIP Schalter ...
Wo wird dieser denn eingelesen, finde ich gerade nicht ...

von Stefan (Gast)


Lesenswert?

Den habe ich auskommentiert. Da ich erstmal mit einer definierten 
Startadresse anfangen wollte.

von S. Landolt (Gast)


Lesenswert?

(so allmählich gehen mir die Ideen aus)

Das
1
   UCSRA &=~(1<<FE);
scheint mir unsinnig.

Mit diesem Break-Ablauf kenne ich mich nicht aus, aber könnte es sein, 
dass die Reihenfolge
1
tmp =  UDR;
2
  if(UCSRA & (1<<FE))
falsch ist? Im Datenblatt steht:
"Bit 4 – FE: Frame Error ... This bit is valid until the receive buffer 
(UDR) is read ..."

von Stefan (Gast)


Lesenswert?

So, ich glaube ich habe es. Bin den ganzen Code nochmal durchgegangen 
und hab den Tiny jetzt soweit das er das Signal akzeptiert. Warum auch 
immer das jetzt tut...
Jetzt ist nur noch das Problem, das er wie wild an zu flackern fängt 
(und zwar alles) wenn kein DIP Schalter gesetzt ist. Also alle 
Eingangspins durch die gesetzten PullUps auf HIGH sind... Das passiert 
auch wenn ich SW9 schalte. Sobald ich einen von 1-8 schalte und damit 
auf Ground ziehe hört das auf.

Vielen vielen Dank schon mal für die Hilfe bis hierhin

von Gabriel M. (gabse)


Lesenswert?

S. Landolt schrieb:
> "Bit 4 – FE: Frame Error ... This bit is valid until the receive buffer
> (UDR) is read ..."

Habe es gerade eben auch in deinem Code gesehen. Ja, du musst erst UCSRA 
sichern bevor du UDR ausliesst.

Beschreibe:
Stefan schrieb:
> das er wie wild an zu flackern fängt
> (und zwar alles)

mal genauer. Was flackert?

von Stefan (Gast)


Lesenswert?

Ich versuche es mal zu beschreiben.

Die Blaue LED, die eigentlich nur den Betrieb anzeigt und somit immer an 
sein sollte, wird dunkler und heller, ohne einen Takt. Die gelbe LED 
geht auch an und aus ohne Takt, und auch die rote LED (die den B0 
anzeigt) geht an, wird dunkler, aus usw. alles ohne einen ersichtlichen 
Takt.

Wenn ich SW9 (PD2) schalte, bleibt dieser undefinierte Zustand. Bei 
allen anderen geht er in normal Betrieb.

von Gabriel M. (gabse)


Lesenswert?

Zeigt sich diese Verhalten nur wen DMX Daten anliegen, bzw den UART RX 
Interrupt deaktivierst oder immer?
Was passiert wen du den Pullup nicht aktivierst?
Kann es sein, dass du die CKOUT Fuse gestetzt hast? PD2 ist zufällig 
genau der Clock Out portpin.
Kann es sein dass du die WDTON fuse gesetzt hast und deshalb der 
Controller ständig zurückgesetzt wird?

von Stefan (Gast)


Lesenswert?

Gabriel M. schrieb:
> Zeigt sich diese Verhalten nur wen DMX Daten anliegen, bzw den UART RX
> Interrupt deaktivierst oder immer?
> Was passiert wen du den Pullup nicht aktivierst?
> Kann es sein, dass du die CKOUT Fuse gestetzt hast? PD2 ist zufällig
> genau der Clock Out portpin.
> Kann es sein dass du die WDTON fuse gesetzt hast und deshalb der
> Controller ständig zurückgesetzt wird?

Ja, passiert tatsächlich nur wenn Daten anliegen.

CKOUT ist deaktiviert
WDTON ist deaktiviert

Auftreten tut es sobald Daten anliegen und alle DIPs ausgeschaltet sind. 
Egal welche Position SW9 hat...

von Gabriel M. (gabse)


Lesenswert?

Stefan schrieb:
> Die Blaue LED, die eigentlich nur den Betrieb anzeigt und somit immer an
> sein sollte

In deinem code ist sie aber nicht immer an, denn:
1
 if(tmp == 0)    
2
    {
3
      dmx_valid = 1;    
4
      ledBlueToggle();
5
      dmx_channel_rx_count++;
6
    }


Stefan schrieb:
> Auftreten tut es sobald Daten anliegen und alle DIPs ausgeschaltet sind.
> Egal welche Position SW9 hat...

zeigt sich diese Verhalten auch wenn du
1
DmxAddress=1;
oder nur wenn du die DIPs einliest?

Gibt es einen Grund das dmx_buffer als Array ausgeführt wird? Das 
Startbit kannst du auch direkt auf 0 prüfen.
1
  if(tmp == 0)    
2
    {
3
      dmx_valid = 1;    
4
      ledBlueToggle();
5
      dmx_channel_rx_count++;
6
    }

Da du nur ein Datenbyte brauchst kannst du auch:
1
if(dmx_valid)
2
  {
3
  if (dmx_channel_rx_count > DmxAddress) return;
4
    else if (dmx_channel_rx_count == DmxAddress) dmx_buffer = tmp;
5
    dmx_channel_rx_count++;
6
    return;
7
  }

oder gleich:
1
 if(dmx_valid)
2
  {
3
  if (dmx_channel_rx_count > DmxAddress) return;
4
5
  else if (dmx_channel_rx_count == DmxAddress) 
6
  {
7
    if (tmp < 127)
8
        {
9
          RelayOff();
10
        } 
11
    else
12
        {
13
          RelayOn();
14
        }
15
  }
16
    dmx_channel_rx_count++;
17
    return;
18
  }

Es wäre auch darüber nachzudenken das DataOverrun Flag zu lesen 
dmx_valid  bei einem overrun auf 0 zu setzen.

Achtung Code ungetestet

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Stefan schrieb:

> Hab ich angehängt.

Die Empfangsroutine ist immer noch Unsinn. Korrekt gegebene Hinweise im 
Thread wurden in keinster Weise berücksichtigt, insbesondere (in 
Reihenfolge der Relevanz für die Nicht-Funktion): "Reihenfolge des 
Auslesens von Daten- und Statusregister", "fehlender vollständiger Test 
auf BREAK", "fehlender Test auf Data-Overrun").

Das sind die Knackpunkte, solange nicht wenigstens das korrekt umgesetzt 
ist, kann und wird es nicht korrekt und zuverlässig funktionieren 
können. Aber: es sind noch mehr Bugs drinne. Nur wirst du die niemals 
finden können, solange nicht wenigstens die Basis der Sache zuverlässig 
funktioniert...

Lustigerweise: wenigstens der völlig abstruse Kommentar wurde 
korrigiert. Leider ändert aber eine korrekte Kommentierung des "Soll" 
alleine noch nichts am "Ist" einer Funktion...

von S. Landolt (Gast)


Lesenswert?

an Stefan:

Vorab: ich verweise auf den Beitrag von gestern 21:27 bez. UDR <-> 
UCSRA.FE

> Ich versuche ein DMX Relais zu bauen, mit nur einem Kanal.
Wo wird das 'Startbyte' (lt. Wikipedia, ich bin DMX-Laie) abgehandelt? 
Ich würde, nur zur Probe, mal versuchen:
1
  // DMX Adresse festlegen
2
  DmxAddress=2;//1;

Das Flackern kann ich mir eigentlich nicht erklären, vielleicht gibt es 
noch ein Hardwareproblem.

von Stefan (Gast)


Lesenswert?

Sehr geehrter c-hater,

alleine der Name zeigt schon wie absolut fehlend die Akzeptanz anderer 
Meinungen und andere Ansätze vorhanden ist.
Ich für meinen Teil konnte Deine Nachrichten gut ignorieren und möchte 
mich nochmal bei den Helfenden bedanken.
Leider fehlt bei einigen wenigen durchaus der Wille sinnvoll und vor 
allem zielführend zu diskutieren oder eben sein Wissen ohne Wertung mit 
anderen zu teilen. Sondern hier liegt das Ziel eher dabei, sich selber 
ein gewisses Maß an Aufmerksamkeit zu erschleichen und sein eigenes 
Selbstwertgefühl mit beleidigenden Aussagen aufzubauen. Ich danke für 
die Kommentare, denn das hat mir durchaus den Anstoß gegeben, das Ganze 
zu schaffen.
Zumal wenn man die Nachrichten hier in der richtigen Reihenfolge liest, 
kamen einige Änderungen nach dem zuletzt angehängten Code. Deswegen kann 
Ihnen leider überhaupt nicht klar sein, ob die Fehler zum jetzigen 
Zeitpunkt noch im Code vorhanden sind.

Nochmal möchte ich mich bei den Helfern bedanken. Es hat mir wirklich 
viel geholfen. Ich habe den Code heute komplett überarbeitet, das DOR 
noch eingebaut, Variablen bereinigt und ein DMX Lost noch eingesetzt. 
Wie gestern gegen Ende schon geschrieben, das Relais funktioniert jetzt. 
Der Fehler mit den DIPs ist immernoch da, aber in der nächsten Rev. hab 
ich die DIPs auf PORTB gelegt und die Verteilung etwas verändert. Vielen 
Dank auch für diese Tips. Ich werde sehen, ob es was nützt.

Ich finde es schön zu Wissen, das man hier schnelle und qualifiziert 
Antworten auf Fragen bekommt.

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

> Wo wird das 'Startbyte' (lt. Wikipedia, ich bin DMX-Laie) abgehandelt?

Gleich im ersten "if" der ISR und in der Zeile davor. Nur halt FALSCH 
und zwar gleich in doppelter Hinsicht. Zum einen wird durch die falsche 
Reihenfolge des Zugriffs auf UDR und UCSRA die Information von UCSRA de 
facto weggeworfen (das ist das Hauptproblem!), zum anderen wird nicht 
wirklich auf BREAK getestet (nur auf ein erforderliches, aber allein 
nicht hinreichendes Anzeichen dafür in Form des gesetzten FE-Bits).

Alle nötigen Hinweise wurden im Thread gegeben. Wenn sie nicht genutzt 
werden, zeigt das nur eins: grenzenlose Mißachtung der Helfer und/oder 
absolute Inkompetenz des TO. Die ist halt so gering, dass nichtmal 
zielführende Hinweise als korrekt erkannt und entsprechend umgesetzt 
werden...

von S. Landolt (Gast)


Lesenswert?

Schon, aber der Zähler dmx_channel_rx_count läuft dabei mit, und er 
wird später mit DmxAddress verglichen.

von c-hater (Gast)


Lesenswert?

Stefan schrieb:

> alleine der Name zeigt schon wie absolut fehlend die Akzeptanz anderer
> Meinungen und andere Ansätze vorhanden ist.

Tja, das Problem ist halt einfach, das logische Systeme wie z.B. 
µC-Programme kaum Platz lassen für "Meinungen" und "alternative 
Ansätze". Da zählen i.A. nur Fakten...

> Zumal wenn man die Nachrichten hier in der richtigen Reihenfolge liest,
> kamen einige Änderungen nach dem zuletzt angehängten Code. Deswegen kann
> Ihnen leider überhaupt nicht klar sein, ob die Fehler zum jetzigen
> Zeitpunkt noch im Code vorhanden sind.

Wenn's jetzt funktioniert, sind sie wohl nicht mehr vorhanden. Das hast 
du aber nicht irgendwelchen "Meinungen" oder "alternativen Ansätzen" zu 
verdanken, sondern einfach der Tatsache, dass du am Ende wohl doch in 
der Lage warst, die gegebenen Hinweise korrekt umzusetzen.

Und wenn das so ist, ist es eine bodenlose Frechheit, den korrigierten 
und nunmehr funktionierenden Code nicht auch hier zu veröffentlichen. 
Das nicht zu tun, zeigt ganz klar, was du bist: ein Nassauer!

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

:D Na da wären die Nassauer aber beleidigt jetzt.

Ich war einfach noch nicht ganz fertig. Also jetzt hier der fertige 
Code.

Danke nochmal an die Helfer.

Und in diesem Sinne, in der heutigen Zeit, bleibt gesund!

von S. Landolt (Gast)


Lesenswert?

1
  TCCR0A |= (1<<WGM01);
2
  TCCR0B |= (1<<CS00);
3
  TIMSK |= (1<<OCIE0A);
4
  OCR0A = F_CPU/1024/100 - 1; //Tick 1ms
Kommentar?
Ich komme auf 9.75 us; mal 8000 ergibt 78 ms für die DMX-Lost-Erkennung.

von Stefan (Gast)


Lesenswert?

Jetzt stehe ich tatsächlich aufm Schlauch.

Beim Nachrechnen komme ich sogar nur auf 10ms...

Der OCR0A ergibt ja 78,125 Schritte

f.OC0A = 8000000/1024/78,125 = 100Hz also nur 0,01s

also müssten es eigentlich F_CPU/1024/1000 sein.

Oder wo ist da der Denkfehler?

von S. Landolt (Gast)


Lesenswert?

OCR0A wird auf 77 gesetzt, der Interrupt wird folglich alle 78 * 1/F_CPU 
ausgelöst, d.h. 9.75 us (bei 8 MHz).
  Im Zweifel einfach nachmessen: in der ISR (TIMER0_COMPA_vect) einen 
Ausgang toggeln und Frequenzzähler oder Oszilloskop dran.

von Stefan (Gast)


Lesenswert?

Ja. Klar. Stimmt, weil ich die 1024 in der Berechnung stehen habe und 
nicht als Prescaler aktiviert.
Da gehe ich nachher nochmal dran.

Danke für den Hinweis

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.