NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » How do I increase the sampling time of my circuit

November 13, 2013
by jmuthe
jmuthe's Avatar

I have been working on a project, where I would create a simple voltage recording device.I do it by using the ADC in the ATMEGA 328 microcontroller, and the I2C controlled memory chip (24LC128) and Digital to Analog Converter (MAX518). I used Fleury's code to write to these chips. My program is supposed to first display the message "Record" on the LCD. When it is in record mode, you could insert a voltage into the ADC, where it would convert it into a digital number, and then store the digital value into the memory chip. After a few seconds, the LCD would display the message "Play" and when it is play mode, the memory chip would output its values into the Digital to Analog Converter. The DAC would of course convert it to an analog signal. So basically an analog voltage is stored and then played back. For example, I first connected a potentiometer to the input of the ADC so that I could vary the voltage. When I was in record mode, I set the voltage to 0 volts and gradually set it to 5 volts. When the program was in play mode, the DAC output started at 0 volts and gradually climbed up the same way.

My program technically works but not like I want it to. When I use the potentiometer to vary the voltage, the circuit worked. I also tried another experiment where I used another ATMEGA 328 to cause an output pin to blink a LED in a certain way. I then connected the output pin of that microcontroller to the ADC input pin of the other microcontroller. As predicted, the microcontroller copied the signal in record mode and the DAC caused the LED to blink in the same way in play mode.

Basically the circuit works fine if I vary the input voltage slowly. However, it doesn't work so well when the input frequency is faster. For example, I used the first microcontroller to play music. The easiest way to do that it to connect an output pin to a speaker, and then make the output pin turn off an on at one frequency to play one note and at another frequency to play another note. Once I knew that the program worked (because I heard my music), I connected the output pin of the first microcontroller to the ADC input of the other microcontroller. Then I connected the speaker to the DAC output pin. I expected the speaker to play the same tune when the program was in play mode but it does nothing more than click a few times each second.

My theory of why it didn't work is because my program doesn't sample high enough to capture higher frequencies. Do you think that is the problem or is there anything else that I am missing? If my program doesn't sample fast enough then how do I fix it? Is there something I could do in the program to speed it up or do I have to get faster chips?

#define F_CPU 14745600
#include <stdio.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/interrupt.h>

#include <avr/io.h>
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/io_328p.h"
#define DEV24LC128  0xA0     // device address of EEPROM 24C02, see datasheet
#define MAX518  0x58     //device address for the MAX518 DAC
int j;
int i;
int t;
int16_t z;
int16_t ret;
void intitialvalues ();
uint16_t result;
void memorywrite ();
void memoryread ();
void DAC ();
int ADC1 ();

int main ()
{

   while (1)
   {
   initialvalues ();
   lcd_init();
   lcd_line_four();
   lcd_write_string(PSTR("recording   "));
   memorywrite ();
   lcd_line_four();
   lcd_write_string(PSTR("playing   "));
   memoryread();
   }
}

int ADC1 ()
{
   ADCSRA |= (1<<ADSC);
    uint16_t low = ADCL;
uint16_t high = ADCH;
result = low + (high<<8);
result = result>>2; //result is shifted over so that the 10 digit value becomes two digits.   
return result;     //The last two digits are cropped
}

void DAC()//sends information to the DAC
{
i2c_start_wait(MAX518+I2C_WRITE);
     i2c_write(0x00);
     i2c_write(ret);
}

void initialvalues ()
{

   i2c_init();
   j=0;
   i=0;
 ADMUX = 0; // set analog to digital converter for external //reference (5v), single ended  input ADC0
 ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

// set analog to digital converter
// to be enabled, with a clock prescale of 1/128
 // so that the ADC clock runs at 115.2kHz.

}

void memorywrite ()//Reads from the ADC and writes to the EPROM
 {
j=0; //j is upper address bit for the serial EPROM
i=0; //i is the lower memory bit fot the serial EPROM
for (j=0;j<128;j++)
 {
  for (i=0;i<256;i+=64)
     {
      i2c_start_wait(DEV24LC128 +I2C_WRITE);     // set device address and write mode
      i2c_write(j);
      i2c_write(i);
      for (t=0;t<64;t++)
       {
        z = ADC1 ();    //read value from ADC
        i2c_write(z);    //store ADC value in the memory chip          
       }
       i2c_stop();

    }
 }

}

 void memoryread ()//Reads from the EPROM and sends to the DAC
{

 for (j=0;j<128;j++) //j is upper address bit for the serial EPROM
  {
   for (i=0;i<256;i++)//i is lower address bit for the serial EPROM
    {
     i2c_start_wait(DEV24LC128 +I2C_WRITE);// set device address and write mode
     i2c_write(j);                        
     i2c_write(i);                        
     i2c_rep_start(DEV24LC128 +I2C_READ);
     ret = i2c_readAck(); //ret reads the value from the serial EPROM
     DAC();// This sends value to the DAC
     i2c_stop();
    }

   }
 }
November 14, 2013
by Noter
Noter's Avatar

Did you search the forum on 'adc sampling rate'? There are several threads on the subject.

November 14, 2013
by BobaMosfet
BobaMosfet's Avatar

jmuthe-

You haven't provided some fundamental information-- what is the max frequency you're trying to capture/replay?

BM

November 18, 2013
by jmuthe
jmuthe's Avatar

I think I may not have not been too clear in my first post. When I said that the sampling rate might be to slow, I didn't mean just the ADC sampling rate. When I say the sampling rate in Record mode, I mean the total time it takes for the ADC to read the input voltage and send it to the EPROM. In Play mode, I mean the time the program takes to extract the data from the EPROM, send it to the DAC, and then have the DAC convert it to an analog voltage. The problem with this setup, is that it can only be as fast as its weakest link. For example, if the the ADC and DAC are fast but the EPROM is slow then this won't sample fast enough.

In response to BobaMosfet's question, I eventually want to make a simple recording device that will record sound. Since the maximum frequency that humans can hear is 20,000 Hz, I want to be able to capture and play something up to that frequency. I believe that the sampling rate should be at least twice the frequency so I would like it to be 40,000 Hz. I don't expect to make a perfect recording device that will sound crisp and clear so if some of the higher frequencies are cut off then that is okay. However, I would like it to at least sound close to the sound I am trying to record. Based on the components I am using, and the program I wrote, would I be able to do this or do I need different components for this job.

November 18, 2013
by Noter
Noter's Avatar

Says here it takes 3.3ms to write the eeprom so that would be around 300hz. Even if your eeprom could write 3 times faster at 1ms that still only 1khz recording. You need something that can write around 100 times faster. Maybe there is serial interface ram that will work for you.

November 20, 2013
by jmuthe
jmuthe's Avatar

I am using a serial interface to store my data. I am using the I2C controlled memory chip (24LC128)and I tried the 24LC256.

November 20, 2013
by Noter
Noter's Avatar

Your memory chips are eeprom and they still require some amount of time to complete a write cycle. I think that time is close to any other eeprom write which is around a couple of ms. You could write a little test program and see how long it takes to write a byte to your memory chip if you want to know for sure.

November 20, 2013
by BobaMosfet
BobaMosfet's Avatar

jmuthe--

Step away from the protocol and the chips for a moment. Ask yourself one question. How much time do I have to process 1 cycle at the desired frequency? Once you know that, you have your design requirement. Will the protocols and other components work fast enough to give you time to process a cycle at that speed, including obvious overhead.

BM

November 21, 2013
by Ralphxyz
Ralphxyz's Avatar

Anyway to buffer before writing to EEPROM?

Ralph

Post a Reply

Please log in to post a reply.

Did you know that NerdKits has been featured in the MIT Undergraduate Research Journal? Learn more...