1

I am trying to establish a connection and read data from a virtual COM port using VB6, following on from my query here: Baud rate limits in software and serial communication with an external device . I am using an FTDI driver to communicate with an device via a USB VCP.

I am using the FTD2XX library on Visual Basic 6 to display the name and serial number of a device (this already works), set the number of stop bits, set baud rates and the number of data bits. I would like now like to read and write from the serial port and I have some code and questions. My code is below:

Public Class FTDI1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim DeviceIndex As Integer
        Dim TempDevString As String
        Dim Read_Result As Integer
        Dim Read_Count As Integer

        ' Get serial number of device with index 0
        ' Allocate space for string variable
        TempDevString = Space(16)
        FT_Status = FT_GetDeviceString(DeviceIndex, TempDevString, FT_LIST_BY_INDEX Or FT_OPEN_BY_SERIAL_NUMBER)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If
        FT_Serial_Number = Microsoft.VisualBasic.Left(TempDevString, InStr(1, TempDevString, vbNullChar) - 1)
        ' Display serial number on form
        TextBox1.Text = FT_Serial_Number

        ' Get the model of the connected device
        TempDevString = Space(64)
        FT_Status = FT_GetDeviceString(DeviceIndex, TempDevString, FT_LIST_BY_INDEX Or FT_OPEN_BY_DESCRIPTION)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If
        FT_Description = Microsoft.VisualBasic.Left(TempDevString, InStr(1, TempDevString, vbNullChar) - 1)
        ' Display serial number on form
        TextBox2.Text = FT_Description

        ' Set baud rate of the connected device
        ' Set Baud Rate
        FT_Status = FT_SetBaudRate(FT_Handle, 1000000)
        If FT_Status <> FT_OK Then
            Debug.Print("Baud rate set")
            Exit Sub
        End If

        ' Set the number of stop bits of the recorded device
        ' Set parameters
        FT_Status = FT_SetDataCharacteristics(FT_Handle, FT_DATA_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE)
        If FT_Status <> FT_OK Then
            Debug.Print("Stop bits, parity and data bits set")
            Exit Sub
        End If

        ' Read bytes (not strings)        
        FT_Status = FT_Read_Bytes(FT_Handle, FT_In_Buffer(16), Read_Count, Read_Result)
        If FT_Status <> FT_OK Then
            Debug.Print(Read_Result)
            Exit Sub
        End If

        ' Display read bytes on form
        TextBox3.Text = Read_Result
        ' Close device
        FT_Status = FT_Close(FT_Handle)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If

    End Sub
End Class

My questions are as follows:

1) I have set the baud rate, stop bits and number of data bits using the FD2XX library. Once this has been done, is it possible to connect to the serial port directly and send or receive data using functions that are not within the FTDI library? I ask this because I am not sure if the FTD2XX drivers are separate from the VCP and FTDI do not provide documentation on serial communication using a USB VCP.

2) Are there any well documented function libraries/code suggestions that would enable me to read from it? If this requires some form of conversion, please can a well documented function library for this be suggested too?

3) Are there any well documented function libraries for writing unsigned integers to the device I am communicating with via the USB VCP?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
velvetshelter
  • 37
  • 1
  • 6
  • What is specifically "functions that are not within the FTDI library"? I think that the function to read/write is included. – kunif May 16 '19 at 16:27
  • @kunif I've been trying the FT_Write_Bytes and FT_Write_Strings functions since posting here but I have not been successful so far. The device requires a binary number number to be sent to it twice to work. At the moment I've modified by code as follows to send data as a string: Dim TempStringData As String = 121 and then I use this command twice to write the string to the device: ' Write string data to device FT_Status = FT_Write_String(FT_Handle, TempStringData, Len(TempStringData), BytesWritten) If FT_Status <> FT_OK Then Exit Sub End If – velvetshelter May 17 '19 at 10:02
  • @kunif For writing bytes to the device instead of strings, I declare the variable at the top of script like this DimBytestoDevice as Byte = 121 and then use this command twice to send the command: ' Write string data to device FT_Status = FT_Write_String(FT_Handle, DimBytestoDevice, Len(DimBytestoDevice ), BytesWritten) If FT_Status <> FT_OK Then Exit Sub End If I'm unsure whether simly using this command twice will work or whether a pause needs to be introduced between the two commands. – velvetshelter May 17 '19 at 10:04

2 Answers2

1

I am not really familiar with VB but I use the FT devices via C and python frequently. So here is what I know:

General comment to avoid missconcepts: VCP stands for Virtual COM port. So this actually enables the system to address the FT devices without the need to use a specific library like the D2XX. Most languages provide some "native" access to com ports. So there is no need to deal with the D2XX at all for regular com port operation. It is mainly meant for alternative operation modes and access to the MPSSE to the best of my knowledge.

1) If you open a port via the D2XX it will be unavailable for other access. If you release it and open it via another way (e.g. MSComm or IO.Ports.SerialPort in case auf .net) the settings will be overwritten (or at least should be automatically).

2) I am afraid that only the example projects by FT are your best bet. But maybe someone else can point out a better approach.

3) typically the native access (of C and python) allow you write and read plain byte strings. So the only thing you have to do is "transform" it in the correct type. ctype / CByte / CInt seems to be your cue.

Christian B.
  • 816
  • 6
  • 11
  • Thanks for answering. A caveat to this is that I have to use the FT_SetBaud function to set the baud rate of the virtual COM port to 1000000 because this rate is not supported by the MSComm. – velvetshelter May 16 '19 at 14:36
  • And you cannot use VB.net as well, right? You could try to stay with pure FT and use FT_Read in conjunction with FT_GetStatus (see [FT_Read](https://www.ftdichip.com/Support/Knowledgebase/index.html?ft_read.htm) for details). – Christian B. May 16 '19 at 19:20
1

By the way, where did the FT_Write_String and FT_Write_Bytes functions presented in the question come from?

In FTDI Code Examples, it is FT_Write, FT_WriteByte, FT_W32_WriteFile.

Visual Basic Examples

D2XX Module

many of the Visual Basic examples posted on this page use a module to interface to the D2XX DLL. To download the unit (D2XX_Module.bas) for Visual Basic 6, click here.
Please note that the code examples below may already contain a module handling the D2XX DLL interface. There may be differences between the current module file and the ones distributed with the examples.

D2XX_Module.bas

Public Declare Function FT_Write Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByVal lpszBuffer As String, ByVal lngBufferSize As Long, ByRef lngBytesWritten As Long) As Long
Public Declare Function FT_WriteByte Lib "FTD2XX.DLL" Alias "FT_Write" (ByVal lngHandle As Long, ByRef lpszBuffer As Any, ByVal lngBufferSize As Long, ByRef lngBytesWritten As Long) As Long

Public Declare Function FT_W32_WriteFile Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByVal lpszBuffer As String, ByVal lngBufferSize As Long, ByRef lngBytesWritten As Long, ByRef lpftOverlapped As lpOverlapped) As Long

Note: However, the ByVal lpszBuffer As String parameter of FT_W32_WriteFile seems to be a mistake of ByRef lpszBuffer As Any.

Example 6

Our thanks go to Bob Freeth for providing this VB6 example of using the FT2232C MPSSE for SPI communication with a MAX187 ADC.
Source code and executable are available for free download. This code is provided "as-is" for illustration purposes only and as such neither FTDI or Bob Freeth provide technical support for this VB6 code.


Visual Basic's String variables are Unicode, so they are not suitable for handling binary data.

Instead of substituting String variables, it is better to store data in byte array variables explicitly and write using FT_WriteByte function.

Based on the above, it will be as follows.

Dim SendData(nnn) As Byte ' nnn is value of send data size - 1  
SendData(0) = 121
SendData(1) = xxx
SendData(2) = yyy
.
.
.

FT_Status = FT_WriteByte(FT_Handle, SendData(0), Len(SendData), BytesWritten)
kunif
  • 4,060
  • 2
  • 10
  • 30
  • Thank you! When I put in Dim SendData(nnn) as Byte it says nnn is not declared, is it ok to put 3 in instead to specify a data size of 3? What is the purpose of the xxx and yyy? Also, when I specify SendData like you do there it says 'Value of type '1-dimensional array of byte cannot be converted to byte'. This can be solved by just putting SendData(0) when SendData(0) = 121 - is this right? They are from the FT_NET examples but they look like they work. – velvetshelter May 17 '19 at 13:36
  • @velvetshelter, nnn, xxx, yyy, are temporary string representing numeric value. Please replace with the length and value you actually use. And setting of the value may use CByte(121), CByte(xxx). – kunif May 17 '19 at 14:01
  • Thank you for all of your help. I am now successfully communicating with my external device. – velvetshelter May 21 '19 at 13:53