Autor Tema: Funcion SendAT y confirmar respuesta  (Leído 4783 veces)

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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Funcion SendAT y confirmar respuesta
« Respuesta #15 en: 08 de Mayo de 2015, 22:59:22 »
Citar
- Si, quiero que este en un do.. while, porque quiero que lo envié forzando hasta tener la respuesta., si lo dices por el do del main es solo para hacerlo correr.

Vos me pediste que funcione como el de arduino, lo que estas haciendo no me parece correcto pero bueno. Para mi deberias enviar una sola ves y esperar la respuesta y fin.

Citar
cuenta las interrupciones dependiendo del timerout ingresado

Esto es un error, por que el codigo que tenes ( o que pasaste al ultimo ) no hace eso, sino que calcula la cantidad de interrupciones, pero no luego no compara eso, sino que tenes una variable que se incrementa cada vez que se compara y compara con lo calculado, pero jamas compara con las veces que entro a la interrupcion.

Esta es la linea en cuestion:

Citar
if (++i > numero_de_intr) { break; }

Antes de comparar eso, incrementa i, y luego compara. pero para entrar ahi no hay nada que lo limite. Por eso yo lo habia puesto dentro de un if, pero mi codigo no tengo activo el interrupt del tmr0, solo leo el flag.

Código: [Seleccionar]
if(interrupt_active(INT_RTCC))
  {
    if (++i > cantidad_de_intr) { break; }      // en la misma sentencia sumo 1 a i cada ves que entra, y comparo con la cantidad de veces que tiene que entrar, si se supero ejecuto el break; para salir del do..while
   }

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re: Funcion SendAT y confirmar respuesta
« Respuesta #16 en: 10 de Mayo de 2015, 13:49:50 »
......

Ok, entonces así queda, igual me gusta como trabaja:
Una ultima cosa, ¿Por qué no seria bueno enviar el comando varias veces? ¿Quién garantiza que llegue bien? es por eso que lo hago.


Código: [Seleccionar]
#include <18F26K22.h>
#Device  PASS_STRINGS=IN_RAM 
#ZERO_RAM     
#FUSES INTRC_IO, NOWDT, BROWNOUT, NOPUT , NOPBADEN, NOHFOFST,NOPLLEN ,PROTECT
#use delay(clock=4M)
#use rs232(baud=9600,bits=8,parity=N,xmit=PIN_C6,rcv=PIN_C7,ERRORS,bits=8,stream=uart1)  // Configuración UART1 (Hardware)
#use rs232(baud=9600,bits=8,parity=N,xmit=PIN_B6,rcv=PIN_B7,ERRORS,bits=8,stream=uart2)  // Configuración UART2 (Hardware)
#define FASTER_BUT_MORE_ROM                                                              // Variables en memoria
#include <string.h>                                                                      // Librerias para manejo de strings
#include <stdlib.h>
void clear_buffer1();
int8 sendATcommand(char *ATcommand, char *expected_answer,unsigned int timeout);
char c;
char buffer1[30];
int xbuff1=30;


#int_RDA                               // Interrupción por recepción de datos UART1
void RDA_isr1(void) {                  // Interrupción recepción serie USART
   c=0x00;                             // Inicializo caracter recibido                   
   if(kbhit(uart1)){                   // Si hay algo pendiente de recibir ...
      c=getc(uart1);                   // lo descargo y ...
      buffer1[xbuff1++]=c;             // Añade caracter recibido al Buffer   
      if(xbuff1==30) xbuff1=0x00;      // Si buffer esta lleno se resetea
      }
   }


#int_timer0
void timer0_isr() {          // Interrupción por desbordamiento de timer0
}

// Programa Principal
void main(){   
//-------------- Configuración ----------                //
    enable_interrupts(GLOBAL);                           // Habilitar Interrupción Global
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_bit);  // 256 us overflow
    enable_interrupts(INT_RTCC);
    enable_interrupts(int_rda);                          // Habilita Interrupción RDA UART1
     
//--------------- Subprograma ---------------                                     
 while(true){
 
   if  (sendATcommand("AT+CGPSPWR=1\r\n", "OK",5000)){
       fprintf(uart1,"\r\nListo...\r\n");}
   else {
        fprintf(uart1,"\r\nError...\r\n");}
   }
}

//******* Enviar AT  ********************
int8 sendATcommand(char *ATcommand, char *expected_answer,unsigned int timeout)
{
    int16 numero_de_intr=0;                             // Variables       
    int answer=0,i=0;                                   // Variables
    clear_buffer1();                                    // Limpiar buffer
    numero_de_intr = (int32)(timeout *1000) /256;       // Numero de Interrupciones
    set_timer0(0);                                      // Pongo a 0
    clear_interrupt(INT_RTCC);                          // Limpia mi flag TMR0
    fprintf(uart1,"%s",ATcommand);                      // Enviar Comando AT Retardo 0.3 segundos   

    do{
      if (strstr(buffer1, expected_answer)>0)           // Busca la respuesta que debe ser
        { answer=1;  clear_buffer1();}                  // Respuesta Correcta    y  Limpiar buffer1       
     
      if(interrupt_active(INT_RTCC)){
        if (++i > numero_de_intr) { break; }            // en la misma sentencia sumo 1 a i cada ves que entra, y comparo con la cantidad de veces que tiene que entrar, si se supero ejecuto el break; para salir del do..while
      }
     } while (answer == 0);                             // mientras respuesta sea 0
   return answer;                                       // Retorna respuesta (1 o 0)
}
//******* Borrar Buffer1 ****************
void clear_buffer1(void){                              // Inicia a \0 buffer1
   int i;                                              //
   for(i=0;i<30;i++){                                  // Bucle que pone a 0 todos los caracteres en el buffer
      buffer1[i]=0x00;                                 //
   }                                                   //
   xbuff1=0x00;                                        // Inicializo el indice de siguiente caracter
}



Muchas gracias por tu tiempo y sugerencias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Funcion SendAT y confirmar respuesta
« Respuesta #17 en: 10 de Mayo de 2015, 14:30:40 »
Es tiempo ocupado mandando datos, con lo cual 1 ves serviria. Si la respuesta fuera mas larga que el envio del comando, como actuaria el receptor? por ejemplo que la respuesta sea 30 caracteres y tu envio sea de 10, envias 10, el receptor comienza a devolver y cuando va por 10 de 30, le llega nuevamente otra peticion, deja de hacer lo que estaba haciendo ? e intenta responder a esta?.
En fin, no le veo nada bueno a eso. Ya que con que lo envies una sola ves ya estaria.

Si tenes problemas sobre si tus cosas llegaron o no para eso tenes el timeout, obviamente en el codigo que trajiste no se separa entre timeout por que no llego nada, o timeout por que llego un resultado que no era el esperado.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re: Funcion SendAT y confirmar respuesta
« Respuesta #18 en: 11 de Mayo de 2015, 17:11:27 »
Es tiempo ocupado mandando datos, con lo cual 1 ves serviria. Si la respuesta fuera mas larga que el envio del comando, como actuaria el receptor? por ejemplo que la respuesta sea 30 caracteres y tu envio sea de 10, envias 10, el receptor comienza a devolver y cuando va por 10 de 30, le llega nuevamente otra peticion, deja de hacer lo que estaba haciendo ? e intenta responder a esta?.
En fin, no le veo nada bueno a eso. Ya que con que lo envies una sola ves ya estaria.

Si tenes problemas sobre si tus cosas llegaron o no para eso tenes el timeout, obviamente en el codigo que trajiste no se separa entre timeout por que no llego nada, o timeout por que llego un resultado que no era el esperado.

Genial, gracias por la aclararon ahora entiendo algunos problemas que tuve anteriormente, precisamente la respuesta era mucho mas larga que el comando.

El código que estoy desarrollando lo  quiero trabajar en 64MHZ, lo que debo configurar el overflow asi:
Código: [Seleccionar]
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_bit); //4,0 ms overflow

pero nunca entra en :
Código: [Seleccionar]

if(interrupt_active(INT_RTCC)){
        if (++i > numero_de_intr) { break; }            // en la misma sentencia sumo 1 a i cada ves que entra, y comparo con la cantidad de veces que tiene que entrar, si se supero ejecuto el break; para salir del do..while
      }

¿Como debe ir configurado para que este mismo código trabaje a 64MHZ?


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Funcion SendAT y confirmar respuesta
« Respuesta #19 en: 11 de Mayo de 2015, 21:46:22 »
La frecuencia pasa de 4 Mhz a 64Mhz, asi que vas a esperar ver el mismo incremento de pulsos en el timer. Antes habiamos usado un preescaler de 1.

64Mhz/4Mhz = 16

Pone un preescaler de 16 y vas a seguir teniendo el overflow a 256us, y no tenes que cambiar nada mas del codigo, me refiero a la formula y a la parte de la interrupcion.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re: Funcion SendAT y confirmar respuesta
« Respuesta #20 en: 11 de Mayo de 2015, 23:25:33 »
La frecuencia pasa de 4 Mhz a 64Mhz, asi que vas a esperar ver el mismo incremento de pulsos en el timer. Antes habiamos usado un preescaler de 1.

64Mhz/4Mhz = 16

Pone un preescaler de 16 y vas a seguir teniendo el overflow a 256us, y no tenes que cambiar nada mas del codigo, me refiero a la formula y a la parte de la interrupcion.

Aja así lo hago, he intento con otros valores... lo curioso es que si funciona y a la ves no...
cuando hago un debug, veo que  "i "no incrementa, y es como si no entrará a la interrupción.
pero, cuando lo corro de seguido si funciona,  como se muestra en la imagen, arroja el mensaje error si no se encuentra el dato esperado.




Bueno, igual así como esta me sirve, espero que tambien funcione en la practica... pero pienso que algo debe estar mal.
con 4M en el debug si muestra el incremento de "i"... pero solo si el proteus tiene 4M, entonces puede que sea problemas del simulador.

Muchas gracias.
« Última modificación: 11 de Mayo de 2015, 23:31:35 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Funcion SendAT y confirmar respuesta
« Respuesta #21 en: 11 de Mayo de 2015, 23:44:15 »
Puede ser que que se reciba la respuesta antes del que entre a una interrupcion.

Podes fijarte en el registro del TMR0 si es que se rebalsa o no

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re: Funcion SendAT y confirmar respuesta
« Respuesta #22 en: 13 de Mayo de 2015, 01:46:12 »
Puede ser que que se reciba la respuesta antes del que entre a una interrupcion.

Podes fijarte en el registro del TMR0 si es que se rebalsa o no

según el debug, justo cuando llega algo  el timer0 se dispara... mmm es raro. pero bueno, almenos puedo obtener una respuesta... dejaré así.
Muchas gracias!

PD: Hice un hilo sobre otro tema de comandos AT donde expongo  dos funciones para extraer datos de un string, por favor regalanos tus sugerencias.
http://www.todopic.com.ar/foros/index.php?topic=44517.0