When using C# I can only read the last 4 characters of the value in COM2.
Putty reads it correctly
I have no control or information over the source that is putting the value on COM2.
My C# settings resemble the basic settings on Putty configuration screen, but C# offers more settings, so Putty must have some underlying settings not being shown.
I checked the documentation on Putty, I can't find the default settings on serial port.
My code:
using System.IO.Ports;
...
SerialPort mySerialPort = null;
mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 19200;
mySerialPort.Parity = System.IO.Ports.Parity.None;
mySerialPort.StopBits = System.IO.Ports.StopBits.One
mySerialPort.DataBits = 8;
mySerialPort.Handshake = System.IO.Ports.Handshake.None;
mySerialPort.DiscardNull = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.ReadBufferSize = 2147483647;
...
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string value= sp.ReadExisting(); //I onle get the last four characters
}
So I should be obtaining the value "17159160118A" but I onle get "118A", Putty reads the whole string correctly
So given that I have no information about the signal source, my best bet is to use similar configuration as Putty in my code, do you know what configuration this could be? or what am I doing wrong?
So, I deleted all the code and started again with a clean console application, the source was sending the data in two parts, , I was just only reading the second, I just needed to know what was the string terminator, I found out that it was the null terminator character ('\0') so I used that to concatenate my strings, here's my code:
class Program
{
static void Main(string[] args)
{
using (SerialPort sp = new SerialPort("COM2", 19200, Parity.None, 8, StopBits.One))
{
//sp.DiscardNull = true;
sp.Handshake = Handshake.XOnXOff;
sp.ReadBufferSize = 16384;
sp.Open();
sp.DataReceived += sp_DataReceived;
AppDomain.CurrentDomain.ProcessExit += new EventHandler((x, y) =>
{
sp.Close();
});
Console.ReadKey();
}
}
static string myString = string.Empty;
static void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (sender as SerialPort);
if (sp.BytesToRead > 0)
{
myString += sp.ReadExisting().Trim();
if (myString.Last() == '\0')
{
myString = myString.Trim('\0').Trim();
if (!string.IsNullOrWhiteSpace(myString))
{
Console.WriteLine(myString);
}
sp.DiscardInBuffer();
myString = string.Empty;
}
}
}
}
I commented out //sp.DiscardNull = true; as it was removing all the null characters and it worked, so any way thanks for the downvote.
Related
EDIT: Okay, so I've moved on and made a fully working console app:
public static void Main(string[] args)
{
SerialPort mySerialPort = new SerialPort("COM4");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine($"Data Received: {indata}");
indata = "";
}
Now the problem is that when I try to do something similar in the UWP app -
public void InitScanner()
{
SerialPort mySerialPort = new SerialPort("COM4")
{
BaudRate = 9600,
Parity = Parity.None,
StopBits = StopBits.One,
DataBits = 8,
Handshake = Handshake.None,
RtsEnable = true
};
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
tBlock_spState.Text = mySerialPort.IsOpen.ToString();
}
void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
tBlock_test.Text = indata;
}
public MainPage()
{
this.InitializeComponent();
InitScanner();
}
It throws an System.IO.IOException with description "Too many posts on a semaphore" (sorry for the translation, I am using VS with Czech language). Does anyone know the reason why is this happening? Once again, can't find anything anywhere.
So, I've got a task to write a code, which could allow to read data from a barcode scanner that does not act like a keyboard and write it to a textbox. My thought was that it could be possible via System.IO.Ports.SerialPort class, but I have absolutely no idea how to make it work as it should. I am working on this in an UWP. I've tried this so far
SerialPort sp = new SerialPort("COM4", 9600);
void MethodName()
{
string s;
if(!sp.IsOpen)
sp.Open();
while (sp.BytesToRead > 0)
{
s = sp.ReadLine();
tBlock_test.Text = s;
}
sp.Close();
}
And that is where I've ended and don't know what to do next, or even if this is somehow correct. Again, basic question, i know, but i am seriously stuck on this and cannot find solution anywhere. I'd appreciate any kind of help.
I've remade the app in the WPF template and tried the answer from here: SerialPort reading cause error because of not owning thread (Delegate + Invoke method) and it finally worked.
I want to send the hex over the COM port. I have prepared code manually, but its for string sending.
This is how application looks like currently :
I need to read data from textbox and then send in hex format to COM port.
Currently I am handling the button click with the following sending code, however currently it is sending hard coded values, but I need ones taken from text field.
private void btnSendData_Click(object sender, EventArgs e) {
if (serialPort1.IsOpen) {
dataOUT = tBoxDataOut.Text;
if (sendWith == "WriteLine") {
serialPort1.WriteLine(dataOUT);
} else if (sendWith == "Write") {
serialPort1.Write(dataOUT);
}
}
}
You can read about Standard Numeric Format Strings here. Read the section "The Hexadecimal ("X") Format Specifier".
private void btnSendData_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
//dataOUT = tBoxDataOut.Text;
int intVal = Int32.Parse(tBoxDataOut.Text);
dataOUT = intVal.ToString("X");
if (sendWith == "WriteLine")
{
serialPort1.WriteLine(dataOUT);
}
else if (sendWith == "Write")
{
serialPort1.Write(dataOUT);
}
}
}
I would like to include a simple, working example. I do not have a COM port, but the com0com virtual driver works fine for this demonstration; you can download it here. I also used Putty to display the ports' received data; you can download it here.
Here's my program:
public class HexConvert
{
SerialPort mySerialPort;
public HexConvert()
{
InitPort();
}
void InitPort()
{
mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
}
public void SendMessage()
{
try
{
string s = "15"; // "F" In Hexadecimal
int x = Int32.Parse(s);
string s2 = x.ToString("X");
if(!mySerialPort.IsOpen)
mySerialPort.Open();
mySerialPort.WriteLine(s2);
mySerialPort.Close();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Here's my com0com utility's Configuration (I added the COM1 and COM2 pair; no other actions taken in this emulator):
Here is my Putty Configuration (Note that I used COM1 in the program, and COM2 in Putty):
And, finally, here is the output that my demo app produces:
I am working with BC66 modem from Quectel. On my program when I type some AT commands to the modem it can not show the entire response from the modem, but instead the reply of the AT command. see figur below:
Instead using an terminal program and type the AT commands i got the status of my request. See figure below:
This is what I am expecting in my program, but unfortunately not happened.
The code snip:
static void Main(string[] args)
{
if (InitPort() == true)
{
Console.WriteLine("Port initialized");
TestAT();
}
}
private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort.BytesToRead];
serialPort.Read(data, 0, data.Length);
Console.WriteLine(Encoding.ASCII.GetString(data));
//Console.WriteLine(serialPort.ReadExisting());
}
private static void TestAT()
{
for (int i = 0; i < 10; i++)
{
serialPort.Write("at");
Thread.Sleep(2000);
serialPort.Write("at+cereg");
Thread.Sleep(2000);
}
}
private static bool InitPort()
{
serialPort.PortName = "COM51";
serialPort.BaudRate = 115200;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.DataReceived += SerialPort_DataReceived;
try
{
serialPort.Open();
return true;
}
catch
{
return false;
}
}
Any suggestion on what is wrong?
As you can see here on page 7 you need to finish your commands with <CR><LF>.
The “AT” or “at” prefix must be set at the beginning of each command
line. Entering <CR> will terminate a command line.
in C# the equivalent is \r\n
As #Mong Zhu pointed out, you can achieve that by using
serialPort.WriteLine("at");
Code for C#
using System;
using System.Windows.Forms;
using System.IO.Ports;
SerialPort port;
private void btnStart_Click(object sender, EventArgs e)
{
port = new SerialPort("COM6", 9600);
port.Open();
port.Write("START");
port.Close();
}
Code for Arduino
"#"include "MOVIShield.h"
MOVI recognizer(true);
Code inside the loop
signed int res=recognizer.poll();
if(Serial.available() > 0){
String data = Serial.readString();
if(data = "START"){
recognizer.ask("Hello. My name is John");
}
}
I tried to click the btnStart to send "START" to my Arduino Program and the Arduino Program should run ask("Hello. My name is John") after received the data from C# program. But when I clicked the btnStart, there is nothing happened.
You can try different a couple of different things:
1- Make sure COM port parameters are the same on both sides
As explained at http://www.instructables.com/id/How-to-connect-Arduino-to-a-PC-through-the-serial-/
Add this to the Arduino C code outside the loop:
Serial.begin(9600);
And change your C# to a code similar to:
private void btnStart_Click(object sender, EventArgs e)
{
port = new SerialPort("COM6", 9600);
port.DataBits = 8;
port.StopBits = StopBits.One;
port.Handshake = Handshake.None;
port.Parity = Parity.None;
port.Open();
port.Write("START");
port.Close();
}
2- Use a different tool than C# to test if you can communicate to the Arduino.
e.g. this tool has 15 days demo: https://www.eltima.com/rs232-testing-software/
I imagine the single equals in this line may have something to do with it.
if(data = "START")
There are loads of questions about listening of devices on Serial Port using C#.
However I couldn't find something that will be useful for my application and working.
Now this is a code i finally decided to use however I cannot see why it will not output anything:
namespace SerialPorts
{
class Program
{
static void Main(string[] args)
{
SerialPort myPort = new SerialPort();
myPort.DataReceived += MyPortDataReceived;
myPort.PortName = "COM3";
myPort.BaudRate = 19200;
myPort.DataBits = 7;
myPort.Parity = Parity.Even;
myPort.StopBits = StopBits.One;
myPort.Open();
Console.ReadLine();
myPort.Close();
}
static void MyPortDataReceived(object sender,
SerialDataReceivedEventArgs e)
{
var myPort = sender as SerialPort;
Console.WriteLine(myPort.ReadLine());
}
}
}
My device is OCR PASSORT reader.
I expect a string when i swipe a passport. However I get nothing, no output at all.
Can you please help me what can i do to make it output a string at least?
BTW I know the OCR reader is working since there is an app coming with it that outputs its data and when I use apps that test the COM i get data but with this code I get nothing. Any help will be appreciated!
Regards!