Starting from this post I finally got something with this RedPitaya board using the redPitaya SCPI server and string commands through TCP/IP connection. This is a cross post of a post I put here on the Mathematica StackExchange. SCPI server works ways faster than the serial port access. Below is a tutorial I built while experimenting with the board and SCPI commands and existing examples. I hope it could be useful for others. For me it answers my original question. :) PS : Thanks also to Pavel on the Redpitaya Forum who helped a lot. Thanks to Vitaly who suggested to share again on this group.
Christian Néel
Communication via TCP/IP device
Launch the SCPI interface from Serial console :
Here we start communication with the board using a simple Serial console on USB COM port and PuTTY. (PuTTY utility allow simple serial communication as well as Raw TCP/IP or SSH within the same utility)
Note: this could be done by editing the initialisation on Red Pitaya SD Card,or communicating with Serial link by Mathematica ...
After launching SCPI server:
initialization of TCP/IP with JLink
I got the source from from this link: "Mathematica TCP socket client toward Trading Platform" on Mathematica StackExchange
Needs["JLink`"];
InstallJava[];
(*ip addess and port where SCPI server is running*)
tcpaddress = "192.168.1.100";
tcpport = 5000;
(*create a Socket object*)
socket = JavaNew["java.net.Socket", tcpaddress, tcpport];
out = JavaNew["java.io.PrintWriter", socket@getOutputStream[], True];
in = JavaNew["java.io.BufferedReader",
JavaNew["java.io.InputStreamReader", socket@getInputStream[]]];
Using SCPI / API functions
example of simplest SCPI command communication. Everything is a string...
(*send the request*)
out@println["ACQ:DEC?"];
(*read the response*)in@readLine[]
After use, the socket is closed
socket@close[];
Note: this was done using MMA10.1, after 10.1 the TCPsocket funtion are native function in MMA.
Using package redpitaya.m
For convenience I wrote a package that contents a set of function that matches (approximately) the API name in the SCPI definition document. The function list includes as well the TCP initialisations For reference, see the SCPI command release link at :http:// http://redpitaya.com/examples-new//. Since I found that the above link may evolve the reference of SCPI function on: https://github.com/RedPitaya/RedPitaya// and more precisely on: https://github.com/RedPitaya/RedPitaya/blob/master/scpi-server/doc/SCPIAPI_commands.odt?raw=true
Now we load the specific package that wraps the SCPI functions with Mathematica (in this example it is located in this notebook directory)
SetDirectory[NotebookDirectory[]];
<<redpitaya.m
Then, test package has been loaded by typing a command help (type ?rp*)
?rp*
and get a list of all available functions of the package). Clicking a fonction name displays the help at the bottom of the list
Or type directly the requested function help:
Initialize communication
rpSCPIinit[]
Test communication
rpAcqGetGain[1]
LV
Builds from Matlab examples on site
This set of examples follows (roughly) the specifications of Matlab example that are provided on the Red Pitaya Site Reference examples here : http://redpitaya.com/examples-new/
Digital
Blink
Test function which lights LED1 for 5 seconds then turn it off.
rpDpinSetLedState[1, 1];
Pause[5];
rpDpinSetLedState[1, 0];
The function is just a text wrapper for calling SCPI server as shown in the package help:
Bar graph with LEDs
Matlab example here : http://redpitaya.com/examples-new/bar-graph-with-leds/
Test function which displays the LED based on a discretized value p from 0 to 7:
Clear[barLED];
barLED[p_] := (rpDpinSetLedState @@ #) & /@Table[{i, Boole[Floor[Clip[p, {0, 7}]] == i]}, {i, 0, 7}];
Tests
barLED[5];
Pause[1];
barLED[-33];
Pause[1];
barLED[22];
Pause[1];
barLED[0];
Push button and turn on LED diode
Matlab example here : http://redpitaya.com/examples-new/push-button-and-turn-on-led-diode/
Code below is for test purpose only, a better implementation could be done using Mathematica scheduling capabilities;
rpDpinSetDioDirection[5, "INP", "N"]
s = 0; While[ s == 0,
s = 1 - rpDpinGetDioState[5, "N"];
rpDpinSetLedState[7, s]]
Interactive LED bar graph
Matlab example here : http://redpitaya.com/examples-new/interactive-led-bar-graph/
Bar graph with Slider control
Slider[Dynamic[LED], {0, 7, 1}]
Dynamic[(rpDpinSetLedState @@ #) & /@Transpose[{Range[0, 7],Boole[# <= LED] & /@ Range[0, 7]}];]
(* using (#\[GreaterEqual]LED)& or(#<=LED)functions gives a thermometer or ribbon display*)
Sorry no video here but the first tests of moving slider on the screen and seing the LED position moving on the board is quite rewarding :)
Analog
Read analog voltage on slow analog input
Matlab example here http://redpitaya.com/examples-new/read-analog-voltage-on-slow-analog-input/
Read 10 turns Potentiometer and put it on the LED bar display...for a while.
Again this code is just for checking, a better implementation still to be done with Mathematica scheduling capabilities.
Do[barLED[7/3.3*rpApinGetAinValue[3]], {100}]
Set analog voltage on slow analog output
Matlab example here: http://redpitaya.com/examples-new/set-analog-voltage-on-slow-analog-output-4/
here we apply a variable voltage setpoint to AOUT2 and we measure the voltage with the corresponding ADC. Some additionnal info about the functions:
data = {};
Do[rpApinSetAoutValue[2, voltage];
AppendTo[data, {voltage, rpApinGetAoutValue[2]}], {voltage, 0, 3.3,
0.01}]
ListPlot[data]
Then draw the transfert function error for evaluation of the DAC/ADC chain:
ListPlot[Transpose[{data[[;; , 1]],
data[[;; , 2]] - Clip[data[[;; , 1]], {0, 1.8}]}], Joined -> True]
Interactive voltage setting on slow analog output
Matlab example here : http://redpitaya.com/examples-new/interactive-voltage-setting-on-slow-analog-output-2/
Get slider input and put it on the slow DAC output and read it back with ADC on demand.
data = {}; Manipulate[rpApinSetAoutValue[2, value];
Grid[{{Button["Read & display", data = rpApinGetAoutValue[2]],
data}}, Frame -> All], {value, 0, 1.8, .01}]
Generating signals at RF outputs (125 MS/s)
Generate continuous signal
Matlab example here : http://redpitaya.com/examples-new/generate-continuous-signal-on-fast-analog-outputs/
Use API-Like basic functions for driving generator (see definition in the redpitaya.m package).
rpGenWaveform[1, "SINE"]
rpGenFreq[1, 20000]
rpGenAmp[1, 0.9]
rpGenOutEnable[1]
Using the redpitaya WebScope application for visualizing the signals in the same time is also Ok. Image below show the result after the waveform has been changed with the following instructions:
rpGenOutDisable[1]
rpGenWaveform[1, "SQUARE"]
rpGenOutEnable[1]
Beware! when you close the Web browser windows, the communication with the Red Pitaya is closed and you need to restart the SCPI server (well...at least it worked for me).
Simultaneous generation on both channels:
rpGenOutDisable[#] & /@ {1, 2};
rpGenWaveform[#, "SINE"] & /@ {1, 2};
rpGenFreq[1, 20000, 0]
rpGenFreq[2, 40000, 75]
rpGenAmp[#, 0.5, 0.5] & /@ {1, 2};
rpGenOutEnable[#] & /@ {1, 2};
Using PWM output
rpGenPWM[1, 10];
rpGenPWM[2, 10];
rpGenFreq[1, 20000, 0]
rpGenFreq[2, 20000, 180]
Generate signal pulses
Matlab example here : http://redpitaya.com/examples-new/generate-signal-pulses/
Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
rpGenReset[];
rpGenOutDisable[1];
rpGenWaveform[1, "SINE"];
rpGenFreq[1, 5000];
rpGenBurstConfig[1, 5, 3,
0.002];(*note that the period is expressed in seconds, it is \
expressed in \[Micro]s in the SCPI*)
rpGenBurstEnable[];
rpGenBurstTrigSource[1, "INT"];
rpGenBurstTrigger[1];(*prepare trigger but wait for outpt enable*)
Launch burst in a controlled manner
rpGenOutEnable[1];
Clean-up for return to normal operation
rpGenBurstConfig[1, "INF", "INF", 1]
rpGenBurstDisable[1];
Test for return to normal operation
rpGenWaveform[1, "TRIANGLE"]
rpGenFreq[1, 2000]
rpGenAmp[1, 0.9]
rpGenOutEnable[1]
Note: It is a bit awkward to organize the sequencing of all functions to get a good control of the burst, The matlab example shows a good sequencing of calls but some subtilities are hidden in the Red Pitaya SCPI. Probably need to build a more sophisticated function for easier use.
EDIT The most recent update of the redpitaya SCPI server (march 2016 in my understanding) seems to show a more straightforward burst mode (but I had no time to play with).
Generate signal on external trigger
Matlab example here :http://redpitaya.com/examples-new/generate-signal-on-fast-analog-outputs-with-external-triggering/
Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
rpGenReset[];
rpGenWaveform[1, "SINE"]
rpGenFreq[1, 20000]
rpGenAmp[1, 1]
rpGenBurstConfig[1, 4, 1,
0.001];(*note that the period is expressed in seconds, it is \
expressed in \[Micro]s in the SCPI*)
rpGenBurstEnable[];
rpGenBurstTrigSource[1, "GATED"]
rpGenOutEnable[1]
(*prepare trigger and wait for external input *)
Clean-up for return to normal operation
rpGenBurstConfig[1, "INF", "INF", 1]
rpGenBurstDisable[1];
Custom waveform signal generation
Matlab example here :http://redpitaya.com/examples-new/custom-signal-generating/
Generate two arbitrary waveforms:
{x, y} = Transpose[Table[{Sin[t] + Sin[3 t]/3, 1/2 Sin[t] + Sin[4 t]/4}, {t, 0, 2 Pi,2 Pi/16383}]] // N;
ListPlot[Transpose[{x, y}], PlotLabel -> "XY graph"]
ListPlot[{x, y}, PlotLabel -> "Waveforms"]
Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
rpGenReset[];
rpGenArbitrary[1, x]
rpGenArbitrary[2, y]
rpGenFreq[#, 10000] & /@ Range[2];
rpGenAmp[#, 1] & /@ Range[2];
rpGenOutEnable /@ Range[2];
Acquiring signals at RF inputs (125 MS/s)
On trigger signal acquisition
Matlab example here :http://redpitaya.com/examples-new/single-buffer-acquire/ Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
setup Generators CH1 & CH2 (CH2 connected to Acq CH1 on my RP configuration and vice versa)
rpGenReset[]
rpGenWaveform[1, "TRIANGLE"]
rpGenWaveform[2, "SINE"]
rpGenFreq[1, 10000, 90]
rpGenFreq[2, 10000]
rpGenAmp[#, 1, 0] & /@ Range[2];
rpGenOutEnable[#] & /@ Range[2];
setup Acquisition CH1 & CH2
rpAcqReset[]
n = 64;(*decimation factor see RP documentation here we sample at \
about 103kHz*)
rpAcqSetDecimation[64](*125/n MS/s and n=1,8,64,1024,8192,65535*)
timebase = Table[N[i n/((125 10^6))], {i, 0, 16383}];
(*timebase ticks for display later*)
rpAcqSetAveraging["OFF"]
rpAcqSetTriggerThreshold[500](*trigger level 500mV*)
rpAcqSetTriggerDelay[8192];(*triggers at the beginning of the buffer*)
rpAcqSetGain[1, "HV"];
rpAcqSetGain[2, "HV"];
rpAcqSetDataUnit["VOLTS"];
rpAcqSetDataFormat["FLOAT"];
Run Acquisition CH1 & CH2
rpAcqStart[]
rpAcqSetTriggerSource["CH1_PE"]
(*Trigger source setting must be after ACQ:START*)
While[rpAcqGetTriggerState[] != "TD"](*wait for trigger*)
rpAcqGetWritePointerAtTrig[](*print current trigger pointer*)
data1 = Transpose@{timebase,rpAcqGetFullDataNum[1]};(*get full buffer CH1*)
data2 = Transpose@{timebase,rpAcqGetFullDataNum[2]};(*get full buffer CH2*)
ListPlot[{data1, data2}, Joined -> True, PlotRange -> {{0, 500 10^-6}, All},ImageSize -> "Large", PlotTheme -> "Detailed"]
rpAcqStop[]
Oops! seems that picture was taken when the CH1 was disconnected (Hardware issue..).Anyway, it is possible to play with the data:
ListPlot[{Log@Abs@Fourier[(Transpose@data1)[[2]]], Log@Abs@Fourier[(Transpose@data2)[[2]]]}, PlotRange -> {{0, All}, All}, Joined -> True, ImageSize -> "Large", PlotTheme -> "Detailed"]
Signal acquisition on external trigger
Matlab example here :http://redpitaya.com/examples-new/on-given-external-trigger-acquire-signal-on-fast-analog-input/
Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
setup Generators CH1 & CH2 (CH2 connected to Acq CH1 on my RP configuration and vice versa)
rpGenReset[]
rpGenWaveform[1, "TRIANGLE"]
rpGenWaveform[2, "SINE"]
rpGenFreq[1, 10000, 90]
rpGenFreq[2, 10000]
rpGenAmp[#, 1, 0] & /@ Range[2];
rpGenOutEnable[#] & /@ Range[2];
setup Acquisition CH1 & CH2
rpAcqReset[]
n = 64;(*decimation factor see RP documentation here we sample at about 103kHz*)
rpAcqSetDecimation[64](* x 125/n MS/s and n=1,8,64,1024,8192,65535*)
timebase = Table[N[i n/((125 10^6))], {i, 0, 16383}];
(*timebase ticks for display later*)
rpAcqSetAveraging["OFF"]
rpAcqSetTriggerThreshold[500](*trigger level 500mV*)
rpAcqSetTriggerDelay[8192];(*triggers at the beginning of the buffer*)
rpAcqSetGain[1, "HV"];
rpAcqSetGain[2, "HV"];
rpAcqSetDataUnit["VOLTS"];
rpAcqSetDataFormat["FLOAT"];
Run Acquisition CH1 & CH2
rpAcqStart[]
rpAcqSetTriggerSource["EXT_PE"](*Trigger source setting must be after \
ACQ:START*)
While[rpAcqGetTriggerState[] != "TD"](*wait for trigger*)
rpAcqGetWritePointerAtTrig[](*print current trigger pointer*)
data1 = Transpose@{timebase, rpAcqGetFullDataNum[1]};(*get full buffer CH1*)
data2 = Transpose@{timebase, rpAcqGetFullDataNum[2]};(*get full buffer CH2*)
ListPlot[{data1, data2}, Joined -> True, PlotRange -> {{0, 500 10^-6}, All},ImageSize -> "Large", PlotTheme -> "Detailed"]
rpAcqStop[]
Synchronised one pulse signal generation and acquisition
Matlab example here :http://redpitaya.com/examples-new/synchronized-one-pulse-generating-and-acquiring/
Configure using API-Like basic functions for driving generator (see definition in the redpitaya.m package).
rpGenReset[]
rpAcqReset[]
(*waveform settings*)
rpGenWaveform[1, "SINE"];
rpGenFreq[1, 10000]
rpGenAmp[1, 0.5];
(* burst generation settings*)
rpGenBurstEnable[];
rpGenBurstConfig[1, 5, 2, 0.004]
rpGenOutEnable[1];
(*acuqisition settings*)
rpAcqSetDecimation[64];
rpAcqGetSamplingRateHz[]
rpAcqSetGain[1, "HV"];
rpAcqSetTriggerThreshold[0.25];
rpAcqSetTriggerDelay[8192];
rpAcqSetTriggerSource["AWG_PE"];
(*acquisition phase*)
rpAcqStart[];(*acquisition launch*)
rpGenBurstTrigger[]
(*wait for trigger & display*)
While[rpAcqGetTriggerState[] != "TD"];
data1 = rpAcqGetFullDataNum[1];
ListPlot[data1, Joined -> True, ImageSize -> "Large", PlotRange -> All, PlotTheme -> "Detailed"]
rpAcqReset[]
End
rpSCPIclose[]
The full package is attached and also the tutorial notebook.
Attachments: