{"id":25,"date":"2020-12-13T11:31:08","date_gmt":"2020-12-13T15:31:08","guid":{"rendered":"http:\/\/blog.labhackers.com\/?p=25"},"modified":"2020-12-21T12:22:29","modified_gmt":"2020-12-21T16:22:29","slug":"detecting-labhackers-serial-port-addresses-using-python","status":"publish","type":"post","link":"https:\/\/blog.labhackers.com\/?p=25","title":{"rendered":"Testing Round Trip USB Serial Latency using Python"},"content":{"rendered":"\n<p><sup>Originally posted February 26, 2019.<\/sup><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-twentytwentyone-border\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"597\" src=\"https:\/\/blog.labhackers.com\/wp-content\/uploads\/2020\/12\/figure_1.png\" alt=\"\" class=\"wp-image-372\" srcset=\"https:\/\/blog.labhackers.com\/wp-content\/uploads\/2020\/12\/figure_1.png 800w, https:\/\/blog.labhackers.com\/wp-content\/uploads\/2020\/12\/figure_1-300x224.png 300w, https:\/\/blog.labhackers.com\/wp-content\/uploads\/2020\/12\/figure_1-768x573.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>One important consideration when using a 1000 Hz USB Serial device interface is the delay from when a Serial message is sent to the device to the time when the Serial reply is received by the program. We call this the round trip, or end to end, USB Serial latency of the device.<\/p>\n\n\n\n<p>Here is a simple Python script that tests the round trip USB Serial latency of the first detected MilliKey or USB2TTL8 device.<\/p>\n\n\n\n<p>This example uses a fixed Serial port address that needs to be manually changed to the correct Serial port of the device being tested. For an example of how to programmatically detect your LabHackers\u2019 device serial port from within Python&nbsp;<a href=\"http:\/\/blog.labhackers.com\/?p=51\">c<\/a><a href=\"http:\/\/blog.labhackers.com\/?p=353\" target=\"_blank\" rel=\"noreferrer noopener\">heckout this post.<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">#!\/usr\/bin\/env python\n# -*- coding: utf-8 -*-\nfrom __future__ import division, print_function\n\nimport serial\nimport numpy\nfrom timeit import default_timer as getTime\n\nSERIAL_PORT = 'COM138'\nITERATION_COUNT = 10000\n\ntry:\n    sconn = serial.Serial(SERIAL_PORT, baudrate=128000, timeout=0.1)\nexcept serial.SerialException as e:\n    print(\"Check SERIAL_PORT variable is correct for device being tested.\")\n    raise e\n    \n#clear anything in serial rx\nwhile sconn.readline():\n    pass\n\n# Test time it takes to send a serial message to the labhackers device\n# and receive the serial reply.\nresults = numpy.zeros(ITERATION_COUNT, dtype=numpy.float64)\nfor i in range(ITERATION_COUNT):\n    tx_time = getTime()\n    sconn.write(b\"PING\\n\")\n    r = sconn.readline()\n    rx_time = getTime()\n    if r:\n        results[i] = rx_time-tx_time\n    else:\n        raise RuntimeError(\"Serial RX Timeout.\")\n\nsconn.close()\n\n# Convert times to msec.\nresults = results * 1000.0\n\nprint(\"LabHackers' USB Serial Rx - Tx Latency Stats\")\nprint(\"\\tCount: {}\".format(results.shape))\nprint(\"\\tAverage: {:.3f} msec\".format(results.mean()))\nprint(\"\\tMedian: {:.3f} msec\".format(numpy.median(results)))\nprint(\"\\tMin: {:.3f} msec\".format(results.min()))\nprint(\"\\tMax: {:.3f} msec\".format(results.max()))\nprint(\"\\tStdev: {:.3f} msec\".format(results.std()))<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><\/pre>\n\n\n\n<p>Here is the output from the script when run on Windows, Linux and macOS, showing that the average&nbsp;<em>round trip<\/em>&nbsp;USB serial delay of a LabHackers\u2019 device is well under 1 msec on all operating systems.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Windows 10<\/h3>\n\n\n\n<p>Run using PsychoPy 3.0.5 Coder IDE<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">LabHackers' USB Serial Rx - Tx Latency Stats\n    Count: (10000,)\n    Average: 0.391 msec\n    Median: 0.379 msec\n    Min: 0.352 msec\n    Max: 1.840 msec\n    Stdev: 0.055 msec<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Linux (Mint 18.3)<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">LabHackers' USB Serial Rx - Tx Latency Stats\n\tCount: (10000,)\n\tAverage: 0.320 msec\n\tMedian: 0.313 msec\n\tMin: 0.253 msec\n\tMax: 0.583 msec\n\tStdev: 0.026 msec\n\t<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">macOS 10.13.6<\/h3>\n\n\n\n<p>Run using PsychoPy 3.0.5 Coder IDE<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">LabHackers\u2019 USB Serial Rx \u2013 Tx Latency Stats\nCount: (10000,)\nAverage: 0.708 msec\nMedian: 0.719 msec\nMin: 0.559 msec\nMax: 1.501 msec\nStdev: 0.059 msec<\/pre>\n\n\n\n<p>Happy Hacking!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Originally posted February 26, 2019. One important consideration when using a 1000 Hz USB Serial device interface is the delay from when a Serial message is sent to the device to the time when the Serial reply is received by the program. We call this the round trip, or end to end, USB Serial latency&hellip; <a class=\"more-link\" href=\"https:\/\/blog.labhackers.com\/?p=25\">Continue reading <span class=\"screen-reader-text\">Testing Round Trip USB Serial Latency using Python<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[4,13],"tags":[8,10,14,11,9],"class_list":["post-25","post","type-post","status-publish","format-standard","hentry","category-millikey-response-box","category-usb-serial-timing","tag-millikey","tag-python","tag-timing","tag-usb-serial","tag-usb2ttl8","entry"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/posts\/25","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=25"}],"version-history":[{"count":7,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/posts\/25\/revisions"}],"predecessor-version":[{"id":443,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=\/wp\/v2\/posts\/25\/revisions\/443"}],"wp:attachment":[{"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=25"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=25"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.labhackers.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=25"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}