Fast Fourier Transform (FFT) (Part 7)

Part 1234567891011

Those who exercized the library and tried to change the default value from the customizable variables (and most probably the size of both data vectors) probably faced some lockups, inifinite loops or unpredicted operations.

In most cases, the answer to these problems lies in the limited size of the arduino memory… Let’s be positive and study this subject.

Depending upon the type of Arduino platform, you may use one of these microprocessors:

  • Arduino Diecimila: ATMega168 (data sheet)
  • Arduino Duemilanove: ATMega368 (data sheet)
  • Arduino Uno: ATmega328 (data sheet)For other platforms, follow this thread
    For older platforms, follow this threadEach of these microprocessors has three separate memories:
  • FLASH memory: this is a non volatile memory space where the sketch is stored
  • SRAM (Static Random Access Memory): this is the memory sapce where the sketch creates and manipulates variables at run time
  • EEPROM (Electrically-Erasable Programmable Read-Only Memory): this is a non volatile memory space where data can be read/write at run time. This memory has limitations: the number of read/write cycle is estimated to be no more than 100.000, and it takes real time to get access to it
  • Let’s go back to our problem. The size of the SRAM (where the vectors are created at run time) depends upon the microprocessor:
  • ATMega168: 1024 bytes
  • ATMega368: 2048 bytes
  • That is not much… and every byte counts!Now let’s consider the vectors. Firstly, we have to decide about the type of data to be recorded:
  • boolean or char or unsigned char or byte or uint8_t: 1 byte each
  • int or unsigned int or uint16_t or int16_t: 2 bytes each
  • long or unsigned long or uint32_t or int32_t: 4 bytes each
  • float or double: 4 bytes each
  • For more information on data types, follow this threadThis means that the following vectors will occupy:
    byte vX[32]; // 32*8=256 bytes
    int vX[32]; // 32*16=512 bytes
    float vX[32]; // 32*32=1024 bytes

    So that it is a good idea to check the available memory space prior to running sketches. This how you can do this:

    int memoryTest() {
    // This function will return the number of bytes currently free in SRAM
      int byteCounter = 0; // initialize a counter
      byte *byteArray; // create a pointer to a byte array
      // Use the malloc function to repeatedly attempt allocating a certain number of bytes to memory
      while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
        byteCounter++; // If allocation was successful, then up the count for the next try
        free(byteArray); // Free memory after allocating it
      }
      free(byteArray); // Also free memory after the function finishes
      return byteCounter; // Send back the number number of bytes which have been successfully allocated
    }

    This code has been written by Rob Faludi

    Next post on same subject

2 Comments

  1. qwertygin says:

    Hi Didien,nice work you’ve done!! 🙂
    So i guess the attiny85 is out of the question due to memory issues (0.5KB sram) and not processing power.
    could it be possible though considering a very small sampling window?

    • Didier says:

      If you are just considering very low resolution frequency spectra for fancy audio spectrum display (say 16 bars), low adc resolution (8 bits) if you get rid of the signal weighing (box car), and to the cost of some code optimization (in place calculations) you need no more than (nbr. of bars * 2 * (1 + 4 + 4)) bytes for the vectors of data, which is affordable for small sized RAM chips. But again, this spectrum will good enough for fun not for ‘quasi’ instrumentation.

Leave a Reply

You must be logged in to post a comment.