Autor Tema: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad  (Leído 5203 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Hola compañeros, llevo bastante tiempo en un proyecto en el que tengo un PIC24 conectado a ethernet y a un bus RS485, los cuales son "controlados" desde una aplicación android, todo funciona muy bien y he conseguido el envío de datos a una aceptable velocidad de aprox 80ms de respuesta en la parte de RS485 pero sólo con dos esclavos sin que existan colisiones, pero cuando lo que quiero es que muestre el valor del ADC de algún esclavo, existe un retardo, el cuál no es importante, pero tengo un/os problema(s):

1º Parece que kbhit() no funciona y envía la trama cuando le parece provocando la colisión.
2º El PIC24 está continuamente enviando la trama de solicitud de datos para todos los esclavos, lo que no deja de entrar la interrupción de la UART en los esclavos y no deja de interrumpir la conversión ADC.

Creo que el problema lo tengo en la 2ª opción, y había pensado en mantener un orden como por ejemplo token ring, pero esto me traerá otros problemas (no hablo de programación)
Otra solución es cambiar los PIC de los esclavos (actualmente 16f1825) pero una característica de este proyecto es su bajo coste de fabricación y no quiero poner PIC's mas caros/potentes.

Había pensado en desactivar la interrupción RDA durante el trabajo del ADC, pero entonces, o amplío el tiempo de muestreo o pierdo tramas.
Tampoco creo que tenga bien configurado el ADC del PIC esclavo y es por eso que tarda demasiado en realizar el muestreo.

Gracias por vuestra ayuda

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Cambiate a bus CAN...
No tendras colisiones nunca... ;-)
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Cambiate a bus CAN...
No tendras colisiones nunca... ;-)

Desconozco totalmente el bus CAN, ¿qué distancia máxima permite y a qué velocidad? ¿que costo tienen los transceiver? ¿que tal complicado es su implementación?

Con el max487 puedo llegar poner 128 elementos, 250Kbps y hasta 1200 metros de distancia dependiendo de la velocidad con un costo mas que razonable. Es mucho más de lo que necesito, pero ahí queda.

Voy a ver que tal esto del CAN pero tenía entendido que era para destancias cortas (un coche).

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
He visto este: http://www.nxp.com/documents/data_sheet/TJA1041A.pdf

¿Todos los transceiver de todos los fabricantes son compatibles entre sí?

Por lo que veo son más caros que los rs485

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
En RS485, la norma dice que puedes poner 128 esclavos (en realidad 127, porque uno es el master) pero en realidad a 1200 metros y 250 k, vas poder decir Hola solamente... :D
En CanBus el cableado sera el mismo que hoy tienes, par retorcido balanceado impedancia 100 ohms.
La velocidad a utilizar determina la longitud del cableado, por ejemplo:

  • Para 1 mbit/seg  solo podras llegar a 80 mts (creo)
  • Para 500 Kbit/seg es de 100 mts
  • Para 250 Kbit/seg  podras llegar a 250 mts
  • Para 125 Kbit/seg es de 250 mts
  • Para 80 Kbit/seg (la mas baja) es de 500 mts

Lleva resistencias terminadoras en los extremos mas distantes.
A diferencia de 485, puede tener derivaciones hasta los nodos de maximo 6 metros, aunque se descuentan de la longitud del cableado, pero permiten ciertas comodidades, como no ir y volver.

Los transceiver MCP2551 tienen precio equivalente a un MAX485, y la ventaja que parte del protocolo se maneja desde el hardware, como el control de bit timing.
No hay colisiones, porque el protocolo detecta esa posibilidad y segun quien tenga el ID mas bajo, este gana la arbitracion y el otro espera para transmitir su mensaje.

Y lo mas importante: es multimaestro, cualquiera de los nodos puede ser esclavo segun el caso y pasar a maestro en otros, sin inconvenientes.
Esta basado en un sistema llamado productor/consumidor, y pueden mandarse mensajes entre esclavos sin participacion de los demas, mensajes por difusion (todos los escuchan) a solo una serie de nodos, etcetera.
Como funciona tu red lo determinas tu mismo.

Que tal? :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
He visto este: http://www.nxp.com/documents/data_sheet/TJA1041A.pdf

¿Todos los transceiver de todos los fabricantes son compatibles entre sí?

Por lo que veo son más caros que los rs485

Creo que te has metido en productos que exceden la norma, esta en creacion (y pruebas) un estandar que permitira exceder el tamaño de mensajes de 8 bytes, creo que hasta 128 bytes, utilizando buses de mucho mas alta velocidad, creo que hasta 10 megabytes.

yo no conocia ese transceiver, solo los de Microchip, Texas y otras marcas que son compatibles e intercambiables entre si.

Aunque tengas diferencia de .5 dolares entre el Max y un transceiver, creo que veras ampliamente justificada la inversion.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
MGLSOFT todo lo que leas, absolutamente todo lo que leas sobre rs485 debes dejarlo entre "". Aun no tengo cableado solo estoy haciendo pruebas y... ¡¡en estrella!!, aunque son sólo 3 elementos, el "master" y dos esclavos, con una logitud corta y con una tasa de transferencia de creo recordar de 50 y pico kbps, pero la cuestion no es la tasa, si no que las pruebas que hice era del envio masivo de tramas de 6 bytes y los dos esclavos respondian perfectamente a razon de 11 respuestas por segundo (entre los dos).

Por supuesto que cualquier elemento puede ser maestro, sólo hay que implementar el protocolo para seguir un orden en el acceso al medio y así evitar las colisiones, y en eso estoy.

A ver si me hago con unos pocos de metros de cable a ver hasta cuanto puedo extender la estrella.

El problema lo tengo cuando quiero leer el ADC por que se me interrumpe la comunicación y creo que ese problema lo seguiré teniendo con el CAN.


Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
La mensajeria de CAN se resuelve a nivel de hardware, quedan los mensajes en 3 o mas buffer para que los leas cuando tengas tiempo, a diferencia del otro protocolo que es implementado "a pecho"... ;-)
Cuando quieres enviar, pones el mensaje en otro buffer y le das orden de transmit, y te vas a hacer otras tareas, por lo tanto no creo tengas problemas.
Si lo quieres hacer mejor, puedes generar interrupcion por mensaje recibido y por mensaje enviado y lees una bandera que seteas dentro de esa interrupcion.
Si crees que el A/D es mas importante, tambien lo haces por interrupcion y le das la mayor prioridad.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Con el RS485 no podras hacer un sistema multimaestro como el que quieres hacer, solamente podrias hacer un sistema maestro-esclavos es decir: el maestro le pide al esclavo 1 que este envie el valor del ADC y el esclavo responde con el valor entonces el maestro pide que el esclavo 2 le envie X informacion y este responde... Pero nunca podras hacer que los esclavos manden informacion sin que el maestro los controle ya que se produciria siempre colisiones... En la linea de rs232 no existe ninguna forma de verificar que el bus esta ocupado por lo cual se producirian muchas colisiones...

Para ello tienes el CAN que es un sistema multimaestro con toda la capa hardware y software implementada, no te tendrias que preocupar por nada, incluso en caso de alguna colision o algun error en la recepcion del mensaje, este mismo se encarga de reenviar el mensaje hasta X veces, a partir de esas veces da error de bus (detectable por un registro) y deja de enviar hasta que lo resetees...

Yo al igual que tu quise hacer este sistema que indicas multimaestro con rs485, pero al final me di cuenta que era bastante complicado por no decir casi imposible.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
MerLiNz, no pretendo hacer un sistema multimaestro, y creeme que sí se podría, nada impide que el esclavo 1 solicite al esclavo 2 que le envíe el estado de por ejemplo uno de sus puertos y que a su vez otro (digamos el "maestro") active otro puerto de los dos esclavos anteriores.

Puedo detectar si el bus está libre si no existe dato en el pin Rx de la UART, esto ya funciona y a una velocidad relativamente alta y mas que suficiente, solo tengo que dejar libre el bus entre trama y trama para que responda el esclavo que corresponda, pero mi problema es el ADC.

Este es el diseño de lo que he hecho, nada del otro mundo pero es efectivo. Aun queda implementar una especie de checksum

[inicio][destino][origen][comando][argumento][fin] -------//-------- [inicio][destino][origen][comando][argumento][fin]

El esclavo se queda esperando esa pequeña pausa para enviar la respuesta pero con el ADC es cuando tengo el problema. Realmente no es una pausa, es la continuación del ciclo de programa que tarda más o menos en función de las peticiones que le haga por TCP/IP con la aplicacion Android, pero es lo suficientemente rápido.

De todas formas si el transceiver CAN se ocupa de todo esto, sería interesante valorarlo.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
« Respuesta #10 en: 28 de Junio de 2013, 12:15:48 »
Habéis probado alguno? son compatibles entre distintas marcas y/o modelos?

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
« Respuesta #11 en: 28 de Junio de 2013, 12:39:28 »
MerLiNz, no pretendo hacer un sistema multimaestro, y creeme que sí se podría, nada impide que el esclavo 1 solicite al esclavo 2 que le envíe el estado de por ejemplo uno de sus puertos y que a su vez otro (digamos el "maestro") active otro puerto de los dos esclavos anteriores.

Puedo detectar si el bus está libre si no existe dato en el pin Rx de la UART, esto ya funciona y a una velocidad relativamente alta y mas que suficiente, solo tengo que dejar libre el bus entre trama y trama para que responda el esclavo que corresponda, pero mi problema es el ADC.

Este es el diseño de lo que he hecho, nada del otro mundo pero es efectivo. Aun queda implementar una especie de checksum

[inicio][destino][origen][comando][argumento][fin] -------//-------- [inicio][destino][origen][comando][argumento][fin]

El esclavo se queda esperando esa pequeña pausa para enviar la respuesta pero con el ADC es cuando tengo el problema. Realmente no es una pausa, es la continuación del ciclo de programa que tarda más o menos en función de las peticiones que le haga por TCP/IP con la aplicacion Android, pero es lo suficientemente rápido.

De todas formas si el transceiver CAN se ocupa de todo esto, sería interesante valorarlo.

No se podria te voy a comentar porque, no existe ningun registro que indique que se esta usando el bus, el kbhit que indicas lo unico que hace es ver si hay datos recibidos, pero este se pone a 1 cuando RECIBE ALGUN DATO no mientras se esta haciendo un envio, si el esclavo 1 envia un mensaje mientras el esclavo 2 esta enviando otro entonces tienes una colision clara. Otro ejemplo claro si se pudiese ver el estado del bus seria que por ejemplo 2 esclavos verifiquen el estado del bus, este esta libre, entonces ambos envien a la vez los datos, resultado: colision.

De hecho si te miras tutoriales sobre CAN veras que lo que hace para evitar colisiones es bastante complejo, con el usart tu no puedes modificar el hardware a no ser claro, que hagas tu propio usart diseñado por ti, asi podrias controlar el estado del bus, otra forma seria poniendo otro cable y que los pics lo pongan a 1 cuando se este usando el bus y a 0 cuando acaben, asi podrias detectar el uso del bus, pero tambien podrias tener algunos problemas de colision.
Es mas, el CAN no evita las colisiones sino que establece una prioridad, si hay 3 que quieren enviar a la vez, estos empiezan enviando y cuando uno de los mensajes es de menor prioridad entonces deja de enviar hasta que este acabe y asi hasta que se envie 1 mensaje, una vez se envia ese mensaje empiezan de nuevo a enviar y se vuelve a establecer una prioridad hasta que por fin se envien todos los mensajes.
« Última modificación: 28 de Junio de 2013, 12:42:12 por MerLiNz »

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
« Respuesta #12 en: 28 de Junio de 2013, 13:06:21 »


No se podria te voy a comentar porque, no existe ningun registro que indique que se esta usando el bus, el kbhit que indicas lo unico que hace es ver si hay datos recibidos, pero este se pone a 1 cuando RECIBE ALGUN DATO no mientras se esta haciendo un envio, si el esclavo 1 envia un mensaje mientras el esclavo 2 esta enviando otro entonces tienes una colision clara. Otro ejemplo claro si se pudiese ver el estado del bus seria que por ejemplo 2 esclavos verifiquen el estado del bus, este esta libre, entonces ambos envien a la vez los datos, resultado: colision.

De hecho si te miras tutoriales sobre CAN veras que lo que hace para evitar colisiones es bastante complejo, con el usart tu no puedes modificar el hardware a no ser claro, que hagas tu propio usart diseñado por ti, asi podrias controlar el estado del bus, otra forma seria poniendo otro cable y que los pics lo pongan a 1 cuando se este usando el bus y a 0 cuando acaben, asi podrias detectar el uso del bus, pero tambien podrias tener algunos problemas de colision.
Es mas, el CAN no evita las colisiones sino que establece una prioridad, si hay 3 que quieren enviar a la vez, estos empiezan enviando y cuando uno de los mensajes es de menor prioridad entonces deja de enviar hasta que este acabe y asi hasta que se envie 1 mensaje, una vez se envia ese mensaje empiezan de nuevo a enviar y se vuelve a establecer una prioridad hasta que por fin se envien todos los mensajes.


A lo mejor hago una pregunta tonta, pero ¿no te parece suficiente comprobar que no se está recibiendo ningún byte para saber que el bus está libre?.

Es ese quizas mi problema que cuando termina el ADC y va a enviar la trama está ocupado el bus, y eso es lo que quiero solucionar.

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
« Respuesta #13 en: 28 de Junio de 2013, 15:09:28 »
Te repito porque creo que no me has entendido bien:

No existe forma de saber si se esta recibiendo un mensaje. Solo puedes comprobar que tienes un mensaje ya recibido a la finalizacion de la recepcion, pero nunca cuando se esta recibiendo. Te pongo un ejemplo:

-El esclavo A esta enviando un mensaje
-El esclavo B verifica con kbhit, como da 0 este envia un mensaje
-Al estar enviando el esclavo A un mensaje (imagina que aun le queda el 50%) y el esclavo B intentar enviar un mensaje ocurre una colision, se uniria el 50% del esclavo A con parte del esclavo B.

Para ser mas concretos, kbhit indica que EXISTE UN MENSAJE RECIBIDO EN EL BUFFER pero hasta que ese mensaje no esta 100% recibido el kbhit no lo indica. Igual ocurre con la lectura de registros, no existe registro que diga que se esta recibiendo un mensaje, solo existe un registro que indica que se ha recibido al 100% un mensaje.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
« Respuesta #14 en: 28 de Junio de 2013, 17:44:55 »
Te repito porque creo que no me has entendido bien:

No existe forma de saber si se esta recibiendo un mensaje. Solo puedes comprobar que tienes un mensaje ya recibido a la finalizacion de la recepcion, pero nunca cuando se esta recibiendo. Te pongo un ejemplo:

-El esclavo A esta enviando un mensaje
-El esclavo B verifica con kbhit, como da 0 este envia un mensaje
-Al estar enviando el esclavo A un mensaje (imagina que aun le queda el 50%) y el esclavo B intentar enviar un mensaje ocurre una colision, se uniria el 50% del esclavo A con parte del esclavo B.

Para ser mas concretos, kbhit indica que EXISTE UN MENSAJE RECIBIDO EN EL BUFFER pero hasta que ese mensaje no esta 100% recibido el kbhit no lo indica. Igual ocurre con la lectura de registros, no existe registro que diga que se esta recibiendo un mensaje, solo existe un registro que indica que se ha recibido al 100% un mensaje.


kbhit devuelve 1 si existe un byte para leer, te refieres entonces cuando está al 50% del primer byte.... la posibilidad de que ocurra eso debe ser minima, pero es cierto que existe.

Fijate en el bit RCIDL de la imagen que te adjunto... Antes de transmitir chekeo ese bit. ¿es posible que exista una colision? por supuesto como en todas las comunicaciones que no sean tipo token ring y es lo que quiero hacer, buscar la forma de realizar eso perdiendo la mínima eficacia posible.