Phasors calculation using libpruio

I have the following C code’s parts that uses tables of sins and cosins to calculate a fundamental phasor of 60 Hz electrical system using 16 samples per cycle (960 Sps):

float cosins[]={1, 0.92388, 0.70711, 0.38268, 0, -0.38268, -0.70711, -0.92388, -1,
-0.92388, -0.70711, -0.38268, 0, 0.38268, 0.70711, 0.92388};

float sins[]={0, 0.38268, 0.70711, 0.92388, 1, 0.92388, 0.70711, 0.38268, 0,
-0.38268, -0.70711, -0.92388, -1, -0.92388, -0.70711, -0.38268};

for(i=0; i <16; i++){

ret_r=x[15-i]*cosins[i]+ret_r;
ret_i=x[15-i]*sins[i]+ret_i;
}

return 0.088388ret_r -0.088388ret_i*I;

Is it possible to perform this using the libpruio in order to read 6 analog inputs? If yes? What is the best way to implement it if other operations were need, i.e. compute the division of 2 phasors.

Thanks.

PRU uses 32-bit integer arithmetic, and only has unsigned add and
subtract. You'd have to recast your calculation into fixed point and
use software multiplication. What is the required accuracy? If it's
not too much, perhaps you could use table lookup, or combine table
lookup with linear interpolation?

Hi!

Is there a reason you don’t do this on the ARM processor? In the v4.8 kernel, the ADC uses DMA, so you can sample at full speed.

Regards,
John

TJF,

so I only need a C-code file like io_inputs.c (from libpruio examples)?

I need a fixed sampling rate (960 Sps each channel), calculate the 6 phasors and save in a file.

Thanks for your help.

Przemek Klosowki,

accuracy of 95% is requiered, not much.

john3909,

there’s no reason to use the PRUs. I only need read 6 analog inputs in real-time. I thought the only way would be using the PRUs. And the best way by means of lbpruio.

TJF,

so I only need a C-code file like io_inputs.c (from libpruio examples)?

Yes, just C code for the ARM. But io_inputs.c operates in IO mode (no accurate timing). Better use MM (measurement) or RB (ring buffer) mode. MM mode for a fixed number of samples, RB mode for continous sampling.

I need a fixed sampling rate (960 Sps each channel), calculate the 6 phasors and save in a file.

Note: It’ impossible to sample at exactly 960 Sps. The timing gets controlled by a clock running at 200MHz. The best approximation you can get is 960,001536002 Sps. If you aim to measure for a long period of time, you’ll have to correct the difference.

Regards

Well, it all depends on what you mean by realtime? The ADC on the AM3358 uses a sequencer that samples the analog channels at a fixed sampling rate and places those samples in a FIFO. It does not matter if you use PRU or the IIO driver, because the channel sampling occurs at the same time. The difference is the PRU samples the ADC status and then copies the data into DDR and the IIO driver uses DMA to move the samples into DDR. The IIO driver is faster and can achieve higher sampling rates. Also the IIO driver is easier to use because you just read from /dev/iio:deviceX. Better still, you have both PRUs available for more important work.

Regards,
John

Hi John!

The IIO driver is faster and can achieve higher sampling rates.

The sampling rate limitation is the FiFo buffer in the TSC_ADC_SS. Both drivers can operate at full speed. iio puts more load on the ARM CPU.

Also the IIO driver is easier to use because you just read from /dev/iio:deviceX.

Can you please provide some PRU example code how to read from /dev/iio:deviceX? iio is made for ARM side only. In contrast libpruio can provide the data either for the ARM or for the second PRU.

Regards

Hi TJF,

The IIO ADC can sample at 800K samples per second [1]. You cannot achieve that sampling rate with with PRU and have it do something useful with those samples.

[1] https://patchwork.kernel.org/patch/9391499/

I don’t see the purpose of having PRU read from /dev/iio:deviceX. This is for ARM only. The OP wanted to do phasor analysis which requires math not easily implemented on the PRU. Since the samples are already available on the ARM side, I suggested that the OP do phasor analysis on the ARM?

Regards,
John

I’d break it out on a PIC16F so I got isolation from the BBB itself using their ADC’s. Just read it in via UART. Then use the BBB to crunch the data,

I understand there are many ways to solve the problem.

  1. Using PRUs via libpruio suggested by TJF.
  2. Using DMA via iio driver suggested by John.
  3. Using a external ADC suggested by Woody.

I understand the solution 1.

John, can you send a example of ADC sampling and DMA?

For 3, I don’t want to use a external ADC for this project. But, for others I’ll have in mind this solution. This solution would be possible with RPi3?

Thanks you.

Search for iio_generic_buffer, which is in mainline under tools/iio. This will show you how to read the IIO buffer from a user space app.

Alternatively, you can use iiod which you will find in libiio, which allows you to read the samples remotely. You can use IIO_Oscilloscope to connect to iiod.

https://wiki.analog.com/resources/tools-software/linux-software/iio_oscilloscope

Regards,
John

Hi TJF,

The IIO ADC can sample at 800K samples per second [1].

This is not real-time sampling! When you transfer chunks of samples by DMA, you add further and unsteady latency. The only way to sample real-time is pulling samples one by one from the FiFo, and this is limited to 200 kSps (= TI specification, on some boards I got up to 250 kSps).

You cannot achieve that sampling rate with with PRU and have it do something useful with those samples.

Why do you know what I can achieve? I did experimental sampling at 1600 kSps with the PRU, up to 295 samples (until the FiFo overflows). I assume that I can get twice that number by using both FiFos (with more than one channel). But this is not real-time, and it’s not ready for daily use.

BTW: At 200 kSps the PRU performes 1000 instructions between two samples. Fairly enough to do something useful (as long as you don’t use remoteproc framework).

Please do not confuse the users! You should mention that your solution is experimental and you’re looking for beta testers.

I don’t see the purpose of having PRU read from /dev/iio:deviceX.

Not today, but in future you may notice that the PRUSS are very good in data processing and you’ll need to feed them with data for that purpose.

@Fabián

The external ADC is an option when you may need the TSC_ADC_SS for a touch screen on the board. Otherwise it’s an overkill, just protect the analog input lines against under-/overvoltage.

Regards

Well, again it depends on what you mean by realtime. To most developers, it means deterministic and since the AM335x ADC uses a sequencer to do the sampling, it is deterministic, and hence there is no difference between the PRU and ARM with DMA. This shouldn’t be a pissing match as to how fast you can sample, but rather focus on what the OP application was. In this case, since the PRU doesn’t have the required math functions, the PRU is only doing what the DMA is doing, moving samples from the FIFO to DDR memory. Hence, why waste the PRU on such a trivial function. Rather save it for something more useful.

One more thing, the IIO framework is capable of GSPS performance.

Regards,
John

Well, again it depends on what you mean by realtime. To most developers, it means deterministic

Yes, deterministic:

  1. steady latency
  2. the lowest possible steady latency

and since the AM335x ADC uses a sequencer to do the sampling, it is deterministic,

The sequencer garanties a deterministic process from analog line to the FiFo buffer. You know that you cannot compute inside the FiFo. The data has to get to a processor register first. And the complete process, from analog line up to the processor register, has to be deterministic.

and hence there is no difference between the PRU and ARM with DMA.

There is a big difference, since the ARM gets loaded by other kernel tasks. On Beaglebone hardware under LINUX, the PRU is the only system that can garanty deterministic sampling (when bus access is unlimited).

This shouldn’t be a pissing match as to how fast you can sample, but rather focus on what the OP application was. In this case, since the PRU doesn’t have the required math functions,

The math in the original post contains simple table lookups, additions and multiplications. It’s easy to implement that on the PRU (, but not necessary for 6 kSps).

the PRU is only doing what the DMA is doing, moving samples from the FIFO to DDR memory. Hence, why waste the PRU on such a trivial function. Rather save it for something more useful.

Yes, don’t waste the PRUSS! That’s why I didn’t propose any customized firmware, but libpruio. Even if Fabián doesn’t need the digital features (GPIO, PWM, CAP, QEP), he might use the trigger features to start the measurement at the same phasing, in order to make results better comparable.

Regards

Well, again it depends on what you mean by realtime. To most developers, it means deterministic

Yes, deterministic:

  1. steady latency
  2. the lowest possible steady latency

and since the AM335x ADC uses a sequencer to do the sampling, it is deterministic,

The sequencer garanties a deterministic process from analog line to the FiFo buffer. You know that you cannot compute inside the FiFo. The data has to get to a processor register first. And the complete process, from analog line up to the processor register, has to be deterministic.

and hence there is no difference between the PRU and ARM with DMA.

There is a big difference, since the ARM gets loaded by other kernel tasks. On Beaglebone hardware under LINUX, the PRU is the only system that can garanty deterministic sampling (when bus access is unlimited).

It is only the period between the samples that is important to be deterministic. After that, it doesn’t matter if there is any latency unless he is using the calculations in a control loop. If he is just doing phasor measurements, then latency isn’t important. You need to understand the application before you make assumptions like this.

Regards,
John

Ahhh, now I understand!

We should use two different solutions for measurement and closed loop control …

Thank you TJF and John for share your knowledge.

Actually, I have in mind two projects based on phasor calculation:

  1. A low-cost PMU (Phasor measurement unit) that requires the phasors calculation and then send to a collector.

  2. A low-cost protection relay that requieres the phasors calculations, operations between these phasors and responses (digital outputs) every each fixed time. 960 Sps por each analog input and 280 Sps for each digital output.

I have began code and then I hope share it with you.

Regards.