Serial communication with Velleman relais card - vb.net

I am trying to integrate a Velleman relay card VM8090 into my vb.net project. Unfortunately Velleman only provides a 32bit DLL, but our program is compiled x64. Therefore I try the communication directly over the serial interface (USB).
This is the protocol description from Velleman.
Communication with the demo app provided by Velleman works perfectly. After setting a relaystate I get a response from the relay card. This is displayed in the demo app.
The crazy thing is: after opening the serial interface in vb.net I don’t get any traffic infos in the demo app (and vb.net also) anymore. But I need this relais-status-infos (51h). But even though no more data is sent from the card, I can still turn relays on and off.
This code already causes the card to stop sending info.
myComPort = New SerialPort("COM3") With {
.BaudRate = 19200,
.DataBits = 8,
.Parity = Parity.None,
.StopBits = 1,
.Handshake = Handshake.None,
.ReadBufferSize = 1024,
.WriteBufferSize = 1024}
myComPort.Open()
myComPort.Close()

Make sure that only 1 program uses the SerialPort, usually only 1 program can read and send data through a SerialPort.
Also check if the device is connected to the correct usb port (usb port 3 in this case).
Check if all SerialPort settings are set correctly
Finally, in your code the comPort is opened and immediately closed again
myComPort.Open() myComPort.Close()
Only close the comPort when you want to close the program or the communication between your computer and the hardware.
I hope this helped.

Related

SerialDevice IsRequestToSendEnabled Raspberry Pi

I am programming with vb and have a UWP project using a Raspberry Pi.
When I use a USB to RS485 converter I can use the IsRequestToSendEnabled from SerialDevice to sync communication between the Raspberry and the PLC, but when I try to use the UART, with a TTL to RS485 converter, the IsRequestToSendEnabled is not available.
The following error shows up:
The request is not supported. (Exception from HRESULT: 0x80070032)
And
System.AccessViolationException
HResult=0x80004003
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The UART does not support it? I am no expert in UART, so how do I sync communication frames in Modbus then? The TTL to RS485 is Half-Duplex, I assume I have to sync communication somehow. It does work with a USB to RS485 converter, but I do not want to use it.
Here is a code sample:
Private Async Function ListAvailablePorts() As Task(Of Boolean)
Try
Dim aqs As String = SerialDevice.GetDeviceSelector("UART0") '"UART0") '"COM1")
Dim _portlist As DeviceInformationCollection = Await DeviceInformation.FindAllAsync(aqs, Nothing)
client = Await SerialDevice.FromIdAsync(_portlist(0).Id)
client.ReadTimeout = TimeSpan.FromMilliseconds(1000)
client.WriteTimeout = TimeSpan.FromMilliseconds(1000)
client.BaudRate = 9600
client.Parity = SerialParity.None
client.DataBits = 8
client.StopBits = SerialStopBitCount.One
client.Handshake = SerialHandshake.None ' SerialHandshake.None ' SerialHandshake.XOnXOff ' SerialHandshake.RequestToSend
client.IsRequestToSendEnabled = False ' error here when using UART
client.IsDataTerminalReadyEnabled = False
Return True
Catch ex As Exception
Debug.WriteLine("Error listing ports: " & ex.Message)
Return False
End Try
End Function
The error you are receiving can happen in various use cases. But I'm guessing the device capapability isn't set for serial access.
Make sure to enable the serial communication device capability in the package.appxmanifest.
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>
</Capabilities>
UWP on Raspberry Pi will not produce a proper SerialDevice.GetDeviceSelector when using
SerialDevice.GetDeviceSelector("COM0")
USB-Serial devices don't show as COM ports on Window IoT Core like they do on Windows 10 Desktop.
Also, if you are attempting to use a serial device OTHER than the onboard UART, or an FTDI serial device, it will not work unless you get drivers for the Pi installed on the Pi. Which is unlikely, as I have yet to find a manufacturer other than FTDI provide drivers for Windows IoT Core. (ala CH340)
The Windows.Devices.SerialCommunication namespace is flaky at best. I am willing to accept it that my troubles are of my own design but with the lack of support it's like pulling teeth to get a solution stable. Every iteration of enhancement provides their own set of difficulties.
Here's what I've learned over the past week on the subject of Serial Communication on the Raspberry Pi.
The serial device that you can communicate with must be an FTDI device.
You need to work around GetDeviceSelector and FindAllAsync short comings. (no "COM1") selector.
DataReader.LoadAsync will await until the ENTIRE bufferLength you provide has been filled.
Therefore, processing a buffer length of 1, provides the best way to get data of any length.
DataReader.LoadAsync will await forever the first time after you write something to the serial device. Provide a cancellation token and try again. (Note this is probably my own shortcoming/lack of understanding)
When you are done writing to the device - detach the writer's stream before attempting to read and vice versa.
And a big one - you must keep the serialDevice open for as long as you need it. DO NOT attempt to Dispose of the SerialDevice until your program closes - it will hang.
Here's how I initialize an FTDI USB-Serial device.
var aqs = SerialDevice.GetDeviceSelector();
var devices = await DeviceInformation.FindAllAsync(aqs);
var deviceInfo = devices?.Where(i => i.Name == "FT232R USB UART").FirstOrDefault();
What I did was inspected ALL devices and chose a unique property to select my device. Supposedly, using SerialDevice.GetDeviceSelectorFromUsbVidPid should work, but it did not for me.

stm32f3 'USER USB' not detected

I'm working on stm32f3 discovery board. For my current project I planned on coding a simple UART program on the board, I happened to read somewhere on the internet that to use the board for UART communication with PC the 'USER USB' has to be used.
My questions are the following
Firstly when i connect my board to PC using the 'USER USB'. The PC refuses to recognize the board.(F.Y.I- OS used is windows 7 64bit). This problem persists even after I update the driver! How to resolve this?
Is the "Connecting USER USB" part correct? because I can't see any RS232 chip on board
Should I use an add on board?
P.S I've installed all the necessary drivers from ST website and works flawlessly while using 'ST-Link interface' part of the board
I started working with the STM32F3 disco a few weeks ago. The user USB thing is a bit tricky.
To get it clear: The board has 2 USB ports.
One mostly for programming and debugging. It connected to a second ST chip which works as programming adapter.
The seconds (called USER USB) is connected to the STM32F303 chips you program
So what you can do is to configure your STM32 to implement a CDC over USB. With the windows driver installed (automatic or from ST, depends on OS version) you should get a virtual com port in your device manager. If you don't have the driver, you also get a device labeled as virtual com port but with a yellow exclamation mark.
So if I get you question right, this is what you're trying to do? Then yes, "Connecting USER USB" is correct. No, you don't need an extension board.
How to resolve that? It depends:
Do you already see the device in your device manager as communication device or serial interface or something? Then only the CDC driver from ST is missing.
Or do you get an "Unknown Device" in your device manager? That is what I experienced.
In STM32CubeMX you need to enable the USB device (Peripehrals->USB)
In STM32CubeMX you need to select the USB stack (MiddleWares->USB_DEVICE->Communication Device Class)
Generate the code. If you are using HSI as clock source CubeMX will generate a error message you can ignore for now. For a real product you should use an external clock.
Note that there is a bug in CubeMX version 4.20. The code generator generates code which may not work if you select HSE as clock input source. Even if you go back to HSI, the error remains.
Compile an run the code. You maybe need to reset the board removing BOTH USB plugs
Windows should detect the board now.
Extra problem: The board is ... well. Tricky. If you only plug in the USER USB to your PC, it should work but Windows may also inform you that you have an UNKNOWN DEVICE because enumeration has failed.
Remove the plug again. Now, first plug in the other, ST-LINK USB to power on the board. Wait 1-2 seconds. Now plug in the USER USB. There seems to be a startup problem. Only using the USER USB for power supply and CDC seems to run in a race condition between boot and USB and USB enumeration fails. First powering the board and then plugging in removes this race condition (at least at my board)
Now Windows should enumerate the device and offer you a virtual com port. Actually you should get two of them: One "ST... STLink Virtual COM Port" and one "ST... Virtual COM Port". The seconds one is the one you are looking for.
I hope that was the answer on the question you had.
Thanks for the post, had the same issue, here is what I added
Approach: Turn-off USB lines programmatically by changing input to output, forcing it to zero and reenable them after around 1 second
Also used power-off and on from ST USB Libs
// Force Re-Enumeration by the USB Host
//
int aux_retrigger_usb()
{
GPIO_InitTypeDef GPIO_InitStructure;
// ST USB Function
PowerOff();
// Program Pin 12 USB_DP from Input to Output
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Set USB_DP to 0
GPIOA->BRR |= GPIO_Pin_12 ;
// Wait for for minimum 32* 50msec , 1,6 secs
while(tim3_cnt%32!=0) ; while(tim3_cnt%32!=31) ;
// ST USB Functions
PowerOn();
USB_Init();
Virtual_Com_Port_Reset() ;
// Program Pin 12 USB_DP from Output to input
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
return 1 ;
}
So basically to avoid the power on race condition, the ports may be programmed
first to outputs and then released after 1 second.
I'm also struggling with the STM32F302. The USB is not recognized by the HUB Down stream port, and therefore does not appear in a device manager on PC(HUB's upstream port is connected to PC).
So, I made a deep search after I checked all the HW and SW.
It appears that 1.5Kohm resistor should be added on a DP, as F302 does not have the embedded one.
My design does not have neither, so hopefully, it will solve the issue tomorrow, so I have a hope for tonight)
You can read AN4879 by ST - the place I found these directions.

USB port to detect "close" or "open" switch

I need to make a program that would play a sound as I press a push button switch. My idea is to use the USB port, and that if I short 2 wires from it (like for example the data+ and data-), the program would play a sound repeatedly while the 2 wires are shorted. Is my idea possible and simple to do? Can you please help me do it using VB? Thanks a lot for any help.
No, that is not practical. USB ports do not have that feature is far as I know. There are plenty of small, cheap USB microcontroller boards that are up to the task though.
For example, you could get an A-Star 32U4 Micro, program it using the Arduino IDE, and make it send a certain message on the its virtual COM port (which is accessed from the Serial object) when a button is pressed and another message when it is released. Then in Visual Basc, you would use the SerialPort class to connect to the A-Star's COM port and listen for that message.
USB ports are mainly used for transmitter and receiver communications for data transfers. They are not used for open or closed switch detection. In order to use a USB port for switch detection, you can used a serial to USB conversion breakout board with a specialized IC chip designed to detect an open or closed switch and communicate this via the USB protocols to send out a communications data transmission that a switch has just been open or closed. Then you would program an application in any language to listen on that USB port for this specific data transmission for a closed or open thrown switch. You can potentially detect about 4 switches opened or closed simultaneously if you want. And this serial to USB breakout board can easily be purchased online at:
https://www.sparkfun.com/products/199

PySerial: Create serial object without opening port

I'm running some code on Arduino, I have website with a slider which uses a cgi script to pass values to Python. Then the python script uses pySerial to send the values to Arduino which controls a motor.
The plan was to be able to control the motor speed using the slider on the website.
However I seem to be coming up against a problem of the Arduino resetting whenever I change a value on the website, causing the motor to stop. Is there any way around this? My python code is below.
#!/usr/bin/env python
import cgi
form=cgi.FieldStorage()
import json
ser = serial.Serial('dev/ttyACM0', 9600)
#I think there should be a sleep here for 1.5 seconds
ser.write("%s\n" % (form["value"]))
ser.close()
print "Content-type: application/json"
print
print(json.JSONEncoder().encode({"status":"ok"}))
So, say I have the motor running at 50% speed, then change a value on the website, it runs this script which executes the serial.Serial('dev/ttyACM0', 9600) command. That opens the port which resets the arduino, stopping the motor before passing the new command.
Is there any way to pass ser.write("%s\n" % (form["value"])) to the arduino without freshly opening the port? Such as leaving the port open between python sessions?
If not, is there any other way around this problem?
I believe the reset is due to a hardware design of the specific Arduino device you are using. I suggest using an Arduino Micro or Leonardo board instead. They use a virtual serial port and should not restart your sketch each time a serial port is opened. This is from the Arduino site:
No reset when you open the serial port.
Unlike the Arduino Uno, the Leonardo and Micro won't restart your
sketch when you open a serial port on the computer. That means you
won't see serial data that's already been sent to the computer by the
board, including, for example, most data sent in the setup() function.
Serial re-enumeration on reset.
Since the boards do not have a dedicated chip to handle serial
communication, it means that the serial port is virtual -- it's a
software routine, both on your operating system, and on the board
itself. Just as your computer creates an instance of the serial port
driver when you plug in any Arduino, the Leonardo/Micro creates a
serial instance whenever it runs its bootloader. The board is an
instance of USB's Connected Device Class (CDC) driver. This means that
every time you reset the board, the USB serial connection will be
broken and re-established. The board will disappear from the list of
serial ports, and the list will re-enumerate. Any program that has an
open serial connection to the Leonardo will lose its connection. This
is in contrast to the Arduino Uno, with which you can reset the main
processor (the ATmega328P) without closing the USB connection (which
is maintained by the secondary ATmega8U2 or ATmega16U2 processor).
This difference has implications for driver installation, uploading,
and communication...
I you might be able to use the setDTR(False), but I have tested this yet. A while back they fixed the bug that were initially associated with setDTR. What operating system are you use this on?
ser = serial.Serial('dev/ttyACM0', 9600)
ser.timeout = 1
ser.setDTR(False)
Let us know if this does not work.

Serial port communication

i'm creating a windows form to send/receive data to/from serial port.
At first : i send the data as string to the serial port .
Second: i tried to read the string again for test the successfull transmission , but i recieved empty string
this is my code :
Try
Dim SerialPort1
As New SerialPort("Com1",9600, Parity.None, 8, StopBits.One)
SerialPort1.Open()
SerialPort1.DtrEnabled=True
SerialPort1.WriteLine("This is my test message ." )
' ================= Read from serial port
Label1.Text=SerialPort1.ReadExisting() ' this returns empty string
Catch ex As Exception
MessageBox.Show(
"Error writing to serial port:" & ex.Message)
Finally
SerialPort1.Close()
End Try
i need to ask another question:
is it required to connect device to serial port to send/recieve data successfully ????
please i need an urgent help
thanks
As Heinzi already mentioned, if you want to see data you need to have some coming in. There is no automatic echo of data you send out.
To answer your other question: Yes, you need to have another device connected to your serial port in order to send/receive data successfully. With no other device, what would be the point?
Fortunately for you, the "device" you connect can be as simple as a plug with some wires. Here is a set of instructions and diagrams for building a so-called loopback plug: http://www.airborn.com.au/serial/rs232.html
This will allow you to echo your output to your input using very simple hardware. If you're not into soldering up your own plug, you can use a so-called breakout box or board. Here's an example: http://www.breakoutboxes.com/D-Series-9-Position-Breakout-Board_p_31.html .
ReadExisting returns the data sent by the device you are communicating with, not the data sent by you.
You could try to use com0com for generating a virtual serial port pair, then you can rename one of these virtual ports to common name like "COM4". You should open other SW like hyperterminal for serial communication, then set to open the remaining port from the pair.
You may try to use com0com fist with two hyperterminals.
You will need a device through which your application will send and receive data.
For testing, you might consider creating a virtual serial port with software like this Virtual Serial Port Driver. It allows you to create serial ports that aren't actually connected to any physical device. You can then debug your program with another program or with something like HyperTerminal or PuTTY.
Assuming you have a loopback plug (simply connect pins 2 and 3 together) so that anything you send is immediately received.
However - you need to consider that the RS232 is slowly. ("S L O W L Y") and the transfer happens asynchronously so your program is hitting the readexisting long before the data has even been sent. So you're reading an empty buffer.
Just for the sake of your test you need to put some delay in there. so that you can wait a moment after sending before trying to receive.
In a real application though you'd use the receive event to read the serial port.