Forum: Mikrocontroller und Digitale Elektronik C# (Visual Studio) string erstellen.


von Marion (Gast)


Lesenswert?

Hallo,

ich möchte mit einer GUI einen String an einen AVR senden.

Der AVR erwartet Werte wie "0,12,124,42\n".
1
         private void button1_Click(object sender, EventArgs e)
2
        {
3
            string str;
4
            str = "0";
5
          str += Convert.ToString(trackBar1.Value);
6
            str += ",";
7
            str += Convert.ToString(trackBar2.Value);
8
            str += ",";
9
            str += Convert.ToString(trackBar2.Value);
10
            str += "\n";
11
            serialPort.WriteLine(str);
12
        }

Leider liefert mir die Funktion das nicht. Was ist da genau falsch?

von Peter II (Gast)


Lesenswert?

Marion schrieb:
> Leider liefert mir die Funktion das nicht.

und was liefert sie?

Man kann es auch besser lesbar schreiben.
1
string str = string.Format("0,{0},{1},{2}\n", trackBar1.Value, trackBar2.Value, trackBar2.Value );
2
serialPort.WriteLine(str);

von Wolfgang (Gast)


Lesenswert?

Marion schrieb:
> Leider liefert mir die Funktion das nicht. Was ist da genau falsch?

Zähl mal deine Kommata im String.

von Marion (Gast)


Lesenswert?

1
serialPort.WriteLine(string.Format(",{0},{1},{2}\n", trackBar1.Value, trackBar2.Value, trackBar2.Value));

Liefert nicht die Anzahl erwünschter ','. Es wird lediglich 1 ',' 
gesendet

von Marion (Gast)


Lesenswert?

Sende ich über Putty "1,2,3,4\n" wird es auf dem AVR korrekt 
"entschlüsselt".

von Peter II (Gast)


Lesenswert?

Marion schrieb:
> Liefert nicht die Anzahl erwünschter ','. Es wird lediglich 1 ','
> gesendet

glaube ich nicht.

Bei mir geht es. Die Zwischenvariable hilft übrigens beim Debuggen, dann 
sieht man was wer sendet.

von bluppdidupp (Gast)


Lesenswert?

Beachten sollte man, das WriteLine() selbst noch ein NewLine-Zeichen 
anhängt.
Beim Senden von Zeichenketten statt Bytes kann es generell nicht 
schaden, SerialPort.Encoding und SerialPort.NewLine besser auf 
gewünschte Werte zu setzen.

von Roland .. (rowland)


Lesenswert?

Marion schrieb:
> Leider liefert mir die Funktion das nicht.

Also was sendet der Code denn jetzt, was steht in "str"?

von Marion (Gast)


Lesenswert?

1
      private void button2_Click(object sender, EventArgs e)
2
        {
3
            string str = string.Format("1,{0},{1},{2}", trackBar1.Value, trackBar2.Value, trackBar3.Value);
4
            serialPort.WriteLine(str);
5
            lbSent.Items.Add(str);
6
        }

Sendet laut dem Ausgabefenster "1,0,0,255". Die Werte passen soweit, 
jedoch bekomme ich vom AVR die Antwort

"LED   1 (hue,sat,val)  : 0, 0, 0"

1
    #ifdef DEBUG_UART
2
    static char uart_puffer[32];
3
    #endif
4
    
5
    #define NUM_FIELDS  5
6
    static uint8_t fieldIndex = 0;
7
    static uint16_t values[NUM_FIELDS];
8
    static uint8_t i = 0;
9
    
10
    // RXC0 Flag gesetzt
11
    if(uart_available())
12
    {
13
      // Zeichen aus UDR0 lesen
14
      char c = uart_getc();
15
16
      if(c >= '0' && c <= '9')
17
      {
18
        if(fieldIndex < NUM_FIELDS)
19
        {
20
          values[fieldIndex] = (values[fieldIndex] * 10) + (c - '0');
21
        }
22
      }
23
      else if(c == ',')
24
      {
25
        fieldIndex++;
26
      }
27
      else
28
      {
29
        // Einzelne Led setzen
30
      //  if((values[0] >= 0x0f) && (values[0] < (0x10 + NUM_LEDS)))
31
        if(values[0] < NUM_LEDS)
32
        {
33
          #ifdef DEBUG_UART
34
          sprintf(uart_puffer, "LED %3d (hue,sat,val)\t:%3d,%3d,%3d\r\n", values[0], values[1], values[2], values[3]);
35
          uart_puts(uart_puffer);
36
          #endif
37
          hsv[values[0]].h = values[1];
38
          hsv[values[0]].s = values[2];
39
          hsv[values[0]].v = values[3];        
40
          //hsv[values[0]-0x10].h = values[1];
41
          //hsv[values[0]-0x10].s = values[2];
42
          //hsv[values[0]-0x10].v = values[3];
43
        }
44
        // Alle Leds setzen
45
      //  else if(values[0] == (0x10+NUM_LEDS))
46
        else if(values[0] == NUM_LEDS)
47
        {
48
          #ifdef DEBUG_UART
49
          sprintf(uart_puffer, "LEDS    (hue,sat,val)\t:%3d,%3d,%3d\r\n", values[1], values[2], values[3]);
50
          uart_puts(uart_puffer);
51
          #endif
52
          for(uint16_t led = 0; led < NUM_LEDS; led++)
53
          {
54
            hsv[led].h = values[1];
55
            hsv[led].s = values[2];
56
            hsv[led].v = values[3];
57
          }
58
        }
59
        else
60
        {
61
        uart_puts("ELSE\n");
62
          //not yet
63
        }
64
        // Index zuruecksetzen
65
        fieldIndex = 0;
66
        // Array loeschen
67
        for(uint8_t i = 0; i < NUM_FIELDS; i++) values[i] = 0;
68
      }
69
    }

von Peter II (Gast)


Lesenswert?

Marion schrieb:
> Sendet laut dem Ausgabefenster "1,0,0,255". Die Werte passen soweit,
> jedoch bekomme ich vom AVR die Antwort

setzte mal noch wie schon von bluppdidupp geschrieben das Encoding auf 
ASCII.

von Marion (Gast)


Lesenswert?

Wie mache ich das, habe von C# nicht viel Ahnung und brauche nur ein 
kleines Programm. Hab ansonsten erst einmal nicht weiter vor mit C# zu 
arbeiten.

von Marion (Gast)


Lesenswert?

Okay,

das Encoding scheint schon auf ASCII zu stehen.

            serialPort.Encoding = Encoding.GetEncoding(28591);

Beim AVR kommt einfach kein 2. ',' an.

von Roland .. (rowland)


Lesenswert?

Probier mal statt der WriteLine-Methode das hier (WriteLine sendet wie 
schon von bluppdidupp angemerkt selbst LF/CR mit):
1
Byte[] Buffer = Encoding.ASCII.GetBytes(str);
2
serialPort.Write(Buffer, 0, Buffer.Length);

von Peter II (Gast)


Lesenswert?

Marion schrieb:
> Beim AVR kommt einfach kein 2. ',' an.

dann lass doch den AVR einfach mal zurückschicken, was er bekommt. Es 
müsste ja schon das erste Zeichen reichen was er nicht erkannt hat.
1
sprintf(uart_puffer, "LED %3d (hue,sat,val)\t:%3d,%3d,%3d (char=%x)\r\n", values[0], values[1], values[2], values[3], c);

von Stefan S. (sschultewolter)


Lesenswert?

Hmmm,

das Problem hab ich scheinbar an der falschen Stelle gesucht. Wieso es 
aber mit Putty geht, ist mir ein Rätsel.

Ich habe im Programm ein delay_ms(10). Davor wird ein WS2812 Strip 
beschrieben (80Leds). Nehme ich beide Teile raus, funktioniert es auch 
mit dem Visual C#.

Was kann ich da ggf. machen mit der UART Schnittstelle? Interruptbetrieb 
ist nicht möglich, da die Leds das blockieren.
1
void readUartInput(void)
2
{
3
  #define MAX    50
4
  static uint8_t strComplete = 0;
5
  static uint8_t strCount = 0;
6
  static char string[MAX+1] = "";
7
  
8
  if(uart_available())
9
  {
10
    char c = uart_getc();
11
    if(strComplete == 0)
12
    {
13
      if(c == '\n' || c == '\r' || strCount >= MAX)
14
      {
15
        string[strCount] = '\0';
16
        strCount = 0;
17
        strComplete = 1;
18
      }
19
      else
20
      {
21
        string[strCount] = c;
22
        strCount++;
23
      }
24
    }
25
  }
26
  if(strComplete == 1)
27
  {
28
    uart_puts(string);
29
    uart_puts("\r\n");
30
    strComplete = 0;
31
  }
32
}

von Peter II (Gast)


Lesenswert?

Stefan S. schrieb:
> Was kann ich da ggf. machen mit der UART Schnittstelle? Interruptbetrieb
> ist nicht möglich, da die Leds das blockieren.

dann zeig mal das komplette Programm. Niemand weiß was hinter 
uart_available und uart_getc steckt.

> Wieso es aber mit Putty geht, ist mir ein Rätsel.
vermutlich weil du viel langsamer tippst als C# sendet.

von Peter II (Gast)


Lesenswert?

Nachtrag.

die könntest einfach die Baudrate runter drehen, dann hat der µC mehr 
zeit für die Verarbeitung.

von Marion (Gast)


Lesenswert?

1
uint8_t uart_getc(void)
2
{
3
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
4
  ;
5
  return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
6
}
7
8
uint8_t uart_available(void)
9
{
10
  return ((UCSR0A & (1<<RXC0)));
11
}

Baudrate werde ich mal runterdrehen.

von Peter II (Gast)


Lesenswert?

und wo im Programm steht das delay?

von Roland .. (rowland)


Lesenswert?

Stefan S. schrieb:
> Interruptbetrieb ist nicht möglich, da die Leds das blockieren.

Verstehe ich nicht.

Den String im C# Code zeichenweise mit Pausen senden (und hoffen, dass 
der UART-Puffer nicht die Zeichen sammelt), dann hat der µC auch genug 
Zeit.

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.