TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: alperez en 28 de Junio de 2013, 04:40:34

Título: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 04:40:34
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
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MGLSOFT en 28 de Junio de 2013, 08:39:22
Cambiate a bus CAN...
No tendras colisiones nunca... ;-)
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 08:55:12
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).
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 09:13:11
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
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MGLSOFT en 28 de Junio de 2013, 09:26:05
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:


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:
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MGLSOFT en 28 de Junio de 2013, 09:34:33
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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 09:47:18
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.

Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MGLSOFT en 28 de Junio de 2013, 10:50:51
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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MerLiNz en 28 de Junio de 2013, 11:22:20
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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 12:01:49
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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 28 de Junio de 2013, 12:15:48
Habéis probado alguno? son compatibles entre distintas marcas y/o modelos?
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MerLiNz 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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez 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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MerLiNz 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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez 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.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MGLSOFT en 28 de Junio de 2013, 18:30:36
Lo que dice Merlinz es que el bit que se testea en Kbhit es el bit RCreg.
ese se activa al terminar la recepcion solamente.
El que estas testeando creo que esta mal, es para otra cosa...
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: MerLiNz en 28 de Junio de 2013, 19:17:52
Con el tiempo te daras cuenta de que lo que quieres hacer es mas complicado que usar algo que ya existe (por ejemplo CAN), solo piensa que aunque exista un minimo % de colision estaras perdiendo bastante. Puedes probar a poner rs485 multimaster en google y veras que todo el mundo llega a la conclusion que es mas sencillo usar algo ya diseñado que diseñar algo donde no puedes controlar el bus al 100%.
Título: Re: Solicito informacion/recomendacion, evitar colisiones BUS RS485 a alta velocidad
Publicado por: alperez en 29 de Junio de 2013, 03:15:17
Al final tendré que optar por CAN, por tecnología, por velocidad y por soporte, pero antes probare a implementar un protocolo del tipo token ring...