Nowe posty

Autor Wątek: C++ otwarcie portu /dev/ttyUSB0 jak PuTty . Klocki RS485 AVT  (Przeczytany 5323 razy)

ziel_inf

  • Gość
witam
Mam problem komunikacją na szeregowym porcie (wirtualny przez USB).
Piszę program w C++ do odczytu danych z kart  RS485 ( klocki RS485 AVT).
Na port /dev/ttyUSB0 wysyłam zapytanie np "T00" i po 4 sekundach odczytuje odpowiedz. np T00=23;T01=24.
Problem w tym że używając PuTty ( z odpowiednią prędkością ) zawsze otrzymuję odpowiedz z kart , natomiast używając mojego programu (C++ - kompilacja g++ , uruchomienie w terminalu) prawidłową odpowiedz dostaje tylko raz. Potem nie ma żadnej odpowiedzi z portu. Jedynie reset kompa pomaga. Wygląda to tak jakby port /dev/ttyUSB0 sie "zapchał" - został nieprawidłowo otwarty , coś wisi w buforze , lub sam - nie wiem . Jest to problem oprogramowania poniewaz na PuTty - zawsze działa.
JAK PRAWIDŁOWO SKONFIGUROWAC PORT ??? - naśladując ustawienia PuTty

Kod konfiguracji w C++ - działa niestabilnie
fd1=open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

if (fd1 == -1 )

{

perror("open_port: Unable to open /dev/ttyUSB0 – ");

}

else

{

//fcntl(fd1, F_SETFL,0);
        struct termios options;

        fcntl(fd1, F_SETFL, 0);

        tcgetattr(fd1, &options);

        options.c_cflag = B1200 | CRTSCTS | CS8 | CLOCAL | CREAD;// dla karty wejsc
    cfsetispeed(&options, B1200);
    cfsetospeed(&options, B1200);

   // ustawiamy opcje: CLOCAL - polaczenie lokalne, bez modemu
    // CREAD -  wlaczenie odbioru
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;  // wylaczenie kontroli parzystosci
    options.c_cflag &= ~CSTOPB;  // 1 bit stopu
    options.c_cflag |=  CS8;     // 8 bitow/znak
    options.c_cflag &= ~CRTSCTS; // brak 'hardware flow control'
         //Raw input
        //options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

        //Disable parity checking
options.c_iflag &= ~(INPCK | ISTRIP);

        //Don't map CR to NL or NL to CR
        options.c_iflag &= ~(ICRNL | INLCR);

        //Don't map uppercase to lowercase
        options.c_iflag &= ~IUCLC;

        //Don't ignore CR
        options.c_iflag &= ~IGNCR;

        //Ignore BREAK condition
        options.c_iflag |= IGNBRK;

        //Disable software flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY);

        //Raw output - other c_oflag bits ignored
options.c_oflag &= ~OPOST;

//Set new settings
        tcsetattr(fd1, TCSANOW, &options);

 /* Clear the line */
       tcflush(fd1,TCIFLUSH);

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3056
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
C++ otwarcie portu /dev/ttyUSB0 jak PuTty . Klocki RS485 AVT
« Odpowiedź #1 dnia: 2014-07-25, 10:04:54 »
U mnie otwarcie portu com-USB (dostęp do wyświetlacza CrystalFontz 635) wygląda tak:

int comOpen( char *devname )
{
        int handle;
        int brate = B115200;
        struct termios term;

        //open device
        handle = open( devname, O_RDWR | O_NOCTTY | O_NONBLOCK );

        if( handle < 0 )
                return -1;

        //get device struct
        if( tcgetattr( handle, &term ) != 0 )
        {
                close( handle );
                return -2;
        }

        //input modes
        term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF);
        term.c_iflag |= IGNPAR;

        //output modes
        term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FF

        //control modes
        term.c_cflag &= ~(CSIZE | PARENB | PARODD | HUPCL | CRTSCTS);
        term.c_cflag |= CREAD | CS8 | CSTOPB | CLOCAL;

        //local modes
        term.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO);
        term.c_lflag |= NOFLSH;

        //set baud rate
        cfsetospeed( &term, brate );
        cfsetispeed( &term, brate );

        //set new device settings
        if( tcsetattr( handle, TCSANOW, &term ) != 0 )
        {
                return -3;
        }

        return handle;
}
Zmień B115200 na B1200 i powinno banglać. Jeżeli read(...) ma się blokować czekając na znak (zamiast zwracać 0 bajtów), to usuń "| O_NONBLOCK" z open-a.
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy