TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇,只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
TCP可以分为服务端(TCP Server)和客户端(TCP Client),服务端就相当于一个服务器,可以允许接入多个客户端接入,接入之后相互之间就可以通过TCP协议进行数据传输。
关于TCP具体的原理介绍就不细说了,本文主要讲解Arduino环境下怎么使用TCP来实现一个无线网络的数据传输。
我们的MCU(esp8266或者esp32)可以作为服务端,也可以作为客户端,看具体的需求来选。这里只讲解PC端作为服务端,MCU这边作为客户端的情况。其他情况举一反三即可。
本文主要实现的功能如下:
1 硬件简介
我这里以ESP8266和ESP32为例讲解,实际上根据自己的MCU选择一种即可,方法和原理都是一样的。
硬件配置如下:
模块 | 型号 | 说明 |
---|---|---|
ESP8266 | ESP-12F | 这是安信可的一款模组,内部主要是用乐鑫的ESP8266EX再加上一个片外FLASH组成,开发板型号是NodeMCU-12F(CH340版本) |
ESP32 | ESP-WROOM-32 | MCU是乐鑫的一款芯片,开发板型号ESP32 DEVKITV1 |
具体的硬件参数和电路原理图这里就不发出来了,不同厂家做的开发板引脚可能会有点差别。
2 Arduino环境搭建
关于Arduino的环境搭建大家应该都懂,这里就不多赘述了,不懂的同学可以参考一下我之前发的博客。
esp8266开发入门教程(基于Arduino)——环境安装
3 建立TCP Server
在PC端测试的时候我们可以使用网络调试工具来建立一个服务端,网络调试工具网上都有很多,我比较习惯用NetAssist和sscom,sscom是串口和TCP一体的,既可以调试串口又可以调试网络,这个还是挺方便的,所以我这里就以sscom为例来讲解吧。
当然了,用这种方式建立的服务器是有限制的,只有同一局域网下的设备能连上这个服务器,如果你有公网服务器那就最好了,可以不受限与局域网。
找不到工具的同学可以到我网盘上下载。
网盘链接:https://pan.baidu.com/s/1cATkEnPX1iIX9U64wrflsw
提取码:1ysz
1)打开sscom,配置端口参数
参数 | 值 |
---|---|
端口号 | TCPServer |
远程 | 不用配置 |
本地 | 选择自己的电脑的本地IP地址,端口任意,如:192.168.43.128, 1234 |
提示:不知道IP地址的可以在网络适配器查找。
2)点击 “侦听”,然后等待client接入
如果有设备连接上,会有提示信息。
当然了,现在这里肯定不会有这个信息,因为我们的设备还没有配置WIFI和TCP client,等后面我们把代码烧录进去就能连上了。
4 编写代码并运行测试
在Arduino IDE的ESP8266和ESP32开发板库里面其实都有TCP相关的示例代码,我在这个示例的基础上做了一点修改,增加了串口和TCP的数据互传。
ESP8266和ESP32的库是不同的,但是TCP相关库函数的基本用法是一样的,我这个示例代码做了ESP8266和ESP32的兼容,可以通用。
ESP8266和ESP32 TCP测试示例代码如下:
/*
This sketch establishes a TCP connection to a "quote of the day" service.
It sends a "hello" message, and then prints received data.
*/
#ifdef ESP8266
#include <ESP8266WiFi.h> // esp8266
#else
#include <WiFi.h> // esp32
#endif
#ifndef STASSID
#define STASSID "mate40"
#define STAPSK "123456789"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "192.168.43.128";
const uint16_t port = 1234;
void setup() {
Serial.begin(115200);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
/* Explicitly set the ESP8266 or ESP32 to be a WiFi-client, otherwise, it by default,
would try to act as both a client and an access-point and could cause
network-issues with your other WiFi-devices on your WiFi-network. */
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
static bool wait = false;
Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}
// This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}
#if 0
// wait for data to be available
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
delay(60000);
return;
}
}
#endif
// Read all the lines of the reply from server and print them to Serial
Serial.println("receiving from remote server");
while (client.connected() || client.available() || Serial.available()) {
while (Serial.available()) {
char data;
data = Serial.read();
if (client.connected()) {
client.print(data);
}
}
while (client.available()) {
char ch = static_cast<char>(client.read());
Serial.print(ch);
}
}
#if 1
// Close the connection
Serial.println();
Serial.println("closing connection");
client.stop();
#endif
if (wait) {
delay(300000); // execute once every 5 minutes, don't flood remote service
}
wait = true;
}
注意:示例代码里面有几个地方需要根据自己的实际情况修改之后才能正常使用。还有电脑和设备(esp8266或esp32)要在同一个局域网下,不懂什么是局域网的话可以把电脑和设备连接到同一个WIFI下。
参数 | 值 |
---|---|
STASSID | 你的WIFI名称,示例:“test” |
STAPSK | 你的WIFI密码,示例:“12345678” |
host | 服务器地址,也就是你建立TCP Server时设置的IP地址,示例:“192.168.43.128” |
port | 服务器端口,也就是你建立TCP Server时设置的端口,示例:1234 |
esp8266运行测试如下:
连接esp8266的串口,方便打印设备运行的信息,这样就可以更好的看到TCP连接的情况。
打开TCP Server,等待设备连接,如果这个时候MCU已经连上了WIFI并且可以访问到这个服务端的话,就能连接上。
TCP成功连接之后,就可以互发数据了。esp8266会将串口接收到的数据转发到TCP Server,TPC Server发送过来的数据转发到串口发送给PC端。
esp32运行测试如下:
esp32的运行结果和esp8266是完全一样的。
结束语
好了,关于Arduino TCP/IP的编程和使用方法就讲到这里。因为时间的关系,我没有做TCP数据传输速度的测试,以后有时间的话再补上吧(如果还记得的话