I'm an ultranoob and I'm not able to get out of a while loop

So i have a tiny led lamp connected to the port 5 of my NodeMCU. And I activate it with Alexa (alexa updates IFTTT and IFTTT updates Adafruit IO) so everything here works until I arrive at the WHILE in the code.

I have 4 commands
ON (IF)
OFF (IF)
PULSE(IF)
BLINK (WHILE)

In fact, if I try to “BLINK” the light in this condition and I try to exit with an “OFF” command the light is just irresponsive and keeps on blinking.

Checking on my Adafruit dashboard I see the new command (so it updates there). However, it seems like the following code

if (!strcmp((char*) onoff.lastread, "OFF"))
            {
              break;
            }

is not able to recognize the new char* and it is stuck at the old one (BLINK).

I apologize for the position of the parenthesis and other things but I am a real noob in this. This is the full main loop.

void loop()
{
  MQTT_connect();
  
  Adafruit_MQTT_Subscribe * subscription;
  while (subscription = mqtt.readSubscription(5000))
  {
   if (subscription == &onoff)
      {
      if (!strcmp((char*) onoff.lastread, "ON"))
         {
          digitalWrite(5, HIGH);
         }
      if (!strcmp((char*) onoff.lastread, "OFF"))
         {
          digitalWrite(5, LOW);
         }
      while (!strcmp((char*) onoff.lastread, "PULSE"))
         {
        float in, out;
        for (in = 0; in < 6.283; in = in + 0.001)
            {
             out = sin(in) * 127.5 + 127.5;
             analogWrite(5,out);
            }
         }
      while (!strcmp((char*) onoff.lastread, "BLINK"))
         {
          digitalWrite(5, HIGH);
          delay(250);                     
          digitalWrite(5, LOW);   
          delay(250);                   
         
          if (!strcmp((char*) onoff.lastread, "OFF")){
              break;
            }
         }         
     }   
   }
  if (!mqtt.ping())
  {
    mqtt.disconnect();
  }
}

It would be nice if someone could give me some options (i also tried the DO WHILE loop but no luck)

Thank you very much also if you just visited and read without answering!

How can lastRead change inside the while loop if you never do any reads while you are there?

How about if instead of while?

Welcome to the forums. Thank you very much for using code tags to post your code, although you should always post your complete sketch. Who knows how you defined your variables, etc. unless we can see them.

As for your code, I think you want to be using if()… else clauses. You simply test for onoff to be “ON” and then turn on an led. Then you test for “OFF”, etc. If it is “ON”, it can’t be “OFF” or “BLINK” or anything else.

I’m not that familiar with MQTT, so you may need to tweak this:

void loop()
{
  MQTT_connect();

  Adafruit_MQTT_Subscribe * subscription;
  while (subscription = mqtt.readSubscription(5000)) {
    if (subscription == &onoff) {
      if (!strcmp((char*) onoff.lastread, "ON")) {
        digitalWrite(5, HIGH);
      }
      else if (!strcmp((char*) onoff.lastread, "OFF")) {
        digitalWrite(5, LOW);
      }
      else if (!strcmp((char*) onoff.lastread, "PULSE")) {
        float in, out;
        for (in = 0; in < 6.283; in = in + 0.001) {
          out = sin(in) * 127.5 + 127.5;
          analogWrite(5, out);
        }
      }
      else if (!strcmp((char*) onoff.lastread, "BLINK")) {
        digitalWrite(5, HIGH);
        delay(250);
        digitalWrite(5, LOW);
        delay(250);
      }
    }
  }
  if (!mqtt.ping()) {
    mqtt.disconnect();
  }
}

Also, it is not a good idea to use a ‘float’ as the index in a for() loop since they are not precise. You also iterate over 6000 times given your current step size. The analogWrite() function takes an value between 0-255 so your loop is constantly being truncated and the same value gets written many times.

As for the parenthesis, etc. Format your code with Ctrl-T in the IDE.

Thanks so much for the answers guys I'll try out and report!

I already tried also the if else but it had the same issue.

I showed it to a friend of mine and he said that it's the ugliest code he'd ever seen :cry:

By the way this is the full code

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define WIFI_SSID "Bbox-C4BF90E8"
#define WIFI_PASS "MASTROLINDO"
#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "sammyragazzofoca"
#define MQTT_PASS "7f0fc0999d2241fda99923d0ca5fc27b"

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);
Adafruit_MQTT_Subscribe onoff = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/onoff");
void setup()
{
  Serial.begin(9600);

  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  mqtt.subscribe(&onoff);
  pinMode(5, OUTPUT);
}
void loop()
{
  MQTT_connect();

  Adafruit_MQTT_Subscribe * subscription;
  while (subscription = mqtt.readSubscription(5000))
  {
    if (subscription == &onoff)
    {
      if (!strcmp((char*) onoff.lastread, "ON"))
      {
        digitalWrite(5, HIGH);
      }
      if (!strcmp((char*) onoff.lastread, "OFF"))
      {
        digitalWrite(5, LOW);
      }
      if (!strcmp((char*) onoff.lastread, "PULSE"))
      {
        float in, out;
        for (in = 0; in < 6.283; in = in + 0.001)
        {
          out = sin(in) * 127.5 + 127.5;
          analogWrite(5, out);
        }
      }
      while (!strcmp((char*) onoff.lastread, "BLINK"))
      {
        digitalWrite(5, HIGH);
        delay(250);
        digitalWrite(5, LOW);
        delay(250);

        if (!strcmp((char*) onoff.lastread, "OFF")) {
          break;
        }
      }
    }
  }
  if (!mqtt.ping())
  {
    mqtt.disconnect();
  }
}


/***************************************************
  Adafruit MQTT Library ESP8266 Example

  Must use ESP8266 Arduino from:
    https://github.com/esp8266/Arduino

  Works great with Adafruit's Huzzah ESP board & Feather
  ----> https://www.adafruit.com/product/2471
  ----> https://www.adafruit.com/products/2821

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Tony DiCola for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/

void MQTT_connect()
{
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected())
  {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
  {
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0)
    {
      // basically die and wait for WDT to reset me
      while (1);
    }
  }
  Serial.println("MQTT Connected!");
}

I apologize for before that I said I had an if for the pulse but it was a while. Now it’s correct.