LoginSignup
1
3

More than 1 year has passed since last update.

概要

arduinoでfftやってみた。

参考にしたページ。

写真

DSCN0546.JPG

サンプルコード

#include "fix_fft.h"
#include <Adafruit_GFX.h>
#include "Adafruit_TFTLCD.h"

#define LCD_CS              A3
#define LCD_CD              A2
#define LCD_WR              A1
#define LCD_RD              A0
#define LCD_RESET           A4
#define BLACK               0x0000
#define BLUE                0x001F
#define RED                 0xF800
#define GREEN               0x07E0
#define CYAN                0x07FF
#define MAGENTA             0xF81F
#define YELLOW              0xFFE0
#define WHITE               0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define SAMPLING_FREQUENCY      15000
#define TIME_FACTOR             2
#define SCALE_FACTOR            8
#ifdef LOG_OUTPUT
const float log_scale = 64. / log(64. / SCALE_FACTOR + 1.);
#endif
const float coeff = 1. / TIME_FACTOR;
const float anti_coeff = (TIME_FACTOR - 1.) / TIME_FACTOR;
const unsigned int sampling_period_us = round(1000000 * (2.0 / SAMPLING_FREQUENCY));
int8_t data[64],
    buff[32],
    peak[32];
unsigned long microseconds;
int summ,
    avg;
const char SPLASH_TITLE[] = "SPECTRUM SPEAKER\n @nori-dev-akg";
unsigned long t0;

void setup() {
    OSCCAL = 250;
    ADCSRA &= ~(bit(ADPS0) | bit(ADPS1) | bit(ADPS2));
    ADCSRA |= bit(ADPS2);
    ADCSRA |= bit(ADPS0);
    tft.reset();
    uint16_t identifier = 0x9341;
    tft.begin(identifier);
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    //tft.setRotation(3);
    t0 = millis();
};

void loop() {
    tft.fillScreen(BLACK);
    summ = 0;
    for (int i = 0; i < 64; i++)
    {
        microseconds = micros();
        int val = analogRead(A0);
   val = random(256);
        data[i] = (val >> 2) - 128;
        summ += data[i];
        while (micros() < (microseconds + sampling_period_us))
        {
        }
    }
    avg = summ / 64;
    for (int i = 0; i < 64; i++)
    {
        data[i] -= avg;
    }
    fix_fftr(data, 6, 0);
    int8_t reordered[32];
    for (int i = 0; i < 32; i++)
    {
        if (i % 2 != 0)
            reordered[i] = data[i / 2 + 16];
        else
            reordered[i] = data[i / 2];
    }
    for (int i = 0; i < 32; i++)
        data[i] = reordered[i];
    for (int count = 0; count < 32; count++)
    {
        if (data[count] < 0)
            data[count] = 0;
#ifdef LOG_OUTPUT
        else
            data[count] = log_scale * log((float) (data[count] + 1));
#else
        else
            data[count] *= SCALE_FACTOR;
#endif
        data[count] = (float) buff[count] * anti_coeff + (float) data[count] * coeff;
        buff[count] = data[count];
        if (data[count] > 63)
            data[count] = 63;
    }
    uint8_t x,
        y;
    int d;
    for (int i = 0; i < 32; i++)
    {
        d = data[i] / 2;
        x = i * 8;
        y = 200 - (d + 1) * 4;
        tft.fillRect(x, y, 7, 200 - y, WHITE);
        peak[i] = (peak[i] > y || peak[i] == 0) ? y : peak[i];
        //tft.drawLine(x, peak[i], x + 2, peak[i], RED);
    }
    unsigned long t = millis();
    if (t - t0 > 200)
    {
        for (int i = 0; i < 32; i++)
        {
            peak[i]++;
            if (peak[i] > 31)
                peak[i] = 31;
        }
        t0 = t;
    }
 delay(300);
}





以上。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3