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
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
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 ;)
> 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
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.
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
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
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
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?
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.
:-)
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.
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
1
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
1
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?
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.
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^^
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;
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;
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.
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_funktioniert_String-Verarbeitung_in_C.3Fhttp://www.sprut.de/electronic/pic/c/pic_c/pic_c00.html
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
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
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 ">>"
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
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?
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
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:
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
! 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.
1
Dim nummer As Long
2
Dim byte1 As Byte
3
Dim byte2 As Byte
4
Dim byte3 As Byte
5
Dim DMXValues(512) As Byte
6
Dim DMXValuesOld(512) As Byte
7
8
For nummer = 0 To 511
9
DMXValues(nummer) = Rnd(1) * 255
10
DMXValuesOld(nummer) = 0
11
Next
12
' Überprüfen ob sich ein Wert geändert hat
13
For nummer = 0 To 511
14
If DMXValues(nummer) <> DMXValuesOld(nummer) Then
15
16
byte1 = 128 + (nummer And 384) / 128 + (DMXValues(nummer) And 128) / 32
Ok, jetz hab ich keinen Fehler mehr.
Senden tu ich mit Chr(..), also
1
MSComm1.Output=Chr(byte1)
2
MSComm1.Output=Chr(byte2)
3
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
Emanuel J. schrieb:> Ok, jetz hab ich keinen Fehler mehr.>> Senden tu ich mit Chr(..), also>>
1
MSComm1.Output=Chr(byte1)
2
>MSComm1.Output=Chr(byte2)
3
>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
Wenns einfach sein soll und der Overhead keine Rolle spielt mache es so:
Datenpaket für einen bestimmten Wert - 5 Bytes je Paket):
1
word $4458 = Magic-Word "DX"
2
word $xxxx = Index des Wertes, z.Bsp. Wert 100
3
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):
1
dim magic as word
2
dim index as word
3
dim value as byte
4
dim DMXValues(511) as word
5
6
do
7
magic=waitinput(2) ' 2 bytes
8
select case magic
9
case $4458 ' DX - Wert soll aktualisiert werden
10
index=waitinput(2) ' index-Nummer lesen (2 Bytes)
11
value=waitinput(1) ' Wert lesen (1 Byte)
12
DMXValues(index)=value
13
case $5858 ' XX - Liste soll aktualisiert werden
14
for i=0 to 511
15
DMXValue(i)=waitinput(1)
16
next
17
end select
18
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
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.
1
int16ADDR;Adresse
2
intWERT;Wert
3
intrecB;Bytedasempfangenwurde
4
intrecSt;Status*/
5
6
recSt=0;
7
while(recSt<3)
8
{
9
recB=getc();
10
if(recSt=0)
11
{//noch auf 1. Byte warten ?
12
if(recB&&128)//Startbit gesetzt ?
13
{
14
ADDR=(recB&3)<<6;//nur Adressbits und zur richtigen Pos
15
WERT=(recB&4)<<5;//nur Wertebit und zur richtigen Pos
16
recSt=1;
17
}
18
}
19
else
20
{
21
if(recSt=1)
22
{
23
ADDR=ADDR+recB;//Rest der Adresse
24
recSt=2;
25
}
26
if(recSt=2)
27
{
28
WERT=WERT+recB;//Rest des Wertes
29
recSt=3;
30
}
31
}
32
lcd_gotoxy(1,1);
33
printf(lcd_putc,"A: %ld ",ADDR);
34
lcd_gotoxy(1,2);
35
printf(lcd_putc,"W: %u ",WERT);
36
}
37
38
}
irgendwie ergibt
1
ADDR=ADDR+recB;//Rest der Adresse
2
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!
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
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
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.
?????
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)
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.
1
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 ...
1
ADDR=recB&3;
2
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
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
>
1
>ADDR=(recB&3)<<7;
2
>
> 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 ...>
1
>ADDR=recB&3;
2
>ADDR=ADDR<<7;
3
>
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
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
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 ...>
1
>ADDR=recB&3;
2
>ADDR=ADDR<<7;
3
>
Jap, jetz gehts!
Ich werd mal einfach ein bisschen herumprobieren bezüglich der
Geschwindigkeit und Datenverarbeitung...
THX