So, I'm trying to use my Barcode Scanner as a 'Serial' device as opposed to a Keyboard emulator but it is not creating the com port. I have scanned the set-up codes from the manual that set it as a Serial device, that seems to configure the scanner correctly (it stops sending scanned codes to text-box\text editor) but because there is no COM port, I cannot capture the data when I scan a barcode......
Windows installed the driver when it was first plugged in, there wasn't a disk\driver supplied... wondered if anyone else has experienced the same issue.....
Here is my code....
class Program
{
// Create the serial port with basic settings
private SerialPort port = new SerialPort("com1", 9600, Parity.None, 8, StopBits.One);
[STAThread]
static void Main(string[] args)
{
new Program();
}
private Program()
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
Console.WriteLine("Incoming Data:");
// Attach a method to be called when there
// is data waiting in the port's buffer
port.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived);
// Begin communications
port.Open();
// Enter an application loop to keep this thread alive
Application.Run();
}
private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
// Show all the incoming data in the port's buffer
Console.WriteLine(port.ReadExisting());
}
}
I get the error message..... 'The port 'com1' does not exist'..... when I try to open the Port.
When I create a virtual Port (using 3rd party app) the code runs BUT I still don't get the data from the Scanner....
I just newbie, and I was having task - recieve data from BarCode scaner by serial port... I spent a lot of time... and I have next result
using System.IO.Ports;
using System.Timers;
namespace BarCode_manager
{
public partial class MainWindow : Window
{
private static SerialPort currentPort = new SerialPort();
private static System.Timers.Timer aTimer;
private delegate void updateDelegate(string txt);
public MainWindow()
{
InitializeComponent();
currentPort.PortName = "COM6";
currentPort.BaudRate = 9600;
currentPort.ReadTimeout = 1000;
aTimer = new System.Timers.Timer(1000);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
if (!currentPort.IsOpen)
{
currentPort.Open();
System.Threading.Thread.Sleep(100); /// for recieve all data from scaner to buffer
currentPort.DiscardInBuffer(); /// clear buffer
}
try
{
string strFromPort = currentPort.ReadExisting();
lblPortData.Dispatcher.BeginInvoke(new updateDelegate(updateTextBox), strFromPort);
}
catch { }
}
private void updateTextBox(string txt)
{
if (txt.Length != 0)
{
aTimer.Stop();
aTimer.Dispose();
txtReceive.Text = Convert.ToString(aTimer.Enabled);
currentPort.Close();
}
lblPortData.Text = txt;
lblCount.Content = txt.Length;
txtReceive.Text = Convert.ToString(aTimer.Enabled);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (currentPort.IsOpen)
currentPort.Close();
}
}
}
you may used below code. I can able to open the COM which I configured in specific port.
SerialPort _serialPort;
// delegate is used to write to a UI control from a non-UI thread
private delegate void SetTextDeleg(string text);
private void Form1_Load(object sender, EventArgs e)
{
// all of the options for a serial device
// can be sent through the constructor of the SerialPort class
// PortName = "COM1", Baud Rate = 19200, Parity = None,
// Data Bits = 8, Stop Bits = One, Handshake = None
//_serialPort = new SerialPort("COM8", 19200, Parity.None, 8, StopBits.One);
_serialPort = new SerialPort("COM8", 19200, Parity.None, 8, StopBits.One);
_serialPort.Handshake = Handshake.None;
_serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
}
I'm in the process of writing my own barcode scripts. My scanner defaults to being a plug-n-play USB-HID...Human Interface Device...as opposed to being a USB-COMn port. I have to scan a barcode to switch it over to serial port mode. You can watch the transformation process in the Device Manager tree...as a "Ports" branch sprouts out, containing your barcode scanner's details. Mine's COM3.
Related
I've been trying to get a live updating chart to work with WPF using livecharts, my goal is to have a chart update as it reads a serial input from an Arduino that just gives some numbers.
Using this example: https://lvcharts.net/App/examples/v1/wpf/Constant%20Changes
Although the example includes a built in randomizer of numbers, I want to switch that out for the Arduino serial input.
I read the serial input like this:
private void Button_Serial_Click(object sender, EventArgs e)
{
Thread thread = new Thread(SerialThread);
thread.Start();
}
static SerialPort _serialPort;
private void SerialThread() //serial thread starts here
{
_serialPort = new SerialPort();
_serialPort.PortName = "COM3";//Set your board COM
_serialPort.BaudRate = 9600;
try
{
_serialPort.Open();
}
catch (Exception e)
{
Console.WriteLine("could not connect to serial");
}
while (true)
{
string serialMSG = _serialPort.ReadExisting();
Console.WriteLine(serialMSG);
Thread.Sleep(200);
}
}
My problem is that I don't know what code to switch out for it to read the serial instead of the built in randomizer the example uses. The example has no usable comments or explanation of how it works and my inexperience with coding makes me unable to understand it fully.
I've looked at similar issues, but most just say to read through livechart examples. Well I did, but I do not understand it enough still.
Any assistance is appreciated.
Instead of while(true), you should let c# you decided when data
class Program
{
private static SerialPort port = new SerialPort("COM3",
9600, Parity.None, 8, StopBits.One);
private static ChartValues<MeasureModel> _chartValues;
static void Main(string[] args)
{
SerialPortWorker();
Console.Read();
}
private static void SerialPortWorker()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); //called when the data waiting in the buffer
port.Open(); //// Begin communications
Console.ReadLine(); // keep console thread alive
}
private static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if(port.BytesToWrite > 0)
{
var data = port.ReadExisting(); //read incoming data
_chartValues.Add(new MeasureModel
{
DateTime = DateTime.Now,
Value = data
});
SetAxisLimits(now);
//lets only use the last 150 values
if (ChartValues.Count > 150) ChartValues.RemoveAt(0);
}
}
}
class MeasureModel
{
public DateTime DateTime { get; set; }
public String Value { get; set; }
}
I'm working with Dallas Key which is wired on the COM2 port.
The dallas Key has a value when it's ON (for example 00 AA BB) and a value when it's removed (for example 00 00 00).
How can I ready continuously the value of the COM2 port in order to detect it's change and take actions based on it ( winforms application ).
I've tried to get the value by port name and read it but it says access denied in some cases.
private SerialPort port = new SerialPort("COM2",9600, Parity.None, 8, StopBits.One);
static void Main(string[] args)
{
SerialPortProgram();
}
private static void SerialPortProgram()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
Console.ReadLine();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(port.ReadExisting());
}
I want to listen to the COM2 port value all the time without having a big impact on the application speed, get the value of the COM2 port (my dallas key) when it is ON and detect when it is off and take specific action.
Even though you didn't describe what line actually throws, by reading the documentation i found this nuget
SerialPort.Open Method
Exceptions UnauthorizedAccessException Access is denied to the port.
-or-
The current process, or another process on the system, already has the
specified COM port open either by a SerialPort instance or in
unmanaged code.
You either don't have permission to open the port, or you already have it open, you need to figure out which one it is and deal with it appropriately
Note : com ports can be a bit fickle if you are using usb to com
The below code works when I write in console (Project is Console Application) but when I changed back to Windows Application and try to write in a label or change a variable value: this doesn't work:
public Form1()
{
InitializeComponent();
SerialPortProgram();
}
private void SerialPortProgram()
{
SerialPort mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
mySerialPort.Close();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
switch (ASCIItoHex(indata))
{
case "00000113":
LB_Display.Text = "User 1";
break;
case "0000017a":
LB_Display.Text = "User 2";
break;
default:
LB_Display.Text = "Disconnect";
break;
}
}
public static string ASCIItoHex(string Value)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in Value)
sb.Append(string.Format("{0:x2}", b));
return sb.ToString();
}
I currently have a program made using VB6 code that uses the MSCOMM control to pull back data from the serial port. This manages to successfully receive the data from my serial port, in which a Denso BHT-904B device is connected.
I am now trying to move this code over to C# so it fits in with a new piece of software that i am developing. To do this i am using the SerialPort class. However, the issue is that when i open the port up the data received event only fires when the device fails to communicate (which im guessing is due to a timeout). The data then received in the event is '↑↑↑↑↑'.
My SerialPort control settings are the following:
DtrEnable = True
PortName = COM3
ReadBufferSize = 1024
WriteBufferSize = 512
The code that i am using behind my form control is:
namespace BHTTestingDotNet
{
public partial class Form1 : Form
{
private string rxString;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serialPort.DtrEnable = true;
serialPort.Encoding = Encoding.Default;
serialPort.DataReceived += serialPort_DataReceived;
serialPort.ErrorReceived += serialPort_ErrorReceived;
serialPort.Open();
}
private void serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
MessageBox.Show(e.ToString());
}
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
var serialPort = (SerialPort)sender;
var test = serialPort.BytesToRead;
SerialPort sr = (SerialPort)sender;
rxString = sr.ReadExisting();
this.BeginInvoke(new EventHandler(displayText));
}
private void displayText(object o, EventArgs e)
{
txtBHT.AppendText(rxString);
}
}
}
I have already tried to set both RtsEnable and DtrEnable to true but that didn't make any difference.
UPDATE - I have now changed to protocol settings on the device but i now only receive pipes and then a return symbol, for example like so:
|||||¬
I am using SerialPort class often and for my purposes I have made my own class
public class SerialPortDataSource : SerialPort
where SerialPort.DataReceived handler invoke this method:
private void SerialPortDataSource_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (BytesToRead > 0)
{
var buffor = new byte[BytesToRead];
Read(buffor, 0, buffor.Length);
_receivedBytes = buffor;
//wConsole.WriteLine(ArrayExtension.ToString(buffor));
var dataLogger = DataLogger;
if (dataLogger != null)
{
dataLogger.WriteLine("- DR - {0}", true, BitConverterExtension.ToHexString(buffor));
}
if (OnDataReceived != null)
{
OnDataReceived(this, buffor);
}
}
}
catch (InvalidOperationException)
{
// sometimes DataReceived event is invoked after port is closed which causes InvalidOperationException
}
}
This method is working for me in many applications with variety serial port settings.
I have this (Working) code for receiving data from serial ports and displaying it in a console application in c#.
#region Namespace Inclusions
using System;
using System.IO.Ports;
using System.Windows.Forms;
#endregion
namespace SerialPortExample
{
class SerialPortProgram
{
// Create the serial port with basic settings
private SerialPort port = new SerialPort("COM1",
9600, Parity.None, 8, StopBits.One);
[STAThread]
static void Main(string[] args)
{
// Instatiate this class
new SerialPortProgram();
}
private SerialPortProgram()
{
Console.WriteLine("Incoming Data:");
// Attach a method to be called when there
// is data waiting in the port's buffer
port.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived);
// Begin communications
port.Open();
// Enter an application loop to keep this thread alive
Application.Run();
}
private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
// Show all the incoming data in the port's buffer
Console.WriteLine(port.ReadExisting());
}
}
}
But how would I transfer this code into working on a Windows Forms Application?
I know this is a vague question, but please if possible could you provide some example code for such an application.
If you add the following lines to replace your Application.Run statement you should be ready to go.
(remove your original port.DataReceived line)
var frm = new Form { Height = 200, Width = 200 };
var txt = new TextBox {Dock = DockStyle.Fill, Multiline=true };
frm.Controls.Add(txt);
port.DataReceived += (sender, args) => {
if (txt.InvokeRequired)
{
txt.Invoke(new MethodInvoker(() => {
txt.Text += port.ReadExisting();
}));
}
else
{
txt.Text += port.ReadExisting();
}
};
Application.Run( frm);
i have a serial port that will iterate through the ports with this method:
foreach (string s in SerialPort.GetPortNames())
{
var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (serialOneOfMany.IsOpen)
{
serialOneOfMany.Close();
}
else
{
try
{
serialOneOfMany.Open();
}
catch
{
var openSerial = new System.Timers.Timer(3100);
openSerial.Elapsed += (o, e) =>
{
serialOneOfMany.Open();
openSerial.Enabled = false;
openSerial.Dispose();
};
openSerial.Enabled = true;
}
}
if (serialOneOfMany.IsOpen)
{
string received;
try
{
lblPortNum.Content = s;
lblPortNum.Refresh();
serialOneOfMany.Write(testMessage);
serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
}
catch (TimeoutException e)
{
serialOneOfMany.Close();
continue;
}
}
}
so, i want to open the port, send it a message, listen for the response, then close it. as everyone knows, every comport found in GetPortNames isn't a valid serial port. so, what i've been doing is setting a timer with a dispatcher timer:
DispatcherTimer time = new DispatcherTimer();
time.Interval = TimeSpan.FromMilliseconds(3000);
time.Tick += new EventHandler(someEventHandler);
time.Start();
here's the other method handled here:
private void someEventHandler(Object sender, EventArgs args)
{
SerialPort serial = (SerialPort)sender;
if (serial.IsOpen)
serial.Close();
serial.Dispose();
//if you want this event handler executed for just once
DispatcherTimer thisTimer = (DispatcherTimer)sender;
thisTimer.Stop();
}
so, it'll open the com port, if it doesn't get a response within 3 seconds, it will close the port. the problem i'm having is that the foreach loop will just barrel through the code and open the comport several times, i'll get a message saying The COM Port is open already and can't be used. so basically it's not pausing in openSerial.
i want it to open a new serial port, and if it's not accessible, wait 3100 milliseconds and try again. how do i do that?
UPDATED CODE:
private void button1_Click(object sender, RoutedEventArgs e)
{
CheckPorts();
}
private void checkPorts()
{
SendMessage("messageToDevice1", 19200);
SendMessage("Message2", 9600);
}
private void SendMessage(string testMessage, int baudRate)
{
int baudRate = 9600;
string testMessage = "test";
txtPortName.Text = "Testing all serial ports";
foreach (string s in SerialPort.GetPortNames())
{
SerialPort newPort = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (!newPort.IsOpen)
{
try
{
newPort.Open();
}
catch { }
}
if (newPort.IsOpen)
{
openPorts.Add(newPort);
newPort.Write(testMessage);
newPort.DataReceived += new SerialDataReceivedEventHandler(serialOneOfMany_DataReceived);
}
else
{
newPort.Dispose();
}
}
txtPortName.Text = "Waiting for response";
tmrPortTest.Enabled = true;
}
my new problem is that it just blows through the com ports, i need it to stop for each one, take a second to listen, then close it. it just blows through the foreach loop.
now, the reason why i don't just open up the port and keep it open through all the messages is that my devices have different baud rates, and i can't adjust them to all match. so, i need to open the ports, then send messages, listen, if they don't respond to the first round of messages, then open them up at the new baudrate and send a new batch of messages. but the foreachloop doens't pause for me to listen.
I think this more or less agrees with rare's answer. The port where you receive a response (you would probably want to check the response as well) will remain open and all the others should close.
private List<SerialPort> openPorts = new List<SerialPort>();
private void button3_Click(object sender, EventArgs e)
{
int baudRate = 9600;
string testMessage = "test";
txtPortName.Text = "Testing all serial ports";
foreach (string s in SerialPort.GetPortNames())
{
SerialPort newPort = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (!newPort.IsOpen)
{
try
{
newPort.Open();
}
catch { }
}
if (newPort.IsOpen)
{
openPorts.Add(newPort);
newPort.Write(testMessage);
newPort.DataReceived += new SerialDataReceivedEventHandler(serialOneOfMany_DataReceived);
}
else
{
newPort.Dispose();
}
}
txtPortName.Text = "Waiting for response";
tmrPortTest.Enabled = true;
}
private void serialOneOfMany_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
txtPortName.Text = ((SerialPort)sender).PortName;
}
private void tmrPortTest_Tick(object sender, EventArgs e)
{
tmrPortTest.Enabled = false;
foreach (SerialPort port in openPorts)
{
if (port.PortName != txtPortName.Text)
{
port.Close();
port.Dispose();
}
}
}
Here's how I would do this --
First, try to open all the serial ports. The ones that actually do open are put in a list.
Assign all serial ports in the list to the same DataReceived event handler. The event handler is where you will save the port name (it's in the args) and kill the timer if you rx'd the response
Send your testMessage out all the open ports
Set just one timer for 3.1 seconds
Close the ports once the timer fires or the event handler rx's the response.