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.
Related
I am working on making GUI for a Smart Water flow meter whose communication protocol is RS485,
as per instructions from Communication Manual i am sending an inquiry packet and i am receiving proper response in serial port terminal. But when i am trying to do it on my C# app.
Things are happening oppositely.
string data = "[H201815000081]";
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Write(data);
incoming_data = serialPort1.ReadExisting();
text_reciever.Text = incoming_data;
}
// text_reciver is the text box of my gui where i want to display the
// values from flow meter.Data Type of incoming_data is string
Here is the code, i am sending an inquiry code to the device and in return i am getting garbage values on my text box. Some times it is stream of Question mark symbol (?), some time it shows nothing.
But when i revert myself to serial port terminal (Real Term).
It is showing proper values as mentioned in communication manual.
Please assist in this regards.
After looking around i just found the answer to my question.
The point is previously i was communicating with serial port teminal, where everything was working fine, but when it comes to interacting with peripherals one need to make sure that Serialport.DTRProperty is enabled.
When opening the serial port one must enable the DTR property by:
serialPort1.DtrEnable = true;
Otherwise the windows form will read the garbage value.
the incoming data would be serial number of device (ASCII Format) and Water flow values
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
I have a serial port app that read weighing machine.
public void Read()
{
while (Puerto.BytesToRead > 0)
{
try
{
string inputData = Puerto.ReadExisting();
dataReceived = inputData;
}
catch (TimeoutException) { }
}
}
the return string is like this
It has other extrange chars in it, how can i do to parse or get a clean data from it? all I need is 0.52lb
I have no idea what weighing machine is it and what the serial port specs on it but, if it is black box to you too then, check the following:
- check if you have a technical spec that explains what comes out of RS232 port
- do several (10?) samples with one sample weight and see if the number of bytes are delivered each time
- if you see the number of bytes being constant (barring discrepancy in the 0.52lb text changing to 0.5lb once in a while), it is likely that garbage following the weight is additional binary data.
- if not, and you see the weight (text) with exact offset each time, you just can scrape the output
this is complete reverse engineering, I suggest going after technical spec and doing more insightful data handling though.
This could be anything - a bug in the weighing machine, some sort of hardware issue, or a problem in how the serial port is configured. I would suspect a configuration problem. Make sure all the settings are correct (BaudRate, Handshake, Parity, StopBits). Also, try connecting to the same serial port device using another program (e.g. see http://helpdeskgeek.com/windows-7/windows-7-hyperterminal/ ) and see if you see the same garbage data.
what should i do to wait until all the data sent to serial port
to test this condition assume the code bellow:
Console.WriteLine("Baud is:" + SerialPortObj.BaudRate);
Console.WriteLine(DateTime.Now.Millisecond);
string tmpStr="";
for (int i = 0; i < 100; i++)
{
tmpStr += "A";
}
SerialPortObj.Write(tmpStr.ToCharArray(),0,99);
Console.WriteLine(DateTime.Now.Millisecond);
example output is:
Baud is:300
97
97
And it indicate that .Net is not waiting until all chars to be send!
just to mention the code below does not work:
Console.WriteLine("Baud is:" + SerialPortObj.BaudRate);
Console.WriteLine(DateTime.Now.Millisecond);
string tmpStr="";
for (int i = 0; i < 100; i++)
{
tmpStr += "A";
}
SerialPortObj.Write(tmpStr.ToCharArray(),0,99);
while (SerialPortObj.BytesToWrite>0)
{
Thread.Sleep(1);
Console.WriteLine(SerialPortObj.BytesToWrite);
};
Console.WriteLine(DateTime.Now.Millisecond);
example output is:
Baud is:300
97
97
i am working on an special protocol that is depends on baud rate change over and use some thing like the follow:
->[Send Some Bytes (Baud300)]
<-[Receive Another Bytes (Baud9600)]
so i want to send some chars by write method and wait until it finish and right after finishing i try to change baud , so i could understand the received bytes
is there any idea?
In the first place the serial port is stateless. So you can never really by sure when the right point in time is reached for a baud rate change. Due to the fact that you are going to implement your own special protocol you must have control of both sides of the communication (sender/receiver). So in that case i strongly recommend to also set the Handshake property to RequestToSend and checking of the DtrEnable property.
Also you should use two buffers (received/outgoing) on each site of the communication which are watched by their own task/thread. If you push something into the outgoing buffer, the task check if sending is possible (CtsHolding, DsrHolding) and if yes, change the baudrate and push that data onto the wire. Wait till the holding properties are set back and then change the baudrate to the other value. The incoming thread is quite simple in this case. It simply waits for the DataReceived event cause the change of the baudrate is done by the outgoing task.
If you use hardware handshake (which i strongly recommend in your case), then be sure that your serial port supports it correctly. Most of the USB-to-Serial-Adapters don't work very well with anything else then 19200-8-N-1. So before you think you didn't code it right or the SerialPort class is buggy try to find two machines with a real serial port (or one machine with two ports for testing).
Try to store your data in a variable and when a specific condition apear (can be set by you), send the value of the variable to the serial port
Do it in hardware?
You might try to use two serial adaptors, configured as 300/9600. Tx on one and rx on the other. You would need a 'funny cable' with pins 2/3 split out to different D-types, but that should work.
I am working with a codec and am trying to poll the state of RS232 serial pin 1 (CD high/low).
The code I have I think is right but I am second guessing myself and was hoping someone could confirm or correct me.
According to the the data sheet of the codec Pin 1 should be High when a call is active. I suspect i have done something wrong because while in a call I get a return of false (low).
This is a Windows Forms application and I am using System.IO.Ports
private void button4_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen)
{
serialPort1.Open();
}
bool test = serialPort1.CDHolding;
if (test == false)
{
MessageBox.Show("Pin low");
}
else
{
MessageBox.Show("Pin high");
}
}
Also is there an easy way to show the actual voltage on the pin?
There really isn't much here we can tell you that you don't already know. Yes SerialPort.CDHolding "Gets the state of the Carrier Detect line for the port." I would first verify (electrically) the state of the pin, and then check that against what this property tells you. I'm guessing it is telling you the correct state.
When it comes to serial ports, I would always double check your pin-out; depending on the hardware and connector, they can be incredibly non-standard, and are easy to mess up.
You ask about showing the voltage on the pin. Do you mean programattically? No, that is impossible. That is a digital input line; once it hits the UART it is a digital signal, you cannot know the analog voltage.
Just as an additional tidbit, this property is actually just a wrapper that calls the Win32 GetCommModemStatus function, and returns true if bit 7 (decimal 128) is set.
Can you use the .PinChanged event instead? Or do you need to only poll on button press?