Skip to content
Snippets Groups Projects
red_pitaya_raw_transfer_tests.md 5.48 KiB
jupyter:
  jupytext:
    formats: ipynb,md
    text_representation:
      extension: .md
      format_name: markdown
      format_version: '1.2'
      jupytext_version: 1.3.0
  kernelspec:
    display_name: Python 3
    language: python
    name: python3
import redpitaya_scpi as scpi
import numpy as np
import time
# Red Pitaya Stuff

address = "rp-f06897.local"
rp_s = scpi.scpi(address)
dec_exp = np.array([0,3,6,10,13,16])
dec = 2**dec_exp
t_total = np.array([131.072e-6, 1.049e-3, 8.389e-3, 134.218e-3,1.074, 8.590])
dec

ASCII Version

rp_s.tx_txt('ACQ:RST')
rp_s.tx_txt('ACQ:DATA:FORMAT ASCII')
rp_s.tx_txt("ACQ:DEC 1024")
rp_s.tx_txt('ACQ:START')
rp_s.tx_txt('ACQ:TRIG NOW')

while 1:
    rp_s.tx_txt('ACQ:TRIG:STAT?')
    if rp_s.rx_txt() == 'TD':
        break
        

The above triggers and runs the acquisition.

rp_s.tx_txt('ACQ:DATA:UNITS VOLTS')
rp_s.tx_txt('ACQ:DATA:FORMAT ASCII')    
rp_s.tx_txt('ACQ:SOUR1:DATA?')
buf = rp_s.rx_txt()
rp_s.tx_txt('ACQ:SOUR2:DATA?')
buf = rp_s.rx_txt()
print('\nBuffer: \n')
print(buf[0:100])

Binary version

From python file, it seems you need to use the rx_arb() routine:

https://github.com/RedPitaya/RedPitaya/blob/master/Examples/python/redpitaya_scpi.py

But there are no real instructions on how?

Probably the best documentation of this is the source code of the SCPI server itself:

https://github.com/RedPitaya/RedPitaya/tree/master/scpi-server/src

I think the relevant function is RP_AcqDataOldestAllQ:

https://github.com/RedPitaya/RedPitaya/blob/master/scpi-server/src/acquire.c

I guess this from here:

https://github.com/RedPitaya/RedPitaya/blob/master/scpi-server/src/scpi-commands.c

    {.pattern = "ACQ:SOUR#:DATA?", .callback            = RP_AcqDataOldestAllQ,},

OK, wait, I just found this:

https://github.com/RedPitaya/RedPitaya/blob/master/test/scpi/acq_bin_test.py

If I run the above code, my red pitaya then also seems to completely crash...its built-in webserver is no longer responsive.

And all subsequent attempst to connect with ASCII code above also fail until I manage to stop and restart the SCPI server?

Ok, I found some useful code:

https://github.com/RedPitaya/RedPitaya/blob/master/test/scpi/acq_bin_test.py

It shows in principle how to use the binary read.

rp_s.tx_txt('ACQ:DATA:UNITS VOLTS')
rp_s.tx_txt('ACQ:DATA:FORMAT BIN')

rp_s.tx_txt('ACQ:SOUR1:DATA?')
buf = rp_s.rx_arb()
print(buf)

OK, this just does not work.

And now if I try to execute the ASCII code above, I get errors!

---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-19-5f026792b443> in <module>
      2 rp_s.tx_txt('ACQ:DATA:FORMAT ASCII')
      3 rp_s.tx_txt('ACQ:SOUR1:DATA?')
----> 4 buf = rp_s.rx_txt()
      5 
      6 print('\nBuffer: \n')

~/Documents/GitHub/gary-misc-notebooks/redpitaya_scpi.py in rx_txt(self, chunksize)
     42         msg = ''
     43         while 1:
---> 44             chunk = self._socket.recv(chunksize + len(self.delimiter)).decode('utf-8') # Receive chunk size of 2^n preferably
     45             msg += chunk
     46             if (len(chunk) and chunk[-2:] == self.delimiter):

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfd in position 4008: invalid start byte

I think that the rx_arb() code is just not clearing the socket properly.

I did this for a while:

while len(rp_s._socket.recv(1)) > 0:
    ;

Now I'm not getting anything new from the socket. Let's go back up and try the ASCII code again.

2020-03-15 22:29:31

Ha! The ASCII code works again! Yes!

Let's try just manually reading from the socket ourselves after a binary data request.

def my_read():
    # The first thing it sends is always a #
    #
    # One thing I don't understand here is that even if I do a recv(10), 
    # I always get only one answer back. Like somehow we are getting a
    # terimination signal in the socket? I don't know enough about sockets. 
    # This doesn't work though for the the number of digits. 
    # Maybe I need to look in the SCPI server code. 
    #
    buf = rp_s._socket.recv(1)
    print(buf.decode('utf-8'))

    # The second thing it sends is the number of digits in the byte count. 
    buf = rp_s._socket.recv(1)
    digits_in_byte_count = int(buf)

    # The third thing it sends is the byte count
    buf = rp_s._socket.recv(digits_in_byte_count)
    print(buf.decode('utf-8'))
    byte_count = int(buf)

    # Now we're ready read! You might thing we would just to a recv(byte_count), but somehow this often 
    # results in an incomplete transfer? Maybe related to first point above? 
    # The RP code just reads one byte at a time until it's gets all
    # it wants? I tried that and it seems to work. But it is not mega-fast? 317 ms, whereas we should be 
    # able to get data off much faster than that! It is 65536 bytes = 5 ms at 100 MBit / second. 
    # But 317 ms is still at least a lot better than the ASCII read which takes 1.3 seconds!

    buf = []
    while len(buf) != byte_count:
        buf.append(rp_s._socket.recv(1))
    print(len(buf))
rp_s.tx_txt('ACQ:DATA:UNITS VOLTS')
rp_s.tx_txt('ACQ:DATA:FORMAT BIN')
rp_s.tx_txt('ACQ:SOUR1:DATA?')
my_read()
rp_s.tx_txt('ACQ:SOUR2:DATA?')
my_read()

For if we need to clear the buffer

n = 0
while True:
    rp_s._socket.recv(1)
    n += 1
print(n)
len(buf)*8/100e6