项目需要电脑与一个设备无线通讯,想做一个像虚拟串口那样的无线串口互连的设备,用两个ESP8266,一个AP,一个SP,不用提供wifi。
程序特点:1、服务端,客户端的串口,每次loop检测Serial.available();
2、服务端的server检测/update;
3、客户端的接收,在loop里,靠client.available()检测,
过程:
1、服务端建立热点,设置固定wifi热点名和密码;
2、服务端尝试连接;
3、客户端连接服务端的热点,并且在Loop里检测连接状态,断了就再连;
4、服务端串口接到数据,就用server.send()发出去;
5、客户端串口接到数据,就用client.print(httpRequest)发出去;
6、服务端tcp接到数据,解析出来server.arg("data");,就发给串口;
7、客户端tcp接到数据,读出来client.read(),再发给串口;
服务端:
#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi库
#include <ESP8266WebServer.h> // 使用WebServer库
const char *ssid = "taichi-maker"; // 这里定义将要建立的WiFi名称。此处以"taichi-maker"为示例
// 您可以将自己想要建立的WiFi名称填写入此处的双引号中
const char *password = "12345678"; // 这里定义将要建立的WiFi密码。此处以12345678为示例
// 您可以将自己想要使用的WiFi密码放入引号内
// 如果建立的WiFi不要密码,则在双引号内不要填入任何信息
//uint8_t data[2];
ESP8266WebServer server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
IPAddress local_IP(192, 168, 4, 1); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 4, 1); // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
IPAddress dns(192,168,4,1); // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
// 要连的server ip
const char* host = "192.168.4.2"; // 即将连接服务器网址/IP
const int httpPort = 80; // 即将连接服务器端口
String rx_data;
//串口中断函数
void Serial_callback()
{
while (Serial.available())
{
rx_data+=char(Serial.read());
delay(5); //这里不能去掉,要给串口处理数据的时间
}
if(rx_data!="")
{
server.send(200, "text/plain", rx_data);
//Serial.print(rx_data);
rx_data="";
}
}
void setup() {
Serial.begin(9600); // 启动串口通讯
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
WiFi.softAP(ssid, password); // 此语句是重点。WiFi.softAP用于启动NodeMCU的AP模式。
// 括号中有两个参数,ssid是WiFi名。password是WiFi密码。
// 这两个参数具体内容在setup函数之前的位置进行定义。
// 设置开发板网络环境
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("Failed to Config ESP8266 IP");
}
Serial.print("Access Point: "); // 通过串口监视器输出信息
Serial.println(ssid); // 告知用户NodeMCU所建立的WiFi名
Serial.print("IP address: "); // 以及NodeMCU的IP地址
Serial.println(WiFi.softAPIP()); // 通过调用WiFi.softAPIP()可以得到NodeMCU的IP地址
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
//server.on("/update", handleUpdate); // 处理服务器更新函数
server.on("/update", HTTP_GET, handleUpdate);
server.begin();
}
void loop() {
server.handleClient(); // 检查http服务器访问
Serial_callback();
}
void handleUpdate()
{
delay(1);
String strdata = server.arg("data");
if(strdata!="")
{
Serial.print(strdata+"\r\n");
}
}
客户端:
#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi库
#include<WiFiClient.h>
#define buttonPin D3 // 按钮引脚D3
const char *ssid = "taichi-maker"; // 请将您需要连接的WiFi名填入引号中
const char *password = "12345678"; // 请将您需要连接的WiFi密码填入引号中
const char* host = "192.168.4.1"; // 即将连接服务器网址/IP
const int httpPort = 80; // 即将连接服务器端口
float clientFloatValue; //存储客户端发送的浮点型测试数据
int clientIntValue; //存储客户端发送的整数型测试数据
bool buttonState; //存储客户端按键控制数据
WiFiClient client;
IPAddress local_IP(192, 168, 4, 2); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 4, 1); // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
String rx_data;
//串口中断函数
void Serial_callback()
{
//Serial.println("read;");
while (Serial.available())
{
rx_data+=char(Serial.read());
delay(3); //这里不能去掉,要给串口处理数据的时间
}
if(rx_data!="")
{
wifiClientRequest2(rx_data);
rx_data="";
}
}
String Read_Tcp()
{
String data="";
while(client.available()>0){
data += char(client.read());
delay(1);
}
return data;
}
void Tcp_Handler(String data){
if(data!="")
{
//Serial.print("收到服务器信息:");
int maxIndex = data.length();
int ipos=0;
for(int i=maxIndex;i>=0;--i)
{
if(data.charAt(i)==0x0D)
{
ipos=i;
break;
}
}
String data2="";
for(int i=ipos;i<maxIndex;++i)
{
char sterp = data.charAt(i);
if(sterp!=0x0D && sterp!= 0x0A)
{
data2+=sterp;
}
}
Serial.print(data2);
}
}
//连接路由器
void getwifi(){
while(WiFi.status()!=WL_CONNECTED){
delay(500);
Serial.print(".");
}
}
//连接服务器
void ycconnect(){
Serial.println("client try connect");
client.connect(host,httpPort);
delay(1);
}
void setup() {
Serial.begin(9600); // 启动串口通讯
delay(100); // 保持连接稳定
pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
WiFi.mode(WIFI_STA); //将ESP8266设置为STA模式
//WiFi.softAP(ssid, password);
WiFi.begin(ssid, password); // 启动网络连接
// 设置开发板网络环境
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("Failed to Config ESP8266 IP");
}
getwifi();
Serial.println("Wifi OK");
delay(100);
}
void loop()
{
if(WiFi.status()!=WL_CONNECTED){
WiFi.disconnect();
WiFi.begin(ssid,password);
getwifi();
Serial.println("5");
}
else
{
//如果没有连接到服务器
if(!client.connected())
{//Serial.println("1");
client.stop();
if (client.connect(host, httpPort))
{//Serial.println("3");
//delay(1);
Tcp_Handler(Read_Tcp());
Serial_callback();
}
}
else
{
Tcp_Handler(Read_Tcp());
Serial_callback();
}
}
}
void wifiClientRequest(){
String url = "/update?float=" + String(clientFloatValue) +
"&int=" + String(clientIntValue) +
"&button=" + String(buttonState) +
"&data=" + "kk";
// 建立字符串,用于HTTP请求
String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n" +
"\r\n";
client.print(httpRequest); // 向服务器发送HTTP请求
}
void wifiClientRequest2(String data1)
{
String url = "/update?data=" + data1;
String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
//"Connection: close\r\n" +
"\r\n";
client.print(httpRequest); // 向服务器发送HTTP请求
}
这个无线串口通讯的问题是,需要USB口有供电!!!!!
有的设备有个RS232,用一个RS232转USBtypeA公,再接个USBtypeA母对母,再接USBtypeA转microUSB接到3sp8266板子上,发现没有供电。。。。外接电池才能通上。
所以目前两个电脑之间的通讯是没问题的,只要microUSB转USBTypeA的数据线不是特别廉价传不了数据那种,简单分辨你方法就是,太细的就是劣质的,只供电,粗一些才能既供电又传数据。