#
# moku example: Plotting Oscilloscope
#
# This example demonstrates how you can configure the Oscilloscope
# instrument, and view triggered time-voltage data frames in
# real-time.
#
# (c) 2021 Liquid Instruments Pty. Ltd.
#
import matplotlib.pyplot as plt
from moku.instruments import Oscilloscope

# Connect to your Moku by its ip address using
# Oscilloscope('192.168.###.###')
# or by its serial number using
# Oscilloscope(serial=123)
i = Oscilloscope('192.168.###.###')

try:
    # Trigger on input Channel 1, rising edge, 0V 
    i.set_trigger(type='Edge', source='Input1', level=0)

    # View +-5usec, i.e. trigger in the centre
    i.set_timebase(-5e-6, 5e-6)

    # Generate an output sine wave on Channel 1, 1Vpp, 1MHz, 0V offset
    i.generate_waveform(1, 'Sine', amplitude=1, frequency=1e6)

    # Set the data source of Channel 1 to be Input 1
    i.set_source(1, 'Output1')

    # Set the data source of Channel 2 to the generated output
    # sine wave
    i.set_source(2, 'Input2')

    # Get initial data frame to set up plotting parameters. This can
    # be done once if we know that the axes aren't going to change
    # (otherwise we'd do this in the loop)
    data = i.get_data()

    # Set up the plotting parameters
    plt.ion()
    plt.show()
    plt.grid(b=True)
    plt.ylim([-1, 1])
    plt.xlim([data['time'][0], data['time'][-1]])

    line1, = plt.plot([])
    line2, = plt.plot([])

    # Configure labels for axes
    ax = plt.gca()

    # This loops continuously updates the plot with new data
    while True:
        # Get new data
        data = i.get_data()

        # Update the plot
        line1.set_ydata(data['ch1'])
        line2.set_ydata(data['ch2'])
        line1.set_xdata(data['time'])
        line2.set_xdata(data['time'])
        plt.pause(0.001)

except Exception as e:
    print(f'Exception occurred: {e}')
finally:
    # Close the connection to the Moku device
    # This ensures network resources and released correctly
    i.relinquish_ownership()
