Autor Tema: Crear un archivo de datos capturados cada 44us  (Leído 4012 veces)

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

Desconectado floydblues

  • PIC10
  • *
  • Mensajes: 9
Crear un archivo de datos capturados cada 44us
« en: 12 de Marzo de 2009, 20:51:32 »
Hola a todos. Estoy haciendo un proyecto donde estoy usando pic 18f452 con un crystal de 4Mhz. Mi proyecto es crear un archivo wave de 22kHz, necesito capturar cada 44us datos con el puerto A0 con A/D, convertirlos esos valores entre un rango de 0 - 255 crear un archivo txt y guardarlo en una memoria SD.

Mi problema es el siguiente, no logro capturar datos cada 44us, cambie el crystal a 10MHz y tampoco, hice simulaciones en proteus con uno 40MHz y tampoco funciono. Estoy usando el MikroC. Es el único que falta para lograr terminar mi proyecto, alguna sugerencia para poder lograrlo?

gracias, saludos.


Desconectado aitopes

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5100
    • uControl
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #1 en: 12 de Marzo de 2009, 23:49:47 »
Usar ASM? :?
Si cualquier habilidad que aprende un niño será obsoleta antes de que la use, entonces, ¿qué es lo que tiene que aprender? La respuesta es obvia:
La única habilidad competitiva a largo plazo es la habilidad para aprender
“. Seymour Papert

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #2 en: 13 de Marzo de 2009, 00:35:40 »
pss yo no programo en mikroC pero para los q saben de tal lenguaje les seria mas facil ayudarte  si posteas el codigo, o talvez si puedes hacer migrar tu post  al foro de "lenguaje C para microcontroladores"
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #3 en: 13 de Marzo de 2009, 01:15:45 »
Primera sugerencia:

Pon el codigo, este es el lenguaje de comunicacion entre tu y nosotros.

Segunda sugerencia:

¿Cual es el problema? ... Define bien el problema. No lograr capturar a 44us no es el problema, ese es el efecto del problema.

No entiendo si .. es que no logras tomar las muestras en ese tiempo o es que no tomas del todo ninguna muestra.

Eso me hace pensar en varios problemas (de mayor probabilidad a menor probabilidad):

-> Timer configurado incorrectamente.
-> ADC mal configurado.
-> Oscilador configurado incorrectamente.
-> Programa mal estructurado ...
-> Exigencias de hardware no acordes al objetivo.

Tercera sugerencia.

Escribe mas detalles, no seas tan general, en este foro pocos pero muy pocos son adivinos ... ellos son los que casi nunca contestan  :D :D

Tenes mucho espacio para escribir, podes subir imagenes, escribir codigo, subir archivos, etc etc ...

Saludos!


« Última modificación: 13 de Marzo de 2009, 01:22:35 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #4 en: 13 de Marzo de 2009, 14:33:22 »
También hay que considerar si la velocidad de escritura por muestra (n número de bytes) de la memoria SD es menor a 44us. Por ejemplo, si una muestra ocupa 2 bytes, entonces la sd debe ser capaz de escribir 2 bytes en menos de 44us. También el muestreo del ADC tiene su tiempo de adquisición por lo que...

Tadq + Tescritura < 44us

Desconectado floydblues

  • PIC10
  • *
  • Mensajes: 9
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #5 en: 13 de Marzo de 2009, 18:39:51 »
Gracias a los interesados por ayudar. Si he logrado capturar datos y guardarlos pero no los captura a 44us. Este es el codigo del programa.

char filename[]="LARVOMTRTXT";
unsigned sec,hsec,loop;
unsigned short t;
unsigned char ch1,ch2,flag,choice,ret_status,car[2],sound[10], txt[12];
unsigned long file_size,i,rec_size, usec;

void Get_Sound()
{
   unsigned long Vin, Vdec, Vfrac;
   unsigned char op[12];
   unsigned char i,j;
        unsigned float conv=1.243902;
 
 
   Vin= Adc_Read(0);      //Read from channel 0 (AN0)
        Vin= Vin*conv;
   Vdec= Vin;
   LongToStr(Vdec,op);      //Convert Vdec to string in "op"

//Remove leading blanks

   j=0;
   for(i=0;i<=11;i++)
   {
      if(op!=' ')      //if a blank
      {
         sound[j]=op;
         j++;
      }
   }
   sound[j]=0x0D;         //Add carriage-return
   j++;
   sound[j]=0x0A;         //Add line-feed
   j++;
   sound[j]='\0';
}

void initmmc()
{
   //Initialise the Spi bus
  Spi_Init_Advanced(MASTER_OSC_DIV4,DATA_SAMPLE_MIDDLE,CLK_IDLE_LOW,LOW_2_HIGH);

  //Initialise the SD card bus
  while(Mmc_Init(&PORTC,2));

  //Initialise the FAT file system
  while(Mmc_Fat_Init(&PORTC,2));

  rec_size=0;

}

void init_timer()
{
  //PROGRAMAR MODULO Timer1 5ms a 40MGHz
  TRISD.F7=0;
  // Set Interrupt Enable bits
  PIE1.TMR1IE = 1;    // bit 0 TMR1 Ovewflow Interrupt Enable
  INTCON = 0xC0;              // Set GIE, PEIE

  // Timer1 Registers: Prescaler=1:1; TMR1 Preset=65492; Freq=22,727.27273Hz; Period=44.00 µs
  T1CON.T1CKPS1 = 0;  // bits 5-4  Prescaler Rate Select bits
  T1CON.T1CKPS0 = 0;  // bit 4
  T1CON.T1OSCEN = 1;  // bit 3 Timer1 Oscillator Enable Control: bit 1=on
  T1CON.T1SYNC  = 1;  // bit 2 Timer1 External Clock Input Synchronization Control bit: 1=Do not synchronize external clock input
  T1CON.TMR1CS  = 0;  // bit 1 Timer1 Clock Source Select bit: 0=Internal clock (FOSC/4) / 1 = External clock from pin T13CKI (on the rising edge)
  T1CON.TMR1ON  = 1;  // bit 0 enables timer
  TMR1H = 0xFE;         // preset for timer1 MSB register
  TMR1L = 0x48;         // preset for timer1 LSB register
 
  PIR1.TMR1IF  = 0;           // clear TMR1IF
  PIE1.TMR1IE  = 1;           // enable Timer1 interrupt
}

void interrupt()
{
      initmmc();
      Mmc_Fat_Assign(&filename,0x80);            //Assign the file
      Mmc_Fat_Rewrite();                     //Clear
      Mmc_Fat_Write("# SOUND DATA SAVED AT 22KHZ \r\n",43);
      
        if(PIR1.TMR1IF==1)
       {
         usec++;
         //Read the sound from A/D converter, format and save
          Mmc_Fat_Append();
         Get_Sound();
         Mmc_Fat_Write(sound,9);
         
         TMR1H = 0xFE;
         TMR1L = 0X48;
                        PIE1.TMR1IE  = 1;
                        PIR1.TMR1IF = 0;   //apago fuente de interrupcion
          if (usec == 22720)
      {

       usec=0;
       sec++;
       PORTD.F7 = !PORTD.F7;

       if (sec == 60)
       {
          PIE1.TMR1IE  = 0;
          INTCON.TMR0IE = 0;
       }
      }
      }
}
void main()
{
  //Configure A/D converter
  TRISA=0XFF;
  ADCON1=0X80,         //Use AN0, Vref=+5V


  TRISD.F7=0;
  PORTD.F7 = 0;
  TRISB.F0=1;
  TRISB.F1=1;

  hsec=0;
  sec=0;
  usec=0;
  loop=0;
  Spi_Init_Advanced(MASTER_OSC_DIV4,DATA_SAMPLE_MIDDLE,CLK_IDLE_LOW,LOW_2_HIGH);

  while(1)
  {
  if (PORTB.F0==1)       // IF SW1 IS PUSH
     {
      init_timer();

      }
  }
}

Esta version solo captura un dato y ya. Tengo otra version del programa donde no uso el timer1, uso "delay_us(44)"; esta version captura datos pero no cada 44us.

char filename[ ] = "LARVOM01TXT";
unsigned int usec,sec,hsec,loop;
unsigned short t;
unsigned char ch1,ch2,flag,choice,ret_status,car[2],sound[10], txt[12];
unsigned long file_size,i,rec_size;

void Get_Sound()
{
   unsigned long Vin, Vdec, Vfrac;
   unsigned char op[12];
   unsigned char i,j;
     unsigned float conv=1.243902;
 
 
   Vin= Adc_Read(0);      //Read from channel 0 (AN0)
   Vin=Vin*conv;
   Vdec= Vin;         //Decimal Part
   LongToStr(Vdec,op);      //Convert Vdec to string in "op"

//Remove leading blanks

   j=0;
   for(i=0;i<=11;i++)
   {
      if(op!=' ')      //if a blank
      {
         sound[j]=op;
         j++;
      }
   }

   sound[j]=0x0D;         //Add carriage-return
   j++;
   sound[j]=0x0A;         //Add line-feed
   j++;
   sound[j]='\0';
}

void initmmc()
{
   //Initialise the Spi bus
  Spi_Init_Advanced(MASTER_OSC_DIV4,DATA_SAMPLE_MIDDLE,CLK_IDLE_LOW,LOW_2_HIGH);

  //Initialise the SD card bus
  while(Mmc_Init(&PORTC,2));

  //Initialise the FAT file system
  while(Mmc_Fat_Init(&PORTC,2));

  rec_size=0;

}

void main()
{
  //Configure A/D converter
  TRISA=0XFF;
  ADCON1=0X80,         //Use AN0, Vref=+5V
 
  TRISD.F7=0;
  PORTD.F7=0;
  TRISB.F0=1;
  TRISB.F1=1;
 

  hsec=0;
  sec=0;
  usec=0;
  loop=0;
 
  initmmc();
  flag=0;
 
  while(1)
  {
   if (PORTB.F0==1)       // IF SW1 IS PUSH
     {
      Mmc_Fat_Assign(&filename,0x80);            //Assign the file
      Mmc_Fat_Rewrite();                     //Clear
      Mmc_Fat_Write("# SOUND DATA SAVED AT 22KHZ \r\n",43);
      //Read the sound from A/D converter, format and save

      while(1)
         {
                 Mmc_Fat_Append();
            Get_Sound();
            Mmc_Fat_Write(sound,9);
            Delay_us(45);
               }
     }
 
  } // end of while
}

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #6 en: 13 de Marzo de 2009, 22:55:41 »
En el primer codigo parece que falta la rutina de servicio de interrupcion .. supongo que dentro de esa rutina que llama a la funcion: interrupt(),

Dudo mucho que la grabación de un dato en SD sea en menos de 44us ... por ejemplo, en una EEPROM se debe esperar de 1ms a 5ms entre cada escritura ... no se cuanto es el tiempo de escritura de una SD .. habra que preguntar a San Google.

Ademas en un dsPIC de 40MIPS (80MHz) y 16bits! .. tarda aprox 5us ejecutando una sola multiplicacion en punto flotante. Si las rutinas de FAT y SC necesitan ejecutar alguna operacion en punto flotante u ordenamientos de arreglos ahi tendras mucho retraso. Ademas dudo que la escritura en SD solo sea de enviar el byte y ya ... hay que considerar los comandos de escritura, la direccion de memoria y por ultimo el dato.

Creo que el poder de transferir datos a una SD se da por bloques, por ejemplo, se llena un bloque de 1kbyte de informacion en RAM, cuando se completa, se hace la transferencia de todo ese bloque a la SD mediante DMA, mientras se realiza la transferencia el micro esta tomando datos y guardando en un bloque en otro sector de la memoria RAM (Accesible tambien por el DMA).

En este tipo de transferencias tenes que esperar igual algunos ms para volver a escribir, la diferencia rádica en que en vez de esperar entre byte y byte .. lo haces entre 1kbyte y 1kbyte .... lo mismo ocurre en una EEPROM, estas tienen opcion de escribir páginas completas, es decir se transfiere toda la informacion de la página (por lo general 256bytes) cuando se realiza la transferencia completa se debe esperar unos ms para la siguiente escritura ...

Ademas creo que le estas pidiendo mucho procesamiento a tu PIC18 ... si estoy en lo correcto usaria un micro con DMA.

Te recomendaria que guardes los datos primero en una RAM y luego la escribas a la SD al final del muestreo. Si no te alcanza la del PIC hay RAM seriales. Microchip sacó unas de 20MHz y 32kbytes, podrias guardar aprox 1.5seg a ese muestreo.

 
« Última modificación: 13 de Marzo de 2009, 23:14:32 por blackcat »
Control Automático, DSP & Microcontroladores

Desconectado floydblues

  • PIC10
  • *
  • Mensajes: 9
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #7 en: 16 de Marzo de 2009, 19:25:29 »
Gracias blackcat. Si había pensado que era demasiado procesamiento para un PIC18. Cambie la multiplicación en punto flotante, ahora guardo los datos como hexadecimal.

Tuve la idea de utilizar dos PIC’s conectados entre sí, uno que capturara los datos ADC y otro que los guardara en sectores del SD para cuando termine de recibir los datos los empiece a procesar y guardar los valores en archivo txt; pero en las simulaciones en Proteus el resultado fue casi igual al anterior.

El guardarlos en RAM es muy buena idea pero no alcanza la del PIC, como mencionaste, la RAM serial no sé si sería la solución ya que necesito guardar datos de muestreo para un minuto. Hay una que tenga la capacidad suficiente?

Podría usar un micro como el dsPIC4013 (que tiene DMA) o cual recomendarías? un Arduino serviría?

Saludos

Desconectado floydblues

  • PIC10
  • *
  • Mensajes: 9
Re: Crear un archivo de datos capturados cada 44us
« Respuesta #8 en: 24 de Marzo de 2009, 15:58:44 »
Hola de nuevo, todavía sigo sin lograrlo. Logre que capturara datos, con el PIC18, a 2.1kHz (476us) pero todavía estoy lejos de los 22kHz (44us).

Voy a pedir un dsPIC pero me gustaria que alguien me sugiriera uno.

Saludos.