Baud rate limits in software and serial communication with an external device - matlab

I am using a USB port port operating as a virtual COM port to achieve serial communication with an external device using MATLAB or Visual Basic 6. I am facing baud rate limitations depending on the software I use to communicate with the device. MATLAB (2018a) has no problems because it can set high baud rates. Visual Basic 6 on the other hand faces limitations on the baud rates that can be set in the software. In terms of solutions, I have looked into this to set a higher baud rate in Visual Basic 6: https://www.mev.co.uk/pages/Support/VB-Baud.html
The drivers for the virtual COM port are made by FTDI and can be found here: http://www.ftdichip.com/Drivers/VCP.htm . After configuration in the Device Manger, the device I am communicating with appears under 'Ports (COM & LPT)' as 'USB Serial Port (COM4)' in the Device Manager.
The device requires a baud rate of 1000000 and 2 stop bits for successful communication (if you need any more information, please let me know). As far as I am aware, the baud rate set in the software to communicate via the serial port has to be 1000000 to match that of the external device I am using. I think my problem might require a bit an explanation of how serial communication works when a USB port is acting as a virtual COM port because I worry that it differs from communication using a 'real' serial port, if possible. The FTDI driver appears to be very flexible so I do not understand why Visual Basic cannot tap into this flexibility. Is it impossible to set a baud rate of 1000000 in Visual Basic 6? If it is impossible, are there any methods to overcome this limitation?
The VB6 code for baud rate setting is found below, where 'Port' is the address of COM port e.g. COM4, COM3:
MainForm.MSComm1.CommPort = Port
MainForm.MSComm1.Settings = "9600,N,8,1"
If anyone can help me understand how serial communication works in this setting and if I can overcome the constraints of Visual Basic 6, I would be very grateful.

It seems that you are using MSComm32.ocx, not VB6 directly.
The maximum speed you can set for this is 256,000 bps.
How to send to the serial port by using Mscomm32.ocx
The following baud rate values are valid: 110, 300, 600, 1200, 2400, 4800, 9600 (default), 14400, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 256000.
If you want more speed, please use Win32 API directly with the following library etc.
Serial port programming VB6 via Win32 API
Serial Port Communication
Serial port programming on Visual Basic with Windows API
grricks/vb6SerialAPI
Or, can it be used if the library provided by FTDI is defined by Declare Function like the above library?
D2XX Programmer's Guide
6.9 FT_W32_SetCommState
Example
FT_HANDLE ftHandle; // setup by FT_W32_CreateFile
FTDCB ftDCB;
if (FT_W32_GetCommState(ftHandle,&ftDCB)) {
// FT_W32_GetCommState ok, device state is in ftDCB
ftDCB.BaudRate = 921600; // Change the baud rate
if (FT_W32_SetCommState(ftHandle,&ftDCB))
; // FT_W32_SetCommState ok
else
; // FT_W32_SetCommState failed
}
else
; // FT_W32_GetCommState failed

Related

Can't receive from USB bulk endpoint despite Windows enumerates and libusb reads descriptor of STM32 custom device class

For a fast ADC sampling USB device, I am using the USB 2.0 High Speed capable STM32F733 with the embedded USB-HS PHY. In USBView, I can see that the device is enumerated, the libusb code opens the device and claims interface, but when I try to receive data with libusb_bulk_transfer, the operation times out (return code -12). Things I have tried: I have confirmed than when I request data with libusb_bulk_transfer, the device is interrupted. Note: I have DMA enabled in my class configuration C file and it is not clear to me how that is triggered. I have verified that the transfersize and packet count registers are being set correctly by the LL library function, and that when I request data from
Any tips on debugging such problems will be much appreciated - this board is my undergrad thesis due in under two months!
Desktop sequence:
libusb_get_device_list, libusb_get_device_descriptor, libusb_open, libusb_get_string_descriptor_ascii, libusb_free_device_list, libusb_bulk_transfer(devh, fat_EPIN_ADDR, inframe, fat_EPIN_SIZE, &gotBytes, 100). Where gotBytes is integer, and inframe is a large array.
Device firmware:
MX_USB_DEVICE_Init();
uint8_t txBuffer[10*fat_EPIN_SIZE];
while (1)
{
USBD_LL_Transmit(&hUsbDeviceHS, Custom_fat_EPIN_ADDR, txBuffer, Custom_fat_EPIN_SIZE);
HAL_Delay(1);
}
Custom_fat_EPIN_SIZE is 0x200 and the endpoint address is 0x81 (EP IN 1)
Installed driver for device is WinUSB (verified in Device Manger to be winusb.sys), and I am linking libusb-1.0 into my desktop program. You can find my source code at https://gitlab.com/tywonemi-school-stuff/silicon-radar-fun, the firmware is My SW/v1 and the desktop software is a Qt Creator project in My SW/Viewer, of note is usb.cpp. You can also compare with testing project/HIDTest, which is code that I tested with STM32F303 nucleo dev board where I was able to read an array through IN bulk endpoint with the Viewer application. However, F3 has the USB peripheral, while F7 has OTG_USB, and I am now attempting USB 2.0 compliant HS so there may be more protocol-based pitfalls. You can also find the output of the device descriptor etc from USBView in my SW/USBView_broken.txt
EDIT 1: I have found finally some concrete error in the STM32 behavior. The DMAADDR is set for EPIN 0x81, and never increments, despite the DMA being enabled. I have went through literally every occurrence of the word "DMA" in the USB_OTG periphery.
I thought it might be that my linker script makes my array be stored in DTCM or similar, and the OTG DMA can't access it, but the address of txBuffer is 0x2003EBEC which is in SRAM2. The AHB matrix in the reference manual clearly shows, that the USB OTG HS DMA is master for a bus that SRAM2 is a slave of. And DTCM is connected too. I will look for application notes for USB OTG HS DMA - it just seems to be refusing to copy data!
I have fixed my issue by disabling the DMA setting. I have re-read the relevant portions of the reference manual and still don't know how exactly the values propagate into the Tx FIFOs. It is possible that DMA-less operation will be a major bottleneck in my project, I might return to this later.

FTDI Get modem status values (DSR, DCD, CTS)

I'm working on a project where I'd like to be able to send a simple on/off signal back to the PC via one of the modem pins (DSR, DCD, CTS), separate from the standard serial communications.
I'm having trouble accessing these when connecting to the device with the standard VPC serial driver.
Sample Python using pySerial:
import serial
def main(argv):
watchPort(sys.argv[1])
def watchPort(portName):
ser = serial.Serial(portName)
while True:
print("DCD {0}, DSR {1}, CTS {2}".format(ser.cd, ser.dsr, ser.cts))
time.sleep(0.5)
if __name__ == "__main__":
main()
These values are always the same, no matter if the pins are connected HIGH or LOW. I've also tested with a couple terminal programs to verify (CoolTerm, SerialTerm).
I am, however, able to get these values via the D2XX drivers and related APIs, but I'd rather use the simpler serial device method, if possible. Is this not possible?
Why?
I'm setting up a multi-drop RS485 network and planning to use one of these lines as a common signal line that can be used to signal "ready", "error" and to prevent communication collisions.
It turns out that the problem was with the stock FTDI driver that comes with OS X. (see post) Updating to the latest VPC driver fixed it.

serial monitoring method to test communication via com ports without a serial communication device

I have a Verilog code simulated and synthesized on ISE design toolkit. I've got an FPGA spartan 6 device which is to be used for the implementation. But there is a problem with the device (probably a power issue) which makes the device unavailable in any of the COM ports when I connected it to my PC. So I want to check whether my Matlab code which I made for serial communication through the device does the desired job. So I need a method to test serial communication via any of the COM ports without connecting a serial com device to the PC. Is there any such method that I can Tx Rx serial data from Matlab to COM ports? Any software or any other method would be highly appreciated :)
I found a way to test Matlab serial communication using virtual serial ports.
Download "Freeware Virtual COM Ports Emulator" from: http://freevirtualserialports.com/
I installed it in Windows 10, and it's working (as trial).
Add a pair of two serial ports:
Execute the following Matlab code sample to verify it's working:
s3 = serial('COM3','BaudRate',115200);
s4 = serial('COM4','BaudRate',115200);
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
%fprintf(s3, '12345');
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
delete(s3);
clear s3
fclose(s4);
delete(s4);
clear s4
The output is:
RxBuf =
1
2
3
4
5
Bypassing the problem "it only stays for a single test session".
There is a problem when creating a pair of virtual ports using the software, it only stays for a single test session.
I guess it's a problem with the COM port emulation software.
The following solution, is not a good practice (and not a true solution).
Declare the serial object as global, keeping the object persistent.
Create the serial object only if it's not created.
Don't delete and don't clear the serial object.
See the following code sample:
global s3 s4
if isempty(s3)
s3 = serial('COM3','BaudRate',115200);
end
if isempty(s4)
s4 = serial('COM4','BaudRate',115200);
end
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
%delete(s3);
%clear s3
fclose(s4);
%delete(s4);
%clear s4
You can also look for a better virtual COM port software.
As Rotem suggested, if you need to communicate via serial line between 2 program of your PC you need a virtual COM port emulator.
It seems you are running on Windows OS so I would recommend a completely free emulator (not a trial one). For Windows I use com0com Null-modem emulator (from SourceForge).
In the example below I will show how to communicate with "another" device so Matlab will not handle both side of the communication. The other device will be simulated by a simple terminal. For windows I use RealTerm: Serial/TCP Terminal (also from SourceForge).
Setup:
Execute the setup of both program with all default options. by default com0com will create a virtual pair COM3/COM4 but if these port already exist on your system the program may assign other numbers. Check the numbers before you run the example. (it will also create a CNCA0/CNCB0 pair but you can ignore this one for now).
For RealTerm, once installed (don't forget to activate the server registration at the end of the setup, it should be ticked by default though), it will look like below. Keep all default options, just set the port number and the baud rate if they need to be changed.
Test MATLAB -> Terminal
You are ready to send Ascii characters or binary values from MATLAB to your device. The animation below shows you an example of both option:
you can click on the picture to see it full size. It is running in loop so you may want to wait until it restart from the beginning.
Test Terminal -> MATLAB
Below animation shows you how to test the communication in the other way:
Don't forget to tick [CR] [LF] on RealTerm when you send Ascii characters and want to use the '%s' format specifier on MATLAB, as it needs these characters to detect the end of the string.
Note:
If you have another terminal program that you are more used too, it
will work the same.
If the RealTerm option does not suit you, or if you want to handle
both sides of communication from Matlab, then you can use the code
provided by Rotem in his first answer. Just install com0com but
ignore all the RealTerm part.

Pyserial and QUERY Issues

I have a MKS pressure transducer with a 9 pin DB connector. The user interface is through RS-232 or RS-485 serial communications. I am currently developing code using pyserial and python to query the transducer via a plugable RS-232 to usb adaptor. I'm sure the adaptor works because I have used it for communicating with another instrument via pyserial.
The relevant pins for the transducer are:
3 - POWER +
4 - POWER -
6 - RELAY COMMON
7 - RS485 - / RS232 TXD
9 - RS485 + / RS232 RXD
My adaptor is connected to /dev/ttyUSB1.
The transducer has a factory default baud rate = 9600, the data format is 8 data bits, no parity and one stop bit. Based on the manual the query and command syntax are the same for RS485 and RS232.
The problem that I am having is querying the transducer.
The syntax required for a query is:
#<device address><query>?;FF
For example to Query current baud rate: #253BR?;FF
Where:
# <attention charector>
253 <default address>
BR? <query for baud rate>
;FF <terminator>
My python code is:
import serial
Piezo = serial.Serial(port ='/dev/ttyUSB1',
baudrate=9600,parity =serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,
timeout =1)
print Piezo.isOpen()
Piezo.write('#253BR?;FF')
print Piezo.readall()
Piezo.close()
With my response:
%run /home/vivekd/Desktop/Software/Pressure/Piezon.py
True
unfortunately I do not get a response back, I am assuming it has to do with the write sequence and the non-traditional terminator. I have tried other write combo's but I get no response. Any and all suggestion would be helpful.
Thanks.
-V
Solved, the issue was the rs232 sent and received pin wiring were backwards.

Bluetooth low energy (BLE 112 ) Difference between BGAPI and BGScript

What is the Difference between BGAPI and BGScript ?
And if we write any code for BG profile than how can we burn it in BLE 112?
The BGAPI interface defines the protocol used to talk to the module over USB or serial link.
BGScript is something which runs on the module processor itself, when the USB or serial link is not used.
I have the dongle, BLED112, which is the same thing as BLE112 with a USB connector on it, and the code is "burned" to it using standard USB DFU interface.
The downloading of the code to BLE112 can be done using several methods:
(1) Bring out the DD, DC debug interface pins from your module and use the CC-Debugger (digikey part 296-30207-ND, $55). This works every time. If you have the DKBLE112 kit, the CC-Debugger fits on the 10-pin .050 connector in lower right corner. You can "burn" any firmware and any stack this way. Works awesome.
(2) Hope that the current firmware on the CC2540 has serial bootloader, and load the new firmware (hopefully also containing serial bootloader) using UART. TI has the tools, but it sure seems quite convoluted to me, and I did not try it.