Forum: Mikrocontroller und Digitale Elektronik LED von VB-Programm aus dimmen


von Jens K. (mister232)


Lesenswert?

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
case 2:
3
    if(msgCNT == 0)
4
    {
5
      redValue = rxData;
6
    }
7
    else if(msgCNT == 1)
8
    {
9
      greenValue = rxData;
10
    }
11
    else if(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
26
27
        SerialPort1.Write("2")
28
        SerialPort1.Write("1")
29
        SerialPort1.Write(HScrollBar3.Value)
30
        SerialPort1.Write(HScrollBar2.Value)
31
        SerialPort1.Write(HScrollBar1.Value)
32
33
End Sub

von Jens K. (mister232)


Lesenswert?

Hier noch die Initialisierung der PWM-Timer:
1
// Function to initialize the PWMs for color selection
2
void init_pwm(void)
3
{
4
  // Timer0
5
  
6
  // Set PWM-Pin as output (OC0)
7
  DDRB |= (1<<PB3);
8
  // Set timer0 to fast PWM mode, prescaler = 256, non-inverting mode
9
  TCCR0 = (1<<WGM00) | (1<<WGM01) | (1<<COM01) | (1<<CS02);
10
  
11
  TCNT0 = 0x00;
12
  
13
  // Timer1
14
  
15
  // Set PWM-Pin as output (OC1A)
16
  DDRD |= (1<<PD5);
17
  // Set timer1 to fast PWM mode, prescaler = 256, non-inverting mode
18
  TCCR1A = (1<<WGM12) | (1<<WGM10) | (1<<COM1A1);
19
  TCCR1B = (1<<CS12);
20
  
21
  TCNT1 = 0x00;
22
  
23
  // Timer2
24
  
25
  // Set PWM-Pin as output (OC2)
26
  DDRD |= (1<<PD7);
27
  // Set timer2 to fast PWM mode, prescaler = 256, non-inverting mode
28
  TCCR2 = (1<<WGM20) | (1<<WGM21) | (1<<COM21) | (1<<CS22) | (1<<CS21);
29
  
30
  setNewColor();
31
}
32
33
// Function to set a new color value to the RGB-Display
34
void setNewColor(void)
35
{
36
  OCR0 = redValue;
37
  OCR1A = greenValue;
38
  OCR2 = blueValue;
39
}

von Joachim (Gast)


Lesenswert?

> SerialPort1.Write(HScrollBar3.Value)


Wird das nicht in einen String umgewandelt? Wäre nicht 
SerialPort1.Write(Asc(HScrollBar3.Value)) sinnvoller?

Gruß

von Jens K. (mister232)


Lesenswert?

Leider tut sich jetzt beim Verschieben der Schiebeleisten garnichts mehr 
:-(
Die Farben bleiben alle voll ausgesteuert

von Mike (Gast)


Lesenswert?

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.

von Mike (Gast)


Lesenswert?

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.

von nee (Gast)


Lesenswert?

@jens

Arbeitest du auch mit Option Strict On?

von Joachim (Gast)


Lesenswert?

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ß

von Jens K. (mister232)


Lesenswert?

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
  unsigned int rxData;
5
  
6
  rxData = UDR;
7
  
8
  switch(rxCNT)
9
  {
10
    // Receive the start-sign "STX"
11
    case 0:
12
      if(rxData == '2')
13
      {
14
        rxCNT = 1;
15
      }
16
      break;
17
      
18
    // Receive the function code
19
    case 1:
20
      if(rxData == '1')
21
      {
22
        // The following payload contains the new color values
23
        rxCNT = 2;
24
        msgCNT = 0;
25
      }
26
      else if(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
      else if(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
    case 2:
41
      if(msgCNT == 0)
42
      {
43
        redValue = rxData;
44
      }
45
      else if(msgCNT == 1)
46
      {
47
        greenValue = rxData;
48
      }
49
      else if(msgCNT == 2)
50
      {
51
        blueValue = rxData;
52
        setNewColor();
53
        rxCNT = 0;
54
      }
55
      msgCNT++;
56
      break;
57
    
58
    // Receive a new display text
59
    case 3:
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
    case 4:
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
      else if((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 ;-)

von Joachim (Gast)


Lesenswert?

> 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ß

von Joachim (Gast)


Lesenswert?

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ß

von Jens K. (mister232)


Lesenswert?

> 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.

von Jens K. (mister232)


Lesenswert?

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 :-(

von Joachim (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe mal mein altes VB6 angeworfen. Anbei die Einstellung einer ser. 
Schnittstelle.

Gruß

von Klaus R. (klara)


Lesenswert?

Hallo Jens,
hast Du für Deinen Mikrocontroller keinen Debugger? Damit könntest Du 
genau sehen was ankommt.
mfg. Klaus.

von Jens K. (mister232)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe einen AVR MKII. Ich nutze Atmel Studio 6, weiß aber leider
>nicht wie das mit dem Debuggen funktioniert.

Wenn es ein AVR ISP MKII ist, gar nicht.

MfG Spess

von Jens K. (mister232)


Lesenswert?

Okay, schade

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens K. (mister232)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von Joachim (Gast)


Lesenswert?

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ß

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Jens K. (mister232)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Und das beginnt schon damit, dass du gar nicht weißt, was auf VB Seite
> eigentlich exakt auf die Leitung geht.

Von SerialPort.Write gibt es der MSDN zufolge genau 3 Überladungen

http://msdn.microsoft.com/de-de/library/system.io.ports.serialport.write(v=vs.110).aspx

Nur eine davon, kann IMHO für
1
        SerialPort1.Write(HScrollBar3.Value)
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'.

: Bearbeitet durch User
von Joachim (Gast)


Lesenswert?

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ß

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von nee (Gast)


Lesenswert?

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

von Jens K. (mister232)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

Noch was:

>  TCCR1A = (1<<WGM12) | (1<<WGM10) | (1<<COM1A1);
   ^^^^^^       ^^^^^^

Sicher, das sich WGM12 bei deinem AVR in TCCR1A befindet?

MfG Spess

von Cyblord -. (cyblord)


Lesenswert?

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

von Jens K. (mister232)


Lesenswert?

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?

von Cyblord -. (cyblord)


Lesenswert?

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.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jens K. (mister232)


Lesenswert?

Naj, zur Arbeit muss ich eh ;-)

von Jens K. (mister232)


Lesenswert?

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 :-(

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Joachim (Gast)


Lesenswert?

Joachim schrieb:
> Jens K. schrieb:


> Wie kann ich ihm nun sagen das er den Wert
> als Byte und nicht als String senden soll?


> 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ß

von c-hater (Gast)


Lesenswert?

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...

von Hilfe (Gast)


Lesenswert?

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.

von Mike (Gast)


Lesenswert?

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.

von Jens K. (mister232)


Lesenswert?

Es läuft!
1
Private Sub HScrollBar3_Scroll(sender As Object, e As ScrollEventArgs) Handles HScrollBar3.Scroll
2
3
        TextBox2.Text = HScrollBar3.Value
4
5
        SerialPort1.Write("2")
6
        SerialPort1.Write("1")
7
        SerialPort1.Write(New Byte() {HScrollBar3.Value}, 0, 1)
8
        SerialPort1.Write(New Byte() {HScrollBar2.Value}, 0, 1)
9
        SerialPort1.Write(New Byte() {HScrollBar1.Value}, 0, 1)
10
11
End Sub

Danke für die Hilfe

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.