Using FFT_test.fcfx
Moderator: Benj
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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
-
- 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.
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.
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- Has thanked: 40 times
- Been thanked: 19 times
- Contact:
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 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.
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.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- Has thanked: 40 times
- Been thanked: 19 times
- Contact:
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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
-
- Valued Contributor
- Posts: 2045
- Joined: Wed Aug 27, 2008 10:31 pm
- Location: Netherlands
- Has thanked: 553 times
- Been thanked: 1081 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
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
“Integrity is doing the right thing, even when no one is watching.”
― C.S. Lewis
― C.S. Lewis
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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: 187 times
- Been thanked: 140 times
- Contact:
Re: Using FFT_test.fcfx
Thanks Jac for sharing those two articles - really helpful.
best
Pete
best
Pete
sorry about that Chief!
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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: Larry
This is the modified program: Larry
-
- Valued Contributor
- Posts: 2045
- Joined: Wed Aug 27, 2008 10:31 pm
- Location: Netherlands
- Has thanked: 553 times
- Been thanked: 1081 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
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
― C.S. Lewis
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- Has thanked: 40 times
- Been thanked: 19 times
- Contact:
Re: Using FFT_test.fcfx
Hi Jac
I think this is the output file you are asking about. 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
I think this is the output file you are asking about. 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
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
Larry
-
- Valued Contributor
- Posts: 2045
- Joined: Wed Aug 27, 2008 10:31 pm
- Location: Netherlands
- Has thanked: 553 times
- Been thanked: 1081 times
- Contact:
Re: Using FFT_test.fcfx
The cause is as I suspected:
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).
The flowchart requires too much RAM memory.Link Error: Could not allocate data 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).
“Integrity is doing the right thing, even when no one is watching.”
― C.S. Lewis
― C.S. Lewis
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
You were right on. Program is running, but not as expected. I will play with it some more so I may better understand.
Larry
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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
-
- Valued Contributor
- Posts: 2045
- Joined: Wed Aug 27, 2008 10:31 pm
- Location: Netherlands
- Has thanked: 553 times
- Been thanked: 1081 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
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
“Integrity is doing the right thing, even when no one is watching.”
― C.S. Lewis
― C.S. Lewis
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Using FFT_test.fcfx
Hello,
In the CAL I was re-enabling the ADC by doing this.
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.
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.
In the CAL I was re-enabling the ADC by doing this.
Code: Select all
AD1CON1bits.SAMP = 1;
AD1CON1bits.SAMP = 0; //begin next conversion
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
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.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- Has thanked: 40 times
- Been thanked: 19 times
- Contact:
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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.
Larry
Would you please take a look at my FFT program, does not seem to work right.
Larry
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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
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
-
- Valued Contributor
- Posts: 2045
- Joined: Wed Aug 27, 2008 10:31 pm
- Location: Netherlands
- Has thanked: 553 times
- Been thanked: 1081 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):
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
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):
This is might well be the reason your code does not behave like expected.FFT_Test_2.c3: warning: #warning "This interrupt has previously been enabled, so the macro <Timer_tick> may never get called."
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
- (18 KiB) Downloaded 336 times
“Integrity is doing the right thing, even when no one is watching.”
― C.S. Lewis
― C.S. Lewis
-
- Posts: 155
- Joined: Thu Feb 10, 2011 4:39 am
- Location: Las Vegas, Nevada USA
- 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. Any comments or suggestions will be greatly appreciated.
Larry
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. Any comments or suggestions will be greatly appreciated.
Larry