Dear all,
to complete this example I’ll put here the full sketch listing and some explanations.
To get all working you have to perform a change into the optimization flag for the gcc compiler, to do that go at the following boards folder (I’m using the 2.7.2 Mbed OS version):
C:\Users…\AppData\Local\Arduino15\packages\Seeeduino\hardware\mbed\2.7.2
with a text editor open the platform.txt file and perform a search for compiler.c.flags then put after the -g3 option the -O2 optimization switch.
Perform another search for compiler.cpp.flags and again put just after the -g3 option the -O2 optimization switch.
then just run the sketch and all should be able to work properly.
The reading loop about the SAADC is fired every 2ms (the sampling frequency was set to 500Hz) and a buffer of 1000 samples (DATA_BUFFER_SIZE) have to be filled before data will be sent through the serial port, so to perform any data elaboration we have an interval of 2".
The code I’ve written implement a double buffering software approach so, briefly, suppose that the SAADC is filling the three buffers dataBuffer1[0][], dataBuffer2[0][] and dataBuffer3[0][] under the ISR code SAADC_IRQHandler_v (I’ve planned three analog source to be sampled), in this time the other three buffers dataBuffer1[1][], dataBuffer2[1][] and dataBuffer3[1][] are processed into the main loop code.
When the dataBuffer1[0][], dataBuffer2[0][] and dataBuffer3[0][] are fully filled the global buffers index bfrIdx switch from 0 to 1 so within the next 2" time window the buffers that will be filled from the SAADC will be the dataBuffer1[1][], dataBuffer2[1][] and dataBuffer3[1][] and then into the main loop we have to process the previosuly filled dataBuffer1[0][], dataBuffer2[0][] and dataBuffer3[0][], and so on…
Obviously to avoid any loss of data is important that these three buffers are fully processed into the main in a time that must be less than 2".
Using such approach we just have care to be sure that the main processing loop will finish before all the data is filled inside the other three buffers group currently managed under the SAADC ISR handler.
If you look directly at the code this approach will appear more simple that the description above.
Into the code you can see some NRF_P1->… statements, these one are used to trigger some output pin used to debug the code and verify that the timing described above are respected (pin D6 and D7), into the screenshoot below in yellow there is the ISR timing (every 2" the buffers are filled) and the green wave is about the data processing function, filtering and data serial sending by means of the elabData() function.
Digital filtering is made through the filtering1(), filtering2() and filtering3() functions, actually these perform same filtering, here is the place where you can change the filtering strategy. Remember to design the filter according the sampling frequency! Actually the filter is a IIR implemented with first direct form. IIR filters are shorter than FIR filters if compared to same filtering performances, but can going to be unstable so carefully check the behavior and the implementation used.
In this example I’ve used this online tool:
https://www.meme.net.au/butterworth.html
of course you can also design your one filter and check about it performance through the Scilab or Matlab tools, there are many tutorial (theoretical and practical) around the web about signal processing and digital filtering and this field is very amazing.
Hope such things can be useful for someone, of course let me know if you have improvements and other useful things about!!
Best regards.
Fire aka Powemos
xiao_nrf52840_esempio8.zip (6,7 KB)