0

I'm building a raspberry pi project that focuses on outputting analog signals through a DAC connected via SPI. For now, I only need the outputs to be updated every millisecond. I'm testing on a pi3 and pi4 with the latest raspberry pi os lite, but I have installed xorg and there's a bunch of stuff going on concurrently. Still, overall CPU usage isn't very high I believe ('top' says around 85% idle, the load average says 2.0 <- not sure what that means).

There is a single C++ process under all this that does one thing in a loop :

  • if 1ms has passed since the last update, update the DAC with a new value (that comes from an in memory buffer, no blocking or anything)

Measuring time is done with clock_gettime(CLOCK_REALTIME, ...).

I can carefully analyze the analog output with an oscilloscope and I notice a few things:

  1. The output is close to perfect, but every few seconds a pause in updates occurs that can last up to about 10ms (much more so on the pi 3)
  2. Any increase in activity in the other processes causes much more of these short glitches
  3. There are a few monster glitches that are >100ms, but they are very rare (less than one every couple of minutes, very long stretches of time without any, especially with a light load => CPU throttling?)

Although this is clearly linked to the other processes running (including one making small writes to the SD card), memory usage is very stable and the CPU never comes close to full load.

My question is what can I do to get the best possible output stability? Is it inevitable that a process will sometimes have its execution suspended for 10ms? One option I'm guessing is attaching a microcontroller as a buffer to the DAC. But even then, a 100ms latency is too much and I see no other way of covering the "monster glitches".

1

The first thing to try is to give the process real-time priority.

struct sched_param param;

param.sched_priority = sched_get_priority_max(SCHED_FIFO);

sched_setscheduler(0, SCHED_FIFO, &param);

man sched_setscheduler for details.

If that isn't good enough you can dedicate a core to your process. I have not tried that solution but plenty of people have. Search the raspberrypi.org/forums for details.

If neither of those work you could use pigpio waves to generate the output data. That would need quite a bit of effort.

2
  • I'm seeing a nice gain from the priority boost, might be sufficient for my purposes. I tried quickly the second method to no avail, but I didn't try hard... I probably need to rearrange some things to make the most of this method. Pigpio waves look interesting. Is it run in a way that gives better real time garanties?
    – schmop
    Oct 27 '20 at 0:19
  • pigpio waves will be as accurate as you can get. The problem will be you probably want to vary the output values in response to some other condition. The hard part would be in changing the wave on the fly to meet that need. Input is easier as you are always sending the same message. See raspberrypi.org/forums/viewtopic.php?t=71089
    – joan
    Oct 27 '20 at 8:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.