text:
NodeMCU MQTT getting topic but not calling IF loop
I am very new to Arduino/ESP and I am writing a code to activate 2 relays using MQTT. My connection is successful and I am able to receive message/topic printed out on serial console. Here is my code:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "SSD1306Wire.h"
#define wifi_ssid "SSID"
#define wifi_password "PASSWORD"
#define mqtt_server "192.168.1.1"
#define mqtt_user "mqtt_username"
#define mqtt_password "mqtt_password"

SSD1306Wire  display(0x3c, D2, D1);
const int relay1 = 5;
const int relay2 = 4;
String header;
String output5State = "off";
String output4State = "off";
const int output5 = 5;
const int output4 = 4;
WiFiClient wificlient;
WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server(80);

//------------------- MAIN WEB PAGE ------------------------
const char MAIN_page[] PROGMEM = R"=====(
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>HOME IOT</title>

Security Door

<button class="button">Open</button>

<button class="button">Close</button>

)=====";
//------------------- MAIN WEB PAGE ------------------------

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  //-----------------------------------------
  WiFiManager wifiManager;
  //wifiManager.resetSettings();
  wifiManager.autoConnect("IOT-LivinRoom");
  //-----------------------------------------
  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("Initializing OLED Display");
  display.init();

  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  Serial.println("HTTP server started");
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    messageTemp += (char)payload[i];
  }
  Serial.println();
  Serial.print(messageTemp);

 if(topic=="livingroom/securitydoor"){
     Serial.print("Changing esp01 relay1 to ");
     if(messageTemp == "on"){
       digitalWrite(relay1, LOW);
       Serial.print("On");
       Serial.print("On from opening");

     }
     else if(messageTemp == "off"){
       digitalWrite(relay1, HIGH);
       Serial.print("Off");
       Serial.print("On from Closing");
     }
 }
 Serial.println();

 if(topic=="livingroom/ac"){
     Serial.print("Changing esp01 relay2 to ");
     if(messageTemp == "on"){
       digitalWrite(relay2, LOW);
       Serial.print("On");
       Serial.print("On from opening");

     }
     else if(messageTemp == "off"){
       digitalWrite(relay2, HIGH);
       doorClosing();
       Serial.print("Off");
       Serial.print("On from Closing");
     }
 }
 Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      client.subscribe("livingroom/securitydoor");
      client.subscribe("livingroom/ac");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//--------------------------- void loop-----------------------
void loop() {

  server.handleClient();
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

}

//----------------------------- Web Calls Function -----------
void handle_OnConnect() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s);
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

Issue is: message from below is not printing in serial
       Serial.print("On");
       Serial.print("On from opening");

In fact code is displaying topic and message in serial console.
My actual user case is to display status on OLED display as well as control relay.

That's not how you compare C strings.  You're comparing two addresses there, and they will never match.  Read up on strcmp.

thanks for suggestions,
When i am doing it in below way, it got worked
if (strcmp(topic, "livingroom/securitydoor") == 0)
  {
    Serial.print(topic);
  }


text:
Syntax for stopping loop until the condition has made false
I am taking reading from temperature sensor and from that data. I have to control 3 LEDs. Lets consider LED1, LED2, LED3.
If temperature range between 0-20
   I have to HIGH LED2.
   else if temperature range between 20-30
I have to HIGH LED1; HIGH LED3; LOW LED1;

my sketch is something like this:-
while(1)
{
if(temp>=0&&temp<=20)
{
digitalWrite(2,HIGH);
}
else if (temp>=20&&temp<=30)
{
digitalWrite(1,HIGH);
digitalWrite(3,HIGH);
digitalWrite(1,LOW);
}
}

The problem which I am facing is LED1 is continuously ON (which should be OFF), when temperature is between 20-30 because of continuously running loop so, how can I stop loop, once the statement under second condition has executed till the second condition has made false.

Don't understand your "I have to HIGH LED1; HIGH LED3; LOW LED1;" ? What do you want for LED1 ?

I want to first ON LED1 then ON LED2 then OFF LED1

when the condition2 is satisfied  and stop the loop till the condition 2 is made false

If the temperature is exactly 20, which LEDs should be on/off? Shouldn't LED2 be in this statement somewhere "I have to HIGH LED1; HIGH LED3; LOW LED1;".

yeah sorry brother  have to mention LED3 at the place of 2 ... as according to you

let me explain again if the temperature is between 20-30 condition2 will be executed as LED1 HIGH; LED3 HIGH; LED1 LOW . after execution i have to stop loop till the condition 2 is made false i.e temperature exceeds 30 or decrease below 20. while stoping the loop we also have to continuously taking reading from temperature sensor –

if the LED is supposed to be off, then why do you not turn it off?

You don't want to stop the loop! You want it to run fast and often.
Eventually you want it to not change the current state of a LED, but in your case, I rather do not see enough defined states of LEDs.

I want to first ON LED1 then ON LED2 then OFF LED1"

if then means an amount of time, remember that loop runs fast and does not take time by itself. You will have to notice the starting point in time and compare that with the current time and your desired intervals. (And you do not mention what should happen to LED2 after the second then )
const unsigned int LED1_DURATION=500;
const unsigned int LED3_DURATION=1000;
bool c2 = false;  // true while condition2 is met
unsigned long start2;  // time when condition2 starts
void loop() {
  int temp = analogRead(A0); //read a temp value somehow
  if(temp<=20)
  {
    digitlaWrite(1, LOW);
    digitalWrite(2,HIGH);
    digitlaWrite(3, LOW);
    c2 = false;
  }
  else if (temp >20 && temp <= 30)
  {
     digitalWrite(2, LOW);

     if (c2 == false) { c2 = true; start2=millis(); } // detect start time

     if ((millis() - start2 < LED1_DURATION) ||
         (millis() - start2 > LED3_DURATION)   )
          digitalWrite(1,HIGH);
     else digitalWrite(1, LOW);

     if ((millis() - start2 > LED1_DURATION) &&
         (millis() - start2 < LED3_DURATION)    )
          digitalWrite(3,HIGH);
     else digitalWrite(3,LOW);
  }
  else
  {
    digitlaWrite(1, LOW);
    digitalWrite(2, LOW);
    digitlaWrite(3, LOW);
    c2 = false;
  }
}

This code contains a couple of guesses about states you did not mention, and a slightly different behavior (sorry), but I hope you get an idea...

LED2 has to be off if the condition1 is not correct...

let me explain again if the temperature is between 20-30 condition2 will  be executed as LED1 HIGH; LED3 HIGH; LED1 LOW . after execution i have to stop loop till the condition 2 is made false i.e temperature exceeds 30 or decrease below 20. while stoping the loop we also have to continuously  taking reading from temperature sensor

sorry i have a mistake at the place of LED2 it should be LED3

"while stoping the loop we also have to continuously taking reading from temperature sensor" So don't call it stoping You're simply in the part 'Condition2' but the time has exceeded both then times and your LEDs have a desired state.

i dont get what you said

suppose  then be delay of 1 sec

see my added sample code with 2 * 500 msec

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"
C:\Users\ashwa\AppData\Local\Temp\cc3u0raS.ltrans0.ltrans.o: In function `main':
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino/main.cpp:43: undefined reference to `setup'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Uno.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

its showing error

Don't try to copy/paste the code DataFiddler posted and complain when it gives compile errors It's intended to be a guide, not the exact code for your problem. Study the approach they're recommending and then apply that approach to your problem. The idea is that you don't "stop the loop", you use a combination of flags to keep track of state, and timers to track when events occur. You then write code that checks the current value of millis() on each pass through the loop, waiting for the desired amount of time to pass.

i am not getting code of datafiddler

is it possible to send compiler back ..back in the sense sending compiler 2-3 statement back

In the answer's code the function setup() is missing, where pinMode for output pins has to be set. You should be able to add this yourself. 2. You should know and understand the basic BlinkWithoutDelay principle, and be able to apply that principle to anything requiring an amount of time without "stopping" loop()

I do not understand " sending compiler 2-3 statement back "

Your code doesn't make sense. You have a while (1) statement, which will run forever. Inside the body of that statement, you never change the value of temp.
An Arduino sketch's loop() function runs continuously. You should not have a while (1) loop inside your loop function. You should have a loop function something like this:
void loop() {
  temp = //read a temp value somehow
  if(temp>=0&&temp<=20)
  {
    digitalWrite(2,HIGH);
  }
  else if (temp>=20&&temp<=30)
  {
    digitalWrite(1,HIGH);
    digitalWrite(3,HIGH);
    digitalWrite(1,LOW);
  }
}

With that loop function you would fetch a new value of temp on each pass through the loop, then decide what LEDs to light.

I have edited the code as u said     but  I am facing the problem i have to stop LED1 till the condition 2 is made false ...but it is continuously ON

I have to stop loop till the  condition 2 has made false along with  continuously taking reading of temperature

This is much better than the original question's sketch, but still very questionable: 2 will never be LOW, once it was set  HIGH; 3 will never become LOW, once it was set HIGH; 1 is considerably dimmed, if temp is between 20 and 30. (dimming depends on the time it takes to read temp)

@DataFiddler The OPs logic is incomplete, and I didn't attempt to address those issues. I was just trying to explain how to write code that gets called continuously.

"I have to stop loop..." No. Full stop. You should not write a sketch that freezes the loop until some condition occurs. That is a very bad idea. You need to come up with a different approach.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
This code gives the wrong output. Why?
void setup()
{
  int calc(9,2);
  Serial.begin(9600);
}

void loop()
{}

int calc(int val1, int val2)
{
  Serial.print(val1 + val2);
}

It's not syntax error, i am getting output as 1, i should get 11.

what is int calc(9,2);? you print before Serial.begin()

There are two serious warnings, indicating that the compiler obviously does not understand your intentions. ( Neither do I :) )

A function's name should tell what it does.
Something called calc() should not mainly print (except for debug purposes))
void setup() {
  Serial.begin(9600);
  printSum(9,2);
}
void loop() {}

void printSum(int val1, int val2) {
  Serial.print(val1 + val2);
}

The other good approach is to really define a function returning a result.
int calc(int a, int b) {
   return a+b;
}
void setup() {
   Serial.begin(9600);
   Serial.println(calc(9,2));
}
void loop() {}

If your goal is to call your function with int calc(9,2);, you might want to change it to calc(9,2);, this is the way to call functions, no type declarator needed if you arent creating said function (or in a declaration, wich has nothing to do in the setup)
If you want to declare your functions, it must be done at the very top of your code, out of the setup function, and with arduino 1.8.9 on my end, this is not mandatory.
Also, you are calling your printing function before the Serial.begin(), one good practice may be to Serial.begin() at the very top of your setup, so you don't make mistakes on why your debug is not showing.
As on why you have a 1 printed, if that's all your code, i don't really know, i have no output when i try your code on my end
tl;dr;
void setup() {
  Serial.begin(9600);
  calc(9,2);
}

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Cannot get esp8266 - 12 wifi module to always read analogRead incoming voltage accurately
So I have and arduino uno that is firing an output on pin 8. This code is not in this file just to be clear. From there Im taking that output and using it to fire pin 0 on the wifi module. Im using pin 0 because from what I understand all other pins have a pullup or pulldown resistor. When pin 0 is hot I want to print that value. Sometimes it works when I do it other times the analog values reads very low. I am using the 3.3v from the arduino uno and I plan to get a voltage regulator for the wifi module but would this cause this kind of issue? I am very very new to arduino so if anyone has any ideas I would appreciate a very dumbed down explanation. Thanks a lot. Also the reason why I have the delay turned down so low is because it seemed to make the analog signal pick up more often. Im not sure why this would matter but at a delay of 3000 it would almost never change analog value but when I turned the delay down to one the value came through much more consistently. Currently the code just outputs low analog numbers and occasionally pops up 1023 when voltage is applied but not consistently. And sometimes it just stops altogether until I keep trying for a while. I am getting voltage to the pin however so I know I have a complete circuit and power.
include
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

const char* ssid = "ENDOWED Underwear";
const char* password = "endowwear";

HTTPClient http;

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

int featherPin = D3;

void setup() {
  Serial.begin(115200);
  pinMode(featherPin, INPUT);

  WiFi.begin(ssid, password);

  while(WiFi.status() != WL_CONNECTED) {
    delay(10);
    Serial.println("Waiting for connection");
  }
}

void loop() {
  int sensorValue = analogRead(featherPin);

  if (WiFi.status() == WL_CONNECTED) {
        Serial.println("yay connect");

        http.begin("http://10.150.40.121:3000/");
        http.addHeader("Content-Type", "text/plain");

        int httpCode = http.POST("Message from ESP8266");
        String payload = http.getString();
//        Serial.println(payload);
        http.end();

    } else {
        Serial.println("Error in Wifi connection");
    }

    if (sensorValue > 850) {

      http.begin("http://10.150.40.121:3000/home");
      http.addHeader("Content-Type", "text/plain");

      int httpCode = http.POST("Message from ESP8266");
      String payload = http.getString();
      Serial.println(payload);
      Serial.print("hi");
      http.end();
      } else if (sensorValue < 850) {
        Serial.print(sensorValue);
//        Serial.println("I am not hot");
      }

//  digitalWrite(trigPin, LOW);
//  delayMicroseconds(1);
//  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(2);
//  digitalWrite(trigPin, LOW);
//
//  pinMode(echoPin, INPUT);
//  duration = pulseIn(echoPin, HIGH);
//
//  inches = (duration / 2) / 74;
//  Serial.println(inches);
//
//  spaceIntruded = inches;
//
//  if (spaceIntruded <= 50 || spaceIntruded >= 900){
//      digitalWrite(ledPin, HIGH);
//      digitalWrite(hornPin, HIGH);
//      Serial.println("Intruder Detected!");
//      Serial.println("Sending text Notification...");
//      delay(500);
//      Serial.println("Armed...");
//  }
//
//  else{
//    digitalWrite(hornPin, LOW);
//    digitalWrite(ledPin, LOW);
//  }
    delay(1);

}

When pin 0 is hot I want to print that value...? What value? What do you mean by "hot"?

When pin 0 on the Arduino uno is hot meaning it has 3.3v applied to it I want to analogRead the change in value. If no voltage is applied it should read as a lot number and when voltage is applied it should read as a high number and sometimes it does but it in no way consistent. Im not sure if its because Im taking the 3.3v from the arduino uno but i also tried taking it from the 5v on the arduino uno and steeping it down with a voltage regulator and Im getting the same issue. However it was adjustable voltage regulator. Im going to get one that is specifically for 3.3v.

Do you have the pin connected to the analog input pin as well as pin 0?  You do know that the ESP8266 has only one analog input, and that is a special pin and not one of the normal Dx pins, yes?

No I didnt and I not to clear on what you mean by DX pin and I have pins soldered for each pin and im am maunally touching the output from the arduino uno to the 0 pin and no consistent change occurs. As of right now its working at all but at times it does. But the pin is not connected to an analog pin its just a pin. All the pins are soldered on and im only using pin 0 cause it doesnt have a pullup pulldown internal resistor. When tried using the other pins I couldnt get the value to change at all. Only when I chnaged to 0 did it read the change sometimes.

https://www.microcenter.com/product/460313/feather-huzzah-with-esp8266-wifi
This is the wifi module I am using

The pin labelled ADC is the only one that can be used with analogRead. And unless that board includes a divider it can't read more than 1V.

Do you think I could step down the voltage to one volt and work with it that way. I'm only keeping track of one value or how would ypu go about it. I have two files one for arduino uno and one for the feather. I just want to read and chnage the state of one pin. I set of a sensor in the arduino program that fires an input and makes kne pin on the Wi-Fi module that I can read the change from low to high. I also dont know much about rx TX but ive read I can talk to the module or should I use a different Wi-Fi module. Thanks again for your help.

Yes. Yes you can. Google knows how.

I understand Google knows how. Ive googled my way up to this point. I'm just seeking some direction from someone with experience becuase I just started learning two days ago so certain things I'm confused on. Ive read dozens of articles so if you could guide me in a direction or maybe explain it from your point of virw I would greatly appreciate it. Thanks a lot for your help.

The key word, which I have already mentioned, is "divider". Specifically voltage divider. A basic principle of electronics that you need to learn. The board may already have it though, so check the manual or schematic.

This is cool. Thank you. I need this. My last question is the pin labeled adc can I treat this pin like a regular analog read as far as the code goes and do you know why I cant do a digital read. Is it because its floating until its not. I'm mainly curious now. Thanks again. This is helpful.

why do you want to use troubled ADC of the esp8266 if you have an Uno with 5 good analog inputs in project setup?

The ADC pin can only be used with analogRead(). No other pin can, and nothing else can be done with the ADC pin. It is directly connected to the ADC internal to the chip and nothing else. You can't use digitalRead(), digitalWrite(), pinMode() or analogWrite(). It doesn't even have a pin number to use with those functions.

Majenko is right that the only pin you can use with analogRead is pin A0. I would add that I think you are making a mistake in assuming that any of those other pins can be used. I'm also new to this but I have two NodeMCU ESP8266 units and only a few pins are actually useful as input or output. Many of the pins are dedicated to other uses like serial RX/TX, storage, and RST. Pin D3, in particular, is reserved for FLASH. Some info here.

I would also add that analogWrite does NOT just set some voltage level on a pin. The pins can only go to 0 or 3.3 -- i.e., completely on or completely off. In order to emulate some voltage level in between, the ESP8266 will use PWM, which is basically switching the voltage on and off quickly to mimic the intermediate voltage.

Analog to Digital conversion is one aspect1 where the ESP8266 is very poor. It has a single ADC pin which can read a maximum of 1V.
That pin is the only pin you can use with analogRead(). Any attempts to use any other pin just use that pin instead. The parameter (pin number) to analogRead(pin) is ignored and no matter what you do that one single ADC pin is what is being read. Also the pin cannot be used for anything else. None of the digital functions can be used with it since the pin doesn't have a GPIO number associated with it.
Some boards include a simple voltage divider on the ADC pin to allow higher voltages to be read, such as the NodeMCU:

If your board doesn't have such a divider you will have to implement it (or something similar) to be able to read the 3.3V incoming voltage.

1 The ESP8266 is great for WiFi but pretty poor for everything else. It is seriously starved of internal peripherals (it doesn't even have I²C). For a more feature-rich solution you might consider upgrading to the ESP32.


text:
Reset an Arduino Uno in code
Is it possible to reset an Arduino (i.e., to reboot it) from code (i.e from the sketch itself)? I know that is possible with a special circuit but is there a chance to make it just with code?
Below is my code and the comment //reset is where I want to force a reset.
#include <TrueRandom.h>

int i;
int randSeed;
long randNumber;

void setup(){
  Serial.begin(9600);
  Serial.println("20 pseudo Zufallszahlen:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println();
  //randomSeed(TrueRandom.random());
  randSeed = analogRead (A0);
  randomSeed(randSeed);
  Serial.print("Der 'seed' Wert: ");
  Serial.println(randSeed);
  Serial.println();
  Serial.println("20 Zufallszahlen mit analogem 'seed' Wert:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println("---------------------------");
  Serial.println();
  delay(500);
  //reset
}

void loop() {
}

I want to reset the micro-controller at the end of the setup function to show the effect of random numbers with and without a seed.

There three ways to accomplish this. (last is my favorite)
1) Jumper an unused IO to the RESET pin. Leave it as INPUT for normal
    run, As it is externally pulled high. And when desired to reset set
    it as LOW and Output. (bang its rebooting).
setup() {
  ...
  pinMode(PINtoRESET, INPUT);    // Just to be clear, as default is INPUT. Not really needed.
  digitalWrite(PINtoRESET, LOW); // Prime it, but does not actually set output.
  ...                            // Does disable 10K pull Up, but who cares.

then when desired...
...
  pinMode(PINtoRESET, OUTPUT);   // lights out. Assuming it is jumper-ed correctly.
  while(1);                      // never gets here.

2) Jump to beginning of the code.
void(* resetFunc) (void) = 0;  // declare reset fuction at address 0
...
resetFunc(); //call reset

But be careful, this does not perform a true reset, in that all the registers ARE NOT DEFAULTED. Rather they and the IO are left as is. Where somethings from the bootloader and then the heap will be initialized. And reset are not!
3) Use the watchdog. The SoftReset library makes it easy. Although it is not difficult to implement directly. Shown below..
#include <avr/wdt.h>
...
setup() {
  ...
  MCUSR = 0;  // clear out any flags of prior resets.
  ...

then when desired...
...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) {
  // do nothing and wait for the eventual...
}
...

From everything I've read, the first option is not recommended. Options 2 and 3 are fine.

@sachleen: Please say more about that (opt-1).

Option 1. or a variant can be a clean enough way to do this as long as power on transient conditions are designed for.

@RussellMcMahon - How does one design for the Power on transient conditions?

It should be noted that option 2 does not run the bootloader.

Wouldn't calling resetFunc() not reset the stack? So calling it repeatedly would overflow the stack.

Option 1 is not recommended by the chip designer, Atmel. They do not recommend performing a reset with the chip's pins.

Option 3 works only with bootloaders that have WDT enabled. It puts board into reset loop otherwise.

Option 2 executes the same code that runs when you do a hardware reset or a power-up: the chip always begins at address 0.

Option 2 should be edited to add the fact that not every chip begins at address 0. A pointer to the function to be called should be used instead
void(* resetFunc) (void) = &setup; (in this case setup should be called to begin again, or even main if it makes sense)
I just had the case with stm32 where it begins later in the memory.

Option 2 is a null pointer assignment of a function pointer that actually points to nothing when calling the function. Calling this is illegal, cause a null pointer exception and without exception handling results in a reboot. That is a dirty trick and unreliable to recommend. For all believers, the pointer is a pointer to a VOLATILE memory location, not a program memory (flash) location. @Dardanboy, calling setup() is not a reset and yes all memory start at location 0 however it could be possible not all lower memory is accessible

@Codebeat Nope, this is an actual valid memory address in the program flash, where the embedded program begins.

@DmitryGrigoryev Nope, it is a valid offset you can jump to, not a valid address. Do not confuse these two.

I'm laughing at the comment, "lights out" — thanks. Wish I had a spare I/O pin.

In case you have the original Arduino bootloader which you want to execute as a part of the reset, you can do a SW reset by jumping to the bootloader reset address (0x7800 on ATmega328p boards)
void reset() { asm volatile ("jmp 0x7800"); }

The watchdog reset approach will not work because of a bug in the bootloader. Here's a note from ATmega328P Datasheet page 45:

Note: If the watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the watchdog timer will stay enabled. If the code is not set up to handle the watchdog, this might lead to an eternal loop of time-out resets. To avoid this situation, the application software should always clear the watchdog system reset flag (WDRF) and the WDE control bit in the initialization routine, even if the watchdog is not in use.

This is exactly what will happen after a watchdog reset on a system with Arduino bootloader.

Yes, I have observed the eternal loop of timeouts, while answering the question, "I wonder if the boot loader resets the WDT" Why not just do "jump 0x0" ?

@EricNelson Jumping to 0x0 will not run the bootloader, which is one of the two major use cases for a software reset. The second use case, resetting the system to a known state, is not possible without a bootloader with WD support or connecting the reset pin to a GPIO.

@DmitryGrigoryev For some reason, Visual Studio thinks this is invalid syntax. It underlines the semicolon in red saying it expected a '('. The code will compile, however. I'm guessing it's some sort of discrepancy between Visual Studio and Visual Micro (the arduino plugin for VS).
However, the arduino also gets reset if I leave out the volatile keyword (and that way, Intellisense doesn't complain). Are there any side effects to this?

@Bas volatile prevents the compiler from over-optimizing your code. Technically, the compiler is allowed to eliminate the reset function entirely as it has no side effects visible to the C compiler. Of course, modern compilers are usually smart enough not to do this (e.g. volatile is not necessary with GCC which knows it's forbidden to optimize jmp), but strictly speaking the reset is not guaranteed to happen without volatile on a random compiler.

Thanks @DmitryGrigoryev! Turns out that Intellisense thinking it was invalid syntax was indeed an older version of Intellisense in combination with VMicro. Updating VMicro resolved the issue. Either way, it now works with the volatile keyword as well.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to receive data from my server database to a variable in my Arduino?
I am learning to work with the client - server communication. I am able to communicate with my server and able to store values in the table. But I want to receive one of the specific data from the database.
Here I want to get the 'abc' value from the 'Current' column to store in a variable in my Arduino.
Below is the code that I have done until now. I would be really happy if you could solve the problem.
Here is my database structure
---------------------------------------------------
| Device |  Previous |  Next |  Distance |  Current|
---------------------------------------------------
|katup123| xyz       | abc   | 2.600     | abc     |
---------------------------------------------------

Here is my PHP code:
locator.php
<?php
$con=mysqli_connect("your_domain.com","peter","abc123","locate");
// Check connection
if (mysqli_connect_errno()) {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT Current FROM locate WHERE Device='katup123'");

while($row = mysqli_fetch_array($result)) {
  echo $row['Current'];
  echo "
";
}
?>

Here is my Arduino code:
// Include the GSM library
#include <GSM.h>
#define PINNUMBER ""
// APN data
#define GPRS_APN       "GPRS_APN" // replace your GPRS APNgpsll
#define GPRS_LOGIN     "login"    // replace with your GPRS login
#define GPRS_PASSWORD  "password" // replace with your GPRS password
// initialize the library instance
GSM gsmAccess;
GSMClient client;
GPRS gprs;
// URL, path & port (for example: arduino.cc)
char server[] = "your_domain.com";
char path[] = "/locater.php";
int port = 80; // port 80 is the default for HTTP

void setup() {
  Serial.begin(9600);
  Serial.println("Starting Arduino web client.");
  // connection state
  boolean notConnected = true;
  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  while(notConnected) {
    if((gsmAccess.begin(PINNUMBER)==GSM_READY) & (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
      notConnected = false;
    else {
      Serial.println("Not connected");
      delay(1000);
    }
  }
  Serial.println("GSM initialized");
  Serial.println("connecting...");
}

void loop() {
  char result [20];
  Serial.print(" Connecting to server Database ");
  if (client.connect(server, port)) {
    client.print("GET /locator.php?");
    Serial.print("GET /locator.php?");
    client.println(" HTTP/1.1");
    Serial.println(" HTTP/1.1");
    client.println("Host: www.your_domain.com");
    Serial.println("Host: www.your_domain.com");
    client.println("User-Agent: Arduino");
    Serial.println("User-Agent: Arduino");
    client.println("Accept: text/html");
    Serial.println("Accept: text/html");
    client.println("Connection: close");
    Serial.println("Connection: close");
    client.println();
    Serial.println();
    Serial.println("\nCOMPLETE!\n");
    client.stop();
  } else {
    Serial.println("connection failed");
    Serial.println("\n FAILED!\n");
  }
  delay(5000);
}

Here I want to store the 'abc' value to my 'result' variable. I don't know how to do it.

To get data from a webserver to the arduino, just make a hph or html page with the value written on the page. That way you can get the value from the webserver by requesting the page and then use the value in your code. Since you already have the submit done, just make another page that writes out the value from the DB.

After you send the GET request, you read the response to fill the char result [20] variable you declared:
int i=0;
...
if (client.connect(server, port))
{
  client.print("GET /locator.php?");
  ...
  Serial.println("\nCOMPLETE!\n");

  // Read response from server
  i=0;
  while (client.available())
  {
    result[i] = client.read();
    Serial.print(result[i]);
    i++;
  }

  client.stop(); // disconnect
}

This is an example, result will contain the text output by locator.php. You will need to tweak this code to apply to your case. The above code has no error checking of any kind. Also, you should perform a check and only make the web call one time.
In locator.php you should replace echo "
"; with echo "\n";. And for good measure, make sure there is no white space before <?, and remove the trailing ?>.

If you have your Arduino on tcp/ip your answer can be found in O'Reilly's Arduino Cookbook: Recipe 15-4.  As Sourcery mentioned you need to make a new page on the PHP side that spits out just the data you are looking for and then use a web client on the Arduino side to download that data.
If you don't have your Arduino on the network then you have to stick the data over the serial line.  One way would be to bake it into your source and recompile/reburn the Arduino.  A smaller hammer would be to build-in something to your Arduino sketch that can deal with getting the data via USB serial and have a shim on the computer side to pull the data from PHP and send it to the Arduino.  Serial communication with Arduino and Processing shows something similar where he is running Processing on the computer which is passing data to the Arduino.

the first link is for authorized users only, and the second is a 404.

I fixed the second URL.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Using HC-SRO4 sensor and looking for obstacle
I am working in TinkerCAD, I want to design and simulate a circuit in which there are following components: 1.)An Arduino board. 2.)A potentiometer 3.)An HC-SRO4 sensor 4.)An LED.
So, the sensor should be able to tell if the range that has been set via the potentiometer has any objects in it or not. And if there are one or more objects in that range then the LED should also light up. Also, the user should be able to change the range using potentiometer during simulation.
I have attached the code here, but for some reason, I don't feel satisfied. Here is a list of the possible reasons. 1.) For LED lightening up, I had to use another if else , since it was showing an error else used without a previous if if I used LED in the same if else2.) The theoretical range for the sensor I have used is 2cm-400cm but in my circuit, it was not showing the upper range as 400cm.
Please tell the possible solutions. Also, can I improve my code and circuit
Here is the code which I used.
const int echoPin = 6;
const int pingPin = 7;

void setup()
{
 Serial.begin(9600);//Starting serial terminal
}

void loop()
{
  int sensorValue = 0;//Setting variable
  int mappedValue = 0;
  const int potentiometerRange = 0;//setting the buttons to variables to avoid confusion.
  long distance;//declaring a varible in loop because we can change the range during runtime.
  long actualDuration;//...
  long duration;
  pinMode(A0,INPUT);
  pinMode(11,OUTPUT);
  digitalWrite(11,LOW);//
  sensorValue = analogRead(potentiometerRange);//reading the potentiometer value.
  mappedValue = map(sensorValue,0,1023,2,400);//mapping the value accordingly for ultrasonic sensor.
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);//to ensure a clean high pulse later
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);//to trigger the ping.
  delayMicroseconds(10);
  digitalWrite(pingPin, LOW);
  pinMode(echoPin,INPUT);//noe echo which tuns low in the time when waves return back.
  duration =  pulseIn(echoPin,HIGH);//time calculated by sensor
  //calculation of distance from any object
  actualDuration = duration/2;//reducing the time in half for the distance is half only.
  distance = 0.0343*actualDuration;//keeping in mid that speed of sound is 343 m/s and pulseIn returns time in microseonds.
  if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
  else
    Serial.println("NO");
  if(mappedValue>=distance)
    digitalWrite(11,HIGH);
  else
    digitalWrite(11,LOW);
   delay(500); // Delay a little bit to improve simulation performance
}

I'm also attaching the picture of my circuit.

I don't feel satisfied .. maybe because you didn't have your morning coffee .... lol ...

What does "not showing the upper range as 400cm" mean?

@chrisl it means that the green area that is there during simulation which is kind of in front of the sensor, there we can look for the range right, it's showing 334.5 cm and not according to the theory as 400 cm.

@jsotola lolol, pm for these queries lol

For me that sounds like a Tinkercad problem. Simulators like Tinkercad are very limited, so you might get strange results, when hitting these limits anywhere. When using a real Arduino, you might not see this behavior

There's not much code there, so not much to optimize. I will however show you how to combine your two ifs.
You have:
if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
  else
    Serial.println("NO");
  if(mappedValue>=distance)
    digitalWrite(11,HIGH);
  else
    digitalWrite(11,LOW);

and I guess you tried this:
if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
    digitalWrite(11,HIGH);
  else
    Serial.println("NO");
    digitalWrite(11,LOW);

That would be correct in Python where the indenting matters (oh how that brings back the PTSD of having to work with COBOL...) but not in C.  In C indenting is ignored completely. It's only there for our benefit in reading the flow of code.
Instead to group statements together within an if or an else (or any other conditional or loop structure) you wrap those statements in a block. That is, place { before it and } after it.  Thus:
if(mappedValue>=distance)//checking if the object is in range
{
    Serial.println("YES");
    digitalWrite(11,HIGH);
}
  else
{
    Serial.println("NO");
    digitalWrite(11,LOW);
}

Or with my preferred formatting:
if(mappedValue>=distance) { //checking if the object is in range
    Serial.println("YES");
    digitalWrite(11,HIGH);
} else {
    Serial.println("NO");
    digitalWrite(11,LOW);
}


text:
Why is my analog output limited to 2.7V?
I have an MKR WIFI1000 (v2.0 [Arduino:XYZ]) with a "real" analog output pin (DAC0/A0/PIN15). According to the documentation, this is a 10 bit DAC, so I assume I can write analogWrite(15, 1023) to have an output of 3.3V on that pin.
However, I don't seem to get it higher than 2.7V, which is already reached well before a value of 256.
This is my code:
#include <Arduino.h>

#define AN_OUTPUT 15

int counter = 0;

void setup()
{
  pinMode(AN_OUTPUT, OUTPUT);
}

void loop ()
{
  counter++;
  if (counter > 1023) {
    counter = 0;
  }

  analogWrite(AN_OUTPUT, counter);
  delayMicroseconds(1);
}

And this is the corresponding signal:

Did you explicitly set A0 to be an output? Read this text about analog output on A0? Also remember the maximum value for a 10-bit DAC is not 1024 but 1023 (2^10-1).

Well, part of it is just that it's in 8-bit mode. And just to telegraph this for anyone that wants to get stupid about it: no that's not an answer. It doesn't explain why the graph output isn't closer to 3.3V or rather 250/255 * 3.3. If more code was in the question it be clear why it isn't a sawtooth shape even. Assuming there's a good reason for that, if this were my project just to sanity check I would measure the 3.3V pin and see that it really is 3.3V and not something closer to 255/250 * 2.7. Are you running from a low battery?

@StarCat I set it with pinMode(DRIVE_PIN, OUTPUT) and DRIVE_PIN is set to 15.

@timemage I power the board from a USB port on my laptop.

Well, I have a samd21 board that isn't what you have but does use the arduino:arduino core for samd for its board definition. I tested with core version 1.8.13. I did analogWrite of 255 for the default 8-bit resolution to the DAC pin and it got within a few tens of mv of 3.3V. Just for the hell of it I did it on a PWM rather than DAC pin and it also gets pretty much right to the rail. If I use 250 it gives 3.22 V. My regulator is pretty much spot on 3.30. Not sure what to tell you other than to include more. All code and wiring information, all versions information, etc.

@timemage I updated my question

It's good that you added the code. I don't know what "v2.0 [Arduino:XYZ]" refers to.

@timemage that 's what I get for "Version" when I upload the program....

Well, it seems like you've answered it yourself, so I guess I'm just not going to worry about what it means. You didn't have the code in the question at the time I did my testing and I just didn't use pinMode / OUTPUT because there's no reason to. So, I'm curios to see if I can replicate the problem now that I know what it is using my own board.

This link had the answer, you have to remove the pinMode(PIN, OUTPUT) line.


text:
Assign a delay value generated by a random function called randomBlink()
I'm trying to make a sketch where my led blinks with random delay. I have 2 functions: ledBlink() and randomBlink(). The randomBlink use as delay parameter a random number "r" generated from 1 to 499 and pass this value to the ledBlink function to make the led blink with a delay according the random number generated. But seems like that led  doesn't consider the random value of blinkDelay. Any help is appreciated, thank you so much!
#include <JC_Button.h>

int ledPin = 11;

int ledState = LOW;
unsigned long blinkDelay;
unsigned long lastBlinkMillis = 0;

void setup() {

  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
  ledBlink();

}

void loop() {
  randomBlink();
}

you may like this https://github.com/jandrassy/SunriseClock/blob/6ad596040e6a87d569ffaacddd7988803fc5d376/SunriseClock/SunriseClock.ino#L687

set a busy flag at begining of ledBlink() ... clear it inside of the if block ... call randomBlink() only if not busy

Your problem descriptions is a bit unclear, though I think I see your problem.
On every loop() iteration you call randomBlink(), which generates a new random delay value and then calls ledBlink(), which in turn checks millis() for the time to toggle the LED and exits fast. So you are blinking only when the current blinkDelay has passed, but you generate new random values for blinkDelay on every loop() iteration - so really really fast. In the time needed for even the small delays you may have generated thousands of new random values, so it is very likely that some of them are rather small values. You check against these so you only get short delays.
Think of how you would do such thing in real life. Lets say you use a dice to determine the numbers of minutes to wait. You are throwing the dice every few seconds while watching the clock. Chances are that you will at some point get a 1 or 2 after waiting 1 or 2 minutes. It is unlikely that you don't get a 6 for 6 minutes straight. Instead you would want to through the dice only once per waiting period.
For the code this means, that you need to restructure it. Calculate the new delay value only when you toggle the LED. So something like this:
void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);

    // generate new random delay
    randomBlink();
  }
}

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
}

void loop() {
  ledBlink();
}

Calling ledBlink() in every loop() iteration makes sure, that the toggling of the LED actually happens. A new random value for the delay is only called after the LED just got toggled. Now the range of the delay will be the full 499ms.

oh ok, gotcha! thanks!


text:
Wake-UP the ATtiniy44 from sleep_mode_pwr_down with a PushButton
I'm curently playing with sleep modes. When I push the button, melody starts, push again go to deep down sleep and save 3v battery, push again wake up and melody starts again. But seems like it doesn't completely goes to sleep and can't wake up.
#include <OneButton.h>
#include <avr/sleep.h>
#include <avr/power.h>

#define cs6 1109
#define fs5 740
#define d6 1175
#define c6 1047
#define f5 698
#define b5 988
#define e5 659
#define bf5 932
#define ef5 622
#define b4 494
#define g5 784
#define led1 8
#define led2 7

const uint16_t halloween[] PROGMEM = { cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                       c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
                                       c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                       c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5, cs6,  f5,
                                       b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                       b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                       bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                       bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                       b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                       b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
                                       bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                       bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
                                       fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4
                                     };

typedef enum {
  ACTION_OFF,
  ACTION_ON
}
MyActions;

const int buzzer = PA1;
unsigned long previousMillis = 0;
unsigned long pauseBetweenNotes = 218;
int noteDurations = 6;
int thisNote=0;
int ledState = LOW;

OneButton button(10, true, true);

MyActions nextAction = ACTION_OFF; // no action when starting

void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(10), wakeUpFromSleep, FALLING);
  button.attachClick(myClickFunction);

}

void melody () {

  unsigned long currentMillis = millis();

  if (thisNote <= 290 && currentMillis - previousMillis >= pauseBetweenNotes)
  {
    previousMillis = currentMillis;

    if (ledState == LOW) {

      ledState = HIGH;

      tone(buzzer, pgm_read_word(&halloween[thisNote]), 168);
      pauseBetweenNotes = 167 * 0.65;
      thisNote++;
    }

    else {

      ledState = LOW;
    }
    digitalWrite(led1, ledState);
    digitalWrite(led2, ledState);

  }
}

void wakeUpFromSleep() {
  // Rimuovi l'attivazione dell'interrupt per il pulsante
  detachInterrupt(digitalPinToInterrupt(10));
  sleep_disable();
  power_all_enable();
 }

void myClickFunction() {

  if (nextAction == ACTION_OFF)
  {
    nextAction = ACTION_ON;
    thisNote = 0;
    pauseBetweenNotes = 0;
    previousMillis = 0;
  }

  else
  {
    nextAction = ACTION_OFF;
    digitalWrite(led1, LOW);  // spegni i led
    digitalWrite(led2, LOW);
    noTone(buzzer);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_cpu();
  }
}

void loop() {

  button.tick();

  if (nextAction == ACTION_OFF) {
    wakeUpFromSleep();
  }

  else if (nextAction == ACTION_ON) {
    melody();
    }
}

When you press the button , the chances are high that, the interrupt is deactivated. You attach the interupt in the setup routine but then detach it with the first
"loop" run. Without an active interrupt and after the first button press the MCU sleeps and pressing the button again does nothing.

So you think I should attach interrupt somewhere else ?

attachInterrupt(digitalPinToInterrupt(10), cannot be fully understood without knowing which configuration of which board core you are using.

I'm using attiny44a mcu and button pin is attached to PB0 pin

That isn't exactly what I asked, but it is relevant information to a correct answer which you should edit into your question.

I wrote Attiny44 in my thread title, I should also insert in the text of question?

"attiny44" is not "which configuration of which board core you are using". You can at least include "PB0" in your question so someone (not me) can explain to you why attachInterrupt simply won't work with that pin. And why it won't wake with that pin.

According to the datasheet external interrupt are triggered by any pin PCINT[11:0] so i think PB0 is ok for attachInterrupt

I understand your confusion. But, that is not the case. attachInterrupt works with INT# not PCINT#. These are different things. Importantly none of the PCINT will wake your chip from powerdown.

ok so the new code will never work, I have to redesign completely.....

And for the button pin i have to use PB2 that according datasheet have INT0

Alright, so I've found another datasheet and this one did mark PCINT as a wake-up source in the table, not just in the statement elsewhere in the sheet. To confirm this isn't just an error, I set up a T44A with CKOUT fuse enabled, verified that stops outputting clock in powerdown mode sleep. Configured PCINT and triggered it with a button and it did wake and resume CKOUT production. So at least with at T44A it's verified to wake with PCINT. The part regarding PCINT and attachInterrupt stands; so you'd need to integrate NicoHood's library for that part.

Yes I've used his library and with PB0 seems working for power down

EDIT
I've written the following programm. It should provide the requested features.
But for the time being I don't have access to an ATtiny44a so I used a Arduino UNO. I read both data sheets and did not find anything that prevents the program from running on a ATtiny44. So please try it and if it runs you can read the comments in the program to understand what I did to get it running.
I have a very "chirpy" button, so some times the program can not differ whether I clicked twice or the button bounces. I've used long debouncing periods to get rid of that. I've commented it in the code, please check what value works best for you.
Ah, And I've accellerated the the melody a little bit ;-). I like Heavy Metal more than Walzing Matilda style ;-). And I change the programm so that it runs the mellody again and again until you pressed the button again. Your Program stopped ofter playing the melody once.
// This Code is intended to run on an ordinary Arduino Uno
// The original request was to implement it for an ATtiny44a.
// I will document if there are difference to take
// into consideration. Most of the code should run on a
// attiny44 as well.

// The purpose of this program is to let the MCU play a melody
// started and stopped by clicking a button. The mcu should enter
// a enerngy saving sleep mode when the melody stops.
// When in sleep mode, pressing a button should wake up the MCU
// which then should continue playing the melody.

#include <avr/sleep.h>
#include <avr/power.h>

// The button pin must be pin two for Arduino Uno
// for a tiny any pin can be used so pin 2 is fine.
const int buttonPin = 2;
const int buzzerPin = 10;
const int led1 = 8;
const int led2 = 7;

// Attention!!!!: I use a pull up and a push button
// connected to GND.
// With this setup pressing the button will pull the pin to GND.
// Therefore we read LOW while the button is pressed.
// If the button is HIGH active - that means the button
// is connected to VCC - the LOW of the following constant must
// be changed to HIGH and the RISING must be changed to FALLEN.
#define BUTTON_PRESSED LOW
#define INTERRUPT_TRIGGER_METHOD RISING

// I decided to use a very long debounce delay, because I
// featured a very "chirpy" button. Feel free to experiment
// with this delay.
const long debounceDelay = 150L;

// setup for the melody

// define the note pitch values
#define cs6 1109
#define fs5 740
#define d6 1175
#define c6 1047
#define f5 698
#define b5 988
#define e5 659
#define bf5 932
#define ef5 622
#define b4 494
#define g5 784

// provide a melody as an array.
const uint16_t halloween[] PROGMEM = {
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
  c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  cs6, fs5, fs5, cs6, fs5, fs5, cs6, fs5,  d6, fs5,
  c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
  c6,  f5,  f5,  c6,  f5,  f5,  c6,  f5,  cs6,  f5,
  b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
  b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
  bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
  bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
  b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
  b5,  e5,  e5,  b5,  e5,  e5,  b5,  e5,  c6,  e5,
  bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
  bf5, ef5, ef5, bf5, ef5, ef5, bf5, ef5,  b5, ef5,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4,
  fs5,  b4,  b4, fs5,  b4,  b4, fs5,  b4,  g5,  b4
};

//define processing variables for the play functionallity
unsigned long previousMillis = 0;
unsigned long pauseBetweenNotes = 300;
unsigned long lengthOfActiveNote = 300;
int noteCounter = 0;
boolean toneOn = false;

// handling the play mode
// after inserting the battery the melody does not play.
// After the user will have pushed and released
// the push button, we will start with the melody.
volatile boolean playMelody = false;
volatile bool playModeChangeRequested = false;

// reading and debouncing the button
volatile unsigned long lastDebouncingMillis = 0;

void stopTheMelody()
{
  noTone(buzzerPin);
  toneOn = false;
  digitalWrite(led1, toneOn);
  digitalWrite(led2, toneOn);
}

void startTheMelody()
{
  previousMillis = 0;
  pauseBetweenNotes = 0;
  noteCounter = 0;
  toneOn = false;
  digitalWrite(led1, toneOn);
  digitalWrite(led2, toneOn);
}

void melody ()
{
  unsigned long currentMillis = millis();
  if (! toneOn &&
      (currentMillis - previousMillis) > pauseBetweenNotes)
  {
    pauseBetweenNotes = 167 * 0.2;
    tone(buzzerPin, pgm_read_word(&halloween[noteCounter]));
    noteCounter++;
    if (noteCounter > 290)
    {
      // the old program plays the melody only once
      // with resetting the note counter to 0
      // the melody start again and again.
      noteCounter = 0;
    }
    toneOn = true;
    digitalWrite(led1, toneOn);
    digitalWrite(led2, toneOn);
    previousMillis = currentMillis;
  }
  else if(toneOn &&
          (currentMillis - previousMillis) > lengthOfActiveNote)
  {
    lengthOfActiveNote = 58;
    noTone(buzzerPin);
    toneOn = false;
    digitalWrite(led1, toneOn);
    digitalWrite(led2, toneOn);
    previousMillis = currentMillis;
  }
}

// This is the interrupt service routine.
// It is called every time the button will have been released.
void ISR_buttonReleased()
{
  // Here, we know that this ISR is called because,
  // the button was released.
  lastDebouncingMillis = 0L;
  playModeChangeRequested = true;

  if (!playMelody)
  {
    // if the interrupt was triggered while the MCU was sleeping
    // we need to switch off the sleep mode to resume
    // normal activity. Otherwise the debouncing method does not
    // work, as it is done by code outside of the ISR.
    sleep_disable();
    power_all_enable();
  }
}

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buzzerPin, OUTPUT);

  // paranoia setup
  playMelody = false;
  playModeChangeRequested = false;
  lastDebouncingMillis = 0;

  // the interrupt is triggered on rising edge, i.e.
  // when the button will be released
  attachInterrupt(
       digitalPinToInterrupt(buttonPin),
       ISR_buttonReleased,
       INTERRUPT_TRIGGER_METHOD);

  // stop melody and sleep
  stopTheMelody();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
}

void loop()
{
  // lastDebouncingMillis will be set to 0 1st) in the
  // setup routine and 2nd) in the ISR.
  if (lastDebouncingMillis==0 ||
      digitalRead(buttonPin)==BUTTON_PRESSED)
  {
    // Here lies the magic!
    // We synchronize the ISR, the sleep mode, a long button
    // press without release and the
    // button bouncing with this single if statement.
    lastDebouncingMillis = millis();
  }

  if (playModeChangeRequested)
  {
    unsigned long tempMillis = millis();
    if((tempMillis - lastDebouncingMillis) > debounceDelay)
    {
      playModeChangeRequested = false;
      playMelody = !playMelody;
      if (!playMelody)
      {
        // stop melody and sleep
        stopTheMelody();
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        sleep_cpu();
      }
      else
      {
        startTheMelody();
      }
    }
  }

  if(playMelody)
  {
      melody();
  }
}

Old Answer removed
The old answer was not clear enough for this complicated topic.

Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed.


text:
The Arduino UNO Pin 3V3 have OUTPUT 5V (measured with meter)
I just noticed that my original Arduino UNO on pin 3V3 have 4.98V output. That's odds. That pins should have 3.3V. So I measured the Vout on the voltage regulator LP2985-33DBVR where that pins is connected. And the voltages on Vout are the same of what I have measured on that pin. Does that voltage regulator need to be replaced?

I guess either the regulator has failed creating a short or the 5v rail is shorted to the 3v3 rail elsewhere. Removing the regulator and checking the 3v3 rail is no longer 5v should tell you.
The only time I broke a 3v3 regulator, it failed open, so I don't know how likely it is for a LP2985 to fail short.
You could briefly attach a small load, say a LED and 270 or 330 ohm resistor, to be more certain of the voltage reading.

I tested pin 3v3 and pin 5v5, but there is no continuity between them. they seems not shorted together

I removed the regulator and the 3v3 pin it's around 1,5-2v

A Uno with no shields and no connections to offboard components should have nothing connected to the output 3v3 regulator.  See updated answer - though I wrote that before seeing your comment and 1.5v won't be enough to light most LEDs. I suspect your voltmeter is now seeing a meaningless floating value.

I agree about testing it with a small load since sometimes a regulator can actually show a higer voltage(typically input of the regulator(so around 5v in this case)) when no load it attached to it. essentially the voltage won't drop, and so the small spikes keep it high.

also try testing it with the arduino uno's analog ports, so get 2 resistors of the same value(for example both 1k resistors, 1 in 3.3v, 1 in gnd, and the middle in a analog port. if you read a value of around 500(half of analog range then you get a reading which keeps fluctuating, or is close to 0 then it is broken most likely, if you get a value of around 350(actually 341)(340(+-30) of 1024 range) then it should still work.

Sorry, how I have to connect resistor? I didn't understood, one resistor 1k between 3v3 and GND and one around 500ohm between GND and A0?

With a LED Red and a 330ohm resistor connected to 3.3V pin, I have 2.35V


text:
Make a code loop 100 times with a text on Serial Monitor
Ok, this is my code:
int rosso = 13;
int verde = 12;
int blu = 11;
int count = 0;
String command_on, command_off;
String s;
String enough = "stop";

void setup(){
  pinMode(rosso, OUTPUT);
  pinMode(verde, OUTPUT);
  pinMode(blu, OUTPUT);
  Serial.begin(9600);
  command_on = String("on");
  command_off = String("off");
}

void redToBlue(){
  if(count < 100) {
  rgb(0,255,0);
  delay(100);
  rgb(0,0,0);
  delay(100);
  rgb(255,0,0);
  delay(100);
  rgb(0,0,0);
  count = count+1;
  }
}

void switchOff(){
  rgb(0,0,0);
  delay(100);
}

boolean wait_command(){
  if(s == command_on){
    redToBlue();
  }
  if(s == command_off){
  switchOff();
  }
}

void accendi(){
  if(s == command_on){
  redToBlue();
  }

  if(s == command_off){
  switchOff();
  }
}

void rgb(int r, int g, int b){
  analogWrite(rosso, r);
  analogWrite(blu, b);
  analogWrite(verde, g);
}

void loop(){
 s = Serial.readString();
 Serial.println("What I have to do? ");
 wait_command();
}

When I open the Serial Monitor and type "on" there, the redToblue() function must loop 100 times. But in my case loops only one time then it stops. I think I have to change something inside loop() function and on redToBlue()...

You loop() function is the one that will be called when the program runs and it will keep looping around until you stop it.  So at the moment you have loop() doing the following:

Reading a string from the serial connection
Displaying a message to the serial connection
Parsing the string that was read and acting upon it.

So when your code runs you see it print the message and maybe do something with the light and then it stops/freezes.  Its not really frozen, its waiting for you to enter an answer.
So if you really want it to ask what to do and then then loop 100 times you need to do this:

Display the message.
Read the data.
Call wait_command() (after you have modified it)

void redToBlue(){
for (int count = 0; count < 100; ++count) {
rgb(0,255,0);
delay(100);
rgb(0,0,0);
delay(100);
rgb(255,0,0);
delay(100);
rgb(0,0,0);
}
} // Sorry I can't get the code to format.
I think you could also refactor the function to loop over an array of 4 rgb values.  I don't now if that would be better for the processor, it would look nicer :)

I'm not sure exactly what you want, but if you expect after a single command on to have it looped 100 times, you need to call the redToBlue function in every loop (within wait_command, that checks for a boolean if the on command has been requested, and when so, call the redToBlue function. When the off command is set, you reset the boolean.
Also wait_command is not a good name, as it does not wait for a command, but processes it.

yes I would like that If I type "on" loop 100 times, and if I type "off" doesn't do nothing, and rgb led is off.

It will also stop before 100 if you type "off" when 100 loops are not reached yet.


text:
MPU6050 Problem with NodeMCU
I am using MPU6050 as a part of IMU of my drone, and I wrote this program for Arduino Nano to fetch the orientation of the MPU6050 module in 3D space. And that works perfectly fine, but when I uploaded this exact code to a NodeMCU, the output started getting increased only, i.e., whenever there's any change of orientation of the module, the output, instead of showing the specific orientation, gets increased on and on. Can you please help me out with interfacing the MPU6050 with my NodeMCU. I am providing the program underneath.
#include <Wire.h>
const int MPU = 0x68; // MPU6050 I2C address

char status;                // Declaring all the necessary variables
double T, P;
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll_sensor, pitch_sensor, yaw_sensor;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        // end the transmission
  calculate_IMU_error();  // Call this function if you need to get the IMU error values for your module
  delay(20);
}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 6 registers total, each axis value is stored in 2 registers

  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value

  // Calculating roll_sensor and pitch_sensor from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorX;
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorY;

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 4 registers total, each axis value is stored in 2 registers

  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

  // Correct the outputs with the calculated error values
  GyroX = GyroX - GyroErrorX;
  GyroY = GyroY - GyroErrorY;
  GyroZ = GyroZ - GyroErrorZ;

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + (GyroX * elapsedTime); // deg/s * s = deg
  gyroAngleY = gyroAngleY + (GyroY * elapsedTime);
  yaw_sensor =  yaw_sensor + (GyroZ * elapsedTime);

  // Complementary filter - combine acceleromter and gyro angle values
  roll_sensor = (0.94 * gyroAngleX) + (0.06 * accAngleX);
  pitch_sensor = (0.94 * gyroAngleY) + (0.06 * accAngleY);

  // Print the values on the serial monitor
  Serial.print("                   roll_GY: "); Serial.print(roll_sensor);
  Serial.print("         pitch_GY: "); Serial.print(pitch_sensor);
  Serial.print("         yaw_GY: "); Serial.print(yaw_sensor);
  Serial.println();

}
void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * (180 / PI)));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * (180 / PI)));
    c++ ;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 300;
  AccErrorY = AccErrorY / 300;
  c = 0;
  // Read gyro values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);

    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();

    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }

  //Divide the sum by 300 to get the error value
  GyroErrorX = GyroErrorX / 300;
  GyroErrorY = GyroErrorY / 300;
  GyroErrorZ = GyroErrorZ / 300;
}

"output started getting increased only" - What exactly does this mean?

Ohh I am sorry for being unspecific before and I edited that!

gyroAngleX is never reset, only added to.

No, that's alright, as depending on the sign of the GyroX, GyroY, GyroZ, it provides the expected figures.

I see that you are reading 16-bit integers from the IMU like this:
// doesn't work on 32-bit systems
void loop() {
    ...
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
    ...
    GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // ...
    GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
    GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
    ....
}

While all too often I am forced to use "#ifdef" to set up platform-specific code for each platform,
in this case I'm pretty sure it's possibly to write cross-platform compatible code that will work on both platforms;
perhaps something more like this:
// warning: untested, but I think it should work
int16_t wire_read_16(){
    int16_t value = (Wire.read() << 8 | Wire.read());
    return value;
}

void loop() {
    ...
    AccX = (wire_read_16()) * (1.0f / 16384.0f); // X-axis value
    AccY = (wire_read_16()) * (1.0f / 16384.0f); // Y-axis value
    AccZ = (wire_read_16()) * (1.0f / 16384.0f); // Z-axis value
    ...
    GyroX = (wire_read_16()) * (1.0f / 131.0f); // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
    GyroY = (wire_read_16()) * (1.0f / 131.0f);
    GyroZ = (wire_read_16()) * (1.0f / 131.0f);
    ....
}

I see that
onehorse is apparently having exactly the same problem at
"integer type definitions on Teensy 3.1"
It sounds like maybe you've stumbled over a quirk of the C programming language where "int" varies from system to system.
(See Ido Gendel, "The problem with ints").
The "int" in some systems (such as the ATmega based Arduinos) is a 16-bit integer.
The "int" in some other systems (such as the ARM based Arduinos, perhaps including NodeMCU) is a 32-bit integer.
(
inttypes vs Arduino defined integral types
; "Arduino reference: int"
)
In yet other systems, "int" is a variety of other sizes.
For example, when your IMU is trying to send you a "-2",
it sends 0xFFFE.
When the nano puts that into its "int" which is a 16-bit integer, it then later properly interprets that as meaning "-2".
I suspect what's happening is that
when the other system puts that value into its "int" which is a 32-bit integer, that somehow ends up containing
0x0000FFFE which means +65534,
but what should have happened is "sign extension" so that 32-bit integer ends up containing
0xFFFFFFFE which means "-2".
By sticking that value into an intermediate "int16_t" variable, we're explicitly telling the compiler that it's a signed 16-bit integer,
so later when that compiler sticks it into a 32-bit integer it sign-extends properly.
The C compiler (correctly) handles an int divided by a float by converting both values to floats (and sign extending properly), and then dividing. Likewise with an int divided by a double.

yes! I resolved that, with typecasting the raw MPU6050 data into int16_t as
AccelX = (((int16_t)Wire.read()<<8) | Wire.read()), but one problem prevails again, which is the millis(), which is applicable for Arduino Nano, but its problematic interfacing with Nodemcu is still misunderstood to me, can you please suggest a way to measure the execution time, in NodeMCU! Thanks a lot, by the way!

Does https://arduino.stackexchange.com/questions/56712/nodemcu-millis-simple-counter-how-long-is-led-on answer your question? If not, could you post a fresh new question?


text:
Latency in Websocket
I am using Websocket, for a communication from my mobile phone to a NodeMCU, and transmitting 4 channel, data, through 4 different Websocket Ports.
the NodeMCU control code is here:
// ============ By Pritam Pagla ============ //
// The Only Websocket Program is attached within master branch

// NodeMCU SIDE

#include <SoftwareSerial.h>
#include <ArduinoJson.h>     // Preferably use ArduinoJson 5.x, as StaticJsonBuffer object is not defined in further versions
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include<WebSocketsServer.h>

#include "index_NodeMCU_Test1.h";   // Complete Webpage

SoftwareSerial s(D6,D5);          // Rx as D6 and Tx and D5

int16_t throttle_Val = 0;
int16_t yaw_Val = 0;
int16_t pitch_Val = 0;
int16_t roll_Val = 0;

uint8_t num;
WStype_t type;
uint8_t *payload;
size_t length;

//WiFi Connection configuration
const char *ssid = "PriCopter";       // Can choose these anything one wants
const char *password = "01234567";

WebSocketsServer Twebsocket = WebSocketsServer(9001);
WebSocketsServer Ywebsocket = WebSocketsServer(9002);
WebSocketsServer Rwebsocket = WebSocketsServer(9003);
WebSocketsServer Pwebsocket = WebSocketsServer(9004);

ESP8266WebServer server(80);

//================================================

void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

//================================================
//            Setup
//================================================

void setup() {
s.begin(115200);
Serial.begin(115200);
 delay(100);

  //Setup the NodeMCU as an AP
  WiFi.softAP(ssid, password, 1, false, 1);    //Use NodeMCU as an access point

  //If connection successful show IP address in serial monitor
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  //Initialize Webserver
  server.on("/",handleRoot);

  server.begin();
  Twebsocket.begin();
  Ywebsocket.begin();
  Rwebsocket.begin();
  Pwebsocket.begin();

}

void loop() {
 StaticJsonBuffer<100> jsonBuffer;
 JsonObject& root = jsonBuffer.createObject();

 server.handleClient();
 Twebsocket.loop();
 Ywebsocket.loop();
 Rwebsocket.loop();
 Pwebsocket.loop();

 Twebsocket.onEvent(ThrottleEvent);
 Ywebsocket.onEvent(YawEvent);
 Rwebsocket.onEvent(RollEvent);
 Pwebsocket.onEvent(PitchEvent);

 Serial.print("Throttle:  "); Serial.print(throttle_Val);
 Serial.print("   Yaw:  "); Serial.print(yaw_Val);
 Serial.print("   Pitch:  "); Serial.print(pitch_Val);
 Serial.print("   Roll:  "); Serial.print(roll_Val);

  root["throttle"] = throttle_Val;
  root["yaw"] = yaw_Val;
  root["roll"] = pitch_Val;
  root["pitch"] = roll_Val;

 root.printTo(s);
 Serial.println("   (Sent)");
}

void YawEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      yaw_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void ThrottleEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      throttle_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void RollEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      roll_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void PitchEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      pitch_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

and requiring Webpage details is as:
const char MAIN_page[] PROGMEM = R"=====(<!DOCTYPE html>
<html lang = 'en'>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport"
    content="width=950, height=420 initial-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible"
    content="ie=edge"/>
    <title>Drone Remote</title>
    <style>
    body{
      background-color: #333;
      color: 'black';
      display: flex;
      flex-direction: row;
      align-items: center;
      font-family: Arial, Helvetica, sans-serif;
      min-height: 100vh;
      margin:0;
    }
    #canvasL{
      background: #f0f0f0;
      border-radius: 5x
    }
    #canvasM{
      background: #f0f0f0;
      border-radius: 5px
    }
    #canvasR{
      background: #f0f0f0;
      border-radius: 5px
    }

    #source{
      display: none;
    }

    </style>
  </head>
  <body>
    <canvas id="canvasL" width="450" height="420"></canvas>
    <canvas id="canvasM" width="50" height="420"></canvas>
    <canvas id="canvasR" width="450" height="420"></canvas>

    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAHWElEQVRoQ7WZT2xUVRTGv9vptIBAC6ghbtQYEhtD4kLcsJCNUdOtLUldGKOuujH+STQYDcGQKEFWGv8LIQgMqcrG6AZcGEkwxEjShUFJVxAIaEVsC23nmnN7v+mZM/fOvJm2L3m5b968ee/87vedc++747BC2/vA1iqwfR54aA6Y98CvM8DP7wAXVuKRbjlu+iXQXwX+rgLwAKSVfQ7AfNzleDae0y2ANQeA6aXGsSSQIwuxdUsQ3jls3b0brlRC1fsFIO9r+3w8FjA5PzM9jVP79oUbyH4buPEp0NcpUEcgFYkbgOwP7toF19UFHwOVNgvhfVBoTlq1/zs5iZ8OHhQY2ecPx85pB6otkDHgRwc81gVg8+Ag1g8MABK4Cj4cxyCpSLCX9wFAzhFEWrFcaL3H+KlTuHTxYgCaBV6tAPuLwhQG+QbwJQCy3zc6Cud9gCCIPDBYihZSVmLvM+AApQB4/rb3uD07izNjYwFG8qyyIHzLrchF7iRQlUSQ/Z6REZR6eupArCrMB/a8BDQbVWLQ0oaklzYqIq3A/HnuHK5evhy+l60ITFOQr4FN3cC1coQQNTYPD6PL+wBCVSQnqISoov2f6nlCSODcCRRgAJw/fTq0cu8iMFmQCtCzCrglEAQRRe4cHFwECeUq5oiylM4JgdI9rlWgAgIhSoTqFY9/P3s2gMi9uDVTJgvyLeAFoCeCSCsg/Tt2BBBJ+JoiqmIFOxn/13o+WowAPB+qFWG8xy3vMTE+zqSvy48cTBJkDPC9CoAwArZ+2zaUoq0EhoqwQulKpK3D4ENFikEz+NAqGPl8aWICtxbKccOWgmkAOQZUVwGOIA1A3d1YvWVLqF6ijAZJQQTLxF7W1pFeJ0gIOH6W89evXq1ByHfME0X0QwV4UhM2gJyIagiAKCG7PhZVejdsQHnduqAMQcROtvpIcBIIFUgFz3PTEeTm1BRmqtU6EKl6drOq1IEcBTwDZ/C2JZzkS3njxpAnYV4VS6gERgXEFjr4mahMOBe/k2OeF4BwPu481gmvgTRMA4gEzl1D5YCcc5grlxeDVxYJATFoFaANlJ+ZE/qzHLcFcihayiqyKtqLrYUUZWwA0pMzMVHZ2mBT59sF0eNLTREBySmQUogWk8olg17KErme16C29/V9+F1OkQaQj4G/eoEN2j72WCc8y7GoIT0Rxo0IE2ewdSrZ4Cx0Tr1WOSIgDnj0OPBLUOSjjK1SlUuP9FKC5QaS7KFqLb5bcEpeA8oFn7KTBU9VLZv0AeRDU3ItAEd4rQRnwmFMVG+C8SWpNiqH8mvyiIGm4ORamz+JcaRhtHcecB8AVRt8bmTXE0gmGF9vaTGrjAZJWU+rksq1xDDSCLIf2FsG3rA5oOdYnGdpCNqKd6S9wmzX2EyrRBCriv6siwGn8s1g5oEB966qVtpCdQNfnHfJ97RUmDTGPbXgoBcY4htfLW9SMDmwZhVLwR1yeyMIA9dKMLH1NN6CMEesvawyNndyMNZarfKDMG6PAmHgKTUEQMptmCzGXU8LuASkl4G0xZg31mbMn1RBKGKrGsjbRhGrglZDAARG20rnCKsXYagKxxjaTavRLH9ald262e+b8QVK50eYEMag+a5OACrC/ODNdJ7oRTkNY1XJ2Y0lu1W1qgN53YBIwKxSErROcOaHQISXKpXs4b1dDY4pGA2iS3QKqGCSk+WMewX4vgw8oUusVYMANj/0OGJB7JJparmUABakndyIJI8LyL0OmLCLDFSCCW4hqIiWVye8Hlf0QJmrZlqhopWKz5b3ktCpLwGeuWBLbQ6EakjLB+tFbFpLW4zzsVw1E5g2LRVYaiCjCRDayZZcViyriLZWqhRTFa0IqxnbTiDqQF6MCa8rlAaRoDkl4RjCRNdVy8KkVOFfDbSS/ruhnSqlrr1WAe4KDhkCSn3AnM0LW3L1QGhXLQhhyzBzhYrYfOnUTjo/6jr1WWUvXaV0kmtbtQJJlWJrL6rToRK1/KgDGQE+KwHP6+TW8yqqkRrV9XyLAHqU1xbT1mq3OlngMtB3BLhhbY6dURUNkJrt6sEwlyMaJGWvpahgbZUCec4DX4htUvmhR/Rc1UpVL63IcgDIPXqBtYeB/3i/hpXGYbVCycBTtkotGmsIm/TLBZBSo0ERXqRhNDEninbCaO3FgXG5g89BZEGGgI0OuL5SgSzlvm39rRDHFlkremQpD13u33YBLxwDPk/dt+lfb0PAFQfcXTSg1H8ZzX4rM+6imwe+OgE8k7u+KYj8aCfwhwceaPbAm0WjyVy3tvXv36oAe5pd1hIk2ux+B1xM3WiydRCFrujPXNUP9HyysMbXdCsEwjukqtlyVYRNiTCL/C3Nn7UFEtV5zQHv6eeKKi27LNOfawDcYb5zwMPHgd9aqaC/bxuEPx4CvnPAU/Zh/8R13mZBSPCZvHi5AhxoB6BjRexDhoDVDpjq5OH8zQBQ2r2wqN/x1rEiuScOA9s9cNIBKdvLa/GFbuDpo8D5jqNO/PB/ioZ2+ax3loAAAAAASUVORK5CYII=" alt="" id="source"/>
    <script>
    const canvasL = document.getElementById('canvasL');       // Object for left canvas
const Lctx = canvasL.getContext('2d');

const canvasM = document.getElementById('canvasM');       // Object for Middle canvas
const Mctx = canvasM.getContext('2d');

const canvasR = document.getElementById('canvasR');       // Object for Right canvas
const Rctx = canvasR.getContext('2d');

const LcenterX = (canvasL.width / 2);    // Marking centre for left Joystick
const LcenterY = (canvasL.height / 2);
const RcenterX = (canvasR.width / 2);    // Marking centre for Right Joystick
const RcenterY = (canvasR.height / 2);
const McenterX = (canvasM.width / 2);    // Marking centre for Middle Portion
const McenterY = (canvasM.height / 2);

var Tsocket = new WebSocket('ws://' + window.location.hostname + ':9001/');
var Ysocket = new WebSocket('ws://' + window.location.hostname + ':9002/');
var Psocket = new WebSocket('ws://' + window.location.hostname + ':9003/');
var Rsocket = new WebSocket('ws://' + window.location.hostname + ':9004/');

const image = document.getElementById('source');

var throttle_Val = 0;
var yaw_Val = 0;
var pitch_Val = 0;
var roll_Val = 0;

const throttle = "t";
const yaw = "y";
const pitch = "p";
const roll = "r";

const LJoyStickBall = {         // defining left joystick as an object
  w: 60,
  h: 60,
  x: LcenterX,
  y: LcenterY+195,
  speed: 1,
  dx: 0,
  dy: 0
};
const RJoyStickBall = {         // defining right joystick as an object
  w: 60,
  h: 60,
  x: RcenterX,
  y: RcenterY,
  speed: 1,
  dx: 0,
  dy: 0
};

function drawLeftCenterBall(){      //Drawing the Left Joystick ball
  Lctx.drawImage(image, LJoyStickBall.x-30, LJoyStickBall.y-30, LJoyStickBall.w, LJoyStickBall.h);
}
function drawRightCenterBall(){      //Drawing the Right Joystick ball
Rctx.drawImage(image, RJoyStickBall.x-30, RJoyStickBall.y-30, RJoyStickBall.w, RJoyStickBall.h);
}

function LnewPos() {                    // changing position for keyboard activity
  LJoyStickBall.x += LJoyStickBall.dx;
  LJoyStickBall.y += LJoyStickBall.dy;

  LdetectBoundary();
}

function RnewPos() {                    // changing position for keyboard activity
  RJoyStickBall.x += RJoyStickBall.dx;
  RJoyStickBall.y += RJoyStickBall.dy;

  RdetectBoundary();
}

function LdetectBoundary(){             // defining the boundary for the LeftJoystickCenterBall
  // Left side
  if (LJoyStickBall.x < LcenterX-195) {
    LJoyStickBall.x = LcenterX-195;
  }

  // Right side
  if (LJoyStickBall.x > LcenterX+195) {
    LJoyStickBall.x = LcenterX+195;
  }

  // Top side
  if (LJoyStickBall.y < LcenterY-195) {
    LJoyStickBall.y = LcenterY-195;
  }

  // Bottom side
  if (LJoyStickBall.y > LcenterY+195) {
    LJoyStickBall.y = LcenterY+195;
  }
}

function RdetectBoundary(){             // defining the boundary for the LeftJoystickCenterBall
  // Left side
  if (RJoyStickBall.x < RcenterX-195) {
    RJoyStickBall.x = RcenterX-195;
  }

  // Right side
  if (RJoyStickBall.x > RcenterX+195) {
    RJoyStickBall.x = RcenterX+195;
  }

  // Top side
  if (RJoyStickBall.y < RcenterY-195) {
    RJoyStickBall.y = RcenterY-195;
  }

  // Bottom side
  if (RJoyStickBall.y > RcenterY+195) {
    RJoyStickBall.y = RcenterY+195;
  }
}

function drawDesigns(){               // 4 Convrntric circles and 2 crossed st lines for better interface
  Lctx.beginPath();
  Lctx.lineWidth = 2.5;
  Lctx.moveTo(LcenterX, LcenterY-195);    // Crossing lines on left
  Lctx.lineTo(LcenterX, LcenterY+195);
  Lctx.moveTo(LcenterX-195, LcenterY);
  Lctx.lineTo(LcenterX+195, LcenterY);
  Lctx.arc(LcenterX, LcenterY, 195, 0, Math.PI * 2);   //Concentric circles on Left
  Lctx.arc(LcenterX, LcenterY, 150, 0, Math.PI * 2);
  Lctx.arc(LcenterX, LcenterY, 100, 0, Math.PI * 2);
  Lctx.arc(LcenterX, LcenterY, 50, 0, Math.PI * 2);
  Lctx.stroke();

  Rctx.beginPath();
  Rctx.lineWidth = 2.5;
  Rctx.moveTo(RcenterX, RcenterY-195);    // Crossing lines on Right
  Rctx.lineTo(RcenterX, RcenterY+195);
  Rctx.moveTo(RcenterX-195, RcenterY);
  Rctx.lineTo(RcenterX+195, RcenterY);
  Rctx.arc(RcenterX, RcenterY, 195, 0, Math.PI * 2);   //Concentric circles on Right
  Rctx.arc(RcenterX, RcenterY, 150, 0, Math.PI * 2);
  Rctx.arc(RcenterX, RcenterY, 100, 0, Math.PI * 2);
  Rctx.arc(RcenterX, RcenterY, 50, 0, Math.PI * 2);
  Rctx.stroke();
}
function clearScreen(){             // Clearing the LeftCanvas and RightCanvas on every loop of the Animation
  Lctx.clearRect(0, 0, canvasL.width, canvasL.height);
  Rctx.clearRect(0, 0, canvasR.width, canvasR.height);
}

function ConsoleOUT(a,b,c,d){
   throttle_Val = (405-a);
   yaw_Val = (b-225);
   pitch_Val = (210-c);
   roll_Val = (d-225);
  console.log('Throttle: '+throttle_Val+'    Yaw: '+yaw_Val+'    Pitch: '+pitch_Val+'    Roll: '+roll_Val);
}

function LeftUpdate(){
  clearScreen();                                //Left Joystick
  drawDesigns();
  drawLeftCenterBall();
  drawRightCenterBall();
  LnewPos();
  RnewPos();
  ConsoleOUT(LJoyStickBall.y,LJoyStickBall.x,RJoyStickBall.y,RJoyStickBall.x);
  requestAnimationFrame(LeftUpdate);

}
function RightUpdate(){                                 //Right Joystick
  clearScreen();
  drawDesigns();
  drawLeftCenterBall();
  drawRightCenterBall();
  LnewPos();
  RnewPos();
  ConsoleOUT(LJoyStickBall.y,LJoyStickBall.x,RJoyStickBall.y,RJoyStickBall.x);
  requestAnimationFrame(RightUpdate);
}

function LmoveUp() {                          // For KeyboardActivity
  LJoyStickBall.dy = -LJoyStickBall.speed;
}

function LmoveDown() {
  LJoyStickBall.dy = LJoyStickBall.speed;
}

function LmoveRight() {
  LJoyStickBall.dx = LJoyStickBall.speed;
}

function LmoveLeft() {
  LJoyStickBall.dx = -LJoyStickBall.speed;
}
function RmoveUp() {
  RJoyStickBall.dy = -RJoyStickBall.speed;
}

function RmoveDown() {
  RJoyStickBall.dy = RJoyStickBall.speed;
}

function RmoveRight() {
  RJoyStickBall.dx = RJoyStickBall.speed;
}

function RmoveLeft() {
  RJoyStickBall.dx = -RJoyStickBall.speed;
}

canvasL.addEventListener('touchstart', function(e){         // 'touchstart' event in LeftCanvas
       e.preventDefault();
       canvasL.addEventListener('touchmove', function(e){
              var touchobj = e.touches[0]; // reference first touch point for this event
              LJoyStickBall.x = touchobj.pageX;
              LJoyStickBall.y = touchobj.pageY;
              sendData(throttle,405-LJoyStickBall.y);
              sendData(yaw,LJoyStickBall.x-225);
              }, false)
   }, false)

   canvasL.addEventListener('touchend', function(e){            // 'touchend' event in LeftCanvas
       e.preventDefault();
       LJoyStickBall.x = LcenterX;
       sendData(yaw,0);
    }, false)

canvasR.addEventListener('touchstart', function(e){         // 'touchstart' event in RightCanvas
       e.preventDefault();
       canvasR.addEventListener('touchmove', function(e){
              var touchobj = e.touches[0]; // reference first touch point for this event
              RJoyStickBall.x = touchobj.pageX - (canvasR.width + RJoyStickBall.w);
              RJoyStickBall.y = touchobj.pageY - RJoyStickBall.h;
              sendData(pitch,210-RJoyStickBall.y);
              sendData(roll,RJoyStickBall.x-225);

          }, false)
   }, false)

   canvasR.addEventListener('touchend', function(e){            // 'touchend' event in RightCanvas
       e.preventDefault();
       RJoyStickBall.x = RcenterX;
       RJoyStickBall.y = RcenterY;
       sendData(pitch,0);
       sendData(roll,0);
      }, false)

  function sendData(a,b){

    if(a == throttle){
      Tsocket.send(b);
    }
    if(a == yaw){
      Ysocket.send(b);
    }
    if(a == roll){
      Rsocket.send(b);
    }
    if(a == pitch){
      Psocket.send(b);
    }

    // switch(a){

    //   case throttle:
    //     Tsocket.send(b);
    //     break;
    //   case yaw:
    //     Ysocket.send(b);
    //     break;
    //   case roll:
    //       Rsocket.send(b);
    //       break;
    //   case pitch:
    //       Psocket.send(b);
    //       break;
    //   default:
    //     console.log('Interruption Occured.')
    // }
  }

  document.addEventListener('keydown', function (e) {        // When certain key is pressed down
    if (e.key == 'ArrowRight') {
      LmoveRight();
      sendData(yaw,LJoyStickBall.x-225);
    } if (e.key == 'ArrowLeft') {
      LmoveLeft();
      sendData(yaw,LJoyStickBall.x-225);
    } if (e.key == 'ArrowUp') {
      LmoveUp();
      sendData(throttle,405-LJoyStickBall.y);
    } if (e.key == 'ArrowDown') {
      LmoveDown();
      sendData(throttle,405-LJoyStickBall.y);
    }
    if(e.key == 'w'){
      RmoveUp();
      sendData(pitch,210-RJoyStickBall.y);
    }
    if(e.key == 's'){
      RmoveDown();
      sendData(pitch,210-RJoyStickBall.y);
    }
    if(e.key == 'a'){
      RmoveLeft();
      sendData(roll,RJoyStickBall.x-225);
    }
    if(e.key == 'd'){
      RmoveRight();
      sendData(roll,RJoyStickBall.x-225);
    }
  });
   document.addEventListener('keyup', function (e) {        // When certain key is released
    if (
      e.key == 'ArrowLeft' ||
      e.key == 'ArrowRight' ||
      e.key == 'ArrowUp' ||
      e.key == 'ArrowDown' ||
      e.key == 'w' ||
      e.key == 's' ||
      e.key == 'a' ||
      e.key == 'd'
    ) {
      LJoyStickBall.dx = 0;
      LJoyStickBall.dy = 0;
      RJoyStickBall.dx = 0;
      RJoyStickBall.dy = 0;
      LJoyStickBall.x = LcenterX;
      RJoyStickBall.x = RcenterX;
      RJoyStickBall.y = RcenterY;
      sendData(yaw,0);
      sendData(pitch,0);
      sendData(roll,0);
    }
  });

  LeftUpdate();
  RightUpdate();
    </script>
  </body>
</html>

)=====";

Now, I am new to Web based projects and clearly new to Websockets. In the beginning, i used single websocket port and transmitted the data of the four channels as JSON file, but differentiating the data in 4 different channels, increased the speed slighly, but still one problem is consistent throughout, i.e. after a few seconds, (30-35), it starts to achieve latency, and it stays untill the page is not refreshed again.
Can someone please suggest any solution for this, as I am using this for controlling my drone, therefore, any unnecessary latency can be dangerous.
For further information, you can see detailed description and similar codes in this repo.
Thanks in advance.

Your WebSocket server listens on port 81, whereas your client connects to 9000–9003. Are you sure the HTML you posted matches the sketch just above it? Please, make sure the elements of your question are consistent with one another.

Ohh, I'm really sorry for that, actually I made several versions  of this project, and previously I did with, one websocket port, and actually I mistakenly pasted it from that project. I'm just making it right.

now you can check!

Having 4 servers isn't neccessary. Does the latency happen from time to time and does recover or does the latency remain high? I currently have a similar issue with the WebsocketsClient from that repo

Not really a proper answer, but a few ideas that hopefully could help
you debug the issue:

I doubt using multiple WebSocket servers really helps, as you end up
adding more context switching, i.e. you have to loop through all of
them even when they have no data to process.
SoftwareSerial tends to be really slow, as it blocks execution of
the sketch while it is sending. You may try to disable it, at least
while you troubleshoot this latency issue.
Calling Serial.print() on every loop iteration is also going to slow
the sketch down until it is no faster than the serial port. Try to
print only once in a while, or only when things actually change.
Both Firefox and Chrome have “developer tools” which should help you
diagnose the problem. At the very least you should be able to see
whether the slowdown comes from the server or from the client.

No, i just used SoftwareSerial for the SBUS between NodeMCU and Nano, that has nothing to do with websocket, and without that, it still gives the same problem.