## Using FFT_test.fcfx

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 6.

Moderator: Benj

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Using FFT_test.fcfx

Hi Ben
I have been studying the above subject Program from the component/DSP/FFT help page, so that I might understand using the DSP-FFT component. I am starting to get a little bit of a handle on it but I have 2 things at the moment that are causing me confusion.

First:
The program uses a couple of delays at the bottom of the Main. Is the delays for demo only and would you then control the frequency of the sample rate with a Timer1 interrupt to control the sample rate in the real world? If not how would you control the sample rate accuracy?

Second:
Would you please explain the calculation Data = Data - 512, Data = Data * 32 after the pot is read.. I see the reference to convert the 10bit ADC to full scale +/- 16 bit, but I don't understand what is really going on. I did note that the FFT component is set for 16 bit accuracy and I am sure that is related. Would you be so kind as to explain the mechanics of that mathematical gyration. I know your converting the number to signed +32k/-32k, but I have never worked with these numbers before, so any elaborating on the mathematics will certainly be enlightening.

I am eagerly looking forward to your replies. If anyone has anything to express on this, PLEASE do so as I know there is a lot of talent on this forum.

Larry

hyperion007
Posts: 528
Joined: Sat Dec 01, 2012 1:23 pm
Location: Sweden
Has thanked: 49 times
Been thanked: 101 times
Contact:

### Re: Using FFT_test.fcfx

Hi Larry,

The: Data = Data - 512, Data = Data * 32

What this does is to take the 10-bit Data, which always is a positive number out of the ADC, and effectively moves the mid point to zero instead of 512.

A 10-bit ADC swing from 0 to 1023. But the FFT needs to have values centered around a 0 midpoint. It doesn't work with only positive numbers.

So, all ADC values less than 512 will become negative.

Then the resolution is increased by the Data * 32 as you correctly said.

But I guess you might want a more in depth explanation than this so hopefully someone else will chime in because I don't know that much about the math behind this.
These users thanked the author hyperion007 for the post (total 2):
SHORTCIRCUIT (Mon May 25, 2015 1:58 pm) • medelec35 (Fri May 29, 2015 9:53 am)
Rating: 10.53%

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Thanks Hyper

That helps a lot!

Larry

Benj
Matrix Staff
Posts: 14432
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4499 times
Been thanked: 4182 times
Contact:

### Re: Using FFT_test.fcfx

Hello,

Controlling the sample rate with a timer is probably the right way to go. When you reach the correct number of samples you can stop the timer from firing and do the FFT calculations.

The data does need to be centred around 0 so that it is positive and negative, this just helps the FFT maths do it's thing. So if an ADC reading is 10-bit and can range from 0-1023 then you would subtract 512 to get values between -512 and 511. I then multiply up to consume more of the range and give bigger FFT frequency bank spikes though this is not strictly necessary if you are pushed for processing time.
These users thanked the author Benj for the post:
SHORTCIRCUIT (Wed May 27, 2015 12:19 pm)
Rating: 5.26%

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Thanks Ben

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi
If I read a bin after the FFT is performed using "ReadFrequencyBank", I see in the help file that a byte will be returned. What will that byte represent? For instance 00 might mean no frequencies in that bin range and inversely FF might mean a large amount of frequencies in that bin range of frequencies or something else? I am surmising that there will only be one byte in each of the bins and I am trying to figure out what the value of that byte represents. Is amplitude represented at all?
Larry

kersing
Valued Contributor
Posts: 1878
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 534 times
Been thanked: 1043 times
Contact:

### Re: Using FFT_test.fcfx

Hi Larry,

The number represents the amount of energy in the bin. If your input has a sine wave with a large amplitude and it is present in that bin the value will be large. If your input has multiple sine waves with smaller amplitude that are in the same bin (frequencies close or large bin) you will still have a large value as the value is the sum of the energy of all frequencies within that bin.

Have you read this introduction to FFT? This application note could be helpful as well.

Best regards,

Jac
These users thanked the author kersing for the post (total 2):
medelec35 (Fri May 29, 2015 9:53 am) • SHORTCIRCUIT (Fri May 29, 2015 1:15 pm)
Rating: 10.53%

“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac

Thank you very much for the reply. That is exactly what I was after. Your explanation helps a lot and the reading references you pointed to are also helpful. I have already scanned through them, but I will have to read them slowly a couple of more times.

Larry

petesmart
Valued Contributor
Posts: 395
Joined: Thu May 06, 2010 11:42 am
Location: Sydney, Australia
Has thanked: 190 times
Been thanked: 140 times
Contact:

### Re: Using FFT_test.fcfx

Thanks Jac for sharing those two articles - really helpful.

best

Pete

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

I modified the FFT_test.fcfx program for 30F4013 chip but it will not program to that chip via the EB064 multi programmer board. Am I doing something wrong.

This is the modified program:
FFT_Test.fcfx

Larry

kersing
Valued Contributor
Posts: 1878
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 534 times
Been thanked: 1043 times
Contact:

### Re: Using FFT_test.fcfx

Larry,

Are you getting any errors? If so, which? May-be you could attach the output?

Looking at the device specification I think you will be running out of RAM, 2048 bytes is not a lot when working with FFT.

Best regards,

Jac
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac

FFT_Test.msg.txt

I can cut the size of the buffers in half or even smaller as I am only interested in Audio up to 1200 HZ

Larry

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

I cut the buffers to 128 and then it seemed to compile to the chip. It didn't run when it got there but at least it got there. That's one step forward.

Larry

kersing
Valued Contributor
Posts: 1878
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 534 times
Been thanked: 1043 times
Contact:

### Re: Using FFT_test.fcfx

The cause is as I suspected:

Link Error: Could not allocate data memory

The flowchart requires too much RAM memory.

The buffer size is linked to the frequency, however you need to take the input filter and required bin size into account. For instance if you want 1200 hertz with a bin size of about 1.2 hertz you would need to 2048 samples at 2400 hz. (Always sample at at least double the frequency of the filter you are using, google Nyquist to see why) However if you are satisfied with 75Hz bins you would only need 32 samples (also 2400 hz sampling).
These users thanked the author kersing for the post:
SHORTCIRCUIT (Sat May 30, 2015 10:10 pm)
Rating: 5.26%

“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Thank you Jac

You were right on. Program is running, but not as expected. I will play with it some more so I may better understand.

Larry

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac
Can you tell me why for the ADC conversion the "RawSampleInt" is used instead of say "Get Int".
Also, the above ref program uses Raw enable only once at the start of the program which seems to simulate ok but when I load it to a real chip the ADC only reads once at start-up. I wrote a test ADC program and inserted a Raw Enable just before the RawSampleInt and the ADC reads it over and over. So is this a mistake in the original FFT_test program or is there something I'm not getting?
Larry

kersing
Valued Contributor
Posts: 1878
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 534 times
Been thanked: 1043 times
Contact:

### Re: Using FFT_test.fcfx

Hi Larry,

I haven't looked at the FFT_test program in detail, however I know the Raw functions have been added to Flowcode to speed up ADC sampling. The regular ADC routines contain code to switch the pin to analog mode, configure the ADC to read the correct pin, wait a bit, take a sample and switch the pin back to digital mode. As this takes a (relative of course) lot of cycles the raw versions have been added to speed things up. The RawEnable call sets the pin to the correct mode and configures the ADC. This allows subsequent RawSampleInt calls to skip the setup and wait time and just read the value. So there is no need to call RawEnable multiple times. (You just can't use any other ADC at the same time as it would interfere with the settings)

Best regards,

Jac
These users thanked the author kersing for the post:
SHORTCIRCUIT (Mon Jun 01, 2015 11:09 pm)
Rating: 5.26%

“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac

Thank you for the response. I am wondering if there is an error in Flowcode 6 for chip 30F4013. I did a search and found nothing. I am using AN8 which is on Port BH.
I wrote a program to just read ADC using RawSampleInt with raw enable at the start of the program and it would only read the ADC once. Then I moved the raw enable just before the rawsample in the loop part of the program and the ADC would now read repeatedly. In simulation the raw enable only once worked as you described but not on the chip.

Thank you for your help, I learned a lot from you.

Larry

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Ben

Please check the attached program. ADC does not seem to be working as expected. with raw enabled the adc only reads 1 time when the program is loaded to the chip. Yet in simulation it works ok.

Larry

Benj
Matrix Staff
Posts: 14432
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4499 times
Been thanked: 4182 times
Contact:

### Re: Using FFT_test.fcfx

Hello,

In the CAL I was re-enabling the ADC by doing this.

Code: Select all

`      AD1CON1bits.SAMP = 1;      AD1CON1bits.SAMP = 0;                           //begin next conversion`

However this was causing the lock up.

The code has now been changed to this which limits the max sample speed slightly but works as expected and is still more efficient for sampling a single ADC channel then calling the simple sample functions.

Code: Select all

`      ADCON1bits.SAMP = 1;      delay_us(1);                                 //wait the acquisition time      ADCON1bits.SAMP = 0;                           //begin next conversion`

I tried simply adding no operation commands but these did not work to solve the problem.

To fix the bug copy the file below into your "C:\Program Files (x86)\Flowcode 6\CAL\PIC16BIT" directory and recompile your project.

Let me know how your getting on.
These users thanked the author Benj for the post:
SHORTCIRCUIT (Tue Jun 02, 2015 2:05 pm)
Rating: 5.26%

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Ben
It now works as expected.
Larry

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac
Would you please take a look at my FFT program, does not seem to work right.

FFT_Test_2.fcfx

Larry

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Benj
I sent you a PM asking you to check the above post with no reply. I need to know if I am doing something wrong or if there is a problem with the FFT module because the program seems to simulate ok but does not work properly after it has been compiled to chip.
Larry

kersing
Valued Contributor
Posts: 1878
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 534 times
Been thanked: 1043 times
Contact:

### Re: Using FFT_test.fcfx

Hi Larry,

First of all, it would help if you specify what you expect and what does (not) happen. Now I'm left guessing what you mean by 'does not work right'. And my guesses may be totally of the mark...

First thing I notice is the disable/enable TMR1 in the interrupt routine. This results in the warning (did you notice it?? The compiler output can contain valuable clues):
FFT_Test_2.c:3830:3: warning: #warning "This interrupt has previously been enabled, so the macro <Timer_tick> may never get called."

This is might well be the reason your code does not behave like expected.

Second, I would not process the FFT in the interrupt. I would set a flag (and disable INT1) and have the main loop check that flag. Once the flag is set you can process the data in the main loop. After processing restart sampling by clearing the flag and enabling INT1.

Attached the revised code, untested as I do not have the hardware required. One thing I left for you to work out, by starting with Count = 1 and comparing Count to 32, how many samples are you collecting?? (31 or 32?)

Best regards,

Jac
Attachments
FFT_Test_2_mod.fcfx
These users thanked the author kersing for the post (total 2):
medelec35 (Sat Jun 06, 2015 10:08 am) • SHORTCIRCUIT (Sat Jun 06, 2015 12:59 pm)
Rating: 10.53%

“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

SHORTCIRCUIT
Posts: 152
Joined: Thu Feb 10, 2011 4:39 am
Has thanked: 40 times
Been thanked: 19 times
Contact:

### Re: Using FFT_test.fcfx

Hi Jac

Thank you very much for your reply. I did not know that about the Interrupt and there are so many warnings that I do not know how to interpret I basically ignore them which I guess is not smart. Every time you post I learn something. I corrected the read data 31 to 32 by changing the count to 0..

The program simulates in flowcode but still does not work on the chip. I am posting a photo showing the gLCD display while running on my test board. The photo indicates that all the frequencies are present, but I am only injecting 1frequency (500 hz) via AN8.
FFT.jpg (16.5 KiB) Viewed 11945 times

Any comments or suggestions will be greatly appreciated.

Larry