user50429: I'm trying to analyse mic (A0) input, calculate certain spectral lines with Goertzel algorithm to detect a number encoded by DTFM and display it with 8x8 matrix display (max7219 driver).
The code works perfectly fine without a display sending the result to serial, however when I added a display, strange things started to happen.

if goertzel(..) is called before displayDigit the display doesn't show anything
if displayDigit is called first the output of goertzel(..) is a complete mess
if I comment out 1 line in goertzel(..) which is amp = sqrt(re * re + im * im); // [1] the display works (but it doesn't make sense)

I'm using Arduino UNO, ADC in free-run mode. 
The code below:
/**
 * 8x8 LED matrix display with MAX7219 driver
 * +5V, GND, CLK (8 pin), CS (9 pin), DIN (10 pin)
 */
#include <binary.h> 
#include <LedControl.h>

#include "font8x8.h"

#define N           256
#define IX_LEN      8
#define THRESHOLD   20

/* Display PINs */
#define CLK     13//8
#define CS      12 //9
#define DIN     8 //10

LedControl matrix = LedControl(DIN, CLK, CS, 1);
int8_t lastDetectedDigit = -1;
int8_t currentDigit = -1;
uint32_t lastDetectedMillis = 0;

const int adc_channel = 0;

volatile uint16_t samples[N];
volatile uint16_t samplePos = 0;

float spectrum[IX_LEN] = {0,0,0,0,0,0,0,0};

// Frequences [697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0, 1633.0]
// Corresponding spectrum indexes [18, 20, 22, 25, 32, 35, 39, 43]

// Calculated for 9615Hz 256 samples  
const float cos_t[IX_LEN] = {
  0.9039892931234433, 0.881921264348355, 0.8577286100002721, 0.8175848131515837, 
  0.7071067811865476, 0.6531728429537769, 0.5758081914178454, 0.49289819222978415
  };

const float sin_t[IX_LEN] = {
  0.4275550934302821, 0.47139673682599764, 0.5141027441932217, 0.5758081914178453, 
  0.7071067811865475, 0.7572088465064845, 0.8175848131515837, 0.8700869911087113  
  };

const char table[4][4] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

const uint8_t char_indexes[4][4] = {
  {0, 1, 2, 12},
  {3, 4, 5, 13},
  {6, 7, 8, 14},
  {10, 9, 11, 15}
};


void initADC() {
  // Init ADC; f = ( 16MHz/prescaler ) / 13 cycles/conversion 
  ADMUX  = adc_channel; // Channel sel, right-adj, use AREF pin
  ADCSRA = _BV(ADEN)  | // ADC enable
           _BV(ADSC)  | // ADC start
           _BV(ADATE) | // Auto trigger
           _BV(ADIE)  | // Interrupt enable
           _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
//  ADCSRB = _BV(ADTS2) | _BV(ADTS0);              // Timer/Counter1 Compare Match B
  ADCSRB = 0; // Free-run mode
  DIDR0  = _BV(adc_channel); // Turn off digital input for ADC pin      
}

void goertzel(volatile uint16_t *samples, float *spectrum) {
  float v[N + 2];
  float re, im, amp;

  for (uint8_t k = 0; k < IX_LEN; k++) {
    float a = 2. * cos_t[k];
    v[0] = v[1] = .0;    
    for (uint16_t i = 2; i < N + 2; i++) {
      v[i] = float(samples[i - 2]) + a * v[i - 1] - v[i - 2];      
    }
    re = cos_t[k] * v[N + 1] - v[N];
    im = sin_t[k] * v[N + 1];
    amp = sqrt(re * re + im * im); // [1]
    spectrum[k] = amp;        
  } 
}

float avg(float *a, uint16_t len) {
  float result = .0;
  for (uint16_t i = 0; i < len; i++) {
    result += a[i];
  }
  return result / len;
}

int8_t get_single_index_above_threshold(float *a, uint16_t len, float threshold) {

  if (threshold < THRESHOLD) {
    return -1;
  }

  int8_t ix = -1;
  for (uint16_t i = 0; i < len; i++) {
    if (a[i] > threshold) {
      if (ix == -1) {
        ix = i;
      } else {
        return -1;
      }
    } 
  }
  return ix;  
}

char detect_digit(float *spectrum) {
  float avg_row = avg(spectrum, 4);
  float avg_col = avg(&spectrum[4], 4);
  int8_t row = get_single_index_above_threshold(spectrum, 4, avg_row);
  int8_t col = get_single_index_above_threshold(&spectrum[4], 4, avg_col);

  if (row != -1 && col != -1) {
    return table[row][col];
  } else {
    return 0;
  }
}

void displayDigit(uint8_t c) {
  if (currentDigit == c) {
    return;
  }

  for (uint8_t i = 0; i < 8; i++) {
    matrix.setColumn(0, 7 - i, IMAGES[c][i]); 
  }
  currentDigit = c;
}

void setup() {  
  cli();
  initADC();
  sei();

  matrix.shutdown(0, false);
  matrix.setIntensity(0, 2);

  Serial.begin(115200);

}

unsigned long z = 0;

void loop() {
  while(ADCSRA & _BV(ADIE)); // Wait for audio sampling to finish

  goertzel(samples, spectrum);   
  samplePos = 0;

//  if (z % 25 == 0) {
    displayDigit(2); 

    for (int i = 0; i < IX_LEN; i++) {
      Serial.print(spectrum[i]);
      Serial.print("\t");
    }
    Serial.println();
    char digit = detect_digit(spectrum);
    Serial.println(digit);
//  }
  z++;



  ADCSRA |= _BV(ADIE);       // Resume sampling interrupt
}

ISR(ADC_vect) { 
  uint16_t sample = ADC;

  samples[samplePos++] = sample;

  if(samplePos >= N) {
    ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
  }
}

font8x8.h:
const byte IMAGES[16][8] = {
{
  B00001000,
  B00011000,
  B00001000,
  B00001000,
  B00001000,
  B00001000,
  B00001000,
  B00011100
},{
  B00111100,
  B01000010,
  B01000010,
  B00000100,
  B00011000,
  B00100000,
  B01000000,
  B01111110
},{
  B00111100,
  B01000010,
  B00000010,
  B00000100,
  B00000100,
  B01000010,
  B01000010,
  B00111100
},{
  B00010100,
  B00100100,
  B00100100,
  B01000100,
  B01111110,
  B00000100,
  B00000100,
  B00000100
},{
  B00111110,
  B01000000,
  B01000000,
  B01111100,
  B00000010,
  B00000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000010,
  B01000000,
  B01111100,
  B01000010,
  B01000010,
  B01000010,
  B00111100
},{
  B00111110,
  B01000010,
  B00000100,
  B00000100,
  B00001000,
  B00001000,
  B00010000,
  B00010000
},{
  B00111100,
  B01000010,
  B01000010,
  B00111100,
  B01000010,
  B01000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000010,
  B01000010,
  B01000010,
  B00111110,
  B00000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000110,
  B01001010,
  B01010010,
  B01010010,
  B01010010,
  B01100010,
  B00111100
},{
  B00000000,
  B01010100,
  B00111000,
  B01111100,
  B00111000,
  B01010100,
  B00000000,
  B00000000
},{
  B00101000,
  B00101000,
  B11111110,
  B00101000,
  B11111110,
  B00101000,
  B00101000,
  B00000000
},{
  B00011100,
  B00100010,
  B00100010,
  B01000010,
  B01111110,
  B01000010,
  B01000010,
  B01000010
},{
  B01111100,
  B01000010,
  B01000010,
  B01111100,
  B01000010,
  B01000010,
  B01000010,
  B01111100
},{
  B00111100,
  B01000010,
  B01000000,
  B01000000,
  B01000000,
  B01000000,
  B01000010,
  B00111100
},{
  B01111000,
  B01000100,
  B01000110,
  B01000010,
  B01000010,
  B01000010,
  B01000010,
  B01111100
}};

I use LedControl.h library but inside is uses only digitalWrite, no timing, interrupts.
Can somebody explain what is the problem?
UPD
This is what IDE tells me about the sizes:
Sketch uses 5602 bytes (17%) of program storage space. Maximum is 32256 bytes.
Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000 bytes for local variables. Maximum is 2048 bytes.

This is LedControl library I'm using

user7508: From your recent edit:

Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000
  bytes for local variables. Maximum is 2048 bytes.

Your goertzel() function defines this
float v[N + 2];

where N is 256. This alone takes 258×4 = 1032 bytes of
stack and you only have 1000 bytes available. Then, as I suspected,
you are smashing the stack against the .bss section, effectively
overwriting some of your global variables with the local ones.
It is hard to predict what can happen in such circumstances. The program
is corrupting its memory: you can only expect it to act erratically.

50429: <p>I'm trying to analyse mic (A0) input, calculate certain spectral lines with Goertzel algorithm to detect a number encoded by DTFM and display it with 8x8 matrix display (max7219 driver).</p>

<p>The code works perfectly fine without a display sending the result to serial, however when I added a display, strange things started to happen.</p>

<ul>
<li><p>if <code>goertzel(..)</code> is called before <code>displayDigit</code> the display doesn't show anything</p></li>
<li><p>if <code>displayDigit</code> is called first the output of <code>goertzel(..)</code> is a complete mess</p></li>
<li><p>if I comment out 1 line in <code>goertzel(..)</code> which is <code>amp = sqrt(re * re + im * im); // [1]</code> the display works (but it doesn't make sense)</p></li>
</ul>

<p>I'm using Arduino UNO, ADC in free-run mode. </p>

<p>The code below:</p>

<pre><code>/**
 * 8x8 LED matrix display with MAX7219 driver
 * +5V, GND, CLK (8 pin), CS (9 pin), DIN (10 pin)
 */
#include &lt;binary.h&gt; 
#include &lt;LedControl.h&gt;

#include "font8x8.h"

#define N           256
#define IX_LEN      8
#define THRESHOLD   20

/* Display PINs */
#define CLK     13//8
#define CS      12 //9
#define DIN     8 //10

LedControl matrix = LedControl(DIN, CLK, CS, 1);
int8_t lastDetectedDigit = -1;
int8_t currentDigit = -1;
uint32_t lastDetectedMillis = 0;

const int adc_channel = 0;

volatile uint16_t samples[N];
volatile uint16_t samplePos = 0;

float spectrum[IX_LEN] = {0,0,0,0,0,0,0,0};

// Frequences [697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0, 1633.0]
// Corresponding spectrum indexes [18, 20, 22, 25, 32, 35, 39, 43]

// Calculated for 9615Hz 256 samples  
const float cos_t[IX_LEN] = {
  0.9039892931234433, 0.881921264348355, 0.8577286100002721, 0.8175848131515837, 
  0.7071067811865476, 0.6531728429537769, 0.5758081914178454, 0.49289819222978415
  };

const float sin_t[IX_LEN] = {
  0.4275550934302821, 0.47139673682599764, 0.5141027441932217, 0.5758081914178453, 
  0.7071067811865475, 0.7572088465064845, 0.8175848131515837, 0.8700869911087113  
  };

const char table[4][4] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

const uint8_t char_indexes[4][4] = {
  {0, 1, 2, 12},
  {3, 4, 5, 13},
  {6, 7, 8, 14},
  {10, 9, 11, 15}
};


void initADC() {
  // Init ADC; f = ( 16MHz/prescaler ) / 13 cycles/conversion 
  ADMUX  = adc_channel; // Channel sel, right-adj, use AREF pin
  ADCSRA = _BV(ADEN)  | // ADC enable
           _BV(ADSC)  | // ADC start
           _BV(ADATE) | // Auto trigger
           _BV(ADIE)  | // Interrupt enable
           _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
//  ADCSRB = _BV(ADTS2) | _BV(ADTS0);              // Timer/Counter1 Compare Match B
  ADCSRB = 0; // Free-run mode
  DIDR0  = _BV(adc_channel); // Turn off digital input for ADC pin      
}

void goertzel(volatile uint16_t *samples, float *spectrum) {
  float v[N + 2];
  float re, im, amp;

  for (uint8_t k = 0; k &lt; IX_LEN; k++) {
    float a = 2. * cos_t[k];
    v[0] = v[1] = .0;    
    for (uint16_t i = 2; i &lt; N + 2; i++) {
      v[i] = float(samples[i - 2]) + a * v[i - 1] - v[i - 2];      
    }
    re = cos_t[k] * v[N + 1] - v[N];
    im = sin_t[k] * v[N + 1];
    amp = sqrt(re * re + im * im); // [1]
    spectrum[k] = amp;        
  } 
}

float avg(float *a, uint16_t len) {
  float result = .0;
  for (uint16_t i = 0; i &lt; len; i++) {
    result += a[i];
  }
  return result / len;
}

int8_t get_single_index_above_threshold(float *a, uint16_t len, float threshold) {

  if (threshold &lt; THRESHOLD) {
    return -1;
  }

  int8_t ix = -1;
  for (uint16_t i = 0; i &lt; len; i++) {
    if (a[i] &gt; threshold) {
      if (ix == -1) {
        ix = i;
      } else {
        return -1;
      }
    } 
  }
  return ix;  
}

char detect_digit(float *spectrum) {
  float avg_row = avg(spectrum, 4);
  float avg_col = avg(&amp;spectrum[4], 4);
  int8_t row = get_single_index_above_threshold(spectrum, 4, avg_row);
  int8_t col = get_single_index_above_threshold(&amp;spectrum[4], 4, avg_col);

  if (row != -1 &amp;&amp; col != -1) {
    return table[row][col];
  } else {
    return 0;
  }
}

void displayDigit(uint8_t c) {
  if (currentDigit == c) {
    return;
  }

  for (uint8_t i = 0; i &lt; 8; i++) {
    matrix.setColumn(0, 7 - i, IMAGES[c][i]); 
  }
  currentDigit = c;
}

void setup() {  
  cli();
  initADC();
  sei();

  matrix.shutdown(0, false);
  matrix.setIntensity(0, 2);

  Serial.begin(115200);

}

unsigned long z = 0;

void loop() {
  while(ADCSRA &amp; _BV(ADIE)); // Wait for audio sampling to finish

  goertzel(samples, spectrum);   
  samplePos = 0;

//  if (z % 25 == 0) {
    displayDigit(2); 

    for (int i = 0; i &lt; IX_LEN; i++) {
      Serial.print(spectrum[i]);
      Serial.print("\t");
    }
    Serial.println();
    char digit = detect_digit(spectrum);
    Serial.println(digit);
//  }
  z++;



  ADCSRA |= _BV(ADIE);       // Resume sampling interrupt
}

ISR(ADC_vect) { 
  uint16_t sample = ADC;

  samples[samplePos++] = sample;

  if(samplePos &gt;= N) {
    ADCSRA &amp;= ~_BV(ADIE); // Buffer full, interrupt off
  }
}
</code></pre>

<p><code>font8x8.h</code>:</p>

<pre><code>const byte IMAGES[16][8] = {
{
  B00001000,
  B00011000,
  B00001000,
  B00001000,
  B00001000,
  B00001000,
  B00001000,
  B00011100
},{
  B00111100,
  B01000010,
  B01000010,
  B00000100,
  B00011000,
  B00100000,
  B01000000,
  B01111110
},{
  B00111100,
  B01000010,
  B00000010,
  B00000100,
  B00000100,
  B01000010,
  B01000010,
  B00111100
},{
  B00010100,
  B00100100,
  B00100100,
  B01000100,
  B01111110,
  B00000100,
  B00000100,
  B00000100
},{
  B00111110,
  B01000000,
  B01000000,
  B01111100,
  B00000010,
  B00000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000010,
  B01000000,
  B01111100,
  B01000010,
  B01000010,
  B01000010,
  B00111100
},{
  B00111110,
  B01000010,
  B00000100,
  B00000100,
  B00001000,
  B00001000,
  B00010000,
  B00010000
},{
  B00111100,
  B01000010,
  B01000010,
  B00111100,
  B01000010,
  B01000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000010,
  B01000010,
  B01000010,
  B00111110,
  B00000010,
  B01000010,
  B00111100
},{
  B00111100,
  B01000110,
  B01001010,
  B01010010,
  B01010010,
  B01010010,
  B01100010,
  B00111100
},{
  B00000000,
  B01010100,
  B00111000,
  B01111100,
  B00111000,
  B01010100,
  B00000000,
  B00000000
},{
  B00101000,
  B00101000,
  B11111110,
  B00101000,
  B11111110,
  B00101000,
  B00101000,
  B00000000
},{
  B00011100,
  B00100010,
  B00100010,
  B01000010,
  B01111110,
  B01000010,
  B01000010,
  B01000010
},{
  B01111100,
  B01000010,
  B01000010,
  B01111100,
  B01000010,
  B01000010,
  B01000010,
  B01111100
},{
  B00111100,
  B01000010,
  B01000000,
  B01000000,
  B01000000,
  B01000000,
  B01000010,
  B00111100
},{
  B01111000,
  B01000100,
  B01000110,
  B01000010,
  B01000010,
  B01000010,
  B01000010,
  B01111100
}};
</code></pre>

<p>I use <code>LedControl.h</code> library but inside is uses only digitalWrite, no timing, interrupts.</p>

<p>Can somebody explain what is the problem?</p>

<p><strong>UPD</strong>
This is what IDE tells me about the sizes:</p>

<pre><code>Sketch uses 5602 bytes (17%) of program storage space. Maximum is 32256 bytes.
Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000 bytes for local variables. Maximum is 2048 bytes.
</code></pre>

<p><a href="https://github.com/wayoda/LedControl" rel="nofollow noreferrer">This is LedControl library I'm using</a></p>
 7508: <p>From your recent edit:</p>

<blockquote>
  <p>Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000
  bytes for local variables. Maximum is 2048 bytes.</p>
</blockquote>

<p>Your <code>goertzel()</code> function defines this</p>

<pre><code>float v[N + 2];
</code></pre>

<p>where <code>N</code> is 256. This alone takes 258×4&nbsp;=&nbsp;1032&nbsp;bytes of
stack and you only have 1000&nbsp;bytes available. Then, as I suspected,
you are smashing the stack against the <a href="https://en.wikipedia.org/wiki/.bss" rel="nofollow noreferrer">.bss section</a>, effectively
overwriting some of your global variables with the local ones.</p>

<p>It is hard to predict what can happen in such circumstances. The program
is corrupting its memory: you can only expect it to act erratically.</p>
