Forum: PC Hard- und Software Linux und RS485 Zähler auslesen.


von Lars (Gast)


Lesenswert?

Moin,


ich habe ein Problem. Ich habe einen Hutschienen PC mit einer RS485 
Schnittstelle(16550A) an der Schnittstelle hängt ein Elster A1500 
Zähler.

Wenn ich nun per minicom den Zähler /?! sende geht sein Display aus und 
er sendet, aber leider kommt am PC nicht an!!!


Warum kann per cat /dev/ttyS0 nicht sehen??

Ich habe schon etwas geguckt und es kann an den Flow Controll liegen, 
schaltet das nicht aber automatisch um?


Als System habe ich ein aktuelles Debian installiert.


Evtl kann mir ja mal wer einen Tip geben.

Lars

von Lars (Gast)


Lesenswert?

So ich bin mal ein Ticken weiter:
1
#include "stdio.h"     
2
#include "string.h"    
3
#include "unistd.h"    
4
#include "fcntl.h"     
5
#include "errno.h"     
6
#include "sys/types.h"
7
#include "sys/stat.h"
8
#include "stdlib.h"
9
#include "stdarg.h"
10
#include "termios.h"
11
#include "linux/serial.h"  
12
 
13
#define TIOCSRS485 0x542F
14
 
15
int main(void) {
16
    char txBuffer[10];
17
    char rxBuffer[10];
18
    int fd;
19
    struct termios tty_attributes;
20
    struct serial_rs485 rs485conf;
21
 
22
    if ((fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NONBLOCK))<0) {
23
        fprintf (stderr,"Open error on %s\n", strerror(errno));
24
        exit(EXIT_FAILURE);
25
    } else {
26
        tcgetattr(fd,&tty_attributes);
27
 
28
        // c_cflag
29
        // Enable receiver
30
        tty_attributes.c_cflag |= CREAD;        
31
 
32
        // 8 data bit
33
        tty_attributes.c_cflag |= CS8;          
34
 
35
        // c_iflag
36
        // Ignore framing errors and parity errors. 
37
        tty_attributes.c_iflag |= IGNPAR;       
38
 
39
        // c_lflag
40
        // DISABLE canonical mode.
41
        // Disables the special characters EOF, EOL, EOL2, 
42
        // ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.
43
 
44
        // DISABLE this: Echo input characters.
45
        tty_attributes.c_lflag &= ~(ICANON);     
46
 
47
        tty_attributes.c_lflag &= ~(ECHO);      
48
 
49
        // DISABLE this: If ICANON is also set, the ERASE character erases the preceding input  
50
        // character, and WERASE erases the preceding word.
51
        tty_attributes.c_lflag &= ~(ECHOE);     
52
 
53
        // DISABLE this: When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal. 
54
        tty_attributes.c_lflag &= ~(ISIG);      
55
 
56
        // Minimum number of characters for non-canonical read.
57
        tty_attributes.c_cc[VMIN]=1;            
58
 
59
        // Timeout in deciseconds for non-canonical read.
60
        tty_attributes.c_cc[VTIME]=0;           
61
 
62
        // Set the baud rate
63
        cfsetospeed(&tty_attributes,B300);     
64
        cfsetispeed(&tty_attributes,B300);
65
 
66
        tcsetattr(fd, TCSANOW, &tty_attributes);
67
 
68
        // Set RS485 mode: 
69
        rs485conf.flags |= SER_RS485_ENABLED;
70
        if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
71
            printf("ioctl error\n");
72
        }
73
 
74
        txBuffer[0]='A';
75
        write(fd,txBuffer,1);
76
 
77
        // Read a char
78
        if (read(fd,&rxBuffer,1)==1) {
79
            printf("%c",rxBuffer[0]);
80
            printf("\n");
81
        }   
82
    }   
83
 
84
    close(fd);  
85
    return EXIT_SUCCESS;
86
}


Diesen Code habe ich mal getestet, aber leider sagt der: ioctl error

Irgendwie lässt sich der 16550A nicht in den Rs485 Mode versetzen....

// Set RS485 mode:
        rs485conf.flags |= SER_RS485_ENABLED;
        if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
            printf("ioctl error\n");
        }

von Schorsch (Gast)


Lesenswert?

Hast Du folgendes bedacht:

RS485 ist ein Bus, und bei der Kommunikation mit dem Elster Zähler wird 
das diff. Adernpaar für RX und TX benutzt.

Das heißt, kurz vor dem Senden muß irgendwie der RS485 Treiber auf TX 
geschaltet werden, direkt nach dem Senden wieder disabled werden. Sonst 
hält er den Bus auf einen festen Pegel, und die Antowrt des Zählers 
kommt nicht an.
Sieht bei Dir danach aus - der Zähler reagiert rigendwie, aber Du siehst 
die Antwort nicht.
Sehr oft wird so etwas mit einer Handshake-Leitung gemacht. Versuch doch 
mal, erst RTS zu setzen, zu senden und direkt danach wieder 
zurückzusetzen.
(Oder umgekehrt)

-Schorsch

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Lars schrieb:
> Irgendwie lässt sich der 16550A nicht in den Rs485 Mode versetzen....

Der 16550 kennt keinen RS485-Mode. Die für den RS485-Betrieb zwingend 
erforderliche Sender-/Empfänger-Umschaltung musst Du mit Deinem Programm 
selber vornehmen, was üble Frickelei ist, denn nach dem Absenden von 
Daten musst Du solange warten, bis diese nicht nur das 
Hardware-Sende-Fifo des 16550 verlassen haben, sondern auch das 
Sendeschieberegister.

Abhilfe: Nimm einen USB-RS485-Adapter auf Basis des FT232, der bietet 
eine hardwaremäßige RS485-Unterstützung (siehe Schaltungsbeispiel im 
Datenblatt), und da musst Du Dich um gar nichts kümmern.

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.