Reflexiones en cable con MAX485

Hola a todos, estoy desarrollando una aplicación la cual hace uso de tres cosas, una arduino que actua como master y dos pics que actúan como esclavos. El arduino interroga a los pics y estos responden. Cada pic tiene su propia ID. El tema de escribir y lee está tal cual dice el datasheet del MAX485.

El PROBLEMA que tengo es que cuando solo conecto en el bus un master y un esclavo todo va bien. En cuanto conecto otro esclavo la cosa cambia. El sistema hace cosas raras. A veces solo contesta al primer pic al que le solicito respuesta y el otro no contesta o viceversa.

He puesto la resistencia esa que especifica de 120ohms al inicio y al final del bus y utilizo un cable par trenzado (1m). Yo creo que el problema puede ser por tema de reflexión en el cable o algo. Como podría solucionar ésto? Es urgente...


GRACIASS
 

Adjuntos

  • EsquemaUsoMax485PICS.rar
    6.1 KB · Visitas: 13
Si ambos esclavos funcionan bien independientes con el master. Creo yo que tienes un problema de código...

Yo sacaría q resistencia de 120 dejaría una sola al final del bus

Y solo en el master pondria A a pullup con ina res de 4k7 y B a pulldown con 4k7

Algo así. .
587651968_562.JPG
 
Última edición:
Si ambos esclavos funcionan bien independientes con el master. Creo yo que tienes un problema de código...

Yo sacaría q resistencia de 120 dejaría una sola al final del bus

Y solo en el master pondria A a pullup con ina res de 4k7 y B a pulldown con 4k7

Algo así. .
http://i00.i.aliimg.com/img/pb/968/651/587/587651968_562.JPG

Te puedo adjuntar el código que utiliza uno de los esclavos. El código es el mismo para los dos esclavo excepto la ID de cada uno que será P01 o P02.

Si puedes héchale un vistazo porque estoy muy desesperado con éste tema. Utilizo el pin B0 para control (RE/DE) si quieres mirate la función "enviar()" es donde realizo los envios de datos y allí se controla el pin B0.

Gracias por tu respuesta amigo.

Código:
#include <16f870.h> 
#device ADC=10 
//#fuses NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT, INTRC_IO  
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
//#use delay (internal=8MHz) 
#use delay (clock=8MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) //CONFIGURO PUERTO SERIE         
//#use RS232(UART1, ERRORS) 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 


//**VARIABLES PARA GESTIONAR LA TRAMA RECIBIDA Y LA TRAMA A ENVIAR POR PUERTO SERIE**//
long valor_adc=0; //Variable de 16 bits para lectura ADC 

int P_W=0; //indice escritura
int P_R=0; //indice lectura

int i=0; 
int j=0;

int inicio=0;
int final=0;

char string_valor_adc[5]="0000";//Cadena de caracteres para guardar valor ADC en Carcteres
char trama_entrada[51]={0}; //String para guardar el dato de entrada por UART

char direccion_pic[4]="P02";
char tipo_dato[5]="$ADQ";
char canal[4]="CH0";
char dato[14]="$ADQ,P02,CH0\r";

char miretorno[2]="\r"; 
char misimbolo[2]="$"; 

short flag_final=0;
short flag_permiso=0;
short flag_tst=0;
short flag_envio=0;

//FUNCIÓN PARA LEER LOS DATOS PROCEDENTES DEL PUERTO SERIE//
void lectura(){
 for(P_R=0; P_R<51; P_R++){
  if(trama_entrada[P_R]==misimbolo[0]){
  inicio=P_R;
    for(P_R=inicio; P_R<51; P_R++){
    if(trama_entrada[P_R]==miretorno[0]){
    P_W=0;
    final=P_R;
    flag_permiso=1;
    break;
    }
   }
   break;
  }
 }
}

//FUNCIÓN PARA COPIAR EL DATO PROCEDENTE DEL BUFFER DEL PUERTO SERIE//
void escritura(){

 for(i=inicio; i<=final; i++){ 
     dato[j]=trama_entrada[i];
     j++;}
 i=0;
 j=0;
memset(trama_entrada, 0, sizeof(trama_entrada));
return;
}

//FUNCIÓN PARA PROCESAMIENTO DEL DATO PROCEDENTE DEL PUERTO SERIE//
void procesamiento(){

//Se copia la dirección de la solicitud para saber a qué pic  va dirigido//
//Éste pic tiene la dirección "P01"//
for(i=0; i<3; i++){
    direccion_pic[i]=dato[i+5];}
    direccion_pic[3]='\0';

//Se compara la dirección obtenida con la de éste pic//
if(strcmp(direccion_pic, (char*)"P02")==0){
  memset(direccion_pic, 0, sizeof(direccion_pic));

  //Se copia el tipo de dato que puede ser "$ADQ" o "$TST"//
  for(i=0; i<4; i++){
     tipo_dato[i]=dato[i];}
     tipo_dato[4]='\0';

  //Se compara el tipo de dato con "$ADQ" que es para obtener medidas del ADC//
  if(strcmp(tipo_dato, (char*)"$ADQ")==0){
     memset(tipo_dato, 0, sizeof(tipo_dato));
     flag_tst=0;//flag para el case de la función enviar

   //Se copia el canal para ver qué canal se quiere escoger "CH0" o "CH1"//
     for(i=0; i<3; i++){
        canal[i]=dato[i+9];}
        canal[3]='\0';

    //Se compara el canal//
     if(strcmp(canal,(char*)"CH0")==0){
        set_adc_channel(0);}
  
     else if(strcmp(canal,(char*)"CH1")==0){ 
        set_adc_channel(1);}

   //Lectura del ADC//
     delay_us(20);//retardo para leer ADC
     valor_adc=read_adc();//lectura ADC
     sprintf(string_valor_adc,"%04ld",valor_adc);
   }

  //Se compara el tipo de dato con "$TST" que es para que éste pic responda con "$TST,P01\r"//
   else if(strcmp(tipo_dato,(char*)"$TST")==0){
       memset(tipo_dato, 0, sizeof(tipo_dato));
       flag_tst=1;
   }
  //Se da permiso para enviar dato//
  flag_envio=1;//flag para el case de la función enviar
}

return;

}


void enviar(){

switch(flag_tst){

 case 0:

   output_high(PIN_B0);
   delay_ms(3);
   printf("$ADQ,P02,%s,%s\r", canal,string_valor_adc); 
   delay_ms(3);
   output_low(PIN_B0);

  break;
  

 case 1:

   output_high(PIN_B0); 
   delay_ms(3);
   printf("$TST,P02\r"); 
   delay_ms(3);
   output_low(PIN_B0);

   flag_tst=0;

  break;

  }

return;

}



void main(){

 output_low(PIN_B0);
 output_high(PIN_C4); 
 disable_interrupts(INT_RDA);
 enable_interrupts(GLOBAL); //HABIlLITO TODAS LAS INTERRUPCIONES GLOBALES
 enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
 setup_adc_ports(ALL_ANALOG); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA 
 setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC

 while(1){

output_high(PIN_C4); 
delay_ms(1000);
output_low(PIN_C4);
delay_ms(1000); 
if(flag_final==1){
   flag_final=0;
   lectura();

   if(flag_permiso==1){
    flag_permiso=0;
    escritura();
    procesamiento();

      if(flag_envio==1){
       flag_envio=0;
       enviar();
       
      }
     }
    }
   }
  }



#INT_RDA

void INT_UART(void) {

  trama_entrada[P_W]=getc();

  if(trama_entrada[P_W]=='\r'){
     P_W=0;
     flag_final=1;
   }

  else{
     P_W++;

     if(P_W >=21 ){
       P_W=0;
      }
   }
}
 
Creo que el problema de mi código es que cuando le llega un dato que no es el suyo se queda en un estado "loco" creo que el problema podría estar justo aquí:

if(strcmp(direccion_pic, (char*)"P02")==0){...

Es decir mi programa compara si la dirección del dato llegado por el puerto serie coincide con su dirección... es como si se quedara "loco" cuando le llega un dato que no es para el.
 
Atrás
Arriba