- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear All,
Is there a way to access ADC data faster than the command given below:?
vol= ADC_SAR_CountsTo_Volts(ADC_SAR_GetResult16());
It costing around 10 us at least to get value in vol. Even though I am getting 1 Msps which can be seen via eoc pin.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It depends on what you want to perform. Collecting data with 1 Msps is one thing, question is: How many items and how often and what to do with the results. Can you be a bit more specific about your complete project or are you just searching for the limits?
One way out is DMA or directly accessing the ADC results which are stored in an array.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for quick response.
I am trying to implement a digital PI controller for a DC-DC converter. The switching frequency of the converter is 100 kHz (10 us). SOC pin is connected to the rising edge of the PWM and at EOC (@ 1 Msps) an ISR is initiated to load value via the command that I wrote in my first comment followed by 3-4 multiplications related to PI variables. I want ISR to finish these tasks before next cycle of PWM but only fetching a value from ADC is consuming time more than PWM period i.e., 10 us.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The ADC_SAR_CountsTo_Volts() API uses a calculation as y= ax +b which you may omit in your own calculations. ISR call consumes some time as well, saving the registers and changing the context is not done in zero time. Polling may be faster.
The GCC is so "smart" that just setting a flag in an interrupt handler (no multiplication!!) is quite a lot faster, because only a few registers are needed to be saved.
Put your code in a separate file and after testing set the optimization for this file to "speed" which will keep the rest of the project still debuggable.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What if I want to access that array containing ADC's values that you talked about in your first reply?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look into the ADC_SAR_Seq_finalArray in the .h file (Near line 33)
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
but how to access it into main.c and in to the ISR initiated by EOC of ADC?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A reference to a document and project would be appreciated .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ADC_SEQ_Sar datasheet tells about DMA filling the array at end of conversion. Array declaration is (already!) included in .h file, so you can access the array directly from main(). Channel 0 is element 0 and so on...
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Undefined Reference!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So you are not using the sequenced ADC.
(int16) CY_GET_REG16(ADC_SAR_1_SAR_WRK_PTR);
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are two sources of interrupt: EOC (end of conversion) and EOS (end of sampling). The EOS will return raw conversion results in a buffer. The EOS fires as soon as ADC register ready, which is slightly less than 1 us. The EOC will take >1us to fire, and at 1MHz sampling rate it appears few sampling cycles after the original EOC. It still happens at 1MHz rate, but grossly delayed.
I suggest using an interrupt connected to EOS, where you read raw results ADC_SAR_GetResult16(). Do not convert your data to floating numbers, as float multiply takes about 80 CPU ticks, and even at 80 MHz bus clock it takes entire time slot available (1us). Using int16 will save some CPU ticks, but not much (~20 tick to multiply), using int32 is worse than float, and double is ~10% faster(?) than float. Saying that, it is hard to perform entire PI in 1us. Even if you squeeze it down, the CPU will be 100% consumed - no room for any other code running - it will immediately break PI loop determinism.
Two other approaches remain: (i) use Digital Filter Block to write your own PI code in assembler. Check this and other posts of <Magnus Lundin> and <matejs>:
http://www.cypress.com/forum/psoc-5-device-programming/psoc-5lp-dfb-assembler
http://arttools.blogspot.se/2016/02/psoc-5lp-dfb-assembler.html
http://www.cypress.com/forum/psoc-5-device-programming/average-calculation-using-dfb-psoc5
(ii) use UDB to perform entire PI in hardware. As an example check PSoC Fan Controller component.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bundle of thanks for your well-articulated response. Fetching the reg mentioned by Bob was a good idea as it reduced 6-8 us. Moreover, I have 10 us (@ 100 kHz switching frequency) to complete PI calculations. So, now the problem arose when I used floating point multiplication for PI coefficients which went to 22 us minimum which was further reduced to 5 us my converting floating point to int by multiplying/scaling coefficients with 100 but still there are still few things left like modulations and update PSFB component's registers etc. So seems like DFB or UDB is the only option left now. So, any rough estimation about the time consumption by UDB or DFB based PI? Would it be less than 5us?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A DFP implementation of a single PI regulator with bounds checking can be done in less than 20 DFB instructions per loop, I have sketched on this but its not tested or even run through the simulator yet. With DMA to feed data from the ADC to the DFB you should have the PID output within 1uS from the ADC generates the DMA request.
All of this of course needs careful testing, and adding setpoint and/or gain changes will make it more complicated, but it still should be real fast.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just wrote one journal paper based on PSoC for my PhD in Power Electronics and it's very hard to change controller in the midway of my degree. I implemented PI with analog but it's not good for a gain scheduling application. Will try with DFB but would cost me few weeks as I am a beginner. Many thanks for your valuable suggestions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hope to be able to upload a PI project that at least works with a software simulated temperature system and is reasonably well commented by tomorrow evening. That should be a startout point for improvements.
I wouldnt call myself an expert on DFB assembly, but at least I can make some basic stuff work 🙂 and it surely seems that what works with the component simulator actually works in RL. So being a stubborn old fool I hammer away at the simulator until things looks ok, and when testing against real hardware it seems to work well.
The process of writing DFB code, thats still a matter of mysterious skill. I am getting better but I am far from being able to formulate some guidelines or coding principles how to do this, still only at the stage of hints and examples
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your efforts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Magnus. I will try it to use in my project and will post the hardware results here. Btw, when you talk about simulation, what kind of software you use for it? PSoC Creator?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I use two levels of simulation, the first is the DFB assembly simulator in the component, this code is not executed on the chip but only in PSoC Creator. The second is a software model of a heated tank, its 5 lines of code in main.c. This code executes on the chip together with the actual DFB hardware running, but it doesnt control a physical system or use the AD/DA system.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No DMA and ADC.
So, I will go through ADC to DMA to DFB interfacing before jumping right into DFB.
Again, many thanks, Magnus.