I have this Arduino code just for testing purpose:
int num=0;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(num);
num+=1;
delay(800);
}
Now it prints an integer and increments its value by one. When I open up Serial Monitor it prints as expected every 800ms.
My Arduino is connected on PORT-6
Now if I try to access the port, it says it is in use, I'm trying to access that from a .NET application. How can I do so?
c# code, collected from the internet, modified a little:
using System;
using System.IO.Ports;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static SerialPort _serialPort;
public static void Main()
{
_serialPort = new SerialPort();
_serialPort.PortName = "COM6";//Set your board COM
_serialPort.BaudRate = 9600;
_serialPort.Open();
while (true)
{
string a = _serialPort.ReadExisting();
Console.WriteLine(a);
}
}
}
}
How can I sniff data from that serial port ? [Educational Purpose]
You can't open a serial port twice.
If what you want is to get to see what is going through the bus (sniffing), you can use virtual ports and port forwarding, see here for a complete example.
Nothing will stop you from replacing any of the tools discussed in the link with your own code (.NET or other), in case they don't suit your needs or if you have enough determination to reinvent the wheel.
Related
I'm working on a C# program that is basically a char sequence's listener in a SerialPortwhich is connected to a FT2232H.
The sequence should start with an arbitrary char and has an arbitrary lenght.
The problem is not that I don't have the correct pattern I expected, the problem is that I don't have the chars I passed into the chip at all, and sometimes they're mixed with other bytes I'm sure to not have passed to the chip!
Even coding this char by char reader didn't help me to understand what happens inside.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms;
namespace FTDI_VCP
{
class SerialPortProgram
{
int _test_counter = 0;
private string _buffer;
private SerialPort port = new SerialPort("COM11",
9600, Parity.Even, 8, StopBits.Two);
[STAThread]
static void Main(string[] args)
{
new SerialPortProgram();
}
private SerialPortProgram()
{
Console.WriteLine("incoming chars:");
port.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
Application.Run();
}
private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
if(port.BytesToRead != 0)
{
do {
int byte2read = port.ReadChar();
if(byte2read == 0xFF) //this is my arbitrary char value
{
Console.WriteLine();
}
else
{
Console.Write((char)port.ReadChar());
}
} while (true);
}
}
}
This is the output:
Suppositions:
I think that using a VCP through a FTDI in UART-RS232 mode I am listening directly on the UART buffer however I fear that there are remote possibilities that I'm reading a something else instead of simple chars. Maybe RS232 packets? Maybe another pattern? I don't know. Can anyone help me to understand what happens inside a UART buffer when I'm using a COM port?
Things I've already checked that seems to be okay
Baud rate mismatching
Other devices interferring
FTDI in right mode, I used FT_Prog like this
Thanks for the attention payed. I'm waiting for a FTDI GURU to help me (:
I am developing a C# Windows Forms Application to communicate via a Bluetooth Connection with a Raspberry Pi Model 3. This connection is mimicked through a virtual serial port on the client machine. I am able to start a bluetooth connection within the C# program but I cannot receive any data from the program. When I use the program Putty, I can see that the data is transmitting on COM Port the way that I would like it to.
I also discovered a weird sort of glitch with the C# program. If i have the COM Port open on Putty and then start the C# program, an error will occur with the port.open() command since the port is reserved. So then if I close Putty and continue the C# application the data will stream perfectly to the program. Has anyone encountered this issue before? I've been at a bit of a loss for a few days now. The Code in my program is shown below:
using System;
using System.IO.Ports;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using InTheHand.Net;
using InTheHand.Net.Sockets;
using InTheHand.Net.Bluetooth;
using System.Threading;
namespace GUIfromPI
{
static class Program
{
//PC BT USB adapter
private static BluetoothEndPoint EP = new BluetoothEndPoint(BluetoothAddress.Parse("##:##:##:##:##:##"), BluetoothService.BluetoothBase); //addressing the usb adapter used on the PC (endpoint)
private static BluetoothClient BC = new BluetoothClient(EP);
//Pi BT Adapter
private static BluetoothDeviceInfo BTDevice = new BluetoothDeviceInfo(BluetoothAddress.Parse("##:##:##:##:##:##")); //addressing the BT adapter on the Rasperry Pi
// private static NetworkStream stream = null;
public static SerialPort mySerialPort = new SerialPort(); //Bluetooth module mimics serial protocol by streaming data through the COM5 port in the host80 computer
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("Executing Program...");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (BluetoothSecurity.PairRequest(BTDevice.DeviceAddress, "1234"))//MY_PAIRING_CODE))
{
Console.WriteLine("PairRequest: OK");
if (BTDevice.Authenticated)
{
Console.WriteLine("Authenticated: OK");
BC.SetPin("1234");//pairing code
//BC.BeginConnect(BTDevice.DeviceAddress, BluetoothService.SerialPort, new AsyncCallback(Connect), BTDevice);
}
else
{
Console.WriteLine("Authenticated:No");
}
}
else
{
Console.WriteLine("PairRequest: No");
}
//mySerialPort = new SerialPort("COM5");
SerialThreadFunction();
}
public static void SerialThreadFunction()
{
mySerialPort.PortName = "COM10";
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DtrEnable = true;
mySerialPort.RtsEnable = true;
mySerialPort.ReadTimeout = 100000;
mySerialPort.Open();
//mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
string mydata = "hello";
while (true)
{
Console.WriteLine(mySerialPort.ReadLine());
mydata = mySerialPort.ReadLine();
}
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received: ");
Console.Write(indata);
}
}
}
UPDATE: I just discovered that declaring my Bluetooth Endpoint, client, and device are interfering with reading off of my serial port. Since the bluetooth connection was already initialized previously, I was able to see the data on the port. Now for why it does this?
Okay, it seems you are not doing anything wrong. Inherently .NET cannot handle multiple ownership of the same port. When you declare your SerialPort instance and connect to say... COM11... You have given ownership of COM11 solely to your SerialPort instance. In order to have access to COM11 you will now need to provide a reference to that specific SerialPort object which has ownership of COM11.
In your case you are opening PuTTY and then running your program. Once PuTTY obtains access to the port, your program will not be able to do so. This is completely standard in the .NET framework. Now, there are other ways that you can get multiple accesses to a COM port, but I think that's outside the scope of this question. Here's a software that will allow you to run an application and sniff traffic over the port at the same time... Free Serial Port Monitor. You can get this for free, and there is a better version for purchase that does all kinds of magic.
Here is a little algorithm for ensuring your port is opened properly, you may want to take this... modify it a little bit... and use it as the Connect method on your BluetoothClient class.
SerialPort port = null;
string error = string.Empty;
bool success = false;
int tries = 5;
foreach(var name in System.IO.Ports.SerialPort.GetPortNames())
{
// try each port until you find an open one
port.Name = name;
// there is always a chance that the port is open
// if trying some operations back-to-back
// give it a few extra tries if necessary
for (int i = tries; i > 0; --i)
{
try
{
// avoid the exception by testing if open first
if (!port.IsOpen)
{
port.Open();
success = true;
return;
}
}
catch (UnauthorizedAccessException e)
{
// sometimes the exception happens anyway, especially
// if you have multiple threads/processes banging on the
// ports
error += e.Message;
}
}
}
In addition to all of this, you may want to watch that your Bluetooth classes are not claiming ownership of the port when you need to read it. That may be what's interfering with reading the port. You really should create one single class and call it say BluetoothClient or something, and have that single class be responsible for all the interactions with the SerialPort reference. This way you ensure that whether you want to send/receive on the port you will always have ownership.
I am trying to read simple sensor reading from a arduino. The arduino is connected to COM3 (used for sending data and programming the arduino). The C# Programm is very simple and tries to read what the arduino sends.
Problem: I can not open COM3 Port with C# or the arduino when the other side (C# or arduino respectively) already opened it. Just sending without opening doesnt produce any results aswell. How are you supposed to "connect" them? My understanding was that both devices open the port with the same baudrate and then you can send and read data. When I am trying to open, I will get a UnauthorizedAccess on the C# side or a "can't open serial" on the arduino side.
Arduino C-Code:
#include <DHT.h>
#define DHTPIN A4
#define DHTTYPE DHT11
#define THERPIN A0
DHT dht(DHTPIN,DHTTYPE);
String hum="Humidity:";
String temptext="Temp:";
String semi=";";
void setup() {
Serial.begin(9600);
dht.begin();
pinMode(A0,INPUT);
}
void loop() {
float humidity = dht.readHumidity();
delay(300);
float temp = dht.readTemperature();
delay(300);
if (isnan(humidity)||isnan(temp))
{
Serial.println("Fehler beim Lesen(NAN)");
delay (5000);
}else
{
Serial.print(temp + semi);
Serial.print(humidity);
Serial.flush();
delay(1000);
}
}
C# Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO.Ports;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
SerialPort serialPort1;
serialPort1 = new SerialPort();
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
REPEAT:
if (serialPort1.IsOpen)
{
string reading = serialPort1.ReadLine();
Console.WriteLine(reading);
serialPort1.Close();
}
else
{
Console.WriteLine("closed,opening");
serialPort1.Open();
goto REPEAT;
}
}
}
}
While searching the solution was always that another programm was already using the COM Port, but isn't that exactly what I need to communicate? Obviously, the arduino has to use the same COM-Port as my C# app, as far as I understand.
Thanks
Your code is opening and closing the serial port perpetually. This does not work, because when .NET code closes the connection Windows internally will close the port asynchronously. It can take a few seconds before the port is actually closed. This is why the program almost immediately blocks.
Open the connection only once at the start of your program.
Besides: avoid GOTO statements at any cost. Edgar Dijkstra wrote a paper against its use many years ago: Go To Statement Considered Harmful.
Not a whole lot to say here other than this doesn't work, and I have no idea why.
The serial output on the Arduino is nothing. The output on the C# code goes down to waiting for a response and then nothing.
The Bluetooth card LED on the Arduino goes green when I start the C# program so there is a connection being made. Just nothing else.
Arduino Code
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 8 // This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7 // This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)
SoftwareSerial blueToothSerial(RxD,TxD);
boolean light = false;
void setup(){
Serial.begin(9600); // Allow Serial communication via USB cable to computer (if required)
pinMode(RxD, INPUT); // Setup the Arduino to receive INPUT from the bluetooth shield on Digital Pin 6
pinMode(TxD, OUTPUT); // Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
pinMode(13,OUTPUT); // Use onboard LED if required.
}
void loop(){
delay(1000);
if(light){
light = false;
digitalWrite(13,LOW);
}
else{
light = true;
digitalWrite(13,HIGH);
}
//Serial.println(blueToothSerial.available());
blueToothSerial.write("Im alive");
if(blueToothSerial.read()>0){
Serial.write(blueToothSerial.read());
}
}
Core C# Code
static void Main(string[] args)
{
byte[] Command = Encoding.ASCII.GetBytes("It works");//{0x00,0x01,0x88};
SerialPort BlueToothConnection = new SerialPort();
BlueToothConnection.BaudRate = (9600);
BlueToothConnection.PortName = "COM4";
BlueToothConnection.Open();
if (BlueToothConnection.IsOpen)
{
BlueToothConnection.ErrorReceived += new SerialErrorReceivedEventHandler(BlueToothConnection_ErrorReceived);
// Declare a 2 bytes vector to store the message length header
Byte[] MessageLength = { 0x00, 0x00 };
//set the LSB to the length of the message
MessageLength[0] = (byte)Command.Length;
//send the 2 bytes header
BlueToothConnection.Write(MessageLength, 0, MessageLength.Length);
// send the message itself
System.Threading.Thread.Sleep(2000);
BlueToothConnection.Write(Command, 0, Command.Length);
Messages(5, ""); //This is the last thing that prints before it just waits for response.
int length = BlueToothConnection.ReadByte();
Messages(6, "");
// retrieve the reply data
for (int i = 0; i < length; i++)
{
Messages(7, (BlueToothConnection.ReadByte().ToString()));
}
}
}
Okay so there were a few issues that are hard to see from above so I will attempt to explain.
First, RX and TX on the bluetooth card DO NOT go to their equals on the arduino. They go to their opposites.
Example:
Bluetooth Card RX -> TX on Arduino
Bluetooth Card TX -> RX on Arduino
So if you look in the photo of the Arduino above it should be painfully obvious that pins 7 and 8 are the incorrect placement.
The next issue that I was having was poor connectivity.
The power and ground seem to be fine in the above configuration. However, the RX and TX connections need to be soldered in. Otherwise you get a poor connection.
Once I made this changes the above code worked flawlessly.
Hope this helps anyone else having these issues!!
Here is similar code simplified for testing the PC <-> Arduino BT communication. In the code below, the PC sends text to the Arduino, which then echoes it back to the PC. PC writes the incoming text to console.
Set your BT serial port (COM5 in the example) from Windows.
Tested with Arduino Uno, an USB-Bluetooth dongle and the bluetooth module HC-05. Arduino's PIN1(TX) voltage was divided from 5V to 2.5V before feeding it to the module's RX pin).
That's it. Easy!
Arduino:
void setup() {
Serial.begin(9600);
delay(50);
}
void loop() {
if (Serial.available())
Serial.write(Serial.read()); // echo everything
}
C#:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
public class SerialTest
{
public static void Main()
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 9600;
serialPort.PortName = "COM5"; // Set in Windows
serialPort.Open();
int counter = 0;
while (serialPort.IsOpen)
{
// WRITE THE INCOMING BUFFER TO CONSOLE
while (serialPort.BytesToRead > 0)
{
Console.Write(Convert.ToChar(serialPort.ReadChar()));
}
// SEND
serialPort.WriteLine("PC counter: " + (counter++));
Thread.Sleep(500);
}
}
}
I'm about to start developing a small app (C#) that communicates with a PLC and a testing unit via Serial Ports - this is my first venture into this area.
In essence, I am going to send the PLC a signal to start an operation, and then I am going to wait for the result of that operation from the test unit (which will be independently communicating with the PLC) to return a ASCII string.
Depending on the content of that string, I may want to listen to a signal from the PLC...
It's all new to me, so at the moment, I'm just researching System.IO.Ports.SerialPort; digression: are there third part products out there than simplify interaction with the Serial Port, or are the built-in classes as good as you will get? I'm thinking of ease of use as opposed to better features.
However, it will be a few weeks before the hardware is available for development and testing, so I was wondering how I could simulate communication to/from the serial port so that I can start developing my app?
[I don't yet know how the PLC and the PC are due to communicate - I understand it will be binary rather than text, but at the moment, that is all I know.]
Abstract away your serial port comms behind an interface so that you can code your app against the interface and then test with a 'fake' implementation. When you've got the hardware for the real thing, you can code up the 'real' implementation of the interface and swap out the fake one.
So for example, you'd have an interface
public interface ISerialComms
{
void SendMessage(string message)
}
and you'd code your app against that interface using a fake implementation:
public class FakeSerialComms : ISerialComms
{
public void SendMessage(string message)
{
//some implementation
}
}
Hope that helps!
I've had some success in the past using com0com.
There are two pieces of software that I have found invaluable while doing serial port work.
Free Serial Port Monitor
http://www.serial-port-monitor.com
Despite the cheesy name, it is actually quite useful. Note that you should have it stop listening to your port if you go to unplug a USB-to-Serial converter. Otherwise it can crash (well... wait indefinitely on exit, which is annoying). It doesn't have to put itself in the middle of a serial connection to sniff data. It monitors the IO using the Win32 API.
Franson Serial Port Tools
http://franson.com/serialtools/
Or.. any loopback software really. There are lots out there. This allows you to send data and receive it within software. If you end up doing any GPS work, Franson also has a nice GPS simulator so you don't have to sit outside the whole time to debug code.
Finally, if you have had enough with the built-in serial class and its horrendous shortcomings, then you need a replacement, and going straight to the Win32 API will take forever.
CommStudio
I have found CommStudio to be absolutely rock solid. Quite frankly, after spending 5 months researching and buying other options, it is the only one that works perfectly with removable USB adapters. All of the other solutions have issues when the device is plugged back in. You can download their free "Express" version here: http://www.componentsource.com/products/commstudio/downloads.html?rv=42917
I have wrote an article on this topic using Virtual Serial Port Driver 9.0 standard using Microsoft SerialPort Class (Sytem.IO.Ports), it is of course possible to use any other comm port tool.
In the software I create 2 virtual ports COM1 and COM2.
I use COM1 to emulate as data sender.
I use COM2 to receive what ever being send from COM1.
This is helpful if you are developing Embedded or IoT solution.
Emulator (in this example as random accelerometer)
private static bool _continue;
private static SerialPort _serialPort;
public static void Main()
{
var stringComparer = StringComparer.OrdinalIgnoreCase;
var readThread = new Thread(Read);
_serialPort = new SerialPort
{
PortName = "COM1",
ReadTimeout = 500,
WriteTimeout = 500
};
_serialPort.Open();
_continue = true;
readThread.Start();
while (_continue)
{
var x = ValueGenerator();
var y = ValueGenerator();
var z = ValueGenerator();
var message = $"x:{x};y:{y};z:{z}";
if (stringComparer.Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort.WriteLine(message);
Thread.Sleep(200);
}
}
readThread.Join();
_serialPort.Close();
}
public static double ValueGenerator()
{
const int range = 1;
var random = new Random();
return random.NextDouble() * range;
}
public static void Read()
{
while (_continue)
{
try
{
var message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}
And my data receiver is almost similar
private static bool _continue;
private static SerialPort _serialPort;
public static void Main()
{
var stringComparer = StringComparer.OrdinalIgnoreCase;
var readThread = new Thread(Read);
_serialPort = new SerialPort
{
PortName = "COM2",
ReadTimeout = 500,
WriteTimeout = 500
};
_serialPort.Open();
_continue = true;
readThread.Start();
while (_continue)
{
var message = Console.ReadLine();
if (stringComparer.Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort.WriteLine(message);
}
}
readThread.Join();
_serialPort.Close();
}
public static void Read()
{
while (_continue)
{
try
{
var message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}
Disclaimer: the link of this guideline refer to my personal web site.
I like David's answer above but if your looking to do integration tests and actually test your serial port communication I have used and application called ViN soft virtual serial cable in the past to basically create 2 serial ports on your machine that are connected by a virtual cable.
Also if you have a serial port on your development machine you could use it to connect to another machine that has a serial port and write an application that will basically simulate the communication of the PLC.
I would prefer to use a combination of both David's method and this method to ensure proper testing.
There is another resource out there that emulates serial ports for windows if anyone else is still looking for decent serial debugging tools.
The 32-bit version is free and seems pretty decent. It's called Virtual Serial Ports Emulator.
Very old but still might be useful to some. Instead of relying on COM interaction, just use the SerialPort.BaseStream to communicate with the port. This allows you to simply use a standard stream interface for communication, in other words, doesn't matter if you use serial ports, TCP connections, or even file streams. Perfect for simulation.