Состояние в цикле while не обновляется на моем mkr1010

Я использую систему сервер-клиент, в которой я отправляю данные с сервера клиенту для включения светодиода (встроенного светодиода). Светодиод должен быть выключен с помощью цифрового входа (обозначен цифрой 7 на разъеме). Поэтому я использую цикл while, который проверяет значение ввода (нажатие кнопки). Пока значение не равно LOW, светодиод остается включенным (я также использую второй светодиод на контакте 13 для двойной проверки). Я предполагаю, что цикл while будет оставлен после нажатия кнопки, к сожалению, этого не происходит. Результат условия кажется не обновленным (остается ВЫСОКИМ). Я измерил напряжение на входе при нажатии кнопки, и оно колеблется от 3,3 В до 0,0 В, так что с оборудованием все в порядке. Насколько я понимаю, цикл while всегда (перед каждым циклом) проверяет условие? почему здесь этого не происходит? я сделал что-то не так ? Я должен использовать некоторое время, потому что я никогда не знаю заранее, когда будет нажата кнопка.

это мой код:

#include <SPI.h>
#include <WiFiNINA.h>
#include <utility/wifi_drv.h>
#include "arduino_secrets.h"
///////пожалуйста, введите свои конфиденциальные данные на вкладке «Секрет»/arduino_secrets.h
char ssid[] = SECRET_SSID;        // SSID вашей сети (имя)
char pass[] = SECRET_PASS;    // ваш сетевой пароль (используйте для WPA или используйте в качестве ключа для WEP)

//int keyIndex = 0; // индекс вашего сетевого ключа (необходим только для WEP)

const int buttonPin = 7;     // номер вывода кнопки
const int ledPin =  13;      // номер вывода светодиода
int buttonState;         // переменная для чтения статуса кнопки


int status = WL_IDLE_STATUS;
IPAddress ServerIP(192,168,0,157);
WiFiClient client;

int i;
String response;




void setup() {

  WiFiDrv::pinMode(25, OUTPUT); //ЗЕЛЕНЫЙ
  WiFiDrv::pinMode(26, OUTPUT); //КРАСНЫЙ
  WiFiDrv::pinMode(27, OUTPUT); //СИНИЙ

 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);

  //Инициализируем серийный номер и ждем открытия порта:
  Serial.begin(9600);
  while (!Serial) {
   ; // ждем подключения последовательного порта. Требуется только для родного порта USB
  }
  // проверяем модуль WiFi:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // не продолжать
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
  Serial.println("Please upgrade the firmware");
  }

  // попытка подключения к сети Wi-Fi:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Подключиться к сети WPA/WPA2. Измените эту строку, если используете открытую сеть или сеть WEP:
    status = WiFi.begin(ssid, pass);
    // ждем 10 секунд для соединения:
    delay(10000);
  }

    // теперь вы подключены, поэтому распечатайте статус:
  printWifiStatus();
}


void loop() {

if (client.connect(ServerIP, 23)) {
  client.print("90");
  String response = client.readStringUntil('\n');

  Serial.println(response);

if (response == "9") {
  buttonState = digitalRead(buttonPin);
 // Serial.println(buttonState);
  while (buttonState != LOW){
    // включить светодиод:
    digitalWrite(ledPin, HIGH);
     WiFiDrv::digitalWrite(25, 255); // для полной яркости
     Serial.println(buttonState);
  } 
  digitalWrite(ledPin, LOW);
  WiFiDrv::digitalWrite(25, LOW); // для полной яркости
        }
  }

  client.stop();
}



void printWifiStatus() {
  // вывести SSID сети, к которой вы подключены:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // напечатать IP-адрес вашей платы:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
 Serial.println(ip);

  // вывести мощность принятого сигнала:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Большое спасибо за помощь!

, 👍1


1 ответ


2
 while (buttonState != LOW){
    // включить светодиод:
    digitalWrite(ledPin, HIGH);
     WiFiDrv::digitalWrite(25, 255); // для полной яркости
     Serial.println(buttonState);
  } 

Вы никогда не обновляете значение buttonState в этом цикле while. Если buttonState не является НИЗКИМ, чтобы попасть в цикл while, ничто внутри цикла while никогда не изменит его, поэтому каждый раз, когда он проверяется, он все равно не будет НИЗКИМ. Он не будет предполагать, что вы хотели прочитать вывод только потому, что вы использовали эту переменную для считывания вывода однажды раньше.

Но нужен ли вам этот цикл while? Не могли бы вы просто написать светодиодный вывод низким, когда вы впервые получаете пресс, а затем написать его высоким, когда он впервые выпущен? См. «Пример изменения состояния». Пусть функция цикла будет циклом. Это приведет к лучшему коду. Вы не видите этого сейчас, потому что вы новичок, но вы собираетесь загнать себя в угол с таким подходом, и вы скоро будете переписывать все это целиком. Это ловушка, в которую попадает большинство новых программистов. Лучше получить его прямо сейчас.

,

Ага. Как правило, вы не хотите использовать циклы while внутри функции цикла вашего скетча. Это почти всегда неправильный подход., @Duncan C

Вы не хотите использовать циклы while где-либо в своем коде, ожидая, что что-то произойдет во внешнем мире. Цикл while предназначен, например, пока у меня есть еще символы в этой строке или пока я не очистил весь массив. У вас никогда не должно быть циклов while, блокирующих ваш код, ожидающих, когда что-то физически произойдет. Это заманивает вас в ловушку, так что во время ожидания ничего больше не может произойти., @Delta_G

Хороший способ объяснить это., @Duncan C

большое спасибо вам обоим! теперь работает. Я не знал об этом (никаких моментов при обнаружении внешних событий)., @Majid