text:
Do you need an ESC to run this brushless DC motor with Arduino Uno?
This is the motor:
https://www.aliexpress.com/item/Wholesale-JGA25-2418-8-5-1977-rpm-Electric-Motors-Brushless-Motor-High-Torque-Speed-Controlled-DC/32360228129.html
I'm hooking it up to the arduino as described and giving the PWM outputpin analogWrite functions, but it's not working.

No. It has an ESC built in.
You just provide power and a PWM signal, and optionally a direction signal.
To test:

Connect red to +12V.
Connect black to 12V GND and to Arduino GND
Connect white to D5
analogWrite(5, 128);

Stupid question, but why does the motors have to connect to Arduino GND as well as the 12V GND?

@Ary https://majenko.co.uk/blog/importance-sharing-grounds


text:
How do you remove dependencies from a library?
I'm writing a library for a project i created, but it depends on the Neopixel library from adafruit. I want to remove this dependency and have my library be a stand-alone library.
Is there a way to run a ws2811 chip without the neopixel or similar library?

Yes. Copy the code from the Neopixel library into yours.

Why is it important to remove the dependency? Of course there is a way to run the WS2811 chip, but you would have to implement the documented protocol yourself, which has already been done several times by several library authors.

I understand. but i want to just run the chip - its not running rgb leds.

The Adafruit Neopixel library is licensed under GPL v3. You can fork a copy of this library into your own code and modify it to suit your own requirements, but if you distribute your code, your compiled project, or a product containing the library or any portion of it, you must ensure you follow the rules of the license by which the library is governed. Those terms of license may include release of the source code if you use any portion of the licensed library in a product. Opinions differ on the exact meaning of GPL v3 with libraries.
You should be able to copy the library into your own codebase and strip out the color-specific routines, put in your own application-specific data-setting routines, but use the same underlying protocol implementation.

source: Stack Exchange

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

sort: votes


text:
Question on a car kit I bought
recently bought an UNIROI Smart Car kit.
(UNIROI Smart Robot Car Kit Arduino Robot Kit with 4 Wheel Drive, Arduino UNO R3 Board, Ultrasonic Sensor, Infrared Tracking Module (No Welding Required) https://www.amazon.co.uk/dp/B07CWS344R/ref=cm_sw_r_cp_tai_wQExCbHT0YM8K)
I bought some extra things with it to make it more interesting, but the problem is is that I need to connect more pins to the Arduino but they are all taken up by the car. What I have noticed is that there are these extra pins along the side of the Arduino board as you can see here: https://i.sstatic.net/7nhBO.jpg
I know you guys don’t have it in hand, but I thought I’d give it a shot to see if any of you know I can use those pins.
The description of the car also quotes
“Extended Pin Interface. The chassis is designed with
extended pin interface for Arduino UNO, only need to solder pins for using, more convenient to develop
and build your own robot car kit”
Appreciate any help you guys got.

Does the CD come with a schematic PDF? I couldn't find it when googling it.. But basically if the pin is free, you can solder to it and modify the firmware as you like. You'd want to have a soldering iron and a multimeter to check connections.

Correction: They have a link to a megaupload drop for all the needed data: https://images-na.ssl-images-amazon.com/images/I/41Y9NGFGlBL.pdf

It seems that you'll have to do some extended modifications to the design. In fact, all Arduino Pins (D0 - D13, A0-A5) are connected to components on the board and thus in use.
Schematics and Code: https://mega.nz/#F!Xbg1FA5L!qGah_HlLFJ_NKxv7ILLY2g folder "5 SCH".

This means that the only way that you'll get new components into this project are:

removing components  and re-programming the firmware to not use them

e.g., the two tracking-sensors left&right -> A2 and A3 are free
e.g., the speaker pin (D13). Who needs a speaker?

restructuring components

e.g. for the analog sensors: instead of using the Arduino's analog pins, throw a I2C ADC module (e.g. ADS1115) in the build and change the firmware to get the analog values via that new module; making this project use an I2C bus will free all analog pins and cost 2 pins (SCL + SDA). The I2C bus has the additional benefit of being able to connect more than one device to it -- you can e.g. put a I2C GPIO expander (e.g. MCP23017) on it to gain 16 more digital I/O -- more than the Uno had to begin with.

Appreciate the reply. Do you think if I removed those tracking sensors and and ultrasonic sensor I could add an SD card module that takes 4 pins? They are also anolog pins so can I still use them as digital?                         As a side note, I also have a spare Arduino so would it be possible to receive signals from the avoid sensor to both Arduinos?

@Josh your SD card is a SPI device and must be connected to the hardware-SPI pins of the Arduino Uno, which are 11,12,13 (MISO, MOSI, SCLK) and any other digital pin for slave-select (SS). On your car, these pins are connected to the servo (D11), the button and the speaker, so you would have to re-locate all these components.. Or use a bit-banged SPI in software, which I haven't yet seen. And yes, the analog pins A0-A5 are all capable of outputting digital output (HIGH,LOW).

I wouldn’t be able to move those items, they’re attached in a way I wouldn’t know how to re-locate, but I appreciate the suggestion. What about using another Arduino? Since I am not great at coding when there’s tons and tons of lines, having a second Arduino that also reads the avoidance sensors would be perfect. Is that possible?

@Josh you could upgrade the entire thing to an Arduino Mega instead of the Uno.. should have similiar code but you have tons of I/O pins more.

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


text:
Need some help on a very small project
Apologies for the simple question, I really couldn’t find any help online with this as when I kept searching, the results had lights that had way too much voltage compared to what I need.
So I have a simple light decoration that requires around 3v and comes with a battery pack to power it (2AA batteries) and I took it apart and was able to connect them via a breadboard to test if is all working.
How do incorporate the Arduino into it so that I can switch the lights on through the Arduino? A lot of the small voltage videos I saw were just simple connecting 1 LED through a digital pin but that’s not enough current for the lights I have and I’m not experienced enough to find myself a solution so help would be greatly appreciated.
For little more info, the 3.3v and 5v pins my Arduino (uno) are already taken up.
Also, I’ll be turning the lights on and off with an IR Remote which I’ve already programmed to a servo that’s powered through the USB supply (5v) and the IR Sensor is connected to the 3.3V.
Sorry if the question was badly worded.

It all depends on the simple light decoration. What is it? Can you show a photo? Do you have a schematic of it? What kind of leds are used? and so on.

https://imgur.com/a/TgPQBDZ https://imgur.com/a/b0l1isT - It’s a small shelf decoration in the shape of ‘&’ @Jot

No @gre_gor, the dude there is calling for a 12v lightbulb.

the 3.3v and 5v pins my Arduino (uno) are already taken up .... no they are not .... run a jumper over to the breadboard so that you can make multiple connections

@jsotola wouldn’t that give less power to each component? I remember trying this with the ir sensor, but it seemed to give the servo less kick.

the comment was about pin availability since you said that you have no more pins for 3.3V and 5V ...... power availability is another issue ..... do not power a servo from the arduino

Thanks for the photo, that could be 10 white leds of 20mA each parallel. The total current is 200mA for leds that are about 3v. Or are they neopixel rgb leds? Was there a controller that could change the color? The first comment by @gre_gor explains that you need a darlington transistor or a mosfet. You also need a resistor of at least 0.5w to limit the current. On the other hand, if they are rgb leds, then they could be for 3v and not for 5v.

@jot thank you for trying to help! They are plain white LED’s. I would really call them white LED’s with a tint of yellow. To turn them on and off, it was a simple switch but as this will be high on a shelf, I don’t want to constantly take it down. I’ll do some research on transistors and see what I find. Thanks again!

I think I managed to make a little circuit that should prevent you from burning up your Arduino.

From what I read you shouldn't connect MOSFET directly to Arduino. Imagine that MOSFET has a little capacitor inside it, and in the beginning that capacitor can take such high current that actually can burn the Arduino pin. Instead you use a simple NPN transistor (with 100kohm resistor) as a "switch". The NPN can survive much higher current, and it will not strain the Arduino pin.
When I simulated this setup using the default "blink" sketch the light bulb was lit when PIN13 was HIGH. Just note that there always is a small voltage drop (think of it as a resistor inside the MOSFET) and it can make the MOSFET get a little warm. In your setup it should not be a problem, but in some cases it's nice to screw a radiator on the MOSFET.

Thank you so much for the reply and schematics. I’ll have to buy a mosfet as the Arduino kit I have didn’t come with one, and then I’ll test it out. Thanks again!

Before I purchase mosfets, as they only come in packs and I will likely never use them again, will anyone of these be sufficient? https://imgur.com/a/U15yVXi (They come with my kit?)

These are not MOSFETs. These are BJT transistors of the NPN type. Since your light decoration will probably not draw much current It's quite possible that you will be able to use just them (just remove MOSFET from my design) Please experiment with different designs in Tinkercad.

After taking out the mosfet, the light turned on. One problem I have before I build the actual circuit is the resistor. I have never decided my own value for resistors before so I don’t know what to do. You mentioned 100k for the mosfet but not that I’m not using it surely I don’t need a 100k resistor? Seems way too much. Also - huge thanks for introducing me to tinkercad. This will help me for tonnns of projects!

MOSFET to work properly needs to be discharged to be opened (that imaginary capacitor is inside) so when the NPN (electronic switch) is "opened" that 100K resistor discharges the MOSFET. But when NPN (electronic switch) is "closed" part the current goes into the MOSFET (charging the imaginary capacitor), and part goes through that resistor. The higher the resistor value the less current is wasted that way (but slower MOSFET discharge) But if you removed the MOSFET you probably don't need to discharge anything, and it's possible that your lights will work without the resistor. Experiment.

Thank for the information! I’ll experiment with some low value resistors and comment if it succeeded.

Just remember that the lower the value of the resistor the more current is wasted, batteries drain faster and the resistor gets hotter.


text:
Two SSL connections at the same time on Uno WiFi rev 2
So I want to have one persistent SSL connection to a cloud server (Azure IoT Hub) to upload telemetry and another SSL connection to a server to perform a simple GET request every 30 minutes.
I've setup my first connection and telemetry is successfully sent, then I connect to the second server, I get a response, close the connection, but my first connection to Azure IoT Hub crashes.
I haven't found any information online on how many simultaneous SSL connections the Arduino Uno WiFi Rev. 2 supports nor any guidance on how to use more than 1 SSL connections. Any help would be greatly appreciated.

I have had some problems with using two sockets simultaneously with WiFiNINA versions > 1.3, see https://github.com/arduino-libraries/WiFiNINA/issues/87 . Maybe it's the same problem. Which WiFiNINA version are you using?

@ocrdu yes I think it's the same problem. I was using version 1.6.0.

Edit: Firmware version is 1.3, library version is 1.7

If things work OK when you use firmware 1.4 and this alternative library: https://github.com/ocrdu/WiFiNINA , then it's the same problem 8-).


text:
Problems Sending Signals to the Arduino-Uno via Keyboard
I have an Arduino Uno and a usb 2.0 shield in which I connected a keyboard to. I have all the necessary libraries installed but what I am trying to figure out is how to light an led when I press a specific key.
I am new to codding Arduino boards and I have done a lot of reading but I cant figure out my issue I feel like if I get this figured out I will be a lot better off in my future projects.
#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

int SKEY = 8;

class KbdRptParser : public KeyboardReportParser
{
    void PrintKey(uint8_t mod, uint8_t key);

  protected:

    void OnKeyDown  (uint8_t mod, uint8_t key);
    void OnKeyUp    (uint8_t mod, uint8_t key);
    void OnKeyPressed            (uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
  Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
  Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

  Serial.print(" >");
  PrintHex<uint8_t>(key, 0x80);
  Serial.print("< ");

  Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
  Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
  Serial.println((mod.bmRightGUI  == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  Serial.print("DN ");
  PrintKey(mod, key);
  uint8_t c = OemToAscii(mod, key);

}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
  Serial.print("UP ");
  PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
  Serial.print("ASCII: ");
  Serial.println((char)key);
};

USB Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);

KbdRptParser Prs;

void setup() {

 Serial.begin(9600);
#if !defined(__MIPSEL__)
  while (!Serial);
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

  delay( 1 );

  HidKeyboard.SetReportParser(0, &Prs);

}

void loop() {
 Usb.Task();
}

Anyways I know how to make if statements and how to activate pins on the Arduino but I cant figure it out in this keyboard library. For now I just made it print "TRUE" since there is not need to get complicated if I cant get the first step to work. Before I made that if statement the serial monitor would show the value assigned to the key and label it DN # and when I let up on the key it would say UP # but how can I translate that to sending a pulse to whatever pin when I push a key and stop sending a pulse when I let up on the key?
Also in my if statement that I made I know I need something before == sign but I tried multiple things and they did not work so I just left it blank and the reason I used the number 16 was because that was the value assigned to the S key in which I wanted to use to light an led. Anyways any help would be greatly appreciated!

what LED are you talking about? ... you have no LED control code in your sketch

you can print DN when a key is pressed ...  why can't you turn on an LED when a key is pressed?

sending a pulse to whatever pin when I push a key and stop sending a pulse ... that only applies to a flashing LED ... if you turn on a LED and leave it on, then that is not a pulse

I dont want to leave an led on... I want to be able to push a key to turn on an led and when I let up on that key the led should turn off. Also I made it clear that I have not made the led code yet because if I cant figure out how to make the proper if-statement none of it will work. Every time I try I get an error which was the whole reason I asked this question I know the code to make an led light up but I dont know how to do that while using the keyboard library...

your post says nothing about an error ... why don't you turn on the LED right after you print DN? ... turn off the LED right after you print UP

If I could I would... why else would I be asking this question if I knew how to do it...

i do not understand ... find the line that prints DN ... insert a line that turns on the LED right after it

The only if statement I see is if (Usb.Init() == -1) but that doesn't seem like one you are having trouble with. What is the full exact error message you get from the Arduino IDE when you compile your code?

Did you post the wrong code?  Where is this if statement you are talking about?

In the oneKeyDown routine you get a parameter called key that has the key that was pressed.  Save it to a variable and you can put that variable in an if statement to do whatever you want if it is equal to some value.  Or just light the led when the button is pressed right there in that routine.

Keyboards cannot be used quite like you wish - the keyboard will send a key (scan) code when a key is pressed and then repeat that code if the button continues to be pressed. There is a different code sent when the same key is released.

The scancode for key release is obtained from it by setting the high
order bit (adding 0x80 = 128). Thus, Esc press produces scancode 01,
Esc release scancode 81 (hex).  For sequences things are similar:
Keypad-/ gives e0 35 when pressed, e0 b5 when released. Most keyboards
will repeat the make code (key down code) when the key repeats.

From: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html

Very strange because when I press a key there is a specific number or number letter combo attached to it. For example when I look at the serial monitor it knows what key I am pressing and for how long. I dont understand how the Arduino knows via the serial monitor what key is being pressed and is able to print it but wont cant send a pulse to a specific pin based on the duration the key is held down. If the Arduino is aware of the specific key being pressed and its duration there is no reason it cant light an led up.

@CyClone Well, this question and its answer were left alone, because you did not edit your question answering 1) how you tried to control the LED, and 2) which error you got trying.


text:
Why Would Declaring a Global Variable Change How An Unrelated Conditional is Evaluated?
Here is my entire sketch. This is my first Arduino project.  I included all of it because I don't know what's relevant.  I am printing out to a 4-digit 7 segment display.  To do that I use sprintf to format the contents of a char[] called tempString  and that gets sent to the display. I declared a new local char[] each time I needed one.  I had a problem with the Arduino Pro Mini running out of memory.   I tried declaring a global chart[] and reusing it when I needed it, but that changed the way the program executed.  That was the only change I made.
After I made that change, the Arduino would always evaluate this true:
 if (countDownTimer.TimeCheck(0, 0, 0))

The CountDownTimer was always evaluating to a time of 0, even after it had been assigned a valid time and the timer hadn't started running. I verified I was setting it correctly, but by the time the conditional was reached, the Timer was back to 0.
If I remove the global declaration for tempString[] and go back to locals the logic works as designed.  I made tempString[] smaller as a local and that seems to have fixed the memory issue but I would like to know why declaring a global caused a problem.
 #include <SoftwareSerial.h>
#include <CountUpDownTimer.h>
#include <EEPROM.h> //Needed to access the eeprom read write functions

//values for EEPROM
int stepsToWrite = 0;
int stepsToRead = 0;
int priorValue = 0;

// addresses to write to and read from
const int thirtySecondAddress = 0;  // constant
const int threeMinuteAddress = 4;   // constant
int addressToUse = 0;   // this will change depending on time user selects

// set uo the serial display
const int displayTx = 5;  // the pins we need to create the software serial instance
const int displayRx = 7;   // we will only use Tx
SoftwareSerial s7s(displayRx, displayTx);

//set up the timer
CountUpDownTimer countDownTimer(DOWN);
const long displaychangeInterval = 10000; // in milliseconds
const long countdownInterval = 1000; // in milliseconds

long previousMillis = 0; // for changing between time left and step count
long previousTimerMillis = 0;  // for updating the display with the new time
const int thirtySecondTime = 30;
const int threeMinuteTime = 180; // 3 minutes expressed as seconds
int timerStartValue = 0;  // needed for some control logic

// booleans to control what is displayed
bool doDisplayStepCount = false;
bool doDisplayCountDown = false;
bool doDisplayHighScore = true;  // we want to display this at startup

// set up the buttons
const int timerbuttonPin = 6;     // the number of the timer pushbutton pin
const int resetbuttonPin = 4;     // the number of the reset button pin

int timerbuttonPushCounter = 0;   // counter for the number of button presses
int timerbuttonState = 0;         // current state of the button
int timerlastButtonState = 0;     // previous state of the button

int resetbuttonPushCounter = 0;   // counter for the number of button presses
int resetbuttonState = 0;         // current state of the button
int resetlastButtonState = 0;     // previous state of the button

int stepsTaken = 0; // the number of steps (jumps)
boolean timerStarted = false;

// for the force resistor
const int FSR_PIN = A0; // Pin connected to FSR/resistor divider
const float VCC = 5.10; // Measured voltage of Ardunio 5V line
const float R_DIV = 3265.0; // Measured resistance of 3.3k resistor

double currentForce = 0;
double previousForce = 0;
boolean previousPos = false;
boolean currentPos = false;

boolean doChangeDisplay = false;

char tempString[4];
void setup() {

  boolean debug = true;
  if (debug)
  {
    EEPROMWriteInt(thirtySecondAddress, 0);  // zero out EEPROM
    EEPROMWriteInt(threeMinuteAddress, 0);  // zero out EEPROM
  }
  // start serial connection
  Serial.begin(9600);

  // set up pins
  pinMode(FSR_PIN, INPUT);
  pinMode(timerbuttonPin, INPUT);
  pinMode(resetbuttonPin, INPUT);

  // serial display
  // Must begin s7s software serial at the correct baud rate.

  // Clear the display
  //  The default of the s7s is 9600.
  s7s.begin(9600);
  //clearDisplay();  // Clears display, resets cursor
  // s7s.print("-HI-");
  // delay(1000);

  displayHighScores();

}

void loop() {

  // Serial.print("freeMemory()=");
  // Serial.println(freeMemory());

  //  Serial.println("Starting loop");
  // button pushes
  // if tinmerbuttonPushCounter = 1, set timerValue to 30 seconds
  // if 2 pushes, set to 3 minutes and reset push counter to 0

  //Serial.println("Reading timer button, state is: " + timerbuttonState);
  timerbuttonState = digitalRead(timerbuttonPin);
  // Serial.println("Reading reset button, state is: " + resetbuttonState);
  resetbuttonState = digitalRead(resetbuttonPin);

  // compare the buttonState to its previous state

  if (timerbuttonState != timerlastButtonState)
  {
    Serial.println("selecting time");
    if (timerbuttonState == HIGH)
    {

      doDisplayHighScore = false;
      timerbuttonPushCounter++;
      // if the current state is HIGH then the timer button went from off to on:
      if (timerbuttonPushCounter == 1)
      {
        doChangeDisplay = false;
        doDisplayCountDown = true;
        timerStartValue = thirtySecondTime;
        addressToUse = thirtySecondAddress;
        Serial.println("timer button pushed: " + String(timerbuttonPushCounter));
        Serial.println("start value: " + String(timerStartValue));
        clearDisplay();
        setDecimals(0b010000);  // Turn on colon
        sprintf(tempString, "%04d", thirtySecondTime);
        Serial.println("Timer set to: " + String(tempString));
        s7s.print(tempString);
      }

      else if (timerbuttonPushCounter == 2)
      {
        timerStartValue = threeMinuteTime;
        addressToUse = threeMinuteAddress;
        doChangeDisplay = true;

        int timerinminutes = timerStartValue / 60;
        Serial.println("timer button pushed: " + timerbuttonPushCounter);
        Serial.println("start value  " + timerStartValue);
        timerbuttonPushCounter = 0;
        clearDisplay();
        setDecimals(0b010000);  // Turn on colon
        sprintf(tempString, "0%d00", timerinminutes);
        Serial.println("Timer set to: " + String(tempString));
        s7s.print(tempString);
      }
    }  // end of if timer state high

    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  timerlastButtonState = timerbuttonState;

  // for reset button, logic is much simpler
  // if state is high, button has been pushed so reset everything
  if (resetbuttonState != resetlastButtonState)
  {
    if (resetbuttonState == HIGH)
    {
      Serial.println("Reset button pushed!");
      doDisplayHighScore = true;
      resetStepCounter();
      // Delay a little bit to avoid bouncing
      delay(50);
    }
  }

  resetlastButtonState = resetbuttonState;

  // step pad logic
  int fsrADC = analogRead(FSR_PIN);
  previousForce = currentForce;
  currentForce = calculateForce(fsrADC);
  // trying this using force values
  // when we step force is always positive
  // when we lift our foot force is always negative

  if (currentForce > 0)
  {
    currentPos = true;
    Serial.println("Force detected!");
    delay(1000);
  }
  if (previousForce < 0)
  {
    previousPos = true;
  }

  if (currentPos && previousPos)
  {
    // start the timer on the first step
    if (!timerStarted)
    {
      Serial.println("First steop!");
      timerStarted = true;
      // Serial.println("Timer start value: " +String(timerStartValue));
      countDownTimer.SetTimer(0, 0, timerStartValue);
      countDownTimer.StartTimer();

      //  char tempstring[10];
      sprintf(tempString, "%4d", countDownTimer.ShowMinutes(), countDownTimer.ShowSeconds());
      Serial.println("Timer set to: " + String(tempString));
      //  Serial.println("Timer started");
      //  delay(2000);
      doDisplayCountDown = true;
    }

    stepsTaken++;
    Serial.println("Step Detected!");
    currentPos = false;
    previousPos = false;
  }

  // if timer is 0 we have run out of time
  // this needs to be done here as it must always be done and can't depend
  // on displayCountDown being true

  if (timerStarted)
  {
    if (countDownTimer.TimeCheck(0, 0, 0))
    {
      //Serial.println("out of time");
      //delay(500);
      timerStarted = false;  // set timerRunning to false
      countDownTimer.StopTimer();
      if (timerStartValue == thirtySecondTime)
      {
        WriteHighScore(thirtySecondAddress, stepsTaken);
      }

      if (timerStartValue == threeMinuteTime)
      {
        WriteHighScore(threeMinuteAddress, stepsTaken);
      }
      Serial.println("wrote high score");
      delay(500);
      // clearDisplay();
      //displayStepCount();
      // resetStepCounter();

      // displayCountDownTimer();
    }

    //else

    if (!(countDownTimer.TimeCheck(0, 0, 0))) // && timerStarted)
    {

      countDownTimer.Timer(); // run the timer
      Serial.println("Timer is running");
      // timer logic
      // every 10 seconds, change booleans on what gets displayed
      unsigned long currentMillis = millis();
      // the last 10 seconds only display the step count
      //if (countDownTimer.TimeCheck(0, 0, 10))
      // {
      //
      //   displayStepCount();
      // }

      // else
      //  {

      if (doChangeDisplay)
      {
        if ((currentMillis - previousMillis) >= displaychangeInterval)
        {
          // save the last time we checked the interval
          //  Serial.println("10 second interval!");
          previousMillis = currentMillis;

          // if this is true, set it to false
          // set the countdown display to true
          if (doDisplayStepCount)
          {
            doDisplayStepCount = false;
            doDisplayCountDown = true;
          }

          else
            // countdown display is true, so set it to false
            // and set stepcount display to true
          {
            doDisplayStepCount = true;
            doDisplayCountDown = false;
          }

        }
      }

      // only display step count if this is the interval to do it
      if (doDisplayStepCount)
      {
        displayStepCount();
      }

      // only display countdown timer if this is the 10 second interval to do it
      if (doDisplayCountDown)
      {
        displayCountDownTimer();
      }

      //  }

    }
  }

}

// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplay()
{
  s7s.write(0x76);  // Clear display command
}

// Turn on any, none, or all of the decimals.
//  The six lowest bits in the decimals parameter sets a decimal
//  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
//  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
// (0b010000) - colon only
//  (0b111111) - all decimals
void setDecimals(byte decimals)
{
  s7s.write(0x77);
  s7s.write(decimals);
}

void resetStepCounter()
{
  timerbuttonPushCounter = 0;
  if (timerStarted)
  {
    countDownTimer.StopTimer();
    timerStarted = false;
  }

  // clean up
  stepsTaken = 0;
  clearDisplay();
  timerStartValue = 0;
  doDisplayHighScore = true;
}

void displayStepCount()
{
  setDecimals(0b000000);  // Turn off the colon
  // Will be used with sprintf to create strings
  sprintf(tempString, "%04d", stepsTaken);
  Serial.print("Steps taken: " + String(tempString));
  clearDisplay();
  s7s.print(tempString);
}

void displayCountDownTimer()
{
  // example formats
  //sprintf(tempString, "%4d", deciSecond); //Convert deciSecond into a string that is right adjusted
  //sprintf(tempString, "%d", deciSecond); //Convert deciSecond into a string that is left adjusted
  //sprintf(tempString, "%04d", deciSecond); //Convert deciSecond into a string with leading zeros
  //sprintf(tempString, "%4d", deciSecond * -1); //Shows a negative sign infront of right adjusted number
  unsigned long currentMillis = millis();
  int seconds = 0;
  int minutes = 0;

  // only update the display if 1 second has passed
  // if(currentMillis - previousTimerMillis >=  countdownInterval)
  // CountUpDownTimer TimeHasChanged() returns boolean (in seconds)

  if (countDownTimer.TimeHasChanged())
  {
    // previousTimerMillis = currentMillis;
    seconds = countDownTimer.ShowSeconds();
    Serial.println("Time left: " + seconds);
    minutes = countDownTimer.ShowMinutes();
    sprintf(tempString, "%02d%02d", minutes, seconds);

    clearDisplay();
    setDecimals(0b010000);  // Turn on colon
    Serial.println(tempString);
    s7s.print(tempString);
  }
}
void EEPROMWriteInt(const int p_address, const int p_value)
{
  byte lowByte = ((p_value >> 0) & 0xFF);
  byte highByte = ((p_value >> 8) & 0xFF);

  EEPROM.write(p_address, lowByte);
  EEPROM.write(p_address + 1, highByte);
}

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
int EEPROMReadInt(const int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);

  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}

void WriteHighScore(int address, int value)
{
  // int valueRead = EEPROMReadInt(address);
  //if (valueRead < value)
  // {
  EEPROMWriteInt(address, value);

  delay(500);
  sprintf(tempString, "%04d", value);
  Serial.print("high score: " + String(tempString));
  clearDisplay();
  s7s.print("-HI-");
  delay(500);
  clearDisplay();
  s7s.print("SCOR");
  delay(500);
  clearDisplay();
  s7s.print(tempString);
  delay(500);

  // }
}
void displayHighScores()
{
  int thirtySecondScore = EEPROMReadInt(thirtySecondAddress);
  int threeMinuteScore = EEPROMReadInt(threeMinuteAddress);
  sprintf(tempString, "%04d", thirtySecondScore);
  Serial.println("thirty second score: " + String(tempString));
  sprintf(tempString, "%04d", threeMinuteScore);
  Serial.println("Three minute score: " + String(tempString));

  clearDisplay();  // Clears display, resets cursor
  s7s.println("-HI-");
  delay(1000);
  clearDisplay();
  Serial.println("SCOR");
  s7s.print("SCOR");
  delay(1000);
  clearDisplay();
  sprintf(tempString, "%04d", thirtySecondScore);
  Serial.println(tempString);
  s7s.print(tempString);
  delay(1000);

  clearDisplay();
  sprintf(tempString, "%04d", threeMinuteScore);
  Serial.println(tempString);
  s7s.print(tempString);
  delay(1000);
  clearDisplay();
}

float calculateForce(int pinvalue)
{
  // Use ADC reading to calculate voltage:
  float fsrV = pinvalue * VCC / 1023.0; // 1023 is # of units of voltage between 0 and 5V
  // Use voltage and static resistor value to
  // calculate FSR resistance:
  float fsrR = R_DIV * (VCC / fsrV - 1.0);
  // Serial.println("Resistance: " + String(fsrR) + " ohms");
  // Guesstimate force based on slopes in figure 3 of
  // FSR datasheet:
  float force;
  float fsrG = 1.0 / fsrR; // Calculate conductance
  // Break parabolic curve down into two linear slopes:
  force = (fsrG - 0.00075) / 0.00000032639;
  return force;
}

add a position for terminating zero in tempString. tempString[5]. now the 0 is written by sprintf to memory after the array

This line:
sprintf(tempString, "%04d", thirtySecondTime);

writes 5 characters to tempString, the four digits and a terminating null.  You only gave the array room for four.
This:
Serial.println("Timer set to: " + String(tempString));

is a total waste of resources.  If you want to talk about memory usage then don't use the String class and definitely don't use it where it simply is not needed.
Write that as:
Serial.print("Timer set to: ");
Serial.println(tempString);

or better yet from a memory standpoint as:
Serial.print(F("Timer set to: "));
Serial.println(tempString);

thanks.  I was reading about String() memory usage and will change that.  Most of the serial output will be removed after I am done with all the debugging.  From @Juraj comment I did some research and now understand the termination.


text:
Does baud rate for HC-05 Bluetooth module need to match the Serial Monitor?
I have this sketch that I got as a sample.  I have the two HC-05s connected.  What I type in one serial monitor shows up on the other, but as question marks.  The most common reason for this I find is baud rate doesn't match.   I didn't change the baud rate on the HC-05s when I got them, so I assume they are set to default.  I can put them in command mode and ensure the baud rate is set.
Does the baud rate of the HC-05s have to match the baud rate of the Serial monitor?  I would assume not.  I am also wondering if this is a problem with formatting a char[] when writing to the serial display.
#include <SoftwareSerial.h>
SoftwareSerial BTserial(7, 8); // RX | TX
// Connect the HC-05 TX to Arduino pin 7 RX.
// Connect the HC-05 RX to Arduino pin  8 TX through a voltage divider.
//

char c = ' ';

void setup()
{
Serial.begin(9600);
Serial.println("Arduino is ready");
Serial.println("Remember to select Both NL & CR in the serial monitor");

// HC-05 default serial speed for AT mode is 38400
BTserial.begin(38400);
}

void loop()
{

// Keep reading from HC-05 and send to Arduino Serial Monitor
if (BTserial.available())
{
    c = BTserial.read();
    Serial.println(c);
}

// Keep reading from Arduino Serial Monitor and send to HC-05
if (Serial.available())
{
    c =  Serial.read();
    BTserial.write(c);
}
}

It was the baud rate.  I read the baud rate from the bluetooth modules, it was set to 9600.  I tweaked the code and its working now

Both of these comments should be answers @jsotola

@jsotola thanks.  I didn't think so.

No, they do not need to match.
You are talking about two separate serial port connections.
The baud rate between the HC-05 and the Arduino (BTserial) has to match.
The baud rate between the Arduino and your PC (Serial) has to match.
BTserial and Serial can use different baud rates.
An overflow problem can arise if a lot of data arrives from the HC-05 and there is not enough memory to store it until it can be forwarded to Serial.

simulate this circuit – Schematic created using CircuitLab


text:
Reading data from SPI on ESP32-WROOM-32
I'm newbie with Arduino and need to do a short task: read data from SPI (sent by another microcontroller) and send to WiFi (by ESP32-WROOM-32).
I can't understand how to initialize and read data from SPI. I'm using VSPI. I need to use VSPI class? Or a SPI class?
Any idea will help me a lot.
Thanks

can you use uart instead? it's a lot simpler...

@dandavis unfortunately no

ESP-32 is not an Arduino

@Juraj you are correct, but ESP-32 can be programmed with Arduino IDE and arduino code

do you use the Arduino IDE and the ESP32 Arduino package?

Yes. WiFi part is running ok. The problem is SPI communication.

did you see the example of the SPI library?

I saw SPI_Multiple_Buses example. Is it?

yes, there is everything explained

In this example there is no SPI slave. Correct me if I'm wrong. I have a master microcontroller, who send me information on SPI bus. I need do read these information and put on WiFi (ESP-32) connection. In this case ESP-32 is the SPI slave. Right?

you didn't ask about slave mode. slave can send data to master (if the master requests them). esp32 arduino SPI slave library is not implemented yet


text:
Enable and disable individual interrupts
I am working on timer interrupts and external interrupts.
for external interrupts I understood the functions like attachInterrupt. detachinterrupt for individual interrupts ,noInterrupts() and  interrupts() can be used to enable and disable all interrupts at a time.
But How to enable and disable timer interrupts??
I am writing a code for alarm clock and snooze button. So what I want is
1) whenever alarm time is equal to watch time, start a timer for 5 minutes and a buzzer buzzes.
2) whenever I press the snooze button,  another timer starts and after 30 seconds a buzzer beeps. again I press snooze and again the timer starts and after 30 seconds buzzer beeps.
3) But after 5 minutes of the first timer, both timer interrupts gets disabled as now I dont want any buzzer.
I know how to initialize the timer in setup function, and I am getting the buzzes every 30 seconds. I also know that interrupts will come according to the timer value and I need to call the function after a fix number of counts or 30 seconds or 5 minutes.
But I dont know how to disable and enable timer interrupts wherever I want in code.

Why are you using timer interrupts for this? A software timer (based on millis()) seems more appropriate, as you cannot program a hardware timer to fire more than about 4.2 seconds into the future.

Thank you very much, I have just read about the millis() and I think that it'll be more useful. I'll try to do my project using millis and let you know.

Step 1: Read the datasheet for the chip.
Step 2: Find the registers that control the timers and their interrupts.
Step 3: Set or clear the relevant bits in those registers.

For example, the ATMega328P has the TIMSK1 register for Timer 1, which has three bits related to interrupts:

Bit 2 – OCIE1B: Timer/Counter1, Output Compare B Match Interrupt Enable

When this bit is written to one, and the I-flag in the status register is set (interrupts globally enabled), the Timer/Counter1
  output compare B match interrupt is enabled. The corresponding interrupt vector (see Section 11. “Interrupts” on page 49) is
  executed when the OCF1B flag, located in TIFR1, is set.

Bit 1 – OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable

When this bit is written to one, and the I-flag in the status register is set (interrupts globally enabled), the Timer/Counter1
  output compare A match interrupt is enabled. The corresponding interrupt vector (see Section 11. “Interrupts” on page 49) is
  executed when the OCF1A flag, located in TIFR1, is set.

Bit 0 – TOIE1: Timer/Counter1, Overflow Interrupt Enable

When this bit is written to one, and the I-flag in the status register is set (interrupts globally enabled), the Timer/Counter1
  overflow interrupt is enabled. The corresponding interrupt vector (see Section 11. “Interrupts” on page 49) is executed when
  the TOV1 flag, located in TIFR1, is set.

So to turn off the Compare B Match interrupt you can use:
TIMSK1 &= ~(1 << 2);

And to turn it on again:
TIMSK1 |= (1 << 2);

Both Timer 0 and Timer2 have a TIMSKx register which works in the same way.


text:
Connecting ESP8266 to website
I would like to control a relay using Wemos D! R1 via a website from anywhere. I managed to control it using local web server and now would like to step it up further.
I'm using the following code which connects to this website and retrieve data as JSON perfectly.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

const char* ssid = "SSID";
const char* password = "PASS";

void setup () {
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
    }
}

void loop() {
    if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
        Serial.println("");
        HTTPClient http;  //Declare an object of class HTTPClient
        http.begin("http://jsonplaceholder.typicode.com/users/1");  //Specify request destination
        int httpCode = http.GET();                                                                  //Send the request

        if (httpCode > 0) { //Check the returning code
            String payload = http.getString();   //Get the request response payload
            Serial.println("");                  // Empty Line
            Serial.println(payload);             //Print the response payload
            //////////////// Json code
              StaticJsonDocument<2000> doc;
              DeserializationError error = deserializeJson(doc, payload);
              if (error) {
                Serial.print(F("deserializeJson() failed: "));
                Serial.println(error.c_str());
                return;
              }
              const char* sensor = doc["name"];
              const char* username = doc["username"];
              const char* email = doc["email"];
              const char* address = doc["address"];
              Serial.println(sensor);
              Serial.println(username);
              Serial.println(email);
              Serial.println(address);
            //////////////// End of Json Code
              http.end();   //Close connection
              while ( 0 < 1 ){ delay(10000); }  // to break the loop
            }
    }
    delay(10);    //Send a request every 30 seconds
}

I made a web page that makes AJAX call to a PHP file to retrieve data from MYSQL DB, but when I run it, the monitor keeps printing empty lines forever although connected successfully to my WIFI.
$(document).ready(function(){
$.ajax({
        url: "test.php",
        type: 'GET',
        dataType: 'json', // added data type
    data: ({mobile: 'hi'}),
        success: function(res) {
            console.log(res);
        }
    });
});

The result I'm getting from AJAX is (which you can check visiting this link:
    {"status":"ON"}

I'm using the following code on php file:
<?php
header('Content-type: application/json');
require 'functions.php';
header("Access-Control-Allow-Origin: *");
    $catrecord = mysqli_query($link,"SELECT * FROM `ard`");
        while($catinfo = mysqli_fetch_array($catrecord, MYSQLI_ASSOC)){ $Cat = $catinfo['status']; }
    $responseArray = array('status' => $Cat );

if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    $encoded = json_encode($responseArray);
    header('Content-Type: application/json');
    echo $encoded;
} else {
    echo $responseArray['status'];
}
?>

check the returning code. 200 is OK. all others are an error. negative return values are a local error. positive are a HTTP error

What is the exact question? You don't know how to modified the Arduino code to receive json payload of {"status":"on"}?

you can use port forwarding or websockets to control from the WAN. or hammer the php site from the wemos, but that's not as good as talking to the esp server directly or having always-on streaming.

@dandavis "talking to the esp server directly or having always-on streaming." would you please elaborate more or share a link about this methodology. Thx

You should do what @Juraj suggested. The way it's written now, your code won't correctly report errors which would hide the cause of the problem you're seeing.


text:
Most Efficient & Cost Effective Home Automation Setup
I managed to build a system using Wemos D1 R1 connected to my website to retrieve data to power on or off a 5V relay. Now I would like to expand the project to control all my house outlet. Assuming I have, 5 rooms each of which has 5 electricity wires to control. My question is what is the best setup to achieve my goal in terms of efficiency and cost optimization. If I clone my current setup, I would be needing Wemos Module for every room that connecting separately to my Wifi and then to my server which seems too much for me. So what would you recommend?
Thoughts:

Can I use one single central Wemos and then communicate to each room through ESP2866 or 433MHZ RF modules.
I would be using at least 4 channel 5V relay Module. Could it be powered using 5V in Wemos or Arduino or should be powered with adapter
If I want to control a fridge or AC or water heater, should I need SS Relay or any relay would suffice
if SS Relay to be used, I have read that heat sink or fan should be included, is that a must?

Those are a lot of questions in one. You could start by using 3V relay modules that do not need an external transistor. In my home, I am using a separate ESP module, connected to my Wifi for each device that needs to be controlled. What would be the advantage of using a central module with separate 433MHz channels to other modules? It only adds complexity and unnecessary dependencies. As for your other questions, you should look into the specifications of the relays / Solid State relays.

Just get a bunch of SWA1 WiFi socket adapters. They are ESP8266 based and you can hack them with your own code.

@Majenko, exactly. Sonoff also makes hackable ESP8285 / ESP8266 based smart switches that can be modified to run your own code.

why would you want to unplug your fridge or water heater? Both of those would be better with relays than SSRs, unless you deal with the SSR's heat correctly. Assume 1.5 watt of heat for every amp of current. I would much rather have 1 ESP per outlet than illegally re-wiring 4 outlets to a 4 channel relay. Wifi can handle the "traffic", don't worry about that; i ran out of reserved IPs on mine, and have dozens of static IPs going as well, yet i still have about 10-20ms lag per command, which is typical and acceptable.

I like sonoffs, but I found "WiOn 50050" smart outlets can be controlled by node-red without cracking them open using UDP packets, so if all you need is on/off control, they are a decent low-effort option.

I advice you to buy some Sonoff devices, either the basic or S20. (they are pretty cheap on AliExpress/ebay etc.) They are perfect for the job. Flash them with Tasmota, which you find on github Tasmota. Then use a RaspberryPi (or similar) as a server. Run Node-RED on this server to communicate via MQTT to all your (Sonoff) devices. Use Mosquitto as the MQTT broker.
I know this sounds like a lot, but thank me later when your done.


text:
Frequency of Retrieving Data from Website
I have wrote a code that communicate with my website to retrieve data to power on or off a 5V relay. I'm running the code every second to make sure it is real time. Is there more efficient way to tell Arduino to get the data whenever it is changed rather than continuous GET request.
// Send HTTP GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");        Serial.println(httpResponseCode);        String payload = http.getString();
        StaticJsonDocument<2000> doc;             DeserializationError error = deserializeJson(doc, payload);
        if (error) {              Serial.print(F("deserializeJson() failed: "));              Serial.println(error.c_str());              return;            }

        String status = doc["status"];
        Serial.println(status);
         if ( status == "ON" ) {
           digitalWrite(ledPin, LOW);
         } else {
           digitalWrite(ledPin, HIGH);
         }
  }

you could use the response code to indicate the state of the relay

Use websockets instead. Or MQTT if you can run your own server or use a free public server...

Your two best options would be MQTT and WebSockets.
Both would open a long lived TCP connection that the ESP8266 and browser could use to transmit and receive data. Both would avoid constant polling to see if there's a new command.
MQTT requires an external broker. There are MQTT services with free tiers you could use for this or you could run one locally - Eclipse Mosquitto is a popular MQTT broker that runs nicely on a Raspberry Pi. MQTT is particularly useful for networks with multiple publishers and subscribers (it's a "pubsub" protocol) and is probably overkill if you just have a single device and endpoint.
It's easy to use MQTT from a browser using Javascript. The Paho Javascript MQTT client works well. The ESP8266 would establish a connection to the MQTT broker, subscribe to a topic name and set a callback function that would be called when data was published to that topic. The browser would also establish a connection to the MQTT broker and would publish a message to the topic when responding to events from the user.
WebSockets would allow the ESP8266 and browser to establish a full duplex connection between them. The ESP8266 would create a websocket server which the browser would connect to. The ESP8266 would check for data on the websocket during while running code in loop() and would assemble messages from the browser.
Either works easily if both your devices are on the same network (for instance, at home). If your browser is outside the network, it won't be able to communicate directly with the ESP8266.
MQTT has the advantage that an MQTT server located outside of the network (not one running locally on a Raspberry Pi) would allow the browser and ESP8266 to communicate with one another through it. WebSockets would require the use of a proxy server (there are modules for popular web servers like NGINX and Apache, but this requires control of the web server to configure). If you only ever want to use the browser to control the ESP8266 while they're both on the same network you don't need to worry about this.


text:
I Can't Connect to my MQTT server via arduino
I have mosquitto MQTT installed on my VPS server which I can subscribe and publish to it using paho client thorugh websockets. However when I tried to connect to it through Arduino, I get the following error:
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds

I uploaded the following code to arduino:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "IOT";
const char* password = "11112222";
const char* mqtt_server = "burooq.com";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  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("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("test", "hello world");
      // ... and resubscribe
      client.subscribe("test");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

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

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("test", msg);
  }
}

i checked my server mosquitto ports which shows
mosquitto 10436       mosquitto    4u  IPv4   46043      0t0  TCP 127.0.0.1:1883 (LISTEN)

I checked my conf file and it has
listener 1883 localhost

so how what's wrong within my code or settings that prevents me from connecting to my server?`

does it work from other computer then the server?  what is burooq.com?

@Juraj yes I can connect to using websocket from my computer. for burooq.com it is my server domain

is 'your' computer other computer then the server computer?

This is the problem:

mosquitto 10436       mosquitto    4u  IPv4   46043      0t0  TCP
127.0.0.1:1883 (LISTEN)

Your MQTT server is listening only on port 127.0.0.1.  That will accept local incoming connections only but nothing from another IP address.
The IP 127.0.0.1 is the LOCAL ONLY IP address.  You need to reconfigure your MQTT server to listen on either IP 0.0.0.0 or whatever that server's actual IP address is.
Check your mosquitto.conf file and look for the line that begins with "bind_address":
listener 1883 localhost

change this to:
listener 1883 0.0.0.0

and restart your MQTT server.


text:
Esp32 external interrupts sometime is missing
In short. ESP32, two water meters (hot and cold). Booth, hot and cold, some interrupts are missed. When i connect ESP32 to serial monitor and watch then all interrupts are detected (about 5-10 minutes). But if i leave to 5v power only, then some interrupts are missed (in one day it can be up to 50 or even more).
About water counter - one pulse per liter. Correct info about sensor is in PDF Original Operating Instructions.
Sensor connections. Brown wire to GND, white to PIN 32(hot),33(cold).
Board. Olimex ESP32-POE Rev C.

Powered via 5v Samsung phone charger (standard 5V charger without 9v)
WiFi enabled (For NTP and to see counter readings)
OTA enabled
WEB server running (plain html, ESPAsyncWebServer)
Bluetooth disabled
SD card attached (stores SQLite database only)
Uses  siara-cc/esp32_arduino_sqlite3_lib  library

Water usage in last month (May)

hot - 4777 liters (counted with sensor - 2675)
cold - 9289, with sensor - 5528

As we can see, difference is huge. Maybe ISR routine exec time is too long and some interrupts are skipped? I know that WiFi too uses interrupts... Is my interrupt code wrong? Water counter reading is stored in SQLite database when 10 liters are used. Thanks for anyone for your time in advance!
Here is image of water counter and sensor
Here is some code, related to interrupts (debug disabled).
struct WaterCounter
{
  const uint8_t PIN; // microcontroller pin...
  volatile uint32_t liters_total; // max 4294967295
  volatile uint16_t liters_in_session; // max 65535
  volatile uint32_t session_started; // unix timestamp
  volatile uint32_t session_last_pulse; // unix timestamp
  const char display_name[5];
  volatile unsigned long pulse_start;
  volatile unsigned long pulse_stop;
  volatile uint32_t isr_prev_time;
  volatile uint32_t liters_last_written;
  volatile uint32_t liters_used_today;
};
WaterCounter wc_hot =  { PIN_WC_HOT, 0, 0, 0, 0, "Hott", 0, 0, 0, 0, 0 };
WaterCounter wc_cold = {PIN_WC_COLD, 0, 0, 0, 0, "Cold", 0, 0, 0, 0, 0 };
void IRAM_ATTR handle_wc(WaterCounter *wc)
{
  uint32_t  t = micros();
  uint32_t dt = t - wc->isr_prev_time;
  if (dt<1500) return;
  wc->isr_prev_time = t;
  if (wc->pulse_start == 0)
  {
    wc->pulse_start = millis();
    #ifdef DEBUG_ISR
      //Serial.printf("Started %s pulse!\n", wc->display_name);
      ets_printf("Started %s pulse!\n", wc->display_name);
    #endif
  }else
  {
    wc->pulse_stop = millis();
    unsigned long pulsew = wc->pulse_stop - wc->pulse_start;
    wc->pulse_start = 0;
    if (pulsew > 40 && pulsew < 55)
    {
      wc->liters_total++;
      wc->liters_in_session++;
      wc->liters_used_today++;
      if (wc->session_started == 0)
      {
        wc->session_started = now;
      }
      wc->session_last_pulse = now;
    }
    #ifdef DEBUG_ISR
      //Serial.printf("%s: pulse_width: %ld\n", wc->display_name, pulsew);
      ets_printf("%s: pulse_width: %ld\n", wc->display_name, pulsew);
    #endif
  }
}
void IRAM_ATTR isr_wc_cold()
{
  handle_wc(&wc_cold);
}

void IRAM_ATTR isr_wc_hot()
{
  handle_wc(&wc_hot);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Boot...");

  // allow some time to pull up pin, interrupt is attached below
  pinMode(wc_cold.PIN, INPUT_PULLUP);
  pinMode(wc_hot.PIN, INPUT_PULLUP);

  Serial.printf("Watchdog timeout: %dms\n", WATCHDOG_TIMEOUT);
  timerWD = timerBegin(0, 80, true);                  //timer 0, div 80
  timerAttachInterrupt(timerWD, &resetModule, true);  //attach callback
  timerAlarmWrite(timerWD, WATCHDOG_TIMEOUT * 1000, false); //set time in us
  timerAlarmEnable(timerWD); //enable interrupt
  timerWrite(timerWD, 0); //reset timer (feed watchdog)

  SD_MMC.begin();

  enqRC = sqlite3_initialize();
  if (enqRC == SQLITE_OK)
  {
    openDb();
    initSensorDatabase();
    timerWrite(timerWD, 0); //reset timer (feed watchdog)
    SetupWiFi();
    closeDb();
  }
  timerWrite(timerWD, 0); //reset timer (feed watchdog)
  pollNtp();
  timerWrite(timerWD, 0); //reset timer (feed watchdog)

  openDb();
  initTotalValues(&wc_cold);
  timerWrite(timerWD, 0); //reset timer (feed watchdog)
  initTotalValues(&wc_hot);
  closeDb();
  timerWrite(timerWD, 0); //reset timer (feed watchdog)

  attachInterrupt(digitalPinToInterrupt(wc_cold.PIN), &isr_wc_cold, FALLING);
  attachInterrupt(digitalPinToInterrupt(wc_hot.PIN), &isr_wc_hot, FALLING);

  timer_session = timerBegin(1, 80, true);
  timerAttachInterrupt(timer_session, &onSessionTimer, true);
  timerAlarmWrite(timer_session, 1000000, true); // every 1 second
  timerAlarmEnable(timer_session);

  EnableOTA();

  //* async web
  webServer.on("/", HTTP_GET, handleRootAsync);
  webServer.on("/heap", HTTP_GET, heapInfoAsync);
  webServer.on("/post", HTTP_POST, handlePostAsync);
  webServer.on("/params", HTTP_GET, handleParameterPage);
  webServer.onNotFound(onNotFoundAsync);
  webServer.begin();

  time(&now);
}

void loop() {
  // put your main code here, to run repeatedly:
  loop_task();
}
void loop_task()
{
  if (time_every_second <= now)
  {
    writeWcTotalToDb(&wc_cold);
    writeWcTotalToDb(&wc_hot);
    time_every_second = now + 1;
  }

  if (time_every_30_seconds <= now)
  {
    pollNtp();
    time_every_30_seconds = now + 30;
  }
}
void IRAM_ATTR finishSession(WaterCounter *wc, time_t tt)
{
  if (wc->session_started == 0)
  {
    return;
  }
  if (tt - wc->session_last_pulse > SESSION_LENGHT)
  {
    //finish session
    #ifdef DEBUG_ISR
      //Serial.printf("# %s liters in session: %d, duration %d(s)\n", wc->display_name, wc->liters_in_session, wc->session_last_pulse - wc->session_started);
      ets_printf("# %s liters in session: %d, duration %d(s)\n", wc->display_name, wc->liters_in_session, wc->session_last_pulse - wc->session_started);
    #endif

    wc->session_started = 0;
    wc->liters_in_session = 0;
  }
}

/* every 1s  */
void IRAM_ATTR onSessionTimer()
{
  timerWrite(timerWD, 0); //reset timer (feed watchdog)
  //ets_printf("\nonSessionTimer()\n");
  time(&now);
  getLocalTime(&timeinfo);
  strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
  if (now % 86400 == 75600) /* works if this function is called every second */
  {
    ets_printf("\n!!!midnight!!\n");
    wc_cold.liters_used_today = 0;
    wc_hot.liters_used_today = 0;
  }
  finishSession(&wc_cold, now);
  finishSession(&wc_hot, now);
}
void writeWcTotalToDb(WaterCounter *wc)
{
  #ifdef DEBUG_WRITE
    Serial.printf("writeWcTotalToDb(%s): begin\n", wc->display_name);
  #endif

  uint8_t ldiff = wc->liters_total - wc->liters_last_written;
  if (ldiff == 0)
  {
    #ifdef DEBUG_WRITE
      Serial.println("writeWcTotalToDb(): diff zero");
    #endif
    return;
  }
  if (ldiff <= LITERS_BEFORE_WRITE && wc->session_started > 0)
  {
    #ifdef DEBUG_WRITE
      Serial.println("writeWcTotalToDb(): ldiff <= LITERS_BEFORE_WRITE && wc->session_started > 0");
    #endif
    return;
  }
  #ifdef DEBUG_WRITE
    Serial.println("writeWcTotalToDb(): start writting procedure!");
  #endif
  if (!openDb())
  {
    char *sql = "INSERT INTO `water_counter` VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
    sqliteResultCode = sqlite3_prepare_v2(sqliteDb, sql, strlen(sql), &sqliteRes, NULL);
    if (sqliteResultCode != SQLITE_OK)
    {
      #ifdef DEBUG
        Serial.printf("writeWcTotalToDb(): ERROR preparing sql: %d -> %s\n", sqliteResultCode, sqlite3_errmsg(sqliteDb));
      #endif
    }else
    {
      #ifdef DEBUG
        Serial.print("writeWcTotalToDb(): Prepare OK\n");
      #endif
      //getLocalTime(&timeinfo); // inside every 1 sec
      //strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
      sqlite3_bind_int(sqliteRes, 1, now); // datums
      sqlite3_bind_int(sqliteRes, 2, wc->liters_total);
      sqlite3_bind_text(sqliteRes, 3, timeStringBuff, strlen(timeStringBuff), SQLITE_STATIC);
      sqlite3_bind_text(sqliteRes, 4, wc->display_name, strlen(wc->display_name), SQLITE_STATIC);
      sqlite3_bind_int(sqliteRes, 5, 0);
      sqlite3_bind_int(sqliteRes, 6, wc->liters_in_session);
      sqlite3_bind_int(sqliteRes, 7, wc->session_started);
      sqlite3_bind_int(sqliteRes, 8, 0); /* currently not used */

      if (sqliteResultCode = sqlite3_step(sqliteRes) != SQLITE_DONE)
      {
          #ifdef DEBUG
            Serial.printf("writeWcTotalToDb(): ERROR executing stmt: %d -> %s\n", sqliteResultCode, sqlite3_errmsg(sqliteDb));
          #endif
      }else
      {
          #ifdef DEBUG
            Serial.print("writeWcTotalToDb(): data saved!\n");
          #endif
          wc->liters_last_written = wc->liters_total;
          sqlite3_clear_bindings(sqliteRes);
          sqliteResultCode = sqlite3_reset(sqliteRes);
          if (sqliteResultCode != SQLITE_OK)
          {
            #ifdef DEBUG
              Serial.printf("writeWcTotalToDb(): sqlite3_reset(res) result code = [%s] %s\n", sqliteResultCode, sqlite3_errmsg(sqliteDb));
            #endif
          }else
          {
            #ifdef DEBUG
              Serial.print("writeWcTotalToDb(): sqlite3_reset(res) OK\n");
            #endif
          }
          sqlite3_finalize(sqliteRes);
      }
    }
    closeDb();
  }else
  {
    #ifdef DEBUG
      Serial.println("writeWcTotalToDb(): Failed to open database!");
    #endif
  }
  #ifdef DEBUG_WRITE
    Serial.printf("writeWcTotalToDb(%s): finished!\n", wc->display_name);
  #endif
} /* writeWcTotalToDb() */

You should switch to using the "pulse counter" peripheral in the ESP32. Read more here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html

Trying it tomorrow

@Majenko: can that be used with Arduino?

a binary counter IC would make reliability easy, but if there's a built-in counter we can use, that's even better.

Yes. Arduino used the IDF to control the chip. You'd just be skipping the Arduino layer and calling the IDF directly.

I tried pcnt (with arduino). It works with one input pin, but until no i cannot get to work with two different inputs (for  each water meter). As i understood, i must start two pcnt instances..

Maybe someone knows how to get channel number in pcnt_isr_register handler?

As @Majenko suggested, i created solution with pulse counter.
Here is working code, based on espressif PCNT Example. Arduino studio, Olimex ESP32-POE board.
Each water meter uses separate pulse counter unit. Now I am testing this code and after several days i will accept answer if all works like i want :)
#include "freertos/queue.h"
#include "driver/pcnt.h"
#include "driver/periph_ctrl.h"
#include "driver/gpio.h"
#include "esp_attr.h"

#define PCNT_H_LIM_VAL      1
#define PCNT_L_LIM_VAL     -1
#define PCNT_THRESH1_VAL    0
#define PCNT_THRESH0_VAL   -0
#define PCNT_INPUT_SIG_WC_HOT   32 // hot water counter
#define PCNT_INPUT_SIG_WC_COLD  33 // cold water counter
/*
Cold meter uses PCNT_UNIT_1
hot meter uses PCNT_UNIT_0
*/
xQueueHandle pcnt_evt_queue;   // A queue to handle pulse counter events
pcnt_isr_handle_t user_isr_handle = NULL; //user's ISR service handle

/* A sample structure to pass events from the PCNT
 * interrupt handler to the main program.
 */
typedef struct {
    pcnt_unit_t unit;  // the PCNT unit that originated an interrupt
    uint32_t status; // information on the event type that caused the interrupt
} pcnt_evt_t;

/* Decode what PCNT's unit originated an interrupt
 * and pass this information together with the event type
 * the main program using a queue.
 */
static void IRAM_ATTR pcnt_example_intr_handler(void *arg)
{
    uint32_t intr_status = PCNT.int_st.val;
    int i;
    pcnt_evt_t evt;
    portBASE_TYPE HPTaskAwoken = pdFALSE;

    for (i = 0; i < PCNT_UNIT_MAX; i++) {
        if (intr_status & (BIT(i))) {
            evt.unit = (pcnt_unit_t)i;
            /* Save the PCNT event type that caused an interrupt
               to pass it to the main program */
            evt.status = PCNT.status_unit[i].val;
            PCNT.int_clr.val = BIT(i);
            xQueueSendFromISR(pcnt_evt_queue, &evt, &HPTaskAwoken);
            if (HPTaskAwoken == pdTRUE) {
                portYIELD_FROM_ISR();
            }
        }
    }
}

/* Initialize PCNT functions:
 *  - configure and initialize PCNT
 *  - set up the input filter
 *  - set up the counter events to watch
 */
static void pcnt_example_init()
{
    //Serial.printf("pcnt_example_init(%d, %d)\n", _unit, _pin);
    /* Prepare configuration for the PCNT unit */
    pcnt_config_t pcnt_config = {};
    pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_WC_HOT;
    pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED;
    pcnt_config.channel = PCNT_CHANNEL_0;
    pcnt_config.pos_mode = PCNT_COUNT_INC;
    pcnt_config.neg_mode = PCNT_COUNT_DIS;
    pcnt_config.lctrl_mode = PCNT_MODE_KEEP;//PCNT_MODE_REVERSE;
    pcnt_config.hctrl_mode = PCNT_MODE_KEEP;
    pcnt_config.counter_h_lim = PCNT_H_LIM_VAL;
    pcnt_config.counter_l_lim = PCNT_L_LIM_VAL;
    pcnt_config.unit = PCNT_UNIT_0;

    /* Initialize PCNT unit */
    ESP_ERROR_CHECK(pcnt_unit_config(&pcnt_config));

    /* cold water meter */
    pcnt_config.pulse_gpio_num = PCNT_INPUT_SIG_WC_COLD;
    pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED;
    pcnt_config.channel = PCNT_CHANNEL_0;
    pcnt_config.pos_mode = PCNT_COUNT_INC;
    pcnt_config.neg_mode = PCNT_COUNT_DIS;
    pcnt_config.lctrl_mode = PCNT_MODE_KEEP;//PCNT_MODE_REVERSE;
    pcnt_config.hctrl_mode = PCNT_MODE_KEEP;
    pcnt_config.counter_h_lim = PCNT_H_LIM_VAL;
    pcnt_config.counter_l_lim = PCNT_L_LIM_VAL;
    pcnt_config.unit = PCNT_UNIT_1;
    ESP_ERROR_CHECK(pcnt_unit_config(&pcnt_config));

    /* Configure and enable the input filter */
    ESP_ERROR_CHECK(pcnt_set_filter_value(PCNT_UNIT_0, 1000)); // filter_val is a 10-bit value, so the maximum filter_val should be limited to 1023.
    ESP_ERROR_CHECK(pcnt_filter_enable(PCNT_UNIT_0));

    /* Set threshold 0 and 1 values and enable events to watch */
    ESP_ERROR_CHECK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, PCNT_THRESH1_VAL));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1));
    ESP_ERROR_CHECK(pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_0, PCNT_THRESH0_VAL));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0));
    /* Enable events on zero, maximum and minimum limit values */
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_ZERO));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_L_LIM));

    /* Initialize PCNT's counter */
    ESP_ERROR_CHECK(pcnt_counter_pause(PCNT_UNIT_0));
    ESP_ERROR_CHECK(pcnt_counter_clear(PCNT_UNIT_0));

    /* Register ISR handler and enable interrupts for PCNT unit */
    ESP_ERROR_CHECK(pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, &user_isr_handle));
    ESP_ERROR_CHECK(pcnt_intr_enable(PCNT_UNIT_0));

    /* Everything is set up, now go to counting */
    ESP_ERROR_CHECK(pcnt_counter_resume(PCNT_UNIT_0));

    /* PCNT_UNIT_1 configuration  */
    /* Configure and enable the input filter */
    ESP_ERROR_CHECK(pcnt_set_filter_value(PCNT_UNIT_1, 1000)); // filter_val is a 10-bit value, so the maximum filter_val should be limited to 1023.
    ESP_ERROR_CHECK(pcnt_filter_enable(PCNT_UNIT_1));

    /* Set threshold 0 and 1 values and enable events to watch */
    ESP_ERROR_CHECK(pcnt_set_event_value(PCNT_UNIT_1, PCNT_EVT_THRES_1, PCNT_THRESH1_VAL));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_1, PCNT_EVT_THRES_1));
    ESP_ERROR_CHECK(pcnt_set_event_value(PCNT_UNIT_1, PCNT_EVT_THRES_0, PCNT_THRESH0_VAL));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_1, PCNT_EVT_THRES_0));
    /* Enable events on zero, maximum and minimum limit values */
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_1, PCNT_EVT_ZERO));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_1, PCNT_EVT_H_LIM));
    ESP_ERROR_CHECK(pcnt_event_enable(PCNT_UNIT_1, PCNT_EVT_L_LIM));

    /* Initialize PCNT's counter */
    ESP_ERROR_CHECK(pcnt_counter_pause(PCNT_UNIT_1));
    ESP_ERROR_CHECK(pcnt_counter_clear(PCNT_UNIT_1));

    ESP_ERROR_CHECK(pcnt_intr_enable(PCNT_UNIT_1));

    /* Everything is set up, now go to counting */
    ESP_ERROR_CHECK(pcnt_counter_resume(PCNT_UNIT_1));
}

void setup() {
  Serial.begin(115200);
  Serial.println("Boot...");
  // put your setup code here, to run once:
  pinMode(PCNT_INPUT_SIG_WC_HOT, INPUT_PULLUP);
  pinMode(PCNT_INPUT_SIG_WC_COLD, INPUT_PULLUP);
  /* Initialize PCNT event queue and PCNT functions */
  pcnt_evt_queue = xQueueCreate(10, sizeof(pcnt_evt_t));

  pcnt_example_init();
  //  pcnt_example_init(PCNT_UNIT_WC_HOT, PCNT_INPUT_SIG_WC_HOT);
    //pcnt_example_init(PCNT_UNIT_WC_COLD, PCNT_INPUT_SIG_WC_COLD);

    Serial.printf("Setup done\n");
}

int16_t count = 0;
pcnt_evt_t evt;
portBASE_TYPE res;

char * chToName(int ch)
{
  if (ch == 1) return "Cold";
  if (ch == 0) return "Hot";

  return "Unc";
}

void loop() {
  // put your main code here, to run repeatedly:
      /* Wait for the event information passed from PCNT's interrupt handler.
         * Once received, decode the event type and print it on the serial monitor.
         */
        res = xQueueReceive(pcnt_evt_queue, &evt, 1000 / portTICK_PERIOD_MS);
        if (res == pdTRUE) {
            pcnt_get_counter_value(evt.unit, &count);
            Serial.printf("Event PCNT unit[%d=%s]; cnt: %d, status: %d\n", evt.unit, chToName(evt.unit), count, evt.status);
            if (evt.status & PCNT_EVT_THRES_1) {
                Serial.printf("THRES1 EVT\n");
            }
            if (evt.status & PCNT_EVT_THRES_0) {
                Serial.printf("THRES0 EVT\n");
            }
            if (evt.status & PCNT_EVT_L_LIM) {
                Serial.printf("L_LIM EVT\n");
            }
            if (evt.status & PCNT_EVT_H_LIM) {
                Serial.printf("H_LIM EVT\n");
            }
            if (evt.status & PCNT_EVT_ZERO) {
                Serial.printf("ZERO EVT\n");
                // here we are increment liter count
            }
        } else {
            pcnt_get_counter_value(PCNT_UNIT_0, &count);
            Serial.printf("Current counter value: %s=%d,", chToName(PCNT_UNIT_0), count);
            pcnt_get_counter_value(PCNT_UNIT_1, &count);
            Serial.printf(" %s=%d\n", chToName(PCNT_UNIT_1), count);
            //pcnt_get_counter_value(PCNT_UNIT_WC_COLD, &count);
            //Serial.printf(", %d on unit: %d\n", count, PCNT_UNIT_WC_COLD);
        }

        /*
        if(user_isr_handle) {
          Serial.printf("Clearing user_isr_handle\n");
          //Free the ISR service handle.
          esp_intr_free(user_isr_handle);
          user_isr_handle = NULL;
        }*/
}

You can use Pulse Counter(PCNT) feature in ESP32 to count the number of pulse in background, Its also possible to configure event when number of counts reached certain threshold and had lot of options,
For get information and available Interfaces and API's for Pulse Counter(PCNT) please follow below link, https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html

Initially I faced lot of issue to make Pulse Counter(PCNT) work in Adrino IDE for ESP-32, After multiple attempt I make it working, And same  sample code is uploaded in GitHub for reference. I have not use all the API's in the official documentation but but used few of them and are working..

I have created a simple sample program for a water flow meter, there also we use to get pulse which needs to count to measure the water flow rate.
GitHub Sample code Path:- https://github.com/Embedded-Linux-Developement/Arduino_Sample_Programs/tree/main/ESP_32/Water_Flow_Pulse_counter_WithOut_Interrupt_Using_PCNT
I have not placing the code here, because its there in GitHub and a simile one and can use it. Its a working code I tested in ESP32 HW.
Hopes Its helpful,
Regards, Jerry James


text:
Am not able to call C++ function pointers from inline assembly
Due to some curiosity, I was trying to use some assembly with my Arduino MEGA 2560.
I am not able to invoke a function from a c++ function pointer array.
When I uncomment the call function, func_a runs. However, when I almost reproduce the assembly, it doesnt work.
Example:
extern "C" void __attribute__ ((used, noinline, noreturn)) func_a();

typedef void (*volatile func_ptr)();

func_ptr tasks[MAX_TASKS] = {&func_a};

extern "C"
void __attribute__ ((used, noinline)) call(func_ptr *ptr) {
    (*ptr)();
}

void __attribute__ ((noreturn, used)) setup() {

    // call(tasks);

    asm volatile (
    "lds r26, (tasks)\n"
    "lds r27, (tasks + 1)\n"

    "ld r30, X+\n"
    "ld r31, X\n"

    "eijmp\n"
    );
}

Generated assembly recovered from avr-objdump
000001c6 <setup>:
 1c6:   a0 91 00 02     lds r26, 0x0200 ; 0x800200 <tasks>
 1ca:   b0 91 01 02     lds r27, 0x0201 ; 0x800201 <tasks+0x1>
 1ce:   ed 91           ld  r30, X+
 1d0:   fc 91           ld  r31, X
 1d2:   19 94           eijmp
 1d4:   08 95           ret

000001d6 <call>:
 1d6:   dc 01           movw    r26, r24
 1d8:   ed 91           ld  r30, X+
 1da:   fc 91           ld  r31, X
 1dc:   19 94           eijmp

An specific resources I should refer for things like this?
If it matters, I'm using platformio on a linux system for compilation.

It seems you got confused by the pointer indirections, which is
confounded by the implicit indirections made by the compiler.
Here:
extern "C"
void __attribute__ ((used, noinline)) call(func_ptr *ptr) {
    (*ptr)();
}

The parameter ptr is not a function pointer: it's a pointer to a
function pointer. You have to dereference it twice in order to get the
function: (**ptr)();. Note that the compiler implicitly dereferences a
function pointer if you call it like a function: that's why you get no
error by explicitly dereferencing the pointer only once. In the
generated assembly, the lines
ld  r30, X+
ld  r31, X

dereference ptr in order to get the address of the function to call.
You probably wanted to write
extern "C"
void __attribute__ ((used, noinline)) call(func_ptr ptr) {
    ptr();
}

And then use it as:
call(tasks[0]);

If you just call(tasks), the array identifier decays to pointer, and
the compiler handles this as a shortcut for call(&tasks[0]);, which
turns out to be compatible with your initial implementation of call().
Now, in your inline assembly you have
lds r26, (tasks)
lds r27, (tasks + 1)

The assembly treats tasks as a symbol representing the address of
the tasks array. The linker replaces those symbols by the actual
address (0x0200). Those instructions read the RAM at this and the
following address. These slots of RAM hold the first item of the array,
namely &func_a. So now you have this address in the X register pair.
No need to read RAM again: you can movw r30, r26 and do the indirect
jump. Or, better yet, load into Z to begin with:
lds r30, (tasks)
lds r31, (tasks + 1)
eijmp

See also Majenko's answer: here I am assuming EIND is somehow
correctly set up to begin with. On an Uno, you would just use ijmp
instead of eijmp and not worry about EIND.

That kindof eplained things. When I used (tasks) in the asm, I expected it to load the address of the first element of the array and not the value pointed to by it. Im not sure how to do that. Maybe I will have to understand the extended asm syntax.

@darkspine: You can load the address of tasks with, e.g., ldi r26, lo8(tasks)\n ldi r27, hi8(tasks). Unlike lds, the ldi instruction does not access the RAM, as the address is known at build time and filled-in by the linker.

I will start off by saying that I am no expert in AVR assembly, so I have no idea if any of this is actually correct. However from reading the various documents on the subject I have gleaned:

On the ATMega2560 EIJMP uses a combination of both the Z register and the EIND register to form a full address.

That means that as well as setting up the Z register for the lower 16 bits of the address you also have to set up the EIND register for the upper 5 bits of the address.

Indirect jump to the address pointed to by the Z (16 bits) Pointer Register in the Register File and the EIND Register in the I/O space. This instruction allows for indirect jumps to the entire 4M (words) Program memory space.

It then goes on to show an example:
ldi r16,$05 ; Set up EIND and Z-pointer
out EIND,r16
ldi r30,$00
ldi r31,$10
eijmp ; Jump to $051000

How you determine what the EIND register should be? Well, in general you don't. You wouldn't use EIJMP. From what I understand for functions outside the lower 64kwords of address space the compiler builds a "jump table" which is stored in the lower area of memory. You jump to the entry in that table with IJMP and that table then jumps to the final destination with EIJMP for you.
Doing this kind of jumping in assembly isn't really a nice thing to try and figure out. It's messy. Better to let the compiler do it for you and use C rather than assembly.  The AVR-GCC guys put a lot of work into making function pointers work correctly (from what I have read it wasn't easy even for them), and you're just re-inventing the wheel.
At the very least you should implement your code 100% in C to begin with then look at the compiled output to see how the compiler thinks it should be done.

I switched to eijmp because thats what gcc was using. The problem turned out to be that tasks is dereferenced when using it in the asm.
Also, thanks for the document, Its much more verbose than the ATMega2560 datasheet.


text:
Esp32: is OTA compatible with FREERTOS
Can I use OTA along with FreeRTOS tasks on ESP32. I ask this because in the following  example OTA seems to be enabled if FreeRTOS is disabled. Can for example upload firmware that runs on both cores over OTA?
Example taken from OTA template project by Andrea's Speiss

You can't not use FreeRTOS on the ESP32. The whole ESP-IDF is based around it.

yes, you can...

You can't not use FreeRTOS. The whole ESP-IDF is based around it. The Arduino setup() and loop() run in their own FreeRTOS thread.
If you "turn off" FreeRTOS then nothing will work.
Whatever that "template" is from it's of no use to you.

I was also believing that it is not possible but I handle it thanks to this post below;
https://github.com/SensorsIot/ESP32-OTA/issues/8
I applied what ever shared and it works like a charm together both FreeRTOS and OTA features.
As summary you need to create 2 custom header which includes your wifi credentials and OTA function. The remaining is same mostly.
credentials.h
#pragma once
const char* mySSID = "SSID of your AP";
const char* myPASSWORD = "Password of your AP";

OTA.h
#ifdef ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#endif

#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#if defined(ESP32_RTOS) && defined(ESP32)
void ota_handle( void * parameter ) {
  for (;;) {
    ArduinoOTA.handle();
    delay(3500);
  }
}
#endif

void setupOTA(const char* nameprefix, const char* ssid, const char* password) {
  // Configure the hostname
  uint16_t maxlen = strlen(nameprefix) + 7;
  char *fullhostname = new char[maxlen];
  uint8_t mac[6];
  WiFi.macAddress(mac);
  snprintf(fullhostname, maxlen, "%s-%02x%02x%02x", nameprefix, mac[3], mac[4], mac[5]);
  ArduinoOTA.setHostname(fullhostname);
  delete[] fullhostname;

  // Configure and start the WiFi station
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  // Wait for connection
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Port defaults to 3232
  // ArduinoOTA.setPort(3232);

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });

  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });

  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });

  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("\nAuth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("\nBegin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("\nConnect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("\nReceive Failed");
    else if (error == OTA_END_ERROR) Serial.println("\nEnd Failed");
  });

  ArduinoOTA.begin();

  Serial.println("OTA Initialized");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

#if defined(ESP32_RTOS) && defined(ESP32)
  xTaskCreate(
    ota_handle,          /* Task function. */
    "OTA_HANDLE",        /* String with name of task. */
    10000,            /* Stack size in bytes. */
    NULL,             /* Parameter passed as input of the task */
    1,                /* Priority of the task. */
    NULL);            /* Task handle. */
#endif
}

OTA Template sketch.ino
#define ESP32_RTOS  // Uncomment this line if you want to use the code with freertos only on the ESP32
                    // Has to be done before including "OTA.h"

#include "OTA.h"
#include "credentials.h"

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");

  setupOTA("TemplateSketch", mySSID, myPASSWORD);

  // Your setup code
  /*  Example
  pinMode(2, OUTPUT);
  */
}

void loop() {
#ifdef defined(ESP32_RTOS) && defined(ESP32)
#else
  ArduinoOTA.handle();
#endif

  // Your code here
  /* Example
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(1000);
  */
}


text:
How can I start freshly? Libraries mess Wemos D1 Mini
I am using a wemosd1 MINI which has a ESP8266 module. I am using it for an IoT project, however a lot has been going wrong.  With libraries and version types. I want to start over but noticed that simply reinstalling arduino didnt do tha trick. How can i restart?

Windows, Linux or Mac?

Delete your IDE's data folder and libraries folder.

I don't understand, what your problem is. If you have a big mess of libraries, you can just delete the libraries from the libraries folder

Windows! Deleting the libraries causes conflicts in my program i feel like i deleted some curical ones as well.

Of course if you delete the libraries you won't be able to compile your program. It's after deleting that you need to the install the right versions of the right libraries.


text:
Error compile board LOLIN(WEMOS) D1 R2 & mini
I have a wemos d1 mini and a mpu 6060 sensor. I am trying to send the data from the sensor to Firebase. However i have come across a hurdle which i cant seem to solve. This is my error, can you help me out with this issue?
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
In file included from C:\Users\Zakaria\Documents\Arduino\libraries\firebase-arduino-master\src/Firebase.h:30:0,

                 from C:\Users\Zakaria\Desktop\WORKING_ACCELERAMETOR_BACKUP\WORKING_ACCELERAMETOR_BACKUP.ino:4:

C:\Users\Zakaria\Documents\Arduino\libraries\firebase-arduino-master\src/FirebaseObject.h:109:11: error: StaticJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6

     std::shared_ptr<StaticJsonBuffer<FIREBASE_JSONBUFFER_SIZE>> buffer_;

           ^

In file included from C:\Users\Zakaria\Desktop\WORKING_ACCELERAMETOR_BACKUP\WORKING_ACCELERAMETOR_BACKUP.ino:4:0:

C:\Users\Zakaria\Documents\Arduino\libraries\firebase-arduino-master\src/Firebase.h:86:11: error: StaticJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6

   std::shared_ptr<StaticJsonBuffer<FIREBASE_JSONBUFFER_SIZE>> buffer_;

           ^

Using library FirebaseJson at version 2.3.3 in folder: C:\Users\Zakaria\Documents\Arduino\libraries\FirebaseJson
Using library firebase-arduino-master at version 0.1 in folder: C:\Users\Zakaria\Documents\Arduino\libraries\firebase-arduino-master
Using library ArduinoJson at version 6.15.0 in folder: C:\Users\Zakaria\Documents\Arduino\libraries\ArduinoJson
Using library ESP8266HTTPClient at version 1.2 in folder: C:\Users\Zakaria\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266HTTPClient
Using library ESP8266WiFi at version 1.0 in folder: C:\Users\Zakaria\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266WiFi
Using library Wire at version 1.0 in folder: C:\Users\Zakaria\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\Wire
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.

it says: "error: StaticJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6". so install ArduinoJson 5.x or do the upgrade steps


text:
acelermetor count goes down after 1 peak
I am using a Wemos D1 Mini and an mpu 6050 accelerametor. I managed to get the acceleratmetor to work and have 1 value come out of movements. So when a peak it hit (aka, the threshold of 1.00 is hit) n gets incremetented with 1. So it work a bit like a pedometer. This value is pushed to my firebase DB.
However mY problem is that after pushing it once, so the value of n is 1. The program blocks for a second and either slows down bad or the accelerametor value drops to 0. this only happens when i my piece of firebase code in. Im not sure if this causes any delays..
here is my part of my code:
#include <Wire.h>

#include "ESP8266WiFi.h"
#include "FirebaseArduino.h"

#define FIREBASE_HOST "xxxxxxxxxx.firebaseio.com" //Without http:// or https:// schemes
#define FIREBASE_AUTH "XXXXXXXXXXXXXXXXXXXXX"
#define WIFI_SSID "Bankai"
#define WIFI_PASSWORD "xxxxxxxxxxxx"

const float HI_THRESHOLD = 1.00;
const float LO_THRESHOLD = 0.70;
bool count_flag = false;

int n= 0; //will be used to store the count
int oldValue = n;
String myString;

const uint8_t MPU_addr = 0x68; // I2C address of the MPU-6050

const float MPU_GYRO_250_SCALE = 131.0;
const float MPU_GYRO_500_SCALE = 65.5;
const float MPU_GYRO_1000_SCALE = 32.8;
const float MPU_GYRO_2000_SCALE = 16.4;
const float MPU_ACCL_2_SCALE = 16384.0;
const float MPU_ACCL_4_SCALE = 8192.0;
const float MPU_ACCL_8_SCALE = 4096.0;
const float MPU_ACCL_16_SCALE = 2048.0;

struct rawdata {
  int16_t AcX; //Acceleration
  int16_t AcY; //Acceleration
  int16_t AcZ; //Acceleration
  int16_t Tmp;
  int16_t GyX; //Gyroscope
  int16_t GyY; //Gyroscope
  int16_t GyZ; //Gyroscope
};

// Using int variables to convert later on to degrees and decimals
struct scaleddata {
  float AcX; //Acceleration
  float AcY; //Acceleration
  float AcZ; //Acceleration
  float Tmp;
  float GyX; //Gyroscope
  float GyY; //Gyroscope
  float GyZ; //Gyroscope
};

bool checkI2c(byte addr);
void mpu6050Begin(byte addr);
rawdata mpu6050Read(byte addr, bool Debug);
void setMPU6050scales(byte addr, uint8_t Gyro, uint8_t Accl);
void getMPU6050scales(byte addr, uint8_t &Gyro, uint8_t &Accl);
scaleddata convertRawToScaled(byte addr, rawdata data_in, bool Debug);

//start connection, serial, and connection to db
void setup() {
  Wire.begin();
  Serial.begin(115200);

  mpu6050Begin(MPU_addr);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

}

//if the value now is different from the current value it gets pushed to the DB, otherwise a flood of numbers apperars.
void loop() {
  rawdata next_sample;
  setMPU6050scales(MPU_addr, 0b00000000, 0b00010000);
  next_sample = mpu6050Read(MPU_addr, false);
  convertRawToScaled(MPU_addr, next_sample, false);

I feel likeit is thei part which creates the bottleneck.
  //myString = String(n);
  if(oldValue != n){
   Firebase.setInt("Reps/Value", n);
  }
  delay(100); // Wait 5 seconds and scan again

}

 float filterConstant = 0.05;
  values.AcX = (float) data_in.AcX / scale_value;
  values.AcY = (float) data_in.AcY / scale_value;
  values.AcZ = (float) data_in.AcZ / scale_value;
  filteredAx = filteredAx * (1.0 - filterConstant) + values.AcX * filterConstant;
  filteredAy = filteredAy * (1.0 - filterConstant) + values.AcY * filterConstant;
  filteredAz = filteredAz * (1.0 - filterConstant) + values.AcZ * filterConstant;
  float result = sqrt((filteredAx * filteredAx) + (filteredAy * filteredAy ) + (filteredAz * filteredAx ));

//  Serial.print(values.AcX); Serial.print("\t");
//  Serial.print(filteredAx); Serial.print("\t");

  Serial.println(result);

  //    Serial.print(values.AcY); Serial.print("\t");
  //    Serial.print(values.AcZ);
//  Serial.println();

 if( result > HI_THRESHOLD && !count_flag) //if analog_in > Hi_THRESHOLD and count_flag == false
     {
           n++;
           count_flag = true;
     }

     if(result <= HI_THRESHOLD) //set count_flag to false only when below the threshold
           count_flag = false;

  Serial.println(n);

  return values;
}

Can you help me find the problem? Thank you!

Logging the data is indeed what slows your program down.  You can't avoid that.  There are several ways to deal with it depending on what you need.
Instead of logging data all the time, you could try to accumulate a bunch of data and then write it.  This approach of buffering data will still fail to read while you log, but you will be able to get bursts of good data in between.


text:
SIM900A network connection
I can't connect to the network.
Hardware used: Arduino UNO and SIM900A GSM module
Tutorial used: https://www.instructables.com/id/GSM-SIM900A-With-Arduino/
Sim card used: Orange (I set it on 2G frequency and disabled pin code)
I am from Romania.
Based on the tutorial above, once the connection is established successfully, the status/network LED on the SIM900A will blink continuously every 3 seconds. This does not happen to me, so it is a problem from the start. It keeps on searching for a network to connect.
Would you mind helping me, please?
Thank you so much!

any update on this topic? i have the same problem.
I am from Romania too, and i tried with orange and vodafone ass well


text:
How to stop motor after a desired time?
I am trying to stop a dc motor after a desired amount of time !! And the motor starts upon settling on a condition !! From that very moment i want my motor to just run for 5 seconds and stop!! Below is the pseudocode:
 #define max 150
 #define min -150
 #define pin1 3
 void setup()
    {
        Serial.begin(9600);
         mpu.initialise();
     }
   void loop()
     {
        x= some_accelerometer_values;
         If (x>250)
            {
                analogWrite(pin1,255);
                delay(5000);
                exit(0);
             }
      }

I tried using millis() but it starts time with execution of program and i can't get to implement it just before the motor starts running!

Don't use exit(0) on a microcontroller. There is no OS to take charge after the end of the program. Better use an infinite loop, if you want to end the program and do nothing more

Have you understood the BlinkWithoutDelay example, that comes with the Arduino IDE? I explains the use of millis() rather good. You take a timestamp (value of millis()), when the start condition arises, and then you calculate the difference between the current millis() value and the timestamp and compare it to the 5s (5000ms).

Thumbs up for the exit(0); information !! I didin't knew that, nor it was working with it !! But the millis(); is troublesome !! Its counting time since the program started !! And not since the motor started !!

@HrithikBaishakhiya You can use a variable to save the time when the motor started. Then always check the difference between now, and when the motor has started. And if the difference is >= then 5 seconds, it turns off

But the millis(); is troublesome !! Its counting time since the program started !! And not since the motor started !! ..... how do you boil  an egg for 3 minutes by using a clock, without using a timer?

Assuming you turn your motor on with analogWrite(pin1, 255); just write analogWrite(pin1, 0); after the delay(5000);.
And using exit(0); isn't as bad as people will most likely say. Using exit(0) is the same as cli(); + while(1). So it disables interrupts and stucks your code in a while loop till your reset the arduino.

But if x remains greater than 250 for a while then it will run until x < 250!!

@HrithikBaishakhiya since you used exit(0); you want your code to only run once. And if you write analogWrite(pin1, 0); before the exit(0) your motor will turn off. Then the program will stop and not ask about whether x is greater than 250 or not.

@HrithikBaishakhiya if() is triggered by a condition, and will only be executed once per loop()

I respect your effort !! But its not recommended to use exit(0); as written in some contexts and suggest by chrisl above!! I am little confused here !!

@HrithikBaishakhiya as of I know, exit(0); disables interrupts and throws the arduino into a while(1) loop. I just tried it on my arduino-uno. It's pretty much a loop() but with disabling interrupts.