### Python Moku API Setup Source: https://apis.liquidinstruments.com/api/getting-started Get started with the Moku Scripting API for Python. Requires data files to be downloaded before running any program. ```Python # Example: Download data files before running Python scripts # import os # os.system('mokucli download_data_files') ``` -------------------------------- ### Install moku library and mokucli utility Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Installs the 'moku' Python library using pip and verifies the installation by importing the library. It also shows how to install the 'mokucli' utility and check its help output. ```Shell $ pip install moku $ python -c 'import moku' ``` ```Shell $ mokucli --help Usage: mokucli [OPTIONS] COMMAND [ARGS]... Moku command line utility Version: 4.0.1 (c) Liquid Instruments 2016-2025 ... ``` -------------------------------- ### LabVIEW Waveform Generator Example Source: https://apis.liquidinstruments.com/api/getting-started/starting-labview Demonstrates a simple use of the LabVIEW API for the Waveform Generator. It includes opening a Moku session, uploading the instrument, generating a waveform, and closing the session. This snippet can be used directly after installing the LabVIEW driver. ```LabVIEW VI Snippet of a simple Waveform generator example ``` -------------------------------- ### MATLAB Moku API Setup Source: https://apis.liquidinstruments.com/api/getting-started Access the Moku Scripting API for MATLAB through the MATLAB File Exchange and the MATLAB Add-on Manager. ```MATLAB % Example: Install Moku API from MATLAB File Exchange or Add-on Manager % addpath('path/to/moku_api'); ``` -------------------------------- ### Install Moku Library using Python Source: https://apis.liquidinstruments.com/api/getting-started/starting-python This snippet demonstrates how to install the 'moku' library by executing the pip command directly through a Python interpreter. This is a workaround for cases where the 'pip' command might be out of sync with the Python installation. ```Python python -m pip install moku ``` ```Python python -c 'import moku' ``` -------------------------------- ### Shell: Install Moku Library and Download Bitstreams Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Provides shell commands to install the `moku` Python library using pip and download bitstreams. This is a deprecated method. ```Shell pip install moku moku download ``` -------------------------------- ### Test MATLAB Installation Source: https://apis.liquidinstruments.com/api/getting-started/starting-matlab To verify that the Moku Scripting API for MATLAB has been successfully installed, execute the `help Moku` command in the MATLAB Command Window. A successful execution indicates that the toolbox is ready for use. If the command fails, consult the troubleshooting section. ```MATLAB help Moku ``` -------------------------------- ### LabVIEW Moku API Setup Source: https://apis.liquidinstruments.com/api/getting-started Utilize the Moku Scripting API for LabVIEW, which includes VIs for Moku instrument operation. Download the VI package to begin. ```LabVIEW // Example: Load Moku instrument VIs in LabVIEW // Requires downloading the VI package. ``` -------------------------------- ### Python: Initialize Oscilloscope with Force Connect Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Illustrates initializing an Oscilloscope instrument with a specific IP address and forcing a connection. This example is used to demonstrate a `ValueError` related to firmware compatibility. ```Python from moku.instruments import Oscilloscope i = Oscilloscope('192.168.###.###', force_connect=True) ``` -------------------------------- ### LabVIEW Oscilloscope Example: Sine Wave Generation and Display Source: https://apis.liquidinstruments.com/api/getting-started/starting-labview An example demonstrating the use of the Moku Oscilloscope through LabVIEW. It covers initiating a Moku client session, uploading the Oscilloscope instrument, configuring the timebase, generating an output sine wave, and retrieving and displaying the time-series voltage data on a front panel graph. The client and error terminals are passed through each VI for proper data flow and error handling. ```LabVIEW VI Snippet of the example ``` -------------------------------- ### Python Cloud Compile Adder Example Setup Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This Python script demonstrates setting up Cloud Compile with the Moku Multi-Instrument mode to run the Adder example. It imports necessary libraries for instrument control and plotting. ```Python # # moku example: Adder Cloud Compile # # This example demonstrates how you can configure Cloud Compile, using # Multi-Instrument mode, to add and subtract two input signals together and # output the result to the Oscilloscope. # # (c) Liquid Instruments Pty. Ltd. # import matplotlib.pyplot as plt from moku.instruments import MultiInstrument, CloudCompile, Oscilloscope # Connect to your Moku by its ip address using # MultiInstrument('192.168.###.###') ``` -------------------------------- ### PID Controller Plotting Example Setup Source: https://apis.liquidinstruments.com/api/moku-examples/python-api Imports necessary libraries (matplotlib.pyplot and PIDController from moku.instruments) for plotting and interacting with the PID Controller instrument. This serves as the setup for a script that demonstrates PID controller configuration and real-time output plotting. ```python import matplotlib.pyplot as plt from moku.instruments import PIDController # Connect to your Moku by its ip address using PIDController('192.168.###.###') ``` -------------------------------- ### Download Data Files with MATLAB Source: https://apis.liquidinstruments.com/api/getting-started/starting-matlab This command downloads the necessary data files for the Moku Scripting API for MATLAB. Replace '###' with the current firmware version of your Moku device. This step is crucial for running any programs with the API and is typically only needed upon initial installation or upgrade. ```MATLAB moku_download(###) ``` -------------------------------- ### Download instrument bitstreams Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Downloads instrument bitstreams for a specified MokuOS version using the mokucli command. This step is necessary before running any programs with the Moku Scripting API. ```Shell # download instrument bitstreams for MokuOS 4.0.1 $: mokucli instrument download 4.0.1 ℹ Resolved Version 4.0.1 to instruments build 18260 Downloading 362 bitstream(s) matching 'all'... ━━━━━━━━━━━━━━━━━ 100% 0:00:00 ✓ Downloaded 362/362 bitstream(s) ``` -------------------------------- ### Initialize Oscilloscope and get data (IPv4) Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Initializes an Oscilloscope instrument object using its IP address and retrieves data from it. This is a basic example of interacting with a Moku device via the Python API. ```Python >>> from moku.instruments import Oscilloscope >>> osc = Oscilloscope('192.168.###.###') >>> osc.get_data() ``` -------------------------------- ### Python: Connect to Oscilloscope and Get Data Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Demonstrates how to connect to an Oscilloscope instrument using its IP address and retrieve data. This code requires the `moku` library and assumes a successful connection. ```Python from moku.instruments import Oscilloscope osc = Oscilloscope('192.168.###.###') osc.get_data() ``` -------------------------------- ### Check Python version Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Checks the installed Python version on the system. The Moku Scripting API requires Python 3.5 or higher. ```Shell $: python --version Python 3.9.0 ``` -------------------------------- ### Configure and Control Multi-Instrument Setup Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This snippet shows how to initialize a MultiInstrument object, set up connections between different instruments (WaveformGenerator, NeuralNetwork, Oscilloscope), configure their parameters, and generate a real-time plot of the data. It includes error handling and resource management. ```Python from moku.instruments import WaveformGenerator, NeuralNetwork, Oscilloscope from moku import MultiInstrument import matplotlib.pyplot as plt # Connect to your Moku by its ip address using MultiInstrument('192.168.###.###', platform_id=4) # force_connect will overtake an existing connection m = MultiInstrument('192.168.###.###', platform_id=4, force_connect=True) try: # Set up MiM configuration wg = m.set_instrument(1, WaveformGenerator) nn = m.set_instrument(2, NeuralNetwork) osc = m.set_instrument(3, Oscilloscope) connections = [dict(source="Slot1OutA", destination="Slot2InA"), dict(source="Slot1OutA", destination="Slot2InB"), dict(source="Slot1OutB", destination="Slot2InC"), dict(source="Slot1OutB", destination="Slot2InD"), dict(source="Slot2OutA", destination="Slot3InA")] print(m.set_connections(connections=connections)) # Generate ramp wave in Waveform Generator wg.generate_waveform(channel=1, type='Ramp', amplitude=0.25, frequency=5e3, symmetry=100) print(wg.summary()) # Load network into Neural Network and set inputs and outputs nn.set_input(strict=False, channel=1, low_level=-1, high_level=1) nn.set_input_sample_rate(sample_rate=305000) nn.upload_network("/path/to/simple_sine_model.linn") nn.set_output(strict=False, channel=1, enabled=True, low_level=-1, high_level=1) print(nn.summary()) # Set up Oscilloscope for plotting osc.set_timebase(-5e-3, 5e-3) data = osc.get_data() print(osc.summary()) # Set up the plotting parameters plt.ion() plt.show() plt.grid(visible=True) plt.ylim([-1, 1]) plt.xlim([data['time'][0], data['time'][-1]]) line, = plt.plot([]) # Configure labels for axes ax = plt.gca() # This loops continuously updates the plot with new data while True: # Get new data data = osc.get_data() # Update the plot line.set_ydata(data['ch1']) line.set_xdata(data['time']) plt.pause(0.001) except Exception as e: m.relinquish_ownership() raise e finally: # Close the connection to the Moku device # This ensures network resources and released correctly m.relinquish_ownership() ``` -------------------------------- ### C++ Moku API Client Source: https://apis.liquidinstruments.com/api/moku-examples/other-language-api This C++ code demonstrates how to interact with the Moku REST API. It includes functions for building URLs, executing HTTP GET and POST requests, and handling responses. The example shows how to claim ownership of a Moku device, set up authentication headers, and retrieve device details such as its name and serial number. ```C++ /* * Simple C++ example on how to use the Moku REST API for Liquid Instruments * Moku Devices. * IMPORTANT: Deploy the Oscilloscope through the Desktop or iPad apps before * running this script in order to transfer the instrument data. See * https://apis.liquidinstruments.com/starting-curl.html#first-steps * NOTE: This example demonstrates how to deploy and interact with an * Oscilloscope. Details on list of methods and associated request * schemas can be found at * https://apis.liquidinstruments.com/reference/oscilloscope/ * NOTE: This example uses nlohmann/json(https://json.nlohmann.me/) which is a header only library * to serialize and deserialize JSON body. */ #include #include #include "nlohmann/json.hpp" using json = nlohmann::json; std::string ipAddress = "192.168.73.1"; std::string clientKey = ""; std::string buildURL(const std::string &endpoint) { std::ostringstream urlStream; urlStream << "http://" << ipAddress << "/api/" << endpoint; return urlStream.str(); } json executeHttpRequest(CURL *curl, const std::string &url, const std::string &response) { CURLcode resCode = curl_easy_perform(curl); if (resCode != CURLE_OK) { fprintf(stderr, "Error occurred while performing %s. Error: %s", url.c_str(), curl_easy_strerror(resCode)); std::exit(-1); } else { long httpCode; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); if (httpCode != 200) { fprintf(stderr, "Error occurred while performing %s. HTTP Code: %ld", url.c_str(), httpCode); std::exit(-1); } json apiResponse = json::parse(response); if (!apiResponse["success"]) { std::ostringstream errorStream; errorStream << apiResponse["code"] << ": " << apiResponse["messages"].dump(); fprintf(stderr, "%s", errorStream.str().c_str()); std::exit(-1); } return apiResponse["data"]; } } size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *response) { size_t totalSize = size * nmemb; response->append(static_cast(contents), totalSize); return totalSize; } json httpGet(CURL *curl, const std::string &url) { CURLcode resCode; std::string response; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); return executeHttpRequest(curl, url, response); } json httpPost(CURL *curl, const std::string &url, json requestBody) { CURLcode resCode; std::string response; auto postData = requestBody.dump(); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.size()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); return executeHttpRequest(curl, url, response); } int main() { CURL *curl; CURLcode res; curl = curl_easy_init(); if (curl) { { /* * The first thing we need to do is to take ownership of the Moku. * We do that by sending a `POST` to the `claim_ownership` resource * and it gives us back a key that we can include in all future * requests to prove we are the owner. */ json claimReq; claimReq["force_connect"] = true; clientKey = httpPost(curl, buildURL("moku/claim_ownership"), claimReq); /* * Now that we obtained the clientKey, we include it as * part of header for every subsequent request proving * the ownership. * Let's do that by adding it to the headers of * the curl object */ struct curl_slist *headers = NULL; std::ostringstream clientKeyHeader; clientKeyHeader << "Moku-Client-Key: " << clientKey; headers = curl_slist_append(headers, clientKeyHeader.str().c_str()); headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); printf("Established connection, client key: %s\n", clientKey.c_str()); } { // Get the Moku's name auto result = httpGet(curl, buildURL("moku/name")); std::cout << result << std::endl; } { // Get the Moku's serial auto result = httpGet(curl, buildURL("moku/serial_number")); std::cout << result << std::endl; } { ``` -------------------------------- ### Configure Output and Front-end Settings (cURL) Source: https://apis.liquidinstruments.com/api/getting-started/starting-mim This cURL example shows how to configure output gain and front-end settings for a Multi-instrument Interface (MIM) using the REST API. It requires specifying the Moku-Client-Key and the IP address of the instrument. ```cURL curl -H 'Moku-Client-Key: ' http:///api/mim/set_output -d '{channel: 1, gain: "14dB"}' curl -H 'Moku-Client-Key: ' http:///api/mim/set_frontend -d '{channel: 1, impedance: "50Ohm", attenuation: "0dB", coupling: "DC"}' ``` -------------------------------- ### Get Moku Name (Node.js) Source: https://apis.liquidinstruments.com/api/moku-examples/other-language-api This example demonstrates how to retrieve the name of the Moku device. It sends a GET request to the `/api/moku/name` endpoint, including the `Moku-Client-Key` in the headers. ```javascript response = await makeRequest({ url: `http://${IP_ADDRESS}/api/moku/name`, method: 'GET', headers: { 'Moku-Client-Key': clientKey } }) console.log(JSON.parse(response.body)) ``` -------------------------------- ### Configure Request Session Attributes in Moku API Source: https://apis.liquidinstruments.com/api/getting-started/starting-python This example demonstrates how to configure session attributes, such as proxy or authentication parameters, for the Moku API connection by prepending 'session_' to the attribute name and passing it to the instrument constructor. Here, 'session_trust_env' is set to False. ```Python o = Oscilloscope("192.168.###.###", session_trust_env=False) ``` -------------------------------- ### cURL Initialization and Cleanup Source: https://apis.liquidinstruments.com/api/moku-examples/other-language-api Demonstrates the necessary steps for initializing and cleaning up the cURL library for making HTTP requests. This includes global initialization and per-handle cleanup. ```C++ // Clean up curl_easy_cleanup(curl); } // Clean up global cURL resources curl_global_cleanup(); return 0; } ``` -------------------------------- ### Decode API Output with jq Source: https://apis.liquidinstruments.com/api/getting-started/starting-curl Process JSON responses from the Moku API using the `jq` command-line JSON processor. This example demonstrates how to extract specific data fields, such as the magnitude data for channel 1 from a Frequency Response Analyzer trace. ```bash # Extract the magnitude data from a Frequency Response Analyzer trace $: curl -H 'Moku-Client-Key: ' http:///api/fra/get_data | \ jq ".data.ch1.magnitude" ``` -------------------------------- ### Configure Moku:Go Power Supply Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This example demonstrates how to configure the power supply units of the Moku:Go. It shows how to set the voltage and current for a specific power supply unit and then retrieve its status. ```Python # Project: /websites/apis_liquidinstruments_api # # moku example: Basic Programmable Power Supply Unit # # This example will demonstrate how to configure the power supply # units of the Moku:Go. # # (c) Liquid Instruments Pty. Ltd. # from moku.instruments import Oscilloscope # Connect to your Moku by its ip address using Oscilloscope('192.168.###.###') # An instrument must be deployed to establish the connection with the # Moku, in this example we will use the Oscilloscope. # force_connect will overtake an existing connection i = Oscilloscope('192.168.###.###', force_connect=True) try: # Configure Power Supply Unit 1 to 2 V and 0.1 A i.set_power_supply(1,enable=True,voltage=2, current=0.1) # Read the current status of Power Supply Unit 1 print(i.get_power_supply(1)) except Exception as e: i.relinquish_ownership() raise e finally: # Close the connection to the Moku device # This ensures network resources and released correctly i.relinquish_ownership() ``` -------------------------------- ### Configure PID Controller Basic Source: https://apis.liquidinstruments.com/api/moku-examples/matlab-api Demonstrates basic configuration of the PID Controller instrument, including setting the control matrix, enabling channels, and configuring controllers by gain and frequency. ```matlab %% Basic PID Controller Example % % This example demonstrates how you can configure the PID Controller instrument. % % (c) Liquid Instruments Pty. Ltd. % % Connect to your Moku and deploy the PID controller instrument % force_connect will overtake an existing connection i = MokuPIDController('192.168.###.###', force_connect=true); try %% Configure the PID controller % Configure the control matrix i.set_control_matrix(1,1,0); i.set_control_matrix(2,0,1); % Enable all input and output channels i.enable_input(1,true); i.enable_input(2,true); i.enable_output(1,true,true); i.enable_output(2,true,true); % Configure controller 1 by gain i.set_by_gain(1,'prop_gain',10, 'diff_gain',-5,'diff_corner',5e3 ); % Configure controller 2 by frequency i.set_by_frequency(2, 'prop_gain', -5, 'int_crossover',100, 'int_saturation',10); catch ME % End the current connection session with your Moku i.relinquish_ownership(); rethrow(ME) end i.relinquish_ownership(); Copied! ``` -------------------------------- ### Phasemeter: Basic Configuration Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This example demonstrates the basic configuration of the Phasemeter instrument to measure four independent signals. It shows how to import the instrument and connect to a Moku device. ```Python # # moku example: Basic Phasemeter # # This example demonstrates how you can configure the Phasemeter # instrument to measure 4 independent signals. # (c) Liquid Instruments Pty. Ltd. # from moku.instruments import Phasemeter # Connect to your Moku by its ip address using Phasemeter('192.168.###.###') ``` -------------------------------- ### Get Moku Instrument Name in MATLAB Source: https://apis.liquidinstruments.com/api/reference/moku/name Retrieve the instrument's name in MATLAB by calling the 'name' function directly from the Moku instrument reference. This example uses the MokuOscilloscope class. ```MATLAB m = MokuOscilloscope('192.168.###.###', false); % Here you can access the name function m.name() ``` -------------------------------- ### Configure and Operate Moku Instruments Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This snippet demonstrates connecting to a Moku device, setting up instruments like CloudCompile and Oscilloscope, configuring connections between instrument slots, generating waveforms, setting timebases and triggers, and acquiring data. It also shows how to perform arithmetic operations (add, subtract, multiply) on input signals and plot the results. ```Python from moku.instruments import MultiInstrument, CloudCompile, Oscilloscope import matplotlib.pyplot as plt # Connect to the Moku device m = MultiInstrument('192.168.###.###', platform_id=2, force_connect=True) try: # Set up instruments and upload bitstreams bitstream = "path/to/project/arithmetic/bitstreams.tar.gz" mcc = m.set_instrument(1, CloudCompile, bitstream=bitstream) osc = m.set_instrument(2, Oscilloscope) # Configure instrument connections connections = [ dict(source="Slot1OutA", destination="Slot2InA"), dict(source="Slot2OutB", destination="Slot2InB"), dict(source="Slot2OutA", destination="Slot1InA"), dict(source="Slot2OutB", destination="Slot1InB") ] m.set_connections(connections=connections) # Configure Oscilloscope waveforms and trigger osc.generate_waveform(1, 'Square', amplitude=50e-3, frequency=1e3, duty=50) osc.generate_waveform(2, 'Ramp', amplitude=50e-3, frequency=1e3, symmetry=50) osc.sync_output_phase() osc.set_timebase(-2e-3, 2e-3) osc.set_trigger(type="Edge", edge="Rising", level=0, mode="Normal", source="ChannelB") # Set up plotting fig, axs = plt.subplots(3, sharex=True) # Perform arithmetic operations and plot results operations = {0b00: 'Add - 0b00', 0b01: 'Subtract - 0b01', 0b10: 'Multiply - 0b10'} colors = ['r', 'b', 'y'] for i, (op_code, title) in enumerate(operations.items()): mcc.set_control(1, op_code) data = osc.get_data(wait_reacquire=True) axs[i].plot(data['time'], data['ch1'], color=colors[i]) axs[i].grid(visible=True) axs[i].set_title(title) if i == 1: axs[i].set_ylabel("Amplitude [Volt]") plt.xlabel("Time [Second]") plt.tight_layout() plt.show() except Exception as e: m.relinquish_ownership() raise e finally: m.relinquish_ownership() ``` -------------------------------- ### Configure PID Controller and Plot Data Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This example demonstrates how to configure a PID controller with specific control matrix, frequency response, and gain characteristics. It also shows how to set up monitoring, timebase, trigger, and enable output channels. The data is then plotted in real-time. ```Python # Project: /websites/apis_liquidinstruments_api # force_connect will overtake an existing connection i = PIDController('192.168.###.###', force_connect=True) try: # Configures the control matrix: # Channel 1: input 1 gain = 1 dB, input 2 gain = 0 dB # Channel 2: input 2 gain = 0 dB, input 2 gain = 1 dB i.set_control_matrix(channel=1, input_gain1=1, input_gain2=0) i.set_control_matrix(channel=2, input_gain1=0, input_gain2=1) # Configure the Channel 1 PID Controller using frequency response # characteristics # P = -10dB # I Crossover = 100Hz # D Crossover = 10kHz # I Saturation = 10dB # D Saturation = 10dB # Double-I = OFF # Note that gains must be converted from dB first i.set_by_frequency(channel=1, prop_gain=-10, int_crossover=1e2, diff_crossover=1e4, int_saturation=10, diff_saturation=10) # Configure the Channel 2 PID Controller using gain characteristics # Overall Gain = 6dB # I Gain = 20dB i.set_by_gain(channel=2, overall_gain=6.0, prop_gain=20) # Set the probes to monitor Output 1 and Output 2 i.set_monitor(1, 'Output1') i.set_monitor(2, 'Output2') # Set the timebase i.set_timebase(-1e-3, 1e-3) # +- 1ms i.set_trigger(type='Edge', source='ProbeA', level=0) # Enable the output channels of the PID controller i.enable_output(1, True, True) i.enable_output(2, True, True) # 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(visible=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: i.relinquish_ownership() raise e finally: # Close the connection to the Moku device # This ensures network resources and released correctly i.relinquish_ownership() ``` -------------------------------- ### Initialize Oscilloscope and get data (IPv6) Source: https://apis.liquidinstruments.com/api/getting-started/starting-python Initializes an Oscilloscope instrument object using an IPv6 address (enclosed in square brackets) and retrieves data from it. This demonstrates how to connect to a Moku device using IPv6. ```Python >>> from moku.instruments import Oscilloscope >>> osc = Oscilloscope('[fe80::7269:79ff:feb9:0000%0]') >>> osc.get_data() ``` -------------------------------- ### Configure and Log Data with Datalogger Source: https://apis.liquidinstruments.com/api/moku-examples/python-api This snippet shows how to configure the Datalogger instrument, set frontend parameters, sample rate, acquisition mode, generate a sine wave, start logging data for a specified duration, track logging progress, and download the log file. It includes error handling and ensures proper relinquishing of device ownership. ```Python from moku.instruments import Datalogger import time import os # force_connect will overtake an existing connection i = Datalogger('192.168.###.###', force_connect=True) try: # Configure the frontend i.set_frontend(channel=1, impedance='1MOhm', coupling="AC", range="10Vpp") # Log 100 samples per second i.set_samplerate(100) i.set_acquisition_mode(mode='Precision') # Generate Sine wave on Output1 i.generate_waveform(channel=1, type='Sine', amplitude=1, frequency=10e3) # Stop an existing log, if any, then start a new one. 10 seconds of both # channels logFile = i.start_logging(duration=10) # Track progress percentage of the data logging session complete = False while complete is False: # Wait for the logging session to progress by sleeping 0.5sec time.sleep(0.5) # Get current progress percentage and print it out progress = i.logging_progress() complete = progress['complete'] if 'time_remaining' in progress: print(f"Remaining time {progress['time_remaining']} seconds") # Download log from Moku, use liconverter to convert this .li file to .csv i.download("persist", logFile['file_name'], os.path.join(os.getcwd(), logFile['file_name'])) print("Downloaded log file to local directory.") except Exception as e: i.relinquish_ownership() raise e finally: # Close the connection to the Moku device # This ensures network resources and released correctly i.relinquish_ownership() ``` -------------------------------- ### Get Power Supply State (cURL) Source: https://apis.liquidinstruments.com/api/reference/ppsu/get_power_supply Provides an example of how to get the power supply state using cURL. It includes the necessary headers for authentication and content type, along with the JSON payload containing the power supply ID. ```cURL $: curl -H 'Moku-Client-Key: ' -H 'Content-Type: application/json' --data '{"id": 1}' http:///api/moku/get_power_supply ``` -------------------------------- ### Configure Cloud Compile Adder Example Source: https://apis.liquidinstruments.com/api/moku-examples/matlab-api This MATLAB code configures the Moku device for Cloud Compile using Multi-Instrument mode to run the Adder example. It connects to the Moku, sets up the Cloud Compile and Oscilloscope instruments, defines signal routing, generates waveforms, and plots the results. It requires the Moku Instruments toolbox and a bitstream file. ```MATLAB %% Adder Cloud Compile Example % % This example demonstrates how you can configure Cloud Compile, using % Multi-Instrument mode, to add and subtract two input signals together and % output the result to the Oscilloscope. % % (c) Liquid Instruments Pty. Ltd. % %% Before running % The 'Adder' example is located at: % (https://github.com/liquidinstruments/moku-examples/tree/main/mcc/Basic/Adder) % % Unzip the bitstream (.tar file) once downloaded, and the unzipped folder % contains 2 or 4 .bar files depending on Moku hardware. The bitstream path % should point to this unzipped folder. %% Connect to your Moku % Connect to Moku via its IP address. Change platform_id to 2 for Moku:Lab and Moku:Go. % force_connect will overtake an existing connection m = MokuMultiInstrument('192.168.###.###', 4, force_connect=true); try %% Configure the instruments % Set the instruments and upload Cloud Compile bitstreams from your device % to your Moku bitstream = 'path/to/project/adder/unzipped_bitstream'; mcc = m.set_instrument(1, @MokuCloudCompile, bitstream); osc = m.set_instrument(2, @MokuOscilloscope); % configure routing connections = [struct('source','Slot1OutA', 'destination','Slot2InA'); struct('source','Slot1OutB', 'destination','Slot2InB'); struct('source','Slot2OutA', 'destination','Slot1InA'); struct('source','Slot2OutB', 'destination','Slot1InB')]; m.set_connections(connections); %% Configure the Oscilloscope to generate a ramp wave and square wave with % equal frequencies, then sync the phases osc.generate_waveform(1, 'Square', 'amplitude',1, 'frequency',1e3, 'duty',50); osc.generate_waveform(2, 'Ramp', 'amplitude',1, 'frequency',1e3, 'symmetry',50); osc.sync_output_phase(); % Set the time span to cover four cycles of the waveforms osc.set_timebase(-2e-3, 2e-3); %% Plot the acquired data and set up plotting parameters % Get initial data to set up plots data = osc.get_data('wait_complete', true); % Set up the plots figure plot(data.time, data.ch1); hold on plot(data.time, data.ch2); xlabel(gca, 'Time (sec)') ylabel(gca, 'Amplitude (V)') legend('Add', 'Subtract') grid on; axis tight; catch ME % End the current connection session with your Moku m.relinquish_ownership(); rethrow(ME) end m.relinquish_ownership(); ``` -------------------------------- ### Configure Waveform Generator with Modulation Source: https://apis.liquidinstruments.com/api/moku-examples/matlab-api This example extends the basic setup by demonstrating how to configure modulation for the Waveform Generator. It includes amplitude modulation on Channel 1 and burst mode on Channel 2, triggered by an external output. ```matlab %% Basic Waveform Generator Example % % This example demonstrates how you can configure the Waveform Generator % instrument. % % (c) Liquid Instruments Pty. Ltd. % %% Connect to your Moku % Connect to your Moku by its IP address. % force_connect will overtake an existing connection i = MokuWaveformGenerator('192.168.###.###', force_connect=true); try %% Configure the instrument % Generate a sine wave on Channel 1 % 0.5Vpp, 1MHz, 0V offset i.generate_waveform(1, 'Sine','amplitude', 0.5, 'frequency',1e6,'offset',0); % Generate a square wave on Channel 2 % 1Vpp, 10kHz, 0V offset, 50% duty cycle i.generate_waveform(2, 'Square', 'amplitude',1,'frequency',10e3,'duty', 50); % Phase sync between the two channels i.sync_phase(); %% Configure modulation % Amplitude modulate the Channel 1 Sinewave with another internally- % generated sinewave. 50% modulation depth at 1Hz. i.set_modulation(1,'Amplitude','Internal','depth',50, 'frequency',1); % Burst modulation on Channel 2 using Output 1 as the trigger i.set_burst_mode(2,'Output1','NCycle','trigger_level',0.1, 'burst_cycles',2); catch ME % End the current connection session with your Moku i.relinquish_ownership(); rethrow(ME) end i.relinquish_ownership(); ``` -------------------------------- ### Get Chunk Data in Python Source: https://apis.liquidinstruments.com/api/reference/datalogger/get_chunk Retrieves a single data chunk from a stream using the Datalogger instrument. Ensure the Moku library is installed and the instrument is initialized with the correct IP address. The `start_streaming` method must be called before `get_chunk`. ```Python from moku.instruments import Datalogger i = Datalogger('192.168.###.###') i.start_streaming(duration=10) data = i.get_chunk() ``` -------------------------------- ### Configure Programmable Power Supply Source: https://apis.liquidinstruments.com/api/moku-examples/matlab-api Demonstrates configuring a Programmable Power Supply unit on the Moku:Go, setting its voltage and current, and reading its status. ```matlab %% PPSU Example % % This example will demonstrate how to configure the power supply % units of the Moku:Go. % % (c) Liquid Instruments Pty. Ltd. % % Connect to your Moku by its IP address. % An instrument must be deployed to establish the connection with the % Moku, in this example we will use the Oscilloscope. % force_connect will overtake an existing connection i = MokuOscilloscope('192.168.###.###', force_connect=true); try % Configure Power Supply Unit 1 to 2 V and 0.1 A i.set_power_supply(1,'enable',true,'voltage',2,'current',0.1); % Read the current status of Power Supply Unit 1 disp(i.get_power_supply(1)); catch ME % End the current connection session with your Moku i.relinquish_ownership(); rethrow(ME) end i.relinquish_ownership(); Copied! ``` -------------------------------- ### Get Oscilloscope Data (Node.js) Source: https://apis.liquidinstruments.com/api/moku-examples/other-language-api This example shows how to retrieve data from the oscilloscope. It sends a POST request to the `/api/oscilloscope/get_data` endpoint with a JSON body specifying `wait_reacquire: false`. The response contains time-series data for channels. ```javascript response = await makeRequest({ url: `http://${IP_ADDRESS}/api/oscilloscope/get_data`, method: 'POST', body: JSON.stringify({ wait_reacquire: false }), headers: { 'Moku-Client-Key': clientKey } }) console.log(JSON.parse(response.body).data) ``` -------------------------------- ### Configure PID Controller with Force Connect Source: https://apis.liquidinstruments.com/api/moku-examples/python-api Initializes the PIDController with force connect enabled and configures control matrices for two channels. It then sets up PID control loops using frequency response characteristics for channel 1 and gain characteristics for channel 2. Finally, it enables the outputs for both channels and includes error handling with connection relinquishment. ```python i = PIDController('192.168.###.###', force_connect=True) try: i.set_control_matrix(channel=1, input_gain1=1, input_gain2=0) i.set_control_matrix(channel=2, input_gain1=0, input_gain2=1) i.set_by_frequency(channel=1, prop_gain=-10, int_crossover=1e2, diff_crossover=1e4, int_saturation=10, diff_saturation=10) i.set_by_gain(channel=2, overall_gain=0, prop_gain=10, diff_gain=-5, diff_corner=5e3) i.enable_output(1, signal=True, output=True) i.enable_output(2, signal=True, output=True) except Exception as e: i.relinquish_ownership() raise e finally: i.relinquish_ownership() ``` -------------------------------- ### cURL Moku API Interaction Source: https://apis.liquidinstruments.com/api/getting-started Interact with your Moku device from a terminal or any REST-supporting programming language using cURL. ```bash # Example: Basic cURL command to interact with Moku API # curl http:///api/version ``` -------------------------------- ### Plot Lock-in Amplifier Data Source: https://apis.liquidinstruments.com/api/moku-examples/matlab-api Configures the Lock-in Amplifier and sets up real-time plotting of input signals. It includes signal monitoring, trigger configuration, and a loop to continuously update plots with new data. This example requires the basic configuration setup. ```MATLAB %% Plotting Lock-in Amplifier Example % % This example demonstrates how you can configure the Lock-in Amplifier % instrument to demodulate an input signal from Input 1 with the reference % signal from the Local Oscillator to extract the X component and generate % a sine wave on the auxiliary output % % (c) Liquid Instruments Pty. Ltd. % %% Connect to your Moku % Connect to your Moku by its IP address and deploy the Lock-in Amplifier % instrument. % force_connect will overtake an existing connection i = MokuLockInAmp('192.168.###.###', force_connect=true); try %% Configure the instrument % Configure the frontend % Channel 1 DC coupled, 1 MOhm impedance, and 400 mVpp range i.set_frontend(1, 'DC', '1MOhm','0dB'); % Channel 2 DC coupled, 1 MOhm impedance, and 4 Vpp range i.set_frontend(2, 'DC', '1MOhm','-20dB'); % Configure the demodulation signal to Local oscillator with 1 MHz and % 0 degrees phase shift i.set_demodulation('Internal','frequency',1e6,'phase',0); % Set low pass filter to 1 kHz corner frequency with 6 dB/octave slope i.set_filter(1e3,'slope','Slope6dB'); % Configure output signals % X component to Output 1 % Aux oscillator signal to Output 2 at 1 MHz 500 mVpp i.set_outputs('X','Aux'); i.set_aux_output(1e6,0.5); %% Set up signal monitoring % Configure monitor points to Input 1 and main output i.set_monitor(1,'Input1'); i.set_monitor(2,'MainOutput'); % Configure the trigger conditions % Trigger on Probe A, rising edge, 0V i.set_trigger('type','Edge', 'source','ProbeA', 'level',0); % View +- 1 ms i.e. trigger in the centre i.set_timebase(-1e-3,1e-3); %% Set up plots % Get initial data to set up plots data = i.get_data(); % Set up the plots figure lh = plot(data.time, data.ch1, data.time, data.ch2); xlabel(gca,'Time (sec)') ylabel(gca,'Amplitude (V)') %% Receive and plot new data frames while 1 data = i.get_data(); set(lh(1),'XData',data.time,'YData',data.ch1); set(lh(2),'XData',data.time,'YData',data.ch2); axis tight pause(0.1) end catch ME % End the current connection session with your Moku i.relinquish_ownership(); rethrow(ME) end i.relinquish_ownership(); ```