Dear all,
in the past I used Python and SCPI to receive data from and control the Red Pitaya. Now I want to receive data from a C# application and I'm thinking about how to do it. When I was searching on Google I always found "VISA" https://en.wikipedia.org/wiki/Virtual_I ... chitecture which seems to be connected somehow to SCPI. I'm confused now!
As far as I understood, SCPI is a standard how to define commands. Since I used Python and SCPI I think the command will be the same with C#. But I don't know how to communicate with the device. Is it correct that VISA is the way how to get connected to a device like the Red Pitaya? What I want to do is to send the commands from my C# application via the network to my Red Pitaya to receive the data.
It would be nice if someone could help me to understand it correctly.
Thanks,
Alex
scpi commands via c# application
-
- Posts: 26
- Joined: Thu Feb 09, 2017 1:13 pm
Re: scpi commands via c# application
scpi is just a set of commands that are transferred using a tcp socket. So you just have to establish a tcp connection with the red pitaya. Have a look at the Matlab examples that also use a raw tcp socket.
-
- Posts: 34
- Joined: Tue Nov 24, 2015 11:26 am
Re: scpi commands via c# application
Thanks for this idea! For me working with sockets is not easy. I tried to do it from the scratch but it was not really successful. If the scpi deamon is running on the RP it will be the server and my program will the client:tknopp wrote:scpi is just a set of commands that are transferred using a tcp socket. So you just have to establish a tcp connection with the red pitaya. Have a look at the Matlab examples that also use a raw tcp socket.
Code: Select all
const int port = 5000;
const string redpitaya = "172.31.153.79";
static TcpClient client = new TcpClient(redpitaya, port);
static NetworkStream nwStream = client.GetStream();
Code: Select all
static void sendCommand(string command)
{
byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(command);
Console.WriteLine("Sending : " + command);
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
}
Code: Select all
static void readAnswer()
{
nwStream.ReadTimeout = 100;
try
{
client.ReceiveBufferSize = 16384;
byte[] bytes = new byte[16384];
nwStream.Read(bytes, 0, 16384);
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
Finally, I have some doubts about this part from the Matlab code:
Code: Select all
%% Wait for trigger
while 1
trig_rsp=query(tcpipObj,'ACQ:TRIG:STAT?')
if strcmp('TD',trig_rsp(1:2))
break
end
end
-
- Posts: 28
- Joined: Fri Apr 28, 2017 12:43 am
Re: scpi commands via c# application
No, you can monitor the position of the current write data pointer while the buffer is filling. I needed to acquire ~8sec data but I couldn't wait until the end. I wrote the following Python code that allowed me to retrieve 1sec chunks, process the data and then wait for the next 1sec chunk. It's rather long but the information is there. Even though it is Python, it still uses the same SCPI commands. If you look elsewhere in the forum, I posted a question about the final chunk not getting read but I have had no reply.Does it mean it is necessary to wait until the buffer is filled before I can receive data?
In the end, though, I gave up on the RP for my acquisition needs. I found it just far too much work to achieve the most basic functionality.
Code: Select all
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 7 15:33:22 2017
@author: john
CONTINUOUS CAPTURE
"""
import redpitaya_scpi as scpi
import matplotlib.pyplot as plot
import time
def sendScpi(hostobj, text, echo = True):
if echo:
print(hostobj.host + ' [TX]: ' + text.upper())
hostobj.tx_txt(text.upper())
def recvScpi(hostobj, echo = False):
text = hostobj.rx_txt()
if echo:
print(hostobj.host + ' [RX]: ' + text)
return text
def sendRecvScpi(hostobj, text, echo = True):
sendScpi(hostobj, text, echo)
return recvScpi(hostobj, echo)
def createScpiObject(hostip):
scpi_retry = True
while scpi_retry:
scpi_retry = False
try:
scpiobj = scpi.scpi(hostip)
sendScpi(scpiobj, '*RST')
sendRecvScpi(scpiobj, '*IDN?')
except:
print('scpi.scpi(' + hostip +') exception')
scpi_retry = True
return scpiobj
def configureGenerator(hostobj, channel, shape, amp, freq, phase = 0):
source = 'SOUR' + str(channel)
output = 'OUTPUT' + str(channel)
sendScpi(hostobj, 'GEN:RST')
sendScpi(hostobj, source + ':FUNC ' + shape)
sendScpi(hostobj, source + ':VOLT ' + str(amp))
sendScpi(hostobj, source + ':PHASE ' + str(phase))
sendScpi(hostobj, source + ':FREQ:FIX ' + str(freq))
sendScpi(hostobj, output + ':STATE ON')
sendScpi(hostobj, source + ':TRIG EXT_PE')
def configureAcquire(hostobj, decim = 65536, level = 100, delay = 8192):
sendScpi(hostobj, 'ACQ:STOP', False)
sendScpi(hostobj, 'ACQ:DATA:UNITS RAW')
sendScpi(hostobj, 'ACQ:DATA:FORMAT ASCII')
sendScpi(hostobj, 'ACQ:DEC ' + str(decim), False)
sendScpi(hostobj, 'ACQ:TRIG:LEVEL ' + str(level), False)
sendScpi(hostobj, 'ACQ:TRIG:DLY ' + str(delay), False)
sendScpi(hostobj, 'ACQ:START', False)
def acquireData(hostobj, decim, chunksize, chunkcount, channel = 3):
echo = False
count = 0
timescale = decim / 125e6
tpos = []
currentchunkstart = 0
currentchunkpos = 0
currentchunkend = currentchunkstart + chunksize - 1
if channel & 1:
buff1 = []
if channel & 2:
buff2 = []
while 1:
response = sendRecvScpi(hostobj, 'ACQ:TRIG:STAT?', False)
if response != 'TD':
if tpos == []:
tpos = int(sendRecvScpi(hostobj, 'ACQ:TPOS?', False))
wpos = int(sendRecvScpi(hostobj, 'ACQ:WPOS?', False))
if wpos < tpos:
wpos = wpos + 16384
currentchunkpos = wpos - tpos
if currentchunkpos >= currentchunkend:
print('CHUNK - ' + str(count + 1)) # + ', ' + str(tpos) + ', ' + str(currentchunkstart) + ', ' + str(currentchunkend) + ', ' + str(chunksize))
if channel & 1:
buff1.append(getDataChunk(hostobj, 1, tpos, currentchunkstart, chunksize) + ',')
if channel & 2:
buff2.append(getDataChunk(hostobj, 2, tpos, currentchunkstart, chunksize) + ',')
currentchunkstart = currentchunkend + 1
currentchunkend = currentchunkstart + chunksize - 1
count = count + 1
if count == chunkcount:
if channel == 1:
return [buff1[:-1]]
if channel == 2:
return [buff2[:-1]]
if channel == 3:
return [buff1[:-1], buff2[:-1]]
else: # TD
if channel == 1:
return [buff1[:-1]]
if channel == 2:
return [buff2[:-1]]
if channel == 3:
return [buff1[:-1], buff2[:-1]]
# print(round(((int(wpos) - int(tpos)) * timescale), 1))
def getDataChunk(hostobj, channel, tpos, offset, size):
start = (tpos + offset) & 16383
# if start > 16384:
# start = start - 16384
maxsize = size
if start + size > 16383:
maxsize = 16383 - start
scpistring = 'ACQ:SOUR' + str(channel) + ':DATA:STA:N? ' + str(start) + ',' + str(maxsize)
sendScpi(hostobj, scpistring, False)
buff = recvScpi(hostobj, False)
buff = buff[1:-1]
if maxsize != size:
maxsize = size - maxsize
scpistring = 'ACQ:SOUR' + str(channel) + ':DATA:STA:N? ' + str(0) + ',' + str(maxsize)
sendScpi(hostobj, scpistring, False)
buff = buff + ',' + recvScpi(hostobj, False)[1:-1]
return buff
def showData(buff):
buffstr = ''.join(str(e) for e in buff)
buffstr2 = buffstr.strip('{}[]\n\r\'"').replace(" ", "").split(',')
print(buffstr2)
plot.plot(list(map(float, buffstr2)))
def main():
channel = 2
chunksize = 2048
chunkcount = 16384 / chunksize
decim = 65536
rp = createScpiObject('192.168.2.100')
sendScpi(rp, 'DIG:PIN:DIR OUT, DIO2_P')
sendScpi(rp, 'DIG:PIN DIO2_P, 0')
configureGenerator(rp, 1, 'sine', 0.01, 0.25, 0)
configureAcquire(rp, decim, delay = 8192)
sendScpi(rp, 'ACQ:TRIG EXT_PE', False)
sendScpi(rp, 'DIG:PIN DIO2_P, 1')
sendScpi(rp, 'DIG:PIN DIO2_P, 0')
# time.sleep(0.05)
start = time.time()
if channel == 1:
buff1 = acquireData(rp, decim, chunksize, chunkcount, 1)
if channel == 2:
buff2 = acquireData(rp, decim, chunksize, chunkcount, 2)
if channel == 3:
[buff1, buff2] = acquireData(rp, decim, chunksize, chunkcount, 3)
print ('Total acquisition time: ', round(time.time() - start, 2), 's')
print ('Downloading full channel 2 data...')
rp.tx_txt('ACQ:SOUR2:DATA?')
buff_string = rp.rx_txt()
buff_string = buff_string.strip('{}[]\n\r\'"').replace(" ", "").split(',')
buff3 = list(map(float, buff_string))
plot.plot(buff3)
plot.xlim(0, 16383)
plot.show()
# showData(buff1) #+','+buff3)
showData(buff2) #+','+buff4)
plot.xlim(0, 16383)
plot.show()
if __name__ == "__main__":
main()
-
- Posts: 34
- Joined: Tue Nov 24, 2015 11:26 am
Re: scpi commands via c# application
Hi all,
I wrote a "scpi" class for the Red Pitaya to send commands and receive answers via tcp/ip. I used the Matlab code as suggested to write everything in C#. Currently, I'm working on the style of the code. I think I'll share the project later if someone is interested.
Thanks,
Alex
I wrote a "scpi" class for the Red Pitaya to send commands and receive answers via tcp/ip. I used the Matlab code as suggested to write everything in C#. Currently, I'm working on the style of the code. I think I'll share the project later if someone is interested.
Thanks,
Alex
-
- Posts: 7
- Joined: Fri Nov 27, 2015 9:20 pm
Re: scpi commands via c# application
Hi Alex,
yes.. please share your C# code with others. I made some trials 1-2 years ago by using C#.
BR,
Ilkka
yes.. please share your C# code with others. I made some trials 1-2 years ago by using C#.
BR,
Ilkka
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie
Who is online
Users browsing this forum: No registered users and 60 guests