Robot - Bus 485

Hola, todo bien?
Les cuento que estoy realizando mi proyecto de grado y el mismo consiste en la construcción de un robot autónomo, controlarlo y diseñar su "inteligencia".

Para la parte de sensores decidimos basarnos en un bus 485. Tenemos el rabbit que manda a través de la librería Packet al bus 485 y 4 pics esclavos que interrumpen al recibir un mensaje y si es para ellos responden. Utilizo max 485 como transceivers en el maestro y cada nodo.

Logré comunicar el rabbit con un pic y anda perfecto (lo chequeo mediante un 232 desde el rabbit que me muestra la respuesta del PIC).

Al conectar otro transceiver y pic al bus con el mismo programa no logro obtener respuesta.
Es como que la conexión interfiere en la comunicación. El pic nùmero 2 posee un programa similar al pic 1 salvo que tiene una dirección de esclavo distinta por lo que no pueden estar ocupando el bus al mismo tiempo.

A alguien se le ocurre que puede estar pasando?

Leyendo un poco más ví que existe una distancia mínima entre nodos y vi una fórmula que la calcula pero no se como calcular las capacitancias que me pide. Por ahora los nodos están a 4 cm uno del otro. (No podría ser mayor la distancia porque aumentaría el tamaño del robot al ponerle más sensores y no es posible eso).

Probé con resistencias de terminación de 120 ohm y no me funciona para nada... Sin ellas el pic 1 contesta bien como expliqué recien...
 
Muchas gracias! Justo la parte que explicas software falta...
Al parecer me anda del rabbit al pic pero la respuesta del Pic no llega bien, es un tema de software creo...
 
Acabo de fijarme y agreguè las resistencias para ver si funciona... Es raro porque seùn que funciòn de lectura de puerto serial utilice anda "mejor"...
Mira uso interrupciones en el pic...
Te muestro los còdigos:

RABBIT

Código:
#define DIR_PIC_1 1


#define START_RABBIT 0x0F
#define START_PIC 0xD2

//DEFINES PARA SENSORES (funcion)
#define PRENDO_LED 0x01
#define APAGO_LED 0x10

//DEFINES PARA SENSORES (datos)
#define DATOS_NULL 0xFF

//DEFINES DE RESPUESTA DE SENSORES
#define RESPUESTA_OK 0x77
#define RESPUESTA_NULL 0x33

//Encabezado de funciones utilizadas

void rx_max485(void);
void tx_max485(void);

//Variables globales

//PROTOCOLO
char mensaje_in[5];
char mensaje_out[5];

char funcion;
char datos;
char flag;



//motores
char instruccion_motor1[6];
char instruccion_motor2[6];
char bytes_rcv;




void main()											//Función principal
{
	//Declaracíon de variables

	char flag;
	char flag_checksum;

   char bytes;

   bytes_rcv = 0;

	flag = 0;
	flag_checksum = 0;


	BitWrPortI(PFDDR, &PFDDRShadow, 1, 0);
	BitWrPortI(PFDDR, &PFDDRShadow, 1, 1);			//Declaración del bit 1 del puerto F del rabbit como salida
	BitWrPortI(PFDDR, &PFDDRShadow, 1, 4);			//Declaración del bit 4 del puerto F del rabbit como salida
	BitWrPortI(PFDDR, &PFDDRShadow, 1, 5);			//Declaración del bit 5 del puerto F del rabbit como salida
	BitWrPortI(PFDDR, &PFDDRShadow, 1, 6);			//Declaración del bit 6 del puerto F del rabbit como salida
	BitWrPortI(PFDDR, &PFDDRShadow, 1, 7);			//Declaración del bit 7 del puerto F del rabbit como salida

	//BitWrPortI(PCDDR, &PCDDRShadow, 1, 2);
    //BitWrPortI(PCDDR, &PCDDRShadow, 0, 3);
    BitWrPortI(PEDDR, &PEDDRShadow, 1, 7);


   serCopen ( 9600 );							//Apertura del puerto serial A para comunicarse con el PC
   serCrdFlush();

  	serAopen ( 9600 );							//Apertura del puerto serial A para comunicarse con el PC
   serArdFlush();


	while(1)										//Loop infinito
	{
		costate										//Coestado que se encarga de la lectura de los sensores
		{

 //PIC 1
       waitfor(DelayMs(600));               //INICIALIZACION DE SENSORES

 		if (flag == 0)
			{
            	mensaje_out[0] = START_RABBIT;
  					mensaje_out[1] = DIR_PIC_1;
  					mensaje_out[2] = PRENDO_LED;
 					mensaje_out[3] = DATOS_NULL;
 					mensaje_out[4] = 1;

			 		flag = 1;
			}
			else
			{
            	mensaje_out[0] = START_RABBIT;
  					mensaje_out[1] = DIR_PIC_1;
  					mensaje_out[2] = APAGO_LED;
  					mensaje_out[3] = DATOS_NULL;
 					mensaje_out[4] = 1;

           		 flag = 0;
			}


         tx_max485();
			wfd cof_serCwrite(&mensaje_out[0], 5);
         rx_max485();

		}

//RESPUESTAS

costate
{


            wfd bytes_rcv = cof_serCread(&mensaje_in[0], 5, 10);
            if (bytes_rcv == 5)
            {
            	wfd cof_serAwrite(&mensaje_in[0], 5);           //DEBUG POR SERIAL
					while(serAwrFree()!=AOUTBUFSIZE);

             }

}



}
}

void rx_max485(void)
{
	BitWrPortI(PEDR, &PEDRShadow, 0, 7);
}

void tx_max485(void)
{
	BitWrPortI(PEDR, &PEDRShadow, 1, 7);
}




PIC


//PIC NUMERO 1                          (SENSOR DE TEMPERATURA MLX90614)

#define DIR_PIC 1

#define START_RABBIT 0x0F
#define START_PIC 0xD2

//DEFINES PARA SENSORES (funcion)
#define PRENDO_LED 0x01
#define APAGO_LED 0x10
#define FUNCION_NULL 0xFF

//DEFINES PARA SENSORES (datos)
#define DATOS_NULL 0xFF

//DEFINES DE RESPUESTA DE SENSORES
#define RESPUESTA_OK 0x77
#define RESPUESTA_NULL 0x33

#define SLAVE_ADRESS 0x35


//ENCABEZADOS

void envio_mensaje_out ( char valor_1, char valor_2, char valor_3, char valor_4);
void conf_interrupciones();

char mensaje_in[5];
char mensaje_out[6];


char bytes;
char flag_checksum = 0;

//REGISTROS INTERNOS AL PIC

char registro_1 = 0x00;                                                       //REGISTRO CON LA FUNCIÓN A EJECUTAR
char registro_2 = 0x00;                                                       //REGISTRO CON DATO RECIBIDO
char registro_3 = 0x00;                                                                                                                  //REGISTRO CON TEMP_1
char registro_4 = 0x00;                                                                                                              //REGISTRO CON TEMP_2
char registro_5 = 0x00;                                                                                                                 //REGISTRO CON PEC

char puerto = 0x00;                                                     //Variable global para actualizar el puerto B
char puerto_a = 0x00;

void main()                                                                     //Funci?n principal
{
        char orden;                                                  //Array que almacenar? los datos enviados por el rabbit
        char valor_l;
        char valor_h;
        int distancia;
        char tomada;

        TRISA = 0x80;                                   //RA6 y RA7 como salidas

        TRISB = 0x82;
        PORTB = puerto;


        UART1_Init(9600);                                               //Inicializamos puerto serial del PIC
        bytes = 0;
        conf_interrupciones();

        while(1)                                                                //Loop infinito
        {
                        if(registro_1 == PRENDO_LED)
                        {
                                puerto.F5 = 1;
                                PORTB = puerto;
                        }
                             else if(registro_1 == APAGO_LED)
                        {
                                puerto.F5 = 0;
                                PORTB = puerto;
                        }

         }



}


//FUNCIONES EXTRAS

void envio_mensaje_out ( char valor_1, char valor_2, char valor_3, char valor_4)
{

        mensaje_out[0] = 0x01;                                                                        //SE PUEDE OPTIMIZAR
        mensaje_out[1] = 0x01;
        mensaje_out[2] = 0x01;
        mensaje_out[3] = 0x01;
        mensaje_out[4] = 0xFF;


        puerto.F3 = 1;
        PORTB = puerto;

        UART1_Write(mensaje_out[0]);
        UART1_Write(mensaje_out[1]);
		UART1_Write(mensaje_out[2]);
		UART1_Write(mensaje_out[3]);
		UART1_Write(mensaje_out[4]);

        puerto.F3 = 0;
        PORTB = puerto;
        


}


void conf_interrupciones()
{
                INTCON.GIE=1;     //habilita interrupciones generales
                INTCON.INTE=1;    //habilita interrupciones externas
                INTCON.PEIE=1;    //habilita interrupciones perifericas

                PIE1.RCIE=1;                //interrucpcion via serial
                PIR1.F0 = 0;                // Ponemos el flag de la interrupcion a 0

}

void interrupt()
{
        if (PIR1.RCIF == 1)
        {
				if (bytes == 0)
                {
					mensaje_in[0] = UART1_Read();

					if( mensaje_in[0] == START_RABBIT )
					{
						bytes = 1;
					}

				}
				else if (( bytes != 5)&&( bytes != 0))
                {
					mensaje_in[bytes] = UART1_Read();
					bytes++;
				}
                else if (bytes == 5)
                {
                                        bytes = 0;                                                                                        //PROCESO PAQUETE

                                        if (mensaje_in[1] == DIR_PIC)
                                        {
											envio_mensaje_out ( START_PIC, DIR_PIC, registro_3, registro_4);

											registro_1 = mensaje_in[2];
											registro_2 = mensaje_in[3];

                                        }

                }

                PIR1.RCIF = 0;

        }

}

Capaz que es un tema de software...

Tenès alguna sugerencia?
Probè las funciones de la librerìa packet del rabbit pero me andan solo del rabbit al PIC y no del PIC al rabbit...
 
Última edición por un moderador:
Atrás
Arriba