C/Visual C - Leer del puerto con RS485

   
Vista:

Leer del puerto con RS485

Publicado por Jorge (31 intervenciones) el 14/06/2016 22:27:52
Hola a todo el mundo:

Estoy intentando hacer un programa en C para leer y escribir por el puerto serie en modo RS485.


Por al momento he probado con un pequeño código que he bajado de internet pero con él puedo escribir, pero no leer.


Este es el código:

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
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asm/ioctls.h>
#include <errno.h>
#include <termios.h>
 
/* RS485 ioctls: */
#define TIOCGRS485 0x542E
#define TIOCSRS485 0x542F
 
 
// Control struct for setting the port in 485 mode
struct rs485_ctrl {
unsigned short rts_on_send;
unsigned short rts_after_sent;
unsigned int delay_rts_before_send;
unsigned short enabled;
};
 
// his struct is only needed if we would like to write with ioctl()
struct rs485_wrt {
unsigned short outc_size;
unsigned char *outc;
};
 
int main(void) {
char dev[] = "/dev/ttySC0";
// char buffer_to_send[] = { 0x55, 0x00, 0x55 };
char buffer_to_send[11] = "HELLO WORLD";
char buffer_to_recv[100] = "";
int baudrate = B9600;
 
struct rs485_ctrl ctrl485;
int status;
int fd;
struct termios ti;
struct termios ti_prev;
 
// Open the serial port
fd = open(dev, O_RDWR|O_NONBLOCK);
if (fd < 0) {
printf("ERROR! Failed to open %s\n", dev);
return -1;
}
 
// Set the serial port in 485 mode
ctrl485.rts_on_send = 0; // It means that DE is at 3.3 volt on send
ctrl485.rts_after_sent = 1; // It means that DE is at 0 volt on send
ctrl485.delay_rts_before_send = 0; // DE will be active at same time of data
ctrl485.enabled = 1;
// status = ioctl(fd, TIOCSERSETRS485, &ctrl485);
status = ioctl(fd, TIOCSRS485, &ctrl485);
if (status) {
// printf("ERROR PORT 1! TIOCSERSETRS485 failed %i", status);
printf("ERROR PORT 1! TIOCSRS485 failed %i", status);
return -1;
}
 
tcgetattr(fd, &ti_prev); // Save the previous serial config
tcgetattr(fd, &ti); // Read the previous serial config
cfsetospeed(&ti,baudrate); // Set the TX baud rate
cfsetispeed(&ti,baudrate); // Set the RX baud rate
 
cfmakeraw(&ti);
tcsetattr(fd, TCSANOW, &ti); // Set the new serial config
 
// Send buffer_to_send content to RS485
if (write(fd, buffer_to_send, sizeof(buffer_to_send)) != sizeof(buffer_to_send)) {
printf("ERROR! write() failed \r\n");
}
 
// Read a char
int Lcl_Cant = read(fd,&buffer_to_recv,1);
printf("Lcl_Cant: [%d]\n", Lcl_Cant);
// perror( error );
if ( Lcl_Cant == 1) {
printf("%c",buffer_to_recv[0]);
printf("\n");
}
else {
perror("ERROR: !");
printf("errno = %d.\n", errno);
}
 
ti_prev.c_cflag &= ~HUPCL; // This to release the RTS after close
tcsetattr(fd, TCSANOW, &ti_prev); // Restore the previous serial config
close(fd);
 
return 0;
}

No entiendo que es lo que estoy haciendo mal.

Por favor, podrían ayudarme

Muchas Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Leer del puerto con RS485

Publicado por Tom (481 intervenciones) el 15/06/2016 13:03:08
Sin saber nada sobre ese tipo de puertos, lo que sí veo es que estás abriendo el device en modo no bloqueante (O_NONBLOCK), así que read puede no devolverte nada. Has trazado el error en errno para algo ¿ no ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Leer del puerto con RS485

Publicado por Jorge (31 intervenciones) el 15/06/2016 14:18:38
Hola

Gracias por la respuesta.

En lo que se refiere al parámetro "O_NONBLOCK" no me había dado cuenta. Probaré a quitarlo.

En lo que se refiere al error, en efecto trazo el error, pero se me olvidó ponerlo, jeje

El error que devuelve es 11: "Resource temporarily unavailable"

He estado leyendo que los chips utilizados para transmitir por RS485 tienen una pata llamada RTS la cual hay que poner a 1 para enviar y a 0 para recibir ya que el protocolo RS485 no es full dúplex.

Lo que desconozco es como se hace esto (o incluso si el código que he puesto ya lo contempla)

Alguna idea ?

Gracias y saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar