Forum: PC-Programmierung Serielle Kommunikation (USART) mit libSerial (c++) unvollständig


von gunknown (Gast)


Lesenswert?

Hallo,

ich habe folgendes problem. Wenn ich die zahlen 0-255 von meinem 
mikrokontroller über USART an den PC sende und dort über die libSerial 
empfange kommen diese nicht vollständig an.
Es fehlen immer die Zahlen 9-13 und die 32 (dezimal). Dieses Verhalten 
habe ich auf zwei unterschiedlichen Rechnern eindeutig reproduzieren 
können.

Wenn ich gtkTerm (ein serielles Terminal) zum empfangen der Daten 
verwende erscheinen alle Zahlen. Das problem muß also die libSerial 
sein.

Kann jemand dieses Problem bestätigen beziehungsweise dem widersprechen?

Ich benutze die libserial-dev 0.5.2-0ubuntu1

Der entsprechende code vom uc:
1
unsigned char grr=0;
2
                        for(int i=0; i<256; ++i)
3
                        {
4
                                USART_Transmit(grr++);
5
                        }

Und der client für den PC:
1
    SerialStream serialstream;
2
3
    serialstream.Open("/dev/ttyUSB0");
4
    //setze parameter (8N1)
5
    serialstream.SetBaudRate(SerialStreamBuf::BAUD_115200);
6
7
    serialstream.SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
8
    serialstream.SetNumOfStopBits(1);
9
    serialstream.SetParity(SerialStreamBuf::PARITY_NONE);
10
    serialstream.SetFlowControl(SerialStreamBuf::FLOW_CONTROL_NONE);
11
12
13
   unsigned char test;
14
   for(int i=0; i<256; ++i)
15
   {
16
       serialstream >> test;
17
       cout << test << endl;
18
   }

Probleme mit der Baudrate sind auzuschließen, da sonstige kommunikation 
eigentlich einwandfrei funktioniert.

von Klaus W. (mfgkw)


Lesenswert?

ändere doch mal dazu:
1
   cout << int(test) << endl;

Kommt dann was an?

von Klaus W. (mfgkw)


Lesenswert?

oder noch dummer gefragt:
glaubst du im Ernst, eine Ausgabe sehen zu können, wenn du ein
Leerzeichen (32) ausgibst, oder horizontal tabulator (9) u.s.w.?

von gunknown (Gast)


Lesenswert?

Sorry, der fehler ist durch unaufmerksamkeit beim erstellen meines 
postings entstanden. Natürlich gebe ich den wert von test als integer 
aus (printf("%d\n", test);).

Die ausgabe sieht dann übrigens so aus:

0
1
2
3
4
5
6
7
8
14
15
16
.
.
.

Tritt bei euch auch dieses problem auf?

von Klaus W. (mfgkw)


Lesenswert?

Das Problem, mit einem winzigen Quelltextfragment Fragen zu
stellen, und dann ist es noch das falsche, tritt bei mir
nicht auf, nein.

von gunknown (Gast)


Lesenswert?

Hier mal vollständige source codes, wobei das auf dem uc (ich verwende 
einen atmega8) evtl. unterschiedlich sein kann:

uc:
1
#include <avr/io.h>
2
3
//set desired baud rate
4
#define BAUDRATE 115200UL
5
6
//calculate UBRR value
7
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
8
9
void USART_Init()
10
{
11
12
   //Set Baud rate
13
 UBRRL=UBRRVAL; //low byte
14
 UBRRH=(UBRRVAL>>8); //high byte
15
16
 UCSRC=(1<<URSEL)|(3<<UCSZ0);
17
18
19
 //Enable The receiver and transmitter
20
 UCSRB=(1<<RXEN)|(1<<TXEN);
21
}
22
23
void USART_Transmit( unsigned char data )
24
{
25
  /* Wait for empty transmit buffer */
26
  while ( !( UCSRA & (1<<UDRE)) )
27
       ;
28
  /* Put data into buffer, sends the data */
29
  UDR = data;
30
}
31
32
int main(void)
33
{
34
    USART_Init();
35
    DDRC = 0b00111101;
36
    PORTC = 0b11000010;
37
38
    unsigned char grr=0;
39
    for(int i=0; i<256; ++i)
40
    {
41
        USART_Transmit(grr++);
42
    }
43
44
}

client auf dem PC:
1
#include <SerialStream.h>
2
#include <iostream>
3
4
using namespace LibSerial;
5
6
int main( int argc, char** argv )
7
{
8
    SerialStream serialstream;
9
10
    serialstream.Open("/dev/ttyUSB0");
11
    //setze parameter (8N1)
12
    serialstream.SetBaudRate(SerialStreamBuf::BAUD_115200);
13
14
    serialstream.SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
15
    serialstream.SetNumOfStopBits(1);
16
    serialstream.SetParity(SerialStreamBuf::PARITY_NONE);
17
    serialstream.SetFlowControl(SerialStreamBuf::FLOW_CONTROL_NONE);
18
19
unsigned char test;
20
   for(int i=0; i<256; ++i)
21
   {
22
       serialstream >> test;
23
       printf("%d\n", test);
24
   }
25
}

Und falls es sich tatsächlich um einen tiefgreifenden bug in der 
libserial handelt, kennt jemand gute alternativen?

von Klaus W. (mfgkw)


Lesenswert?

Das Problem ist m.E. nicht serialStream, sondern das Lesen daraus:
1
       serialstream >> test;

Standardmäßig wird der Operator >> auf einem istream jeglichen white 
space verwerfen.

Das kann für jeden Stream auch anders eingestellt werden.
Probier doch mal vor der Schleife:
1
  serialstream >> std::noskipws;

von gunknown (Gast)


Lesenswert?

Tatsächlich, serialstream >> std::noskipws; bringt die lösung. Nun 
werden alle zahlen korrekt empfangen.
Ist mir zwar nicht verständlich warum, aber danke in jedem fall, da wäre 
ich nie drauf gekommen.

von gunknown (Gast)


Lesenswert?

Ist natürlich doch klar. Man braucht sich in der ascii tabelle ja nur 
mal die zeichen für die entsprechenden zahlen ansehen. Das sind eben 
gerade white spaces.

von Klaus W. (mfgkw)


Lesenswert?

Daß ein istream-operator>> per Voreinstellung alle white space
verwirft, ist z.B. bei Stroustrup oder dem Buch über die
C++-Standardbibliothek von Nicolai Josuttis erwähnt.
Daß man nicht alles parat hat, was da so erwähnt wird, steht auf
einem anderen Blatt...

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.