{"id":453,"date":"2010-12-21T20:56:37","date_gmt":"2010-12-21T20:56:37","guid":{"rendered":"https:\/\/ibex.tech\/visualcpp\/?p=453"},"modified":"2022-02-17T06:24:04","modified_gmt":"2022-02-17T06:24:04","slug":"ftdi-usb-devices","status":"publish","type":"post","link":"https:\/\/ibex.tech\/visualcpp\/serial-port\/ftdi-usb-devices","title":{"rendered":"FTDI USB Devices"},"content":{"rendered":"<h4>\nFinding Connected FTDI Devices<br \/>\n<\/h4>\n<pre>\r\n<code>\r\nusing namespace Microsoft::Win32;\t\t\/\/&lt; Needed to access registry\r\n<\/code><\/pre>\n<pre>\r\n<code>\r\nint Count;\r\nint CharPosn;\r\nint CheckEachPortCount;\r\nString ^RegistryMainFolder;\r\nString ^SerialNumber;\r\nString ^Port;\r\narray&lt;String^&gt; ^FoundCommPorts = gcnew array&lt;String^&gt;(0);\r\narray&lt;String^&gt; ^FoundSerialNumbers = gcnew array&lt;String^&gt;(0);\r\n\r\n\/\/----- SETUP THE COMM PORT COMBO BOX -----\r\n\r\n\/\/Add the default comm port &quot;None&quot;\r\ncmbCommPort-&gt;Items-&gt;Add(L&quot;None&quot;);\r\n\r\ntry\r\n{\r\n\t\/\/----- DISCOVER ALL AVAILABLE SERIAL PORTS -----\r\n\tarray&lt;String^&gt; ^AvailableSerialPorts;\r\n\t AvailableSerialPorts = SerialPort::GetPortNames();\r\n\r\n\t\/\/&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; DEBUG SIMULATE COM PORT CONNECTED\r\n\t\/\/Array::Resize(AvailableSerialPorts, AvailableSerialPorts-&gt;Length + 1);\r\n\t\/\/AvailableSerialPorts[AvailableSerialPorts->Length - 1] = &quot;COM3&quot;;\r\n\t\/\/&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;\r\n\r\n\t\/\/----- CHECK REGISTRY TO FIND MATCHING FDTI DEVICES AND ONLY INCLUDE THOSE COMM PORTS -----\r\n\t\/\/(We only show comm ports for our devices that are currently connected)\r\n\t\/\/This is the registry path we&#39;re interested in (taken from FTDI web site):-\r\n\t\/\/HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS\\VID_VID+PID_PID+Serial_Number\\0000\\DeviceParameters\\PortName\r\n\r\n\t\/\/Retrieve all the subkeys for the specified key.\r\n\tRegistryMainFolder= L&quot;SYSTEM\\\\CurrentControlSet\\\\Enum\\\\FTDIBUS&quot;;\r\n\r\n\tRegistryKey ^rkey = Registry::LocalMachine;\r\n\trkey = rkey-&gt;OpenSubKey(RegistryMainFolder);\r\n\tarray&lt;String^&gt;^names = rkey-&gt;GetSubKeyNames();\r\n\r\n\tfor each (String^ name in names)\r\n\t{\r\n\t\t\/\/----- CHECK NEXT FTDI DEVICE IN THE REGISTRY -----\r\n\t\t\/\/This example is based on finding only devices where the FTDI name includes a custom programmed serial number like this:\r\n\t\t\/\/name = VID_VID+PID_PID+Serial_Number\r\n\r\n\t\t\/\/Get Serial Number portion\r\n\t\tCharPosn = name-&gt;LastIndexOf(&quot;+&quot;);\r\n\t\tif (CharPosn &gt;= 0)\r\n\t\t{\r\n\t\t\tSerialNumber = name-&gt;Substring(CharPosn + 1);\t\/\/Returns rest of string starting at character posn #\r\n\t\t\tSerialNumber = SerialNumber-&gt;Trim();\r\n\r\n\t\t\tif ((SerialNumber-&gt;Length == 7) &amp;&amp; (SerialNumber-&gt;Contains(&quot;ABC&quot;)))\t\/\/Example test of length and contents\r\n\t\t\t{\r\n\t\t\t\trkey = Registry::LocalMachine;\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(RegistryMainFolder);\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(name);\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(L&quot;0000\\\\Device Parameters&quot;);\r\n\t\t\t\tPort = Convert::ToString(rkey-&gt;GetValue(&quot;PortName&quot;));\t\t\t\/\/Will be COM1 etc\r\n\r\n\t\t\t\tfor (CheckEachPortCount = 0; CheckEachPortCount &lt; AvailableSerialPorts-&gt;Length; CheckEachPortCount++)\r\n\t\t\t\t{\r\n\t\t\t\t\tif (AvailableSerialPorts[CheckEachPortCount]-&gt;ToString() == Port-&gt;ToString())\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\/\/THIS PORT EXISTS SO DEVICE IS CONNECTED - ADD IT TO THE ARRAY OF FOUND DEVICES\r\n\t\t\t\t\t\tArray::Resize(FoundCommPorts, FoundCommPorts-&gt;Length + 1);\r\n\t\t\t\t\t\tArray::Resize(FoundSerialNumbers, FoundSerialNumbers-&gt;Length + 1);\r\n\t\t\t\t\t\tFoundCommPorts[FoundCommPorts->Length - 1] = Port;\r\n\t\t\t\t\t\tFoundSerialNumbers[FoundSerialNumbers->Length - 1] = SerialNumber;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\trkey-&gt;Close();\r\n\r\n\t\/\/ADD EACH OF THE FOUND DEVICES TO THE COMM PORT COMBO BOX\r\n\tif (FoundCommPorts-&gt;Length)\r\n\t{\r\n\t\tArray::Sort(FoundCommPorts, FoundSerialNumbers);\t\t\/\/Sort by port number\r\n\r\n\t\tfor (Count = 0; Count &lt; FoundCommPorts-&gt;Length; Count++)\r\n\t\t{\r\n\t\t\tcmbCommPort-&gt;Items-&gt;Add(FoundCommPorts[Count] + \" (Serial #: \" + FoundSerialNumbers[Count]-&gt;Substring(4, 4) + &quot;)&quot;);\r\n\t\t}\r\n\r\n\t}\r\n}\r\ncatch(System::Exception^ e)\r\n{\r\n\r\n}\r\n<\/code><\/pre>\n<h4>\nSetting Latency Of FTDI Devices<br \/>\n<\/h4>\n<pre>\r\n<code>\r\n\/\/----- CHECK LATENCY SETTINGS OF FTDI COM PORTS FOR OUR DEVICE -----\r\n\/\/FTDI latency is the time from receiving the last byte before the packet is sen&#39;t via USB\r\n\/\/It is 16mS defualt, we want it as fast as possible and FTDI recomends a min value of 2mS (not 1mS)\r\n\/\/Check each of the FTDI ports that is used by our device and modify the value if need be.  On Windows\r\n\/\/Vista and above access permission will not be given by UAC so a message box is displayed informing the user they need to use &#39;Run As\r\n\/\/Administrator&#39; to allow the applicaiton to update the registry.  To do this they need to log on as an administrator rights user,\r\n\/\/find the application executible in windows explorer, right click and select run as administrator.  Alternatively the values could\r\n\/\/be edited in regedit.\r\n\/\/Tested after setting to 2 and it woudl take between 1mS and 3mS for for the next packet to be sent, implying that the timer in the\r\n\/\/FDTI chip is literally a 1mS incrementing timer, hence the min value of 2mS being recomended.\r\n\r\nint CharPosn;\r\nString ^RegistryMainFolder;\r\nString ^SerialNumber;\r\nint Latency;\r\nstatic bool NotifiedUserCantWriteRegistry = false;\r\n\r\ntry\r\n{\r\n\t\/\/----- CHECK REGISTRY TO FIND FDTI DEVICES -----\r\n\t\/\/Retrieve all the subkeys for the specified key.\r\n\tRegistryMainFolder= L&quot;SYSTEM\\\\CurrentControlSet\\\\Enum\\\\FTDIBUS&quot;;\t\t\/\/FTDI Path:- HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\FTDIBUS\\VID_VID+PID_PID+Serial_Number\\0000\\DeviceParameters\\\r\n\r\n\tRegistryKey ^rkey = Registry::LocalMachine;\r\n\trkey = rkey-&gt;OpenSubKey(RegistryMainFolder);\r\n\tarray&lt;String^&gt;^names = rkey-&gt;GetSubKeyNames();\r\n\r\n\tfor each (String^ name in names)\r\n\t{\r\n\t\t\/\/----- CHECK NEXT FTDI DEVICE IN THE REGISTRY -----\r\n\t\t\/\/name = VID_VID+PID_PID+Serial_Number\r\n\r\n\t\t\/\/Out device has a serial number programmed that always begins with &quot;ABC&quot; so look for it\r\n\r\n\t\t\/\/Get Serial Number\r\n\t\tCharPosn = name-&gt;LastIndexOf(&quot;+&quot;);\r\n\t\tif (CharPosn &gt;= 0)\r\n\t\t{\r\n\t\t\tSerialNumber = name-&gt;Substring(CharPosn + 1);\t\/\/Returns rest of string starting at character posn #\r\n\r\n\t\t\tif (SerialNumber-&gt;Contains(&quot;ABC&quot;))\t\t\t\/\/&lt;&lt;&lt;&lt;&lt;&lt; SET STRING TO LOOK FOR IN SERIAL NUMBER\r\n\t\t\t{\r\n\t\t\t\t\/\/THIS IS OUR PRODUCT\r\n\t\t\t\trkey = Registry::LocalMachine;\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(RegistryMainFolder);\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(name);\r\n\t\t\t\trkey = rkey-&gt;OpenSubKey(L&quot;0000\\\\Device Parameters&quot;);\r\n\r\n\t\t\t\t\/\/CHECK IF WE NEED TO CHANGE THE LATENCY TIMER VALUE\r\n\t\t\t\tLatency = Convert::ToInt32(rkey-&gt;GetValue(&quot;LatencyTimer&quot;));\r\n\t\t\t\tif (Latency != 2)\t\t\t\t\t\t\/\/&lt;&lt;&lt;&lt;&lt;&lt;&lt; LATENCY VALUE REQUIRED\r\n\t\t\t\t{\r\n\t\t\t\t\trkey = rkey-&gt;OpenSubKey(&quot;&quot;, true);\t\/\/Open as writable\r\n\t\t\t\t\trkey-&gt;SetValue(&quot;LatencyTimer&quot;, 2);\t\/\/&lt;&lt;&lt;&lt;&lt;&lt;&lt; LATENCY VALUE REQUIRED\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\trkey-&gt;Close();\r\n}\r\ncatch(System::Exception^ e)\r\n{\r\n\tif (!NotifiedUserCantWriteRegistry)\r\n\t\tMessageBox::Show(L&quot;Unable to modify FTDI latency parameters in Windows registry.\\nUSB communications will be slower than normal.\\nUse &#39;Run As Administrator&#39; to allow application to set the required values&quot;, L&quot;Need admin permissions&quot;, MessageBoxButtons::OK, MessageBoxIcon::Exclamation);\r\n\tNotifiedUserCantWriteRegistry = true;\r\n}\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Finding Connected FTDI Devices using namespace Microsoft::Win32; \/\/&lt; Needed to access registry int Count; int CharPosn; int CheckEachPortCount; String ^RegistryMainFolder; String ^SerialNumber; String ^Port; array&lt;String^&gt; ^FoundCommPorts = gcnew array&lt;String^&gt;(0); array&lt;String^&gt; ^FoundSerialNumbers = gcnew array&lt;String^&gt;(0); \/\/&#8212;&#8211; SETUP THE COMM PORT COMBO BOX &#8212;&#8211; \/\/Add the default comm port &quot;None&quot; cmbCommPort-&gt;Items-&gt;Add(L&quot;None&quot;); try { \/\/&#8212;&#8211; DISCOVER ALL AVAILABLE [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57],"tags":[],"class_list":["post-453","post","type-post","status-publish","format-standard","hentry","category-serial-port"],"_links":{"self":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/comments?post=453"}],"version-history":[{"count":3,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/453\/revisions"}],"predecessor-version":[{"id":1077,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/453\/revisions\/1077"}],"wp:attachment":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/media?parent=453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/categories?post=453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/tags?post=453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}