如何在void循环中使用两次serial.available?

How to use serial.available twice in void loop?

我在 arduino nano 上使用键盘(4x4),然后串行通信 arduino nano 和 nodemcu。我的 arduino nano 代码是:

#include <SoftwareSerial.h>
#include <Password.h>
#include <Keypad.h>
Password ssid = Password( "1234" );
Password pass = Password( "56789" );
Password connection = Password( "C" );

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns

char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = { 2,3,4,10 };
byte colPins[COLS] = { 11,7,8,9 };
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );
SoftwareSerial s(5,6);
//void checkPassword();
void setup(){
  Serial.begin(9600);
  s.begin(9600);
  customKeypad.addEventListener(keypadEvent); //add an event listener for this keypad
  Serial.println("enter SSID: ");    
}

void loop()
{
  char customKey = customKeypad.getKey(); //storing pressed key value in a char
  if (customKey) {
    if(s.available() > 0) {
      switch (customKey) {
        case '1':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '2':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '3':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '4':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '5':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '6':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '7':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '8':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '9':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case '0':
          Serial.println(customKey);
          s.write(customKey);
          //s.write("\nPassword verified\nPress C to connect\n");
          break;
        case '*':
          Serial.println(customKey);
          s.write(customKey);
          //s.write();
          //s.write("\nSSID verified\nEnter your Password\n");
          //checkPassword();
          break;
        case '#':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case 'A':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case 'B':
          Serial.println(customKey);
          s.write(customKey);
          break;
        case 'C':
          Serial.println(customKey);
          s.write(customKey);
          //s.write("\nConnecting to..");
          break;
        case 'D':
          Serial.println(customKey);
          s.write(customKey);
          break;
      }
    }
  }
}

void keypadEvent(KeypadEvent key){

  switch (customKeypad.getState()) {
    case PRESSED:
      // Serial.println(key);
      //s.write(key);
      switch (key) {

        case '*': 
          checkPassword();
          break;

        case '#': 
          ssid.reset();
          pass.reset();
          connection.reset();
          break;

        default: 
          ssid.append(key);
          pass.append(key);
          connection.append(key);
      }
  }
}

void checkPassword(){

  if (ssid.evaluate()) {
    Serial.println();
    Serial.println("SSID verified");
    Serial.print("enter password: ");  
  } else if (pass.evaluate()){ 
    Serial.println();
    Serial.println("Password verified");
    Serial.println("press C to connect"); 
  } else if (connection.evaluate()) { 
    Serial.println();
    Serial.println("Connecting to....");
  } else {
    Serial.println("Wrong");
  }
}

我的 nodemcu 代码是:

#include <String.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
SoftwareSerial s(D6,D5); // (Rx, Tx)
String shab;
String shab2;
String arr[40];
String arr1[40];
const char* shab1="";
const char* shab3="";
std::string str;
int i,k;

void setup() {
  s.begin(9600);
  Serial.begin(9600);
  Serial.print("enter ssid: ");
}

void loop() {

  s.write("s");
  while(s.available() >0) {
    char data=s.read();
    shab += data;
    Serial.print(data);
  }

  int len=shab.length();
  if (shab.charAt(len-1)=='*') {
    for(i=0;i<shab.length();i++) {
      arr[i]=shab.substring(0,len-1);
    }
    shab1 = arr[0].c_str();
    Serial.println();
    Serial.println(shab1);
    Serial.print("Enter ur password: ");
    // delay(7000);


    // while(true){
    while(s.available() >0) {
      char data1=s.read();
      shab2 += data1;
      Serial.print(data1);
    //}
      int len1=shab2.length();
      if(shab2.charAt(len1-1)=='*') {
        for(k=0;k<shab2.length();k++) {
          arr1[k]=shab2.substring(0,len1-1);
        }
        shab3 = arr1[0].c_str();
        Serial.println();
        Serial.println(shab3);
        Serial.println("Connecting to wifi: ");
        delay(2000);
        Serial.println(shab1);
        Serial.flush();
        WiFi.begin(shab1,shab3);
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
        }
        Serial.println(" IP address: ");
        Serial.print(WiFi.localIP());
        delay(2000);
       // } 
      } 
    }

    while(1) {
      delay(1000);
    }
  }
}

现在的问题是,当我从键盘输入密码时,第二次输入 while(s.available>0) 行时,它不起作用。这不会在串行监视器上打印任何内容。谁能帮帮我?

问题是在Serial.print("Enter ur password: ");之后,程序立即计算s.available()。由于没有可用的,它在 loop() 结束时进入无限循环,并且永远不会退出它。

如果您想在收到 '*' 之前读取传入的数据,您可以这样做。

Serial.print("Enter ur password: ");

bool entered = false;
while (entered == false) { // loop until entered becomes true
    yield();
    while (s.available() > 0) {
        char data1 = s.read();
        shab2 += data1;
        Serial.println(data1);
        int len1 = shab2.length();

        if (shab2.charAt(len1-1) == '*') {
            // do whatever you need to do
            entered = true;  // now you can get out of the loop
        } 
    }
}