I try connect to scale via rs232 cable. When I try write "ENQ" to port then scale turn off and receive nothing. This is my code. Sorry my bad English :(
class ScaleCAS
{
private SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
public string result = null;
public ScaleCAS()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.result = port.ReadExisting();
}
}
ADD
In another class I try write into port
Scale.port.write("ENQ");
Console.Write(Scale.result);
You are not waiting for your scale to answer, you read the value of result a way lot faster then it get filled with data.
A good way to communicate using SerialPort is with ReadLine and WriteLine, check out that NewLine was set correctly according to you device programming manual (which would be nice to add to the question if you are asking question about specific device).
Some general troubleshooting of RS232 communications:
Check baud rate and all other serial port configuration
Check what is the EOL (End of Line) character, and use it to terminate writing statements and to know how to stop reading input messages (or use ReadLine and WriteLine)
Check the communication manually using TeraTerm or some other serial terminal
Related
I recently purchased a modem, which attaches via USB and appears to the operating system as a serial port device: COM19
To ensure the modem was OK, I first tried using PuTTY in serial mode. From there, I have no problem issuing AT commands and receiving responses from the modem. According to PuTTY configuration, my default options for controlling local serial lines are (at the time):
Speed (baud): 9600
Data bits: 8
Stop bits: 1
Parity: None
Flow control: XON/XOFF
Here's what I see in PuTTY (when I type the AT command):
AT
OK
^BOOT:30645964,0,0,0,75
However, when I try to access the same COM port from .NET (not at the same time as running PuTTY) I never receive the "OK" responses. I do still receive (what appears to be) echo, and the occasional unsolicited message from the modem, so I can see that I'm connected to the correct device. Sometimes the modem will respond to a malformed command with "ERROR", but never "OK". Here's the C# snippet where I initialize the COM port:
var commandPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
commandPort.DataReceived += CommandPort_DataReceived;
commandPort.Handshake = Handshake.XOnXOff;
commandPort.Open();
commandPort.Write("AT\n");
for (var i = 0; i < 30; i++)
{
Thread.Sleep(1000);
}
And this is the event handler:
private static void CommandPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.Write(((SerialPort)sender).ReadExisting());
}
This is what's printed back to the console of the C# application (note that I'm not explicitly writing the command to the console, it's added by the CommandPort_DataReceived event handler):
AT
^BOOT:30645964,0,0,0,75
None of the AT commands issued by the .NET application perform any action, though their equivalents in PuTTY are able to query modem state, place calls, etc. What am I doing wrong?
Use the SerialPort class's NewLine property. By default it's set to "\n". This needs to be "\r", then you can use the WriteLine(...) method to send AT commands.
commandPort.NewLine = "\r";
commandPort.Open();
commandPort.WriteLine("AT");
I have 2 devices communicating throw a serial port, i ordered a "T" shaped serial port cable and can listen to the transaction between my 2 devices, when i try with a monitoring soft i have no problem to get ALL the data but when i try whith c# code i only get 1st line right and then i miss char and get "?" instead of some data. Here is more or less what i had on serialport datarecievedhandler:
private void DataReceviedHandler(object sender,SerialDataReceivedEventArgs
e)
{
SerialPort sp = (SerialPort)sender;
this.Data = sp.ReadExisting();
}
giving me line like : CRC ???ogram?? DA?E
I found topic where they talked about Multithreading to be able to continuously listen to port whithout having to stop to listen when "getting" data but this notion is new to me and i don't know how to inplement it.
Isn't there a way to recieve data until a timeout on a "Nodatasend" to then get my data and re-listen to my port ?
I am trying to communicate with an Industrial weight bridge using a serial port. I know how to write the code code (c#). The problem is when I connect the bridge to the Indicator the weight is displayed. However when I connect the bridge to my PC and run the program all that is returned is "\0"(NULL). When I connect my PC to the indicator and run the program I get continuous "\0". I am using xk3190-a9 indicator. here is sample program
namespace SerialPort
{
class Program
{
private static string dev = "";
static void Main(string[] args)
{
System.IO.Ports.SerialPort mySerialPort = new System.IO.Ports.SerialPort("COM15")
{
BaudRate = 2400,
Parity = Parity.None,
StopBits = StopBits.Two,
DataBits = 8,
RtsEnable = true,
};
mySerialPort.DataReceived += DataReceivedHandler;
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
System.IO.Ports.SerialPort sp = (System.IO.Ports.SerialPort) sender;
dev += sp.ReadExisting();
Console.WriteLine(dev);
}
}
}
My question is whether the bridge needs "special" commands to send back the weight or what can I do to get the weight. Any other data from the port would be progress. Also I have tried different port settings all same result.
After searching online and not finding a solution that would fit my case I gave up the digital chase and consulted a weight bridge 'specialist'. In case you are pulling out your hair too, here are a few things to note:
Most weight bridges(trucks and vehicles) will send the weight as an analogue signal. So even though they have a serial port your computer will definately not "get it" hence the \0 return.
To get any weight to your software you will have to go through an indicator which has converters on it's motherboard which read the analogue signal and can convert it to a digital signal
As much as indicators get it, some of them have very low BaudRates and the rate might be set at a weird number(see 4) so you might want to try from as low as 100 to 9600. In my case the BaudRate was 600 which I never tried hence the continuous \0
Know how to configure your indicator - A simple google search using the indicator number should yield a good English language manual, it might be confusing at first but that is the only way you will be able to change the BaudRate(among other settings) and avoid all the guessing.
Simple indicators return GrossWeight and most times this is sufficient but incase you need weight per axle or you want weight on each load cell you might need an advanced indicator like Avery Weigh-Tronix E1310
This notes should guide you to a viable solution, I got mine from 1,3 & 4.
so I have an C# WinForm that use
SerialPort SerialPort1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
SerialPort1.Open()
SerialPort1.DataReceived += new SerialDataReceivedEventHandler(...)
to listen on several Virtual COM Ports that Created by other Software(I can't control it)
So generally it goes well except When the other Software is dead or gone, the Virtual COM port it created is also gone or missing
So my WinForm App fail because there is no COM1 to listen to
Question: How should I handle this error when there is no COM port to listen
Thank you so much for your reply
Put it in a try - catch statement and print a message to the user if something bad happened.
try
{
SerialPort SerialPort1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
SerialPort1.Open()
SerialPort1.DataReceived += new SerialDataReceivedEventHandler(...)
}
catch(Exception e)
{
//Print error to user
}
For finer granularity on the exception, see the msdn documentation of the serial port here.
Well, no, virtual serial ports are emulated by software. If that software fails then of course there's no functional serial port anymore. Nothing you can do about that other than finding better software.
If this is the common failure mode, jerking out the connector of a USB device while a program is talking to it then just don't bother. Whomever does that needs to be learned the Hard Way that using the Windows "Safely Remove Hardware" tray icon option is not optional. It tends to take a bit of reinforcement to get them to realize what "Unsafely Remove Hardware" does. Albeit, oddly, that it tends to be programmers that do this, rarely regular users. Could be site bias and regular users just tend to figure out by themselves that doing this isn't a good idea. It isn't, these drivers count on humans being cooperative. Necessary since serial ports are not plug & play devices, there's no way for the driver to deliver a "device is gone, stop using" notification. Well, other than hard-crashing your program intentionally.
If the only problem is that the number of the port is unpredictable you could detect all the available ports as shown below and the try them one at a time. I once had this problem when a usb device sometimes showed up as COM1 and other times as COM5
string[] availablePorts = SerialPort.GetPortNames();
foreach (string strPortName in availablePorts)
{
try
{
SerialPort SerialPort1 = new SerialPort(strPortName, 9600, Parity.None, 8, StopBits.One);
SerialPort1.Open();
}
catch (Exception e)
{
//Print error to user
}
}
The objectve is to find which Serial port is phyisically connected to other machine. I want to Search my system to find the available serial ports and send a test message using all the ports and wait for the response. And get the port numbers of Which ever ports get a response is connected to the other machine. How to do?? Thanks.
The SerialPort.GetPortNames() method returns an array of the COM port names of all available serial ports. You could iterate it and try to Open() them. Expect failure, the port might already be opened by another program.
You don't want to send something to a device that doesn't expect it. Using the DsrHolding property is a reasonable test to see if a device is attached that's powered up.
Your ultimate nemesis is going to be the Baudrate property. You cannot guess the proper value. Serial ports are way too primitive to support plug-and-play style device discovery. Avoid using something that cannot work reliably, allow you user to configure your program with the settings you need. It is the normal practice.
Use System.IO.Ports.
public static void OnSerialDataReceived(object sender,
SerialDataReceivedEventArgs args)
{
string data = ComPort.ReadExisting();
Console.Write(data.Replace("\r", "\n"));
}
private static void InitializeComPort(string port, int baud)
{
ComPort = new SerialPort(port, baud);
// ComPort.PortName = port;
// ComPort.BaudRate = baud;
ComPort.Parity = Parity.None;
ComPort.StopBits = StopBits.One;
ComPort.DataBits = 8;
ComPort.Handshake = Handshake.None;
ComPort.DataReceived += OnSerialDataReceived;
ComPort.Open();
}
more on Mark Michaelis' blog
SerialPort.GetPortNames() method is static methods for SerialPort .Do you sure communication between them have flow control?