我试图制作由NodeMCU esp-12e开发板驱动的wifi控制的车库门开启器。目前,代码将连接到wifi,并在有人导航到IP地址时发布网页。但是,它几乎总是需要至少两次连接尝试 - 它将在第一次断开客户端,然后重新连接。主要问题是当按下任一按钮时,开发板上没有任何反应。刷新页面或关闭选项卡时,开发板会收到按下的按钮的值,以及其他客户端连接的任何其他尝试。我对HTTP请求几乎一无所知,并且想知道开发板接收按钮的最佳方式是什么。以下是当前使用的代码:
const int http_port = 80;
// or 8080 on linux/unix systems? who knows
const int LEFT_SERVO_PIN = D6;
const int RIGHT_SERVO_PIN = D7;
// almost all GPIO pins on the NodeMCU are PWM-enabled
// Initialize the client library
WiFiClient client;
WiFiServer server(http_port);
byte mac[6];
// set aside space for the MAC address
char msg[128];
// holds HTML response message
int letterCount = 0;
void setup() {
initHardware();
connectWiFi();
server.begin();
}
void loop() {
int dataFlag = 0;
int msgIsolator = 0;
// listen for incoming clients
WiFiClient client = server.available();
// display the module's info
printWifiInfo();
delay(3000);
if(client) {
if(client.connected()) {
Serial.println("\nConnected to client\n");
}
// an HTTP request ends with a blank line
boolean currentLineIsBlank = true;
// the client will send an HTTP request which will be read
// by the server and then written to the Serial monitor
while(client.connected()) {
if(client.available()) {
char c = client.read();
delay(10);
Serial.print(c);
// if you've gotten to the end of the line (received a newline)
// and the line is blank, the HTTP request has ended
if(c == '\n' && currentLineIsBlank) {
displayWebpage(client);
delay(500);
// if you are inside this loop, you are waiting for user message
// so letterCount should be reset to prevent incorrect reading and action
letterCount = 0;
// checkAction will perform some command depending on
// what the user entered by pressing the button
checkAction();
// break;
}
if(c == '\n') {
// you are starting a newline
currentLineIsBlank = true;
}
else if(c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
if(c == '%') {
// indicate we need to start recording the message
dataFlag = 1;
}
if(dataFlag == 1) {
if(c == '=') {
// we have gone through '%=' so what's left is the message
// indicate we need to isolate the message
msgIsolator = 1;
}
}
} // if(client.available())
} // while(client.connected())
// give the browser time to receive the data
delay(100);
// flush the buffer
client.flush();
// disconnect
client.stop();
Serial.println("Client Disconnected");
}
}
/********************
* initHardware
*********************/
void initHardware() {
Serial.begin(9600);
Serial.println();
Serial.println("Entering hardware initialization");
pinMode(RIGHT_SERVO_PIN, OUTPUT);
digitalWrite(RIGHT_SERVO_PIN, LOW);
pinMode(LEFT_SERVO_PIN, OUTPUT);
digitalWrite(LEFT_SERVO_PIN, LOW);
// initial settings
Serial.println("Hardware Initialized");
}
/********************
* connectWiFi
********************/
void connectWiFi() {
Serial.println("Entering WiFi connection stage");
byte ledStatus = LOW;
// byte that tracks the LED's state
// LOW = 0, HIGH = 1
WiFi.mode(WIFI_STA);
// this sets the board's WiFi mode to station,
// as opposed to access point or something else
// WiFi.begin([ssid], [passkey]) initiates a WiFi connection
// to the stated ssid, using the passkey as a WPA, WPA2,
// or WEP passphrase
WiFi.begin(ssid, password);
Serial.print("Connecting...");
// Use the WiFi.status() function to check if the ESP8266
// is connected to a WiFi network
while( WiFi.status() != WL_CONNECTED ) {
// blink the LED to indicate the board is still
// not connected
//digitalWrite(LED_PIN, ledStatus);
ledStatus = (ledStatus == HIGH) ? LOW : HIGH;
// ternary boiiiii
Serial.print(".");
delay(100);
// this delay is necessary for the ESP8266 to set up
// and mantain the WiFi connection
}
Serial.println("Connection Successful!");
//digitalWrite(LED_PIN, HIGH);
// after connecting, the blink loop will be exited
// and the LED will shine continuously
}
/********************
* printWifiInfo
********************/
void printWifiInfo() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
WiFi.macAddress(mac);
Serial.print("Device MAC Address: ");
for(int i = 5; i >= 1; i--) {
Serial.print(mac[i], HEX);
Serial.print(":");
}
Serial.println(mac[0]);
Serial.print("Signal strength (RSSI): ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
}
/********************
* displayWebpage
********************/
void displayWebpage(WiFiClient client) {
// serve up the Webpage to be connected to
// this page will read the status of a button
// and perform actions accordingly
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<title>ESP Valet</title>");
// form code for html buttons
client.println("<center>");
// Button for Left Garage Door
client.println("<form name=\"input\" action=\"\" method=\"post\">");
client.println("<input type=\"submit\" name=\"%\" value=\"Left Door\" style=\"height:50px; width:150px\" >");
client.println("</form>");
// Button for Right Garage Door
client.println("<form name=\"input\" action=\"\" method=\"post\">");
client.println("<input type=\"submit\" name=\"%\" value=\"Right Door\" style=\"height:50px; width:150px\" >");
client.println("</form>");
client.println("</center>");
client.println("</html>");
}
/********************
* checkAction
********************/
void checkAction() {
// check first three letters of message to determing which action to take
Serial.println("\nInside checkAction");
if(msg[0] == 'R' && msg[1] == 'i' && msg[2] == 'g') {
digitalWrite(RIGHT_SERVO_PIN, HIGH);
digitalWrite(LEFT_SERVO_PIN, LOW);
// for debugging, use LEDs, but change to Servos if works
}
else if(msg[0] == 'L' && msg[1] == 'e' && msg[2] == 'f') {
digitalWrite(LEFT_SERVO_PIN, HIGH);
digitalWrite(RIGHT_SERVO_PIN, LOW);
}
}
/********************
* recordMessage
********************/
char recordMessage(char incomingMsg) {
Serial.println("\nInside recordMessage");
msg[letterCount] = incomingMsg;
letterCount++;
delay(100);
}