I have a number of buttons which flicker at different frequencies in my Wondows Form Application. When a specific frequency is measured on the head by an electrode, the signal undergoes signalprocessing in MATLAB, hereafter the frequency found are sent to the application, where the specific value from the UDP connection should press the button which have this specific flickering frequency. I am a bit lost how to create this button handler, using the data I get from Matlab. My thought is:
Value from connection ->
if value == 6
{
button1 is clicked
}
elseif value == 6.5
{
button2 is clicked
}
and so forth.
Any ideas any one ?
if(returnData == String.Empty)
{
}
else
{
button2.PerformClick();
}
Here the returnData is the ongiong incomming data from the UDP connection to MATLAB, you this would work ?
And for another question, I am having a bit of trouble with UDP connection, I would like if it could receive the data I am sending, right now, I have to press a button to open and recieve data, I have made it like this, because I could not update the data otherwise. In mind, I am a novice to 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.Net.Sockets;
using System.Net;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
//public UdpClient receivingUdpClient = null;
public string returnData;
//public byte[] Receive(ref IPEndPoint remoteEP);
// private Print print = null;
//while (true)
//{
public UdpClient receivingUdpClient = new UdpClient(8051);
//bool done = false;
//Creates an IPEndPoint to record the IP Address and port number of the sender.
// The IPEndPoint will allow you to read datagrams sent from any source.
//while (true)
//{
public IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8051);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Visible = false;
label2.Visible = false;
}
void button1_Click(object sender, EventArgs e)
{
label1.Visible = false;
try
{
//while (true)
//{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("This is the message you received " +
returnData.ToString());
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
// }
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
}
if(returnData == String.Empty)
{
}
else
{
button2.PerformClick();
}
}
void button2_Click(object sender, EventArgs e)
{
if (SPELL.Text == String.Empty)
{
SPELL.Text = SPELL.Text + returnData;
label1.Visible = true;
}
else
{
SPELL.Text = null;
SPELL.Text = SPELL.Text + returnData;
label1.Visible = true;
label2.Visible = true;
}
}
}
}
This is my small test program in VIsual Studio so far.
Thanks.
If you want to simulate a button click from code behind, you could simply call the button's handler wherever you want the call to be made.
E.g.
if (value == 6)
{
this.button1_click(this,new EventArgs()) //button1 is clicked
}
else if (value == 6.5)
{
this.button2_click(this,new EventArgs()) //button2 is clicked
}
I'd recommend you better move the button handler's logic to a separate method and call the method instead of calling the handler directly.
Related
I have a problem and none of my fellow colleagues are willing to help me so I'm asking someone if he can help me -
I have a project on c# forms to create a client (the lecturer gave us the python code of the server - just passing the data from player to player) that will play a game of cards with another client(player).
the player clicks on a card and it randomly chooses a card and send it to the server in a specific protocol.
The first message from the first player who clicks on the card is sent and received fine.
The problem is shown after the second player clicks on a card -
he sends the data to the server, BUT the second player receives a byte array of zeros - 0000.
I've been searching for answers but didn't found and I'm really desperate. Can someone help me please.
Client Code which I wrote :
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.Net.Sockets;
using System.Net;
using System.Resources;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
namespace HW6_GuyYoffe
{
public partial class Form1 : Form
{
//connection
bool connected, connectionSucceed = false;
TcpClient client;
NetworkStream clientStream;
byte[] buffer = new byte[MSG_SIZE];
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), PORT_NUMBER);
//game
public int ansFromUser = 0;
string oppCard, userCard;
int userScore = 0, oppScore = 0;
bool cardChosen;
readonly object key = new object();
public Form1()
{
//creates the form
}
//generate card images on the screen
private void GenerateCards(int numOfCards, int startX, int startY)
{
//creates the cards on the screen
}
// called when user clicks a card
private void ClickOnCard(System.Windows.Forms.PictureBox currentPic)
{
//code...
buffer = new ASCIIEncoding().GetBytes("1" + userCard); //usercard - the random card of the current user
clientStream.Write(buffer, 0, buffer.Length);//send to server the chosen card
clientStream.Flush();
Array.Clear(buffer, 0, buffer.Length);
lock (key)
{
cardChosen = true;
Monitor.Pulse(key);
}
}
//called when form is created
public void PlayGame(object sender, EventArgs e)
{
client = new TcpClient();
ansFromUser = OK;
StartThread();
}
//main function
private void TalkToServer(IPEndPoint serverEndPoint)
{
if (ansFromUser != CLOSE_PROGRAM)
{
if (!connected)
ConnectToServer(serverEndPoint); //connect to server - pretty obvious
if (ansFromUser == CLOSE_PROGRAM)
{
BeginInvoke((MethodInvoker)delegate { this.Dispose(); });
return;
}
do
{
int bytesRead = 0;
try
{
Array.Clear(buffer, 0, buffer.Length);
bytesRead = clientStream.Read(buffer, 0, 4); //waits for 4 bytes from server
//// HERE is the problem - in the second time a clients sends his pick the buffer is 0000 - [0,0,0,0]
}
catch (Exception err3)
{
///error
}
if (bytesRead > 0)
{
string input = new ASCIIEncoding().GetString(buffer); //converts byte array to string
if (!connected)
{
if (input == "0000") //start game message
{
//starts game
}
else
{
//error
}
}
else
{
if (input == "2000") //end game message
{
ansFromUser = CLOSE_PROGRAM;
this.Dispose();
}
else if (input[0] == '1')//recieving the opponent's card
{
oppCard = input.Substring(1); //without the message type
int result = OpponentCard();
userScore += result;
oppScore -= result;
}
else
{
//error
}
}
else
{
///error
break;
}
}
Array.Clear(buffer, 0, buffer.Length);
} while (ansFromUser == OK); //while answer isn't end
}
}
//uses another form. Shows the error that have occurred and asks the user if he wants to try again. If so - tries again
private void ErrorMsgBox(string errorDetails)
{
ErrorBox errMsgBox = new ErrorBox(this, errorDetails);
errMsgBox.ShowDialog();
}
private void ConnectToServer(IPEndPoint serverEndPoint)
{
// connect to server
}
private int OpponentCard()
{
const int WIN = 1;
const int TIE = 0;
const int LOOSE = -1;
int result;
lock (key)
{
while (!cardChosen) //wait until opponent and user chose cards
Monitor.Wait(key);
Monitor.Pulse(key); //card is chosen
cardChosen = false; //reset
}
int oppCardNum = int.Parse(oppCard.Substring(0, 2));
int userCardNum = int.Parse(userCard.Substring(0, 2));
//...
result = oppCardNum < userCardNum ? WIN : (oppCardNum == userCardNum ? TIE : LOOSE); //returns the result
return result;
}
private void StartThread()
{
if (ansFromUser != CLOSE_PROGRAM)
{
Thread serverStart = new Thread(() => TalkToServer(serverEndPoint)); //passing the thread the parameters
serverStart.Start();
}
}
}
}
and if someone wants to see - the python server code -
import socket
import select
import Queue
PORT = 8820
HOST = '127.0.0.1'
server = socket.socket()
server.setblocking(0)
server.bind((HOST,PORT))
client = []
while True:
print "new game loop"
clients_connected = 0
server.listen(2)
#Sockets from which we expect to read or write to
inputs = [server]
#waiting for both the connextion to be established
while clients_connected < 2:
readable, writeable, exceptional = select.select(inputs,inputs,inputs)
#handle inputs
for s in readable:
if s is server:
#A readable server socket is ready to accept a connection
conn, addr = s.accept()
print "one connection has been established"
conn.setblocking(0)
inputs.append(conn)
clients_connected = clients_connected + 1
else:
data = s.recv(4)
if not data:
#Interpert empty result as closed connection
print "closing"
#stop listening for input and output
inputs.remove(s)
s.close()
clients_connected = clients_connected - 1
print "both connections has been established"
inputs.remove(server)
initiated = 0
#making sure both of the clients got initializtion message "0000"
while initiated < 2:
readable, writeable, exceptional = select.select(inputs,inputs,inputs)
for s in writeable:
s.send("0000")
initiated = initiated + 1
print "game started"
#Main loop - forwarding messages between the clients
while inputs:
readable, writeable, exceptional = select.select(inputs,inputs,inputs)
#handle inputs
for s in readable:
if s is server:
print "ERROR! can't initiate another connection after the game has been started!"
#Recieve data from the client
data = s.recv(4)
if data:
#A readable client socket has data
print "recieved",data,"from",s.getpeername()
if data != "0000":
#making sure the data isn't initialization message, in case it is the sever will ignore it
#broadcast the recived message:
for o in inputs:
if o is not s:
o.send(data)
else:
#Interpert empty result as closed connection
print "closing"
#stop listening for input and output
inputs.remove(s)
s.close()
for s in exceptional:
print "handling exceptions for",s.getpeername()
inputs.remove(s)
s.close()
HOPE SOMEBODY WILL SEE THIS AND HELP ME...
I have a class defined to get live capture from a camera, and a form button "END CAPTURE" that should halt the capture; and an typical Application.Exit() button.
However, for some reason the while loop as shown below doesn't load the form even when the condition is met. To debug this, I commented out the while loop to see if it snaps at least 1 image; and it does (as shown in fig). What makes the while loop not to load the form and show the output continuously ?
while (!terminated)
{
// CAMERA ACQUISITION CODE
}
Figure of single while loop run:
Full program for reference:
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.Threading;
using mv.impact.acquire;
using mv.impact.acquire.examples.helper;
namespace mv_BlueFoxControl
{
public partial class Form1 : Form
{
private bool button1WasClicked = false;
public Bitmap SnappedBitmap = null;
public static Image PersistentImage = null;
public Form1()
{
InitializeComponent();
mv.impact.acquire.LibraryPath.init(); // this will add the folders containing unmanaged libraries to the PATH variable.
Device pDev = DeviceManager.getDevice(0);// Get a pointer to the first device found
if (pDev == null)
{
Console.WriteLine("Unable to continue! No device found! Press any key to end the program.");
//Console.Read();
Environment.Exit(1);
}
Console.WriteLine("Initialising the device. This might take some time...");
try
{
pDev.open();//start the sensor
Console.WriteLine("Device opened successfully...");
}
catch (ImpactAcquireException e)
{
// throw error code if the same device is already opened in another process...
Console.WriteLine("An error occurred while opening the device " + pDev.serial +
"(error code: " + e.Message + "). Press any key to end the application...");
//Console.ReadLine();
Environment.Exit(1);
}
bool terminated = false;// Bool terminated was here.
Console.WriteLine("Press CAPTURE to end the application");
// create thread for live capture
Thread thread = new Thread(delegate()//Start live acquisition
{
DeviceAccess.manuallyStartAcquisitionIfNeeded(pDev, fi);
Request pRequest = null;
// we always have to keep at least 2 images as the display module might want to repaint the image, thus we
// can free it unless we have a assigned the display to a new buffer.
Request pPreviousRequest = null;
int timeout_ms = 500;
int cnt = 0;
int requestNr = Device.INVALID_ID;
Console.WriteLine(terminated);
while (!terminated)
{
// CAMERA ACQUISITON CODE
}
DeviceAccess.manuallyStopAcquisitionIfNeeded(pDev, fi);
// free the last potential locked request
if (pRequest != null)
{
pRequest.unlock();
}
// clear the request queue
fi.imageRequestReset(0, 0);
// extract and unlock all requests that are now returned as 'aborted'
requestNr = Device.INVALID_ID;
while ((requestNr = fi.imageRequestWaitFor(0)) >= 0)
{
pRequest = fi.getRequest(requestNr);
Console.WriteLine("Request {0} did return with status {1}", requestNr, pRequest.requestResult.readS());
pRequest.unlock();
}
});//End of thread
Console.WriteLine(" End Thread");
thread.Start();
if (button1WasClicked)
{
terminated = true;
}
Console.WriteLine("Program termination");
Console.WriteLine(terminated);
thread.Join();
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
button1WasClicked = true;
}
}
}
Because of thread.Join(); The application will wait that the thread ends (which will not end until you press the button) and so the constructor is never finished.
You have to initialize a Thread field and only close it when you press the button.
Try this:
public partial class Form1 : Form
{
//...
private Thread _cameraThread;
public Form1()
{
//... the previous code
_cameraThread = new Thread(delegate()//Start live acquisition
{
// thread logic
});
_cameraThread.Start();
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
button1WasClicked = true;
//set the flag and wait for the thread to finish
_cameraThread.Join();
Console.WriteLine("Program termination");
}
}
I try to write a UDP-Chat in C#.
I have some unexpected behavoir in my Chat Programm, when I start the programm on two different machines connected to the same Network. At the first mashine the programm works fine it can send and recive messages properly, but on the second machine it can just send messages but it can't recive them.
I testet this with a 3rd mashine too(a VM with a bridged networkinterface), but with the same result, it just can send messages without recieving.
is there a error in my code or is it a desing error?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading;
using System.Net.NetworkInformation;
using System.ComponentModel;
using System.Data;
namespace CScharpChat
{
/// <summary>
/// Interaktionslogik für Chat_window.xaml
/// </summary>
public partial class Chat_window : Window
{
string name = "testuser";
UdpClient receiveClient = new UdpClient(1800);
IPEndPoint receiveEndPint = new IPEndPoint(IPAddress.Any, 0);
public Chat_window(string name)
{
this.name = name;
fileWriter("Chat started", false); // write the initial start date in the errorfile
InitializeComponent();
Message_Load(); // starts the listen server theread
}
private void Message_Load()
{
lb_chat.Items.Add(name + " Joined the room...");
Thread rec = new Thread(ReceiveMessageFn);
rec.Start();
}
private void ReceiveMessageFn()
{
try
{
while (true)
{
Byte[] receve = receiveClient.Receive(ref receiveEndPint);
string message = Encoding.UTF8.GetString(receve);
if (message == name + " logged out...")
{
break;
}
else
{
if (message.Contains(name + " says >>"))
{
message = message.Replace(name + " says >>", "Me says >>");
}
ShowMessage(message);
}
}
//Thread.CurrentThread.Abort();
//Application.Current.Shutdown();
}
catch (Exception e)
{
//errorHandler(e);
}
}
private void ShowMessage(string message)
{
if (lb_chat.Dispatcher.CheckAccess())
{
lb_chat.Items.Add(message);// add Item to list-box
lb_chat.ScrollIntoView(lb_chat.Items[lb_chat.Items.Count - 1]);// scroll down to current Item
lb_chat.UpdateLayout();
}
else {
lb_chat.Dispatcher.BeginInvoke(
new Action<string>(ShowMessage), message); // if list-box is not access able get access
return;
}
}
private void tb_eingabe_GotFocus(object sender, RoutedEventArgs e)
{
tb_eingabe.Text = "";
}
private void btn_submit_Click(object sender, RoutedEventArgs e)
{
submit_message();
}
private void tb_eingabe_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
submit_message();
}
}
void submit_message()
{
if (tb_eingabe.Text != "")
{
string data = name + " says >> " + tb_eingabe.Text;
SendMessage(data);
tb_eingabe.Clear(); // clear the textbox-values
tb_eingabe.Focus(); // get focus on tb if the submit button was used, the tb lost the focus
}
}
private void SendMessage(string data)
{
try{
UdpClient sendClient = new UdpClient();
Byte[] message = Encoding.UTF8.GetBytes(data); // use UTF8 for international encoding
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 1800); // use a broadcast with the given port
sendClient.Send(message, message.Length, endPoint);
sendClient.Close();
}
catch (Exception e)
{
errorHandler(e);
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
string data = name + " logged out...";
SendMessage(data); // send a logout message to the other chat peers
}
// debugging functions
static void errorHandler(Exception errorMsg)
{
MessageBox.Show(errorMsg.ToString()); // create a error-message-box
fileWriter(errorMsg.ToString(), true); // call the file-writer function to write the error in a file
}
static void fileWriter(string fileText, bool append)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(".\\Errorfile.txt", append); // locate the error next to the chat.exe
file.WriteLine(GetTime(DateTime.Now) + "\n " + fileText); // append the date
file.Close();
}
public static String GetTime(DateTime val)
{
return val.ToString("yyyyMMddHHmmssffff"); // return the current date as string
}
}
}
Instead of IPAddress.Broadcast(255.255.255.255) provide your local network broadcast address. See the example below:
IPAddress broadcast = IPAddress.Parse("192.168.1.255"); //replace the address with your local network.
IPEndPoint endPoint = new IPEndPoint(broadcast, 11000);
sendClient.Send(message, message.Length, endPoint);
IPAddress.Broadcast doesn't work in some network.
I'm working on a project that involves my client software sending data to a Arduino microcontroller, AtMega32U4, through serial communication. I've looked through many answered questions so far yet none of them were specific to my problem. However, I believe my problem may be limited to threading issues or Arduino autoreset problems.
Code 1:
public MainForm()
{
InitializeComponent();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.DtrEnable = true;
//serialPort1.RtsEnable = true;
}
private void button3_Click(object sender, EventArgs e)
{
// Disables button while processing
button3.Enabled = false;
GetDir dir = new App.GetDir();
dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + #"\temp2.html", "temp2.xml");
dataBrowser.Navigate(Application.StartupPath + #"\temp2.html");
dataBrowser.Update();
waypoints = dir.coordsLat.Length;
counter = dir.coordsLat.Length;
coords = new double[dir.coordsLat.Length, 2];
for (int i = 0; i < counter; i++)
{
coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
}
//serialPort1.Close();
//System.Threading.Thread.Sleep(1000);
if (serialPort1.IsOpen && !doubleClick)
{
serialPort1.Close();
System.Threading.Thread.Sleep(2000);
try
{
serialPort1.Open();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
System.Threading.Thread.Sleep(2000);
}
else
{
if (!serialPort1.IsOpen)
{
try
{
serialPort1.Open();
doubleClick = true;
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
System.Threading.Thread.Sleep(2000);
serialPort1.Write("^");
System.Threading.Thread.Sleep(1000);
Console.WriteLine('^');
//button3.Enabled = true;
}
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//System.Threading.Thread.Sleep(1000);
readData = serialPort1.ReadLine();
Console.WriteLine(readData);
// If microcontroller sends "&", it is ready to receive next piece of data
if (readData == "&")
{
sendRequest = true;
}
else
{
sendRequest = false;
}
// Write next piece of data to microcontroller if it is ready
if (sendRequest)
{
this.BeginInvoke( new EventHandler (write_serialPort1));
}
}
In during the debugging of code 1, the event handler (serialPort1_DataReceived) never gets called. In this process, somehow button3_click gets called twice as the console outputs '^' twice. Afterwards, the client stalls since there is nothing beind received. Keep in mind that the Arduino will respond with an ampersand ('&') once it has received the circumflex ('^'). The Arduino code has been tested on the Arduino IDE and appears to be working fine. I believe the problem with button3_click being called twice comes from the button3_down and button3_up.
However, I was able to bypass this issue with Code 2. But also hit another brick wall.
Code 2 :
private void button3_Click(object sender, EventArgs e)
{
// Disables button while processing
button3.Enabled = false;
GetDir dir = new App.GetDir();
dir.getCoords(Origin.Text, Destination.Text, Application.StartupPath + #"\temp2.html", "temp2.xml");
dataBrowser.Navigate(Application.StartupPath + #"\temp2.html");
dataBrowser.Update();
waypoints = dir.coordsLat.Length;
counter = dir.coordsLat.Length;
coords = new double[dir.coordsLat.Length, 2];
for (int i = 0; i < counter; i++)
{
coords[i, 0] = (Convert.ToDouble(dir.coordsLat[i]));
coords[i, 1] = (Convert.ToDouble(dir.coordsLon[i]));
}
serialPort1.Close();
try
{
serialPort1.Open();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Cannot open serial port");
}
if (serialPort1.IsOpen)
{
System.Threading.Thread.Sleep(2000);
using (serialPort1)
{
serialPort1.Write("^");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("^");
serialPort1.Close();
System.Threading.Thread.Sleep(5000);
}
}
else
{
button3.Enabled = true;
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//SerialPort sp = (SerialPort)sender;
System.Threading.Thread.Sleep(10000);
/*if (!serialPort1.IsOpen)
{
serialPort1.Close();
System.Threading.Thread.Sleep(10000);
serialPort1.Open();
System.Threading.Thread.Sleep(10000);
}*/
//serialPort1.Open();
//using (sp)
using (serialPort1)
{
serialPort1.Open();
System.Threading.Thread.Sleep(5000);
readData = serialPort1.ReadExisting();
Console.WriteLine(readData);
// If microcontroller sends "&", it is ready to receive next piece of data
if (readData == "&")
{
sendRequest = true;
}
else
{
sendRequest = false;
}
// Write next piece of data to microcontroller if it is ready
if (sendRequest)
{
this.BeginInvoke(new EventHandler(write_serialPort1));
}
}
}
In Code 2, the event handler does get called and the button3_click only runs once. But when it tries to open the port, it returns the error 'Access to Port X denied'. Furthermore, I wish I didn't have to close and open the ports like this, but when the event handler is called (in an earlier code) it returned the error that the COM Port was not opened. In order to satisfy that error, I had to close it and reopen it during button3_click and event handling.
I've added a lot of delay in the code after I read about many problems dealing with the threading issues with serial communication. I had even tried a minute delay in hopes of a thread ending to solve the problem. However, no luck there.
I also specified my serial port in the MainForm designer instead of declaring it in the code (At first I did both and realized it was redundant). I'm not sure if this contributes to the problem, but I've seen examples of both being used.
Lastly, it could definitely deal with the Arduino auto resetting everytime a serial connection has been made (eg. opening and closing a port). In summary, it seems be sending data through serial, but unable to read the incoming data from serial.
Thank you for reading this and if someone could point me in the right direction, it would be very much appreciated.
Edit #1: Even after using BeginInvoke in Code 1, it still deadlocks because the event handler was never called.
Edit #2: Edits to Code 1 as per newbie's suggestions.
Edit #3: Added mainform initialization and updated Code 1 to current state.
Edit #4: Deleted (Commented out) the sleep at the event handler. I was sleeping during the event handler, thus I couldn't receive anything that the microcontroller would send to me. Code works fine as expected now.
Make sure you are using COM1, if you do not COM1 serial port,
change through Computer -> Device Manager -> Ports (COM & LPT) ->
Select the COM to be changed -> Port Settings -> Advanced -> ComPort Number -> select COM1.
Make sure that you have installed jumper / connect with a screwdriver
between pin2 and pin3 of COM1.
Add button1 and textBox1 to Form and run this program
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Text;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
const int MAX_BUFFER = 100;
int i = 0;
byte[] DataReceived = new byte[MAX_BUFFER];
SerialPort serialPort = new SerialPort();
public Form1() {
InitializeComponent();
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
}
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
// wait data ready
Thread.Sleep(500);
// while data ready in buffer
while (serialPort.IsOpen && serialPort.BytesToRead > 0) {
// read data serial
DataReceived[i] = Convert.ToByte(serialPort.ReadByte());
// counter data
i++;
// reset conter if more then maxvalue
if (i >= MAX_BUFFER) {
i = 0;
}
}
if (i == 1 && DataReceived[0] == ASCIIEncoding.ASCII.GetBytes("^")[0]) {
this.textBox1.Invoke(new Action(() => {
this.textBox1.Text = ASCIIEncoding.ASCII.GetString(DataReceived, 0, 1);
}));
}
}
public void InitSerialPort() {
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.ReceivedBytesThreshold = 1;
}
private void Form1_Load(object sender, EventArgs e) {
// initialize serial port
InitSerialPort();
// assure port is closed before open it
if (serialPort != null && serialPort.IsOpen) {
serialPort.Close();
}
serialPort.Open();
}
private void button1_Click(object sender, EventArgs e) {
if (serialPort.IsOpen) {
serialPort.Write("^");
// wait data sent
Thread.Sleep(500);
}
}
}
}
In accordance to my 4th edit, deleted (Commented out) the sleep at the event handler. I was sleeping during the event handler, thus I couldn't receive anything that the microcontroller would send to me. Code works fine as expected now. Nothing was wrong with the serial ports on either components.
Situation:
1. Linux TCP server
2 Windows C# client application
The server receives messages from client, but when I try to send messages from server to the client nothing happens. When I disconnect I get the error:
"Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall." and it points to the line ---> string Response = swRead.ReadLine();
Here is the Client code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace AsynClient
{
public partial class Form1 : Form
{
private TcpClient client;
private StreamWriter swSend;
private StreamReader swRead;
private bool connected = false;
string bojaTekst = "", bojaPoz = "";
private delegate void UpdateLogCallback(string strMessage);
private Thread thrMessag;
public Form1()
{
Application.ApplicationExit += new EventHandler(OnApplicationExit);
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (connected == false)
{
InitializeConnection();
}
else
MessageBox.Show("Vec je uspostavljenja konekcija.");
}
private void InitializeConnection()
{
client = new TcpClient();
client.Connect("192.168.100.82", 3456);
swSend = new StreamWriter(client.GetStream()); //prvo mora da se konektuje, pa onda ova komanda
thrMessag = new Thread(new ThreadStart(ReceiveMessages));
thrMessag.Start();
connected = true;
btnSend.Enabled = true;
btnDisconnect.Enabled = true;
txtMsg.Enabled = true;
btnConnect.Enabled = false;
}
private void UpdateLog(string strMessage)
{
txtServ.AppendText(strMessage + "\r\n");
}
private void ReceiveMessages()
{
swRead = new StreamReader(client.GetStream());
string Response = swRead.ReadLine();
while (connected)
{
// Show the messages in the log TextBox
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { swRead.ReadLine() });
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (listBoxTekst.SelectedIndex == -1)
listBoxTekst.SelectedIndex = 0;
if (listBoxPozadina.SelectedIndex == -1)
listBoxPozadina.SelectedIndex = 0;
bojaTekst = listBoxTekst.Text;
bojaPoz = listBoxPozadina.Text;
SendMessage();
}
private void SendMessage()
{
txtMsg.Text);
if (txtMsg.Lines.Length >= 1)
{
swSend.WriteLine(bojaPoz + "\t" + bojaTekst + "\t" + txtMsg.Text + "\t");
swSend.Flush();
txtMsg.Lines = null;
}
txtMsg.Text = "";
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
char[] quit = new char[5];
quit[0] = 'q'; quit[1] = 'w'; quit[2] = 'w'; quit[3] = 'w'; quit[4] = '\0';
connected = false;
btnConnect.Enabled = true;
btnSend.Enabled = false;
btnDisconnect.Enabled = false;
txtMsg.Enabled = false;
swSend.WriteLine(quit);
swSend.Flush();
swSend.Close();
client.Close();
}
public void OnApplicationExit(object sender, EventArgs e)
{
if (connected == true)
{
connected = false;
swSend.WriteLine("qwww"); //proveri da li radi f-ja kako treba
swSend.Flush();
swSend.Close();
client.Close();
}
}
}
}
The server side receives the messages with the read() function and it works fine, but when it sends with write() the C# client doesn't receive the message.
Just one thing (there mioght be other problems):
You have a connected variable, which value you set to true, after you start your listening thread. The loop within the thread doesnt even run once.
thrMessag = new Thread(new ThreadStart(ReceiveMessages));
thrMessag.Start();
connected = true; //here is your first bug, should come before the previos line