Spuštění skriptu při sepnutí RS232

Smisek

Spuštění skriptu při sepnutí RS232
« kdy: 09. 05. 2013, 16:49:02 »
Ahoj, nemáte někdo vymyšlený skript na zjištění sepnutého stavu rs232 a následné spuštění  akce (pod linuxem)? A které dva kontakty musím spojit? Hledám na anglických webech, ale mám problém definovat co hledám, proto se mi nedaří nic kloudného najít. Díky za odpověď. Smisek
« Poslední změna: 09. 05. 2013, 16:54:15 od Petr Krčmář »


gamer

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #1 kdy: 09. 05. 2013, 17:12:31 »
Chceš detekovat break? To není úplně triviální úloha pro skript:
http://stackoverflow.com/questions/14803434/receive-read-break-condition-on-linux-serial-port

Smisek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #2 kdy: 09. 05. 2013, 19:10:48 »
To bude ono, v céčku něco málo umím, tak to zvládnu, díky. :)

Smisek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #3 kdy: 10. 05. 2013, 13:19:50 »
Tak jsem našel vhodný postup jak stav dostat pomoci tohoto kódu jenž by měl být v pořádku:

Kód: [Vybrat]
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <time.h>

int main ()
{
int status=0,fd=0;
for(;;) {
  fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY );
  ioctl(fd, TIOCMGET, &status); // get the current port status

  printf ("fd: %d",fd);
  printf (" LE %d,",TIOCM_LE);
  printf (" DTR %d,",TIOCM_DTR);
  printf (" RTS %d,",TIOCM_RTS);
  printf (" CTS %d,",TIOCM_CTS);
  printf (" CAR %d",TIOCM_CAR);

  printf ("\n");
  close(fd);
  sleep(1);
}
return 0;
}
Avšak při spuštění mi vypíše pokaždé beze změny: (fd: 3 LE 1, DTR 2, RTS 4, CTS 32, CAR 64), spínám porty RTS a CTS.

monitor

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #4 kdy: 10. 05. 2013, 13:40:19 »
1. preco je stale rovnaky fd (file descriptor):
lebo stdin je 0, stdout je 1, stderr je 2,
no a ty v tom cykle vzdy otvaras a zatvaras subor, a ten ma fd 3. (je to poradove cislo, kolky subor to je otvoreny, tvojim programom).
Cize to je uplne OK.

2. to, ze mas potom pri tych inych riadkoch konstantne rovnaky vystup(kazdu sekundu) je asi dane tym, ze vypisujes konstanty :-)

To, co chces, je zrejme namiesto
printf (" LE %d,",TIOCM_LE);

pouzit nieco ako:

printf (" LE %d,", status & TIOCM_LE);

teda, po slovensky, vypis mi prosim ta na stdout, aka je hodnota TIOCM_LE bitu v mojom statuse, ktory som ziskal tym ioctl TIOCMGET
 
Tu tiez pekne niekto ukazuje, ze to treba "z-and-ovat"...
http://www.linuxjournal.com/article/6908


3ugeene

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #5 kdy: 10. 05. 2013, 14:20:48 »
jinak spinas CTS a RTS, RTS je vystup (request to send) a CTS VSTUP (CTS) z cehoz vyplyva jedna vec: hodnota CTS se ti bude menit pouze v pripade, ze je RTS zapnuty.

Pokud se nepletu, tak pin DTR (data terminal ready) je zapnuty vzdy (spis se pletu), takze zkus spinat CTS a DTR

Smisek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #6 kdy: 10. 05. 2013, 15:03:22 »
Přidal jsem status, teď to vypisuje jen nuly: LE 0, DTR 0, RTS 0, CTS 0, CAR 0,
Zkusil jsem spínat cts+dtr a cts+rts

monitor

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #7 kdy: 10. 05. 2013, 15:36:13 »
Hmm,
najskor: si si isty, ze ti ten port funguje? (je zapnuty v BIOSe)

Ked tam das nejake zariadenie, a otvoris ho napriklad minicom-om, ide to OK?

Ak ano, mozno este skus tuto radu:
(nastav, ze "tok dat" riadi Hardware, aj ked neviem na 100% , ci je to to, co chces, ale skusil by som to...)

http://www.tldp.org/HOWTO/Serial-HOWTO-19.html

stty -F /dev/ttyS0 crtscts

Smisek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #8 kdy: 10. 05. 2013, 15:45:43 »
port funguje na 100% využívám jej na dálkové ovládání, popřípadě mám ještě PCI kartu s dalšími dvěma rs232 porty, které se chovají stejně. Zkusím si zapnout distribuci slitaz a vyzkouším to tam.

nastavit "tok dat" se nepovedlo, viz:
stty -F /dev/ttyS0 crtscts
stty: /dev/ttyS0: Input/output error

minicom vyzkouším...

monitor

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #9 kdy: 10. 05. 2013, 16:05:37 »
Treba sa nato pozriet.. je to zvlastne...

Lebo, na mojom notebooku (s Ubuntu) mam sice "akoze" ttyS0-ttyS3, ale samozrejme, ze jedine
 stty -F /dev/ttyUSB0

vrati nieco ine ako "Input/output error".

A ked som vyskusal plus minus tvoj program, tak sa mi to sprava presne ako u teba - cize, same nuly?

Ale preto, ze vlastne /dev/ttyS0 neexistuje. (teda, on sa da otvorit, preto open vrati pekne fd==3,
ale ked nanho zavolas ioctl, tak to neprejde!

Ten ioctl vracia -1 - cize, nastala chyba!
Presvedc sa o tom vypisom (navratove hodnoty "treba" vzdy testovat :-)

Plus si este za ten ioctl daj:
perror("chybicka se vloudila\n");


a dostanes "Input/output error", presne ako to vypisuje stty.
Jednoducho, musis pouzit iny port.
Co vypise
dmesg|grep tty
???

Tam by si mal vidiet (okrem ineho) tvoje seriove porty... (okrem tty0, co sa nerata...)

Radek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #10 kdy: 10. 05. 2013, 16:26:22 »
Zkus tohle, me to kdysi fungovalo .....

Kód: [Vybrat]

#include <termios.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/ioctl.h>


#define BAUDRATE B9600
#define SERIAL "/dev/ttyS0"

int main(void)
{

    int fdcom;
    struct termios oldtio, newtio, akttio;
    int flags;
    int flst, flold;
   
    int bit_ST = TIOCM_ST;
    int bit_SR = TIOCM_SR;
    int bit_LE = TIOCM_LE;
    int bit_RTS = TIOCM_RTS;
    int bit_CTS = TIOCM_CTS;
    int bit_DTR = TIOCM_DTR;
    int bit_DSR = TIOCM_DSR;
    int bit_CD = TIOCM_CD;
    int bit_RI = TIOCM_RI;


    /*config for serial device */
    fdcom = open(SERIAL, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fdcom < 0) {
        perror(SERIAL);
        return(-1);
    }
    tcgetattr(fdcom, &oldtio);  /* save current port settings */

    /* new port settings */
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD | HUPCL;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    newtio.c_lflag = TOSTOP;
    newtio.c_cc[VMIN] = 1;
    newtio.c_cc[VTIME] = 0;
    tcflush(fdcom, TCIFLUSH);
    tcsetattr(fdcom, TCSANOW, &newtio);
   
    printf("port: %s\n", SERIAL);
   
    for (;;) {

        (void) ioctl(fdcom, TIOCMGET, &flags);
            flst = (flags & bit_RTS);
            printf("RTS: %03x  ", flst);
            flst = (flags & bit_CTS);
            printf("CTS: %03x  ", flst);
            flst = (flags & bit_DTR);
            printf("DTR: %03x  ", flst);
            flst = (flags & bit_DSR);
            printf("DSR: %03x  ", flst);
            flst = (flags & bit_CD);
            printf("CD: %03x  ", flst);
            flst = (flags & bit_RI);
            printf("RI: %03x  \n", flst);
           
//      printf("flags: 0x%03x\n", flags);
        usleep(500000);
    }

    /* restore old port settings */
    tcsetattr(fdcom, TCSANOW, &oldtio);
}



Smisek

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #11 kdy: 10. 05. 2013, 18:08:47 »
Díky monitor za upozornění, vypsal jsem si dmesg a opravdu nenapadlo mě, že mohou být tty namapovany na pozici 4 a 5. Oba porty fungují a program odpovídá na spoje, zajímavé je že mi to na ttyS0 nejde a přitom port funguje. Děkuji všem za rady. :)

Pro zajímavost výpis z tty:
Kód: [Vybrat]
[    0.000000] console [tty0] enabled
[    0.289696] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    0.382144] 00:09: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    0.468615] 0000:00:0e.0: ttyS4 at I/O 0xb000 (irq = 17) is a 16550A
[    0.508557] 0000:00:0e.0: ttyS5 at I/O 0xa800 (irq = 17) is a 16550A

monitor

Re:Spuštění skriptu při sepnutí RS232
« Odpověď #12 kdy: 10. 05. 2013, 18:50:25 »
Hm, ked Ti to nejde na ttyS0, ale na 4 a 5, tak skus porovnat v com je rozdiel:

stty -F /dev/ttyS0

stty -F /dev/ttyS4

Nieco tam musi byt ine, a to si zasa pomocou toho stty mozes nastavit, aby ti to islo aj na ttyS0...