【得捷Follow me第4期】基础任务二:PC通过客户端使用TCPIP或UDP控制主控板
[复制链接]
【得捷Follow me第4期】基础任务二:主控板建立TCPIP或UDP服务器,局域网PC使用TCPIP或UDP客户端进行连接并发送数据,主控板接收到数据后,送液晶屏显示(没有则通过串口打印显示);通过抓包软件抓取交互报文,展示并分析。(TCP和UDP二选一,或者全都操作)
软件开发环境arduino IDE,使用Ethernet库实现以太网初始化和建立UDP服务,在loop函数中检测收到的UDP数据包大小,并推送串口和显示屏,使用TFT_eSPI库实现TFT屏幕初始化和显示。
#include <SPI.h>
#include <TFT_eSPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 0, 7);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
#define TFT_GREY 0x5AEB
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite stext1 = TFT_eSprite(&tft);
void setup() {
Ethernet.init(17);
Ethernet.begin(mac, ip);
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_GREY);
tft.setCursor(0, 0, 2);
tft.setTextColor(TFT_WHITE);
tft.setTextSize(3);
// start UDP
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i=0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBuffer
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
String show ="";
show = "Contents:" + String(packetBuffer);
tft.fillScreen(TFT_GREY);
tft.setCursor(0, 0, 2);
tft.println(show);
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
通过PC发送数据到主控板,并在串口打印
测试数据
收到的信息送TFT屏幕显示
在传递过程中通过wireshark对数据进行抓包,可以看见数据类型,数据长度等信息
在测试的过程中还通过主控板建立了webserve,然后通过PC或者手机等通过http请求来接收收据和控制主控板上的led灯。
代码实现还是通过Ethernet库,根据发送请求的网址信息来做出对应的响应和显示。
代码如下:
#include <SPI.h>
#include <TFT_eSPI.h>
#include <Ethernet.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192,168,0,7);
IPAddress dns(192,168,0,1);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);
EthernetServer server(80);
String request ="";
byte state;
#define TFT_GREY 0x5AEB
TFT_eSPI tft = TFT_eSPI();
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Ethernet.init(17);
Ethernet.begin(mac, ip, dns, gateway, subnet);
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1);
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
tft.init();
tft.setRotation(1);
tft.setTextColor(TFT_WHITE);
tft.setTextSize(3);
tft.fillScreen(TFT_GREY);
tft.setCursor(0, 0, 2);
tft.println(Ethernet.localIP());
tft.setCursor(0, 50, 2);
tft.println("state:");
tft.setCursor(100, 50, 2);
tft.println(0);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an HTTP request ends with a blank line
bool currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
request += String(c);
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
handlerequest();
// send a standard HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("state:"); //响应内容
client.print(state);
client.println("<br />");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
void handlerequest(){
tft.fillScreen(TFT_GREY);
tft.setCursor(0, 0, 2);
tft.println(Ethernet.localIP());
tft.setCursor(0, 50, 2);
tft.println("state:");
if (request.indexOf("state1") > -1) {
state = 1;
}
else if (request.indexOf("state2") > -1) {
state = 2;
}
else if (request.indexOf("state3") > -1) {
state = 3;
}
else {
state = 0;
}
switch(state){
case 0:tft.setCursor(100, 50, 2),tft.println(0);
break;
case 1:tft.setCursor(100, 50, 2),tft.println(1);
break;
case 2:tft.setCursor(100, 50, 2),tft.println(2);
break;
case 3:tft.setCursor(100, 50, 2),tft.println(3);
break;
default:tft.setCursor(100, 50, 2),tft.println(0);
}
request ="";
if (state == 1){
digitalWrite(LED_BUILTIN, HIGH);
}
else{
digitalWrite(LED_BUILTIN, LOW);
}
}
请求地址及相应
主控板串口信息
控制LED灯及TFT的显示
|