Reading Info sent by arduino to Serial Port with C# - c#

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.

Related

sniff serial port - .net

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.

What happens if I use VCP on a FTDI (FT2232H) setted in UART mode? [COM not well talking]

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 (:

C# Application will not Receive Serial Data Stream

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.

C# console application talking to Arduino via Bluetooth

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);
}
}
}

c# Serialport problem: data are send in "clumps"

I am trying to remote control a lego mindstorms NXT robot using a bluetooth serial connection. The program connects without any problem but when i send single commands they do not appear before several other commands has been send. Then they all appear at once on the nxt.
I have tried everything (i can think of or google has told me to) but i cannot seam to get the buffer to flush after a command is send.
Anyone having a idea about what i can do?
Here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace NXTBtRemote
{
public class BTHandler
{
SerialPort comm;
private string comPort;
public BTHandler()
{
comm = new SerialPort();
}
public Boolean Connect(string _comPort)
{
this.comPort = _comPort;
comm.PortName = comPort;
comm.Open();
if (comm.IsOpen) return true;
else return false;
}
public void sendCommand(Command command)
{
string msg = command.cmdType + "#" + command.arguments;
if (!comm.IsOpen) comm.Open();
comm.WriteLine(msg);
comm.DiscardOutBuffer();
}
}
}
Hope somone can help. Thanks in advance
kind regards - kenneth
comm.DiscardOutBuffer();
That's very bad. You are throwing away the bytes you have just written. The WriteLine() method writes the command to the output buffer from which they are slowly written to the serial port. Only if you debug the code, single stepping through the code, would the serial port driver have enough of a chance to actually send something. It would be hit or miss if the chip itself has a FIFO buffer. Just delete the DiscardOutBuffer() call, it does nothing but harm.
Beyond that, you are really complaining about a problem with receiving a response. But didn't show any code that makes any Read call.

Categories