So I'm working in Unity3D, programming in C#, and I heard that one can read data from a Bluetooth adaptor via SerialPort. I have several Bluetooth USB adaptors that I've tried to connect on my PC using this method. However, when I try to open the SerialPort, I get an error message that says port does not exist. I only included the code relevant to the question, but portI is a string ("COM11" or "COM12") and PortIn is of type SerialPort.
void OnGUI() {
GUI.Label(new Rect(btnX, btnY, btnW, btnH), "PortIn = " + portI);
if(!connected) {
for (int i = 0; i<ports.Length; i++) {
if(GUI.Button(new Rect(btnX, btnY + btnH + (btnH * i), btnW, btnH), ports[i])) {
portI = ports[i];
}
}
}
if(GUI.Button(new Rect(btnX + (btnW * 2 + 20), btnY, btnW, btnH), "Connect")) {
portIn = new SerialPort(portI, 9600);
portIn.ReadTimeout = 1000;
if (!portIn.IsOpen) {
portIn.Open();
}
connected = true;
}
}
}
Here is some code I'm working on and it gets data from the bluetooth connection to a standalone pc build (or in the editor) as long as the COM port (in my case COM9) is the same as the bluetooth device when you pair it.
After you pair it go to Bluetooth Settings > COM Ports and see what port is there with the name of your device. It might say COM8 or COM9 or whatever. If the device is paired and the COM Port is the same in the code as it is in your Bluetooth Settings, AND the timeout number and baud rate are the same as in the application you are sending the data from... then you will get something from this code when you run it. This is just meant to help make a connection to the serial over bluetooth connection.
Hope it helps someone. I've gotten a lot of great advice from reading these forums ;)
using System.Collections;
using System.IO.Ports;
public class checker : MonoBehaviour {
public static SerialPort sp = new SerialPort("COM9", 9600, Parity.None, 8, StopBits.One);
public string message, message1;
public string message2;
void Start() {
OpenConnection();
}
void Update() {
message2 = sp.ReadLine();
}
void OnGUI() {
GUI.Label(new Rect(10, 180, 100, 220), "Sensor1: " + message2);
}
public void OpenConnection() {
if (sp != null)
{
if (sp.IsOpen)
{
sp.Close();
message = "Closing port, because it was already open!";
}
else
{
sp.Open();
sp.ReadTimeout = 1000;
message = "Port Opened!";
}
}
else
{
if (sp.IsOpen)
{
print("Port is already open");
}
else
{
print("Port == null");
}
}
}
void OnApplicationQuit() {
sp.Close();
}
}
It should be possible. The bluetooth rfcomm/spp services emulate a serial port. A COM port if it's on Windows. Baudrate doesn't matter in this emulation, it will always go as fast as possible.
You need to have the devices paired and connected though.
To what device are you connecting? Try to make a connection first with Putty or some terminal application.
Related
I'm following this tutorial. The goal is to receive periodic data from the arduino via serial port. I've been struggling with this for a while now. The com port connection is fine as i'm unable to connect with another terminal program to the arduino when my c# app is running ( port is already connected). At this point the SerialListen thread should start but this doesn't happen.
namespace TestReceiveArduino
{
public partial class Form1 : Form
{
//object serialport to listen usb
System.IO.Ports.SerialPort Port;
//variable to check if arduino is connect
bool IsClosed = false;
public Form1()
{
InitializeComponent();
//configuration of arduino, you check if com3 is the port correct,
//in arduino ide you can make it
Port = new System.IO.Ports.SerialPort();
Port.PortName = "COM11";
Port.BaudRate = 9600;
Port.ReadTimeout = 500;
try
{
Port.Open();
Console.WriteLine("open port ");
}
catch { }
}
private void Form1_Load(object sender, EventArgs e)
{
//A Thread to listen forever the serial port
Console.WriteLine("start thread ");
Thread Hilo = new Thread(ListenSerial);
Hilo.Start();
}
private void ListenSerial()
{
Console.WriteLine("start listener");
while (!IsClosed)
{
Console.WriteLine("in while");
try
{
//read to data from arduino
string AString = Port.ReadLine();
//write the data in something textbox
txtSomething.Invoke(new MethodInvoker(
delegate
{
txtSomething.Text = AString;
}
));
}
catch { }
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//when the form will be closed this line close the serial port
IsClosed = true;
if (Port.IsOpen)
Port.Close();
}
}
}
My arduino is sending data, i've checked this with terminal software. I'm also using the correct COM port
I have some experience with c# but i'm new to threads. What could be the reason for this?
OK:
See if these changes help:
namespace TestReceiveArduino
{
public partial class Form1 : Form
{
//object serialport to listen usb
System.IO.Ports.SerialPort Port;
//variable to check if arduino is connect
bool IsClosed = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
// Connect to Arduino
Port = new System.IO.Ports.SerialPort();
Port.PortName = "COM11";
Port.BaudRate = 9600;
Port.ReadTimeout = 500;
Port.Open();
Console.WriteLine("Port successfully opened: Name: {0}, Baud: {1}, ReadTimeout: {2}", Port.PortName, Port.BaudRate, Port.ReadTimeout);
//A Thread to listen forever the serial port
Console.WriteLine("start thread ");
Thread Hilo = new Thread(ListenSerial);
Hilo.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
...
I moved "Open Serial Connection" and "Start Listener Thread" to the same place (Form1_Load), and wrapped both in the same try/catch block. You might even want to move the "try/catch" to a higher level (e.g. so you can display any exceptions in your Windows GUI).
I assume you're using Microsoft VisualStudio (e.g. MSVS Express 2019) as your GUI, correct? Definitely familiarize yourself with your IDE's debugger; definitely get in the habit of stepping through the code as you're developing it.
Your next steps:
Verify the code gets to "Open Serial Connection", and verify that it opens correctly (e.g.prints "Port successfully opened...").
Verify the code then gets to "ListenSerial()", and prints "start listener" and "in while" at least once.
'Hope that helps...
I have a thermometer that has an RS232 connection, so I bought U-Port adapter to USB, per the manual you send it the string "Tcrlf" and it starts outputting data. Tried on PuTTy and it works like a charm.
I'm trying to automate some software with the data stream I am getting, however I am having problems communicating it, I have tried a few snippets from various tutorials around the webs but when I send it the same string via my app it just echoes it back and doesnt stream the data.
This is my Connect Button (after selecting COM port)
private void probeConnectBtn_Click(object sender, EventArgs e)
{
//Connect to the NIST-Reference Probe, using Omega HH42 settings:
if (refProbeCOMPort.SelectedIndex == -1)
{
MessageBox.Show("No COM Port selected for NIST-Reference Probe");
return;
}
if (!connectedreferenceProbePort.IsOpen)
{
connectedreferenceProbePort.DataBits = HH42DataBits;
connectedreferenceProbePort.BaudRate = HH42BaudRate;
connectedreferenceProbePort.PortName = HH42PortName;
connectedreferenceProbePort.Parity = Parity.None;
connectedreferenceProbePort.ReadTimeout = 600;
connectedreferenceProbePort.WriteTimeout = 800;
connectedreferenceProbePort.StopBits = StopBits.One;
connectedreferenceProbePort.DataReceived += new SerialDataReceivedEventHandler(probeDataReceived);
}
try
{
Console.WriteLine("Attempting to open port");
if (!connectedreferenceProbePort.IsOpen)
{
connectedreferenceProbePort.Open();
if (connectedreferenceProbePort.IsOpen)
{
Console.WriteLine("Port Opened, sending RTS");
connectedreferenceProbePort.RtsEnable = true;
connectedreferenceProbePort.WriteLine("Tcrl");
}
}
else
{
Console.WriteLine("Port is already open");
}
}
catch (Exception ex)
{
MessageBox.Show("Error opening/writing to Serial Port:: " + ex.Message, "Fatal Error!");
}
}
That's the connect and "attempting" to start the stream, then I have the datareceived part:
(Per the HH42 manual, after receiving the RTS signal, it sends a ">" character meaning that it's ready to listen).
private void probeDataReceived(object sender, EventArgs e)
{
string dataReceived = "";
Console.WriteLine("Data Incoming");
connectedreferenceProbePort.DiscardOutBuffer();
try
{
dataReceived = connectedreferenceProbePort.ReadExisting();
Console.WriteLine("Recevied :" + dataReceived);
} catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
if (dataReceived.Contains(">"))
{
Console.WriteLine("> Detected, attempting to write Tcrl");
connectedreferenceProbePort.Write("Tcrl");
}
}
This is my output from the console and a screenshot of PuttY:
Attempting to open port
Port Opened, sending RTS
Data Incoming
Recevied :
> Tcrl
> Detected, attempting to write Tcrl
Data Incoming
Recevied :Tc
Data Incoming
Recevied :rl
When you type "Tcrl" and press return in PuTTY, what PuTTY is actually sending are the bytes "T", "c", "r", "l", followed by a carriage return (CR) and a linefeed (NL).
I believe the manual is telling you to send "T", CR, LF, which in C# terms would be the string "T\r\n".
I am just a beginner in c#. I am now trying to interface arduino with a GUI application. And i need a small function to automatically detect the port which I have connected Arduino. I tried using nested "try and catch" blocks but it failed. can anyone suggest a good way to automatic select the port in which arduino is connected and open that port such that we can move directly to coding other switches that do different functions in that arduino.
Recently i had the same situation and i wrote this method to check for our device, all you need to set your device to send specific Pattern on Specific input. In this example if you send 0x33 then your device have to send 0x8A to identify itself.
public enum SerialSignal
{
SendSync = 0x33,
ReceiveSync = 0x8A,
}
private static SerialPort _arduinoSerialPort ;
/// <summary>
/// Polls all serial port and check for our device connected or not
/// </summary>
/// <returns>True: if our device is connected</returns>
public static bool Initialize()
{
var serialPortNames = SerialPort.GetPortNames();
foreach (var serialPortName in serialPortNames)
{
try
{
_arduinoSerialPort = new SerialPort(serialPortName) { BaudRate = 9600 };
_arduinoSerialPort.Open();
_arduinoSerialPort.DiscardInBuffer();
_arduinoSerialPort.Write(new byte[] { (int)SerialSignal.SendSync }, 0, 1);
var readBuffer = new byte[1];
Thread.Sleep(500);
_arduinoSerialPort.ReadTimeout = 5000;
_arduinoSerialPort.WriteTimeout = 5000;
_arduinoSerialPort.Read(readBuffer, 0, 1);
// Check if it is our device or Not;
if (readBuffer[0] == (byte)SerialSignal.ReceiveSync){
return true;
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception at Serial Port:" + serialPortName + Environment.NewLine +
"Additional Message: " + ex.Message);
}
// if the send Sync repply not received just release resourceses
if (_arduinoSerialPort != null) _arduinoSerialPort.Dispose();
}
return false;
}
public partial class Form1 : Form
{
SerialPort serial = new SerialPort();
static SerialPort cport;
public Form1()
{
InitializeComponent();
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i;
try
{
string[] ports = SerialPort.GetPortNames();
foreach(string newport in ports)
{
cport = new SerialPort(newport, 9600);
cport.Open();
cport.WriteLine("A");
int intReturnASCII = serial.ReadByte();
char returnMessage = Convert.ToChar(intReturnASCII);
if (returnMessage == 'B')
{
button2.Enabled = true;
break;
}
else
{
cport.Close();
}
}
}
catch (Exception )
{
Console.WriteLine("No COM ports found");
}
}
I undertand that I'm a bit late, But I have created a simple and free C# NuGet library that allows for interaction between the host PC and an Arduino board!
Examples in the ReadMe.txt file.
ArduinoFace - NuGet
I've been lurking here for a while, and have learned a ton just poking through questions. I'm pretty stumped on something, though. I'm using C#, and I'm trying to use IO.Ports to communicate with a USB device.
I've got code working that assumes the correct serial port, but sometimes my device winds up on a different port when plugged in, and I'd like to be able to run my code without having to change one variable and recompile. So, I want the code to poll the user for a port number, try to open the port, catch IOException when the port name's wrong, and re-poll until a valid port is given.
This is what I have so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
namespace USBDev1
{
class Program
{
static void Main(string[] args)
{
String portname = "COM";
SerialPort port = new SerialPort();
port.BaudRate = 9600;
bool loopthing = true;
while (loopthing == true)
{
Console.WriteLine("Which port?");
portname = "COM" + Console.ReadLine();
try
{
port.PortName = portname;
port.Open();
loopthing = false;
}
catch (System.IO.IOException e)
{
Console.WriteLine("Didn't work, yo");
throw (e);
}
}
// Body code
}
}
}
I am not sure what you are asking, but I think you should list the available ports before choosing one. The following code may work; it compiles, but it is not tested.
This is also not a good way to do it. A better way would be to list the ports before you plug in your device, then list the ports again to see the new port that showed up after you plugged in the device.
SerialPort port;
bool isCorrectPortFound = false;
// Try different ports until a device reacts when a character is written to it
while (!isCorrectPortFound)
{
// Get all open ports
string[] ports = SerialPort.GetPortNames();
// Menu choice for a port to select
char portSelect = '0';
// Write the port names to the screen
foreach (string s in ports)
{
portSelect++;
Console.Write(portSelect);
Console.Write(". ");
Console.WriteLine(s);
}
Console.WriteLine();
Console.Write("Select from port 1 to " + portSelect.ToString() + " > ");
int selectedPort = (Console.Read()) - '0'; // Character value of 1 to ...
try
{
// Assume selectedPort is a valid integer, set baud, etc. as per your choice.
port = new SerialPort(ports[selectedPort] /* COMportBaudRate,
COMportParity,
COMportDataBits,
COMportStopBits */);
// OK, port is open, write to the device. The device
// must respond visually, blinking a LED or something.
port.Write("A");
Console.WriteLine();
Console.Write("Did the device get your message? (y n) > ");
int a = (Console.Read()) - 'a';
if (a + 'a' == 'y')
isCorrectPortFound = true;
else
{
port.Close();
port = null;
}
}
catch (Exception ex)
{
// Display a message box, exit, etc.
}
}
// Do other stuff
I have a very small code that shows available COM ports.
My question is:
Is there an easy way to have the program to run in the tray and only popup when a new COM port is available and is it possible to add the name for the COM port that you can see in device manager ec "USB serial port"?
I often add/remove a USB->RS232 comverter and find it a pain in the ass because I must go into the device manger to see what COM port it is assigned to. It's not the same each time
Maybe there already is a small app that can do this but I havent found it on Google yet
using System;
using System.Windows.Forms;
using System.IO.Ports;
namespace Available_COMports
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//show list of valid com ports
foreach (string s in SerialPort.GetPortNames())
{
listBox1.Items.Add(s);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
public static void Main()
{
// Get a list of serial port names.
string[] ports = SerialPort.GetPortNames();
Console.WriteLine("The following serial ports were found:");
// Display each port name to the console.
foreach(string port in ports)
{
Console.WriteLine(port);
}
Console.ReadLine();
}
Take a look at this question. It uses WMI to find available COM ports. You could keep track of what COM ports exist, and only notify about new ones.
To find out when devices are hot-plugged, you want to handle WM_DEVICECHANGE. Call RegisterDeviceNotification to enable delivery of these notifications.
The code to get the COM number of certain device.
List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject queryObj in searcher.Get())
{
devices.Add(new USBDeviceInfo(
(string)queryObj["DeviceID"],
(string)queryObj["PNPDeviceID"],
(string)queryObj["Name"]
));
}
foreach (USBDeviceInfo usbDevice in devices)
{
if (usbDevice.Description != null)
{
if (usbDevice.Description.Contains("NAME OF Device You are Looking for")) //use your own device's name
{
int i = usbDevice.Description.IndexOf("COM");
char[] arr = usbDevice.Description.ToCharArray();
str = "COM" + arr[i + 3];
if (arr[i + 4] != ')')
{
str += arr[i + 4];
}
break;
}
}
}
mySerialPort = new SerialPort(str);