Sampling the Audio with ADC

Hello everyone, I`ve been having problems with audio sampling from electret microphone. I set the sampling frequency to 50kHz using prescaler, and used 8 bits of ADC on pin A0. How do I print out the data I read from A0, Serial printing clearly doesnt work. Someone told me to cache it and stream the buffer in chunks. How do I do that? Apparently serial printing is too slow for this sampling frequency.

int incomingAudio;

void setup(){
Serial.begin(115200);
  cli();//disable interrupts
  
  //set up continuous sampling of analog pin 0
  
  //clear ADCSRA and ADCSRB registers
  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0 = 0;

  OCR0A = 39;
  TCCR0A |= (1 << WGM01);

  TCCR0B |= (1 << CS01);

  TIMSK0 |= (1 << OCIE0A);

  ADCSRA = 0;
  ADCSRB = 0;
  
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
  
  sei();//enable interrupts

  //if you want to add other things to setup(), do it here

}

ISR(TIMER0_COMPA_vect) {//when new ADC value ready
  incomingAudio = ADCH;//update the variable incomingAudio with new value from A0 (between 0 and 255)
}

void loop(){
//do other stuff here
Serial.println(incomingAudio);
}

You could use a much higher serial baud rate, and since the data are limited to 8 bits, write binary values as one byte instead of using up to 5 ASCII characters (including CR and LF) to represent the same value.

uint8_t incomingAudio;
...
// in loop()
Serial.write(incomingAudio);

Capture the data to a log file using a terminal program like TeraTerm.

The ATmega series doesn't have enough RAM memory to buffer a significant amount of data.

Thank you, is the code I provided okay?

No, the code is not OK.

The main problem is that the loop function has no way of knowing that the ADC has updated the value in incomingAudio. Typically people use a flag to indicate that, e.g.

volatile uint8_t update_flag = 0;  //must be global and declared "volatile"
...

ISR(TIMER0_COMPA_vect) {//when new ADC value ready
  incomingAudio = ADCH;//update the variable incomingAudio with new value from A0 (between 0 and 255)
  update_flag = 1;  //signal the main program of update
}

void loop(){
if (update_flag) {
   Serial.println(incomingAudio);
   update_flag = 0;
   }
}

There may be other problems.

Okay, the idea was to make voice command activated LED, for example if I say POWER ON, it will turn on, and if I say STOP they will turn off. Some guy told me to sample with timer interrupts because I can control it better. I wanted to do DTW to compare prerecorded messages in real time. This is all kind of foreign for me, any suggestions?

You won't get this to work with an Arduino Uno or similar, as they are far too slow and have too little memory to store or stream decent quality real time audio, let alone perform voice recognition.

There are voice recognition modules that can recognize a half-dozen keywords, and much faster Arduino boards that can acquire and stream 16 bit audio.

Dang, one guy told me he done it, I thought I could make it work just for 2 words. So I should just give up

Well, that is unfortunate, thank you friends

He probably used one of these (or similar): Voice Recognition Module v3.1, multi-language commands training Arduino