Reading raw data from a Rigol oscilloscope

class-d-testModern oscilloscopes can be used for much more than  just displaying a waveform. With the some programming, you can use it as a logic analyzer, for jitter measurements or run use it as a spectrum analyzer. In a later article I will show how to do jitter measurements with a digital storage oscilloscope (DSO). You can argue that there are instruments that are more specialized for these use cases than an oscilloscope. You’re right. However if you don’t need the all the features and the superior performance of these instruments (like a logic analyzer or a spectrum analyzer), a DSO might be a cheap alternative. For some specific use cases it might be even superior.

Even relatively cheap scopes like a Rigol DS2072 can already sample data with rates of 2GSamples/s which means one sample every 0.5 nanoseconds. The resolution is usually limited to 8 bit, but the first scopes are already available with 12bit resolution. For many use cases, even 8 bit are more than enough.

The basic approach is to let the scope sample into its internal memory with the sample rate you need, then load the data to a PC and do all the post-processing on the PC. My Rigol scope has an internal memory of 56MSamples – that’s a lot.

The example code at the end of this picture shows how to do this with a Rigol DS2xx2 scope. The standard version of this scope has a memory of only 14MSamples. You can upgrade the memory with a license key. However, for most tasks even the 14MSamples are enough.

There are some things you have to do to get the data from the scope and use the full 56MSamples memory:

  • Timing is important
    I had quite some problems getting the program to work. In most cases I was sending new command to fast. If the scope still processes the last command, it ignores new commands.
    In worst case it is not even responding anymore.
    As a rule of thumb I use 100ms delay after every command and one second after some commands like “AUTO”, “RUN” or “STOP”. This has been found by trial-and-error.
  • Activate only one channel if you don’t need the second
    If you use both channels, the sample memory per channel is only the half.
  • Stop the recording
    With live display only 1400 samples are available.

One characteristic I don’t like with this specific Rigol oscilloscope: data transfers over the network are quite slow. I was able to transfer 110kSamples/s over TCP/IP. That means reading out the full memory of the scope takes over 8 minutes! That’s not really fast. If you don’t need all the samples, reduce the number of samples with the “:WAVeform:POINts” command.
Now some example code how to get the data. You will see, that some parts are missing. It should just give you an idea how to do it by yourself. I have programmed my own measurement toolkit. However the code still needs some cleanup, therefore I won’t publish it now. I plan to publish it later. Note that this is not a high-priority task, therefore I can’t say when it will be ready.

def readdata(instrument):
    global samples
    
    line=str(instrument.connection.read(12))
    
    if not line.startswith("#9"):
        raise Exception("unknown data format: {}.".format(line))

    samplecount=int(line[2:11])
    data=instrument.connection.read(samplecount)
    for d in data:
        samples.append(ord(d))
        
    lf=instrument.connection.readline()
    if (len(lf))>2:
        raise Exception("additional data after samples: {}".format(lf))
  
    
def read_from_scope():
    global samples
    global periods
    samples=[]
    
    ins=get_instrument("DS2202")
    print ins.identify()
    
    
    ins.send_command(":AUT")
    time.sleep(2)
    ins.send_command(":CHAN2:DISP 0")
    ins.mem_depth(points)
    ins.set_aquisition_type("HRES")
    time.sleep(2)
    ins.send_command(":CHANNEL1:BWLimit OFF")
    ins.send_command(":CHANNEL1:COUPLING DC")
    ins.send_command(":CHANNEL1:DISPLAY ON")
    
    ins.send_command(":RUN")
    time.sleep(1)
    ins.send_command(":ACQuire:MDEP {}".format(points))
    ins.send_command(":STOP")
    time.sleep(1)
    ins.send_command(":WAVeform:MODE RAW")
    ins.send_command(":WAVeform:POINts {}".format(points))
    ins.send_command(":WAVeform:FORMAT BYTE")
    ins.send_command(":WAVeform:SOURCE CHAN1")
    
    ins.send_command(":WAVeform:RESet")
    time.sleep(1)
    ins.send_command(":WAVeform:BEGIN")
    time.sleep(1)
    starttime=datetime.datetime.now()
    while True:
        stat=ins.send_command(":WAVeform:STATUS?").lower()
        if stat.startswith("idle"):
            ins.send_command(":WAVeform:DATA?",auto_read=False)
            readdata(ins)
            break
        elif stat.startswith("read,"):
            count=int(stat[5:])
            if count==0:
                break
            ins.send_command(":WAVeform:DATA?",auto_read=False)
            readdata(ins)
        else:
            print "unexpected return string"
            sys.exit(1)
    endtime=datetime.datetime.now()
    sec=(endtime-starttime).total_seconds()
    slen=len(samples)
    print("Retrieved {} samples in {} seconds ({}kSamples/s)".format(slen,sec,slen/sec/1000))

3 thoughts on “Reading raw data from a Rigol oscilloscope

  1. octyminea

    Hi,
    is there any way to download the raw data from DS2072 to the USB without loading it in its internal memory? I want to stream live data directly to the computer and use the oscilloscope just for its ADC.

    Reply

Leave a Reply