[C++] serieele communicatie probleem

Pagina: 1
Acties:

  • ATS
  • Registratie: September 2001
  • Laatst online: 12-02 13:46
Hallo,

Ik ben met behulp van Qt een programma aan het maken dat met GPS moet gaan werken. Deze is via de seriele poort aangesloten. Ik heb daarom een class gemaakt die van de seriele poort leest en hele sentences doorstuurt naar een andere class. Dat werkt. Het vreemde is alleen dat op het begin de communicatie prima verloopt (de data komt snel binnen), maar die snelheid zakt al gauw in. Hieronder een stukje uit de debug-output:

zo ziet het er in het begin uit:
total bytes received: 17
received sentence '$PGRMM,WGS 84*06'
total bytes received: 18
total bytes received: 36
received sentence '$GPBOD,,T,,M,,*47'
total bytes received: 37
total bytes received: 55
received sentence '$GPRTE,1,1,c,0*07'
total bytes received: 56
total bytes received: 90
received sentence '$GPRMC,081020,V,,,,,,,160802,,*37'
GPRMC sentence...
total bytes received: 91
total bytes received: 116
received sentence '$GPRMB,V,,,,,,,,,,,,V*66'
De total bytes receiced messages zijn van mijn serieele connectie class, de overige messages zijn van de class die de sentences ontvangt en parsed. Dit ziet er prima uit. Even later ziet het er echter zo uit:
received sentence '$PGRMZ,,,*7E'
PGRMZ sentence...
total bytes received: 4047
total bytes received: 4048
total bytes received: 4049
total bytes received: 4050
total bytes received: 4051
total bytes received: 4052
total bytes received: 4053
total bytes received: 4054
total bytes received: 4055
total bytes received: 4056
total bytes received: 4057
total bytes received: 4058
total bytes received: 4059
total bytes received: 4060
total bytes received: 4061
total bytes received: 4062
total bytes received: 4063
total bytes received: 4064
received sentence '$PGRMM,WGS 84*06'
total bytes received: 4065
Ofwel: de bytes druppelen binnen?!

Ik heb hieronder de source van deze class gezet. Heeft iemand een idee hoe dit komt? Loopt er een of andere buffer vol ofzo? Alvast bedankt!

André


Source:

gpscon.h:
====================================================
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef GPSCON_H
#define GPSCON_H

#include <qobject.h>
#include <qtimer.h>
#include <qstring.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B9600
#define SERIALPORT "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1


/**GPSCon provides the serial communication with the GPS.
  *@author Andre Somers
  */

class GPSCon : public QObject  {
  Q_OBJECT

  public: 
    GPSCon();
    ~GPSCon();


  private: // Private attributes
    /**  */
    QTimer *timer;
    int fd;
    struct termios oldtio,newtio;
    struct sigaction saio;
    int bcnt;

  char* databuffer;
  int dbsize;

  signals: // Signals
    /** This signal is send every time a new sentence has arrived. */
    void newsentence(QString sentence);
  public slots: // Public slots
    /** This slot is triggered by the timer, and is used to get the data from the serial port. */
    void slot_Timer();
  private: // Private methods
    /** This function initializes and opens the serial port for reading, and if succeeds start the timer. */
    int _openSerialPort();
  /** This function tries to read sentences from the buffer. If it finds any, it sends them as QStrings via the newsentence signal to whoever is listening (that will be GPSNMEA) and takes the sentences out of the buffer. */
  void readSentenceFromBuffer();
  /** Signal handler. Sets wait_flag to FALSE to indicate that characters have been received. */
  //void signal_handler_IO(int status);

};

#endif


gpscon.cpp:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "targets.h"

#ifdef t_cumulus //only compile for cumulus application

#include "gpscon.h"

int wait_flag;
/** Signal handler. Sets wait_flag to FALSE to indicate that characters have been received. */
void signal_handler_IO(int ){
  wait_flag = FALSE;
}


GPSCon::GPSCon(){
bcnt=0;
dbsize=0;
char tmp[4096];
databuffer=tmp;

timer=new QTimer(this);
wait_flag=TRUE;
connect( timer, SIGNAL(timeout()), this, SLOT(slot_Timer()) );

if (_openSerialPort() !=1)
  timer->start(25, FALSE);

}

GPSCon::~GPSCon(){
  /* restore old port settings */
  tcsetattr(fd,TCSANOW,&oldtio);
}

/** This slot is triggered by the timer, and is used to get the data from the serial port. */
void GPSCon::slot_Timer(){
  int res;
  int i;
  char buf[1023];

  if (wait_flag==FALSE) {
    res = read(fd,buf,1023);
     //printf(":%s:%d\n", buf, res);

    for (i=0;i<res;i++) {
      databuffer[dbsize++]=buf[i];
    }
    bcnt+=res;
    buf[res]=0;
    qDebug("total bytes received: %d",bcnt);
    readSentenceFromBuffer();

    wait_flag = TRUE;      /* wait for new input */
  }
}

/** This function initializes and opens the serial port for reading, and if succeeds start the timer. */
int GPSCon::_openSerialPort(){

  fd = open(SERIALPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd == -1)
  {
    /*
     * Could not open the port.
     */

     perror("open_port: Unable to open serial port - ");
     return -1;
  }

  saio.sa_handler=signal_handler_IO;
  //saio.sa_mask=0;
  saio.sa_flags=0;
  saio.sa_restorer = NULL;
  sigaction(SIGIO,&saio,NULL);

  fcntl(fd, F_SETOWN, getpid());
  fcntl(fd, F_SETFL, FASYNC);

  tcgetattr(fd,&oldtio); /*save current port settings */
  /* set new portsettings for canonical input processing */
  newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | ICRNL;
  newtio.c_oflag = 0;
  newtio.c_lflag = ICANON;
  newtio.c_cc[VMIN]=1;
  newtio.c_cc[VTIME]=0;
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);

   return fd;

}


/** This function tries to read sentences from the buffer. If it finds any, it sends them as QStrings via the newsentence signal to whoever is listening (that will be GPSNMEA) and takes the sentences out of the buffer. */
void GPSCon::readSentenceFromBuffer(){
int i;
int p;
char buf[255];
QString sentence;
p=-1;

for (i=0;i<dbsize;i++)
{
  if (databuffer[i]==10)
   {
     p=i;
     break;
    }
}

if (p>-1) { //found a newline, thus a complete sentence is stored in the buffer!
  for (i=0; i<p; i++) buf[i]=databuffer[i]; //copy sentence to buffer;
  buf[i]=0; //append an endbyte
  sentence=buf;
  for (i=0; i<dbsize-p-1; i++) databuffer[i]=databuffer[p+1]; //remove first part of databuffer;
  dbsize-=p+1; //adjust the size of the buffer.
  if (sentence!="") {   //empty sentences are ignored.
    emit newsentence(sentence);
    readSentenceFromBuffer(); //call recursively to check for multiple sentences
  }
}


}

#endif //only compile for cumulus application

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Aetje
  • Registratie: September 2001
  • Laatst online: 18-12-2025

Aetje

Troubleshooting met HAMERRR

Wie communiceert hier met wie via welk medium?

[Edit] Recieved bytes ligt toch echt aan de snelheid van de zender, niet dat van je progsel...

Forget your fears...
...and want to know more...


  • ATS
  • Registratie: September 2001
  • Laatst online: 12-02 13:46
Het is een GPS die bytes uitspuugt naar (nu nog) een PC (uiteindelijk een handheld) via een seriele poort (COM1). Het vreemde is dat als ik mijn programma sluit en weer start, de snelheid weer op peil is. Ik denk dus dat het toch iets met mijn programma te maken heeft.
Edit: de tijd dat het kost voordat de snelheid inzakt is ook afhankelijk van het timerinterval: als dat korter is, dan duurt het langer voordat de snelheid inzakt 8)7

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Belgar
  • Registratie: Januari 2002
  • Laatst online: 17-08 22:31

Belgar

Archmaster ranzige code..

Wat voor Flow control wordt er gebruikt? Ik heb dit probleem ook eens gehad en dat kwam toen omdat ik 'sync' verloor met de andere kant

...Als het maar werkt


  • ATS
  • Registratie: September 2001
  • Laatst online: 12-02 13:46
Errr... goede vraag. Ik zet de CRTSCTS flag voor flowcontrol. Deze weghalen heeft geen effect. Hoe kan ik dat verder zien?

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Belgar
  • Registratie: Januari 2002
  • Laatst online: 17-08 22:31

Belgar

Archmaster ranzige code..

documentatie van de GPS? Het hoeft niet het probleem te zijn. Ik heb zelf echter eens zo'n tool geschreven om een en ander te vergemakkelijken voor router configs. Daar had ik een zelfde probleem. Kijk ook eens of een flush van je iobuffer helpt. Verder heb je volgens mij slechts 1 stopbit. sommige hardware controllers verlangen graag 2 stopbits (ook in documentatie te vinden).

...Als het maar werkt


  • ATS
  • Registratie: September 2001
  • Laatst online: 12-02 13:46
De stopbits bleek niet het probleem, maar het flushen bleek de sleutel! Dank je wel!!! _/-\o_ :)
Ik heb daartoe de volgende regel toegevoegd in het timer event:
code:
1
    tcflush(fd, TCIOFLUSH);

(voor diegenen die ook met dit probleem geconfronteerd worden en de search gebruiken om het op te lossen ;) )

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant

Pagina: 1