I am trying to access RFID Reader through Arduino application which gives me the right output on control monitor.
But when I tried to access it through visual studio C#, it works only once and then gives me access is denied! And also stopped working on Arduino IDE.
//Function to initialize serial port
SerialPort RFIDPort
public SerialPort initializeRFIDPort()
{
try
{
RFIDPort = new SerialPort("COM4",9600,Parity.None,8, StopBits.One);
if (RFIDPort.IsOpen)
RFIDPort.Close();
if(!RFIDPort.IsOpen)
RFIDPort.Open();
}
catch (UnauthorizedAccessException ex) {MessageBox.Show( ex.Message); }
catch (Exception)
{
RFIDPort = null;
}
return RFIDPort;
}
I put the function here:
public products()
{
InitializeComponent();
initializeRFIDPort();
}
There is two scan button the first one for scanning and then add data to the database and the second button is to scan and search for data
private void ScanButton_Click(object sender, EventArgs e)
{
try
{
scanButtonIsClicked = true;
if (RFIDPort.IsOpen)
{
RFIDPort.DataReceived += serialPort1_DataReceived;
textBox1.Text = "";
}
else
MessageBox.Show("RFID Reader is not connected!");
}
catch (System.Exception)
{
MessageBox.Show("Please Try Again");
}
}
private void Searchbutton_Click(object sender, EventArgs e)
{
scansearchbtn = true;
scanButtonIsClicked = false;
try
{
if (RFIDPort.IsOpen)
{
RFIDPort.DataReceived += serialPort1_DataReceived;
textBox2.Text = "";
}
else
{
MessageBox.Show("RFID Reader is not connected!");
}
}
catch (IOException)
{
MessageBox.Show("Please reconnect your device ");
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
string line = RFIDPort.ReadLine();
if (scanButtonIsClicked == true)
this.BeginInvoke(new LineReceivedEvent(LineReceived), line);
else
this.BeginInvoke(new LineReceivedEvent(Line2Received), line);
}
catch (TimeoutException) { }
catch (Exception){ MessageBox.Show("Can't Read from RFID Device.Please try again"); }
}
private delegate void LineReceivedEvent(string line);
private void LineReceived(string line)
{
textBox2.Text = line;
}
private void Line2Received(string line)
{
textBox1.Text = line;
}
And then I closed serial port in Forum-Closing.
Please if anyone can lead me to the right way. I have try many times and it works randomly!
On Aruino side this is my code:
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key;
// Init array that will store new NUID
byte nuidPICC[10];
void setup()
{
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
for (byte i = 0; i < 6; i++)
{
key.keyByte[i] = 0xFF;
}
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
}
void loop()
{
if ( ! rfid.PICC_IsNewCardPresent())
return;
if ( ! rfid.PICC_ReadCardSerial())
return;
// Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType !=
MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K)
{
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++)
{
nuidPICC[i] = rfid.uid.uidByte[i];
}
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
void printHex(byte *buffer, byte bufferSize)
{
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
Related
We need to show a Modal or a Toast notification on an ASP.net page whenever there is a new text file or there is some change in an existing text file. Here is what we've come up with:
private string htmsDir = "C:\\HTMS";
private string htmsDirPath = string.Empty;
FileSystemWatcher watcher;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
watcher = new FileSystemWatcher(htmsDir);
watcher.Filter = "*.txt";
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.EnableRaisingEvents = true;
}
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
String[] lines = System.IO.File.ReadAllLines(e.FullPath);
if (lines.Length < 1)
return;
String line = lines[lines.Length - 1];
int counter = 1;
while (line == null || line.Length < 1)
{
counter++;
if (counter > lines.Length)
break;
line = lines[lines.Length - counter];
}
if (line == null || line.Length < 1)
return;
if (ParseHTMSData(line))
{
UpdateForm();
}
}
catch (Exception) { }
}
private bool ParseHTMSData(string line) {
return true;
}
private void UpdateForm()
{
try
{
Response.Write("this");
}
catch (Exception ex)
{
Common.logger.CreateDBLog(ex.ToString());
}
}
But the problem is functions like Response.Write(); are not working at all! And there is no proper Exception available to start with.
What are we doing wrong? is there any simpler way?
I'm trying to get inputs/outputs from a LCB(lane control board),which in serial. I'm using prolific usb-serial as the interface . I'm new to programming,but i've managed to get send/receive inputs when i shorted pin 2 and 3 of DB9 together . But when i plugged the db9 connector to the LCB , it can send , but not receiving any .
I'm using VS2010 in Windows 10.
Below are my snippets ;
namespace serialPort_wengweng
{
public partial class Form1 : Form
{
byte[] DataReceived = new byte[4096];
byte[] DataTransmitted = new byte[15] { 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15 };
ArrayList ar = new ArrayList();
//------------------------------------LCB input properties here-START------------------------//
String LCBInput;
Boolean i1, i2, i3, i4, i5, i6, i7, i8 = false;
//------------------------------------LCB input properties here-START------------------------//
public Form1()
{
InitializeComponent();
this.serialPort1.DataReceived +=new SerialDataReceivedEventHandler(serialPort1_DataReceived);
}
private void btnConnect_Click(object sender, EventArgs e)
{
Console.Write("Connect button pressed .. ");
//if (serialPort1.IsOpen == true)
//{
//}
//else
// MessageBox.Show("");
if (btnConnect.Text == "Connect")
{
serialPort1.PortName = Convert.ToString(cboPortNames.SelectedItem);
serialPort1.BaudRate = Convert.ToInt32(cboBaudRate.SelectedItem);
serialPort1.DataBits = Convert.ToInt32(cboDataBits.SelectedItem);
serialPort1.DtrEnable = true;
serialPort1.Handshake = (Handshake)Enum.Parse(typeof(Handshake), cboHandshake.SelectedItem.ToString());
serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cboStopBits.SelectedItem.ToString());
serialPort1.RtsEnable = true;
serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cboParity.SelectedItem.ToString());
try
{
if (serialPort1.IsOpen) serialPort1.Close();
serialPort1.Open();
progressBar.Value = 100;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
btnConnect.Text = "Disconnect";
}
else
{
btnConnect.Text = "Connect";
if (serialPort1.IsOpen) serialPort1.Close();
progressBar.Value = 0;
txtTX.Text = String.Empty;
txtRXAll.Text = String.Empty;
txtRXParsing1.Text = String.Empty;
}
Console.WriteLine("Done!");
}
void UpdateTextBox(TextBox objTextBox, String DataParsing)
{
Console.WriteLine("In Update Text Box...");
objTextBox.AppendText(DataParsing);
Console.WriteLine("Done!");
}
void ReceivedData(TextBox objTextBox, String DataParsing)
{
Console.WriteLine("In ReceivedData...");
if (objTextBox.InvokeRequired)
{
this.Invoke(new Action<TextBox, String>(UpdateTextBox), new object[] { objTextBox, DataParsing });
}
Console.WriteLine("Done!");
}
private void PrintValues(ArrayList ar, ComboBox objComboBox)
{
Console.Write("Printing Values... ");
try
{
if (objComboBox.Name == "cboPortNames")
{
foreach (var v in ar)
{
objComboBox.Items.Add("COM" + v);
}
}
else
{
foreach (var v in ar)
{
objComboBox.Items.Add(v);
}
}
}
catch (NotImplementedException nie)
{
Console.WriteLine(nie);
Console.WriteLine("Print Values T.T");
}
Console.WriteLine("Done!");
}
private void Form1_Load(object sender, EventArgs e)
{
Console.Write("In Form Load()");
GetPortNames();
GetBaudRate();
GetDataBits();
GetParity();
GetStopBits();
GetHandshake();
txtTX.Text = ASCIIEncoding.ASCII.GetString(DataTransmitted);
Console.WriteLine("Done!");
}
void GetPortNames()
{
Console.Write("Getting Port Names..");
ar.Clear();
foreach (String s in SerialPort.GetPortNames())
{
ar.Add(s.Substring(3));
}
ar.Sort();
PrintValues(ar, cboPortNames);
cboPortNames.SelectedIndex = 0;
Console.WriteLine("Done!");
}
void GetBaudRate()
{
Console.Write("Getting BaudRate..");
ar.Clear();
ar.Add(110);
ar.Add(300);
ar.Add(1200);
ar.Add(2400);
ar.Add(4800);
ar.Add(9600);
ar.Add(19200);
ar.Add(38400);
ar.Add(57600);
ar.Add(115200);
ar.Add(230400);
ar.Add(460800);
ar.Add(921600);
PrintValues(ar, cboBaudRate);
cboBaudRate.SelectedIndex = 5;
Console.WriteLine("Done!");
}
void GetDataBits()
{
Console.Write("Getting Data Bits..");
ar.Clear();
for (int i = 5; i <= 8; i++)
{
ar.Add(i);
}
PrintValues(ar, cboDataBits);
cboDataBits.SelectedIndex = 3;
Console.WriteLine("Done!");
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.Write("In Data Received ..");
int i = 0;
string dtString="";
string[] dtArray; // data string saving in here
Thread.Sleep(500); // wait data ready
while (serialPort1.BytesToRead > 0) // if data ready in buffer
{
DataReceived[i] = Convert.ToByte(serialPort1.ReadByte()); // read data serial & saving to array byte
i++; // counter buffer
}
if (i == 15 && DataReceived[14]==15)
{
dtString = ASCIIEncoding.ASCII.GetString(DataReceived); // convert array byte to string
dtArray = dtString.Split((char)44); // parsing string data with separator char(44)
ReceivedData(txtRXAll, dtString); // complete receive data show in here
ReceivedData(txtRXParsing1, dtArray[0]); // data first show in here
}
Console.WriteLine("Done!");
}
private void btnExit_Click(object sender, EventArgs e)
{
Console.Write("Button Exit Pressed..");
if (serialPort1.IsOpen == true)
{
MessageBox.Show("Force quit serial port", "Exit", MessageBoxButtons.OK, MessageBoxIcon.Warning);
Application.Exit();
}
else {
Application.Exit();
Console.WriteLine("Serial port closed,quitting app now.");
Thread.Sleep(1000);
}
Console.WriteLine("Done!");
}
private void btnSend_Click(object sender, EventArgs e)
{
Console.Write("Button Send Pressed..");
if (serialPort1.IsOpen)
{
Console.WriteLine("Shoulda write something.");
var collector = new DataCollector("COM6", ProcessMeasurement);
serialPort1.Write(txtTX.Text);
Thread.Sleep(500);
//Console.WriteLine(serialPort1.Read());
}
else {
MessageBox.Show("Not receiving anything", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Console.WriteLine("Done!");
}
private void ProcessMeasurement(List<byte> bytes)
{
Console.WriteLine("In process measurement...");
}
private void GetHandshake()
{
Console.WriteLine("Get Handshake ...");
try
{
ar.Clear();
foreach (String s in Enum.GetNames(typeof(Handshake)))
{
ar.Add(s);
}
PrintValues(ar, cboHandshake);
cboHandshake.SelectedIndex = 0;
}
catch (NotImplementedException nie)
{
Console.WriteLine(nie);
}
}
private void GetStopBits()
{
Console.WriteLine("Get StopBits ....");
try
{
ar.Clear();
foreach (String s in Enum.GetNames(typeof(StopBits)))
{
if (s != "None") ar.Add(s);
}
PrintValues(ar, cboStopBits);
cboStopBits.SelectedIndex = 0;
}
catch (NotImplementedException nie)
{
Console.WriteLine(nie);
}
}
private void GetParity()
{
Console.WriteLine("Get Parity ....");
try
{
ar.Clear();
foreach (String s in Enum.GetNames(typeof(Parity)))
{
ar.Add(s);
}
PrintValues(ar, cboParity);
cboParity.SelectedIndex = 0;
}
catch (NotImplementedException nie)
{
Console.WriteLine(nie);
}
}
}
}
And here is DataCollector class,
namespace serialPort_wengweng
{
class DataCollector
{
private readonly Action<List<byte>> _processMeasurement;
private readonly string _port;
private SerialPort _serialPort;
private const int SizeOfMeasurement = 4;
List<byte> Data = new List<byte>();
public DataCollector(string port, Action<List<byte>> processMeasurement)
{
Console.WriteLine("in Data Collector ..");
_processMeasurement = processMeasurement;
_serialPort = new SerialPort(port);
_serialPort.DataReceived += SerialPortDataReceived;
Console.WriteLine("Done!");
}
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (_serialPort.BytesToRead > 0)
{
var count = _serialPort.BytesToRead;
var bytes = new byte[count];
Console.WriteLine(_serialPort.Read(bytes, 0, count));
AddBytes(bytes);
}
}
private void AddBytes(byte[] bytes)
{
Data.AddRange(bytes);
while (Data.Count > SizeOfMeasurement)
{
var measurementData = Data.GetRange(0, SizeOfMeasurement);
Data.RemoveRange(0, SizeOfMeasurement);
if (_processMeasurement != null) _processMeasurement(measurementData);
}
}
}
}
Hi guys I need your help with my project. I have a 2 textboxes (type string) in a C# program and i need to send this numbers to Arduino using a Serial.Port. So far i got to send one of the values to arduino but it doesn't work very well if I enter "1200" arduino reads and show: 1,2,0,0 i need "1200". How i send 2 values from C# to Arduino? How the arduino will read these values (x and y)?
C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports; // necessário para ter acesso as portas
namespace interfaceArduinoVS2013
{
public partial class Form1 : Form
{
string RxString;
public Form1()
{
InitializeComponent();
timerCOM.Enabled = true;
}
private void atualizaListaCOMs()
{
int i;
bool quantDiferente; //If there are more ports
i = 0;
quantDiferente = false;
//if there are new ports
if (comboBox1.Items.Count == SerialPort.GetPortNames().Length)
{
foreach (string s in SerialPort.GetPortNames())
{
if (comboBox1.Items[i++].Equals(s) == false)
{
quantDiferente = true;
}
}
}
else
{
quantDiferente = true;
}
//it was't detected difference
if (quantDiferente == false)
{
return;
}
//clean comboBox
comboBox1.Items.Clear();
//add all the COMs in the list
foreach (string s in SerialPort.GetPortNames())
{
comboBox1.Items.Add(s);
}
//select the first position
comboBox1.SelectedIndex = 0;
}
private void timerCOM_Tick(object sender, EventArgs e)
{
atualizaListaCOMs();
}
private void btConectar_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen == false)
{
try
{
serialPort1.PortName = comboBox1.Items[comboBox1.SelectedIndex].ToString();
serialPort1.Open();
}
catch
{
return;
}
if (serialPort1.IsOpen)
{
btConectar.Text = "Desconectar";
comboBox1.Enabled = false;
}
}
else
{
try
{
serialPort1.Close();
comboBox1.Enabled = true;
btConectar.Text = "Conectar";
}
catch
{
return;
}
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if(serialPort1.IsOpen == true) // if the port is open
serialPort1.Close(); //close
}
private void btEnviar_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == true) //porta está aberta
serialPort1.Write(textBoxX.Text); //send the text from textboxX
serialPort1.Write(textBoxY.Text);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting(); //read data from serial
this.Invoke(new EventHandler(trataDadoRecebido));
}
private void trataDadoRecebido(object sender, EventArgs e)
{
textBoxReceber.AppendText(RxString);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Arduino Script
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available())
{
char c = Serial.read();
Serial.println(c);
}
}
Reading data through serial port and separating them using strings.
In C#
Add a unique character to starting of 1st box data.
Add a unique character to starting of 2nd box data.
Add a unique character to ending of 2nd box data.
Append two strings and send as single string.
I had a VB example:
Dim WithEvents ADRport As SerialPort = New System.IO.Ports.SerialPort("COM1", 9600, Parity.None, 8, StopBits.One)
msg = "$" & box1.Text & "#" & box2.Text & "*" & vbCrLf
ADRport.Write(msg)
In Arduino:
//--- Wait for the message starting -----
while(Serial.read()!='$');
while (!flag)
{
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
mstr += inChar;
//Serial.write(inChar);
// if the incoming character is a end of line, set a flag
if (inChar == '*')
{
flag = true;
}
}
Seperate strings using
int 1start = int(mstr.indexOf('$'));
int 2start = int(mstr.indexOf('#',numstart+1));
int 2end = int(mstr.indexOf('*'));
text1 = mstr.substring(1start+1,2start);
text2 = mstr.substring(2start+1,2end);
text1.trim();
text1.trim();
Then display it onn lcd/serialport:
lcd.setCursor(0,0);
lcd.print(msg);
Please note that '$' will not get added to the string.
This is what i did, and it worked:
C#
serialPort1.WriteLine(eixver.Text.ToString()+";"+ eixHor.Text.ToString());
Arduino:
int val;
int h, v;
String cont;
void setup() {
Serial.begin(9600);
}
void loop() {
while(Serial.available())
{
char caracter = Serial.read();
cont.concat(caracter);
delay(5);
}
if(cont!="")
{
// Serial.println(cont);
v=cont.substring(0, cont.indexOf(';')).toInt();
h=cont.substring(cont.indexOf(';')+1, cont.length()).toInt();
Serial.print("v=");
Serial.print(v);
Serial.print(" - h=");
Serial.print(h);
cont="";
}
}
I think, this is good for you. C# part:
Connect();
if (serialPort1.IsOpen)
{
double MyInt = ToDouble(lblMixerCase.Text);
byte[] b = GetBytes(MyInt);
serialPort1.Write(b, 0, 1);
double MyInt2 = ToDouble(txtRPM.Text);
byte[] z = GetBytes(MyInt2);
serialPort1.Write(z, 0, 1);
if (MyInt2>1600)
{
MessageBox.Show("Please enter RPM value between 0 and 1600");
}
double MyInt3 = ToDouble(lblCaseRpmSecond.Text);
byte[] p = GetBytes(MyInt3);
serialPort1.Write(p, 0, 1);
double MyInt4 = ToDouble(lblRpmCaseThree.Text);
byte[] s = GetBytes(MyInt3);
serialPort1.Write(s, 0, 1);
serialPort1.Close();
Arduino part:
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (Serial.available() > 0) {
// read the incoming byte:
n = Serial.read();
if (i < 3)
{
number[i] = n;
switch (number[0])
{
case 1:
if (i == 2)
{
switch(number[1])
{
case 1:
openClose();
break;
case 2:
openCloseTwice();
break;
case 3:
openCloseThree();
break;
default:
openCloseIwanted(number[1], number[2]);
break;
}
}
break;
case 2:
if (i == 2)
{
switch(number[1])
{
case 1:
openClose();
break;
case 2:
openCloseTwice();
break;
case 3:
openCloseThree();
break;
default:
openCloseIwanted(number[1], number[2]);
break;
}
}
break;
case 3:
if (i == 2)
{
openCloseIwanted(number[1], number[2]);
}
break;
default:
if (i == 2)
{
openCloseIwanted(number[1], number[2]);
}
break;
}
i++;
if (i == 3)
{
asm volatile (" jmp 0"); //For reset Arduino
}
}
else
{
i = 0;
}
}
I've trying to communicate with an Arduino Due in C#. The communikation works quite well, but my DataReceived handler needs about 1 second to react. This is my problem because I have to send up to 1 billion (1*10E9) commands.
If I activate a DEBUG Setting in the Arduino, it tells me that it's need 64 Milliseconds for a command. I think the C# the App should get it no later than 80 Milliseconds after sending it.
Here is a Part of the Code:
StopWatch s1 = new StopWatch();
private void Open_Port()
{
string port = null;
int baud = 0;
bool ERR = false;
if ((COM_cb.SelectedItem != null) | (BAUD_cb.SelectedItem != null))
{
port = this.COM_cb.GetItemText(this.COM_cb.SelectedItem);
baud = Convert.ToInt32(this.BAUD_cb.GetItemText(this.BAUD_cb.SelectedItem));
ERR = false;
}
else
{
ERR = true;
System.Windows.Forms.MessageBox.Show("Error Msg");
}
if (ERR == false)
{
serialPort1.PortName = port;
serialPort1.BaudRate = baud;
serialPort1.Open();
}
if (serialPort1.IsOpen)//Kalibrieren der Buttons
{
OPEN_btn.Enabled = false;
CLOSE_btn.Enabled = true;
textBox1.ReadOnly = false;
ERR = true;
}
}
private void Print_Click(object sender, EventArgs e) // start
{
Thread t = new Thread(transmit_pic);
t.Start();
}
private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
s1.Stop();
//Till this line it take 1 Second after sending
//string t = "";
int byt = serialPort1.BytesToRead;
byte[] buffer = new byte[1];
for (int i = 0; i < byt; i++)
{
serialPort1.Read(buffer, 0, 1);
if(buffer[0] == '0') {
got_answer = true;
}
//t += (char)buffer[0];
}
//RxString= t;
//this.Invoke(new EventHandler(DisplayText));
}
private void sendAktion(int[,] data)
{
string s = int_to_string(data, false);
Console.Write("Send->");
serialPort1.Write(s);
s1.Start();
got_answer = false;
int i = 0;
while (!got_answer) { i++; } //wait for answer
i = 0;
Console.WriteLine("back again ");
}
private void transmit_pic()
{
stop = false;
Bitmap bm = new Bitmap(img);
if (!serialPort1.IsOpen)
{
MessageBox.Show("Open the Serial Port first!");
}
else
{
int size_X = bm.Width;
int size_Y = bm.Height;
for (int h = 0; h < size_Y; h++)
{
for (int w = 0; w < size_X; w++)
{
if(/*somthing happend*/){
//get data...
sendAktion(data)
}
}
}
Console.WriteLine("DONE");
}
}
Does anyone an Idea why c# needs so long to call the datahandler?
Sincere regards,
Fabian Harmsen
UPDATE
- Added comment to DataHandler (24.02.2016 16:30 Europa/Berlin)
The problem lies in the serialPort1_DataReceived received data handler.
I ran a separate thread with a while(true) loop and serial.ReadLine(), all works perfectly.
Hope someone else doesn't need to spend 3 hours fixing this.
using System.Threading;
public void main()
{
setup();
Thread readThread = new Thread(Read);
readThread.Start();
}
public void Read()
{
while(true)
{
try
{
string message = serialPort1.ReadLine();
}
catch (Exception)
{ }
}
I created an OPC client to connect to KepServerEX, I got realtime data from KepServerEX and now I want to add realtime data to user control that contains a textbox.
Realtime data will be updated via value_changed event.
I created Windows Form Application and added textbox to Form to display realtime value, I can not post images here.
This is my code:
namespace OPC_Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
OPCServer KepServer;
OPCGroups KepGroups;
OPCGroup KepGroup;
OPCItems KepItems;
OPCItem KepItem;
string strHostIP = "";
string strHostName = "";
bool opc_connected = false;
int itmHandleClient = 0;
int itmHandleServer = 0;
private bool CreateGroup()
{
try
{
KepGroups = KepServer.OPCGroups;
KepGroup = KepGroups.Add("OPCDOTNETGROUP");
SetGroupProperty();
KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
KepItems = KepGroup.OPCItems;
}
catch (Exception)
{
return false;
}
return true;
}
private void SetGroupProperty()
{
KepServer.OPCGroups.DefaultGroupIsActive = true;
KepServer.OPCGroups.DefaultGroupDeadband = 0;
KepGroup.UpdateRate = 1000;
KepGroup.IsActive = true;
KepGroup.IsSubscribed = true;
}
private void RecurBrowse(OPCBrowser OPCBrowser)
{
OPCBrowser.ShowBranches();
OPCBrowser.ShowLeafs(true);
listBox1.Items.Clear();
foreach (object turn in OPCBrowser)
{
bool bl = turn.ToString().Contains("System") ;
if (bl == false)
{
if (!Regex.IsMatch(turn.ToString(), #"^(\w+\.\w+\.\w+)$"))
{
}
else
{
listBox1.Items.Add(turn.ToString());
}
}
}
}
private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
{
try
{
KepServer.Connect(remoteServerName, remoteServerIP);
}
catch (Exception ex)
{
MessageBox.Show(""+ex);
return false;
}
return true;
}
// Write the TAG value when executed event
void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
lblState.Text = "";
for (int i = 1; i <= NumItems; i++)
{
lblState.Text += "Tran:" + TransactionID.ToString() + " CH:" + ClientHandles.GetValue(i).ToString() + "Error:" + Errors.GetValue(i).ToString();
}
}
void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
for (int i = 1; i <= NumItems; i++)
{
if (Qualities.GetValue(i).ToString() == "192")
{
// add realtime value to texbox to display
txtTagValue.Text = ItemValues.GetValue(i).ToString();
txtQualities.Text = Qualities.GetValue(i).ToString();
txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
}
else
{
MessageBox.Show("disconnected to opc server");
txtQualities.Text = Qualities.GetValue(i).ToString();
txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (itmHandleClient != 0)
{
Array Errors;
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandle = (Array)temp;
KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
}
itmHandleClient = 1;
KepItem = KepItems.AddItem(listBox1.SelectedItem.ToString(), itmHandleClient);
itmHandleServer = KepItem.ServerHandle;
}
catch (Exception err)
{
itmHandleClient = 0;
txtTagValue.Text = "Error ox";
txtQualities.Text = "Error ox";
txtTimeStamps.Text = "Error ox";
MessageBox.Show("The reserved for system entry:" + err.Message, "message");
}
}
private void Form1_Load(object sender, EventArgs e)
{
//GetLocalServer();
KepServer = new OPCServer();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (!opc_connected)
{
return;
}
if (KepGroup != null)
{
KepGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
}
if (KepServer != null)
{
KepServer.Disconnect();
KepServer = null;
}
opc_connected = false;
}
private void btnSetGroupPro_Click(object sender, EventArgs e)
{
SetGroupProperty();
}
private void btnConnLocalServer_Click(object sender, EventArgs e)
{
try
{
if (!ConnectRemoteServer(txtRemoteServerIP.Text.Trim(), "KEPware.KEPServerEx.V5"))
{
return;
}
btnSetGroupPro.Enabled = true;
opc_connected = true;
GetServerInfo();
RecurBrowse(KepServer.CreateBrowser());
if (!CreateGroup())
{
return;
}
}
catch (Exception ex)
{
MessageBox.Show("" + ex);
}
}
private void btnWrite_Click(object sender, EventArgs e)
{
OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
int[] temp = new int[2] { 0, bItem.ServerHandle };
Array serverHandles = (Array)temp;
Object[] valueTemp = new Object[] { "", txtWriteTagValue.Text };
Array values = (Array)valueTemp;
Array Errors;
int cancelID;
KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
GC.Collect();
}
}
}
Now I want to create some User Controls to display some tag values.What should I do?
This is a pretty big topic in itself, but I have implemented such a beast a few years back in C#, also using KepServerEx.
Without seeing your code it's a bit difficult for me to understand what you have done so far, but the general idea is that you want to handle the OPCGroup.DataChange event. From there you have to "dispatch" the changed value to the proper TextBox.
Of course, you have to setup your OPCServer, your OPCGroup(s) and so on.
I created a library for this, and it was some extensive work required, so I'm afraid it can't really be answered in one Q&A like here.
If you have a very specific question, please open another one and I'll try to answer more specifically.
Cheers