Introduction
In this tutorial we showed how to measure activity on 20M and report the values as a visual gauge to remote clients.
We will now show how to save the measurements to a CSV file and process the results with Matlab® or the open-source equivalent Octave to see the trends and produce nice plots like this one:
Step 1 : updating the script
We refer to the acquisition script oncapture_done.js presented in this tutorial.
Change it as follows:
// this function transforms a string to a buffer object and adds line feed function txtLine(str) { var i ; var buf = new ArrayBuffer(str.length+1); // bytes for each char + new line var bufView = new Int8Array(buf); for(i=0, strLen=str.length; i<strLen; i++) { bufView[i] = str.charCodeAt(i); } // add new line bufView[i++] = 10 ; return buf; } // this function is called automatically when the capture is done // parameter <id> is the internal unique Id of the capture that // was just performed function dataReady(id ) { // var frequency = CaptureEngine.getCenterFrequency(id); var power = CaptureEngine.getRMS( id ); var BW = CaptureEngine.getCaptureBandwidth( id ); //print('RMS power at F= ' + frequency + ' MHz , BW='+BW+' p is =' + power ); // publish an indicator for this value CloudSDR.sendIndicatorValue( '20Meters', 'dBm', power ); // save to file var newCSVLine = now() + ";" + frequency + ";" + BW + ";" + power ; IO.fappend( '20Meters.txt', txtLine(newCSVLine) ); // reschedule another capture CaptureEngine.proceedCaptures( 10000 ); }
We basically call the SDRNode function IO.fappend() function that appends a raw buffer of bytes to a file (created if not exiting). As we are creating data from a simple string, the function txtLine() just converts to a Buffer() object.
Now we have a file on disk where the measurements are stored. Here are some lines of the file :
16/09/2016-23:57:49;14.02;20000;-68.55413818359375 16/09/2016-23:58:05;14.02;20000;-68.47654724121094 16/09/2016-23:58:22;14.02;20000;-68.5374526977539 16/09/2016-23:58:38;14.02;20000;-68.48772430419922 16/09/2016-23:58:55;14.02;20000;-68.84260559082031 16/09/2016-23:59:11;14.02;20000;-68.52120971679688 16/09/2016-23:59:28;14.02;20000;-68.49142456054688 16/09/2016-23:59:44;14.02;20000;-68.4538345336914
We can now process this file for graphing.
Step 2 : import data and process
We use the ‘import data’ assistant in Matlab to generate the .m file (be careful to properly specify the date format : ‘dd/MM/yyyy-HH:mm:ss’ ), and we save the generated script to import_csv_rms.m for reuse.
The processing script becomes quite simple
clear all; [date_mesure,vrms] = import_csv_rms('20Meters.txt'); figure; plot( date_mesure, vrms ); xlabel 'Date'; ylabel 'RMS from RTLSDR'; grid on;
Here is what we get :
Measurements are quite noisy, that is logical : we tuned just in the middle of the CW band and take 1s of signal. Of course if one strong station is in QSO during the capture, the power will be important… To smooth a bit the chart, we will add a 5 min moving average.
Remember that the measurements were performed every 15 seconds and there are 20 measurements over 5 minutes. So will average over 20 values and replot, that’s basically what the following script is doing
clear all; [date_mesure,vrms] = import_csv_rms('20Meters.txt'); interval = 15000 ; mesures_per_5_minutes = 5*60*1000/interval; coeffs = ones(1, mesures_per_5_minutes)/mesures_per_5_minutes; avg = filter(coeffs, 1, vrms); L = length(coeffs); plot( date_mesure(L:end), [vrms(L:end) avg(L:end)] ); title 'Activity measurement with Cloud-SDR'; legend('RMS power on 20m','5 minute Average','location','best') xlabel 'Date'; ylabel 'RMS from RTLSDR'; grid on;
Giving us:
Zoomed :