I am developing a windows form to function as a modbus tcp Master Simulator.I am using NModbus library.
I want to connect to multiple slaves simultaneously and do the read and write operation,does the NModbus library supports this kind of implementation? and if so how?.
Currently i am able to connect to single slave device and do the read/write operations,but i am stuck on how to the same with multiple slaves though.
Should i use the threading Concept to achieve the same.
Here is my code to connect to single slave device and do the read/write operation.
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
TcpClient masterTcpClient = new TcpClient(txtIP.Text, 502);
master = ModbusIpMaster.CreateIp(masterTcpClient);
MessageBox.Show("Connected");
}
catch (SystemException error)
{
MessageBox.Show(error.Message);
}
}
private void btnReadCoil_Click(object sender, EventArgs e)
{
try
{
byte slaveID = 255;
ushort startAddress = Convert.ToUInt16(txtStartaddress.Text);
ushort numInputs = Convert.ToUInt16(txtSize.Text);
bool[] inputs = master.ReadCoils(slaveID, startAddress, numInputs);
AnswerFromServer.Items.Clear();
for (int i = 0; i < inputs.Length; i++)
{
AnswerFromServer.Items.Add(Convert.ToInt16(inputs[i]));
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Exception Reading values from Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnWriteSingleRegister_Click(object sender, EventArgs e)
{
try
{
byte slaveID = 255;
ushort RegisterAddress = Convert.ToUInt16(txtStartaddress.Text);
ushort value = Convert.ToUInt16(txtSingleValue.Text);
master.WriteSingleRegister(slaveID, RegisterAddress, value);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Exception writing values to Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Can any one please help me with this one?
create another instance of this socket and maintain it.
TcpClient masterTcpClient_Two = new TcpClient(txtIPTwo.Text, 502);
Related
I am creating a Windows Form application, where it is connecting to a device through bluetooth. I am able to send commands to the device and I am receiving the data continuously. The problem I am facing is that I am not able to show the continuous data in the text box. The text box only shows the first line of characters the application is receiving. Here is my code:
CONNECT BUTTON ACTION:
private void btnConnect_Click(object sender, EventArgs e)
{
if (listBox.SelectedItem != null)
{
lblProgress.Text = "";
btnStart.Enabled = true;
cBoxAvailablePorts.Enabled = cBoxAvailableBaudRates.Enabled = true;
try
{
int pos = listBox.SelectedIndex;
deviceInfo = array.ElementAt(pos);
if (pairDevice())
{
Thread thread = new Thread(() => connectThread());
thread.Start();
}
else
{
MessageBox.Show("Pair failed!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
else
{
MessageBox.Show("Please connect to a device!");
}
}
THREAD ACTION
private void connectThread()
{
//BluetoothClient client = new BluetoothClient();
bc.BeginConnect(deviceInfo.DeviceAddress, serviceClass, this.connectCallBack, bc);
}
CALLBACK ACTION:
private void connectCallBack(IAsyncResult result)
{
//BluetoothClient client = (BluetoothClient)result.AsyncState;
try
{
if (bc.Connected)
{
MessageBox.Show("Connected!");
}
else
{
MessageBox.Show("Connection Failed!");
}
}
catch (Exception)
{
MessageBox.Show("Not able to identify Bluetooth devices! Please try again.!");
}
}
START BUTTON ACTION:
Here I send a command "S".
In button action I call sendMessage("S").
The function that is called is shown below:
public void sendMessage(string msg)
{
try
{
if (bc.Connected)
{
Stream stream = bc.GetStream();
stream.ReadTimeout = 1000;
StreamWriter streamWriter = new StreamWriter(stream);
streamWriter.WriteLine(msg);
streamWriter.Flush();
// Read operation
StreamReader streamReader = new StreamReader(stream);
string result = streamReader.ReadLine();
txtResult.Text = result;
}
else
{
MessageBox.Show("Sending failed!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I wrote the StreamReader part in a loop, and it gave me Socket Exception.
I also tried to get the data from Serial Port and used DataReceived event just in case, but still it didn't help.
Any help would be appreciated.
Thank you!
OKAY! I solved the problem. Without getting in trouble with 32feet library (though it is fun to code with 32feet), I thought to make communication through serial port. I connected the device with my laptop and got to know the outgoing COMPORT in bluetooth setting of my laptop. The two-way communication can only be done through outgoing COMPORT, not the incoming COMPORT.
Suppose the outgoing COMPORT is COM12 and the baud rate that I have set is 9600.
So here is my code:
public delegate void updateDelegate(string text);
private updateDelegate objDelegate;
private SerialPort serialPort;
public View() // constructor
{
InitializeComponent();
this.WindowState = FormWindowState.Normal;
this.StartPosition = FormStartPosition.CenterScreen;
this.objDelegate = new updateDelegate(getText);
serialPort = new SerialPort("COM12", 9600);
serialPort.Handshake = Handshake.None;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
}
START BUTTON ACTION
private void btnStart_Click(object sender, EventArgs e)
{
sendData("S");
}
// SEND COMMAND
public void sendData(string msg)
{
try
{
if (!serialPort.IsOpen)
{
serialPort.Open();
//serialPort.Close();
}
if (serialPort.IsOpen)
{
serialPort.Write(msg);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// READ DATA
public void readData()
{
try
{
serialPort.DataReceived += SerialPort_DataReceived;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string res = serialPort.ReadExisting();
Thread.Sleep(500);
txtResult.Invoke(this.objDelegate, new object[] {res});
}
public void getText(string text)
{
txtResult.Text = text;
}
I hope this will help someone! Thank you!!!
i have build a chat application that uses UDP and TCP sockets, first let me walk you through the mechanism of the app:
from the android device i send a UDP packet to a group address which has multiple windows devices listening to it, when the windows device receives the packet, it checks whether it has the same phone number or not so i use the phone number as a unique key to identify the device then if it has the same phone number that I've send the packet with, it will respond with a key says: "ImReadyNow" sent through a TCP socket and that will make the android device accept the connection and act as a server for that windows device, i had similar problems when i first start making that app, the respond key from the windows device was returned with some rubbish data before and after it and i solved that problem by attaching a key to that massage and i split it after releasing so that old problem that i was facing was when a windows device sends "Hello" the android device receives
"????Hello" i solved this one by attaching a key to the first of the massage so
i'll receives "????$#!Hello" then i'll split the received string into two parts and displays the massage only, and that works fine for me till, i notice that sometimes the android device receives rubbish data only and that occurs randomly like if windows device sends "hello" then "hi" then "hello"
i may receives the first two massages right but the third one will received as "?????"
and as i told you it occurs randomly so does any one know why is this happening?
after debugging br.readLine() method does sometimes return "????" and this occurs as i said randomly.
here is the code that i'm using:
private class ChatClientThread extends Thread {
#Override
public void run() {
/*Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream=null;*/
// clientSocket=null;
try {
String data=EmpPhoneNumber;
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(52276));
socket.setBroadcast(true);
InetAddress group = InetAddress.getByName(
"224.0.1.2");
System.out.println("HELLO");
System.out.println(data);
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(),
group, 52276);
serverSocket=new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(4125));
int i=0;
while(i<=30){
Thread.sleep(200);
socket.send(packet);
i++;
}
while(true){
clientSocket = serverSocket.accept();
BufferedReader br= new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
strAcceptConnection= br.readLine();
System.out.println(strAcceptConnection);
if(!strAcceptConnection.contains("$#!")){
updateTextView("<font color=\"#0000A0\"> <b>"+empNameChat+": </b></font>"+"Error in recieving msg");
}else{
String parts[]= strAcceptConnection.split("[$#!]+");
if(!parts[1].equals("ImReadyNoW")){
updateTextView("<font color=\"#0000A0\"> <b>"+empNameChat+": </b></font>"+parts[2]);
}}}
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
EmpDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(EmpDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
EmpDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(EmpDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (NullPointerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
} finally {
EmpDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
}
}
public void sendMessage(View view) {
final String msg= et.getText().toString();
et.setText("");
new Thread(new Runnable() {
public void run() {
Socket sock= null;
try {
sock= new Socket(clientSocket.getInetAddress().getHostAddress(), 4125);
Log.v("str", "send sock: "+sock.getInetAddress().getHostAddress()+sock.isConnected()+Integer.toString(sock.getPort()));
} catch (UnknownHostException e) {
Log.v("ERRORTAG", ""+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.v("ERRORTAG", ""+e.getMessage());
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
try {
DataOutputStream out= new DataOutputStream(sock.getOutputStream());
if(!msg.equals("")){
out.writeUTF("XX$#!"+MainActivity.empIdFromD+"$#!"+msg);
out.flush();
updateTextView("<font color=\"#800000\"> <b>"+"You"+": </b></font>" + msg);}
}
catch (IOException e) {
Log.v("ERRORTAG", ""+e.getMessage());
e.printStackTrace();
}
}
}).start();
}
public void updateTextView(String message) {
final String msg= message;
uiHandle.post(new Runnable() {
public void run() {
textView.setMovementMethod(new ScrollingMovementMethod());
Log.v("TAG", "updating textview");
//textView.append(msg+"\n");
textView.append(Html.fromHtml(msg));
textView.append("\n");
Log.v("TAG", "updated textview");
ScrollView sc= (ScrollView)findViewById(R.id.scrollView1);
sc.fullScroll(View.FOCUS_DOWN);
}
});
}
how does the received string look like:
LogCat:
PS. on the other side the windows device receives all of the massages correctly.
I just created 1 simple C# app reading data from serial port (baudrate 57600). When I send file data from another computer through serial port, CPU worked >90%. How can I solve that ?
EDIT:
private void btn_Start_Click(object sender, EventArgs e)
{
if (temp_portname != null)
{
//ポート設定
SerialPort.PortName = PORT1;
SerialPort.BaudRate = 57600;
//ポートを開く
try
{
SerialPort.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I wrote a message last week but would like to add another more simple question again to clarify.
I have a serial port console application. There are 20 virtual ports. My application successfully working but doesnt change received data value until I restart the application. I am not sure why it happens.
This issue appeared after FIFO enabled property was set to true.
How can i refresh serial port?
Thanks
--- here is the codes :
static void serialportinstances()
{
for (int ix =1; ix < 20; ix++)
{
if (sportlar.ContainsValue("COM"+ix.ToString()) ==false)
{
try
{
SerialPort ekle = new SerialPort("COM" + ix.ToString(), 1200, Parity.None, 8, StopBits.One);
//ekle.DtrEnable = true;
//ekle.RtsEnable = true;
try
{
ekle.NewLine = "\r";
ekle.Open();
ekle.DataReceived += new SerialDataReceivedEventHandler(datareceived);
Console.WriteLine(String.Format("Dinamik SP {0} başarıyla açıldı", ekle.PortName));
}
catch (Exception eu)
{
Console.WriteLine(String.Format("Dynamic SP {0} açılamadı!", ekle.PortName));
}
sportlar.Add(ekle, "COM" + ix.ToString());
}
catch (Exception ee)
{
Console.WriteLine("port could not be created");
}
}
}
}
and datareceiving handler ;
static void datareceived(object sender, SerialDataReceivedEventArgs e)
{
lock (mylockobject)
{
SerialPort spn = (SerialPort)sender;
try
{
string s = spn.ReadLine();
GetWeightPWI(spn.PortName, s);
Thread.Sleep(1);
}
catch (Exception ee)
{
Console.WriteLine("error : " + ee.ToString());
}
}
}
and parsing the received data here :
private static void GetWeightPWI(string portadi, string alinan)
{
Console.WriteLine("PORT NAME : "+portadi+" and received data : "+alinan.toString());
}
I am writing an application to send/receive some data to and from a server. I need to make a connection before sending some data and need to keep it open so that user can send data continuously. The user can close the connection at any time by clicking on disconnect button. I created 2 buttons, one to connect and one to disconnect.
Code behind Disconnect button is as below:-
private void button1_Click(object sender, EventArgs e)
{
if (tcpclnt.Connected)
{
tcpclnt.Client.Disconnect(false);
stm.Close();
}
else
{
MessageBox.Show("Not Connected");
}
}
code behind connect button is as below:-
public ASCIIEncoding asen = new ASCIIEncoding();
public TcpClient tcpclnt = new TcpClient();
public NetworkStream stm;
private void Connect_Click(object sender, EventArgs e)
{
if (!tcpclnt.Connected)
{
tcpclnt.Connect("XX.XX.XX.XX", 5500);
MessageBox.Show("Connected to server");
stm = tcpclnt.GetStream();
string sysname = "000B0000" + SystemName.Text.ToString();
byte[] sys1 = asen.GetBytes(sysname);
sys1[0] = 0; sys1[1] = 0;
sys1[2] = 0; sys1[3] = 0xB;
sys1[4] = 0; sys1[5] = 0;
sys1[6] = 0; sys1[7] = 0;
try
{
stm.Write(sys1, 0, sys1.Length);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
MessageBox.Show("Error in Sending data");
}
if (stm.DataAvailable)
{
try
{
byte[] bb = new byte[600];
int k = 8;
k = stm.Read(bb, 0, bb.Length);
string value = ASCIIEncoding.ASCII.GetString(bb, 8, k - 8);
MessageBox.Show(value.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
MessageBox.Show("Error in Reading data");
}
}
}
else {
MessageBox.Show("Already Connected");
}
}
Now, when I click on Disconnect button and again click on connect button, it's throwing an exception on tcpclient.connect line. I don't understand why or how can I solve it.
Not an expert on this topic, but I think a possible solution would be to gracefully close the connection using tcpclnt.Close(). If you don't do this or let the garbage collector do it ungracefully, then you can't reconnect (I think). Close the stream, then close the tcpclnt rather than disconnect.
tcpclnt.GetStream().Close();
tcpclnt.Close();
Also, don't use tcpclnt.Connected to check if there's a connection. Just simply Close it.
EDIT
The above doesn't work. I don't know how to reuse the socket. This is how I got it to work...
private void DisconnectButton_Click(object sender, EventArgs e)
{
tcpclnt.Close();
tcpclnt = new TcpClient();
}
You mentioned that re-instantiating the object creates additional threads. This might be true as I'm unsure how to test for this. I opened up the windows resource monitor and watched the thread count for the app and it didn't show an additional thread opening each time.
Your .Disconnect() call needs to have true as the parameter to allow reuse. You currently are telling the socket to disallow reconnection. See here for the documentation.