www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Array mit 512 Bytes über Rs232 vom PC zum PIC


Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi leute,
Derzeit beschäftige ich mit DMX.
Ich will mithilfe des Freeware-Programms DMXControl die DMX-Daten zu 
meinem PIC senden, um diese dann als DMX-Signal auszugeben. Der letzte 
Punkt ist derzeit unwichtig, also es geht nur über die Übertragung vom 
PC zum PIC.
Wie man Ausgabeplugins in DMXControl Programmiert ist mir klar, die 
Kommunikation zwischen dem Ausgabeplugin und dem PIC mit RS232 haut auch 
tadellos hin.
Nur ich weiß nicht, wie ich ein Array mit 512 Bytes (512 DMX Kanäle mit 
jeweils 8 bit) zum PIC schicken bzw empfangen soll. Das ganze sollte 
möglichst schnell gehen und nur geänderte Werte sollten übertragen 
werden. Die senderoutine wird in Visual-Basic 6 programmiert.
Die ganze Software am PIC bitte nur in C!

Ich bin leider kein Profi-Programmierer; Code-Beispiele wären sehr cool. 
Besonders über die Empfangsroutine am PIC mache ich mir Gedanken.

Danke schonmal für eure Antworten!

MFG Emanuel

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel Jörgner schrieb:
> Hi leute,
> Derzeit beschäftige ich mit DMX.
> Ich will mithilfe des Freeware-Programms DMXControl die DMX-Daten zu
> meinem PIC senden, um diese dann als DMX-Signal auszugeben. Der letzte
> Punkt ist derzeit unwichtig, also es geht nur über die Übertragung vom
> PC zum PIC.
> Wie man Ausgabeplugins in DMXControl Programmiert ist mir klar, die
> Kommunikation zwischen dem Ausgabeplugin und dem PIC mit RS232 haut auch
> tadellos hin.
> Nur ich weiß nicht, wie ich ein Array mit 512 Bytes (512 DMX Kanäle mit
> jeweils 8 bit) zum PIC schicken bzw empfangen soll.
wo liegt da jetzt das Problem genau? Ich denke die Daten kommen aus 
DMXControl ?

> Das ganze sollte
> möglichst schnell gehen
standart DMX=250kBit/s * 512 -> ca. 20ms

> und nur geänderte Werte sollten übertragen
> werden.
dann ist's aber kein DMX-Protokoll mehr

> Die senderoutine wird in Visual-Basic 6 programmiert.
also kommen die Daten nicht aus DMXControl?!

> Die ganze Software am PIC bitte nur in C!
am PIC die 512Byts so wie sie empfangen werden in einen Puffer 
schreiben, aus dem werden die Daten dann auch weiterverarbeitet (PWM?).

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke mal für die Antwort.

Sorry, ich habs wohl nicht klar genug beschrieben

Der Plan ist ja ein eigenes DMX-Interface zu bauen.

Die DMX Daten aus DMXControl haben noch nichts mit dem fertigen DMX 
Protokoll zu tun. Das sind einfach rein die Werte der einzelnen Kanäle 
die übertragen werden sollen. Erst im PIC sollen sie dann gepuffert und 
im RS485-Format, also als DMX-Protokoll, ausgegeben werden. Mein Problem 
ist aber nur die übertragung vom PC zum PIC. Das is einfach ein Array 
mit 512 Bytes. Diese müssen in den PIC. Wie mach ich das?

Ich hoffe dass es jetz klar is ;)

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich hoffe dass es jetz klar is ;)
??
die 512Byte sind doch die Kanaldaten der 512 Kanäle - oder nicht!
und die werden per RS232 vom PC übertragen - damit sind das doch schon 
die DMX-Daten. Was soll denn nun der PIC noch machen? RS485 ist kein 
Protokoll sondern nur die Art der pysikalischen Übertragung.

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja klar sind das schon die 512 Kanaldaten, die Frage ist ja WIE 
übertrage ich die Daten vom PC zum PIC. Die Programmierung, wie ich ein 
Array mit 512 Bytes den PIC schicken soll, geht mir nicht auf. Was dann 
weiters im PIC mit den Daten passiert ist vorerst mal egal. Sie sollen 
nur wieder in ein Array gespeichert werden, so dass PC und PIC auf dem 
gleichen Stand sind.

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht meinst du warum ich die Daten nicht gleich direkt ausm PC als 
DMX-Signal ausgebe - also gleich aus der RS232-Schnittstelle die 
DMX-Scheinwerfer anschließe? Das geht nicht weil man noch z.B einen 
RS485 Treiberbausten braucht und die Daten im PIC gepuffert werden 
sollen, und nur geänderte Werte vom PC empfangen werden sollen um 
Übertragungsfehler zu vermeiden.
Wieso glaubst du gibt es so viele DMX-Interfaces? Weils einfach nicht 
möglich ist bzw. "unsauber" ist die Daten direkt für die DMX-Geräte 
auszugeben

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Vielleicht meinst du warum ich die Daten nicht gleich direkt ausm PC als
> DMX-Signal ausgebe - also gleich aus der RS232-Schnittstelle die
> DMX-Scheinwerfer anschließe?
ja

> Das geht nicht weil man noch z.B einen
> RS485 Treiberbausten braucht
und der lässt sich doch mit einer einfachen Schaltung an RS232 
ankoppeln, abgesehen davon brauchst du den nach dem PIC immer noch.

> und die Daten im PIC gepuffert werden
> sollen, und nur geänderte Werte vom PC empfangen werden sollen um
> Übertragungsfehler zu vermeiden.
wie soll die Übertragung sicherer werden wenn du eine Übertragung 
(PC->DMX) in zwei aufeinanderfolgende (PC->PIC  PIC->?DMX?) zerlegst, 
oder vom PC zum PIC weniger Werte übertragen werden um dann 
DMX-kompatibel trotzdem alle 512Bytes über RS485 zu senden?
Um nur geänderte Werte zu Übertragen brauchst du eine adressierte 
Übertragung, für die 512 Kanäle brauchst du eine 2-Byte Adresse, das 
heist für jeden Kanal nun 3 Byte - wird also nur sinnvoll wenn sich 
weniger als 1/3 der Werte ändern.

> Wieso glaubst du gibt es so viele DMX-Interfaces? Weils einfach nicht
> möglich ist bzw. "unsauber" ist die Daten direkt für die DMX-Geräte
> auszugeben
es soll also in etwa sowas 
http://www.digital-enlightenment.de/usbdmx.htm dabei rauskommen.

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:

>> Das geht nicht weil man noch z.B einen
>> RS485 Treiberbausten braucht
> und der lässt sich doch mit einer einfachen Schaltung an RS232
> ankoppeln, abgesehen davon brauchst du den nach dem PIC immer noch.

das war mir klar.

>> und die Daten im PIC gepuffert werden
>> sollen, und nur geänderte Werte vom PC empfangen werden sollen um
>> Übertragungsfehler zu vermeiden.
> wie soll die Übertragung sicherer werden wenn du eine Übertragung
> (PC->DMX) in zwei aufeinanderfolgende (PC->PIC  PIC->?DMX?) zerlegst,
> oder vom PC zum PIC weniger Werte übertragen werden um dann
> DMX-kompatibel trotzdem alle 512Bytes über RS485 zu senden?

weil wenn der Computer z.b. Abstürzt oder hängen bleibt die Daten immer 
noch vom pic gesendet werden, da diese ja im PIC gepuffert sind.

> Um nur geänderte Werte zu Übertragen brauchst du eine adressierte
> Übertragung, für die 512 Kanäle brauchst du eine 2-Byte Adresse, das
> heist für jeden Kanal nun 3 Byte - wird also nur sinnvoll wenn sich
> weniger als 1/3 der Werte ändern.

Du sagst es, und genau das möchte ich machen. Wenn nur geänderte Daten 
gesendet werden ist der Traffic nicht so hoch. Meine Frage: Wie 
programmiere ich das??????

>> Wieso glaubst du gibt es so viele DMX-Interfaces? Weils einfach nicht
>> möglich ist bzw. "unsauber" ist die Daten direkt für die DMX-Geräte
>> auszugeben
> es soll also in etwa sowas
> http://www.digital-enlightenment.de/usbdmx.htm dabei rauskommen.

ganz genau, nur mit dem unterschied dass ich das alles wirklich selber 
mach. Das Ding hab ich übrigens schon gebaut xD

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:

> ist aber nur die übertragung vom PC zum PIC. Das is einfach ein Array
> mit 512 Bytes. Diese müssen in den PIC. Wie mach ich das?

Ein Bytze nach dem anderen.
Wo liegt da jetzt das Problem?

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ein Bytze nach dem anderen.
> Wo liegt da jetzt das Problem?

Naja, ganz so einfach ist es nicht, denn - wie Sascha schon schrieb - 
brauch ich für jedes Byte eine Adressierung (2 Byte) + der Wert selbst 
(1 Byte).
Das Problem liegt jetzt darin dass ich kein profi-programmierer bin und 
ich das alleine nicht umsetzen kann.
:-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Karl heinz Buchegger schrieb:
>> Ein Bytze nach dem anderen.
>> Wo liegt da jetzt das Problem?
>
> Naja, ganz so einfach ist es nicht, denn - wie Sascha schon schrieb -
> brauch ich für jedes Byte eine Adressierung (2 Byte) + der Wert selbst
> (1 Byte).

Ja. Und
Deswegen gehen trotzdem immer noch lediglich Bytes über die 
Schnittstelle. Der Schnittstelle an sich ist es ja völlig egal, was das 
Byte welches gerade übertragen wird, jetzt für Sender und Empfänger 
bedeutet.

> Das Problem liegt jetzt darin dass ich kein profi-programmierer bin und
> ich das alleine nicht umsetzen kann.
> :-)

Dann musst du das lernen.
Viele Bytes übertragen ist auch nur 1 Byte übertragen und das x mal, 
eins nach dem anderen.

Interessanter ist die Fragestellung: Woher weiß der Empfänger eigentlich 
welches Byte jetzt gerade übertragen wird, was seine Bedeutung ist? 
Irgendwie muss der Empfänger beim Ansehen des Bytes diese Information 
entnehmen können, denn was anderes hat er nicht (ausser vielleicht durch 
die Reihenfolge).
Und da kannst du dich austoben, wie es dir gefällt.

Aber dein erstes Teilziel ist und bleibt: Wie kriege ich 1 Byte vom PC 
zum Empfänger.

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Ja. Und
> Deswegen gehen trotzdem immer noch lediglich Bytes über die
> Schnittstelle. Der Schnittstelle an sich ist es ja völlig egal, was das
> Byte welches gerade übertragen wird, jetzt für Sender und Empfänger
> bedeutet.

Stimmt. War ein denkfehler xD

> Viele Bytes übertragen ist auch nur 1 Byte übertragen und das x mal,
> eins nach dem anderen.
>
> Interessanter ist die Fragestellung: Woher weiß der Empfänger eigentlich
> welches Byte jetzt gerade übertragen wird, was seine Bedeutung ist?
> Irgendwie muss der Empfänger beim Ansehen des Bytes diese Information
> entnehmen können, denn was anderes hat er nicht (ausser vielleicht durch
> die Reihenfolge).
> Und da kannst du dich austoben, wie es dir gefällt.
>
> Aber dein erstes Teilziel ist und bleibt: Wie kriege ich 1 Byte vom PC
> zum Empfänger.

Ok, das is schonmal ein gutes Anfangsziel. Das hab ich auch schon 
zusammengebracht.
In VB6 mach ich das mit
MSComm1.output = Chr(DMXValues(1))

DMXValues ist das Array mit den 512 bytes. Hier wird der Wert des ersten 
Kanals über die COM-Schnittstelle ausgegeben.
Auf der seite des PICs empfange ich mit
getc()

Jetzt mal meine Fragen zum SENDEN
a) wie mach ich das mit der genauen Adressierung?
b) wie mach ich das, dass nur geänderte Werte übertragen werden?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:

> Jetzt mal meine Fragen zum SENDEN
> a) wie mach ich das mit der genauen Adressierung?

Da musst du dir jetzt was ausdenken.

Gegeben 3 Zahlen im Bereich 0 bis 255

   18  24  7  56  127  12  89

Woran erkennst du jetzt, was Adresse ist und was Daten (die zu dieser 
Adresse gehören) ist?

Jetzt ist deine Kreativität gefragt :-)
Du musst das entwickeln, was man gemeinhin ein Protokoll nennt.

> b) wie mach ich das, dass nur geänderte Werte übertragen werden?

ZB. Du merkst dir welchen Wert du zuletzt zum µC übertragen hast. Jetzt 
vergelichst du den neuen Kandidaten mit diesem Wert und wenn beide 
gleich sind, brauchst du den Wert nicht zu übertragen.

Eventuell stellt sich diese Frage aber auch gar nicht, denn die Werte 
kommen ja nicht aus der freien Luft, sondern die wird dir ja zb ein 
Benutzer einstellen. Wenn der am Kanal 25 einen neuen Wert vorgibt, dann 
hat sich Kanal 25 verändert und alle anderen nicht.

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Da musst du dir jetzt was ausdenken.
>
> Gegeben 3 Zahlen im Bereich 0 bis 255
>
>    18  24  7  56  127  12  89
>
> Woran erkennst du jetzt, was Adresse ist und was Daten (die zu dieser
> Adresse gehören) ist?

Ich denke an garnichts. Wahrscheinlich sind start/stoppbits/resets genau 
für sowas da...

> Jetzt ist deine Kreativität gefragt :-)
> Du musst das entwickeln, was man gemeinhin ein Protokoll nennt.

Ja, das muss ich wohl, deshalb frage ich ja wie ichs am besten mach xD, 
mit Programmierbeispielen lerne ich es am besten

danke für deine Hilfe und Geduld^^

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Karl heinz Buchegger schrieb:
>> Da musst du dir jetzt was ausdenken.
>>
>> Gegeben 3 Zahlen im Bereich 0 bis 255
>>
>>    18  24  7  56  127  12  89
>>
>> Woran erkennst du jetzt, was Adresse ist und was Daten (die zu dieser
>> Adresse gehören) ist?
>
> Ich denke an garnichts. Wahrscheinlich sind start/stoppbits/resets genau
> für sowas da...

Das hat damit nichts zu tun.
Start Stopp Bits regeln die Übertragung auf viel niedrigerer Ebene.
Du musst dir hier etwas einfallen lassen!

> Ja, das muss ich wohl, deshalb frage ich ja wie ichs am besten mach xD,
> mit Programmierbeispielen lerne ich es am besten

Oh nein.
Soweit bist du noch lange nicht. Erst mal brauchst du ein Schema, eine 
Vorschrift, ein Protokoll, nach dem die Übertragung laufen soll. Ohne 
Protokoll hat es keinen Sinn zur Tastatur zu greifen.

Ein paar Gedankengänge.

* man könnte zb vereinbaren, dass keine DMX Daten vorkommen, die größer 
als 127 sind. Statt dessen ist 127 (also ein gesetztes 7. Bit) für das 
erste Adressbyte reserviert. Bekommt also der Empfänger die Sequenz zu 
sehen

    78 56 128 20 56 129 02 78

dann weiß er, dass die ersten beiden Bytes von einer vorhergehenden 
Nochricht stammen, die er verpasst hat.
Bei 128 ist das 7. Bit gesetzt, dort beginnt also eine Adresse. Dieses 
Bit löschen lässt 0 zurück. Also ist das nächste Byte, die 20, bereits 
die Adresse. Und der Wert der an Kanal 20 zugewiesen werden soll ist 
daher dann 56.
Danach kommt 129. Auch hier ist wieder das 7. Bit gesetzt, es handelt 
sich also um das erste Adressbyte. 7. Bit löschen (128 abziehen) lässt 1 
zurück. Daher ist das nächste Byte, die 02, nicht wirklich 02 sondern 2 
+ 128, also 130. Und an den Kanal 130 wird der Wert 78 zugewiesen.

* man könnte auch vereinbaren, dass zb der Wert 255 weder in den Daten 
noch in den Adressen vorkommen darf. Jede Nachricht besteht nicht aus 3 
Bytes sondern aus 4, von denen das erste Byte immer 255 ist. In der 
Sequenz

    78 56 255 0 20 56 255 1 3 78

kann man wieder anhand der 255 erkennen, wo die Adressangabe anfängt. 
Das nächste Byte ist 0 und dann folgt 20. 0 sagt uns wiederrum, dass die 
20 schon stimmen, es also um den Kanal 20 geht und dieser Kanal kriegt 
den Wert 56. Darauf folgt wieder eine 255. Also die nächste Nachricht 
beginnt. Das erste Adressbyte hat den Wert 1, es handelt sich also um 
einen der oberen Kanäle, 255 bis 512. Die 3 im nächsten Byte sagt, dass 
es sich um den Kanal 258 (255 + 3) handelt und der bekommt den Wert 78


Das sind jetzt nur 2 Beispiele. Denk dir selber was aus. Die 
Möglichkeiten sind vielfältig.

Vielleicht ist aber auch eine rein binäre Übertragung gar nicht so toll. 
Eventuell geht es mit Texten schicken viel einfacher:

"$78=34;$23=15"

sollte eigentlich unmittelbatr einsichtig sein, was es zu bedeuten hat. 
Dem Kanal 78 wird als neuer Wert die 34 zugewiesen. Dem Kanal 23 die 15. 
Jede Nachricht beginnt (zb) mit $ und endet mit einem ; (wieder: kann 
man so machen, muss man aber nicht unbedingt)
Vorteil: Das was über die Leitung geht ist leicht zu verstehen. 
Nachteil: man muss durch die 'Textverarbeitung' durch und Nachrichten 
sind nicht immer gleich lang
$0=1;
$347=237;

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du gibst dir ja echt mühe - danke :)

dein erstes Beispiel is mir jetzt eher weniger klar, ganz im Gegenteil 
vom zweiten. Leider kann man aber nicht einfach vereinbaren dass z.B. 
DMX-Werte begrenzt sind, da es ja ein festgelegtes Protokoll ist oder?
Jetzt verstehe ich auch auf was du hinauswillst, und ja, da gibts 
wirklich viel möglichkeiten wie man das machen könnte...

Das mit dem Text hab ich mir auch schonmal gedacht, nur wie wertet man 
sowas aus?
Das mit der länge könnte man mit nullen vor der Zahl lösen, also hat 
adresse und wert immer 3 stellen.
Statt $5=8; halt einfach $005=008;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:

> vom zweiten. Leider kann man aber nicht einfach vereinbaren dass z.B.
> DMX-Werte begrenzt sind, da es ja ein festgelegtes Protokoll ist oder?

Langsam.
Was DU über die RS232 zum PIC überträgst ist deine Sache. Das kannst du 
machen wie du willst. Was der PIC dann an die DMX Geräte rausgibt, das 
ist dir vorgegeben. Du kannst, wenn du willst, auch Brieftauben mit 
Papierstreifen und Morsecode zum PIC schicken, interessiert deine DMX 
Geräte nicht die Bohne. Die hören nur darauf was sie vom PIC bekommen. 
Wie der wiederrum zu seinen Erkentnissen kommt, ist denen völlig egal.

Wichtig ist, dass das was du an der Pluginschnittstelle vom DMXControl 
bekommst letztendes auf dem PIC ankommt. Auf welchen Wegen das passiert 
und wie du das zwischenzeitlich umwandelst, das ist ganz und gar dir 
überlassen. Und wenn dein Plugin die Daten ausdruckt und dein PIC macht 
Texterkennung auf dem Ausdruck, dann ist das auch ok.


> Das mit der länge könnte man mit nullen vor der Zahl lösen, also hat
> adresse und wert immer 3 stellen.
> Statt $5=8; halt einfach $005=008;

Könnte man zb machen.

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, die nächste Frage kannst du dir ja vorstellen; wie erkenne ich den 
Text im PIC?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besorg dir ein C-Buch und lerne.

Das du die einzelnen Zeichen zu einem String zusammensetzen musst, 
dürfte ja wohl klar sein.
Auf dem String kann man dann mit Stringoperationen den String 
auseinandernehmen.


Sorry. Aber ich will eigentlich nicht mehr für jemand anderes seine 
Projekte komplett durch-programmieren, nur weil er etwas machen will, 
was er noch nicht kann. Wenn er das nicht selbst kann, dann muss er das 
eben lernen. Ich habs auch müssen. Und Stringverarbeitung in C ist das 
erste etwas kompliziertere Basiswissen.

http://www.mikrocontroller.net/articles/FAQ#Wie_fu...
http://www.sprut.de/electronic/pic/c/pic_c/pic_c00.html

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

um die Begrenzung des Werteumfangs zu umgehen und gleichzeitig mit 3 
Bytes pro Wert auszukommen und den Anfang einer Übertragung zu erkennen 
könnte man folgendes machen:

gegeben: Adresse 1..512   braucht 9 Bit
         Daten   0..255   braucht 8 Bit

Byte 1   Byte 2   Byte 3
S0000WAA 0AAAAAAA 0WWWWWWW

S=immer 1 und kennzeichnt den Begin einer Nachricht
A=Adresse  Bit 8-7 im Byte 1
           Bit 6-0 im Byte 2
W=DMX Wert Bit 7   im Byte 1
           Bit 6-0 im Byte 3


Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist eine gute Idee, ur wie kann ich bytes auf diese Art 
"aufspalten"?!
Konzept ist super, nur das umzusetzen ist meine schwäche.

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PC:
Byte1=128 + ((Adresse & 192) >> 6) + ((Wert & 128) >> 5)
Byte2= Adresse & 127
Byte3= Wert & 127

PIC:
ok das man mit getc() ein Byte einliest weisst du ja schon

mal etwas Pseudocode

int   ADDR         ;Adresse
byte  WERT         ;Wert
byte  recB         ;Byte das empfangen wurde
byte  recSt        ;Status

Empfang:
recSt = 0
while recSt < 3
  recB=getc()
  if recSt=0 then                  ;noch auf 1. Byte warten ?
     if recB && 128 then           ;Startbit gesetzt ?
          recSt=1
          ADDR=(recB & 3) << 6     ;nur Adressbits und zur richtigen Pos
          WERT=(recB & 4) << 5     ;nur Wertebit und zur richtigen Pos
     endif
  else
     if recSt=1 then
          recSt=2
          ADDR=ADDR + recB           ;Rest der Adresse
     endif
     if recSt=2 then
          recSt=3
          WERT=WERT + recB           ;Rest des Wertes
     endif
  endif
wend

;ADDR und WERT gelesen, speichern und was auch immer

-----------
achso: Kanal 1 bis 512 = Adresse 0 bis 511

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> PC:
> Byte1=128 + ((Adresse & 192) >> 6) + ((Wert & 128) >> 5)

so wies ausschaut gibt es in VB6 keine Möglichkeit zur Bitverschiebung, 
zumindest nicht mit der Methode ">>"

Autor: XXX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kukkst du hier:

http://vb-tec.de/bitshift.htm

Gruß
Joachim

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> so wies ausschaut gibt es in VB6 keine Möglichkeit zur Bitverschiebung,
> zumindest nicht mit der Methode ">>"
ja dann nimm halt eine Multiplikation oder Division

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> PC:
> Byte1=128 + ((Adresse & 192) >> 6) + ((Wert & 128) >> 5)

wieso eigentlich "& 192" und "& 128"?

wenn ich das so mach wie Joachim meinte müsste es so richtig aussehen 
oder?
byte1 = 128 + ((ShiftRight((adresse & 192), 6)) + ((ShiftRight((DMXValues(adresse) & 128), 5))))

(und die Funktion selber halt)

da bekomm ich aber einen überlauf

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Sascha Weber schrieb:
>> PC:
>> Byte1=128 + ((Adresse & 192) >> 6) + ((Wert & 128) >> 5)
>
> wieso eigentlich "& 192" und "& 128"?
ja die oberen beiden Bit's der Adresse halt
-> aber mein Fehler - das sind ja Bit 7 und 8 also muss der Wert 384 
(256+128) sein !

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:

> ja dann nimm halt eine Multiplikation oder Division

auf vb-tec.de steht, dass eine Verschiebung nach rechts einer Division 
durch 2 entspricht.

In unserem Fall:
byte1 = 128 + (((nummer & 384) / 2 / 2 / 2 / 2 / 2 / 2) + ((DMXValues(nummer) & 128) / 2 / 2 / 2 / 2 / 2))

--> Überlauf

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also das mit dem '&' scheint in VB nicht zu gehen zumindest in VBA 
geht's nicht!
So müsste es passen:
a = 128 + (nummer And 384) / 128 + (DMXValues(nummer) And 128) / 32

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> So müsste es passen:
> a = 128 + (nummer And 384) / 128 + (DMXValues(nummer) And 128) / 32

Immer noch Überlauf
Dim a as byte
 müsste auch passen oder?

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja
Dim a, w As Byte
Dim n As Integer
    n = 511 'Kanal  0..511
    w = 127 'Wert   0..255
    a = 128 + (n And 384) / 128 + (w And 128) / 32
    Debug.Print a

als was ist DMXValues deklariert?

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> als was ist DMXValues deklariert?

Als Byte
Array mit 512 Bytes (für die DMX-Kanäle)

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie hast du getestet?
Zeig mal deinen Code.

bei meinem Test ...
Sub test()
Dim a As Byte
Dim w, n As Integer
    For n = 0 To 511 'Kanal
        For w = 0 To 255 'Wert
            a = 128 + (n And 384) / 128 + (w And 128) / 32
        Next
    Next
    Debug.Print a
End Sub
... mit Schleife muss ich w als Int deklarieren sonst bringt die 
Schleife am Ende OV!

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> wie hast du getestet?
> Zeig mal deinen Code.

Private Sub timOutput_Timer()
 Dim i As Long
 Dim nummer As Long
 Dim byte1 As Byte
 Dim byte2 As Byte
 Dim byte3 As Byte
 
 ' Wenn das Plugin aktiviert ist
 If OutputEnable Then
  
  If MSComm1.PortOpen = True Then
  
 ' Überprüfen ob sich ein Wert geändert hat
    For nummer = 0 To 512
        If DMXValues(nummer) <> DMXValuesOld(nummer) Then
        
            byte1 = 128 + (nummer And 384) / 128 + (DMXValues(nummer) And 128) / 32
            byte2 = nummer & 127
            byte3 = DMXValues(nummer) & 127

            DMXValuesOld(nummer) = DMXValues(nummer)
        End If
    Next
  End If
 End If

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
            byte2 = nummer & 127
            byte3 = DMXValues(nummer) & 127
! das '&' muss auch dort durch 'and' erstezt werden !

* nummer sollte sich im Bereich von 0 bis 511 bewegen, 0 bis 512 sind ja 
schon 513 Kanäle!

Ich hab's jetzt noch mal in VB getestet dort geht's.
        Dim nummer As Long
        Dim byte1 As Byte
        Dim byte2 As Byte
        Dim byte3 As Byte
        Dim DMXValues(512) As Byte
        Dim DMXValuesOld(512) As Byte

        For nummer = 0 To 511
            DMXValues(nummer) = Rnd(1) * 255
            DMXValuesOld(nummer) = 0
        Next
        ' Überprüfen ob sich ein Wert geändert hat
        For nummer = 0 To 511
            If DMXValues(nummer) <> DMXValuesOld(nummer) Then

                byte1 = 128 + (nummer And 384) / 128 + (DMXValues(nummer) And 128) / 32
                byte2 = nummer And 127
                byte3 = DMXValues(nummer) And 127

                DMXValuesOld(nummer) = DMXValues(nummer)
            End If
        Next
        MsgBox("Test Ok")

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, jetz hab ich keinen Fehler mehr.

Senden tu ich mit Chr(..), also
MSComm1.Output = Chr(byte1)
MSComm1.Output = Chr(byte2)
MSComm1.Output = Chr(byte3)

...weil ohne dem Chr() bekomm ich die Fehlermeldung "Ungültiger 
Eigenschaftswert"
Wenn ich mit einem Terminalprogramm den Ausgang überwache bekomme ich 
übrigens nur alle Tasten der Tastatur hinuntergebrettert (askii-code). 
Ich hoffe es funktioniert trotzdem.

Am PIC konnte ich es aus Zeitgründen noch nicht testen, wenn ichs hab 
melde ich mich.

THX

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Ok, jetz hab ich keinen Fehler mehr.
>
> Senden tu ich mit Chr(..), also
>
>
MSComm1.Output = Chr(byte1)
> MSComm1.Output = Chr(byte2)
> MSComm1.Output = Chr(byte3)
genau

> Wenn ich mit einem Terminalprogramm den Ausgang überwache bekomme ich
> übrigens nur alle Tasten der Tastatur hinuntergebrettert (askii-code).
> Ich hoffe es funktioniert trotzdem.
du kannst die Ausgabe auch z.B. mit Hterm anschauen, dort kannst du auf 
DEZ o. HEX umschalten und siehst auch die nicht-ASCII-Zeichen.

Sascha

Autor: Ehrhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenns einfach sein soll und der Overhead keine Rolle spielt mache es so:

Datenpaket für einen bestimmten Wert - 5 Bytes je Paket):

word $4458 = Magic-Word "DX"
word $xxxx = Index des Wertes, z.Bsp. Wert 100
byte $yy   = DMX-Value


Das datenpaket sieht dann so aus: "DXxxy"

Für eine Komplette Werteliste zum Anfang kannst du statt "DX" z.Bsp. 
"XX" senden und anschließend alle 512 Byte-Werte übertragen, damit alle 
Elemente einen Wert haben.

Auf Controller-Ebene wäre das dann (pseudocode):
dim magic as word
dim index as word
dim value as byte
dim DMXValues(511) as word

do
  magic=waitinput(2)  ' 2 bytes
  select case magic
  case $4458  ' DX - Wert soll aktualisiert werden  
    index=waitinput(2) ' index-Nummer lesen (2 Bytes)
    value=waitinput(1) ' Wert lesen (1 Byte)
    DMXValues(index)=value
  case $5858  ' XX - Liste soll aktualisiert werden
    for i=0 to 511
      DMXValue(i)=waitinput(1)
    next
  end select
loop

Sicherheitsabfragen sollte man natürlich einbauen, beispielsweise die 
Werte zuvor in ein empfangsbuffer übertragen anstatt gleich in das 
DMXValue-Array und erst dort hineinschreiben wenn die Übertragung 
vollständig und in Ordnung gewesen ist.

Ehrhardt

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> PIC:
> mal etwas Pseudocode
>
> int   ADDR         ;Adresse
> byte  WERT         ;Wert
> byte  recB         ;Byte das empfangen wurde
> byte  recSt        ;Status
>
> Empfang:
> recSt = 0
> while recSt < 3
>   recB=getc()
>   if recSt=0 then                  ;noch auf 1. Byte warten ?
>      if recB && 128 then           ;Startbit gesetzt ?
>           recSt=1
>           ADDR=(recB & 3) << 6     ;nur Adressbits und zur richtigen Pos
>           WERT=(recB & 4) << 5     ;nur Wertebit und zur richtigen Pos
>      endif
>   else
>      if recSt=1 then
>           recSt=2
>           ADDR=ADDR + recB           ;Rest der Adresse
>      endif
>      if recSt=2 then
>           recSt=3
>           WERT=WERT + recB           ;Rest des Wertes
>      endif
>   endif

so, ich habs jetzt mal den PIC gegeben, nur irgendwie haut das aber 
nicht ganz hin.
int16  ADDR         ;Adresse
int  WERT         ;Wert
int  recB         ;Byte das empfangen wurde
int  recSt        ;Status*/

         recSt = 0;
         while (recSt < 3)
         {
           recB=getc();
           if (recSt=0)
           {                                 //noch auf 1. Byte warten ?
              if (recB && 128)               //Startbit gesetzt ?
              {
                   ADDR=(recB & 3) << 6;     //nur Adressbits und zur richtigen Pos
                   WERT=(recB & 4) << 5;     //nur Wertebit und zur richtigen Pos
                   recSt=1;
              }
           }
           else
           {
              if (recSt=1)
              {
                   ADDR=ADDR + recB;           //Rest der Adresse   
                   recSt=2; 
              }
              if (recSt=2)
              {
                   WERT=WERT + recB;           //Rest des Wertes
                   recSt=3;
              }
           }
            lcd_gotoxy(1,1);
            printf(lcd_putc, "A: %ld ", ADDR);
            lcd_gotoxy(1,2);
            printf(lcd_putc, "W: %u ", WERT);
         }

    }

irgendwie ergibt
ADDR=ADDR + recB;           //Rest der Adresse
WERT=WERT + recB;           //Rest des Wertes
für mich keinen Sinn

Ich hab mir die Ausgabe in H-Term in Binärdarstellung angeschaut und das 
passt übrigens so wie wir es wollten!

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das 2.Byte was ankommt enthält die untersten 7-Bit der Adresse. Da wir 
im ersten Byte die oberen 2-Bit's der Adresse eingelesen haben und diese 
an die entsprechende Position in ADDR geschoben haben brauchen wir die 
unteren Bits nur noch addieren - mit
ADDR = ADDR | recB;
würde es auch gehen.

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Egal wie ich den Wert auf der PC-Seite ändere, ändert sich der ADDR- und 
WERT-Wert extrem irgendwie. Nach welchem System hab ich noch nicht 
rausgefunden xDDD
Stimmt der Code so wie ich ihn oben stehen hab?

mfg

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int16  ADDR         ;Adresse
int  WERT         ;Wert
int  recB         ;Byte das empfangen wurde
int  recSt        ;Status*/

         recSt = 0;
         while (recSt < 3)
         {
           recB=getc();
           if (recSt==0)
           {                                 //noch auf 1. Byte warten ?
              if (recB && 128)               //Startbit gesetzt ?
              {
;                   ADDR=(recB & 3) << 6;     //nur Adressbits und zur richtigen Pos
                   ADDR=(recB & 3) << 7;     //korrektur
                   WERT=(recB & 4) << 5;     //nur Wertebit und zur richtigen Pos
                   recSt=1;
              }
           }
           else
           {
              if (recSt==1)
              {
                   ADDR=ADDR + recB;           //Rest der Adresse   
                   recSt=2; 
              }
              if (recSt==2)
              {
                   WERT=WERT + recB;           //Rest des Wertes
                   recSt=3;
              }
           }
         }
//Ausgabe erst wenn alle 3 Bytes empfangen wurden, sonst ändern sich die Werte nochmal !
            lcd_gotoxy(1,1);
            printf(lcd_putc, "A: %ld ", ADDR);
            lcd_gotoxy(1,2);
            printf(lcd_putc, "W: %u ", WERT);
    }
* Korrektur beim Shift der ADDR
* Korrektur der if syntax muss wohl == heissen ;bin kein 
C-Programmierer!

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, jetzt ergibt das Ganze schon mehr Sinn.
Funktioniert aber immer noch nicht ganz

Wenn ich bei dem 50. Kanal z.b. 0 einstelle ist ADDR & WERT 0, wenn ich 
ihn auf 1 erhöhe sind ADDR & WERT 50. Auf 3 wieder 3 und auf 4 wieder 
50.
Es wechselt sich also immer ab.

?????

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zeig mal dein ganzes Programm

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> zeig mal dein ganzes Programm

Das ist im Großen und Ganzen mein ganzes Programm.
#include <16f876.h>
#device adc=8
#use delay (clock=20000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)

#define        DMXANZ 10 
#define use_portb_lcd
#include <LCD.C>

unsigned int value[DMXANZ];

int   ADDR;         //Adresse
int  WERT;         //Wert
int  recB;         //Byte das empfangen wurde
int  recSt;        //Status

void main()
{
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   lcd_init();
  lcd_gotoxy(1,1);
   printf(lcd_putc, "TEST");
   delay_ms(1000);
   printf(lcd_putc, "\f");
   
   while (1)
  {
//Empfang:
         recSt = 0;
         while (recSt < 3)

         {
           recB=getc();
           if (recSt==0)
           {                                 //noch auf 1. Byte warten ?
              if (recB && 128)               //Startbit gesetzt ?
              {
//                   ADDR=(recB & 3) << 6;     //nur Adressbits und zur richtigen Pos
                   ADDR=(recB & 3) << 7;     //korrektur
                   WERT=(recB & 4) << 6;     //nur Wertebit und zur richtigen Pos
                   recSt=1;
              }
           }
           else
           {
              if (recSt==1)
              {
                   ADDR = ADDR + recB;           //Rest der Adresse   
                   
                   recSt=2; 
              }
              if (recSt==2)
              {
                   WERT = WERT + recB;           //Rest des Wertes
                   recSt=3;
              }
           }
         }
//Ausgabe erst wenn alle 3 Bytes empfangen wurden, sonst ändern sich die Werte nochmal !
                     lcd_gotoxy(1,1);
            printf(lcd_putc, "\f ");
            lcd_gotoxy(1,1);
            printf(lcd_putc, "A: %u ", ADDR);
            lcd_gotoxy(1,2);
            printf(lcd_putc, "W: %u ", WERT);
    }
}

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
bits=9 ?? wird da das Stoppbit mitgezählt ?

oh was mir gerade noch auffällt ...
...
          else
           {
              if (recSt==1)
              {
                   ADDR = ADDR + recB;           //Rest der Adresse   
                   
                   recSt=2; 
              }
              if (recSt==2)
              {
                   WERT = WERT + recB;           //Rest des Wertes
                   recSt=3;
              }
           }
...
die 3. Abfrage wird ja sofort nach der 2. ausgeführt - so wird das 
nichts.
...
          else
           {
              if (recSt==1)
              {
                   ADDR = ADDR + recB;           //Rest der Adresse   
                   
                   recSt=2; 
              }
              else
              {
                   WERT = WERT + recB;           //Rest des Wertes
                   recSt=3;
              }
           }
...

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK,

Jetz gehts, jedoch geht ADDR nur bis max 255. Ab 255 fangts wieder bei 0 
an.
Ich weiß, ADDR ist unsigned int deklariert, darf also nur bis 255 gehen, 
aber
wenn ich ADDR als int16 deklariere fängt alles erst ab 256 (bei Kanal 1) 
zu zählen an. Ich kapiers nicht.
Wenigstens gehts jetz aber schon halbwegs! THX

Frage: Was ist wenn ich mehrere Werte aufn PC gleichzeitig ändere?
Das Prog am PIC hängt sich dabei glaub ich auf (Display zumindest bleibt 
"stecken", wenn ich danach nur wieder einen Kanal ändere)

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> OK,
>
> Jetz gehts, jedoch geht ADDR nur bis max 255. Ab 255 fangts wieder bei 0
> an.
> Ich weiß, ADDR ist unsigned int deklariert, darf also nur bis 255 gehen,
?? int ist doch 16Bit
> aber
> wenn ich ADDR als int16 deklariere fängt alles erst ab 256 (bei Kanal 1)
> zu zählen an. Ich kapiers nicht.
ADDR=(recB & 3) << 7;
ich denke mal, das hier zunächst mit Byte (recB) gearbeitet wird und die 
Zuweisung an Int (ADDR) erst nach dem shift erfolgt, damit geht 
natürlich das Bit8 verloren. Probier mal ...
ADDR = recB & 3;
ADDR = ADDR << 7;
> Wenigstens gehts jetz aber schon halbwegs! THX
>
> Frage: Was ist wenn ich mehrere Werte aufn PC gleichzeitig ändere?
> Das Prog am PIC hängt sich dabei glaub ich auf (Display zumindest bleibt
> "stecken", wenn ich danach nur wieder einen Kanal ändere)
könnte sein, das durch deine Displayausgabe eine so große Pause entsteht 
in der der AVR ja keine Daten empfangen kann (bzw. nur EIN Byte was in 
seinen Puffer passt), wodurch die vom PC kommenden Daten verloren gehen. 
Also entweder keine Displayausgabe oder langsamer/mit Pause zwischen den 
Paketen senden. Wenn dein AVR dann später noch was anderes machen soll 
wirst du um eine Interruptgesteuerte UART-Verarbeitung ich nicht 
herumkommen.

Sascha


Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> ?? int ist doch 16Bit
Der Wertebereich ist glaub ich abhängig vom C-System bzw Compiler, 
oder?! In der Hilfe von meinem Compiler steht, dass int8 gleichwertig 
wie int ist, also nur 8 Bit

>
> ADDR=(recB & 3) << 7;
> 
> ich denke mal, das hier zunächst mit Byte (recB) gearbeitet wird und die
> Zuweisung an Int (ADDR) erst nach dem shift erfolgt, damit geht
> natürlich das Bit8 verloren. Probier mal ...
>
> ADDR = recB & 3;
> ADDR = ADDR << 7;
> 
Ich werds Morgen mal ausprobieren

> könnte sein, das durch deine Displayausgabe eine so große Pause entsteht
> in der der AVR ja keine Daten empfangen kann (bzw. nur EIN Byte was in
> seinen Puffer passt), wodurch die vom PC kommenden Daten verloren gehen.
> Also entweder keine Displayausgabe oder langsamer/mit Pause zwischen den
> Paketen senden. Wenn dein AVR dann später noch was anderes machen soll
> wirst du um eine Interruptgesteuerte UART-Verarbeitung ich nicht
> herumkommen.
Kann sein.

Was mir aber auch noch Sorgen bereitet ist die Sendung der Pakete. Die 
Senderoutine läuft in einem Timer mit 1ms (kleiner gehts nicht), was 
eigentlich extrem langsam ist; Ich sende ja schließlich mit 115200 Baud. 
Wenn sich in DMXControl z.B. 50 Werte gleichzeitig ändern, und dies so 
schnell, dass in 1 sek. 10 durchläufe sind (also 10x von 0 auf 255 und 
wieder auf 0) dann bekomm ich mit meiner For-Schleife echt Probleme 
oder? Weil die muss ja alle Werte bezüglich einer Änderung durchfragen, 
und in 1. Durchlauf dürfen sich die Daten ja höchstens 1x ändern...
Ich hoffe du verstehst was ich meine :DD
Wie könnte ich das anders (schneller) lösen?

thx, Emanuel

Autor: Sascha Weber (sascha_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Emanuel J. schrieb:
> Sascha Weber schrieb:
>> ?? int ist doch 16Bit
> Der Wertebereich ist glaub ich abhängig vom C-System bzw Compiler,
> oder?! In der Hilfe von meinem Compiler steht, dass int8 gleichwertig
> wie int ist, also nur 8 Bit
sei's drum auf alle Fälle eine 16Bit Variable nehmen

> Was mir aber auch noch Sorgen bereitet ist die Sendung der Pakete. Die
> Senderoutine läuft in einem Timer mit 1ms (kleiner gehts nicht), was
> eigentlich extrem langsam ist; Ich sende ja schließlich mit 115200 Baud.
> Wenn sich in DMXControl z.B. 50 Werte gleichzeitig ändern, und dies so
> schnell, dass in 1 sek. 10 durchläufe sind (also 10x von 0 auf 255 und
> wieder auf 0) dann bekomm ich mit meiner For-Schleife echt Probleme
> oder? Weil die muss ja alle Werte bezüglich einer Änderung durchfragen,
naja die Schleife wird nicht das Problem sein, dann schon eher das 
Senden der Daten innerhalb der Schleife
115200Bd = 11520Bytes/s / 3 = 3840 Pakete/s = 0.26ms pro Paket
das heisst das sich bei einem Durchlauf (1ms) maximal 3 Werte ändern 
dürfen, sonst läuft die Schleife entsprechend länger und deine 
vorgesehene Zeit von 1ms haut nicht mehr hin.
Nur: wenn orig. DMX auf der RS485 mit 250kBaud arbeitet und immer alle 
512 Kanäle überträgt, kommst du an dieser Stelle doch eh nur auf knapp 
50 Transfers/s. Wenn du also deinen Timer auf 20ms einstellst kannst du 
immerhin fast 80 Werte bei jedem Durchlauf senden.

> und in 1. Durchlauf dürfen sich die Daten ja höchstens 1x ändern...
nein - wenn das Array asyncron zu deiner Ausgabeschleife befüllt wird 
können auch mehrere Änderungen erfolgen - nur die werden dann u.U. nicht 
übertragen.

> Ich hoffe du verstehst was ich meine :DD
> Wie könnte ich das anders (schneller) lösen?
siehe meine Rechnung - musst sehen wie schnell du es brauchst
evl. könnte man das Protokoll noch dahingehend erweitern das man mehrere 
Werte hintereinander überträgt ohne jedesmal die Adresse mit zu senden 
(im ersten Byte haben wir ja noch 4Bit frei die man dafür nehmen könnte.

Sascha

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> ich denke mal, das hier zunächst mit Byte (recB) gearbeitet wird und die
> Zuweisung an Int (ADDR) erst nach dem shift erfolgt, damit geht
> natürlich das Bit8 verloren. Probier mal ...
>
> ADDR = recB & 3;
> ADDR = ADDR << 7;
> 

Jap, jetz gehts!

Ich werd mal einfach ein bisschen herumprobieren bezüglich der 
Geschwindigkeit und Datenverarbeitung...

THX

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.