Forum: PC-Programmierung C# Serialport.Write()


von Jan L. (jan_l)


Lesenswert?

Hey
also ich benutze die serialport.write Methode um befehle an mein Board 
zu senden (via bluetooth) und im zb. mitzuteilen, das er doch bitte 
Beschleunigungsdaten senden soll.
1
if (accelCheck.Checked)                         
2
                sPort.Write("a");
3
            else if (!(accelCheck.Checked))
4
                sPort.Write("A");
5
6
if (rot_mat_Check.Checked)                         
7
                sPort.Write("r");
8
            else if (!(accelCheck.Checked))
9
                sPort.Write("R");

das sieht dann in etwa so aus.
Wenn ich beide Aktiviert habe, kommt leider manchmal nur einer der 
beiden Werte an. Ich kann auch keine regelmäßigkeit feststellen...
D.h. manchmal passiert es schon beim ersten Durchlauf manchmal aber auch 
erst bei 4. Aber kommen tut der Fehler irgendwann.

Ausser, ja ausser ich setzte Breakpoints genau auf die sPort.Write()'s. 
Naja das sagt mir ja schonmal das es wohl irgendwas mit der Zeit zutun 
hat. Also habe ich nach jedem sPort.Write() ein sleep von 50ms gesetzt 
leider keine Verbesserung.

Kennt ihr das Problem vielleicht? oder wisst ihr was da los ist?

von Peter II (Gast)


Lesenswert?

das Problem würde ich mehr beim empfangen suchen, beim senden kann da 
nicht schief gehen. Hast du beachtet das c# mit unicode arbeitet? Ich 
bin mir nicht sicher was er wirklihc sendet wenn man mit Strings 
arbeiten (richtig codierung einschalten!).

von Jan L. (jan_l)


Lesenswert?

also er sendet alles und auch richtig, ich lasses mir momentan auf der 
"boardseite" noch ausgeben.

und wenn ich die breakpoints rein setzte gibt er mir ja auch ohne 
probleme die daten richtig aus...

Das heist senden un empfangen klappt nur hat er wahrscheinlich irgendwo 
ein problem mit der geschwindigkeit sonst würde es ja beim debuggen auch 
nicht funktionieren....

von Peter II (Gast)


Lesenswert?

Jan L. schrieb:
> Das heist senden un empfangen klappt nur hat er wahrscheinlich irgendwo
> ein problem mit der geschwindigkeit sonst würde es ja beim debuggen auch
> nicht funktionieren....

Beim senden kann es aber kein timing Problem gehen, nur beim empfangen. 
Wenn du dort nicht sauber mit puffern arbeitest.

von Jan L. (jan_l)


Lesenswert?

ja dann kanns sicher daran liegen das ich beim empfangen garnicht mit 
puffern arbeite...

werd mal schaun was ich da machen kann :P

von Jonas B. (jibi)


Lesenswert?

Und achte darauf einen eigenen Thread zum Empfangen der Daten zu starten 
- ansosnten stoppt der Empfang sporadisch wenn du deien Gui bedienst.

Gruß Jonas

von Jan L. (jan_l)


Lesenswert?

meinst du den empfang von den sonsor daten? das hab ich auch schon 
gemerkt das er da ab und an hackt.

allerdings schreib ich alle Werte in ne Queue und da ich (immoment) noch 
keinen Wert darauf lege die Werte live zu sehen stört mich das erstmal 
wenig.

Dazu kommt, dass während dem Empfang der Daten momentan auch alle gui 
elemente deaktiviert sind, so dass man warten muss bis alle daten da 
sind oder ich auf den Stopbutton klick.

von Jonas B. (jibi)


Lesenswert?

Du kannst zusätzlich noch die Puffergröße (größer machen) umd das 
"Connection Timeout" (länger machen) der seriellen Verbindung anpassen. 
Das brachte einiges bei mir.

Gruß Jonas

von Jan L. (jan_l)


Lesenswert?

ich arbeite mit ner api und muss jetzt grad erst mal schaun das ich nen 
empfangs puffer auf mein Board bekomm...

diese blöde api verursacht mehr probleme als sie löst -.-

von Peter II (Gast)


Lesenswert?

Ich kann jetzt irgendwie nicht folgen..

Du sendest von C# an ein Board. Dabei gehen zeichen verloren. Bei senden 
wartet aber C#, damit kann man beim senden eigentlich nichts falsche 
machen.

Also kann das Problem nur beim empfangen oder der eigentlichen 
Kommunikation liegen.

von Jan L. (jan_l)


Lesenswert?

also ich ruf den sende befehl auf und wenn ich ihn dann zb mit dem 
debugger die sende befehle langsam abarbeite bekommt und verarbeitet die 
andere seite auch alles.

wenn ich das programm aber einfach laufen lass kommen nicht alle befehle 
an.
hab da auch was in der api gefunden. nämlich die funktion die die daten 
empfängt ist folgendermaßen kommentiert
1
/*  Expect only one UART data at a time or the last one */

von Jan L. (jan_l)


Lesenswert?

würde es auch funktionieren, statt eines Buffers eine art 
acknowledgement einzubaun?

hab mir das so gedacht, dass ich einfach ein "send" auf der C# Seite 
mache und auf der C Seite, nach der Bearbeitung des Befehls, zb ein 
'!'(oder irgendein anderes Zeichen) zurück sende und dann, wiederum auf 
der C# Seite solange warte bis das Zeichen da ist und dann erst den 
nächsten send Befehl schicke.

edit: also es sieht soweit ganz gut aus und scheint zu funktionieren...
hab zwar noch paar komische exceptions ab und an aber an sich läufts 
wesendlich besser und zumindest werden immer alle befehle übertragen und 
ausgewertet

von Christoph (Gast)


Lesenswert?

Jan L. schrieb:
> hab mir das so gedacht, dass ich einfach ein "send" auf der C# Seite
> mache und auf der C Seite, nach der Bearbeitung des Befehls, zb ein
> '!'(oder irgendein anderes Zeichen) zurück sende und dann, wiederum auf
> der C# Seite solange warte bis das Zeichen da ist und dann erst den
> nächsten send Befehl schicke.

gehen schon, aber performanter wäre es schon mit einem Puffer...

von Jan L. (jan_l)


Lesenswert?

das problem ist das ich dazu in die api "rein" muss... glaub ich 
zumindest und ich da nicht alles verstehe...

ich glaub, dass das die stelle ist die meine Bytes empfängt
1
/**
2
 *  @brief  Interrupt handler.
3
 *  When an RX interrupt is detected, a callback function (if one is
4
 *  registered) is executed with the RX byte as a parameter.
5
 */
6
#pragma vector=UART_VEC
7
__interrupt void UART_ISR(void)
8
{
9
    switch(__even_in_range(IV,4)) {
10
        case 2:     /* RX interrupt. */
11
            /* Check if previous data processed*/
12
          if(rx_new==0){
13
            rx_new=1;
14
            rx_data = RXBUF;
15
          }
16
            break;
17
        case 4:     /* TX interrupt. */
18
            /* Place next byte on buffer. */
19
            if (uart.length) {
20
                TXBUF = uart.data[0];
21
                uart.data++;
22
                uart.length--;
23
            } else {
24
                IFG &= UCTXIFG;
25
                uart.is_busy_writing_data_right_now = 0;
26
27
            }
28
            break;
29
        case 0:     /* No interrupt. */
30
        default:
31
            break;
32
    }
33
}
34
35
36
/*  Expect only one UART data at a time or the last one */
37
void msp430_get_uart_rx_data(unsigned char *uart_data){
38
  *uart_data = rx_data;
39
}

... allerdings ist "verstehen" was anderes ...

von bluppdidupp (Gast)


Lesenswert?

Ich kenne jetzt das System nicht, aber müsste rx_new nicht irgendwo 
wieder auf 0 gesetzt werden, damit weitere Bytes nicht mehr 
weggeschmissen werden?
Hätte ich in der msp430_get_uart_rx_data() vermutet, die vermutlich vom 
eigenen Code aufgerufen wird?

von Jan L. (jan_l)


Lesenswert?

ja in meiner main klasse hab ich es gefunden
1
//TODO: eingabe
2
static void handle_input(void) {
3
  char c;
4
5
  rx_new = 0;
6
7
  if (check_uart_mode_enabled)
8
    msp430_get_uart_rx_data((BYTE*) &c);
9
10
  memset(&hal.rx.header, 0, sizeof(hal.rx.header));
11
12
13
  // opt = 1
14
  if(c >= 0x80)
15
  {
16
    char temp;
17
    temp = c << 1;
18
    c = temp >> 1;
19
20
    int value = (int)c;
21
    time = value * 1000;
22
    ack();
23
  }else
24
.
25
.
26
.

das ist die funktion mit der ich meine eingaben verwerte. Seh ich das 
richtig, dass der buffer dann hier in die else müsste?
1
#pragma vector=UART_VEC
2
__interrupt void UART_ISR(void)
3
{
4
    switch(__even_in_range(IV,4)) {
5
        case 2:     /* RX interrupt. */
6
            /* Check if previous data processed*/
7
          if(rx_new==0){
8
            rx_new=1;
9
            rx_data = RXBUF;
10
          }else buffer  // <---
11
            break;

von bluppdidupp (Gast)


Lesenswert?

rx_new = 0; gehört meiner Meinung nach in die letzte Zeile der Funktion 
msp430_get_uart_rx_data()

Es sieht mir bei dem Problem so aus, als würden die Daten schneller 
ankommen als du sie verarbeitet bekommst.
Wenn das nur gelegentlich so ist, könnte ein Puffer helfen, ansonsten 
wäre die Problemlösung vllt. einfach die Verringerung der 
Übertragungsrate?

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.