Arduino FFT, spektrum analizátor lcd-vel

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
rephlex
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2013. augusztus 1. csütörtök, 13:09

Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: rephlex »

Sziasztok!
A segítségeteket szeretném kérni. Egy audio spektrum analizátor építésébe fogtam egy 20x4-es lcd-vel, a kódot nem magamtól írtam mert annyira nem látom át a működését :oops: , módosítottam hogy custom character-el és lcd-vel működjön a kijelzés az eredeti led shield helyett de frekvencia generátorral tesztelve mégsem úgy működik ahogy kéne, nem emelkednek egymás után az oszlopok végig, hanem össze vissza.. Bár a kijelzés teljesen olyan amilyennek kéne lenni :mrgreen: . Az eredeti link: http://shin-ajaran.blogspot.hu/2011/07/ ... lyzer.html

include <fix_fft.h>

#define AUDIOPIN 1
#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 4, 9, 10, 11, 12);


char im[128], data[128];

char data_avgs[14];

int i=0,val;

byte level0[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
byte level1[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte level2[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte level3[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte level4[8] = { 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level5[8] = { 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level6[8] = { 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level7[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};


void setup() {
lcd.begin(20, 4);
lcd.clear();
lcd.createChar(0,level0);
lcd.createChar(1,level1);
lcd.createChar(2,level2);
lcd.createChar(3,level3);
lcd.createChar(4,level4);
lcd.createChar(5,level5);
lcd.createChar(6,level6);
lcd.createChar(7,level7);

}
void loop() {
for (i=0; i < 128; i++){
val = 5000 * analogRead(AUDIOPIN); //shin: analog sig not detected from laptop audio out. scale to 5000
data = val;
im = 0;
};

fix_fft(data,im,7,0);

for (i=0; i< 64;i++){
data = sqrt(data * data + im * im); // this gets the absolute value of the values in the array, so we're only dealing with positive numbers
};


// average bars together
for (i=0; i<14; i++) {
data_avgs = data[i*4] + data[i*4 + 1] + data[i*4 + 2] + data[i*4 + 3]; // average together
data_avgs = map(data_avgs, 0, 30, 0, 7); // remap values for LoL
}
for (int x=0; x < 14; x++) {
for (int y=0; y < 7; y++) {
if (y < data_avgs[13-x]) { // 13-x reverses the bars so low to high frequences are represented from left to right.
lcd.setCursor(x,0);
lcd.write(y);
}
}
}}
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

És mit szeretnél? Eddig mi volt a kísérlet tárgya? Milyen eredménnyel?
rephlex
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2013. augusztus 1. csütörtök, 13:09

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: rephlex »

Az a baj ha elkezdem növelni a frekvenciát mondjuk 100Hz-től 10 KHz-ig akkor nem szépen sorban emelkednek az oszlopok hanem össze vissza, valószínűleg ahogy módosítottam a kódot az nem jó, (vagy mégis és máshol kéne keresnem a hibát?) sajnos ebben nem vagyok biztos ezért kérdeztem a fórumban. Egyébként egy VLF vevő kimenetére akarom majd spektrum analizátornak. http://www.auroralchorus.com/bbb4rx3.htm
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

Igen. Az LCD kezelés _nagyon_ időigényes az Arduino alatt. És így az ADC sebessége leesik kicsire:(...

Ezért volt eredetileg LED a kimeneten.... Az azonnal megjelenik...
LED: kb 10-100 usec válaszidő, LCD: 5-60 msec!
dlaszlo
DrótVégénSzéndarab
Hozzászólások: 49
Csatlakozott: 2013. április 20. szombat, 6:38

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: dlaszlo »

Érdekes feladat :) Az esetleg megérhet egy próbálkozást, hogy nem minden ciklusban LCD-zel, ha az lassú, hanem csak ha már van értelmes feldolgozott adat, pl másodpercenként frissítenéd az LCD-t. (csak egy ötlet...)

de ez mit is csinál?

Kód: Egész kijelölése

for (int x=0; x < 14; x++) {
for (int y=0; y < 7; y++) {
if (y < data_avgs[13-x]) { // 13-x reverses the bars so low to high frequences are represented from left to right.
lcd.setCursor(x,0);
lcd.write(y);
} 
}
Megpróbáltam értelmezni ezt a kódót, nem sikerült, jól látom hogy az X oszlophoz ugrik egymás után (maximum) hétszer, és ugyanott frissít, lehet hogy többször is, az if-en múlik?

Ha ez tényleg jó, akkor a belső ciklus helyett már ilyesmit is írhatnál nem? (az ilyesmit aláhúztam :) )

Kód: Egész kijelölése

for (int x=0; x < 14; x++) {
lcd.setCursor(x,0);
if (data_avgs[13-x] < 7) { // 13-x reverses the bars so low to high frequences are represented from left to right.
lcd.write(data_avgs[13-x]);
}
else
{
lcd.write(6);
}
}
Egy másik kérdés: Ha a belső IF nem teljesül (az eredeti kódban), mert változik a data_avgs tartalma, akkor abban az X pozícióban mi töröl az LCD-ről? (ez simán okozhat "ugrálást", folyamatos növekedés helyett (elvileg))

de nem értem mit akar csinálni a kód amit bevágtál, lehet hogy nagyon elnézem, félreértelmezem, de elsőre nem úgy tűnik, mint ami jó.

Még egy dolog (ez is csak ötlet), a folyamatos setCursor helyett egy menetben is frissítheted az LCD-t, előtte a memóriába szedd össze a String-edet. (bár lehet hogy az arduino API pont így működik, nem ismerem). Biztos van ennél ezerszer jobb megoldás, de én így csináltam egy progiban:
https://github.com/dlaszlo/LCDClock/blo ... /LCD/LCD.h
https://github.com/dlaszlo/LCDClock/blo ... CD/LCD.cpp
Ez az osztály a LiquidCrystal-ból származik, egy buffert kezel, itt a clearBuffer-el törlöm a memóriát (pl a ciklus elején), a setText-el, center-el, right-al írok bele, és a végén a show jeleníti meg. (pont azért, hogy ne kelljen mindig képernyőt törölgetni, és setCursort hívogatni, úgy sokat kellene variálni, szerintem nem jól használható)
dlaszlo
DrótVégénSzéndarab
Hozzászólások: 49
Csatlakozott: 2013. április 20. szombat, 6:38

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: dlaszlo »

Csak egy kiegészítés: Csak közben észrevettem az első linket, amit írtál :P

Ott van ez a kód:

Kód: Egész kijelölése

  for (int x=0; x < 14; x++) {
   for (int y=0; y < 9; y++) {
     if (y < data_avgs[13-x]) { // 13-x reverses the bars so low to high frequences are represented from left to right.
      LedSign::Set(x,y,1);        // set the LED on
     } else {
       LedSign::Set(x,y,0);       // set the LED off
     }
   } 
  }
ezt viszont már értem (ezt a led-es kódot), az előző post-omban már biztosabb vagyok. :)

Üdv!
rephlex
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2013. augusztus 1. csütörtök, 13:09

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: rephlex »

Robert, most hogy említetted a lassú lcd-t beugrott a tanfolyamról.. Lefuttattam a tesztet 340 us sebességek jöttek ki. Gondoltam bekötöm az RW lábat és átírom a programot de ugyanaz volt a sebesség(nem használja akkor automatikusan ezt az opciót?).... Most elkezdtem keresgélni meddig csökkenthetném a delay-eket a lcd libraryban.

Dlaszlo eredetileg ledekkel működött a kapcsolás multiplexálva, ahogy én értelmeztem 14 oszlopot léptet és az eredeti 9 ledet villogtatta oszloponként, ezt változtattam meg hogy 8 custom charactert írjon a kijelzőre több kevesebb sikerrel. Egyébként amit linkeltél kódot kipróbáltam és ugyanúgy működik vele mint eddig, szóval te jobban megértetted mint én :mrgreen: . Most újramértem az egészet frekvencia generátorral, szinusz jellel, sokkal kisebb jelszintel, 3-400mV-al. Azt tapasztaltam hogy most szépen sorban emelkednek az oszlopok, viszont van pár oszloppal odébb ami alacsonyabb és követi a nagyobb amplitudójú jelet, lehet hogy ezek felharmonikusok? Elképzelhető hogy ezért működött össze vissza mert túl nagy volt a jelszint és a felharmonikusok is túl nagyok voltak? (lehet hülyeséget beszélek).

Ennél a sornál vajon miért szorozza meg 5000-el a mért jelet? : val = 5000 * analogRead(AUDIOPIN); //shin: analog sig not detected from laptop audio out. scale to 5000 .


Lehet hogy ezzel a sorral tudok változtatni az érzékenységén? Utána olvastam a parancsnak és úgy tűnik mintha átváltaná az értékeket : data_avgs = map(data_avgs, 0, 30, 0, 9); // remap values for LoL .

String-nek pedig majd utána nézek és kipróbálom hogyan változik.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

map(0,100,x,y) : a 0...100 értéket arányosítja a x....y értékekhez.

A programvisszafejtést, köszönöm nem kérem :)....
Meghagyom másnak...

A felharmonikus helyett inkább: adott egy szinuszod. Mondjuk 50 Hz. Ha 60 Hzvel veszel mintát: mit kapsz?
Rajzold le!

Egyszerű: egy elnyújtott 10 Hz-es jelet kapsz eredményül.....
rephlex
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2013. augusztus 1. csütörtök, 13:09

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: rephlex »

Gondolom akkor megint az a probléma hogy lcd-vel túl lassú az egész és nincs meg a kétszeres mintavételezési frekvencia a bemenő jelhez képest.. Lehet inkább máshogy csinálom meg, műveleti erősítős sávszűrőkkel, mondjuk tl074 és akkor abból elég 2 a 8 analóg bemenetre (arduino nano). Megmérem a feszültségeket sávonként és az alapján vezérlem az lcd-t. Elvileg úgy jobbnak kéne lennie nem?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

Jobb ötlet:
1. 100 ms : mintavétel+FFT
2. 100 ms : megjelenítés :)
És ez újra meg újra....
Avatar
GPeti
Bitmanipulátor
Hozzászólások: 131
Csatlakozott: 2011. március 3. csütörtök, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: GPeti »

Van speciális IC a BA3830F, nézz utána.
dlaszlo
DrótVégénSzéndarab
Hozzászólások: 49
Csatlakozott: 2013. április 20. szombat, 6:38

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: dlaszlo »

Még egy ötlet: Egyébként az LCD API-ja műveletek közben letiltja az interruptokat? Ha belefér a mikrokontroller idejébe, nem lehet a mintavételezést, és az FFT-t a timer interrupt-on csinálni? Egyébként is hiányoltam ebből a progiból, hogy nem lehet tudni a mintavételezési frekvenciát, nem értek az FFT-hez, de logikusnak hangzana, hogy kell az hozzá, nem pedig csak úgy mintavételezni, ahogy sikerül, a mostani kódban ennyi van:

Kód: Egész kijelölése

for (i=0; i < 128; i++){ 
val = 5000 * analogRead(AUDIOPIN); //shin: analog sig not detected from laptop audio out. scale to 5000 
data[i] = val; 
im[i] = 0; 
};
WIKI: "A gyors Fourier-transzformáció (FFT = Fast Fourier Transform) a diszkrét Fourier-transzformált kiszámítására szolgál. Ehhez N = 2^n , egyenközű mintavétel szükséges, ahol n > 6. Műveletigénye N log N, A mintavételezés frekvenciáját úgy kell választani, hogy legalább kétszer akkora legyen, mint a maximális feldolgozandó frekvencia, különben torz kép jön létre. Több perióduson át kell mintavételezni úgy, hogy a mintavételezés máshova essen az egyes periódusokban. Például, ha a jel frekvenciája 1 kHz, akkor jobb 2100 Hz-cel mintavételezni, mint 2000-rel, és még jobb mondjuk 4100 Hz-cel, vagy még ennél is nagyobb frekvenciával."

Ha az interrupt használható, az LCD futna, amikor tud futni (ha nem ütközik az interrupt-okkal az LCD használat).

Amúgy mégy egy dolog, figyelj, hogy <7-et írsz az LCD megjelenítős kódba, vagy <=7-et, vagy inkább <8-at, mert mintha egy használható értéket most elvesztenél. Illetve ha jól látom teljesen 0 szint most nincs is, mert az is egy vonal _ a kijelzőn.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

Az Arduino esetén a LCD kezelés el van baltázva. A belső késleltetés delay()-l működik, ami interrupt alapúan használja a Timer 0-t:(
rephlex
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2013. augusztus 1. csütörtök, 13:09

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: rephlex »

Dlaszlo igen jól látod egy _ van 0 bemenetnél is minden oszlop első sorában, viszont hiába változtatom <8-ra az értéket ez így is marad.. Amit még észrevettem hogy az általad módosított kódnál ha menet közben leteszem a bemenetet földre akkor beáll _-ra az összes oszlop, viszont az általam módosítottnál pedig minden megmarad az utolsó állapotnál, nem állnak be az oszlopok a legkisebb jelszintre.

Robert a 100ms mintavétel és a 100ms kijelzésnél arra gondoltál hogy rakjam a mintavételezést és az FFT egy for ciklusba és átlagoljam vagy töltsek fel változókat és utána írjam ki az lcd-re?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino FFT, spektrum analizátor lcd-vel

Hozzászólás Szerző: Robert »

100 msec-ig vegyél mintát és értékeld ki. Utána meg írd ki LCD-re...
Lassabb jelnél a 100 msec minta lehet túl rövid időciklus...
Válasz küldése