Autor Tema: Dudas con el RS485  (Leído 9194 veces)

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

Desconectado navaismo

  • Jubilado Todopic
  • PIC24H
  • ****
  • Mensajes: 1973
Dudas con el RS485
« en: 01 de Abril de 2008, 20:01:47 »
Hola amigos, pues estaba jugando con la comunicacion RS485 en PROTON, y bueno tras leer y leer aun tengo algunas dudas.

Hice un programilla muy basico el cual enciende y apaga un par de leds mediante la PC, cuando es recibido el PIC contesta y se ve en la PC el mensaje. Bueno hasta ahi sin problemas. Las dudas y problemas vienen cuando añado al Bus otro PIC que hace exactamente lo mismo, segun yo para diferenciar la direccion del dispositivo uso el PORTA, pero con el programa que tengo no detectaria mas que 10 dispositivos es decir de 0-9, aun no se me ocurre como hacer que detecte los 31 que soportaria por el PORTA. Esa seria la primer Duda.

La segunda es que segun he leido y el data del max485 cuando RE=1 y DE=0 esta en modo de RX, cuando estan al reves es TX, la duda es: ¿segun mi circuito para que el PC reciba, necesito una NOT, como seria en la realidad para saber que pasa? como hago un PC sea compatible con RX-TX sin un PIC?

Les dejo la imagen del circuito, lo pueden probar funciona lo del encendido y apagado del LEd, solo que ya no manda el mensaje de que la orden fue recibida. para la simulacion use el VSP -Virtal Serial Port- y el Serial Com del PROTON la comunicacion es a 9600 8n1.

Para encender el LED amarillo del U1 se envia "1D"
Para encender el LED azul  del U1 se envia "1U"
Para apagar todo en el U1 se envia "1O"


Para encender el LED amarillo del U5 se envia "0D"
Para encender el LED azul  del U5 se envia "0U"
Para apagar todo en el U5 se envia "0O"

Dejo el pantallazo del Circuito y adjunto los archivos para su simulación. Y bueno se usan 2 PIC16F84A a 4MHZ

Dejo el programa comentado haber si se entiende mejor.

Código: FreeBasic
  1. '****************************************************************
  2. '* Name : test485.BAS *
  3. '* Author : Navaismo *
  4. '* Notice : Copyright (c) 2008 GPL *
  5. '* : All Rights Reserved *
  6. '* Date : 27/03/2008 *
  7. '* Version : 1.0 *
  8. '* Notes : *
  9. '* : *
  10. '****************************************************************
  11. device = 16f84A
  12. xtal = 4
  13. '*********** DEFINIMOS COMUNICACION SERIE A 9600 8N1 *********************
  14. declare rsin_mode true
  15. DECLARE RSOUT_MODE true
  16. declare rsin_pin portB.0 ' PUERTO RB0 COMO ENTRADA SERIAL
  17. declare rsout_pin portB.1 ' PUERTO RB1 COMO SALIDA SERIAL
  18. DECLARE SERIAL_BAUD 9600
  19.  
  20. TRISA=%11111 ' PUERTO A DE ENTRADA PARA DIRECCIONES
  21. TRISB.2=0 ' PUERTOS RB2,RB3 Y RB4 COMO SALIDAS
  22. TRISB.3=0
  23. TRISB.4=0
  24.  
  25. DIM RW AS PORTB.2 ' ALIAS PARA HABILITAR ESCRITURA O LECTURA RS485
  26. DIM MUP AS PORTB.3 ' ALIAS GP -GENERAL PORPOUSE O MEJOR DICHO PARA LO QUE SEA JAJA-
  27. DIM MOW AS PORTB.4 ' ALIAS GP
  28. DIM CTRL[2] AS BYTE ' VARIABLE DE CONTROL DE DATOS
  29. DIM DIR AS BYTE ' VARIABLE DE DIRECCION
  30. DIM T[3] AS BYTE ' VARIABLE PARA PASAR A ASCII LA DIRECCION
  31.  
  32. PORTB=0 ' LIMPIAMOS EL PORTB
  33. CMC: ' EMPEZAMOS RUTINA
  34. DIR=PORTA ' COPIAMOS EL VALOR DEL PORTA A LA VARIABLE
  35. STRN T = STR$ (DEC DIR) ' CONVERTIMOS EL VALOR DEL PORTA AL VALOR ASCII
  36. RW=0 ' PONEMOS EN ESTADO DE LECTURA O RX AL DISPOSITIVO 485
  37.  
  38. rsin str CTRL\2 ' ESPERAMOS LA DIRECCION Y EL COMANDO DEL DISPOSITIVO
  39.  
  40. IF CTRL[0]=T[0] THEN ' SI LA DIRECCION ES IGUAL A LA DE NUESTRO DISPOSITIVO RELAIZA LA ACCION
  41.  
  42. SELECT CASE CTRL[1] ' LEE EL VALOR DEL COMENDO
  43. CASE "U"
  44. MUP=1:MOW=0 ' ************ ENCIENDE O APAGA LOS LEDS ************
  45. DELAYMS 100
  46. GOSUB HS
  47. CASE "D"
  48. mup=0:MOW=1
  49. DELAYMS 100
  50. GOSUB HS
  51. CASE "O"
  52. MUP=0:MOW=0
  53. DELAYMS 100
  54. GOSUB HS
  55. END SELECT
  56. ENDIF
  57. ' HACEMOS LOOP
  58. GOTO CMC
  59.  
  60. HS: ' RUTINA DE HANDSHAKE
  61. RW=1 ' PONEMOS COMO TX EL DISPOSITIVO
  62. RSOUT "RECIBIDO EN 1: ", STR CTRL\2,13 ' ENVIAMOS LO RECIBIDO
  63. DELAYMS 200
  64. RETURN ' REGRESAMOS



Y lo mas importante como que presiento que eso no es comunicacion RS485 he leido una y otra vez los excelentes post de REDPIC y DOGFLU y es por eso que me quedan dudas.


Saludos y Gracias
"Mi tercer deseo, que otra cosa podría ser, poner un final a todo el sufrimiento, que sólo con mi propia extinción el planeta podrá ser aliviado. Pobre de mí, Si tuviera tres deseos hoy, la elección no sería dificil para mí, Sólo tres deseos serían suficientes, No tendría uso para más."

"He sido un hombre que busca y aun lo sigo siendo, pero ya no busco en las estrellas y en los libros, sino en las enseñanzas de mi sangre."

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re: Dudas con el RS485
« Respuesta #1 en: 02 de Abril de 2008, 11:33:56 »
Que tal navaismo,

Es para mi un honor apoyar a uno de los maestros de este foro.
En cuanto a tu circuito, es decir el hardware, unicamente tienes que colocar dos resistencias de 120 ohms y no 3 como tu lo tienes. Y esas resistencias debe estar colocadas solamente en los extremos de la red. Ahora bien, cada circuito con bus RS-485 debe habilitar su modo de comunicacion. Es decir cada circuito debe habilitar si se coloca en modo de recepcion o en modo de transmision. Por lo que los inversores no debe de utilizarse, ya que la idea del RS-485 es poder lograr distancias hasta de 1 km (y ovbiamente llevar la senial del inversor a nivel TTL por 1 km, no funcionaria).

Para controlar el transceiver en la PC tienes que hacer uso del RTS y mediante tu software controlar ese pin, asi puedes colocar la PC en modo e recepcion o transmision.
Otro detalle que veo es que no tienes el convertidor RS-232 del lado de la PC, esto es porque el MAX487 opera en niveles TTL, por lo que primero necesitas cambiar el nivel RS-232 que hay en puerto serial de la computadora para asi tener niveles TTL y despues entonces si usarl el MAX487 (esto es solo en el lado de la PC, en el caso de los PIC no es necesario).

En cuanto al protocolo de cominucacion, regularmente el RS-485 se usa en modo MASTER-SLAVE (Maestro-Esclavo). Lo que significa que alguin debe inicial la comunicacion, en tu caso tal vez sea la PC. Para lograr esto puedes usar varios tipos de protocolo, uno de los que yo he usado es la deteccion de direccion, para ello a cada modulo colcado en la Red le asigno una direccion que puede ser de 8 o 9 bits, con nueve bits es la mejor opcion. Explico por que:

Al usar 9 bits de datos en el frame serial en lugar del 8 bits, tienes la posibilidad de generar una interrupcion en los micros cuando el noveno bit es un uno, (por lo que todos los frmaes que contenga el noveno bit = 1, seran direcciones), y entonces el micro leera la direccion y si corresponde a su direccion asignada el modulo corrrespondiente estara listo para establecer la comunicacion con el master. De ahi en delante toda la comunicacion se hace con el noveno bit = 0, de esta manera todos los frames con el noveno bit en cero serna considerados datos.

Tambien puedes usar direcciones de 8 bits pero el protocolo seria un poquito mas detallado. Para ello tendrias que hacer un protocolo similar a esto, pudiendo tu desarrollarlo a tu manera:

BYTE                                                  Valor hexadecimal                         Descripcion
STX                                                             02h                                   Inicio de transmision
ZZ                                                               ZZ                                   Longitud de la cadena
XX                                                               XX                                  Direccion de fuente
YY                                                               YY                                  Direccion destino
D0                                                                                                       Dato 0
D1                                                                                                       Dato1
.
.
.
Dn                                                                                                       Dato n
ETX                                                           03h                                    Fin de transmision

Tambien puedes agregar algun metodo de checsum a la cadena para verificar la integridad de los datos recibidos.

Todo lo anterior que te he mencionado es para una comunicacion Half-duplex, en modo Maestro-Esclavo.

En el cado de que requieras que cualquier dispositivo inicio una comunicacion con cualquir otro dispositvo, debes verificar que el bus esta libre, lo que se conoce como bus idle. Esto ya complica bastante las cosas, yo nunca lo he hecho asi, pero por lo que se se complica el asunto por lo de la deteccion del bus libre.

Saludos y espero haberte ayudado un poquito con esto del RS-485.

Elreypic.

Desconectado navaismo

  • Jubilado Todopic
  • PIC24H
  • ****
  • Mensajes: 1973
Re: Dudas con el RS485
« Respuesta #2 en: 02 de Abril de 2008, 12:32:54 »
Si de verdad que me has ayudado o abierto los ojos y com veras en mucjas cuestiones no soy nada master creo que el honor es mio por recibir tan excelente y consisa respuesta; además de los consejos. Gracias y los pondre en practica.
"Mi tercer deseo, que otra cosa podría ser, poner un final a todo el sufrimiento, que sólo con mi propia extinción el planeta podrá ser aliviado. Pobre de mí, Si tuviera tres deseos hoy, la elección no sería dificil para mí, Sólo tres deseos serían suficientes, No tendría uso para más."

"He sido un hombre que busca y aun lo sigo siendo, pero ya no busco en las estrellas y en los libros, sino en las enseñanzas de mi sangre."

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Dudas con el RS485
« Respuesta #3 en: 02 de Abril de 2008, 18:27:20 »
Hola amigos ya por fin vuelvo a tener adsl, después de una semana ya la echaba de menos.

Después de lo que te comenta elreypic poco hay que añadir, como bien te dice esto es una comunicación bidireccional
por un único canal, por lo que solo uno puede estar en modo tx al tiempo que los de mas están en modo rx.
En mi caso para gobernar pequeños automatismos siempre he utilizado un pequeño protocolo que se puede complicar
mas o menos según la aplicación, este pequeño protocolo esta compuesto de una trama de datos bien estructurada,
numero de red (o grupo), numero de la placa destino, numero de la de inicio, numero de orden, comando, datos,
checsum y después una respuesta de recibido ok mas o menos compleja según la aplicación. El checsun puede ser
la suma de todos los datos de la trama.

Y detectar si la línea esta libre puede como: al ver que no se reciben datos, ya que los datos llegan a todas las
placas, si cada placa tiene como nombre un numero este mismo numero se puede tomar como retardo al envío de
los datos una vez que se envío una pequeña trama de aviso de transmisión, las otras placas al detectar actividad
esperaran un tiempo antes de intentar apropiarse del bus. Todas las placas llevan un contador interno que pasa a
Reset cada vez que detectan actividad en el bus.

En mi caso todas las placas podían ser master en un momento dado, pero es más fácil si una sola placa es la que
interroga a las de mas una por una.

Bueno esta es la forma en la que he resuelto los problemas, por supuesto no es la mejor pero me funciono bien.
« Última modificación: 02 de Abril de 2008, 18:30:45 por dogflu66 »
Saludos desde Granada, España.

Desconectado navaismo

  • Jubilado Todopic
  • PIC24H
  • ****
  • Mensajes: 1973
Re: Dudas con el RS485
« Respuesta #4 en: 02 de Abril de 2008, 19:36:33 »
Hombre, pues muchas gracias maestro Carlos eso complementado con lo de ElreyPic me ayuda mucho. Y si voy a probar sus metodos sobre todo la parte del checksum
"Mi tercer deseo, que otra cosa podría ser, poner un final a todo el sufrimiento, que sólo con mi propia extinción el planeta podrá ser aliviado. Pobre de mí, Si tuviera tres deseos hoy, la elección no sería dificil para mí, Sólo tres deseos serían suficientes, No tendría uso para más."

"He sido un hombre que busca y aun lo sigo siendo, pero ya no busco en las estrellas y en los libros, sino en las enseñanzas de mi sangre."

Desconectado Pic_lady

  • PIC10
  • *
  • Mensajes: 13
Re: Dudas con el RS485
« Respuesta #5 en: 31 de Mayo de 2008, 12:37:24 »
Tengo un problema relacionado con este tema, tengo un termometro digital y mediante el hyperterminal si le envío una letra mayuscula en particular me envia la temperatura y si le envio la misma letra minuscula es para introducir el set point. El 485 que va conectado al Pic tiene su linea de control conectada al mismo, y la que va junto al max232 a la PC se controla manualmente mediante un interruptor. Cuando le pido la temperatura me funciona bien, pero no me envía bien el retorno de linea y cambio de linea, solo me envía el  segundo que escriba de los dos. En cuanto al set point yo mando un mensaje al hyperterminal que dice algo como "Introduzca el set point" pero no me lo envía no se por que. Aqui esta una parte del codigo

INICIO:
                   call                   Cond_Iniciales
Principal:
         btfss      flagi,1
         goto      sigue
                   call                   Convertir
         bcf         flagi,1
                   call                   Mostrar
sigue:
                   call                   atencion_int
         call         comparar_temp_setpoint
                     goto               Principal
               
         
;********************************************************************
;--------------------------------------------------------------------
; Subrutinas...
;-------------------------------------------------------------------
INTERRUPCION:
         btfss      PIR1,RCIF
         goto      check_tmro_int
                   banksel            PIR1
                     bcf                PIR1,RCIF
                   bsf                flagi,0
                   movf               RCREG,w
                   movwf           Dato_recibido
         goto      salir_de_interrupcion

check_tmro_int:                   
         btfss      INTCON,T0IF
         goto      salir_de_interrupcion
         banksel      TMR0
         movlw      0x3C
         movwf      TMR0
         banksel      INTCON
         bcf         INTCON,T0IF
         incf         cuenta_convertir
         bcf         STATUS,C
         movf      cuenta_convertir,w
         sublw      0x28
         btfsc      STATUS,C
         goto      salir_de_interrupcion
         clrf         cuenta_convertir      
         bsf         flagi,1
         goto      salir_de_interrupcion
salir_de_interrupcion:                                         
                   movf               pclath_Anterior,w
                      movwf           PCLATH
                     movf               status_Anterior,w
                     movwf           STATUS
                   movf               w_Anterior,w

         retfie

;-------------------------------------------------------------------
atencion_int:
                   btfss              flagi,0
                   goto               volver 
                   bcf                   flagi,0       
                     movlw           0x60
                   bcf                STATUS,C
                   subwf              Dato_recibido,w
                   movwf           ID
                   movf               PORTA,w
                   andlw              b'00111100'
                   movwf           rest
                   bcf                STATUS,C
                   rrf                rest
                     rrf               rest,w
                   bcf                STATUS,Z
                   subwf              ID,w
                   btfss              STATUS,Z
                      goto               check_set_point
                   call                   CarryRet_USART
                   call                   NextLine_USART
                   call                  Enviar_temp
         goto      volver

check_set_point:
         bcf                   flagi,0
         movlw           0x40
                   bcf                STATUS,C
                   subwf              Dato_recibido,w
                   movwf           ID
                   movf               PORTA,w
                   andlw              b'00111100'
                   movwf           rest
                   bcf                STATUS,C
                   rrf                rest
                     rrf               rest,w
                   bcf                STATUS,Z
                   subwf              ID,w
                   btfss              STATUS,Z
                      goto                  volver
                   call                   CarryRet_USART
                   call                   NextLine_USART   
         clrf         puntero   
         call         mensaje_serial
         call                   CarryRet_USART
                   call                   NextLine_USART
         call         tomar_set_point
         goto      volver

tomar_set_point:
         movlw      0x20
         movwf      FSR
         bcf         PIE1,RCIE
         bcf         INTCON,T0IE
ciclo_set:
         btfss      PIR1,RCIF
         goto      ciclo_set
         bcf         PIR1,RCIF
         bcf         STATUS,C
         movf      Dato_recibido,w
         sublw      0x40
         btfss      STATUS,C
         goto      ciclo_set

         bcf         STATUS,Z
         movf      Dato_recibido,w
         xorlw      0x0D
         btfsc      STATUS,Z
         goto      limpiar_flag

         bcf         STATUS,Z
         movf      Dato_recibido,w
         xorlw      0x2E
         btfss      STATUS,Z
         goto      sigue_set1
         movf      Dato_recibido,w
         call                   DatoUSART_Tx
         goto      ciclo_set
sigue_set1:   
         movf      Dato_recibido,w
         call                   DatoUSART_Tx
         movlw      0x30
         bcf         STATUS,C
         subwf      Dato_recibido,w
         movwf      INDF
         incf         FSR
         movf      FSR,w
         bcf         STATUS,Z
         xorlw      0x23
         btfsc      STATUS,Z
         goto      limpiar_flag
         goto      ciclo_set
limpiar_flag:
         bcf         flagset,0
         call                   CarryRet_USART
                   call                   NextLine_USART
         bsf         PIE1,RCIE
         bsf         INTCON,T0IE
         return

volver:            return

Enviar_temp
         bsf         Control_pin
                   call               Retardo   
         movlw           0x30
                   addwf              ID,f
                      movlw           'T'
                   call                   DatoUSART_Tx
                   movlw           '#'
                   call                   DatoUSART_Tx
                   movf              ID,w
                   call                   DatoUSART_Tx
                   movlw           ':'
                   call                   DatoUSART_Tx
                   movlw           ' '
                   call                   DatoUSART_Tx
                   movf               DIGIT5,w
                      addlw              0x30
                   call                   DatoUSART_Tx
                   movf               DIGIT4,w
                   addlw              0x30
                   call                   DatoUSART_Tx
                   movlw           '.'
                   call                   DatoUSART_Tx
                   movf               DIGIT3,w
                   addlw              0x30
                   call                   DatoUSART_Tx   
                   Movlw              ' '
                   call                   DatoUSART_Tx
                   Movlw              'C'
                   call                   DatoUSART_Tx
         bcf         Control_pin
                   return
      
mensaje_serial:
            movlw         LOW(Tablaset_point)
            movwf         Offset_L
            movlw         HIGH(Tablaset_point)
            movwf         Offset_H

            movf         puntero,w         
            addwf         Offset_L,f
            btfss         STATUS,Z
            goto         $+3

            movlw         .1
            addwf         Offset_H,f
      
            movf         Offset_H,w
            movwf         PCLATH

            movf         puntero,w
            Lcall         Tablaset_point
            movwf         var
            movlw         0x00
            addwf         var
            btfsc         STATUS,Z
            goto         salir_mensaje
            movf         var,w
            call            DatoUSART_Tx
            incf            puntero      
            goto         mensaje_serial
salir_mensaje:
         return

Tablaset_point:      
            addwf      PCL,f
tablaset:         EQU      $            
            DT         " Introduzca el set point entre 40 y 90 ",0x00

Desconectado navaismo

  • Jubilado Todopic
  • PIC24H
  • ****
  • Mensajes: 1973
Re: Dudas con el RS485
« Respuesta #6 en: 31 de Mayo de 2008, 12:42:27 »
Creo que te ayudarian mas en el subforo de Assembler, aqui solo manejamos BASIC, sorry.
"Mi tercer deseo, que otra cosa podría ser, poner un final a todo el sufrimiento, que sólo con mi propia extinción el planeta podrá ser aliviado. Pobre de mí, Si tuviera tres deseos hoy, la elección no sería dificil para mí, Sólo tres deseos serían suficientes, No tendría uso para más."

"He sido un hombre que busca y aun lo sigo siendo, pero ya no busco en las estrellas y en los libros, sino en las enseñanzas de mi sangre."

Desconectado andresgil466

  • PIC10
  • *
  • Mensajes: 1
Re: Dudas con el RS485
« Respuesta #7 en: 18 de Junio de 2008, 11:50:07 »
Hola soy nuevo en este tema del RS485 y quiero conectar 2 o mas tarjetas cada una con un pic16f628a y displays lcd de 4X20 a un computador para enviarle mensajes desde el pc a cada lcd, segun el estado de cada tarjeta si esta cerrado abierto o en timbre. Me gustaria saber si me pueden colaborar con el arranque del codigo para el manejo de las tramas ya que el hardware ya esta diseñado y me estan pidiendo la implementacion del codigo. Gracias.

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re: Dudas con el RS485
« Respuesta #8 en: 18 de Junio de 2008, 13:01:24 »
Que tal andresgil466,

Bienvenido al foro. En cuanto ayudarte a hacer el codigo lo podemos hacer, pero tu tienes que empezar con algo. Este no es foro de haganlo por mi. Ahora que si lo que quieres es que alguien te desarrolle todo tu codigo, con gusto puedo ayudarte, pero claro esta que tendria un costo.

Espero no ofenderte en ninguna manera, pero asi son las reglas del foro, que por cierto te invito a pasar a leer, para que no cometas alguna violacion al mismo y algun moderador te llame la atencion.

Saludos y esperamos tu respuesta.

Elreypic.