text:
How to use Multipile millis()
I've a exhaust fan that runs when the humidity is high. When the exhaust fan is on it should work for 3 minutes and should wait another 5 minutes to on. I am a beginner to this struggling for almost 2 days now. with this code the led just blink and off
int ledPin =  2;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis2 = 0;
unsigned long previousMillis = 0;
long interval = 10000;           // in
long OnTime = 1000;           // milliseconds of on-time
long OffTime = 2000;          // milliseconds of off-time

void setup()
{

  Serial.begin(9600);
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop()
{

  unsigned long currentMillis2 = millis();

  if (currentMillis2 - previousMillis2 > interval) {
    // save the last time you blinked the LED

    // check to see if it's time to change the state of the LED
    Serial.print("hellohh ");
    unsigned long currentMillis = millis();

    if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      Serial.print("hellohh2 ");
      ledState = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(ledPin, ledState);  // Update the actual LED
    }
    else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      Serial.print("hellohh 3");
      ledState = HIGH;  // turn it on
      previousMillis = currentMillis;
      previousMillis2 = 0; // Remember the time
      digitalWrite(ledPin, ledState);    // Update the actual LED

    }
  }
}

what problem are you struggling with? ... what is your question?

@jsotola 1st checking and 3nd checking only working

In your serial monitor, what is printed? hellohh / hellohh2 / hellohh 3? Can you edit your question and copy/paste some of the output so we can see what logic branches are being followed.

You said 3 minutes and 5 minutes in your question, but I don't see any reference to that in the code (3 minutes would be 3 * 60 * 1000 milliseconds = 180000).

@NickGammon  now just trying with some leds,

@NickGammon one exhaust fan when the humidly is high for 3 minutes, if the humidity still high fan will on again i need 5 minutes gap between the next fan on thats what i meant

Your first test of if (currentMillis2 - previousMillis2 > interval) { is for a longer interval than 1000/2000 so I expect weird behaviour. You haven't said what is actually happening. Saying a "checking is working" is a bit non-specific. What is being printed? Does the LED light?

now ledblink and off @NickGammon

This isn't a forum. Please edit your question and supply extra information, like what the serial output is, and what is actually happening. Comments are not for debugging the problem.

okay @NickGammon new to things, no idea how to do things sorry

I realise that you are new, and I have suggested that you do certain things, which you haven't done as I write this. I recommend that you follow my earlier suggestions about documenting your issue better, and then we may be able to help you better.

Also the question and comments (multiple fans for 3 / 5 minutes) and your code (1 second on / 2 second off LED) don't seem to match at all.

@towe just testing but it stuck

If I understand correctly, you wrote an example code that switches an
LED between two states (on and off), and you are stuck because the
actual problem you want to solve is more complex than that. And indeed,
it seems to me that you want to manage a system with three possible
states: it can be on or off but, when it is off, it can be ready to turn
on if the humidity is high, or it can be in the five minute wait.
The most natural way to think about this kind of systems is a finite
state machine, or FSM. An FSM is defined by the set of states it
can be in, the conditions that make it switch states, and the actions
performed when doing so. If I correctly understood your specification,
your system can be either READY, RUNNING or WAITING, and the transitions
are:

when READY, if the humidity is too high it switches to RUNNING; it
turns the fan on when doing so
when RUNNING, if it has been running for 3 minutes, it switches
to WAITING and turns the fan off
when WAITING, if it has been waiting for 5 minutes, it switches
to READY

This can be illustrated by the following state diagram:

You should correct me at this stage if I did not fully understand your
specification. Otherwise, if the state diagram matches your
requirements, converting it to code is quite straightforward:
const uint32_t MINUTE = 60000;

void loop() {
    static enum {READY, RUNNING, WAITING} state;
    static uint32_t last_change;
    uint32_t now = millis();
    switch (state) {
        case READY:
            if (humidity_is_high()) {
                turn_fan_on();
                state = RUNNING;
                last_change = now;
            }
            break;
        case RUNNING:
            if (now - last_change >= 3 * MINUTE) {
                turn_fan_off();
                state = WAITING;
                last_change = now;
            }
            break;
        case WAITING:
            if (now - last_change >= 5 * MINUTE) {
                state = READY;
            }
            break;
    }
}

I dont know how to thank you , it work like charm

Thanks for understanding my goal :)

For your current issue (turning LEDs on and off after 1s / 2s, much of your code can be simplified:
int ledPin =  2;     // Number of the LED pin
int ledState = LOW;  // ledState used to set the LED
unsigned long TimeLedOFF = 0;     //Time at which the LED was last turned off
unsigned long TimeLedON = 0;      //Time at which the LED was last turned on
unsigned long TimeLastCheck = 0;  //Time at which the next LED state was determined last
long interval = 100;  // How often to check for changes in environment - should be shorter than your switching durations
long OnTime = 1000;   // Milliseconds of on-time
long OffTime = 2000;  // Milliseconds of off-time

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); // set the LED pin as output:
}

void loop() {
  if (millis() - TimeLastCheck > interval) { //If the LED state should be evaluated again - "interval" has passed
    TimeLastCheck = millis();

    Serial.println("Determining next LED state");

    if (ledState == HIGH && (millis() - TimeLedON >= OnTime)) { //If LED was on for long enough
      Serial.println("OnTime elapsed. Turning off.");
      TimeLedOFF = millis(); // Remember the time
      ledState = LOW;        // Turn LED flag off
      digitalWrite(ledPin, ledState); // Update the actual LED
    }
    else if (ledState == LOW && (millis() - TimeLedOFF >= OffTime)) { //If LED was off for long enough
      Serial.println("OffTime elapsed. Turning on.");
      TimeLedON = millis(); // Remember the time
      ledState = HIGH;  // turn it on
      digitalWrite(ledPin, ledState);    // Update the actual LED
    }
  }
}

This results in the LED being turned on for one second, then off for two seconds.

Thanks , when i change the interval time to 20000
OnTime long OffTime change automatically to 20000 @towe

Yes, since you only ever check whether something should happen once per "interval time". By then, the other two durations have long since passed.
What do you need / want interval time for exactly?

Yes , i want the interval time exactly, i don't know how to check :(

my humidity sensor keep checking the temp and hum , i dont want to keep my fan working all time, so i need a interval time 5m if needed

That's not what the "interval time" does in your (or my) sketch - the fan is turned off once OnTime has passed.

Yes, i checked. How can i achieve that ? can you show me an example?

Just to clarify I understand you correctly:
You read the humidity level. If it's too high, you want the fan to run for at most three minutes. Then, it must wait for five minutes, until it checks the humidity again and decides whether or not to turn the fan back on (for three minutes)?

Yes, right.  if(humidity < 50){
fogger();}

else if (humidity > 70){
  digitalWrite(DHTpower, LOW); // exhuast fan on here

}else if ((temp > 32) && (hum < 55))

{
fogger();
}

sensor will keep  checking the humidity once the fan on for 3 minutes , must need 5 minutes gap to on again for 3 minutes

So it'll constantly check humidity, and turn on the fan if your level surpasses 70? What does the fogger() function do?

fogger is actually pump it on when the humidity is below 50

thanks towe for your time and effort , i got the  code. Thanks for your help


text:
How to stringtok this long string?
I have a string,
"id,port,password,ssid,delay,flag,class,category"
Please tell me how can stringtok this and find out the "flag" value(0 or 1)?
Here is what I tried:
void setup()
{
    char input[] = {"id,port,password,ssid,delay,flag,class,category"};
    char *ptr;
    Serial.begin(115200);
    ptr = strtok(input, ",");
    Serial.println(ptr);
    while (ptr != NULL) {
        ptr = strtok(NULL, ",");
        Serial.println(ptr);
    }
}

void loop(){}

I would remove the { and } in char input[] = {"id,port,password,ssid,delay,flag"};

Even with the (useless) braces Juraj suggest removing, your code works as expected. Please, be more specific about what your actual problem is.

how 'flag' substring separately taken ? what modification that i want to made in program?

based on position? 6th item?

For strings with a fixed format like that (I assume it's a fixed format...) I normally just do a manual strtok of the whole thing into a set of pointers. No need for a loop.  You can then just test the last one to see if the whole thing tokenised properly, since if anything before that fails then all other subsequent ones will fail and the last one will have failed.
void setup()
{
    char input[] = {"id,port,password,ssid,delay,flag,class,category"};
    char *ptr;
    Serial.begin(115200);

    char *id = strtok(input, ",");
    char *port = strtok(NULL, ",");
    char *password = strtok(NULL, ",");
    char *ssid = strtok(NULL, ",");
    char *delay = strtok(NULL, ",");
    char *flag = strtok(NULL, ",");
    char *class = strtok(NULL, ",");
    char *category = strtok(NULL, ",");
    if (category != NULL) { // Everything up to and including category worked
        Serial.print("Flag: ");
        Serial.println(flag);
    }
}

void loop(){}

As an aside: if there is ever a chance any of the fields could be empty ("flag,,category" for example) then you should use strsep() instead of strtok() as I detail in my tutorial on splitting strings in C.

source: Stack Exchange

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

sort: votes


text:
Is it support to use Infrared radiation module in ESP12E?

I have a IR module -->image as shown
is it possible to use the IR module in esp8266?
how to do(sent and receive)?
what is the packet format of IR module?
please explain.
Thanks

is it possible to use the IR module in esp8266?

Yes.

how to do(sent and recive)?

You send by pressing a button on your remote control. You receive by measuring the timing of the changes in the pin state.

what is the packet format of IR module?

Whatever packet format your remote control sends.
It's no different using IR on an ESP8266 compared to an Arduino. There's a library that everyone uses (IRRemote.h), and there are plenty of examples and tutorials on the web (or on YouTube if you can't be bothered to read). I suggest you ask Google for some.

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


text:
NodeMCU display temperature and control LED from an autorefresh web page
I'm totaly new to Arduino, I'm using ESP2866 NodeMCU and dht22 to display temperature and humidity in a web page, it is autorefresh (using AJAX) and it works perfectly, I wanted to add 2 buttons to it so I can control 2 Leds but when I tried that I couldn't control them and even the values of temperature and humidity stopped refreshing. Can you tell me what is wrong in the code ? here it is :
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHT.h"
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

 /*Put your SSID & Password*/
 const char* ssid = "xxx";  // Enter SSID here
 const char* password = "xxx";  //Enter Password here

  ESP8266WebServer server(80);

 // DHT Sensor
 uint8_t DHTPin = D6;

  // Initialize DHT sensor.
  DHT dht(DHTPin, DHTTYPE);

  float Temperature;
  float Humidity;
  float reading;
  float percentage;
  // Auxiliar variables to store the current output state
  String output5State = "off";
  String output4State = "off";

 // Assign output variables to GPIO pins
 const int output5 = 5;
 const int output4 = 4;
 void setup() {
 Serial.begin(115200);
 delay(100);

 pinMode(DHTPin, INPUT);
 dht.begin();

// Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
 pinMode(output4, OUTPUT);
 // Set outputs to LOW
 digitalWrite(output5, LOW);
 digitalWrite(output4, LOW);
 Serial.println("Connecting to ");
 Serial.println(ssid);

//connect to your local wi-fi network
WiFi.begin(ssid, password);

//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);

server.begin();
Serial.println("HTTP server started");

}
void loop() {

server.handleClient();
}

void handle_OnConnect() {

Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity

//Serial.println(reading);
String header=SendHTML( Temperature,Humidity,percentage);

server.send(200, "text/html",header);
// turns the GPIOs on and off
        if (header.indexOf("GET /5/on") >= 0) {
          Serial.println("GPIO 5 on");
          output5State = "on";
          digitalWrite(output5, HIGH);
        } else if (header.indexOf("GET /5/off") >= 0) {
          Serial.println("GPIO 5 off");
          output5State = "off";
          digitalWrite(output5, LOW);
        } else if (header.indexOf("GET /4/on") >= 0) {
          Serial.println("GPIO 4 on");
          output4State = "on";
          digitalWrite(output4, HIGH);
        } else if (header.indexOf("GET /4/off") >= 0) {
          Serial.println("GPIO 4 off");
          output4State = "off";
          digitalWrite(output4, LOW);
        }

      }

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

   String SendHTML(float TempCstat,float Humiditystat, float  percentage){
    String ptr = "<!DOCTYPE html> \n";
    ptr +="<meta name=\"viewport\" content=\"width=device-width,
    initial-scale=1.0, user-scalable=no\">\n";
    // ptr +="<meta http-equiv=\"refresh\" content=\"2\" >\n";
   ptr +="<link href=\"https://fonts.googleapis.com/css?
    family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
    ptr +="<title>ESP8266 Weather Report</title>\n";
    ptr +="\n";
     ptr +="\n";

     ptr +="\n";
     ptr +="\n";

     ptr +="
\n";

     ptr +="
ESP8266 Weather Report
\n";
     ptr +="
\n";
     ptr +="
\n";
     ptr +="<svg version=\"1.1\" id=\"Layer_1\"
     xmlns=\"http://www.w3.org/2000/svg\"
     xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
     ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\"
     enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
      ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-
      0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
      ptr+=
       "c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,
        12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
      ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-
      2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
      ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-
      0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
      ptr +="c0.013-3.44,0-6.881,0.007-
      10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
      ptr +="</svg>\n";
      ptr +="
\n";
      ptr +="
Temperature
\n";
      ptr +="
";
      ptr +=(int)TempCstat;
      ptr +="°C
\n";
      ptr +="
\n";
      ptr +="
\n";
      ptr +="
\n";
      ptr +="<svg version=\"1.1\" id=\"Layer_2\"
      xmlns=\"http://www.w3.org/2000/svg\"
      xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\";
      width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-
      background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
      ptr +="<path fill=\"#FFFFFF\"
     d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,
      2.926,2.133,5.05,1.571,7.057\n";
     ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-
     6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
     ptr +="</svg>\n";
     ptr +="
\n";
     ptr +="
Humidity
\n";
     ptr +="
";
     ptr +=(int)Humiditystat;
     ptr +="%
\n";
     ptr +="
\n";

    //Buttons

     ptr +="
\n";
     ptr +="
Button
\n";
     ptr +="
";
     ptr +="
<button class=\"button\">ON</button>

";
     // If the output5State is off, it displays the ON button
        if (output5State=="off") {
          ptr +="
<button class=\"button\">ON</button>

";
        } else {
          ptr +="
<button class=\"button
        button2\">OFF</button>
";
        }
         // If the output4State is off, it displays the ON button
        if (output4State=="off") {
          ptr +="
<button class=\"button\">ON</button>

";
        } else {
          ptr +="
<button class=\"button
          button2\">OFF</button>
";
          }
           ptr +="%
\n";
           ptr +="
\n";
           ptr +="
\n";
           ptr +="\n";
           ptr +="\n";
           return ptr;
          }

Why are you searching for request parameters inside your generated response HTML?

Where shoulf I search !

@AlMa, did you read the answer?

Write handlers for different URLs
server.on("/5/on", led5On);
server.on("/5/off", led5off);

do you get the concept?
or you could write one handler server.on("/setLED", setLED);, if you would send "/setLED?num=5&state=on". and then in setLED function get the parameters values as
String num = sever.arg("num");
String state = sever.arg("state");

see the SimpleAuthentication example


text:
UDP behavior different for STM32
I'm facing a weird situation, where the UDP behavior seems different in STM32 porting (stm32duino).
Short question
Besides port and address, what are the other parameters that characterize the UDP protocol?
Long description
My code listens for incoming UDP packets and answer.
The actual packets contains OSC messages, but they are just UDP messages with binary data.
On host side there is a proprietary software (MAX) that send those packets. The issue is the following:

run both Arduino board and MAX software
from software send a packet
the Arduino receives the packet, and answer
the software receive the answer
now if the software sends more packets, they are not received anymore from Arduino

The weird thing is if I use another application to send the very same packets (i.e. PacketSender) all works fine and I can always send and receive correctly.
Furthermore, this happens with the STM32 porting only. The same code compiled for the standard Arduino Uno works fine.
Now some code:
//#define STM32
#define UNO

#if defined(UNO)
#include <SPI.h>
#include <Ethernet.h>
#elif defined(STM32)
  #include <LwIP.h>
  #include <STM32Ethernet.h>
#endif

#include <EthernetUdp.h>

#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#if defined(UNO)
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
#endif

IPAddress remoteIP;
int remotePort;
OSCBundle bundleOut;
EthernetUDP Udp;
OSCErrorCode error;

void setup()
{
  Serial.begin(115200);

#if defined(UNO)
  Ethernet.init(10);
#endif
  IPAddress localIP(192, 168, 100, 1);
  IPAddress subnet(255, 255, 0, 0);
  IPAddress dns(192, 168, 1, 1);
  IPAddress gateway(192, 168, 1, 1);

#if defined(UNO)
  Ethernet.begin(mac, localIP, subnet, dns, gateway);
#elif defined(STM32)
  Ethernet.begin(localIP, subnet, dns, gateway);
#endif

#if defined(STM32)
  uint8_t *mac = Ethernet.macAddress();
#endif
  char macString[32];
  sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print("IP Address: ");
  Serial.println(Ethernet.localIP());
  Serial.print("MAC Address: ");
  Serial.println(macString);

  int port = 8888;
  Udp.begin(port);
  Serial.print("UDP port: ");
  Serial.println(port);
}

void processOSCMessage(void)
{
  OSCBundle bundle;

  int size = Udp.parsePacket();
  if (size > 0)
  {
    remoteIP = Udp.remoteIP();
    remotePort = Udp.remotePort();

    while (size--) bundle.fill(Udp.read());
    Serial.print("Source: ");
    Serial.print(remoteIP);
    Serial.print(":");
    Serial.println(remotePort);
    if (bundle.hasError())
    {
      error = bundle.getError();
      Serial.print("Error: ");
      Serial.println(error);
    }
    else
    {
      int size = bundle.size();
      for (int i = 0; i < size; i++)
      {
        OSCMessage msg = bundle.getOSCMessage(i);
        char buffer[32];
        msg.getAddress(buffer);
        Serial.print("Message: ");
        Serial.println(buffer);
      }

      bundle.route("/version", version_handler);
    }
  }
}

void version_handler(OSCMessage &msg, int patternOffset)
{
    OSCBundle bundle;
    Serial.println("Answer to message");
    bundle.add("/version").add(1).add("0.1");
    Udp.beginPacket(remoteIP, 8888);
    bundle.send(Udp);
    Udp.endPacket();
}

void loop()
{
  processOSCMessage();
}

I can't understand the difference between the MAX application and PacketSender. They are both configured to send the same data, to the same address and same port, what else?
MAX is still working after point 5 because if I redirect the address to another pc where I have PacketSender I still receive the messages. It seems it's just the STM32 Arduino library that doesn't receive anymore the packets.
For STM32 I'm using the following setup:

Nucleo F429ZI
STM32Ethernet (https://github.com/stm32duino/wiki/wiki/STM32Ethernet)
LwIP per STM32 (anche questa la trovi nel gestore librerie)

Any further idea how to fix this issue?
UPDATE
Following the suggestion, using WireShark I found the only difference between the two packets: the source port. I'm not saying this is the cause, but it's the only difference I can see.
PacketSender sends packets from the same port it also listens too (i.e. 8888).
MAX sends packets from a random port while it listens to the 8888.
Now I can partially replicate the behavior using PacketSender:

open two instances of PacketSender
A: set UDP port to 8888
B: set UDP port to another, say 50127
from B send the packet to Arduino (STM32)
Arduino receives the packet and answers to 8888
A receive the answer
now if I send more packets from B, they are not received anymore from Arduino, this is the same behavior using MAX
BUT if now I send packets from A they are received from Arduino and answered!

So it seems the problem rises when Arduino answer to a different port than the source one. This make no sense to me because the involved port is the source one (host side). Because UDP has no connection, why this might lead to such an issue!?
Furthermore, using the same code compiled for Arduino UNO, it works fine even at point 7.

I would suggest running Wireshark (or something similar) to examine the packets and see what is actually different.

Thanks, question updated.

Are you using a W5100 interface with the STM32, or does it have its own internal Ethernet controller that just needs a PHY interface? I'm not that familiar with that family of chips.

@Majenko the F429ZI embed an Ethernet controller. It just needs the PHY interface.

I would be inclined to raise it as an issue with the maintainers of the core / library.


text:
Cannot compile MFRC522 minimal I2C example
On ESP32 I'm trying to build the Minimal I2C example of the MFRC522 library:
But I get errors on the first declarations:
TwoWire i2cBus = TwoWire(0);
MFRC522_I2C dev = MFRC522_I2C(RST_PIN, 0x28, i2cBus);
MFRC522 mfrc522 = MFRC522(dev); // <--- error

Here the build output:
src/rfid.cpp:6:30: error: no matching function for call to 'MFRC522::MFRC522(MFRC522_I2C&)'
 MFRC522 mfrc522 = MFRC522(dev);
                              ^
In file included from include/rfid.h:5,
                 from src/rfid.cpp:1:
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:348:2: note: candidate: 'MFRC522::MFRC522(byte, byte)'
  MFRC522(byte chipSelectPin, byte resetPowerDownPin);
  ^~~~~~~
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:348:2: note:   candidate expects 2 arguments, 1 provided
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:347:2: note: candidate: 'MFRC522::MFRC522(byte)'
  MFRC522(byte resetPowerDownPin);
  ^~~~~~~
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:347:2: note:   no known conversion for argument 1 from 'MFRC522_I2C' to 'byte' {aka 'unsigned char'}
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:346:2: note: candidate: 'MFRC522::MFRC522()'
  MFRC522() DEPRECATED_MSG("use MFRC522(MFRC522_BUS_DEVICE bus_device)");
  ^~~~~~~
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:346:2: note:   candidate expects 0 arguments, 1 provided
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:343:2: note: candidate: 'MFRC522::MFRC522(MFRC522_BUS_DEVICE*)'
  MFRC522(MFRC522_BUS_DEVICE * dev);
  ^~~~~~~
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:343:2: note:   no known conversion for argument 1 from 'MFRC522_I2C' to 'MFRC522_BUS_DEVICE*'
In file included from include/rfid.h:5,
                 from src/rfid.cpp:1:
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:152:7: note: candidate: 'constexpr MFRC522::MFRC522(const MFRC522&)'
 class MFRC522 {
       ^~~~~~~
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:152:7: note:   no known conversion for argument 1 from 'MFRC522_I2C' to 'const MFRC522&'
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:152:7: note: candidate: 'constexpr MFRC522::MFRC522(MFRC522&&)'
.pio/libdeps/MyProject/MFRC522-spi-i2c-uart-async/src/MFRC522.h:152:7: note:   no known conversion for argument 1 from 'MFRC522_I2C' to 'MFRC522&&'

Unfortunately there is no way to open an issue on the repository.
Why the official example does not work?
UPDATE
Here the compatibility declaration for ESP32:

@VE7JRO they declare the compatibility for ESP32, see the picture in the question updated

@VE7JRO It returns: error: cannot convert 'MFRC522_I2C' to 'MFRC522_I2C*' in initialization

Guys, why the downvote? Without an explanation how can I improve my question? I did my homework: minimal and reproducible example, show effort to solve the issue by myself, complete output message. What else do you want?

you use a fork a of fork. the library is poorly maintained. use MFRC522 mfrc522 = MFRC522(&dev);

if you look, it says, "Candidate expects 2 inputs, one provided."
so in the arduino IDE hover over the function and see what it expects.
(What your putting in MFRC522(byte resetPowerDownPin); what it expects: MFRC522(byte resetPowerDownPin, Something else);)

What it expects is in the declaration of the constructor: https://github.com/MakerSpaceLeiden/rfid/blob/master/src/MFRC522.cpp#L10. And is MFRC522_BUS_DEVICE * dev

I'm not putting any byte


text:
System crash after using sprintf
My Arduino crashes after using sprintf, To reduce system ram am trying to move away from strings to char and now this happened. Loop not working properly and it's not going to webrequest, spent 2 days to find a solution nothing worked yet. My project is to send temp and humidly to my server i was using strings and after one day of use system very slow to send data to server then i realized stings are the culprit then i changed to char
char ventionoroff[6];

char Foggeronoroff[6] ;

char Exhuastonoroff[6] = "OFF";

char current[4];

char today[10];

bool running = false;
bool isFoggerRunning = false;
bool isExhaustFanRunning = false;

Time t;

void loop() {

 t = rtc.getTime();

  hum = dht.readHumidity();
  temp = dht.readTemperature();
  delay(1000);

  if (isnan(hum) || isnan(temp)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  val = digitalRead(powerStatus);

      byte MIN = t.hour;
      byte SEC = t.min;

  char timeStamp[20];
 snprintf(today, "%02d:%02d",  MIN, SEC);

   Serial.println(today);

if (millis() - lastConnectionTime > postingInterval) {
   Serial.println("reaching here2");
    httpRequest();
  }

  if (val)
  snprintf( current , "YES");

  else
 snprintf( current , "NO");

  if (running == false) {
    snprintf( Foggeronoroff , "WAIT");

  } else {
   snprintf( Foggeronoroff , "READY");

  }

    ventilationfan();

void httpRequest() {
Serial.println("shit reached here");
  client.stop();
  char data[10];
  const char phpScript[21]  = "";
  const char server[20]  =  ""; // also change the Host line in httpRequest()

   char strt[6];
   char str[6];
  sprintf(strt, "te=%d", temp);
  strcpy(data, strt);
  strcat (data,"&ti=");
  strcat (data,today);
   strcat (data,"&mot=");
   strcat (data,ventionoroff);
   strcat (data,",");
   strcat (data,Foggeronoroff);
    strcat (data,",");
    strcat (data,current);
     strcat (data,"&mo=");
     strcat (data,Exhuastonoroff);
      sprintf(str, "&hum=%d",hum);
      strcat (data,str);

 Serial.println(data);
   int len = strlen(data);
  if (client.connect(server, 80)) {
    client.print("POST ");
    client.print(phpScript);
    client.println(" HTTP/1.1");
    client.println("Host:");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
    client.print("Content-Length: ");
    client.println(len);
    client.println();
    client.print(data);
    restartnet = 0;
     data[0] = 0;
     Serial.print("data after sucessfull connection");
     Serial.println(data);
     Serial.print("freeMemory after connection");
     Serial.println(freeMemory());
    lastConnectionTime = millis();

  } else {

     Serial.println(F("Failed"));
     data[0] = 0;

  }
}

Do you mean this line? sprintf(strt, "te=%d", temp); - Are you sure, that temp will only have 2 digits? Which type is temp? You didn't include the declaration of it in your question. And why are you doing all the strcat() calls? Why not just using snprintf with a bigger format string, including all the data together?

it doesn't look like data is large enough

And when using snprintf(), shouldn't you also provide the maximum number of characters to write, as this function is meant for that?

@chrisl ttemp is temperature value, i tried to do that but get errors new to sprintf so no idea how to implement to make string

@Juraj new to sprintf , dont know how to deal with it , what i need to do then?

the array size should reflect the count of characters you concatenate into it. does it make sense?

@Juraj Yeah, actually i still don't know why my system  crash.

@Juraj can you show me an example how to declare global char that change status like , on ,off

you rewrite a memory of other variable if you write out of the allocated space. it looks like you write around 30 characters more then your arrays size data[10]

@Juraj i got that, i changed the size to 30. does the system reuse [30] the memory after use?

count the characters and create a large enough array. I said 30 more so I guess 40. it is a local variable allocated on 'stack'.  https://en.wikipedia.org/wiki/Stack-based_memory_allocation

@Juraj After changing to [30] system works looks fine now, if you dont mind can you show me an example to put big strings in sprintf ? because my purpose is to send data to server with webservice  i used strcat insted of sprintf the problem with the strcat ( is i need to empty every time

sprintf_P(buff, PSTR("%-15s|%d-%02d-%02d %02d:%02d:%02d|% 5d|% 5d|% 3u|"), eventLongLabels[ix], year(t), month(t), day(t), hour(t), minute(t), second(t),  events[ix].value1, events[ix].value2, events[ix].count); https://www.cplusplus.com/reference/cstdio/printf/

There are quite a few points that could be improved in this code. The
main ones have already been shown in the comments:

the data buffer was not large enough to hold the whole string,
which leads to a buffer overflow, memory corruption and, ultimately,
the crash you are experiencing.

The second parameter to snprintf() should be the size of the
provided buffer.

Here I will add a few points that, although not really defects of this
program, could help improved it and save memory.
Here:
char current[4];
// ...
if (val)
    snprintf(current, "YES");
else
    snprintf(current, "NO");

you are not using the current buffer to build a string, but only to
store one of two pre-existing strings (the literals "YES" and "NO")
that are already stored in memory. Rather than making a copy, you could
instead reuse those pre-existing strings, and have current be a
pointer to the relevant one:
const char *current;
// ...
if (val)
    current = "YES";
else
    current = "NO";

This only saves two bytes (size of the buffer minus size of the
pointer), but this pattern happens multiple times in the program, and
the savings add up.
Now, another small optimization. Here:
char strt[6];
sprintf(strt, "te=%d", temp);
strcpy(data, strt);

you do not need the extra strt buffer, as you can write directly into
the data buffer. Better yet, you can write everything into the
buffer in a single call to snprintf():
snprintf(data, sizeof data,
        "te=%d&ti=%02d:%02d&mot=%s,%s,%s&mo=%s&hum=%d",
        temp, t.hour, t.min, ventionoroff, Foggeronoroff, current,
        Exhuastonoroff, hum);

If you don't like this approach, and would prefer writing the data in
separate calls to snprintf(), you can do so without using auxiliary
buffers. You have to remember (with a pointer) where within the buffer
you finished your previous write, and pass this address to the next
snprintf() call. Note that you also have to keep track of the room
that is still available, which is easy to do with a second pointer that
points to the end of the buffer:
char *p = data;                  // current writing position
char *end = data + sizeof data;  // end of the buffer
p += snprintf(p, end - p, "te=%d", temp);
p += snprintf(p, end - p, "&ti=%s", today);
// ...

snprintf(data, sizeof data, "te=%d&ti=%d&mot=%s,%s,%s&mo=%s&hu=%d",
temp, today, ventionoroff, Foggeronoroff, current,
Exhuastonoroff, hum);  'today' actualy rtc time , but i get 825 in that char not time , i serial printed the today and i got the time but sending 825 to server dont know where it come

@user2037091: today was an array of char in the original code. Anyway, I amended the answer in order to print t.hour and t.min instead. This saves an extra auxiliary buffer.


text:
WiFi.scanNetworks() sometimes triggers wdt reset
In my sketch for ESP32, I call the network scanning function:
WiFi.scanNetworks(true);

but sometimes it trigger a wdt reset:
E (372741) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (372741) task_wdt:  - async_tcp (CPU 0/1)
E (372741) task_wdt: Tasks currently running:
E (372741) task_wdt: CPU 0: IDLE
E (372741) task_wdt: CPU 1: IDLE
E (372741) task_wdt: Aborting.

abort() was called at PC 0x40113f64 on core 0

Backtrace: 0x40083db5:0x3ffbf1ac |<-CORRUPTED

I added these lines in the setup() with no changes in the behavior:
disableCore0WDT();
disableCore1WDT();
disableLoopWDT();

EDIT:
My questions are:

"Why it triggers a WDT reset even if I disabled the WDT?"
"Why a scan network triggers a WDT reset? It should be a stock function"

what is your question? ... please add a clear, answerable question to your post

@jsotola done. Please tell me if now the questions are clear and answerable, or how to improve them further

WiFi.scanNetworks(true); means async WiFi scan, it is non-blocking, so anything that causing the WDT trigger is in your code and we don't know how you setup the task and handing the state transitions. Do you have any problem running WiFi scan with sync mode WiFi.scanNetworks();?

@hcheung I'm fairly certain that it might be something inside Espressif's proprietary RF driver code. All of the task's setup and everything is hidden away as well from most Arduino users, so I don't think we'll be able to answer #2. For #1, it's because there is also a WDT for tasks, while the disabled WDTs are the "loop WDTs".


text:
Wrong use of memory?
Probably I'm doing something wrong.
I'm writing an Arduino sketch for ESP32.
Among the others I have this function:
#define HDR_MAX_LENGHT 4
#define CMD_MAX_LENGHT 5
#define ARG_MAX_LENGHT 5
#define ARG_MAX_NUMBER 8

void ProcessLine(HardwareSerial *serial, char *line)
{
  int ret;
  int argc;
  char header[HDR_MAX_LENGHT + 1];
  char cmd[CMD_MAX_LENGHT + 1];
  char argv[ARG_MAX_NUMBER][ARG_MAX_LENGHT + 1];

  return; // for debugging
}

Usage example:
void loop()
{
    static char inBuf[64];

    if (Serial.available())
    {
      size_t size = Serial.readBytes(inBuf, 64);
      inBuf[size] = '\0';
      ProcessLine(&Serial, inBuf);
    }
}

In the last days all worked fine.
After adding other code, I noticed that sometimes my program "hangs": nothing runs. Perhaps it goes in an exception trap.
Commenting out the different sections of the code, I discovered that if I remove the declarations of the variables in ProcessLine() no more hangs happen.
The current RAM consumption is negligible: 0.5%.
During the tests NO serial data was received! So the function ProcessLine() was never called.
Hence, only the declaration of the variables lead to the "hang".
I wonder if there are some mistakes in the code above.
Otherwise, how I can further debug my code to understand what I've done wrong?

if size is 64 then you write \0 out of the array

@Juraj good catch, thanks. But as said I'm not sending any data right now.

Can you write a testable, minimal example that reproduces the issue?

@EdgarBonet unfortunately not because with a minimal example all works as expected (as said, in the beginning of the development there were no issues). For this reason I'm asking how to debug in addition to commenting out some part of the code.

This is just a guess, but what about compiler optimization? Try to turn optimization off and test again.

Modify optimize_level  in \hardware\arduino\avr\platform.txt. Acceptable values are  -O0 ,  -O1 ,  -O2 ,  -O3 ,  -Os  and  -Ofast . Default is  -Os .

There is nothing wrong with these declarations. The fact that the program works when you comment out some lines of code does not mean that these lines are causing the problem. It looks like you may have triggered undefined behavior somewhere. When this happens, the behavior of the program becomes unpredictable, and can depend on changes to parts of the code that are completely unrelated to the actual problem. A typical example is memory corruption.

As I said in a comment, there is nothing wrong with these declarations.
Now, here are some debugging strategies you may try:

You can rebuild your program with all compiler warnings enabled. Look
carefully at the compiler messages and investigate any warning you
see.

You can continue with your current strategy: put back those
declarations, then try to remove something else. You may find that
there are multiple pieces of code that, when removed, make your
program work again. Chances are the problem resides in one of those
pieces. But then, it may be that the problem is in the interaction
between multiple pieces rather than in one specific piece.

You may just read the code carefully and see if you spot something
suspicious. This can work sometimes: see how @Juraj spotted a buffer
overflow in your code snippet just by reading it.

You can add debug messages across your program, to check what
branches are executed, the values of variables...

I don't know the ESP32 dev environment, but you can check whether the
compiler supports adding “sanitizers”. These are pieces of code added
by the compiler that do run-time checks on your program, and report
problems as they happen. You may want to enable at least an address
sanitizer and an undefined behavior sanitizer.

If the environment supports it, you can try to run the program in a
debugger. No success guaranteed: if the program corrupts its memory,
it may crash in some place unrelated to the actual problem. The
debugger will tell you where it crashed, which may not be very
helpful in this case.

If the ESP dev environment supports neither 5 nor 6, you may try to
run your program on your PC. There are a couple of Arduino-compatible
cores that you can download for running on a PC.


text:
Avoid 1-LSB noise on ADC readings
I have a potentiometer connected to an ADC input of an Arduino Leonardo.
The ADC resolution is 10-bit (0..1024), while I need just 7-bit (0..127).
I use a simple filter to reduce the noise and then a map to cut the unused bits:
#define ADC_CH                18
#define ADC_FILTER            0.90

uint16_t value;

uint16_t adc = analogRead(ADC_CH);
value = (uint16_t) ((float) ADC_FILTER * adc + (1. - ADC_FILTER) * value);

I show value on an LCD. It's very stable, but it may happen that if the adc readings are in the nearby of two values, there is nothing that could prevent a change in the final value, even if the noise is of just few LSBs.
Is there a simple way to implement an hysteresis for each low-res value?
In this way the change between N and N+1 happens on a different ADC reading than between N and N-1, improving the noise rejection without increasing the filter delay (that would only increase the change interval).

When you reduce the resolution from 10 bits to 7 bits, every possible
output corresponds to an interval of inputs. If you add some hysteresis,
then those intervals should overlap. Below is a representation of the
input intervals corresponding to outputs 0, 1,… 6, for an
hysteresis width of 4:
input: 0    5   10   15   20   25   30   35   40   45   50   55   60
       └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴
       ├─────0────┤
           ├───────1──────┤
                   ├───────2──────┤
                           ├───────3──────┤
                                   ├───────4──────┤
                                           ├───────5──────┤
                                                   ├───────6──────┤

To implement this in code, you have to remember the last output, and
change it only if the input lies outside the interval assigned to this
output. Here is an example implementation:
const int hysteresis = 4;  // tune to taste

/* Remove 3 bits of resolution while adding some hysteresis. */
int resample(int adc)
{
    static int value;  // last output
    if (adc < (value<<3) - hysteresis) {
        value = (adc + hysteresis) >> 3;
    } else if (adc >= ((value+1)<<3) + hysteresis) {
        value = (adc - hysteresis) >> 3;
    }
    return value;
}

Note that a static local variable keeps its value between successive
calls to the function.

I'm not supposed to do this but anyway: excellent answer! Nice graphic, well explained. :)

Your code works perfectly and it fits exactly the example in my question. Anyway, is there a more general approach? For example, what if I want to map the ADC input to [min, max] (always < 1024) ?

@Mark: Then you would replace the shifts (which are basically optimized multiplications and divisions) by arbitrary map()s. You may then want to do some tests in order to see how the rounding errors introduced by the map interfere with the hysteresis.


text:
SerializeJson not working when using softserial
IDE:1.8.8
Board:Arduino UNO
When I use the code below, I get result of print like this.
{ "result": [ { "ID": "01", "Value": [ "2", "1", "13" ] } ] }

But when I use SoftwareSerial and in the setup to being that the serializeJson result like this:
{}

I don't know what happens in the softserial with using json library, can someone tell me why?
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
int dir[3];
char  json[] ="{\"ID\":\"01\",\"Value\":[\"%d\",\"%d\",\"%d\"]}";
//SoftwareSerial Left(8,9);//左
/SoftwareSerial Right(6,7); //右
//SoftwareSerial Up(10,11);//上
//SoftwareSerial Down(14,15);//下
//SoftwareSerial Global(8,9);  //建立軟體串列埠腳位 (RX, TX)左
void setup() {

  Serial.begin(9600);        //設定硬體串列埠速率
 // Up.begin(9600);
 // Right.begin(9600);
  //Global.begin(9600);   //設定軟體串列埠速率
  }

void loop() {

 dir[0]=2;
 dir[1]=1;
 dir[2]=13;
  if(Serial.read()=='j')
{
 StaticJsonDocument<256> docc;
  char b[35];
  sprintf(b, json, dir[0], dir[1],dir[2]);
  deserializeJson(docc, b);
  JsonObject object = docc.as<JsonObject>();

  DynamicJsonDocument doc(1024);
 JsonArray result = doc.createNestedArray("result");
  result.add(object);
  result.add(object);
  serializeJsonPretty(doc,Serial);
   }
  }

These are error code
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
int dir[3];
char  json[] ="{\"ID\":\"01\",\"Value\":[\"%d\",\"%d\",\"%d\"]}";
//SoftwareSerial Left(8,9);//左
SoftwareSerial Right(6,7); //右
SoftwareSerial Up(10,11);//上
//SoftwareSerial Down(14,15);//下
SoftwareSerial Global(8,9);  //建立軟體串列埠腳位 (RX, TX)左
void setup() {

  Serial.begin(9600);        //設定硬體串列埠速率
  Up.begin(9600);
  Right.begin(9600);
  Global.begin(9600);   //設定軟體串列埠速率
  }
void loop() {
     Global.listen();
      while (!Serial.available()) {}  //等到PC傳送字元才到下一步
     Global.write(2);  //傳送給左邊的板子子id
      while (!Global.available()) {}  //等到左方板傳送字元才到下一步
        dir[0]=Global.read();
        Serial.println( dir[0]);  //左方板向PC傳送字串

       Up.listen();
      while (Serial.read()!='Y') {}  //等到PC傳送字元才到下一步
      Up.write(3);  //傳送給左邊的板子子id
      while (!Up.available()) {}  //等到左方板傳送字元才到下一步
      dir[1]=Up.read();
        Serial.println(dir[1]);  //左方板向PC傳送字串
       // }

     Right.listen();
     while (Serial.read()!='Y') {}  //等到PC傳送字元才到下一步
      Right.write(4);  //傳送給左邊的板子子id
      while (!Right.available()) {}  //等到左方板傳送字元才到下一步
       dir[2]=Right.read();
        Serial.println(dir[2]);  //左方板向PC傳送字串
 if(Serial.read()=='j')
{
 StaticJsonDocument<256> docc;
  char b[35];
  sprintf(b, json, dir[0], dir[1],dir[2]);
  deserializeJson(docc, b);
  JsonObject object = docc.as<JsonObject>();

  DynamicJsonDocument doc(1024);
 JsonArray result = doc.createNestedArray("result");
  result.add(object);
  result.add(object);
  serializeJsonPretty(doc,Serial);
   }
}

the code you posted doesn't even use SoftwareSerial

Sorry, i edited.

Your code still isn't even trying to output json to any software serial

And what does "These are error code" mean. There are no errors in the question

Sorry, i didn't make myself clear, the error code is just mean test in software serial begin case return this '{}' result, then when comment out //Right.begin(9600); that can give me fine json print, i don't know what happen between these two library.

yes, but there is still no code that uses SoftwareSerial to ouput JSON

Oh, i tried to change
StaticJsonDocument<256> docc; -> StaticJsonDocument<50> docc;
then result is good, i think this is a memory problem?

yes, but there is still no code that uses SoftwareSerial to ouput JSON

OK, i  show my complete code to use SoftwareSerial , i just use that to collect number to join json string.


text:
ATmega328p - ISC00 with INT1?
I was reading about external interrupts using the ATmega328p, and I saw in the chip datasheet under the paragraph "Bits 3:2 – ISC1n: Interrupt Sense Control 1 [n = 1:0]" the following table:
Value | Description
------+------------------------------------------------------------
00    | The low level of INT1 generates an interrupt request.
01    | Any logical change on INT1 generates an interrupt request.
10    | The falling edge of INT1 generates an interrupt request.
11    | The rising edge of INT1 generates an interrupt request.

From what I understand from the table title and the definition in the datasheet that ISC1n where n=1|0, is dedicated for INT1. And that ISC0n where n=1|0, is dedicated for INT0. However, in the table above, the value 00 is described as "The low level of INT1 generates an interrupt request.".
What I don't understand is how can ISC0n where n=1|0 be dedicated for INT0 but in the table above the value 00 (or ISC00) is used for INT1 ? I could totally be missing something but I would appreciate any guide.

From what I understand from the table title and the definition in the
  datasheet that ISC1n where n=1|0, is dedicated for INT1. And that
  ISC0n where n=1|0, is dedicated for INT0.

This is correct.

[...] in the table above the value 00 (or ISC00) is used for INT1

This is your misunderstanding. The value "00" in the table does not mean
ISC00. The "Value" column of the table is the value you get by
concatenating the bits ISC11 and ISC10. Thus:

"Value = 00" means ISC11 = 0 and ISC10 = 0
"Value = 01" means ISC11 = 0 and ISC10 = 1
"Value = 10" means ISC11 = 1 and ISC10 = 0
"Value = 11" means ISC11 = 1 and ISC10 = 1

Ohh I understand it now! Edgar that's an amazing explanation! Thank you so much!

It's a typo. My revision of the datasheet (revision G) properly says "INT0".

Thanks for your quick reply!!! Where can I find the newest version of the PDF, Google seems to index the one with the typo first ?

The latest revision of any Atmel datasheet is available from Atmel's website. I have confirmed that revision B of the 328/328P datasheet does not have that typo.

Cool I'll check on their website. Thank again!

I think this is it: ATmega48A/PA/88A/PA/168A
/PA/328/P DATASHEET - revision J.

Atmel split the 328/P parts into a separate datasheet recently (for a certain definition of "recently").

Revision B of the Complete datasheet of the ATmega328p has the same type, but some more recent PDFs like the one posted by @NickGammon does not. Thank Nick for the link!

Atmel-42735B-ATmega328/P_Datasheet_Complete-11/2016? I'm not seeing the typo there, unless I'm looking in completely the wrong place.

In the PDF at http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf, page 89 (Both tables)

I'm seeing "INT0" in the table on that page, under "Bits 1:0 – ISC0n".

Correct, but in "Bits 1:0 – ISC0n" table they also put "Value: 10, Description:
The falling edge of INT0 generates an interrupt request" that what confused me

I'm not seeing what's wrong with that. ISC0n is about INT0, and 0b10 means an interrupt on a trailing edge.

From what I understand from this PDF: ISC00, ISC01, ISC10 and ISC11 can be for both INT0 and INT1. However, the newer PDF mention: ISC00 and ISC01 is for INT0. And ISC10 and ISC11 are for INT1

The register descriptions explicitly state that ISC1n is for INT1 and ISC0n is for INT0 in the first two sentences of the first paragraph of each.

Yup, you're right, just the tables contradicted those statements. But it's good I know it's fixed in the newer revision. Thanks again!

Thanks again guys for the help, Edgar in his answer saw where my mistake is.

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


text:
Weird behaviour of rotary encoder values
The plan is to control a NEMA 17 stepper motor with an endless rotary encoder.
First, I found a code to read the rotary encoders data on www.HowToMechatronics.com by Dejan Nedelkovski. It basically manipulates an integer and outputs it on the Serial Monitor.
Works almost perfectly except that it actually doubles the count of steps the rotary encoder does.
So a clockwise turn subtracts 1, outputs it in the SM, subtracts 1 and outputs it in the SM again. Same in the other direction with adding 1. Although being not a big deal for intended use of the rotary encoder data, I think this has something to do with the problem.
In the code down below you will find a modified version of the code from Mr. Nedelkovski. I added a few lines to move the motor a few steps in each direction.
Clockwise rotation works as I expected.
One step on the rotary equals subtract, output, movement, subtract, output, movement.
But counterclockwise rotation now adds 1 to the rotary position and subtracts it immediately, leaving the motor in moving back and forward.
But if I move the rotary very very slowly it will work.
Why are the rotary values jumping around once I added the lines?
Is there a way to solve this?
The code:
/*     Arduino Rotary Encoder Tutorial
 *
 *  by Dejan Nedelkovski, www.HowToMechatronics.com
 *
 *  to make it work with a stepper
 *  modified by me
 *
 */

#include <Stepper.h>

#define outputA 52
#define outputB 50

int counter = 0;
int dir = 0;
int aState;
int aLastState;

Stepper myStepper(200, 47, 49, 51, 53);

void setup() {

  pinMode (outputA,INPUT);
  pinMode (outputB,INPUT);

  Serial.begin (9600);
  // Reads the initial state of the outputA
  aLastState = digitalRead(outputA);

  // set the speed at 60 rpm:
  myStepper.setSpeed(60);

}

void loop() {

  aState = digitalRead(outputA); // Reads the "current" state of the outputA
  // If the previous and the current state of the outputA are different, that means a Pulse has occured

  if (aState != aLastState){
    // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise

    if (digitalRead(outputB) != aState) {

      counter ++;
      myStepper.step(50);

    } else {

      counter --;
      myStepper.step(-50);

    }

    Serial.print("Position: ");
    Serial.println(counter);
  }

  aLastState = aState; // Updates the previous state of the outputA with the current state
}

Thanks for taking your time to read this and help me. I hope that a detailed explanation will help solving the problem.

most rotary handler only fire on the leading or trailing edge, you fire on both...

@dandavis Does it mean that the encoder is broken?

no, it means you need to check not just that the gpios are different, but that they are 0 (or 1) and have changed, but not the other. something like if (digitalRead(outputB) != aState && aState==1)

Unfortunately, I couldn't find the issue.
BUT I used another approach which worked fine.
I used the ClickEncoder library.
This time, my rotary encoder triggered 4 events per notch.
After a little research I found out, that it's possible to set the steps per notch with this library.
I used this code to initiate the ClickEncoder:
encoder = new ClickEncoder(A15, A14, A13, 4);

The first three arguments define the pins the encoder is connected to. The last argument sets the steps per notch. Now it works like a charm!
Full code:
#include <ClickEncoder.h>
#include <TimerOne.h>

ClickEncoder *encoder;
int16_t last, value;

void timerIsr() {
  encoder->service();
}

void setup() {
  Serial.begin(9600);
  encoder = new ClickEncoder(A15, A14, A13, 4);

  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);

  last = -1;
}

void loop() {
  value += encoder->getValue();

  if (value != last) {
    last = value;
    Serial.print("Encoder Value: ");
    Serial.println(value);
  }

  ClickEncoder::Button b = encoder->getButton();
  if (b != ClickEncoder::Open) {
    Serial.print("Button: ");
    #define VERBOSECASE(label) case label: Serial.println(#label); break;
    switch (b) {
      VERBOSECASE(ClickEncoder::Pressed);
      VERBOSECASE(ClickEncoder::Held)
      VERBOSECASE(ClickEncoder::Released)
      VERBOSECASE(ClickEncoder::Clicked)
      case ClickEncoder::DoubleClicked:
          Serial.println("ClickEncoder::DoubleClicked");
          encoder->setAccelerationEnabled(!encoder->getAccelerationEnabled());
          Serial.print("  Acceleration is ");
          Serial.println((encoder->getAccelerationEnabled()) ? "enabled" : "disabled");
        break;
    }
  }
}

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


text:
eval() function for Arduino?
I plan to do the following:
void setup(){
  String term = "12 + (2 * 5)";
  int result = eval(term); // eval function (from Python)
  Serial.println(result); // expecting 22
}

However there is no eval function. Are there any alternatives?

Guess there is more to this question as "String term = 12 + (2 * 5);" can be evaluated at compile time.

TinyExpr does what you want, and more.

TinyExpr is a very small recursive descent parser and evaluation engine for math expressions. It's handy when you want to add the ability to evaluation math expressions at runtime without adding a bunch of cruft to you project.
In addition to the standard math operators and precedence, TinyExpr also supports the standard C math functions and runtime binding of variables.

Your example
You'd just need to save tinyexpr.h and tinyexpr.c next to your Sketch.
#include "tinyexpr.h"

void setup() {
  Serial.begin(115200);
}

void loop() {
  char term[] = "12 + (2 * 5)";
  Serial.println(term);
  int error;
  double result = te_interp(term, &error);
  if (error){
    Serial.println("Problem with expression.");
  } else {
    Serial.printf(" = %.10g\n", result);
  }
  delay(1000);
}

It outputs:
12 + (2 * 5)
 = 22

Since term is known at compile-time, this example is not very useful, and it simply outputs 22 in an endless loop.
Basic interactive console
If you use the input from Serial, you can write a very basic interactive console. A String has been used for conciseness, but this example could be rewritten with cstrings:
#include "tinyexpr.h"

void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available() > 0) {
    String expression = Serial.readStringUntil('\n');
    Serial.print("> ");
    Serial.println(expression);

    int error;
    double result = te_interp(expression.c_str(), &error);

    if (error) {
      Serial.print(" ");
      for (int i = 0; i < error; i++) {
        Serial.print(" ");
      }
      Serial.println("↑");
      Serial.println("I didn't understand this part.");
    } else {
      Serial.printf(" = %.10g\n", result);
    }
  }

  delay(50);
}

TinyExpr knows the order of operations, and it understands many other mathematical expressions:
> 12 + 2 * 5
 = 22
> 3^5
 = 243
> exp(7)
 = 1096.633158
> (1 + sqrt(5)) / 2
 = 1.618033989
> 1 + 2 * 3 + 4 * 5
 = 27
> sin(pi/2)
 = 1
> sin(pi/3)
 = 0.8660254038

If there's a syntax error somewhere, error tells you the position of the first encountered error:
> 3 +
      ↑
I didn't understand this part.
> sin() * 5
      ↑
I didn't understand this part.
> 3 / (4 + 5 * 7
                ↑
I didn't understand this part.

No, there are no alternatives. You need to parse the string and perform the operations yourself.
Personally I prefer to use RPN since it is so much easier to parse. Your string could be re-written then as:
2,5,*,12,+

Tokenise on , and look to see if it's a number (push on a stack) or an operator (pop operands off stack, do operation, push result on stack).

Here is a shell that works accordingly. A mix of Forth and Postscript syntax; https://github.com/mikaelpatel/Arduino-Shell

I Googled and the news isn't good.  There isn't an off the shelf function that does this in C/C++.  There are plenty of links to algorithms that you could implement.  But would you have the memory to do it on an Arduino?
So, looking at the problem for a different perspective why don't you run python on the Arduino?  There is a version called pymite which runs on a mega.


text:
Moving average sticks in fictitious zeroes for the first readings. This delays accuracy
My 9/10 Moving Average inserts zeroes for the first 9 readings. For example, if the first voltage reading is 100, the first moving average given is 10. That is the average of 9 zeroes and one 100. How can I get the moving average to only use actual readings from the adc? Or how can I get the moving average to wait until at least 10 readings are finished before starting its calculations?
#include <SPI.h>
#include <SoftwareSerial.h>
#include <math.h>
#include <ads1262.h>

#define PGA 1 // Programmable Gain = 1
#define VREF 2.50 // Internal reference of 2.048V
#define VFSR VREF/PGA
#define FSR (((long int)1<<23)-1)

ads1262 PC_ADS1262; // class

float volt_V=0;
float volt_mV=0;
float MovingAverage=0;
volatile int i;
volatile char SPI_RX_Buff[10];
volatile long ads1262_rx_Data[10];
volatile static int SPI_RX_Buff_Count = 0;
volatile char *SPI_RX_Buff_Ptr;
volatile int Responsebyte = false;
volatile signed long sads1262Count = 0;
volatile signed long uads1262Count=0;
double resolution;

void setup() {
  // initalize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN, INPUT); //data ready input line
  pinMode(ADS1262_CS_PIN, OUTPUT); //chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);  // start
  pinMode(ADS1262_PWDN_PIN, OUTPUT); // Power down output
  Serial.begin(9600);
  //initalize ADS1292 slave
  PC_ADS1262.ads1262_Init(); // initialise ads1262
  Serial.println("ads1262 Initialised successfully....");
}

void loop() {
  volatile int i, data;
  if((digitalRead(ADS1262_DRDY_PIN)) == LOW) {
    // monitor Data   ready(DRDY pin)
    SPI_RX_Buff_Ptr = PC_ADS1262.ads1262_Read_Data();
    // read 6 bytes conversion register
    Responsebyte = true;
  }
  if(Responsebyte == true) {
    for(i = 0; i <5; i++) {
      SPI_RX_Buff[SPI_RX_Buff_Count++] = *(SPI_RX_Buff_Ptr + i);
    }
    Responsebyte = false;
  }
  if(SPI_RX_Buff_Count >= 5) {
    ads1262_rx_Data[0]= (unsigned char)SPI_RX_Buff[1];
    // read 4 bytes adc count
    ads1262_rx_Data[1]= (unsigned char)SPI_RX_Buff[2];
    ads1262_rx_Data[2]= (unsigned char)SPI_RX_Buff[3];
    ads1262_rx_Data[3]= (unsigned char)SPI_RX_Buff[4];
    uads1262Count = (signed long) (((unsigned long)ads1262_rx_Data[0]<<24)| ((unsigned long)ads1262_rx_Data[1]<<16)|(ads1262_rx_Data[2]<<8)|        ads1262_rx_Data[3]);
    //get the raw 32-bit adc count out by shifting
    sads1262Count = (signed long) (uads1262Count);
    // get signed value
    resolution = (double)((double)VREF/pow(2,31));
    //resolution=  Vref/(2^n-1) , Vref=2.5, n=no of bits
    volt_V = (resolution)*(float)sads1262Count;
    // voltage = resolution * adc count
    MovingAverage = (9*MovingAverage + volt_V)/10;
    Serial.print(MovingAverage,8);
  }
  SPI_RX_Buff_Count = 0;
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Why are almost all variables volatile? Why do you have two variables called i (one global and one in loop)?

There are essentially two ways of initializing a low pass filter. The
first is to let it initialize itself “naturally” by feeding it data
until it reaches its steady state. This is the approach of jwpat7's
answer, and it works really well with FIR filters, like a plain
moving average.
Your exponentially-weighted moving average, however, is an
IIR filter. Given constant input, it converges asymptotically to its
steady state. After feeding it 10 values, it will only have reached 65%
of the steady state (exactly 1 − 0.910), thus you
may want to feed it significantly more than 10 points. E.g., you should
give it 22 points if you want it to be 90% initialized.
The other approach is to provision a specific initialization procedure
that sets the internal state of the filter to what it would have been
had it processed an infinite stream of constant values. This is actually
really easy to do with this particular filter, as we only have to set
the output equal to its first input. Here is the self-initializing
filter written as a function (this keeps the code cleaner):
static float movingAverage(float x)
{
  static bool initialized;
  static float output;

  // Initialize the filter as if this input had been on forever.
  if (!initialized) {
    output = x;
    initialized = true;
  }

  output += 0.1 * (x - output);
  return output;
}

You loose the benefit of the averaging on the very first data points,
but in return you have a simple to use self-initializing filter.
Unrelated to your question, I looked at your code and fond so many
confusing and useless statements that I felt compelled to remove all
that cruft. I did not test the simplified version though:
#include <ads1262.h>

const float VREF = 2.50;  // Internal reference

ads1262 PC_ADS1262;  // ADC object

void setup() {
  // initialize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN,  INPUT);   // data ready input line
  pinMode(ADS1262_CS_PIN,    OUTPUT);  // chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);  // start
  pinMode(ADS1262_PWDN_PIN,  OUTPUT);  // power down output
  Serial.begin(9600);

  // initialize ADS1292 slave
  PC_ADS1262.ads1262_Init();
  Serial.println("ads1262 Initialised successfully....");
}

static float movingAverage(float x) { ... }  // as before

void loop() {
  // Nothing to do unless data ready is asserted.
  if (digitalRead(ADS1262_DRDY_PIN) == HIGH) return;

  // Get a reading and convert to voltage.
  uint8_t *buffer = (uint8_t *) PC_ADS1262.ads1262_Read_Data();
  signed long reading = (uint32_t) buffer[1] << 24
                      | (uint32_t) buffer[2] << 16
                      | (uint32_t) buffer[3] <<  8
                      | (uint32_t) buffer[4] <<  0;
  float voltage = VREF / (1UL<<31) * reading;

  // Report a smoothed-out reading.
  Serial.println(movingAverage(voltage), 8);
}

Thank you Edgar, your simplified codes works fine. I'm obviously no expert on coding. The lesson on filters is very interesting. I'm still playing around with what will work best with this weigh scale project. I plan to try a precision voltage reference instead of the Arduino 5 volt source. I know there is a method of connecting the B+ to other adc inputs and checking B+ continuously to achieve more stability and precision. I'll probably be back to this forum again, this is great!

Edgar, could you please show me how to slow the sample rate in your simplified sketch?

@Rico: Simplest thing would be to add a delay() in loop(). Cleaner would be to conditionally take the samples, on the condition “it's time to do so”. The approach is clearly explained in the Blink Without Delay Arduino tutorial.

The simplest method is just to go "I have only taken one reading, therefore I only need to look at one reading".  I.e., after your first reading you have 100/1. After your second reading you have (100+100)/2. After your 3726482374th reading you have (100+100+100+100+100+100+100+100+100+100)/10.
I have a fully templated library that works in exactly that way - it returns the rolling average (amongst other things) of only the samples you have actually fed it.

https://github.com/MajenkoLibraries/Average

Perhaps the easiest way to take in at least 10 readings before beginning to output results is to set a counter to 10 and count it down, as illustrated in following code.
byte startup=10;
void loop() {
  stuff_to_await_DRDY_and_compute_volt_V();
  MovingAverage = (9*MovingAverage + volt_V)/10;
  if (startup)
    --startup;  // Don't use MovingAverage during startup cycles
  else {        // Now we are done with startup...
    Serial.print(MovingAverage,8);
    other_stuff_with_new_data();
  }
}

As hinted at in a comment to the question, declaring all your variables volatile isn't necessary.  You should declare variables that are shared between threads, or between an ISR and loop(), volatile, but to declare other variables as volatile is in general a coding-style error that will confuse whoever maintains the code.  Spurious volatile declarations also may increase code size slightly, as it prevents one-time evaluation of expressions that are used exactly the same way multiple times, and it prevents code motion like moving constant expressions out of loops.
The following code rewrites severak parts of your sketch.  It uses some pointer arithmetic to avoid the tedious assignments and shifting found in your code.  It removes several extraneous casts because many of the type promotions and conversions coerced by your casts happen automatically anyway.  This code has not been tested; if it has problems, please point them out and I'll edit accordingly.
#include <SPI.h>
#include <SoftwareSerial.h>
#include <math.h>
#include <ads1262.h>
#define PGA 1 // Programmable Gain = 1
#define VREF 2.50 // Internal reference of 2.048V
#define VFSR VREF/PGA
#define FSR (((long int)1<<23)-1)
ads1262 PC_ADS1262; // class
float volt_V=0;
float volt_mV=0;
float MovingAverage=0;
byte SPI_RX_Buff[10];
byte SPI_RX_Buff_Count = 0;
char *SPI_RX_Buff_Ptr;
void setup() {
  // initalize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN, INPUT); //data ready input line
  pinMode(ADS1262_CS_PIN, OUTPUT); //chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);  // start
  pinMode(ADS1262_PWDN_PIN, OUTPUT); // Power down output
  Serial.begin(9600);
  //initalize ADS1292 slave
  PC_ADS1262.ads1262_Init(); // initialise ads1262
  Serial.println("ads1262 Initialised successfully....");
}

byte startup=10;
void loop() {
  double resolution;
  long *ads1262Count;
  if((digitalRead(ADS1262_DRDY_PIN)) == LOW) { // Is data ready?
    resolution = (double)VREF/pow(2,31);  // Vref/(2^n-1), Vref=2.5
    // Get address of 6-byte conversion-data buffer
    SPI_RX_Buff_Ptr = PC_ADS1262.ads1262_Read_Data();
    // Copy address of SPI_RX_Buff_Ptr[1] to ads1262Count
    ads1262Count = SPI_RX_Buff_Ptr+1;
    // Dereference ads1262Count pointer to get 4-byte signed value
    volt_V = *ads1262Count * resolution;
    MovingAverage = (9*MovingAverage + volt_V)/10;
    if (startup)
      --startup; // Don't use MovingAverage during startup cycles
    else {       // Now we are done with startup...
      Serial.print(MovingAverage,8);
      other_stuff_with_new_data();
    }
  }
  SPI_RX_Buff_Count = 0;
}

You do need to move the bytes around: according to the OP's code, the ads1262_Read_Data() method returns the data MSB first, whereas the Uno stores numbers in memory LSB first.

Thank you, your counter method works fine. The lesson on volatiles is very helpful also. I tried your trimmed down code, it showed an error with the void loop line, "ads1262Count = SPI_RX_Buff_Ptr+1;" and the error was "cannot convert 'char*' to 'long int*' in assignment".

@rico, I forgot to cast it ... s.b. ads1262Count = (long int*)(SPI_RX_Buff_Ptr+1); instead.  However, if Edgar Bonet is correct about byte order, copying the bytes is needed anyway.  Will edit answer if I get a chance to check.


text:
Help with combining sensor codes
I'm trying to combine 4 sensors' codes into one to display on the serial monitor: MAX30205, MAX30100, AHT20, and ENS160. I'm using the Adafruit ESP32 Feather V2 board. Here are the libraries that I've used:
https://github.com/gabriel-milan/Arduino-MAX30100
https://github.com/Protocentral/Protocentral_MAX30205
https://github.com/DFRobot/DFRobot_AHT20
https://github.com/DFRobot/DFRobot_ENS160
My code compiled and uploaded successfully, but it seems that only the AHT20 and ENS160 display correct data. When I put my finger on the MAX30100 and MAX30205, the sensor data stays at 0 (0 degrees Celsius, 0 bmp, 0% spo2). I need help to see if there's anything I've missed in combining the code. I've tested all the sensors individually and they work fine. This is my code:
#include <DFRobot_ENS160.h>
#include "Protocentral_MAX30205.h"
#include "MAX30100_PulseOximeter.h"
#include <Wire.h>

// Sensor objects
DFRobot_AHT20 aht20;
DFRobot_ENS160_I2C ENS160(&Wire, 0x53);
MAX30205 tempSensor;
PulseOximeter pox;

#define REPORTING_PERIOD_MS 1000
uint32_t tsLastReport = 0;

// Callback for beat detection
void onBeatDetected() {
  Serial.println("Beat!");
}

void setup() {
  Serial.begin(115200);
  Wire.begin();

  // Initialize AHT20 sensor
  uint8_t status;
  while ((status = aht20.begin()) != 0) {
    Serial.print("AHT20 sensor initialization failed. Error status: ");
    Serial.println(status);
    delay(1000);
  }

  // Initialize ENS160 sensor
  while (NO_ERR != ENS160.begin()) {
    Serial.println("Communication with ENS160 device failed, please check connection");
    delay(3000);
  }
  ENS160.setPWRMode(ENS160_STANDARD_MODE);
  ENS160.setTempAndHum(25.0, 50.0);

  // Initialize MAX30205 sensor
  while (!tempSensor.scanAvailableSensors()) {
    Serial.println("Couldn't find the MAX30205 temperature sensor, please connect the sensor.");
    delay(30000);
  }
  tempSensor.begin();

  // Initialize MAX30100 sensor
  Serial.print("Initializing pulse oximeter...");
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
  }
  pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop() {
  // Collect data from AHT20
  if (aht20.startMeasurementReady(true)) {
    float temperature = aht20.getTemperature_C();
    float humidity = aht20.getHumidity_RH();
    Serial.print("AHT2x - Temperature: ");
    Serial.print(temperature);
    Serial.println(" 'C");
    Serial.print("AHT2x - Humidity: ");
    Serial.print(humidity);
    Serial.println(" %RH");
  }

  // Collect data from ENS160
  uint8_t Status = ENS160.getENS160Status();
  uint8_t AQI = ENS160.getAQI();
  uint16_t TVOC = ENS160.getTVOC();
  uint16_t ECO2 = ENS160.getECO2();
  Serial.print("ENS160 - Air quality index: ");
  Serial.println(AQI);
  Serial.print("ENS160 - Concentration of total volatile organic compounds: ");
  Serial.print(TVOC);
  Serial.println(" ppb");
  Serial.print("ENS160 - Carbon dioxide equivalent concentration: ");
  Serial.print(ECO2);
  Serial.println(" ppm");

  // Collect data from MAX30205
  float bodyTemp = tempSensor.getTemperature();
  Serial.print("MAX30205 - Body temperature: ");
  Serial.print(bodyTemp, 2);
  Serial.println(" 'C");

  // Collect data from MAX30100
  pox.update();
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    float heartRate = pox.getHeartRate();
    float SpO2 = pox.getSpO2();
    Serial.print("MAX30100 - Heart rate: ");
    Serial.print(heartRate);
    Serial.println(" BPM");
    Serial.print("MAX30100 - SPO2: ");
    Serial.print(SpO2);
    Serial.println(" %");
    tsLastReport = millis();
  }

  Serial.println();
  delay(1000);
}```

verify that each sensor is operational ... use separate simple sketch for each sensor ... print values to serial monitor

When you compiled the sketch, you should have seen a report on memory usage. Could you please copy and paste it into your question?

@jsotola all the sensors are functional. I've tested them individually with the example sketches in the libraries I mentioned and they all work well

Delete the delay(1000), move the rest of the code in the loop() with the exception of pox.update() into the if (millis() - tsLastReport > REPORTING_PERIOD_MS)  block.

Definitely try the suggestion from @hcheung to eliminate the delay() and ensure pox.update() is called at loop speed. If that fails create 2 copies of the code, one with all the MAX30205 code removed and the other with all the MAX30100 code removed. Remove also the associated #include statements. Then test both copies. This will help show if there is mutual interference between the two problem sensors. Also update your question with the console output during setup() and one run of the loop().


text:
Common Ground Between Arduino and ESP32 - Can I Re-use the ESP32 GND Pin for a Potential Divider
I am trying to connect an ESP32 to an Arduino Mega via Serial Communication using the UART 2 ports on both microcontroller boards.
There needs to be a common ground between the ESP32 and Arduino. Hence I have connected the ESP32 GND and Arduino GND pins to the negative power rail of a breadboard.
The Arduino Rx2 has been directly connected to the ESP32 Tx2
I need to use a potential divider to convert the Arduino Tx HIGH output from 5V to 3.3V for the ESP32 Rx2.
Main Question: Can I connect the same ESP32 GND pin (used in the GND to GND connection) to Resistor 2 in the potential divider. In other words, is the dark blue wire that connects the 20K resistor to the GND power rail of the breadboard correct. Will current from the 20K resistor flow to the Arduino, ESP32 or both.
See the Circuit below

Also, according to this other question in the URL below, the answer provided by Madivad says that

if you are using the same power source, then they probably have a common ground.

In my circuit, The Arduino and ESP32 both share the same 9V power supply. So does this mean I don't even need to connect the GND of my Arduino and the GND of my ESP32 to the negative power rail on the breadboard..
Wired serial connection between two Arduinos - do they need a common Ground (GND)?

What software did you use to make this drawing?

This: https://www.cirkitstudio.com/

What you have done is great!
Yes, technically you have already grounded both together with the black wire on your diagram, but you need to run the blue wire to one of the two to create the voltage divider. Connecting the breadboard ground to both devices in this case is a good thing.
Note: There are cases where you want to keep the grounds separate, and cases where you need to tie the grounds together separately. In your case it isn't necessary to do it either way.
If you need to level shift multiple signals, you can purchase a chip that has multiple lines and better efficiency than a voltage divider.

Ok, thanks the answer. Why is it that Connecting the breadboard ground to both devices in this case is a good thing. Will current from the potential divider flow to the GND of the Arduino and GND of the ESP32?

You're just lowering the impedance of the ground path which can make your voltage divider more accurate, and your signal a little cleaner.


text:
ESP32 TFT_eSPI 8-bit Parallel Compile Error
I am compiling TFT_eSPI library for Arduino ESP32 in 8 bit parallel mode, When I Compile it in SPI mode then no error occurs, but when I select 8-bit parallel mode in User Setup File, then it shows the error:
c:\Users\yamtech\Documents\Arduino\libraries\TFT_eSPI\Processors/TFT_eSPI_ESP32.c: In member function 'uint8_t TFT_eSPI::readByte()':
c:\Users\yamtech\Documents\Arduino\libraries\TFT_eSPI\Processors/TFT_eSPI_ESP32.c:113:9: error: 'gpio_input_get' was not declared in this scope; did you mean 'gpio_num_t'?
  113 |   reg = gpio_input_get(); // Read three times to allow for bus access time
      |         ^~~~~~~~~~~~~~
      |         gpio_num_t

exit status 1

Compilation error: exit status 1

I already use New Arduino IDE with latest Arduino ESP32 Board by Espressif, but still failure occurs.
Board manager is https://dl.espressif.com/dl/package_esp32_index.json
What i found is that the Newer version of gpio.h does not contain gpio_input_get(), but older version have this function.

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]" and other pages of the [help].

How do you want the issue to be solved? For example, you can patch the library's source yourself, or you can open a ticket in the library's project. If you decided, please come back and [edit] or delete your question.

what is your specific question? ... please add a focused, answerable question to your post

My question is very simple, I just want to resolve the gpio_input_get();, which is not defined in the gpio.h, and this function is used in 8-Bit Parallel ESP32 TFT_eSPI library.

don't use the function then ... I want to resolve ... is not a question ... it is a description of what you are trying to do

I tried my best to make my question simple & clear, only need alternative of gpio_input_get();

that is just it, you did not ask any questions ... why are you unable to ask what is an alternative of gpio_input_get(); ?

In the new esp-idf(V5.x), the GPIO construct is not readily available to all users like it used to be. And there is a related issue on the idf GitHub issues 9184.
As per Espressif, it seems that the (lower-level access of) GPIO was never supposed to be available to users. Instead, it is a low-level library which provides fast pin access by using the pin registers directly. The gpio_input_get() works perfectly fine if the ESP32 Arduino framework is using esp-idf v4.x but may not with esp-idf v5.x core. For some reason, Espressif decided to take it out and make it harder for user to use it.
The TFT_eSPI already have a fix on this and to be roll-out in next release. You can read about it at Issue #2628. In the meantime, you could manually replace the file Processors/TFT_eSPI_ESP32.h in the library with the new one which in the nutshell add the following headers to support the lower-level access of GPIO:
#include "soc/spi_reg.h"
#include "driver/spi_master.h"
#include "hal/gpio_ll.h"

There is also a post in Arduino forum claims gpio_input_get() (still) work by using PlatfromIo, I guess it works because PlatformIo has not upgrade to the esp-idf 5.x yet.

Thank you, you are right gpio_input_get() works perfectly fine if the ESP32 Arduino framework is using esp-idf v4.x,but not works with esp-idf v5.x


text:
Wiring of Wemos/LOLIN D1 mini and 2.13" Tricolor e-Paper?
I'm just about starting with Arduino, ESP8266, etc.
The first project would be to get something diplayed on an e-paper.
My hardware:

LOLIN D1mini V4.0.0
Tri-Color ePaper 2.13 (SSD1680) Shield

Arduino Software, IDE, etc. is installed and the simple LED-blinking demo on D1 mini is working.
For playing with the e-paper and testing any examples, the wiring should be done correctly avoiding some potential damage.
However, so far, I haven't found any clear instructions on how to connect these two components.

The connectors 3V3, GND, RST, SCK, MOSI seem to be obvious.
However, what about BUSY, CS, DC?
Do they stay unconnected or do they need to be connected to some non-obivous pins on the D1 mini board?
On the web, I have found wirings for other boards and e-papers with different connectors and names, but not yet for D1 mini and Wemos/LOLIN 2.13" Tricolor e-paper. If I overlooked it, I would be grateful for a link to comprehensive documentation.
Actually, do the following code lines from the example on gitgub mean that CS, DC, BUSY (from the e-paper) stay unconnected and RST can optionally be connected with RST of the D1 mini? This type of documentation is not self-explanatory for a beginner.
/*D1 mini*/
#define EPD_CS D0
#define EPD_DC D8
#define EPD_RST -1  // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)

CS(chip select) is part of the 4-pin SPI interface so it should connect to SS(slave select), and it therefore should be #define EPD_CS 15 (your board using native GPIO numbering system instead of Arduino's Dx number, so it is better to use GPIO naming). The EPD_DC can be any GPIO pin, so you could use #define EPD_DC 16, EPD_RST -1 means it share with microcontroller's RST, so connect the two RSTs. if you set EPD_BUSY -1, there is no need to connect anything. -1 generally means NOT_A_PIN or not in use.

@hcheung thank you for your comment. I will try and let you know. Do you maybe want to put your comment as answer, so in case it works I can accept the answer? Ideally with some reference where I could have found this information.

@hcheung thank you! After quite some hassle, it finally seems to work (although the EPD ist flickering for almost 30 seconds for a simple screen update). I'm pretty sure everything is somehow documented somewhere, but my problem apparently seems to be where to find the right information for the dozens of variations, versions and options. So, if you could post it as an answer (ideally including a link where you got this information from) I will gladly accept it.

/*D1 mini*/
#define EPD_CS D0
#define EPD_DC D8

This piece of information seems to contradict to the actual Lolin D1 Mini board pin configurations. According to the board variant definition for Lolin D1 Mini, SS(Slave Select as part of SPI interface) is defined as GPIO15(or D8 if using Arduino naming notation), while GPIO16 is D0, so it is exactly opposite to the example on GitHub. The picture of the board silkscreen also clearly shown that the SS is GPIO15. So this should really be:
#define EPD_CS 15 // (D8) SS on D1 Mini
#define EPD_DC 16 // (D0) on D1 Mini

Since your board silkscreen is using the GPIO numbering notation instead of Arduino Dx naming notation, it is better to just direct use the GPIO number.
The EPD_DC is an output pin to specific whether data send via SPI is Data(D) or Command(C).
-1 in ESP8266 is defined as NOT_A_PIN in source code, in fact, it is commonly used to specific a pin that is not in used for configuration setting.
EPD_RST -1 means it share with microcontroller's RST, so connect the two RSTs. If you set EPD_BUSY -1, there is no need to connect anything.
You can find out more about information on how to connect the display with a host MCU from SSD1680 datasheet (see page 10 for 4-wire SPI interface).


text:
I want to read 32 bit floating point variable from Modbus RS485 slave using Arduino as Master
I have a energy meter, which has a modbus port. The registry information is available on the instruction manual. I am able to read the data using arduino, but the format is wrong.
Using open modscan software, I have attached the screenshots. When the data type is selected as u16 then the data doesn't make any sense. When I switched the data type to .32 then I can clearly get the data is mains voltage 240 V in register 40141 and 143. There is no CT connected as of now, so no current data. The value at register 157 is frequency.
WHen reading from arduino ModbusMaster library then I am getting these values.
[17:58:28:217] 62322.00␍␊  // 40141
[17:58:28:217] 17260.00␍␊
[17:58:28:217] 62322.00␍␊   // 40143
[17:58:28:250] 17260.00␍␊
[17:58:28:250] 0.00␍␊
[17:58:28:250] 0.00␍␊
[17:58:28:250] 0.00␍␊
[17:58:28:250] 0.00␍␊
[17:58:28:284] 0.00␍␊
[17:58:28:284] 0.00␍␊
[17:58:28:284] 0.00␍␊
[17:58:28:284] 0.00␍␊
[17:58:28:284] 0.00␍␊
[17:58:28:317] 0.00␍␊
[17:58:28:317] 0.00␍␊
[17:58:28:317] 0.00␍␊
[17:58:28:317] 42972.00␍␊   // 157
[17:58:28:317] 16967.00␍␊
[17:58:28:338] 0.00␍␊
[17:58:28:338] 0.00␍␊

I tried changing the variable and return type of the modbus function the the library to float but nothing worked.
I am assuming this is IEEE754 32 bit floating point variable for the data for the voltage and frequency (and every other data).
_u16ResponseBuffer[i] = word(u8ModbusADU[2 * i + 3], u8ModbusADU[2 * i + 4]);

from this statement it looks like the library is reading 8 bit values and converting to 16 bit and so not able to read 32 bit information. I have previously make an arduino slave which stores a value in IEEE754 format and a master was able to read that info. So should not be an arduino issue because it is an 8 bit MCU.
What could be a possible solution?

I'd need to study this a while in order to understand what you're asking. But it sounds very similar to something I'd answered previously. Have you read through this?

The using the function that I showed in that answer with your frequency values: modbus_16bit_register_pair_to_float(16967, 42972)) gives 49.914, which is a plausible line frequency. If that in fact answers your question it may make sense to mark this as a duplicate question.  modbus_16bit_register_pair_to_float(17260, 62322)) gives 236.951, plausible voltage value.

Also see this and this and this.

I think this should work. The first link you shared. Thanks a lot. Let me do some more testing and I will share my results soon.

This solution is working fine. Thanks a lot! @timemage


text:
Can't flash ESP8266 anymore (NodeMCU)
So I've been happily making away with these nodeMCU boards now for a while but I came across a strange issue when updating some code on my board.The problem was that I couldn't flash anymore with Arduino's IDE (OR the NodeFlasher tool)
The error I was getting in Arduino's IDE was:
warning: espcomm_send_command: didn't receive command response
warning: espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed

I tried flashing over all the memory with the flash tool but that didn't work, I also tried connecting D3 to 3.3v output, that did nothing. I've also tried holding the flash button down while flashing without any effect.

the flash button should be held down at power-up or reset to go into flashing mode at boot. it connects io 0 to ground (D3 is io 0). NodeMCU has circuit to control reset and reset to bootloader by the esptool. The esptool in IDE is different from the esptool.py (until 2.5.0 esp8266 arduino).

Thanks @Juraj , I tried to figure out the right way to "press" the flash button but a lot of things I read were misleading and said to hold until flash was complete.

I am afraid your answer to this question is misleading too. NodeMcu has pull-up resistor on io 0. The bootloader checks io 0 for LOW to start in flashing mode. I don't see a difference in plain wire to ground and a 220 Ohm resistor to ground.

It's entirely possible there isn't one but I hadn't seen anything telling me to do that, this is simply what worked and since it's not broken anymore, I can't test it. But with how many of these I'm running I'm sure it will happen again. I'll update the answer though since not everyone has a 220ohm resistor to try.

The fix ended up being to use a 220ohm resistor between D3 and GND (It has been pointed out, though I haven't tested it, that just wiring D3 to ground on startup should have the same effect). Then unplugging the USB cable, plugging it back in, then flashing the blink program to test. That got it going. I tried a 10kohm resistor too per some documentation I read but that didn't end up working. Wanted to post in case someone else stumbled on this issue.
Source
GitHub Issue
Helpful Articles:
ESP8266 bootloader modes
NodeMCU Pinout

NodeMcu has pull-up resistor on io 0. The bootloader checks io 0 for LOW to start in flashing mode. I don't see a difference in plain wire to ground and a 220 Ohm resistor to ground

Yep, 220ohm worked pretty well for me, thank you :)


text:
Power external daughter board from Arduino only powered by USB?
Been searching for an answer, but I see lots of talk about it, but not clear answers. Can somebody clarify this? If I power the Arduino only via USB, can I put a small daughter board? and power it from the Power connector(5V)
Update:
Thanks for the answers I'm using a Genuino UNO and it does power the daughter board my meter was kaputt, got a good one and it is fine even hooked a breadboard circuit to the 5V and GND and it works!!!

Probably the reason there is a lot of talk, but no clear answers, is that everyone has a different idea of what a "small" daughter board is; there is a limited power margin, and every LED, sensor or other add-on uses some power. The only true answer is "it depends on your specific situation".

Yes. USB is limited to 500mA, the Arduino like an Uno has a 500mA fuse to protect the USB source.
The Arduino itself can use 25-50mA of that, or more depending on what you have connected to the IO pins.

note that USB3 officially provides almost an amp, while most computers and virtually all mains-usb "chargers" provide more than 500ma. Both apple and samsung "wall worts" for example provide 2 amps.


text:
Arduino reading screen color from device (without light/color sensor)
I am a beginner working on a project in which I have purchased a device that can display 4 colors on the display (blue, green, yellow, or red). I would like the Arduino to read what color is on the display and depending on the color supply power to an attached motor. For example, if the screen is green supply power to the motor, if screen is yellow or red or blue do not supply power to the motor.
On the circuit board of the attached device there are clearly labelled wires connecting the LCD display to blue, green, and red LED solder points.
Is it possible to read the current going through these wires to determine what color would be displayed on the LCD display? If not, are there any other suggestions which could work?
As I mentioned earlier, I'm a complete beginner so anything would help. Thanks.

A rgb lcd display? as the one that adafruit has? https://www.adafruit.com/product/398

Do the colors you are interested in seem like an RGB LED backlight to the LCD?     Please add some pictures.  And can you measure the voltages at the RGB LED solder points when the colors of interest are happening?

The pics look fairly straightforward.  If the voltages while on and off are within the Arduino input limit range range, you should be able to read and decode them easily.   It might be as easy as configuring three digital input pins, and some code like lights = (digitalRead(D1) <<2) | (digitalRead(D2)<<1) | digitalRead(D3) ; switch(lights){ case 1: /* green */ .....

what is the device in the picture? ..... it has a UART port ..... perhaps you can use the serial port to ask it about the color


text:
Arduino Yun can no longer send to Dropbox
A long time ago I had set up an Arduino Yun to send files to Dropbox... I tried now and it ends in "killed" when trying to install the latest Dropbox Python module.
pip install (six, urllib3, etc etc) does work individually without running out of memory. Unfortunately when I install all but Dropbox, and then put the Dropbox module code folder in the current directory, it does start to import Dropbox with import dropbox but ends up with the KILLED message.
Is there a way I can connect to my current Dropbox without it using all of the 60mb of RAM and quitting... I keep getting the error with version 2.1:

Error.Cannot connect to Dropbox
  [400] u'v1_retired'

Have you configured any swap space on your Yun?

I'd eventually figured out how to do it running the latest Dropbox module installed into the sd card where there was room.


text:
DIY printer + Arduino. Can I use the position sensor? Multithreading?
I'm trying to make a computer-controlled painter/drawer/CNC, something like this, from an old junk printer that didn't work... I have got as far as a working motor shield that can move the sliding trolley back and forth by running the DC for a short amount of time, and running the stepper that would be "paper feed". But it is currently just some gears and roller.
1: Assuming I can attach the paper-feed gear to a platform to move it in both X and Y directions, is there still no way I can multithread Arduino code? Searching for this, I found results in some really old howtos/forums that say you cannot, but you can fake it by doing one thing then another. I would want a serial command to send the Arduino to say, "start 3mm right" and while doing so, run "3mm forward" for example for a diagonal line. I've only run this on commands that are run intermittently and can block while the command is running like so.
2: There is a clear "tape" with lines on it that goes through the sliding trolley and has a ribbon coming out of the sliding trolley that I assume is reference indicating that it is x mm away from the end, that lets the printer see how long to move. Would it be feasible to reverse-engineer this type of device to use in this custom application? Could this be done with an oscilloscope output connected to pins on the ribbon?

You should really study how Arduino-based 3d printer firmwares (most of which are open source) solve this problem.  The tape you are describing is an incremental encoder, so it will only give you position if you count all of the changes in moving from a start position determined by something else such as a limit switch.

You could also look into using Grbl, which is a CNC style controlling software.  That might be able to help you run your motors, as it would be working with generic g-code, rather than having to invent a language yourself.

You can multitask on arduino by doing stuff for one task for a bit and then do stuff for another task for a bit and switch back and forth like that.
However many arduino libs tend to rely on blocking calls and don't support giving control back to calling code so time spent in delay() calls can be used by other code.

Can it do IO threading? Or, with the way Serial.read() works blocking, would it be best to send a command like 'Left3 Forward4' and then run those at the same time with start motor1, start motor2, end motor2, end motor 1?

servo motor control is done using timed pin manipulation, serial communication auto fills a buffer that Serial.read() pulls out of. All of that can be done without ever blocking.

I recommend using the AccelStepper library (installable via the Library Manager) which will allow you to drive multiple stepper motors at once without blocking commands.

It's possible to multithread on an Arduino but it's a sophisticated operation that you don't actually need to do for this application. Better instead to call one motor move, then the next, in rapid succession in your main loop. The AccelStepper library sort of builds this in when you're using it for position-based control; you tell one motor where to move and then run motor.run() as often as possible in the loop to actually send the commands to your driver to move it. (You also tell the other other motor to move, and also run motortwo.run() just as often as motor.run() in the loop; neither command takes much time at all to run.) For precisely coordinated multi-motor moves, look at the MultiStepper example included in the library, but note that the sort of thing I'm describing, implemented in the similarly-named MultipleSteppers example, will do the trick for you.
Regarding that "clear tape," my suspicion is if you look close, you'll find it's got lots of very narrowly spaced black and clear bands. It is used to report position data back to the motor driver. It more than likely has a photointerruptor that reads its movement. You can read the speed (but not absolute position) of that tape by monitoring the clear and black sections moving through the photointerruptor. For higher precision of data, likely necessary because the tape will be moving relatively fast, you'll likely want to use an interrupt feature of the chip to watch the ticks as they go by, which is designed to take precedence over other would-be simultaneous operations the chip is doing.

Good luck with the project!


text:
Write to file in SD card in wave shield V3
I just started tinkering with Arduino. I'm curious to know though, is it possible to read and write to a file stored in the SD card in the Wave shield v3 by Elechouse? I'm able to play files stored in said SD card, but I don't know how I'd go about writing some logs. I'm using an Arduino Mega.
Thanks in advance.

No, you cannot.  The shield is basically a cheap WAV or AD4 (whatever THAT is) playing chip which loads the audio data direct from an (old, small) SD card.  The only control you have is IO pins that emulate pressing the buttons on an MP3 player.