ESP8266 wifi 服务器到 android 客户端
ESP8266 wifi server to android client
我一直在尝试在特定端口上使用 ESP8266 wifi 模块设置服务器。我已经完成了。
我现在想收到来自它的消息。
每当我使用 socket.connect() 连接时,我都能在 esp8266 中检测到它。但是我收不到任何消息,服务器通过同一个套接字发送。
我正在尝试在异步的 while 循环中使用 DataInputStream 连续获取消息 task.Pls 如果我的方法或代码有误,请告诉我!谢谢!
这是我的代码:
package test.espclient;
import java.io.DataInputStream;
//import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear,buttonDiscon , buttonSendMsg;
EditText welcomeMsg;
Socket socket;
boolean socketStatus = false;
MyClientTask myClientTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
buttonConnect = (Button) findViewById(R.id.connect);
buttonClear = (Button) findViewById(R.id.clear);
buttonDiscon = (Button) findViewById(R.id.closeSocket);
buttonSendMsg = (Button) findViewById(R.id.sendMsg);
textResponse = (TextView) findViewById(R.id.response);
welcomeMsg = (EditText)findViewById(R.id.welcomemsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDiscon.setOnClickListener(buttonDisconnectOnCLickListener);
//buttonSendMsg.setOnClickListener(sendMessage);
buttonClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
textResponse.setText("");
}
});
}
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
if(socketStatus)
Toast.makeText(MainActivity.this,"Already talking to a Socket!! Disconnect and try again!", Toast.LENGTH_LONG).show();
else {
socket = null;
String address = editTextAddress.getText().toString();
int port = Integer.parseInt(editTextPort.getText().toString());
String tMsg = welcomeMsg.getText().toString();
if (address == null || port == 0)
Toast.makeText(MainActivity.this, "Please enter valid address/port", Toast.LENGTH_LONG).show();
else {
myClientTask = new MyClientTask(address,port,tMsg);
myClientTask.execute();
} //else when no active socket conn. and credentials are validated.
} //else when already active socket conn.
}
};
OnClickListener buttonDisconnectOnCLickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (!socketStatus)
Toast.makeText(MainActivity.this, "SOCKET Already Closed!!", Toast.LENGTH_SHORT).show();
else {
try {
onDisconnect();
if(myClientTask.isCancelled()) {
socket.close();
Toast.makeText(MainActivity.this, "Socket Closed!", Toast.LENGTH_SHORT).show();
socketStatus = false;
}
else
{
Toast.makeText(MainActivity.this, "Couldn't Disconnect! Pls try again!", Toast.LENGTH_SHORT).show();
socketStatus = true;
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
};
// OnClickListener sendMessage = new OnClickListener() {
// @Override
// public void onClick(View v) {
// String msg = welcomeMsg.toString();
// if(msg.equals(""))
// {
// Toast.makeText(MainActivity.this, "Message is empty!!!", Toast.LENGTH_SHORT).show();
// }
// else if(!socketStatus)
// {
// Toast.makeText(MainActivity.this, "Please Establish Socket Connection first!", Toast.LENGTH_SHORT).show();
// }
// else
// {
// MyClientTask myClientTask = new MyClientTask(editTextAddress
// .getText().toString(), Integer.parseInt(editTextPort
// .getText().toString()),
// msg);
// myClientTask.execute();
//
// }
//
// }
// };
public void onDisconnect()
{
myClientTask.cancel(true);
}
public class MyClientTask extends AsyncTask<Void, String, Void> {
String dstAddress;
int dstPort;
String response ="";
String msgToServer;
MyClientTask(String addr, int port, String msgTo) {
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
Log.w("MSG","Entering async task");
}
@Override
protected Void doInBackground(Void... arg0) {
// DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
socketStatus = true;
// dataOutputStream = new DataOutputStream(socket.getOutputStream());
// if(msgToServer != null){
// dataOutputStream.writeUTF(msgToServer);
// }
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
socketStatus = false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
Log.w("MSG","Inside while loop for retrieving data");
while(!isCancelled()){
try {
dataInputStream = new DataInputStream(socket.getInputStream());
response = dataInputStream.readUTF();
if(!response.isEmpty())
{
publishProgress(response);
Log.w("Data:",response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// if (dataOutputStream != null) {
// try {
// dataOutputStream.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Log.w("MSG","Stopping async task");
socket.close();
socketStatus = false;
} catch (IOException e) {
e.printStackTrace();
socketStatus = true;
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
textResponse.setText(values[0]);
Toast.makeText(MainActivity.this,"Server:"+values[0],Toast.LENGTH_LONG).show();
Log.w("MSG","Updating with msg");
}
@Override
protected void onPostExecute(Void result) {
Log.w("MSG","On postExecute method..");
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
UPDATE(16-12-15) 我在 doInBackground() 下进行了以下更改。
原来我用的是DataInputStream,现在换成了BufferedReader。
更改是在 while 循环部分下进行的,用于不断检查套接字输入流。还添加了ESP8266代码供参考。
现在我可以接收到ESP8266发来的短信了,但是只有在我通过CIPSEND cmd发送了3条或4条消息后才能收到。例如如果我发送 "hi"、"hello" "yo",在发送第三个单词后,我收到的所有单词都是 "hihelloyo"
我不是一发送就收到每条消息,而是很晚才收到。
我不确定到底是什么导致了这个问题。可能是缓冲区大小?
如何解决这个问题?
修改后的代码:
protected Void doInBackground(Void... arg0) {
// DataOutputStream dataOutputStream = null;
// DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
socketStatus = true;
// dataOutputStream = new DataOutputStream(socket.getOutputStream());
// if(msgToServer != null){
// dataOutputStream.writeUTF(msgToServer);
// }
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
socketStatus = false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
Log.w("MSG","Inside while loop for retrieving data");
while(!isCancelled() && socketStatus) {
try {
// dataInputStream = new DataInputStream(socket.getInputStream());
// response = dataInputStream.readUTF();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
response = br.readLine();
if (!response.isEmpty()) {
publishProgress(response);
Log.w("Data:", response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
ESP266编码
#include <AltSoftSerial.h>
AltSoftSerial ESP8266 ;//(8,9)|Rx,Tx
int LED = 13;
boolean FAIL_8266 = false;
#define BUFFER_SIZE 128
char buffer[BUFFER_SIZE];
String ssid="\"SSID\"";
String pass="\"PASSWORD\"";
void clearESP8266SerialBuffer()
{
Serial.println("= clearESP8266SerialBuffer() =");
while (ESP8266.available() > 0) {
char a = ESP8266.read();
Serial.write(a);
}
Serial.println("==============================");
}
void sendHTTPResponse(int id, String content)
{
String response;
response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: text/html; charset=UTF-8\r\n";
response += "Content-Length: ";
response += content.length();
response += "\r\n";
response +="Connection: close\r\n\r\n";
response += content;
String cmd = "AT+CIPSEND=";
cmd += id;
cmd += ",";
cmd += response.length();
Serial.println("--- AT+CIPSEND ---");
sendESP8266Cmdln(cmd, 1000);
Serial.println("--- data ---");
sendESP8266Data(response, 1000);
}
boolean waitOKfromESP8266(int timeout)
{
do{
Serial.println("wait OK...");
delay(1000);
if(ESP8266.find("OK"))
{
return true;
}
}while((timeout--)>0);
return false;
}
//Send command to ESP8266, assume OK, no error check
//wait some time and display respond
void sendESP8266Cmdln(String cmd, int waitTime)
{
ESP8266.println(cmd);
delay(waitTime);
clearESP8266SerialBuffer();
}
//Basically same as sendESP8266Cmdln()
//But call ESP8266.print() instead of call ESP8266.println()
void sendESP8266Data(String data, int waitTime)
{
ESP8266.print(data);
delay(waitTime);
clearESP8266SerialBuffer();
}
void adc()
{
int ldr;
for(int i=0;i<=3;i++)
{
ldr = analogRead(A0);
sendESP8266Cmdln("AT+CIPSEND=0,5",1000);
sendESP8266Cmdln(String(ldr),1000);
delay(1000);
}
}
void setup()
{
Serial.begin(9600);
ESP8266.begin(9600);
pinMode(LED,OUTPUT);
do{
ESP8266.println("AT+RST");
delay(1000);
if(ESP8266.find("Ready"))
{
Serial.println("Module is ready");
delay(1000);
clearESP8266SerialBuffer();
sendESP8266Cmdln("AT+CWMODE=1",1000);
//Join Wifi network
sendESP8266Cmdln("AT+CWJAP="+ssid+","+pass,6500);
//Get and display my IP
sendESP8266Cmdln("AT+CIFSR", 1000);
//Set multi connections
sendESP8266Cmdln("AT+CIPMUX=1", 1000);
//Setup web server on port 80
sendESP8266Cmdln("AT+CIPSERVER=1,3333",1000);
Serial.println("Server setup finish");
FAIL_8266 = false;
}else{
Serial.println("Module have no response.");
delay(500);
FAIL_8266 = true;
}
}while(FAIL_8266);
digitalWrite(LED, HIGH);
ESP8266.setTimeout(1000);
}
void loop() {
// listen for communication from the ESP8266 and then write it to the serial monitor
if(ESP8266.available()) // check if the esp is sending a message
{
String msg = ESP8266.readString();
if(msg.substring(0,4)=="Link")
Serial.println("Client connected!");
else if(msg.substring(0,6)=="Unlink")
Serial.println("Client Disconncected!!");
else if(msg.substring(1,5)=="+IP")
{
Serial.println("Client says: "+msg.substring(9,14));
}
else
{
// Serial.println("Calling ADC.!");
//adc();
// Serial.println("Msg:"+msg.charAt(0)+msg.charAt(1)+msg.charAt(2)+msg.charAt(3));
// Serial.println("Something recieved!: "+msg.substring(1,2));
Serial.println("MSG:"+msg);
}
}
// listen for user input and send it to the ESP8266
if ( Serial.available() ) { ESP8266.write( Serial.read() ); }
}
//Clear and display Serial Buffer for ESP8266
更新(17-12-15):添加图片以供参考
我的 arduino 序列 window 显示了 AT+CIPSEND 命令。
运行 phone 上的应用图片。
关于这条评论:
... it worked! I can get the messages immediately irrespective of their lengths, after i close the connection on esp side using cipclose=0. But is this is the only way? Is it possible to make the device and the app talk? How come it is possible in the telnet application, where i can continuously send data till i close connection on one side.?
在上层应用层,来自 TCPIP 连接的数据以流的形式呈现。将此流与定义明确的应用程序协议(如 HTTP 或 telnet)一起使用,可以定义消息交换。在您的情况下,Android 方基本上不知道要接收多少数据。使用缓冲后 reader 你得到缓冲的答案,而不是整个。
例如在telnet协议中有控制命令。因此系统继续工作。
解决您的问题:
- 每条消息后关闭连接。 (这会减慢速度)
- 实现一个基本的应用程序协议。例如:实现一个消息框架:
FRAME
1st byte : length ( this byte gives the length of the payload )
2nd...255th byte : payload ( this is the actual message )
LOGIC
-Sender packs the frame giving length and payload.
-Sender sends the data
...
-Receiver queries for the available bytes.
-When available bytes are >1 receive only 1 byte say it is 'n'
-'n' is the length of the total frame
-Read 'n' bytes from the stream. if EOF then return what is received.
除此之外,您还可以执行控制命令。
例如,您可能希望接收方关闭连接,以便您的帧可以是:
Byte 1 : length
Byte 2 : command (0=nothing, 1=close conn)
Byte 3..n : payload
LOGIC
-When receiver finished receiving and command is 1 then closes the connection.
我一直在尝试在特定端口上使用 ESP8266 wifi 模块设置服务器。我已经完成了。
我现在想收到来自它的消息。 每当我使用 socket.connect() 连接时,我都能在 esp8266 中检测到它。但是我收不到任何消息,服务器通过同一个套接字发送。
我正在尝试在异步的 while 循环中使用 DataInputStream 连续获取消息 task.Pls 如果我的方法或代码有误,请告诉我!谢谢!
这是我的代码:
package test.espclient;
import java.io.DataInputStream;
//import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear,buttonDiscon , buttonSendMsg;
EditText welcomeMsg;
Socket socket;
boolean socketStatus = false;
MyClientTask myClientTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
buttonConnect = (Button) findViewById(R.id.connect);
buttonClear = (Button) findViewById(R.id.clear);
buttonDiscon = (Button) findViewById(R.id.closeSocket);
buttonSendMsg = (Button) findViewById(R.id.sendMsg);
textResponse = (TextView) findViewById(R.id.response);
welcomeMsg = (EditText)findViewById(R.id.welcomemsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDiscon.setOnClickListener(buttonDisconnectOnCLickListener);
//buttonSendMsg.setOnClickListener(sendMessage);
buttonClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
textResponse.setText("");
}
});
}
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
if(socketStatus)
Toast.makeText(MainActivity.this,"Already talking to a Socket!! Disconnect and try again!", Toast.LENGTH_LONG).show();
else {
socket = null;
String address = editTextAddress.getText().toString();
int port = Integer.parseInt(editTextPort.getText().toString());
String tMsg = welcomeMsg.getText().toString();
if (address == null || port == 0)
Toast.makeText(MainActivity.this, "Please enter valid address/port", Toast.LENGTH_LONG).show();
else {
myClientTask = new MyClientTask(address,port,tMsg);
myClientTask.execute();
} //else when no active socket conn. and credentials are validated.
} //else when already active socket conn.
}
};
OnClickListener buttonDisconnectOnCLickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (!socketStatus)
Toast.makeText(MainActivity.this, "SOCKET Already Closed!!", Toast.LENGTH_SHORT).show();
else {
try {
onDisconnect();
if(myClientTask.isCancelled()) {
socket.close();
Toast.makeText(MainActivity.this, "Socket Closed!", Toast.LENGTH_SHORT).show();
socketStatus = false;
}
else
{
Toast.makeText(MainActivity.this, "Couldn't Disconnect! Pls try again!", Toast.LENGTH_SHORT).show();
socketStatus = true;
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
};
// OnClickListener sendMessage = new OnClickListener() {
// @Override
// public void onClick(View v) {
// String msg = welcomeMsg.toString();
// if(msg.equals(""))
// {
// Toast.makeText(MainActivity.this, "Message is empty!!!", Toast.LENGTH_SHORT).show();
// }
// else if(!socketStatus)
// {
// Toast.makeText(MainActivity.this, "Please Establish Socket Connection first!", Toast.LENGTH_SHORT).show();
// }
// else
// {
// MyClientTask myClientTask = new MyClientTask(editTextAddress
// .getText().toString(), Integer.parseInt(editTextPort
// .getText().toString()),
// msg);
// myClientTask.execute();
//
// }
//
// }
// };
public void onDisconnect()
{
myClientTask.cancel(true);
}
public class MyClientTask extends AsyncTask<Void, String, Void> {
String dstAddress;
int dstPort;
String response ="";
String msgToServer;
MyClientTask(String addr, int port, String msgTo) {
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
Log.w("MSG","Entering async task");
}
@Override
protected Void doInBackground(Void... arg0) {
// DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
socketStatus = true;
// dataOutputStream = new DataOutputStream(socket.getOutputStream());
// if(msgToServer != null){
// dataOutputStream.writeUTF(msgToServer);
// }
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
socketStatus = false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
Log.w("MSG","Inside while loop for retrieving data");
while(!isCancelled()){
try {
dataInputStream = new DataInputStream(socket.getInputStream());
response = dataInputStream.readUTF();
if(!response.isEmpty())
{
publishProgress(response);
Log.w("Data:",response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// if (dataOutputStream != null) {
// try {
// dataOutputStream.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Log.w("MSG","Stopping async task");
socket.close();
socketStatus = false;
} catch (IOException e) {
e.printStackTrace();
socketStatus = true;
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
textResponse.setText(values[0]);
Toast.makeText(MainActivity.this,"Server:"+values[0],Toast.LENGTH_LONG).show();
Log.w("MSG","Updating with msg");
}
@Override
protected void onPostExecute(Void result) {
Log.w("MSG","On postExecute method..");
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
UPDATE(16-12-15) 我在 doInBackground() 下进行了以下更改。 原来我用的是DataInputStream,现在换成了BufferedReader。 更改是在 while 循环部分下进行的,用于不断检查套接字输入流。还添加了ESP8266代码供参考。
现在我可以接收到ESP8266发来的短信了,但是只有在我通过CIPSEND cmd发送了3条或4条消息后才能收到。例如如果我发送 "hi"、"hello" "yo",在发送第三个单词后,我收到的所有单词都是 "hihelloyo" 我不是一发送就收到每条消息,而是很晚才收到。 我不确定到底是什么导致了这个问题。可能是缓冲区大小? 如何解决这个问题?
修改后的代码:
protected Void doInBackground(Void... arg0) {
// DataOutputStream dataOutputStream = null;
// DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
socketStatus = true;
// dataOutputStream = new DataOutputStream(socket.getOutputStream());
// if(msgToServer != null){
// dataOutputStream.writeUTF(msgToServer);
// }
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
socketStatus = false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
Log.w("MSG","Inside while loop for retrieving data");
while(!isCancelled() && socketStatus) {
try {
// dataInputStream = new DataInputStream(socket.getInputStream());
// response = dataInputStream.readUTF();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
response = br.readLine();
if (!response.isEmpty()) {
publishProgress(response);
Log.w("Data:", response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
ESP266编码
#include <AltSoftSerial.h>
AltSoftSerial ESP8266 ;//(8,9)|Rx,Tx
int LED = 13;
boolean FAIL_8266 = false;
#define BUFFER_SIZE 128
char buffer[BUFFER_SIZE];
String ssid="\"SSID\"";
String pass="\"PASSWORD\"";
void clearESP8266SerialBuffer()
{
Serial.println("= clearESP8266SerialBuffer() =");
while (ESP8266.available() > 0) {
char a = ESP8266.read();
Serial.write(a);
}
Serial.println("==============================");
}
void sendHTTPResponse(int id, String content)
{
String response;
response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: text/html; charset=UTF-8\r\n";
response += "Content-Length: ";
response += content.length();
response += "\r\n";
response +="Connection: close\r\n\r\n";
response += content;
String cmd = "AT+CIPSEND=";
cmd += id;
cmd += ",";
cmd += response.length();
Serial.println("--- AT+CIPSEND ---");
sendESP8266Cmdln(cmd, 1000);
Serial.println("--- data ---");
sendESP8266Data(response, 1000);
}
boolean waitOKfromESP8266(int timeout)
{
do{
Serial.println("wait OK...");
delay(1000);
if(ESP8266.find("OK"))
{
return true;
}
}while((timeout--)>0);
return false;
}
//Send command to ESP8266, assume OK, no error check
//wait some time and display respond
void sendESP8266Cmdln(String cmd, int waitTime)
{
ESP8266.println(cmd);
delay(waitTime);
clearESP8266SerialBuffer();
}
//Basically same as sendESP8266Cmdln()
//But call ESP8266.print() instead of call ESP8266.println()
void sendESP8266Data(String data, int waitTime)
{
ESP8266.print(data);
delay(waitTime);
clearESP8266SerialBuffer();
}
void adc()
{
int ldr;
for(int i=0;i<=3;i++)
{
ldr = analogRead(A0);
sendESP8266Cmdln("AT+CIPSEND=0,5",1000);
sendESP8266Cmdln(String(ldr),1000);
delay(1000);
}
}
void setup()
{
Serial.begin(9600);
ESP8266.begin(9600);
pinMode(LED,OUTPUT);
do{
ESP8266.println("AT+RST");
delay(1000);
if(ESP8266.find("Ready"))
{
Serial.println("Module is ready");
delay(1000);
clearESP8266SerialBuffer();
sendESP8266Cmdln("AT+CWMODE=1",1000);
//Join Wifi network
sendESP8266Cmdln("AT+CWJAP="+ssid+","+pass,6500);
//Get and display my IP
sendESP8266Cmdln("AT+CIFSR", 1000);
//Set multi connections
sendESP8266Cmdln("AT+CIPMUX=1", 1000);
//Setup web server on port 80
sendESP8266Cmdln("AT+CIPSERVER=1,3333",1000);
Serial.println("Server setup finish");
FAIL_8266 = false;
}else{
Serial.println("Module have no response.");
delay(500);
FAIL_8266 = true;
}
}while(FAIL_8266);
digitalWrite(LED, HIGH);
ESP8266.setTimeout(1000);
}
void loop() {
// listen for communication from the ESP8266 and then write it to the serial monitor
if(ESP8266.available()) // check if the esp is sending a message
{
String msg = ESP8266.readString();
if(msg.substring(0,4)=="Link")
Serial.println("Client connected!");
else if(msg.substring(0,6)=="Unlink")
Serial.println("Client Disconncected!!");
else if(msg.substring(1,5)=="+IP")
{
Serial.println("Client says: "+msg.substring(9,14));
}
else
{
// Serial.println("Calling ADC.!");
//adc();
// Serial.println("Msg:"+msg.charAt(0)+msg.charAt(1)+msg.charAt(2)+msg.charAt(3));
// Serial.println("Something recieved!: "+msg.substring(1,2));
Serial.println("MSG:"+msg);
}
}
// listen for user input and send it to the ESP8266
if ( Serial.available() ) { ESP8266.write( Serial.read() ); }
}
//Clear and display Serial Buffer for ESP8266
更新(17-12-15):添加图片以供参考
我的 arduino 序列 window 显示了 AT+CIPSEND 命令。
运行 phone 上的应用图片。
关于这条评论:
... it worked! I can get the messages immediately irrespective of their lengths, after i close the connection on esp side using cipclose=0. But is this is the only way? Is it possible to make the device and the app talk? How come it is possible in the telnet application, where i can continuously send data till i close connection on one side.?
在上层应用层,来自 TCPIP 连接的数据以流的形式呈现。将此流与定义明确的应用程序协议(如 HTTP 或 telnet)一起使用,可以定义消息交换。在您的情况下,Android 方基本上不知道要接收多少数据。使用缓冲后 reader 你得到缓冲的答案,而不是整个。
例如在telnet协议中有控制命令。因此系统继续工作。
解决您的问题:
- 每条消息后关闭连接。 (这会减慢速度)
- 实现一个基本的应用程序协议。例如:实现一个消息框架:
FRAME 1st byte : length ( this byte gives the length of the payload ) 2nd...255th byte : payload ( this is the actual message ) LOGIC -Sender packs the frame giving length and payload. -Sender sends the data ... -Receiver queries for the available bytes. -When available bytes are >1 receive only 1 byte say it is 'n' -'n' is the length of the total frame -Read 'n' bytes from the stream. if EOF then return what is received.
除此之外,您还可以执行控制命令。 例如,您可能希望接收方关闭连接,以便您的帧可以是:
Byte 1 : length Byte 2 : command (0=nothing, 1=close conn) Byte 3..n : payload LOGIC -When receiver finished receiving and command is 1 then closes the connection.