Serielle Kommunikation (USART) mit libSerial (c++) unvollständig

Gast #1373274
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.
Gast #1373439
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?
Gast #1378028
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?
#1378422
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;
Gast #1381477
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren