Hallo Leute,
baue gerade an einem RGB-LED-Display. Der Schaltplan und das Programm
sind eigentlich auch soweit fertig, es gibt da nur noch ein Problem. Auf
dem PC läuft ein sehr einfach gestricktes VB Programm (VB2010). Dort
gibt es drei Schieberegler für die Farben rot, grün und blau. Wenn einer
der Schieberegler nun betätigt wird, so wird der aktuelle Wert der
Farben (Wertebereich von 0 bis 255) via serieller Schnittstelle an den
Mikrocontroller gesendet. Dieser empfängt die Werte auch soweit, doch
leider (wahrscheinlich) im falschen Format. Hier ein Ausschnitt aus dem
C-Programm:
1
// Receive new color values
2
case2:
3
if(msgCNT==0)
4
{
5
redValue=rxData;
6
}
7
elseif(msgCNT==1)
8
{
9
greenValue=rxData;
10
}
11
elseif(msgCNT==2)
12
{
13
blueValue=rxData;
14
setNewColor();
15
rxCNT=0;
16
}
17
msgCNT++;
18
break;
Die vorherige Überprüfung, z.B. nach einem STX zu Nachrichtenbeginn,
funktioniert auch soweit. Nur die drei Farbwerte kommen falsch an. Die
Variable rxData ist übrigens als unsigned int definiert, die Variablen
redValue, blueValue und greenValue ebenfalls.
Hier noch ein Auszug aus dem VB Programm:
1
Private Sub HScrollBar2_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar2.Scroll
2
3
TextBox4.Text = HScrollBar2.Value
4
5
SerialPort1.Write("2")
6
SerialPort1.Write("1")
7
SerialPort1.Write(HScrollBar3.Value)
8
SerialPort1.Write(HScrollBar2.Value)
9
SerialPort1.Write(HScrollBar1.Value)
10
11
End Sub
12
13
Private Sub HScrollBar1_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar1.Scroll
14
15
TextBox3.Text = HScrollBar1.Value
16
17
SerialPort1.Write("2")
18
SerialPort1.Write("1")
19
SerialPort1.Write(HScrollBar3.Value)
20
SerialPort1.Write(HScrollBar2.Value)
21
SerialPort1.Write(HScrollBar1.Value)
22
23
End Sub
24
25
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
> SerialPort1.Write(HScrollBar3.Value)
Wird das nicht in einen String umgewandelt? Wäre nicht
SerialPort1.Write(Asc(HScrollBar3.Value)) sinnvoller?
Gruß
Jens K. schrieb:> Dieser empfängt die Werte auch soweit, doch> leider (wahrscheinlich) im falschen Format.
In deinem C-Fragment wird irgend ein msgCNT ausgewertet und
inkrementiert, aber es wird ein rxCNT nach dem dritten Empfang auf 0
gesetzt. Außerdem wird ein mysteriös, aus dem Nichts auftauchendes,
rxData auf die Farbkomponenten zugewiesen. Solange du es für dein
Geheimnis behälst, wo das herkommt und was das soll, wird dir keiner
helfen können.
Jens K. schrieb:> Leider tut sich jetzt beim Verschieben der Schiebeleisten garnichts mehr> :-(
Wenn das "mehr" bedeutet, dass es vorher ging, heißt es zurück zur
letzten lauffähigen Version und von da aus weitermachen.
Ansonsten ist jetzt systematische Vorgehensweise angesagt: Splitte die
beiden Probleme (Senden vom PC, Empfangen/Auswerten auf dem µC) indem du
dich erstmal mit einem Schnittstellenmonitor bzw. Terminalprogramm
dazwischen hängst und guckst, ob der PC auf der Schnittstelle ausgibt,
was er ausgeben soll. Dann kannst du mit einem Terminalprogamm (z.B.
HTerm) Daten an den µC senden und gucken ob er die versteht.
Wahrscheinlich bauen im Moment beide Mist.
Joachim schrieb:>> SerialPort1.Write(HScrollBar3.Value)> Wird das nicht in einen String umgewandelt? Wäre nicht> SerialPort1.Write(Asc(HScrollBar3.Value)) sinnvoller?
Oder war das nicht Chr(), die Umwandlung in ein Byte? Sry, ist alles zu
lange her.
Gruß
Danke für die vielen Vorschläge.
> Oder war das nicht Chr(), die Umwandlung in ein Byte? Sry, ist alles zu> lange her.
Ich hatte da mit Chr() schon ausprobiert, ging leider trotzdem nicht.
Dabei hatte ich allerdings Folgendes Phänomen:
Ich habe die Daten vom Schieberegler an den µC gesendet, wobei ich diese
zuvor mit Chr() konvertiert hatte. Das Ergebnis war leider wieder nur
eine Vollaussteuerung, egal in welcher Position die Schieberegeler
waren. Habe ich nun von dem am µC empfangenen Wert 48 subtrahiert (ich
weiß nicht mehr warum, aber das hatte ich in einem alten Programm auch
mal so machen müssen), dann lies sich die LED im Bereich von 0 bis 47
dimmen. Dabei war 47 aus und 0 etwas leuchten (dazwischen immer ein
bisschen mehr Helligkeit). Zwischen 48 und 255 war die LED dann wieder
voll ausgesteuert. Habe ich nun den zu subtrahierenden Wert einfach
etwas erhöht, um den Wertebereich zu erhöhen, so ging dies zunächst,
aber ab einer Gewissen Grenze lies die LED sich dann nicht mehr komplett
ausschalten (dimmen).
> Arbeitest du auch mit Option Strict On?
Nein, was ist das?
> Ansonsten ist jetzt systematische Vorgehensweise angesagt: Splitte die> beiden Probleme (Senden vom PC, Empfangen/Auswerten auf dem µC) indem du> dich erstmal mit einem Schnittstellenmonitor bzw. Terminalprogramm> dazwischen hängst und guckst, ob der PC auf der Schnittstelle ausgibt,> was er ausgeben soll. Dann kannst du mit einem Terminalprogamm (z.B.> HTerm) Daten an den µC senden und gucken ob er die versteht.
Das würde ich gerne machen, doch ich verwende einen virtuelle serielle
Schnittstelle und habe leider keine zweite zur Hand. Somit kann ich nur
ein Programm auf die Schnittstelle zugreifen lassen.
> In deinem C-Fragment wird irgend ein msgCNT ausgewertet und> inkrementiert, aber es wird ein rxCNT nach dem dritten Empfang auf 0> gesetzt. Außerdem wird ein mysteriös, aus dem Nichts auftauchendes,> rxData auf die Farbkomponenten zugewiesen. Solange du es für dein> Geheimnis behälst, wo das herkommt und was das soll, wird dir keiner> helfen können.
Okay, hier kommt nun der komplette Code der Interrupt-Routine. Bitte
fangt jetzt aber nicht wieder an über irgendwelche Formatierungen etc.
zu meckern. Der Code soll erstmal laufen und dann kommen die Feinheiten.
1
// UART-Receive interrupt
2
ISR(USART_RXC_vect)
3
{
4
unsignedintrxData;
5
6
rxData=UDR;
7
8
switch(rxCNT)
9
{
10
// Receive the start-sign "STX"
11
case0:
12
if(rxData=='2')
13
{
14
rxCNT=1;
15
}
16
break;
17
18
// Receive the function code
19
case1:
20
if(rxData=='1')
21
{
22
// The following payload contains the new color values
23
rxCNT=2;
24
msgCNT=0;
25
}
26
elseif(rxData==2)
27
{
28
// The following payload contains a new message that shall be displayed on the RGB-Display
29
rxCNT=3;
30
msgCNT=0;
31
}
32
elseif(rxData==3)
33
{
34
// Increase or decrease the shifting speed of the text through the RGB-Display
35
rxCNT=4;
36
}
37
break;
38
39
// Receive new color values
40
case2:
41
if(msgCNT==0)
42
{
43
redValue=rxData;
44
}
45
elseif(msgCNT==1)
46
{
47
greenValue=rxData;
48
}
49
elseif(msgCNT==2)
50
{
51
blueValue=rxData;
52
setNewColor();
53
rxCNT=0;
54
}
55
msgCNT++;
56
break;
57
58
// Receive a new display text
59
case3:
60
if(msgCNT==0)
61
{
62
// Receive the length of the following payload
63
msgLen=rxData;
64
if(msgLen==0)
65
{
66
rxCNT=0;
67
}
68
}
69
else
70
{
71
// Check if a lower-case letter is received -> Convert it to a uper-case letter
72
if((rxData-48)<123||(rxData-48)>96)
73
{
74
displayText[msgCNT-1]=rxData-80;
75
}
76
else
77
{
78
displayText[msgCNT-1]=rxData-48;
79
}
80
}
81
msgCNT++;
82
83
// Check if the end of the message is reached
84
if(msgCNT>msgLen)
85
{
86
rxCNT=0;
87
}
88
break;
89
90
// Increase ore decrease shifting speed
91
case4:
92
// Change the shifting speed of the LED-Display
93
if((rxData-48)==1)
94
{
95
if(shiftSpeed>20)
96
{
97
shiftSpeed-=20;
98
}
99
}
100
elseif((rxData-48)==0)
101
{
102
shiftSpeed+=20;
103
}
104
105
rxCNT=0;
106
107
break;
108
109
default:
110
break;
111
}
112
}
Übrigens ist mir auch aufgefallen das man msgCNT auch durch den rxCNT
ersetzen kann, und dann eine Variable spart ;-)
> if(rxData == '1')> else if(rxData == 2)
Vorsicht, Du vermischt hier Zahl und Zeichen.
Ich kann mich erinnern, dass man die serielle Schnittstelle (MsCom32.Ocx
o. ä.) explizit auf binary setzen muß.
Was passiert, wenn Du bspw.
SerialPort1.Write("21"+chr(0)+chr(255)+chr(0))
per Tastendruck abschickst.
Gruß
BTW:
In Dein Protokoll sollte noch ein TimeOut eingebaut werden. Wenn also
das erste Zeichen empfangen wurde und das Telegramm nicht nach einer
bestimmten Zeit abgeschlossen ist, sollte die Empfangsroutine
zurückgesetzt werden.
Gruß
> Was passiert, wenn Du bspw.> SerialPort1.Write("21"+chr(0)+chr(255)+chr(0))> per Tastendruck abschickst.
Leider das Gleiche: (wahrscheinlich) Vollaussteuerung aller Farben.
Wenn ich übrigens den Variablen greenValue, blueValue und redValue feste
Werte zuweise, z.B. die welche Du sagtest, dann funktioniert alles (Rot
an, Grün aus, Blau an). Es muss also irgendwie an der empfangenen
Nachricht liegen.
Wenn ich mir die Werte der Schieberegler zusende, aber statt diese zu
übernehmen einfach jedesmal den aktuellen Helligkeitswert um 5 erhöhe
(von 0 bis 255), dann lässt sich die LED ebenfalls wie gewünscht dimmen.
Jede Nachricht kommt an und erzeugt eine geringere Helligkeit. Ich
verstehe einfach nicht warum dann nicht der Wert des Schiebereglers
korrekt übertragen wird :-(
Ich habe einen AVR MKII. Ich nutze Atmel Studio 6, weiß aber leider
nicht wie das mit dem Debuggen funktioniert. Ich setze einen Breakpoint
bei dem Case wo er die empfangenen Daten in die Variablen grennValue,
redValue und blueValue schreibt. Dann klicke ich auf das kleine grüne
Play-Symbol (Start-Debugging) und er fängt an in der Konsole ein paar
Zeilen durchzuschieben, so wie beim kompelieren. Wenn dann ganz unten
link Fertig steht und ich von meinem VB-Programm aus etwas sende, dann
bleibt Atmel Studio leider nicht am Breakpoint stehen, sondern das
Programm läuft einfach weiter.
> Ich habe mal mein altes VB6 angeworfen. Anbei die Einstellung einer ser.> Schnittstelle.
Die Einstellungen der seriellen Schnittstelle passen. Habe schon viele
Programme geschrieben in denen alles funktioniert hat. Habe nur nie
vorher versucht die Werte eines Schiebereglers zu übertragen. Sonst
immer nur Texte aus Textboxen.
Hi
>Ich habe einen AVR MKII. Ich nutze Atmel Studio 6, weiß aber leider>nicht wie das mit dem Debuggen funktioniert.
Wenn es ein AVRISP MKII ist, gar nicht.
MfG Spess
Jens K. schrieb:> vorher versucht die Werte eines Schiebereglers zu übertragen. Sonst> immer nur Texte aus Textboxen.
Das ist doch letzten Endes völlig egal, wo die Werte herkommen, die über
die Schnittstelle kommen.
Dein Problem wird gerne als "Stochern im Nebel" umschrieben.
Es ist im höchsten Masse unklug, wenn man keine Möglichkeit hat, sich
selbst irgendwelche Werte auf AVR Seite irgendwo ausgeben zu lassen. So
kannst du nie kontrollieren, was der AVR eigentlich von dem versteht,
was du ihm sendest.
Leider setzen immer wieder viele Neulinge auf "Ich mach keine Fehler und
wenn doch, dann stochere ich eben so lange im Nebel, bis ich irgendwann
zufällig die richtige Programmmodifikation mache". Unnötig zu erwähnen,
dass so etwas praktisch noch nie funktioniert hat.
Schaff dir eine Möglichkeit, wie dir der AVR mitteilen kann, was ER von
der USART liest. Das ist die sicherste Methode, wie du dem Problem auf
den Grund gehen kannst. Es geht auch mit einzelnen LED an einem Port -
es ist nur unendlich mühsam. Ein LCD oder gar eine Ausgabe per UART ist
da viel einfacher.
Also ein Neuling bin ich ganz und garnicht mehr. Ich programmiere
bereits seit mehreren Jahren in C und habe auch im Rahmen meiner
Bachelorarbeit ein sehr komplexes C-Programm entwickelt.
Ich denke ich werde das Teil nachher mal mit zur Arbeit nehmen und mir
auf deren Oszis anschauen was aus der seriellen Schnittstelle rauskommt.
Das hat praktischerweise auch eine Dekodierfunktion, sodass ich gleich
schauen kann was gesendet wird.
Ich dachte nur es wäre vielleicht irgendein einfacher Fehler, wie z.B.
ein falscher Datentyp oder eine falsche Senderoutine auf der VB-Seite.
In VB habe ich nämlich noch nicht so viel gemacht.
Ich werde dann heute Abend mal bereichten was bei dem Test rauskam.
Jens K. schrieb:> Also ein Neuling bin ich ganz und garnicht mehr. Ich programmiere> bereits seit mehreren Jahren in C und habe auch im Rahmen meiner> Bachelorarbeit ein sehr komplexes C-Programm entwickelt.
Nun. Zumindest den Unterschied zwischen ASCII Code und binärer
Übertragung und warum ein Mischen zwischen den beiden nicht sehr schlau
ist, scheinst du nicht wirklich verstanden zu haben.
Karl Heinz schrieb:> Jens K. schrieb:>> Also ein Neuling bin ich ganz und garnicht mehr. Ich programmiere>> bereits seit mehreren Jahren in C und habe auch im Rahmen meiner>> Bachelorarbeit ein sehr komplexes C-Programm entwickelt.>> Nun. Zumindest den Unterschied zwischen ASCII Code und binärer> Übertragung scheinst du nicht wirklich verstanden zu haben.
DAS und eigentlich der gesamte Thread, dürfte doch den obigen Absatz
komplett als Lüge entlarven, oder nicht?
> Ich hatte da mit Chr() schon ausprobiert, ging leider trotzdem nicht.
Siehst du. Genau das meine ich.
Du 'probierst' und hoffst das es dann geht.
So kommst du nicht weiter.
Jens K. schrieb:> Die Einstellungen der seriellen Schnittstelle passen. Habe schon viele> Programme geschrieben in denen alles funktioniert hat. Habe nur nie> vorher versucht die Werte eines Schiebereglers zu übertragen. Sonst> immer nur Texte aus Textboxen.
FYI:
http://msdn.microsoft.com/de-de/library/ms143551.aspx
Dein VB scheint den String in einen in UTF8-Format umzuwandlen.
Müsstest also ein Byte-Array bauen und dieses übertragen.
Gruß
Tip: Es gibt für den PC auch 'serielle Port Monitore'.
Damit kannst du dir zumindest mal auf Byte-Ebene ansehen, was vom PC aus
tatsächlich weggeschickt wird.
Ob das dann auf dem AVR wegen Baudrate, Taktferquenzproblemen auch
wirklich so ankommt, steht auf einem anderen Blatt. Aber das prüft man
sowieso am besten, indem man auf dem AVR mal in einem Testprogramm mit
genau denselben Einstellungen einfach mal was wegschickt und auf dem PC
in einerm Terminalprogramm nachsieht, ob das auch auf dem PC so ankommt.
Das ist ein Test, den ich immer als allererstes machen würde und sei es
nur um sicher zu gehen, dass Taktfrequenz und Baudrate in Ordnung sind.
Ich verstehe einfach nicht warum es immer Leute hier im Forum gibt
(cyblord), die nur kritisieren und keinen sinnvollen Beitrag zum Thema
bringen. Ich war echt froh viele nützliche Tipps bekommen zu haben, bis
wieder irgendwer meint, dass das alles eh kinderkram ist und man einfach
nur meckern muss. Insbesondere für die wirklichen Anfänger ist das sehr
nervig. Als ich angefangen bin mit der C-Programmiererei, da habe ich in
Foren nach hilfreichen Threads gesucht. Leider musste ich meistens
feststellen, dass die ersten Beiträge noch sehr hilfreich waren, doch
dann der gesamte Thread wieder von irgendwelchen Leuten lächerlich
gemacht wurde.
Jens K. schrieb:> Ich verstehe einfach nicht warum es immer Leute hier im Forum gibt> (cyblord), die nur kritisieren und keinen sinnvollen Beitrag zum Thema> bringen.
Weil es in deinem Problemfall keinen sinnvollen Beitrag gibt. Das
Problem kann beginnend mit den Fuseeinstellungen bis hin zum (bei dir
nicht existenten) Protokoll überall stecken.
Und abgesehen von den Fuses kann das Problem sowohl auf PC Seite, als
auch auf AVR Seite stecken oder auf beiden gleichermassen. Da sind
einfach zu viele Unbekannte, als das man mit dem Finger auf eine zeigen
könnte und sagen könnte: Hier steckt der Fehler.
Und das beginnt schon damit, dass du gar nicht weißt, was auf VB Seite
eigentlich exakt auf die Leitung geht.
benutzt werden, und das muss nun mal die STring-Version sein, denn die
restlichen beiden passen von der Anzahl der Argumente her nicht.
D.h. dein AVR kriegt keine 3 Bytes, sondern er kriegt durch die Writes
einen langen Text
1
"20123478"
aus dem er irgendwie die 3 Zahlen rausholen muss. Was natürlich nicht
geht, weil es das 'Protokoll' nicht zulässt, alles zweifelsfrei zu
identifizieren.
Man würde so etwas sehen können, wenn man einfach mal die Serielle
Schnittstelle mit einem Sniffer beobachtet bzw. den AVR einfach mal
ausgeben lassen würde, was er eigentlich empfängt (noch ehe es darum
geht, das dann auch zu interpretieren)
Aber: das ist alles erst mal nur Spekulation. Und genau davon musst du
weg. Weg von 'ich glaube', weg von 'ich vermute'. Hin zu 'Ich WEISS'.
Karl Heinz schrieb:> D.h. dein AVR kriegt keine 3 Bytes, sondern er kriegt durch die 3 Writes> einen langen Text>
1
>"20123478"
2
>
> aus dem er irgendwie die 3 Zahlen rausholenb muss. Was natürlich nicht> geht, weil es das 'Protokoll' nicht zulässt, alles zweifelsfrei zu> identifizieren.
Das war durch das Chr(wert) eigentlich schon ausgeschlossen. Es liegt
wohl eher an einer impliziten Umwandlung des String, besonders für nicht
druckbare Zeichen und >128.
Gruß
Joachim schrieb:> Das war durch das Chr(wert) eigentlich schon ausgeschlossen. Es liegt> wohl eher an einer impliziten Umwandlung des String, besonders für nicht> druckbare Zeichen und >128.
Ich kann mich nur wiederholen:
Er soll einfach mal einen seriellen Port Sniffer auf die Sache ansetzen
um zu WISSEN, was vom PC eigentlich raus geht.
Noch besser wäre eine Möglichkeit auf dem AVR eine Ausgabe in Textform
machen zu können. Aber da wird es eben wieder mal keine derartige
Möglichkeit geben.
Joachim schrieb:> Wird das nicht in einen String umgewandelt? Wäre nicht> SerialPort1.Write(Asc(HScrollBar3.Value)) sinnvoller?
Das ist nicht Korrekt!
so besser
Option Strict On
SerialPort1.Write(CStr(HScrollBar3.Value))
Mit Strict on findest du die Wandlungsfehler alle
Wie gesagt, ich werde nun erstmal zur Arbeit fahren und mir die Ausgabe
des PCs auf nem Oszi anschauen. Ich melde mich heute Abend dann wieder,
dan können wir weiterschauen.
Jens K. schrieb:> Wie gesagt, ich werde nun erstmal zur Arbeit fahren und mir die Ausgabe> des PCs auf nem Oszi anschauen.
Das ist doch völlig überflüssig. Nen Oszi ist dafür doch auch das
falsche Gerät. Wenn dann ein LA. Aber dein PC kann selbst schauen was da
über die Schnittstelle kommt. Dazu gibts ja die Sniffer. Im Zweifel
macht man einen Loop über 2 ComPorts wenn man dem Sniffer nicht traut.
Also deine Methoden an Probleme ranzugehen sind doch sehr eigenartig und
verworren.
gruß cyblord
Das Oszi welcbes ich nutzen möchte besitzt eine Dekodierfunktion für
RS232. Warum sollte ich das nicht nutzen? Auf diese Weise geht man auch
in der industriellen Entwicklung vor. Das Oszi steht doch eh da, warum
dann nicht nutzen?
Jens K. schrieb:> Das Oszi welcbes ich nutzen möchte besitzt eine Dekodierfunktion für> RS232.
Sicher geht das. Aber wo ist der Vorteil? Du willst nunmal keine Signale
beobachten oder zwiefelst an der Funktionalität deiner Schnittstelle.
Sondern du willst wissen welche Bytes gesendet werden.
> Warum sollte ich das nicht nutzen?
Weil es einfacher geht.
> Auf diese Weise geht man auch> in der industriellen Entwicklung vor.
Sicher nicht.
> Das Oszi steht doch eh da, warum> dann nicht nutzen?
Weil es unnötig ist, einfacher geht und du sogar erst noch irgendwohin
fahren musst.
Jens K. schrieb:> Das Oszi welcbes ich nutzen möchte besitzt eine Dekodierfunktion für> RS232. Warum sollte ich das nicht nutzen?
Weil ein serialler Port Sniffer einfacher und schneller geht.
Jetzt bei Google eingeben
Downloaden
und in 10 Minuten weißt du, was über die Schnittstelle rausgeht.
cyblord ---- schrieb:>> Das Oszi steht doch eh da, warum>> dann nicht nutzen?> Weil es unnötig ist, einfacher geht und du sogar erst noch irgendwohin> fahren musst.
... und auch erst noch verkabelt werden muss.
Alao der Test hat ergeben:
Der PC sendet z.B. den Wert 255 als 2, 5 und 5. Er scheint das also als
String zu interpretieren. Wie kann ich ihm nun sagen das er den Wert
als Byte und nicht als String senden soll? Eine Funjtion ReadByte gibt
es zwar, aber kein WriteByte :-(
Jens K. schrieb:> Alao der Test hat ergeben:> Der PC sendet z.B. den Wert 255 als 2, 5 und 5. Er scheint das also als> String zu interpretieren. Wie kann ich ihm nun sagen das er den Wert> als Byte und nicht als String senden soll?
Ich würde ganz ehrlich an deiner Stelle mit den Strings gehen.
Wenn ich mir so ansehe was du programmiert hast, dann unterschätzt du
das Protokoll-Problem mit Binärdaten ganz gewaltig.
Will der PC die rote LED auf 127 setzen, dann schickt er den String
"#R127;"
und fertig.
Jedes Kommando beginnt mit einem '#'. Danach kommt ein Buchstabe, der
die Farbe angibt gefolgt vom Zahlenwert für diese Farbe. Der Zahlenwert
wird mit einem ';' abgeschlossen, welcher dann auch gleichzeitig das
Kommando terminiert.
Ob du jetzt als spezielle Zeichen # und ; benutzt oder irgendwelche
andere, spielt keine so große Rolle. Aber zumindest bist du erst mal das
Problem los, dass du den Anfang eines Kommandos nicht eindeutig erkennen
kannst, weil in einer Binärübertragung ein Byte erst mal jeden
beliebigen Wert annehmen kann. Und du hast sogar noch den Vorteil einer
recht einfach gestrickten Fehlerkennung, die zwar nicht 100% perfekt
ist, aber doch die Mehrheit aller Probleme ausräumen kann. Denn nach
einem # kann nur einer von 3 möglichen Buchstaben kommen, gefolgt von
lauter Ziffern und einem abschliessendem ';'. Jede Abweichung davon kann
also nur aufgrund eines Fehlers sein, wodurch das ganze Kommando
ungültig wird und nicht ausgeführt wird. Der Härtetest ist immer: der PC
schickt und schickt - Kabel rausgerissen, Kabel wieder eingesteckt und
alles muss weiterlaufen wie bisher. D.h. der AVR muss eindeutig den
Anfang des nächsten Kommandos erkennen können, was in deinem 'Protokoll'
nicht gewährleistet ist, wenn alle Bytewerte als mögliche
Helligkeitswerte in Frage kommen.
Und so schwer ist das jetzt auch wieder nicht zu parsen. Die Elemente
sind ja alle da, alles was du noch brauchst ist die Erkentnis, dass man
an eine Zahl mit dem nächsten (Ziffern-Zeichen) eine STelle drann hängt,
in dem man rechnet
1
Neue Zahl = 10 * Alte Zahl + Ziffer
aus der Auswertung der Character '1' und '2' hat man bereits die Zahl 12
zusammengesetzt. Das nächste eintreffende Zeichen ist eine '7', welches
als Ziffernzeichen da einfach "dran gehängt wird", indem man in der
internen darstellung rechnet
1
2
Zahl = 10 * 12 + 7
wodurch aus den temporären 12 die 127 entstehen.
ASCII, also Textübertragung ist zwar langsamer als rein binäre
Übertragung, was aber in deinem Fall keine Rolle spielen wird. Schneller
als dein Benutzer mit der Maus am Schieberegler rumspielen kann, ist das
allemal. Und es hat den Vorteil, dass du erst mal kein VB-Programm
brauchst, um den AVR Part in der ganzen Geschichte auszutesten, sondern
dass du die Texte per Hand in einem Terminalprogramm eingeben kannst,
woraufhin der AVR reagieren muss. Und das ist nicht schlecht, denn es
vermeidet den 2-Fronten Krieg, wonach du erst mal nicht weißt, ob im
Falle eines nicht funktionierens der Fehler im AVR-Part oder im VB
Programm zu suchen ist.
Wenn dir 3 Texte für die 3 Farbanteile zu langsam sind, dann steht es
dir immer noch frei, ein spezielles Kommando
"#F127,64,0;"
einzuführen, in dem alle 3 Farbwerte für R, G und B auf einmal angegeben
werden können.
Jens K. schrieb:> Ich dachte nur es wäre vielleicht irgendein einfacher Fehler, wie z.B.> ein falscher Datentyp oder eine falsche Senderoutine auf der VB-Seite.
Genau das ist auch der Fall. Du sendest Zeichenketten mit Dezimalzahlen,
erwartest aber an Stelle der Dezimalzeichenketten einzelne Binary-Bytes.
Tipp:
SerialPort.Write() ist überladen. Eine dieser überladenen Varianten
akzeptiert ein Bytearray.
Dein Job ist also, aus deinen Headerzeichen und den Werten der
Schieberegler ein solches Bytearray zu bauen.
> SerialPort1.Write("2")> SerialPort1.Write("1")> SerialPort1.Write(HScrollBar3.Value)> SerialPort1.Write(HScrollBar2.Value)> SerialPort1.Write(HScrollBar1.Value)
Das würde dann richtig z.B. so aussehen:
public sub SendRGBValues()
dim buf as byte()=new byte() _
{ _
CByte(AscW("2"c)), _
CByte(AscW("1"c)), _
CByte(HScrollBar3.Value), _
CByte(HScrollBar2.Value), _
CByte(HScrollBar1.Value) _
}
SerialPort1.Write(buf,0,buf.Length)
end sub
Übrigens: Wenn du PC-seitig nicht klarkommst, dann hättest du einfach
den Code auf der µC-Seite entsprechend anpassen müssen. C kannst du ja
angeblich. Ich allerdings würde das ganz ernsthaft bezweifeln...
Hat das C-Programm überhaupt einen Sinn?
Jens K. schrieb:> // Receive new color values> case 2:> if(msgCNT == 0)> {> redValue = rxData;> }> else if(msgCNT == 1)> {> greenValue = rxData;> }> else if(msgCNT == 2)> {> blueValue = rxData;> setNewColor();> rxCNT = 0;> }> msgCNT++;> break;
Wenn der Mikrocontroller den Wert 128 Empfängst dann ist in redValue der
Wert 1, in greenValue der Wert 2 und in blueValue der Wert 8.
Jens K. schrieb:> Das würde ich gerne machen, doch ich verwende einen virtuelle serielle> Schnittstelle und habe leider keine zweite zur Hand. Somit kann ich nur> ein Programm auf die Schnittstelle zugreifen lassen.
Was hat das damit zu tun?
Füttere Google mal mit "Serial Port Monitor". Das ist reine Software,
die unabhängig von deiner Hardware ist.