我正在尝试制作一个机器人。我需要大约6个arduino以太网连接到连接到计算机的思科集线器。我的c#代码是基于线程的,因此它可以处理多个客户端。工作完成后,服务器断开连接,然后客户端重新连接。客户端连接-disconnect-reconnect 100ms。在此,arduino以太网不断发送和接收数据。所有连接都在端口23上进行。每个客户端都有不同的ipaddress。
问题:
最初,当我启动服务器时,它们全部连接但几秒后其中一个冻结3-4秒,之后它会连接但是当它重新连接时,其他一些将处于冻结状态。
如果我将arduino代码的延迟从100ms增加到400ms,所有这些都得到连接n工作正常。但对于我的机器人过程,我需要它在100ms工作。
我无法弄清楚aduino以太网这种奇怪行为的原因。已完成所有基本测试,并在某处感受到arduino问题。
以下是我的c#和我的arduino代码(所有6个代码都相同,只是数据发送和接收不同)
C#代码:
using System.Threading;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace client_server_demo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// input data is stored into s
string receiving_data = "";
int port_no = 23;
// the index of %
int receiving_data_length;
// sonar sensors data
int[] sonar_sensor_data = { 0, 0, 0, 0 };
bool[] limit_switch = { false, false, false, false };
// data to arduinos
string sending_data = "";
byte[] c1;
//store ipaddress of connected client
string ipaddress_client = "";
//error msg of disconnection
string disconnect_error = "";
/// <summary>
/// start of the form
/// </summary>
public MainWindow()
{
InitializeComponent();
Thread tcpthread = new Thread(new ThreadStart(tcpserverRun));
tcpthread.Start();
}
/// <summary>
/// connects to the clients on port 23
/// </summary>
private void tcpserverRun()
{
TcpListener tcplistener = new TcpListener(IPAddress.Any, port_no);
updateUi("listening");
tcplistener.Start();
while (true)
{
TcpClient client = tcplistener.AcceptTcpClient();
updateUi("connected");
//for multiple clients use thread
Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcphandler));
tcpHandlerThread.Start(client);
}
}
private void tcphandler(object client)
{
try
{
TcpClient mclient = (TcpClient)client; // create client
Socket so = mclient.Client; // create a socket so as to get the ipaddress of the client
NetworkStream stream = mclient.GetStream();
//read data from the port
byte[] message = new byte[100];
stream.Read(message, 0, message.Length);
receiving_data = Encoding.ASCII.GetString(message);
receiving_data_length = receiving_data.IndexOf('%');
//remove garbage ahead of %
receiving_data = receiving_data.Substring(0, receiving_data_length + 1);
//get ipaddress of the client connected
ipaddress_client = (IPAddress.Parse(((IPEndPoint)so.RemoteEndPoint).Address.ToString())).ToString();
// show the string on ui -> ip addres+ data
updateUi(ipaddress_client + " : " + receiving_data);
//send data
if (receiving_data == "R%")
{
//send to the arduino
sending_data = "Welcome client 1 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
if (receiving_data == "S%")
{
sending_data = "Welcome client 2 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
if (receiving_data == "L%")
{
sending_data = "Welcome client 3 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
if (receiving_data == "T%")
{
sending_data = "Welcome client 4 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
if (receiving_data == "J%")
{
sending_data = "Welcome client 5 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
if (receiving_data == "A%")
{
sending_data = "Welcome client 6 %";
ASCIIEncoding asen = new ASCIIEncoding();
c1 = asen.GetBytes(sending_data);
stream.Write(c1, 0, c1.Length);
}
//clos al the streams and client so as to avaoid memory leakage
stream.Flush();
stream.Close();
mclient.Close();
}
catch (Exception e)
{
updateException(e.StackTrace);
}
}
/// <summary>
/// for updating the form as per data received from the clients
/// </summary>
/// <param name="s"></param>
private void updateUi(string s)
{
Func<int> del = delegate()
{
textBox1.AppendText(s + System.Environment.NewLine);
label1.Content = "connected";
label2.Content = "";
textBox1.ScrollToEnd();
return 0;
};
Dispatcher.Invoke(del);
}
/// <summary>
/// for showing if any error occurred
/// </summary>
/// <param name="s"></param>
private void updateException(string s)
{
Func<int> del = delegate()
{
label1.Content = "";
label2.Content = "Error : " + s;
return 0;
};
Dispatcher.Invoke(del);
}
}
在arduino代码中,在led的帮助下,我知道它是否接收数据。如果计时器没有从服务器获得数据,那么它会保持跟踪,然后它会保持指示灯亮起。否则它会闪烁。如果未连接到服务器,它将关闭。
arduino code:
#include "Wire.h"
#include "I2Cdev.h" // libraries
#include <SPI.h>
#include <Ethernet.h>
#include <SimpleTimer.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
}
;
char server[] = "192.168.0.50"; //ipaddress of the joystick ethernet
IPAddress ip(192, 168, 0, 53); //ipaddress of this ethernet
EthernetClient client;
char inChar; //for reading bytes received from the server
String inputString = "";
int cleaning_state=0; //for getting the mode selected
int firstcomma=0,secondcomma=0; //for separating data
SimpleTimer timer; //for timer
int received_full_string=0; //to indicate where full data is recieved or not where 0= partial data 1= full data
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
Ethernet.begin(mac, ip);
delay(1000);
if (client.connect(server, 23)) // if client is connected on server 24
{
Serial.write("como");
}
else
{
Serial.write("disconn");
}
//cal a timer every 1s
timer.setInterval(1000, RepeatTask);
}
void loop() {
timer.run(); //start the timer
//chek if client is connected if not than try to reconnect otherwise read data from it
if (client.connected())
{
client.print("R%"); //for handshaking
while(client.available()>0)
{
inChar = (char)client.read();
inputString += inChar; //concat for string
if(inChar == '%')
{
Serial.println(inputString);
received_full_string=1; //indicating full data is recieved
digitalWrite(9, HIGH); // blink the led if received full data
// further processing
}
}
delay(10);
}
else
{
client.stop();
Serial.write("disconnected");
delay(10);
if (client.connect(server, 23))
{
Serial.write("re-connected");
}
}
delay(100);
//if full data is received than while exiting the loop make led turn off
if(received_full_string == 1)
{
digitalWrite(9, LOW);
}
inputString="";
}
//when timer is called check if the full data is received if yes than make the received_full_string=0 if no than stop the process
void RepeatTask()
{
if(received_full_string == 1)
{
received_full_string=0;
}
else
{
Serial.println("stop");
digitalWrite(9, HIGH);
}
}
任何形式的帮助将不胜感激。 感谢
答案 0 :(得分:0)
问题解决了它不是c#代码也没有arduino代码错误它是mac地址。 每个arduino以太网都需要有唯一的ip和mac地址