我现在正在研究学校项目,我正在寻找最简单的方法来通过ESP8266上的WiFi模块而不是通过SerialPort(COM4)连接C#与ESP8266(我必须使用此方法)。我必须构建一个简单的项目,以便将测量数据从ESP发送到C#,还需要接收我自己定义的控制命令(诸如“ LEDON”,“ LEDOFF”等字符串)从C#到ESP,就像测量项目的远程控制一样。我对C#的了解不高,与服务器/互联网的基本知识一样。我已经用Arduino IDE代码完成了所有工作,但由于使用C#,所以我一直受不了,因为我从来没有在那里编程过。希望您能理解我的英语不好和问题的概念。 :)
编辑:
好吧,所以我在学校项目中做了一些更改,现在我处于这个阶段,需要解决这部分代码。我希望这是完成我的项目的最后一步。我要做的就是解决在以下代码中使用名为“ Writing”的未填充方法将数据从C#写入ESP的问题:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ESP8266
{
public class Projekt
{
public event MessageEventHandler Message;
public delegate void MessageEventHandler(Projekt sender, string Data);
public TcpListener server;
public Thread W_Thread;
public Thread R_Thread;
public bool IsLiserning = true;
public TcpClient client;
public StreamReader clientdata;
public StreamWriter serverdata;
public Projekt()
{
server = new TcpListener(IPAddress.Parse(Dns.GetHostEntry(Dns.GetHostName().ToString()).AddressList[1].ToString()), 5000);
server.Start();
W_Thread = new Thread(new ThreadStart(Writing));
W_Thread.Start();
R_Thread = new Thread(new ThreadStart(Reading));
R_Thread.Start();
}
public void Reading()
{
while (IsLiserning == true)
{
if (server.Pending() == true)
{
client = server.AcceptTcpClient();
clientdata = new StreamReader(client.GetStream());
}
try
{
Message?.Invoke(this, clientdata.ReadLine());
}
catch (Exception){}
}
}
public void Writing()
{
while (IsLiserning == true)
{
if (server.Pending() == true)
{
client = server.AcceptTcpClient();
serverdata = new StreamWriter(client.GetStream());
}
try
{
//NEED_TO_SOLVE_THIS_PART
}
catch (Exception){}
}
}
}
}
也许除了代码的那部分之外还缺少一些东西,你们希望能够对我有所帮助:)谢谢您的所有回答:)
答案 0 :(得分:0)
您可能会看到此project,基本上,您想在arduino和C#之间通过TCP / IP进行通信。将C#视为服务器,将arduino视为客户端。然后他们只需要互相发送消息进行交流即可。
我提供的链接的作用远远超出了需要,因此,如果您迷路了,也许可以从一些非常基本的内容开始,然后看一下here并检查有关c#服务器的链接。与我的第一个链接相比,它们将更易于理解。
[EDIT]好吧,只有链接答案是危险的,而不是最好的,所以这是我通过第一个链接给出的内容的一个非常简短的版本:
您的服务器将具有接收方列表,每个接收方仅处理一个客户端。这是我的一个项目的简化,我希望通过删除很多东西,我不会破坏任何东西:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Windows.Data;
namespace DemoServer.Models
{
public class Server
{
public TcpListener Listener { get; set; }
public int Port { get; set; }
public bool IsStarted { get; private set; }
public List<Receiver> Receivers = new List<Receiver>();
public Server(int port)
{
Receivers.Clear();
BindingOperations.EnableCollectionSynchronization(Receivers, Receivers);
Port = port;
IsStarted = false;
}
public void Start()
{
if (!IsStarted)
{
try
{
Listener = new TcpListener(System.Net.IPAddress.Any, 0);
Listener.Start();
IsStarted = true;
IPAddress address = ((IPEndPoint)Listener.LocalEndpoint).Address;
int port = ((IPEndPoint) Listener.LocalEndpoint).Port;
Console.WriteLine("Server Started");
//Start Async pattern for accepting new connections
WaitForConnection();
}
catch (Exception e)
{
Console.WriteLine(e);
IsStarted = false;
}
}
}
public void Stop()
{
if (IsStarted)
{
Listener.Stop();
IsStarted = false;
Receivers.Clear();
Console.WriteLine("Server Stopped");
}
}
private void WaitForConnection()
{
Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null);
}
private void ConnectionHandler(IAsyncResult ar)
{
if (IsStarted)
{
Receiver newClient = new Receiver(Listener.EndAcceptTcpClient(ar), this);
newClient.Start();
Receivers.Add(newClient);
WaitForConnection();
}
}
public void SomeInteractionBetweenClients()
{
Console.WriteLine("Interaction!");
}
}
}
然后是Receiver代码,您可以在其中真正处理与客户的通信:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
namespace DemoServer.Models
{
public class Receiver : ModelBase
{
bool ConnectionStatus = false;
private uint m_Id = 0;
public uint Id
{
get { return m_Id; }
set => SetAndRaisePropertyChanged(ref m_Id, value);
}
private Thread receivingThread;
private Thread sendingThread;
public Server Server { get; set; }
public TcpClient Client { get; set; }
public List<String> MessageQueue { get; private set; }
public Receiver(TcpClient client, Server server)
{
MessageQueue = new List<String>();
Server = server;
Client = client;
Client.ReceiveBufferSize = 1024;
Client.SendBufferSize = 1024;
ConnectionStatus = true;
}
public void Start()
{
receivingThread = new Thread(ReceivingMethod);
receivingThread.IsBackground = true;
receivingThread.Start();
sendingThread = new Thread(SendingMethod);
sendingThread.IsBackground = true;
sendingThread.Start();
}
private void Disconnect()
{
if (!ConnectionStatus) return;
ConnectionStatus = false;
Client.Client.Disconnect(false);
Client.Close();
}
private void SendingMethod()
{
while (ConnectionStatus)
{
if (MessageQueue.Count > 0)
{
var message = MessageQueue[0];
try
{
NetworkStream clientStream = Client.GetStream();
StreamWriter streamWriter = new StreamWriter(clientStream);
streamWriter.Write(message);
streamWriter.Flush();
Console.WriteLine($"We are sending '{message}' to the client");
}
catch
{
Disconnect();
}
finally
{
MessageQueue.RemoveAt(0);
}
}
Thread.Sleep(30);
}
}
private void ReceivingMethod()
{
while (ConnectionStatus)
{
if (Client.Available > 0)
{
try
{
NetworkStream clientStream = Client.GetStream();
StreamReader streamReader = new StreamReader(clientStream);
char[] puchBuffer = new char[Client.Available];
int iQtt = streamReader.Read(puchBuffer, 0, Client.Available);
string msg = String.Empty;
for (int i = 0; i < puchBuffer.Length; i++)
{
msg = $"{msg}{Convert.ToString(puchBuffer[i])}";
}
OnMessageReceived(msg);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Thread.Sleep(30);
}
}
private void OnMessageReceived(String msg)
{
// Here you can parse the messages coming ffrom the client and do whatever is needed
// If needed, you can even call some public methods from the server to forward some info to an other client for example or just the server:
// eg: Server.SomeInteractionBetweenClients();
}
}
}
我希望这会对交流方面有所帮助。对于GUI,Web上有很多教程,但如果可能的话,我仍然认为WPF / MVVM比winforms更易于学习。
答案 1 :(得分:0)
据我了解,您的项目需要双向沟通。将c#用作服务器并不理想,因为没有简单的方法可以将命令从C#发送到esp8266。我假设您的项目正在使用esp8266作为arduino平台(不将esp8266附加到arduino作为wifi模块),请查看MQTT,它是用于发布和订阅消息的代理。这样esp8266和C#都可以通过MQTT进行编码和通信,达到双向通信的目的。
对于esp8266,您可以在以下位置查看esp8266的arduino MQTT库:https://github.com/knolleary/pubsubclient。