diff --git a/Readme.md b/Readme.md index cc27b7e91..1cb6b5c7a 100644 --- a/Readme.md +++ b/Readme.md @@ -105,7 +105,9 @@ HackRF is better used with a sampling rate of 4.8 MS/s and above. The 2.4 and 3.

⚠ The plugins should work normally when running as single instances. Support of many Rx and/or Tx instances running concurrently is considered experimental.

-You will need a minimal installation of LimeSuite. Presently version 17.12.1 should be used with its corresponding firmware (v4) and gateware (v2.12) installed in the LimeSDR device: +

⚠ It seems LimeSDR mini has trouble working with host sample rates lower than 3 MS/s particularly in Tx mode.

+ +You will need a minimal installation of LimeSuite. Presently commit 04b57e0 or later should be used with its corresponding firmware (v4) and gateware (v2.12) installed in the LimeSDR device: - `sudo apt-get install libsqlite3-dev` - `git clone https://github.com/myriadrf/LimeSuite.git` diff --git a/swagger/sdrangel/examples/Readme.md b/swagger/sdrangel/examples/Readme.md index 825938eac..de30f081e 100644 --- a/swagger/sdrangel/examples/Readme.md +++ b/swagger/sdrangel/examples/Readme.md @@ -35,6 +35,33 @@ It uses the following APIs: - URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run` - HTTP method: `POST` +

limesdr_tx.py

+ +Create a Tx device set with a LimeSDR Tx device and a NFM modulator channel configured to send some beacon Morse code. Then starts the Tx. + +It uses the following APIs: + + - To create a new device set: + - OperationID: `instanceDeviceSetsPost` + - URI: `/sdrangel/devicesets` + - HTTP method: `POST` + - To select a device in a device set: + - Operation ID: `devicesetDevicePut` + - URI: `/sdrangel/deviceset/{deviceSetIndex}/device` + - HTTP method: `PUT` + - To create a new channel: + - Operation ID: `devicesetChannelPost` + - URI: `/sdrangel/deviceset/{deviceSetIndex}/channel` + - HTTP method: `POST` + - To change the settings of a channel: + - OperationID: `devicesetChannelSettingsPatch` + - URI: `/sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings` + - HTTP method: `PATCH` + - Start a device streaming + - OperationID: `devicesetDeviceRunPost` + - URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run` + - HTTP method: `POST` +

nfm_test.py

Example of creating NFM channels (demodulator and modulator) and changing the settings diff --git a/swagger/sdrangel/examples/limesdr_tx.py b/swagger/sdrangel/examples/limesdr_tx.py new file mode 100644 index 000000000..c61830e75 --- /dev/null +++ b/swagger/sdrangel/examples/limesdr_tx.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +import requests, json, traceback, sys +from optparse import OptionParser + +base_url = "http://127.0.0.1:8091/sdrangel" + +requests_methods = { + "GET": requests.get, + "PATCH": requests.patch, + "POST": requests.post, + "PUT": requests.put, + "DELETE": requests.delete +} + +# ====================================================================== +def getInputOptions(): + + parser = OptionParser(usage="usage: %%prog [-t]\n") + parser.add_option("-a", "--address", dest="address", help="address and port", metavar="ADDRESS", type="string") + + (options, args) = parser.parse_args() + + if (options.address == None): + options.address = "127.0.0.1:8091" + + return options + +# ====================================================================== +def printResponse(response): + content_type = response.headers.get("Content-Type", None) + if content_type is not None: + if "application/json" in content_type: + print(json.dumps(response.json(), indent=4, sort_keys=True)) + elif "text/plain" in content_type: + print(response.text) + +# ====================================================================== +def callAPI(url, method, params, json, text): + request_method = requests_methods.get(method, None) + if request_method is not None: + r = request_method(url=base_url+url, params=params, json=json) + if r.status_code == 200: + print(text + " succeeded") + printResponse(r) + return r.json() # all 200 yield application/json response + else: + print(text + " failed") + printResponse(r) + return None + +# ====================================================================== +def main(): + try: + options = getInputOptions() + + global base_url + base_url = "http://%s/sdrangel" % options.address + + r = callAPI("/devicesets", "POST", {"tx": 1}, None, "Add Tx device set") + if r is None: + exit(-1) + + r = callAPI("/deviceset/1/device", "PUT", None, {"hwType": "LimeSDR", "tx": 1}, "setup LimeSDR on Tx 1") + if r is None: + exit(-1) + + settings = callAPI("/deviceset/1/device/settings", "GET", None, None, "Get LimeSDR Tx settings") + if settings is None: + exit(-1) + + settings["limeSdrOutputSettings"]["antennaPath"] = 1 + settings["limeSdrOutputSettings"]["devSampleRate"] = 3200000 + settings["limeSdrOutputSettings"]["log2SoftInterp"] = 4 + settings["limeSdrOutputSettings"]["ncoEnable"] = 1 + settings["limeSdrOutputSettings"]["ncoFrequency"] = -500000 + settings["limeSdrOutputSettings"]["lpfFIRBW"] = 100000 + settings["limeSdrOutputSettings"]["lpfFIREnable"] = 1 + + r = callAPI("/deviceset/1/device/settings", "PATCH", None, settings, "Patch LimeSDR Tx settings") + if r is None: + exit(-1) + + settings = callAPI("/deviceset/1/channel", "POST", None, {"channelType": "NFMMod", "tx": 1}, "Create NFM mod") + if settings is None: + exit(-1) + + settings["NFMModSettings"]["cwKeyer"]["text"] = "VVV DE F4EXB " + settings["NFMModSettings"]["cwKeyer"]["loop"] = 1 + settings["NFMModSettings"]["cwKeyer"]["mode"] = 1 # text + settings["NFMModSettings"]["modAFInput"] = 4 # CW text + settings["NFMModSettings"]["toneFrequency"] = 600 + + r = callAPI("/deviceset/1/channel/0/settings", "PATCH", None, settings, "Change NFM mod") + if r is None: + exit(-1) + + r = callAPI("/deviceset/1/device/run", "POST", None, None, "Start device on deviceset R1") + if r is None: + exit(-1) + + except Exception, msg: + tb = traceback.format_exc() + print >> sys.stderr, tb + + +if __name__ == "__main__": + main() +