Comunicación RS-485 PIC C CCS

Buen día amigos del foro me dirijo a ustedes que son mi única ayuda en este momento ya que lo he intentado todo.
es lo siguiente:

1. necesito realizar una comunicación entre un pic maestro y varios pic esclavos por medio de rs485 en ccs ya que este protocolo permite definir unos ID para cada pic y de esta forma se pregunta al pic la informacion deseada por su ID que lo identifica.
2. el rs485 es la comunicación que me sirve debido a sus características de distancia y que el ruido no la afecta.
por el momento solo quiero prender un led cuando mi pic esclavo reciva el dato de mi pic maestro.
3. estos codigos no me funcionan y no se porque.

este es el codigo del maestro:

Código:
#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use RS232(baud=9600,xmit=PIN_D1,rcv=PIN_D2,stream= PC)


#define  RS485_ID 0x20  //ID de identificacion en la red
#include <rs485.c>
#use standard_io(C)
#use standard_io(D)

#include <stdio.h>
#include <stdlib.h>
#include <input.c>
#byte port_a=5
#byte port_b=6
#byte port_e=9

int8 dato;
char data;
void main()
{   
    set_tris_a(0x00);
    set_tris_b(0xFF);
     set_tris_e(0x00);
     
     port_a=0x00;
     port_b=0x00;
     port_e=0x00;
     rs485_init();


  
  while(true)
            {

            data=getc(PC);//recibe dato que envia el pc por rs232
             
             if(data==\'1\') 
                                { 
                                dato=1;//dato que envio
                                output_high(PIN_D0);// pongo en alto para transmitir
                                delay_ms(30);
                                rs485_wait_for_bus(FALSE); 
                                rs485_send_message(0x40,8,dato); // linea que envia al pic que tiene el ID 0x40 y envia el dato #1
                                }
              
          }
}


Este seria el codigo del esclavo:

Código:
#include <16f877a.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#define  RS485_ID 0x40
#include <rs485.c>

#use standard_io(C)
#use standard_io(D)
#include <stdio.h>
#include <stdlib.h>

#byte port_a=5
#byte port_b=6
#byte port_e=9

int dato;


void main()
{   
     set_tris_a(0x00);
     set_tris_b(0x00);
     set_tris_e(0x00);
    
     port_a=0x00;
     port_b=0x00;
     port_e=0x00;
     rs485_init();
     output_low(pin_D0); // pongo en bajo para recibir
  while(true)
            {
                        if(rs485_get_message(dato,0))
                        {
                           output_high(pin_E0);
                           delay_ms(1500);
                           output_low(pin_E0);
                       
                        }
           
            }
      
}

voy a subir imagenes de mi circuito. ...

este es la imagen de mi sistema
 

Adjuntos

  • rs485.zip
    27.7 KB · Visitas: 178
Última edición por un moderador:
Bien, amigo. No me envía el dato y el esclavo no hace nada.

Sigo probando diferentes códigos y no me envía datos el maestro.
 
Última edición por un moderador:
Hola, fijate en la sentencia if ( data==\'1\'), quizás haya un error. Porque utilizas \' en lugar de ' ?
Además que pines utilizas en la transmisión de RS485?
Están configurados cómo salida?
 
Última edición:
gudino, si yo lo tengo como lo dices '1' esta parte me funciona, y los pines estan declarados en la libreria que yo llamo arriba #include<rs485.c>. al momento de subir el codigo no subio del todo con los simbolos.
 
Cuando no se envuelve el código con las etiquetas CODE o PHP, algunos navegadores colocan símbolos HTML.
Esto afecta el código y es por eso que se recomienda que el código sea envuelto antes de ser publicado.

Busca el ejemplo "ex_rs485.c" que viene incluido con PIC Compiler de CCS.
Se encuentra en la carpeta "Examples" en donde está instalado el compilador.
Es muy similar a lo que requieres y seguramente te servirá de orientación.
 
gracias amigo d@rbytes por tu aporte, ya estuve analizando este ejemplo pero no me sirve porque lo que hace es convertir datos RS485 y los pone en línea de datos RS232.
yo necesito es declararle un id a cada pic16f877, para que cuando el maestro le envié un dato a un pic en especifico este pic haga la tarea y devuelva un dato de confirmación.
 
Me parece que si te puede servir ese ejemplo ya que si existe comunicación RS-485 de PIC a PIC.
Obviamente tienes que realizar algunos cambios.

Sí se usa RS-232 como medio de comunicación entre usuario y microcontrolador, pero los datos ingresados del usuario por RS-232, son enviados por RS-485 hacia cada PIC.
Ese ejemplo es como un chat entre microcontroladores, por lo tanto ambos reciben y transmiten hacia un ID específico.

No tengo experiencia sobre éste protocolo, pero lo que necesitas es interceptar los datos RS-485.
Cuando un comando es válido, entonces se activa el Timer 1 y los datos RS-485 se reciben por interrupción externa, que en éste ejemplo es por RB0.

Adjunto el programa con simulación porque me pareció interesante el funcionamiento. :)

El funcionamiento es el siguiente:
Al principio los microcontroladores se deben identificar con algún ID.
Cada uno pedirá el ingreso de un ID de red y se valida presionando la tecla "Enter".
A continuación se escribe la letra "c" (Change Address) para ingresar el ID de destino.
Cuando ambos estén configurados, se envía en cualquiera de ellos el comando "s" (Sin comillas)
Si no se ha ingresado un ID de destino, el microcontrolador en cuestión lo pedirá.
En seguida aparecerá por la terminal RS-232, lo siguiente: (ID):>
(Donde ID será el identificador de destino)
Ésto quiere decir que el microcontrolador está listo para enviar datos.
Se escribe cualquier tipo de mensaje y se presiona la tecla "Enter"
Una vez enviados los datos, el microcontrolador queda nuevamente en espera de comandos.
En ambos microcontroladores se debe realizar el mismo procedimiento.

Los comandos están descritos en el programa y se obtienen por RS-232 al ingresar el comando "h".

Nota:
Programa compilado con PIC C Compiler de CCS v 5.048 (PCWHD) y simuladores ISIS v7.10 y v8.1 de Proteus.

Suerte.
 

Adjuntos

  • Prueba RS-485.jpg
    Prueba RS-485.jpg
    114.8 KB · Visitas: 351
  • 16F628A ex-RS485.rar
    88.6 KB · Visitas: 514
Última edición:
buen dia darkbytes, realice el circuito en proteus tal como esta en la foto y le cargue los archivos y me corrio pero no tuve comunicacion realice los pasos como tal me los explicaste en el foro pero solo pregunta los id les pongo el mismo pero no me deja escribir en los virtual terminal. aqui adjunto la imagen.
agradesco su ayuda y aporte a este tema que es muy interesante ya que en la red hay varios con este mismo problema de comunicacion de rs485 con id. :confused:
 

Adjuntos

  • Nuevo Archivo WinZip.zip
    56.7 KB · Visitas: 102
Te recomiendo que no realices otro diseño y mejor abras cualquiera de los dos que adjunté.
Esto es porque se tienen que configurar las resistencias del bus de enlace de forma diferente.
R3 debe ser digital, R4, R6, R7 y R8 deben excluirse, y R5 debe ser análoga.

Si tienes Proteus 8.0, y no puedes abrir el que adjunto, (8.1) puedes abrir el diseño v7.10.
Pero debes abrir proteus y en el menú File, seleccionas: "Open Project"
En la ventana de búsqueda que aparecerá, en las propiedades "Tipo" debes seleccionar "Design Files"
Con eso ya puedes abrir versiones anteriores a la 8.XX y cuando se guarden, se guardarán con el mismo nombre pero con la extensión ".pdsprj" y para la versión que tengas.

Nota:
Lo que se escribe no se ve, a menos que en la terminal se seleccione "Echo Typed Characters"
Una vez listo el mensaje, se debe presionar la tecla "Enter" para que se envíe.
Si se quiere seguir enviando mensajes, otra vez se debe enviar el comando "s"
 
Bien amigo D@rkbytes. Que excelente ayuda, si me funcionó el chat ya con estos pasos que me explicó.

Tengo una pregunta. ¿Dónde se definen los pines que van conectados al max487?
Ya que yo revisé la librería RS485.c y tienen otros pines de conexión para el max con el PIC.
En el programa tampoco veo donde los definen debido a que yo quiero utilizar un PIC más grande como el 16F877A.

Otra pregunta. ¿En el montaje real, o sea físico qué resistencias entonces se usan cuando en proteus son digitales, en el caso de R8 y R6 que se debe hacer?
Eso sí no lo sabía.

:aplauso::aplauso: Muchas gracias por su ayuda.
 
Última edición por un moderador:
Tengo una pregunta. ¿Dónde se definen los pines que van conectados al max487?
Ya que yo revisé la librería RS485.c y tienen otros pines de conexión para el max con el PIC.
En el programa tampoco veo donde los definen debido a que yo quiero utilizar un PIC más grande como el 16F877A.
Se usan las definiciones de la librería RS485.C, pero para definir otros pines, se debe realizar la definición en la cabecera del programa y antes de incluir la librería.

Por ejemplo:
#define RS485_RX_PIN PIN_C1
#define RS485_TX_PIN PIN_C2
#include <rs485.c>
Otra pregunta. ¿En el montaje real, o sea físico qué resistencias entonces se usan cuando en proteus son digitales, en el caso de R8 y R6 que se debe hacer?
Eso sí no lo sabía.
Las resistencias las puse basándome en un esquema que encontré.
No he realizado éste tipo de conexión, pero sé que es con cable trenzado.
Más información la puedes obtener aquí en el Foro o buscando en Google.
:aplauso::aplauso: Muchas gracias por su ayuda.
De nada. Suerte. (y)
 
Bien, amigo D@rkbytes. El código funciona muy bien en el PIC16F628A, pero al momento que cambio de PIC al 16F877A y armo el circuito en proteus con las resistencias análogas y digitales, y cargo el mismo código y conecto en los mismos pines, no funciona.
¿Usted sabe por qué será esta falla, si utilizo el mismo código?
Lo que cambio es la librería del PIC y armo el mismo circuito con los componentes.
 
Última edición por un moderador:
Seguramente conectaste algo mal.

Adjunto el mismo ejemplo funcionando, pero con 2 PIC16F877A.

PD: Únicamente modifiqué el programa y las conexiones para usar el módulo USART.
Antes:
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, stream=PC)
Ahora:
#use rs232(UART1, stream=PC)
// Configuración por defecto: 9600, 8, N, 1

Ya en tu proyecto debes hacer pruebas con la definición de pines que quieras usar.
 

Adjuntos

  • 16F877A ex-RS485.rar
    96.5 KB · Visitas: 341
BUENAS NOCHES
AMIGO D@RKBYTES
muy agradecido por el circuito que me adjuntas funciono a la perfección y quedo en deuda ya que he avanzado el dia de hoy bastante en mi sistema.:aplauso::aplauso:

Tengo una falla:
la verdad no entiendo porque cuando quiero cambiar para para trabajar con otro pic no me funciona en este caso es con el pic18f4685 como maestro y el pic16f877a como esclavo, te explico porque la insistencia de cambiar de pic's:
Es porque el pic maestro me va a manejar muchas instrucciones que le llegan desde un computador y este pic maestro debe tener excelentes características como por ejemplo (96KB code,3328B data, 1024 EEPROM) como las tiene el pic 18f4685 ,y el pic16f877a ya se me lleno con pocas instrucciones y me quede corto intente de varias formas conectar mi nuevo pic maestro y no me funciona.

gracias si me puede ayudar a solucionar este inconveniente ya que es la única persona que me ha ayudado y muy buena su ayuda.(y)

adjunto como va mi sistema.

esta es la imagen de como voy con mi sistema y yo se que les voy a ayudar a muchas personas a solucionar este tema de comunicación con rs485.



tengo otro inconveniente de que cuando el esclavo retorna datos al maestro no retorna el dato completo.
envia 0, y yo le estoy diciendo que envie 0,100. de pronto tiene idea del porque.



este es un video donde explico mi ultimo problema. para que me ayuden.:confused:
 

Adjuntos

  • circuito de 1 maestro y 2 esclavos.zip
    26.8 KB · Visitas: 252
  • video1.zip
    5 MB · Visitas: 117
Última edición:
Necesitas leer la hoja de datos del PIC18F4685 para elegir la palabra de configuración correcta, las características de los puertos y también de los registros.
Prácticamente todos los PIC de gama alta pueden ejecutar programas de PIC's de gama media, pero es necesario estudiar la hoja de datos para obtener la configuración adecuada.

Sobre el envío y recepción de datos; debe ser porque no se pueden enviar datos del tipo Float.
Prueba enviado sólo Bytes, y no valores con decimales.

¿Y ese vídeo con extensión .camrec, con qué se abre?
Mejor sube el vídeo en formato AVI, también comprimido dentro de un archivo .ZIP o .RAR
 
Buenos dias
aqui adjunto mi video.

como hago para capturar el dato que me envía el esclavo, ya que solo necesitaría compararlo con un if(datoesclavo==0) haga tal proceso.
pero es que el maestro lo captura en msg[32] y no se como convertir este dato.



para compararlo en un if()



otra pregunta estas resistencias que tienen los max487 se colocan solo al principio i al final de la red por lo que he leido, sera que me puedes confirmar si tiene conocimiento.

Necesitas leer la hoja de datos del PIC18F4685 para elegir la palabra de configuración correcta, las características de los puertos y también de los registros.

no entiendo lo de la palabra correcta donde veo esta palabra, la configuracion tengo la mismos pines que en el pic16f877a y no me funciona, de casualidad no tienes un ejemplo con estos pic 18f4685 como maestro y pic16f877a como esclavo que me ayudes. :apreton:
 

Adjuntos

  • video sistema.zip
    2.4 MB · Visitas: 96
Última edición por un moderador:
Necesitas estudiar bien sobre lo que quieres hacer para que adquieras más conocimientos.
Lo de la palabra de configuración, son los fuses que necesita el PIC para determinar el tipo de oscilador, la habilitación o no del Watch Dog Timer, la protección de código y datos, entre otras cosas más.
Busca sobre eso o consúltalo en la hoja de datos. (Configuration Word)

Y no, no tengo ejemplos con ese PIC, porque de hecho, esos que subí son los únicos y son los de CCS.
 
aqui adjunto un video de lo que presenta mi pic 18f4685 cuando envio un dato. el pic muestra en osciloscopio una trama muy rara. en este video aparece es el pic 18f2620 es que estaba probando porque ya me daba por vencido con mi pic18f4685, entonces decidi probar con otro pero se me presento la misma falla con este otro pic. pero la idea es que me funcione con el pic18f4685 por sus exelentes caracteristicas de almacenamiento.



Bien listo voy a seguir probando haber hasta que logre que me funcione.
 
Última edición:
hola a todos tengo una duda, ya realice una comunicacion entre dos pic con la configuración
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
y los pases de datos los realizo con put() y los capturo con el get() todo esto en pic c.
La comunicación entre los pic es buena. Pero ahí puntos en el programa justo después de un envío de datos que tengo delay para realizar un retardo como para darle tiempo a uno de los pic para que realice la tarea y estén sincronizado uno del otro.
Como quiero mejora esto, estoy en busca de la mejor practica para realizar una comunicación fluida entre pic sin ningún tipo de delay y me tope con la función I2C y realizando estudios a diferentes ejemplo en la web encontré que ahí ocasiones que también tiene delay y no se si esto es correcto

me pueden decir cual seria la mejor forma de manejar una comunicación entre pic en PICc ?
 
Última edición:
Atrás
Arriba