text:
arduino circuit review/ safety review
I have the following circuit
It has a simple dc motor that is OFF, and switches ON once a day for 2 seconds.
I use MOSFET IRF540N as a switch
I use L7805CV as a voltage regulator
I would like to have a review and to ask whether it is safe to connect this circuit to a 9v 1A (center+) DC wall plug.
I have measured the dc motor and it takes 60 mA when it is on with 5V.

The "Arduino" part of your schematic looks OK. 9 VDC to VIN on the Uno is OK. Connecting the MOSFET directly to the Arduino is OK.
Personally, I would connect a 1000 ohm resistor in series between the Arduino pin and the gate of the MOSFET. If you like to live dangerously like I do, and change wiring connections with power supplied to your Arduino, then a 1k resistor will limit the maximum current flow to around 5 mA. This is not going to "fry" anything if you inadvertently connect an output to power or ground.
The question about the L7805CV is off-topic, but a quick look at the datasheet suggests an input and output capacitor should be used.
I’m sorry to be the bearer of bad news, but the IRF540N is a poor choice as a MOSFET to use with a micro-controller. While it’s true that you are only drawing 60 mA, the VGS specified for this MOSFET is at 10 VDC, not the 5 VDC supplied by the Uno. A "logic level" MOSFET would be better suited for your application.
For more information regarding MOSFETs, please read: How to control a 12V solenoid valve with a mosfet?

In general your circuit is fine, but the parts are pretty overpowered.
If there is a reasonable voltage drop at the IRF540N you better choose a mosfet with a lower gate-source threshold voltage, if it works I'd say it's fine.

You should not use a "naked" L7805CV. That voltage regulator requires a couple of capacitors in order to build a functioning voltage regulator out of it. You should be able to find instructions online for how to build one. Search on "L7805CV circuit" and you should find quite a few sample circuits.
That said, 9V is a good unregulated voltage to provide to the Vin line on the Arduino. Its built-in voltage regulator should be able to regulate that to 5V quite well, even with "bobble" caused by motor. (The built-in voltage regulator is able to handle input voltages from 7.5V to 12V, although if you feed it 12V and draw a lot of current out of the 5V line you may have overheating problems.)
You should also use a "logic level" MOSFET that can be driven with a 5V gate voltage.


text:
publish json data to mqtt
I am trying to publish JSON data to mqtt with following code snippet
#include <Arduino_JSON.h>
JSONVar data;
data["temperature"] = temperature;
data["humidity"] = humidity;
data["pressure"] = pressure;
data["chipId"] = chipId;

String jsonString = JSON.stringify(data);
client.publish("esp32/data", jsonString);

But getting following error
/home/ubuntu/Arduino/libraries/PubSubClient/src/PubSubClient.h:144:12: note:   candidate expects 4 arguments, 2 provided
Multiple libraries were found for "PubSubClient.h"
 Used: /home/ubuntu/Arduino/libraries/PubSubClient
Multiple libraries were found for "Wire.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/Wire
Multiple libraries were found for "Adafruit_BME280.h"
 Used: /home/ubuntu/Arduino/libraries/Adafruit_BME280_Library
Multiple libraries were found for "Adafruit_Sensor.h"
 Used: /home/ubuntu/Arduino/libraries/Adafruit_Unified_Sensor
Multiple libraries were found for "SPI.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/SPI
Multiple libraries were found for "Arduino_JSON.h"
 Used: /home/ubuntu/Arduino/libraries/Arduino_JSON
Multiple libraries were found for "WiFi.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
 Not used: /opt/arduino-1.8.10/libraries/WiFi
exit status 1
no matching function for call to 'PubSubClient::publish(const char [11], String&)'

Whats is wrong here ?

What's your last error message?
no matching function for call to 'PubSubClient::publish(const char [11], String&)'

Read the documentation for the publish() method in PubSubClient:

int publish (topic, payload)
Publishes a string message to the specified topic.
Parameters
topic - the topic to publish to (const char[])
payload - the message to publish (const char[])

Look at the parameters you're using. You're passing a String as payload. publish() expects payload to be a char[] (essentially the same thing as a char*) - a C language string. This is the error you're seeing.
Read the documentation for String. How do you get a char* from a String? The c_str() method.
You need to change
client.publish("esp32/data", jsonString);

to
client.publish("esp32/data", jsonString.c_str());

As for your other warnings, it looks like your Arduino libraries are a mess with multiple conflicting libraries installed; if you want to get rid of the warnings, clean up your libraries.

is it possible to convert json to char* ?

@roy - I've given you the steps to do that in the answer. If you want to do it more directly, you're using the Arduino_JSON library. The declaration for the stringily() method is at https://github.com/arduino-libraries/Arduino_JSON/blob/master/src/JSON.h and it only shows a String as a return, so you cannot do it more directly using this library.

Arduino_JSON has this link https://github.com/arduino-libraries/Arduino_JSON, not much info here. Most of the example are based on ArduinoJSON.

My comment answered your question - I may have been editing it when you were replying. You can find the answer in the declaration of stringify() injson.h

source: Stack Exchange

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

sort: votes


text:
Extend Pyduino over wireless network
I followed a guide to control my arduino uno using a python web server API (flask), and it works like a charm using the COM port on my PC. I would like to extend this over the network with an ESP8266 module so i can have a web server handling my project's event scheduling and hard work using python/html/css/js (anything supported/needed) and have the arduino as a client receiving the server data and acting accordingly. I am not limited to this method as it seems pretty hard to generalize over the network (Use a virtual COM port on the server side and forward the arduino using the router?//i  have to specify where the arduino port is located) so any other way to setup a Web server handling the event triggering and sending the ON/OFF information to my arduino (i just need to trigger a relay) is accepted.

There are many example how to set up a webserver on an Arduino using an ESP and also about doing this directly with an ESP (since most ESPs are more capable than most Arduinos). When you have a webserver running on the Arduino, sending information to it is nothing more than a web request. Have you looked into this? If yes, why is it not fitting for you?

I was thinking about using the arduino as a web client listening directly to my server and couldn't find exactly what i wanted but then i thought about what you said. I guess i can setup arduino/esp as a web server that handles requests and have another website that sends the requests when certain events are triggered.

I quickly searched for "arduino web request ESP" and found some promising sites. If think, you should look more into it. You write something about a virtual com port over wifi in your question, but honestly I think you would be going the hard way trying that. On a TCPIP network it is the easiest thing to simply do web requests.

I cant understand whats the best way to deal with my problem. Can i set up the arduino to constantly "listen" to a website for a specific event or do i have to use it as a server, port forward it and send the triggered events that way

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


text:
PIR Sensor Gives False High in 55 Minutes (Can't find a way to solve)
I have built a system to identify motions and fire alerts.
System can send a SMS in case if it's identify such alerts.
System consist of two parts,
Part 1: Armed and Disarmed using a PIN (Using Arduino Uno)
This Module Consists with 4*4 PIN PAD, I2C Module, 2 LEDs and Arduino UNO
This part works fine
Part 2: Sensor Systems and SMS System
This module consists of Arduino NANO, MQ135 Gas Sensor, PIR Sensor, SIM 800L Module, Tamper Switches
This part also works, but in every 55 minutes it generates a false motion alert and I could not troubleshoot the issue.
Schematics is attached.
Codes as Below,
Part 1: Test6-LCD_Intigrated_Working_Temper.ino
#include <Keypad.h>
#include<EEPROM.h>
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
char password[4];
char pass[4],pass1[4];
int i=0;
int k=0;
char customKey=0;
byte col = 0;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {

{'1','2','3','A'},

{'4','5','6','B'},

{'7','8','9','C'},

{'*','0','#','D'}

};

byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad

byte colPins[COLS] = {13, 12, 11, 10}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
void setup()
{
  lcd.begin();

  Serial.begin(9600);
  pinMode(4, INPUT);      // Tamper Signal
  pinMode(3, OUTPUT); //Armed
  pinMode(2, OUTPUT); //Disarmed

  lcd.setCursor(0, 0);
  lcd.print ("--SECURE ROOM!--");
  Serial.print("Server Room");
  lcd.setCursor(0, 1);
  lcd.print ("PLEASE ENTER PIN");
  Serial.print("\n*********Keypad Lock********* ");
  delay(2000);
  Serial.println("\n*********Enter Ur Passkey:*********");

  for(int j=0;j<4;j++)
    EEPROM.write(j, j+49);
  for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);
}

void Armed(){

  digitalWrite(3, HIGH);
  digitalWrite(2, LOW);
  Serial.println("\n***System is Armed***");
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("--SYSTEM ARMED--");
  lcd.setCursor(0, 1);
  lcd.print("-SENSORS ACTIVE-");
  delay (2000);
  lcd.noBacklight();
  i=0;
  customKey=0;

  }

void change()
{
  int j=0;
 lcd.backlight();
  Serial.println("\n*********UR Current Passk*********");
  lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("   CURRENT PIN   ");

  while(j<4)
  {
    char key=customKeypad.getKey();
    if(key)
    {
      pass1[j++]=key;

      Serial.print(key);
      lcd.setCursor(j+6, 1);
      lcd.print(key);

    }
    key=0;
  }
  delay(500);

  if((strncmp(pass1, pass, 4)))
  {

    Serial.println("\n*********Wrong Passkey*********");
    lcd.clear();
    lcd.setCursor(0, 0);
      lcd.print("  UNAUTHORIZED  ");

    Serial.println("\n*********UNAuthorized Access*********");
      lcd.setCursor(0, 1);
      lcd.print(" ACCESS  DENIED ");
    delay(10000);
  }
  else
  {
    j=0;

    Serial.println("\n*********Enter New Passk: *********");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" ENTER NEW PIN! ");

    while(j<4)
    {
      char key=customKeypad.getKey();
      if(key)
      {
        pass[j]=key;

        Serial.print("*");
        EEPROM.write(j,key);
        lcd.setCursor(j+6, 1);
        lcd.print(key);
        j++;

      }
    }

    Serial.println("*********Done*********");
    lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("----UPDATED!----");
    delay(1000);
  }

  Serial.println("\n*********Enter Ur Passk: *********");
  lcd.clear();

      lcd.setCursor(2, 0);
      lcd.print ("SECURE ROOM!");
      lcd.setCursor(0, 1);
      lcd.print ("PLEASE ENTER PIN");
      lcd.noBacklight();
  customKey=0;
}

void tamper(){
  Serial.println("\n***System is Tampered***");
  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print("--TAMPERED--");
  lcd.setCursor(0, 1);
  lcd.print("WARN COMPROMISED");
  delay (2000);
  lcd.backlight();
  i=0;
  customKey=0;

  }

void loop()
{
  Serial.println(digitalRead(4));
  customKey = customKeypad.getKey();
  if(customKey=='A')
    Armed();

    if(customKey=='C')
    change();
   /*
    if(digitalRead(4)==LOW)
    tamper();
 */
  if (customKey)
  {
    lcd.backlight();
    password[i++]=customKey;

    Serial.print("*");
    lcd.setCursor(0, 0);
    lcd.print("    PIN INPUT    ");
    lcd.setCursor(0,1);
    lcd.print("       ----     ") ;
    lcd.setCursor(i+6, 1);
    lcd.print("*");

      }

  if(i==4)
  {
    delay(200);
    for(int j=0;j<4;j++)
      pass[j]=EEPROM.read(j);
    if(!(strncmp(password, pass,4)))
    {

      Serial.println("\n*********Passkey Accepted*********");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("---AUTHORIZED---");
    lcd.setCursor(0, 1);
    lcd.print("SYSTEM  DISARMED");

      delay(1000);
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      i=0;

    }
    else
    {

      Serial.println("\n*********Access Denied*********");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("  UNAUTHORIZED  ");
      lcd.setCursor(0, 1);
      lcd.print(" ACCESS  DENIED ");

      delay (5000);

      Serial.println("\n*********Enter Passkey: *********");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print ("--SECURE ROOM!--");
      lcd.setCursor(0, 1);
      lcd.print ("PLEASE ENTER PIN");
      lcd.noBacklight();

      i=0;

    }
  }
}

Part 2: Test7_Tested_Tamper_Smoke_PIR_GSM.ino.ino
/*
    Arduino with PIR motion sensor and MQ 135 Smoke Detector with SMS Alert
    Developed By Vinod Amarathunga 18.09.2019
    DMS Electronics (Pvt) Ltd
*/

#include <SoftwareSerial.h>
SoftwareSerial mySerial(6, 5); //SIM800L Rx Tx
char msg;
String textMessage;

int smokeA0 = A0;            // MQ135 Analog Input
int led = 13;                // the pin that the LED is atteched to
int priState = LOW;             // by default, no motion detected
int TampSignal = 11;       // Tamper 5V Signal
int sensorThres = 150; //Smoke Air Quality Threshold
int pretamper = LOW;
bool premotion = false;
bool prefire = false;

void setup() {
  pinMode(led, OUTPUT);      // initalize LED as an output
  pinMode(3, INPUT);    // initialize sensor as an input
  pinMode(TampSignal, OUTPUT); // Tamper Drive Signal as Output
  pinMode(10, INPUT);    // Tamper Alert
  Serial.begin(9600);        // initialize serial
  mySerial.begin(9600);
}

void SmokeSMS()
{
  Serial.println("Warning!! Secure Room Fire Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+xx\"\r");
  delay(1000);
  mySerial.println("Warning!! Secure Room Fire Detected");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  delay(5000);

  Serial.println("Warning!! Secure Room Fire Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+xx2\"\r");
  delay(1000);
  mySerial.println("Warning!! Secure Room Fire Detected");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

}

void MotionSMS()
{
  Serial.println("Warning!! Secure Room Motion Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"xx\"\r");
  delay(1000);
  mySerial.println("PIN 3 HIGH");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  delay(5000);
/*
  Serial.println("Warning!! Secure Room Motion Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"xx2\"\r");
  delay(1000);
  mySerial.println("Warning!! Secure Room Motion Detected");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");
*/

}

void TamperSMS()
{

  Serial.println("Warning!! System Tamper Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"xx2\"\r");
  delay(1000);
  mySerial.println("Warning!! System Tamper Detected");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

  delay(5000);

  Serial.println("Warning!! System Tamper Detected");
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"xx\"\r");
  delay(1000);
  mySerial.println("Warning!! System Tamper Detected");
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  mySerial.println("AT+CMGD=2");

}

void loop() {
  int analogSensor = analogRead(smokeA0);
  digitalWrite(TampSignal, HIGH); // Drive Signal Always High
  //val = digitalRead(3);   // read sensor value
  //  ReceiveMessage(); //System Recive Messages
  //Serial.print("Smoke Level:");
  //Serial.println(analogSensor);
  Serial.println(digitalRead(3));
  if (analogSensor > sensorThres  ) {           // check if the sensor is HIGH and Armed Status
    digitalWrite(led, HIGH);   // turn LED ON
    Serial.print("\nSmoke Alert....!!!");
    SmokeSMS(); // Smoke SMS Alert
    delay(100);                // delay 100 milliseconds

  }

  else if ( priState == LOW && digitalRead(3) == HIGH && digitalRead(7) == HIGH ) {

    digitalWrite(led, HIGH);   // turn LED ON
    Serial.println("Motion detected!");
    MotionSMS(); //Motion SMS
    priState = HIGH; // Previous Motion Status set to High

    delay(15000);

  }

  else if ( digitalRead(7) == HIGH && digitalRead(10) == LOW )
  {

    digitalWrite(led, HIGH);   // turn LED ON and Temper Alarm On
    Serial.println("One of the TIP Switches being Trigered");
    if ( pretamper == LOW ) {
      TamperSMS(); // Tamper SMS
      pretamper  = HIGH;
      delay(15000);
    }

  }

  else {
    digitalWrite(led, LOW); // turn LED OFF
    digitalWrite(11, HIGH); // Tamper Signal
    delay(200);             // delay 200 milliseconds
    pretamper = LOW;
    //Serial.print("\n.....Normal.....");

    if (priState == HIGH) {
      Serial.println("Motion stopped!");
      priState = LOW;       // update variable state to LOW

    }
  }

}

I am loosing my mind because I could not find the problem of getting false alert in every 55 minutes.
I am very grateful any one can help.

I see nothing in the code that could cause a signal exactly every 55 minutes. -- Is it possible to detach the motion sensor from the NANO, to try out if the signal also appears stand alone. Eventually you attach the Data output of the sensor to a bi stable flip flop, that drives an LED. To find out if the motion detector triggers e.g a test signal every 55 minutes. You could also try to hide the sensor from ambient light. Perhaps there is a light source that flashes IR light every 55 minutes and interferes with the sensor in any way.

Hi @PeterPaulKiefer, Thanks. Actually there is no light emits in every 55 minute. I am testing it in a closed box. I am going to try it in a stand alone as suggested. But I am in a doubt hot to get the alert to inspect

If you still get no findings then, it would be helpful to see the Serial print outs of at least two different test runs. i.e power the alarm system wait 3 x 55 minutes (so the false trigger happens 3 times).  Switch the power off wait 30 minutes and do the same again. The output must contain timestamps.  That 55 minutes interval is really strange. I would be interesting if these are relative intervals or absolute time points, hence the second test run.

After tons of research found a way to solve this issue.
This is common for ordinary PIR sensors when we use the 5V out from Arduino.
Therefore we have to separate the power for PIR and the Arduino using a Opto Coupler and some transistors to smooth the signal.
Now the solution works fine.
I am posting here to help someone stuck with same issue.


text:
How do software interfaces compare to hardware interfaces in therms of speed and reliability?
The Arduino core includes numerous software interfaces mimicking the hardware interfaces provided by the chip and even extending beyond. My question is, if in a project I can either use software or hardware protocol, what would be the difference in stability, speed and versatility? Is there a reason why hardware interfaces are preferred? Because anyways the protocol is handled by the CPU or am I mistaking something?

the peripherals can work autonomous, involving the CPU over an interrupt only if needed. for example if you start a PWM the CPU is not involved in pulses generation. if you use external interrupt on pin, CPU is not involved in monitoring the pin.

In your question you ask about all communication interfaces in general, so the answer will be as general as your question.
Hardware interfaces should always be preferred to software interfaces, though there are situations, where it is a better or needed to use a software interface due to limited resources.

Because anyways the protocol is handled by the CPU

That is mostly wrong. The communication protocol is done by the hardware in most cases, if you use hardware interfaces. Serial (UART) for example automatically sends out the byte, that is placed in the hardware buffer, with the set configuration. It does not rely on any software for that. The same goes for SPI or I2C. The protocol of the interface is handled via hardware.
Though at least for Arduino Core/library users there is more to it, that get's handled automatically. Since the interface hardware is limited, the software have to take care of the resulting or needed data. For example: All the interfaces mentioned above use a 1 byte buffer for the data. The software must read or write this data, so that the hardware can work. If you don't read the byte of data, that was received by the Serial interface, it might get overwritten by the next byte. The hardware cannot provide a buffer, that is generally big enough, since the manufacturer cannot know, how long the transmissions will be. So the interfaces get a 1 byte buffer and the software has to do the rest. For this reason all the libraries use a bigger buffer in their software, that gets filled, when the hardware sends a corresponding interrupt.
So: Hardware interfaces implement the basic interface protocol (how the bits get transmitted) in hardware, thus the software only has to provide and read the byte data. The stability, speed and versatility is only determined by how the manufacturer build the hardware of that interface. This limit is clearly specified in the datasheet and does not change with the code.
For software interfaces, everything is done in software. This also involves monitoring and setting the corresponding pins with the correct timing. In the best case the software can utilize general hardware functions like a pin interrupt, but if it cannot do this, it has to constantly monitor (poll) the pins to receive something. Software interfaces are often called "bit banged", because the software manually pushes out each individual bit with the exact needed timing. That is a tedious task, which often blocks the execution of other code, since the timing often is critical. Especially the timing introduces limits, since doing things in software often involves many clock cycles more, than it could be done by dedicated hardware (consider all the code to poll a pin and the multiple if statements to react to specific situations). For example: When you write data with SoftwareSerial the call to the write function will block, because is manually pushes out bit after bit. Or with SPI: With hardware SPI you can go to incredible clock speeds in the MHz range. You won't every get near that with software, because the software simply cannot run this fast.
Note, that depending on the actual hardware of the used chip, a library may need to implement parts of the protocol in software. For example this is the case for using I2C on an ATtiny85, which does not have full I2C hardware support. Instead the USI (Universal Serial Interface) can be used to implement some functions of the protocol in hardware and the rest in software.
TL;DR

Hardware interfaces lift the heavy duty of handling the low level protocol (transmitting the bits by the needed standard) (which can be rather complex) from the software
The Software then only handles the byte data, not it's transmission
Translating complex protocols from dedicated hardware to software (bit banging the data through simple pins) imposes great limits on speed and reliability.

Using a hardware interface takes a lot of load from the CPU. Let's take an asynchronous serial interface for example.
With the UART built-in hardware you'll get parallel-serial conversion and back done in hardware. The CPU "just" needs to store the data to be sent in a register. The receiving part is handled completely by the hardware and the CPU "just" needs to look at the "received" flag before reading the data. Or it sets up an interrupt as callback.
If you use a software interface the CPU needs to convert the parallel data to serial with several instructions and, really important, needs to maintain a certain timing. For receiving this might be even harder because of the asynchronous nature of the protocol. A timer might be usable to clock the communication, for example by an interrupt, but this puts a lot of load on the CPU. Certain conditions might make this usage impossible, too.
Now you might think about the issues you mentioned:
Stability: If done correctly both approaches are equally stable, meant as reliable function. If you have more tasks to be done you might not be able to meet the requirements. This comes "earlier" with software interfaces than with hardware interfaces due to the higher load.
Speed: Hardware interfaces can be faster than software interfaces because the hardware is commonly clocked faster than what is possible by software which needs multiple instructions for one step. But speed is always a relative issue. There are libraries implementing USB1.1 via software, and the USB1.1 protocol is both fast and really complex.
Versatility: Software interfaces are more versatile because hardware interfaces are limited in their capabilities. If a hardware interface can't do what you need there is no way to make it do this. Software can do "anything" as long as the CPU has enough time and resources for this.
Hardware interfaces are preferred because they are simpler to use and commonly don't put hard requirements on your software architecture.

Re “Stability”: Note that software interfaces sometimes cut corners to simplify the implementation. A software UART will typically take a single sample of RX per bit, whereas the hardware UART would take at least three samples and do a majority vote. It is also not uncommon for a software UART to not check the stop bit, and for a software I2C to not support clock stretching. A hardware port also tends to deliver more consistent timings than a software one.

@EdgarBonet That's what I meant by "If done correctly..." ;-) A hardware UART might start the reception on the leading edge of the start bit, or use a clock of in example 16x. This may be realized in software by edge interrupts and a highly clocked timer interrupt, which is not purely software to be honest.


text:
Does a pulldown resistor use less battery power than a pullup resistor?
I am designing a circuit connected to a simple open-close sensor, like a switch. For ease of construction, the circuit with the sensor switch closes to ground, and uses a 1 MΩ pullup resistor to Vcc to signal HIGH when the switch is open.
I realize that power is flowing the entire time the switch is open, which may (or may not) drain the battery. Would it be more efficient to use a pulldown resistor to ground, and have the switch open to Vcc?
Tangentially, should there be a resistor on the connection to Vcc as well? Either to reduce current (save battery power) or prevent damage to the ATmega328?
Thank you!

The input current does not depend on the pin level. Have a look at this discussion from avrfreaks. The input impedance of a digital pin is extremely high. The leakage current of the Atmega328P (here as example chip) is mentioned to be 1uA for both pin states. So this current is both unavoidable and neglectable from a normal view.
But the input impedance of a digital input pin is not only dependent on this leakage current. There is also a capacitance, which will lower the impedance for higher frequencies. So, if you drive the input with higher frequencies, the input will draw more current. But you only have a switch connected to it, which is very very low frequency.
So it doesn't matter, if you pullup or pulldown. The main current consumption will result from the moments, where the switch is activated, since then a current flows through the pullup/pulldown resistor to ground.

Tangentially, should there be a resistor on the connection to Vcc as well?

No need for a resistor there. The input impedance of the pin is already high enough and you don't want to create a voltage divider with your pulldown resistor (which would change the voltage levels at the pin).

A pullup or pulldown resistor causes a current flow additionally to the neglectable current into a input pin. and the voltage level matters, of course.

The additional current only flows, if the switch is activated, so with a pullup resistor, when the switch connects the pin to ground. Otherwise you have the pullup resistance plus the input impedance in series, which is also very neglectable. Normally the pullup resistor for a switch is big enough, so that the current is also neglectable.

I realize that power is flowing the entire time the switch is open, which may (or may not) drain the battery.

No, it doesn't. You get a small spike as the switch is opened or closed, as the gate capacitance is charged or discharged, but other than that there is negligible current draw by a pin, which remains static regardless of the direction of the biasing resistor.

Tangentially, should there be a resistor on the connection to Vcc as well? Either to reduce current (save battery power) or prevent damage to the ATmega328?

Absolutely not.  The current draw of the MCU is not static. That means that the current through such a resistor would not be static, and so the voltage dropped across that resistor would fluctuate too - meaning if the current draw rises above a certain point the chip will be starved of power and will "brown out".
You only need a resistor to limit current when you have a device that cannot control the current by itself, such as an LED or other "non-linear" device.

Thank you. Does this mean that the Pushbutton tutorial on the official Arduino site is wrong in having a resistor between Vcc and the input pin?

@dotancohen No, because that is a pullup resistor. You are on about a resistor between the power supply and the VCC pin (I assume), which is completely different to what that tutorial has.

Ah, I see where the confusion is. When I said "on the connection to Vcc" I was referring to the connection between the input pin and Vcc. I was not referring to the power to the ATmega 328. How should I reword that so that it is clear? Thank you very much for your help, both in teaching the proper wiring and in helping improve my question phrasing.

I am not really sure what you are asking in that question now. If you have a pullup resistor then you have a pullup resistor. If you have a pulldown resistor then you have a pulldown resistor. What actually are you asking about when you ask about a resistor to vcc? That is a pullup resistor. If you have one then you have one. What are you asking "As well?"...?

If the sensor does provide two defined voltage levels, you do not need a pullup or pulldown resistor, but if it's only a switch: either (closed) connected to Vcc or GND, or (open) not connected, you need a pullup or pulldown resistor to get a defined voltage level in case there's "nothing else" (except the wire to the switch catching noise out of the air) connected to the digital input pin.
When the switch is open, the pullup/pulldown resistor is connected to the input pin and nothing but that neglectable leakage current is flowing.
When that switch is closed, some current will flow through that resistor, according to Ohm's law. You have to optimize between that current and the risk of catching some noise signal. Typically, µControllers like the Arduino atmel atmega328p have builtin pullup resistors of ~30k..50k, which should be fine for standard situations.
If you fear the battery drain, you can experiment with bigger resistors, but first make sure to build a scenario where the usual situation is "switch open". e.g. A fridge's door switch should be NC, but pressed while the door is closed.  :)


text:
Reading from an oven humidity sensor
I have been trying to solve the problem of humidity sensors in a harsh environment (BBQ/Pizza Oven) and I came across this:
enter link description here
But I don't see any documentation on how to connect such a sensor to an arduino.
Are there any examples of how to integrate this?

I doubt you'll find a documentation, because it is a spare part for a microwave oven. I also think, it can not be used in hot environment. The air in an microwave oven is cold compared to a pizza oven ;-). The isolation of the inner wires could melt away and you have a short circuit. I don't know if the sensor itself (without the wires)  is made for hot environments. I haven't found any specification too. As I have written, its a spare part and used to replace defect ones in a microwave oven. See https://www.youtube.com/watch?v=akQ8zCFk_VY .

The title also say is a "Microwave Humidity Gas Steam Temp Sensor". I would interpret that, as if it can measure the temperature of the humidity gas (i.e the vaporized water).  But perhaps I'm wrong.

In general, it's always better to try something first - then ask here. I think what you are asking for is difficult as humidity detection at pizza / baking temperatures 400+ F are likely not kind to COTS humidity sensors. My guess, humidity control is empirically arrived at using the ambient room temperature & humidity and the oven's current temperature plus the amount of water squirted into the oven plus the water content of the food. If you want, you could start looking for academic papers like this one.


text:
How to increase the range to IR transistor receiver
I have a Arduino project which controls LED using IR Receiver and Transistor.The circuits works fine,But the problem is the LED is Blinking Brightly  only for short range basically between 5-8 cm,but when i used my TV remote it works at for very long range(above 1 m).I have tried giving high voltage to IR Transistor,but no use.
Please help to solve this problem!!
Thanks in Advance!

Are you just using digitalWrite() to turn the LED on and off, or are you modulating it with a carrier frequency?

What is it you are trying to achieve? It might be better to use a IR receiver instead of an IR phototransitor.

@Majenko iam using just digitalWrite() to turn LED ON and OFF

Please add your circuit and your code to the question

@chrisl iam just using the arduino to turn IR Transistor on and off

An IR transistor does not (is not build to) emit IR light, it detects it. So why are you turning it on and off? For emitting IR light you should use IR LEDs

The reason your TV remote can work over a much longer distance is because it doesn't just turn an LED on and off.
Instead it turns the LED on and off really fast, and then turns that "turning on and off" on and off as well.
In technical terms: the light is modulated with a carrier frequency.  Just the same as a radio signal is modulated with a carrier frequency, you can do the same with light.
The receiver then samples the light falling on it over time and passes it through a band pass filter to remove any frequencies in the changes of light intensity that aren't within the frequency of the carrier signal.  What is left is then low-pass filtered to recover the overall "on-off" signal that is being transmitted.
Much of that is hard to do using an Arduino, so an IR receiver is used which integrates all the filtering and recovery of the signal. These are sold with different frequency sensitivities, and if you then turn an IR LED on and off at that stated frequency it will be able to "see" it far more efficiently than just having a light on or off.
There is a library for the Arduino that can handle the modulating of the LED at the right frequency for your chosen IR receiver.

thanks for the help


text:
Temperature anomaly on BS18B20 + NodeMCU on Tingspeak
Temperature drops occasionally from 59+C to -13C or to other random values. Used sketch and info from this site:
http://internetofthinking.blogspot.com/2016/02/upload-ds18b20-temperature-sensor-data.html
NodeMCU powered by phone charger 5v 1a via microUSB.
Placing 4.7 kOm resistor between data wire and 3v3 didn't help me.
Does anyone know how to solve this issue? Like filtering results and pushing to server only values that do not differ by more than n*C, or something like that?
Here is the sketch
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define myPeriodic 15 //in sec | Thingspeak pub is 15sec
#define ONE_WIRE_BUS 2  // DS18B20 on arduino pin2 corresponds to D4 on physical board

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float prevTemp = 0;
const char* server = "api.thingspeak.com";
String apiKey ="-";
const char* MY_SSID = "-";
const char* MY_PWD = "-";
int sent = 0;
void setup() {
  Serial.begin(115200);
  connectWifi();
}

void loop() {
  float temp;
  //char buffer[10];
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0)+5;
  //String tempC = dtostrf(temp, 4, 1, buffer);//handled in sendTemp()
  Serial.print(String(sent)+" Temperature: ");
  Serial.println(temp);

  //if (temp != prevTemp)
  //{
  //sendTeperatureTS(temp);
  //prevTemp = temp;
  //}

  sendTeperatureTS(temp);
  int count = myPeriodic;
  while(count--)
  delay(1000);
}

void connectWifi()
{
  Serial.print("Connecting to "+*MY_SSID);
  WiFi.begin(MY_SSID, MY_PWD);
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }

  Serial.println("");
  Serial.println("Connected");
  Serial.println("");
}//end connect

void sendTeperatureTS(float temp)
{
   WiFiClient client;

   if (client.connect(server, 80)) { // use ip 184.106.153.149 or api.thingspeak.com
   Serial.println("WiFi Client connected ");

   String postStr = apiKey;
   postStr += "&field1=";
   postStr += String(temp);
   postStr += "\r\n\r\n";

   client.print("POST /update HTTP/1.1\n");
   client.print("Host: api.thingspeak.com\n");
   client.print("Connection: close\n");
   client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
   client.print("Content-Type: application/x-www-form-urlencoded\n");
   client.print("Content-Length: ");
   client.print(postStr.length());
   client.print("\n\n");
   client.print(postStr);
   delay(1000);

   }//end if
   sent++;
 client.stop();
}//end send

measure several times ... ignore max and min readings

Have you checked the device's Scratchpad CRC

Idk how to.

How is your device hooked up (diagram)

Device is hooked up in normal mode, right like in this pic

DS18b20 (waterproof) is located on top of the boiler in a special pit for measuring temperatures, there are definitely no any sort of microwaves here, and the temp is not higher than 80C.
I'll try today to change the power supply, just in case, and later switch the sensor into parasite mode.

Discarding (potentially) bogus readings could help as a last resort, but something's going on to cause those bogus readings. You'd be better off finding and fixing that than finding a work-around.
These are pretty stable devices and you shouldn't see more than a couple of LSB (a few 1/4 degC). I'm inclined to suggest noise pickup on the one-wire bus but the bogus samples in your photo look identical. I have a >15' parasitic one-wire bus, just a twisted pair with no shield, and a DS18b20 close to the MCU and another out at the end. I do smooth the input but no de-spiking.
Have you checked the device's Scratchpad CRC between converting and reading the temperature? How is your device hooked up (diagram)? Is it in parasitic mode?


text:
display pixel data on serial monitor using ov7670
i am trying to get the image data pixel by pixel from ov7670 to serial monitor and to store it into arduino memory which i can access later. i am using arduino mega and the camera is configured to 160x120 resolution. Any suggestions or code from which i can get help from?

In what way do you want to display "pixel data" on the serial monitor? And what does the serial monitor have to do with storing the data in RAM?

storing pixel data as a 2 dimensional array.

And what does that have to do with the serial monitor?

nothing. i just want to see what and how data is being sent

You are aware that at 24bpp the image will require about 7x more memory than the Arduino Mega has?  And at 8bpp it will need about 2.5x as much memory as the Mega2560 has? Where were you thinking of storing the image?

reducing the resolution to 160x120 and using 8bpp will require 19KB which is way less than memory of mega

No it isn't. The mega has 8kb. Thats much less than 19kb...


text:
arduino & drivers to control 5 brushed CIM motors independently?
i am a complete newbie in electronics but i'm a bit familiar with C.
i am building a machine that requires 5 little engines (12V 2.5in brushed CIM motors) & motor drivers (i need to adjust each motor's speed).
i've got an arduino UNO which i think is too small to control that many motors.
i would like to know if the setup i want was feasible to your opinion and which ardunio would i need to do that ?
i guess an Arduino Mega ?
also, i came accross this tutorial : https://howtomechatronics.com/tutorials/arduino/arduino-dc-motor-control-tutorial-l298n-pwm-h-bridge/
it explains how to configure an arduino with a driver & two motors.
in fact i want to prepare the same kind of thing but with 5 motors that i can control independently.
which hardware would you recommend to do such a thing please ?
many thanks !
regards

Yes, with an UNO and a few of those L298 modules you should be able to control 5 motors independently, no problems.  Try the tutorial you gave the URL for and you'll see how to use more than 1 motor driver.

thanks. However i see that these drivers can control 2 engines, so i would need three of them. can i connect all three on a UNO ? will i have enough ports etc. ?
also, isnt there a better solution (like having 1 driver that can control up to 5 engines ?)

You should have just enough I/O with UNO, so long as you don't want to connect any other hardware/sensors.  Since this is unlikely, it would be better to use another board like Mega, but I'll provide solutions anyway in case you want to try them out:

Option 1:  For 5 motors controlled with L298N boards you'll need 15 output pins, 5 of which should be PWM.  Fortunately, there are 5 PWM outputs on the Arduino UNO on PORTB and PORTD.  The remaining 10 outputs need only be digital (PORTB has 1 and PORTD has 5).  You can use DDRC and PORTC commands to change function of the analog inputs labeled A0-A5, making them digital output, thereby gaining 6 more digital output pins for a total of 12 (more than the minimum 10 needed).
Option 2:  It is possible to use other PWM motor drivers that reduce number of pins required.  Examples are DRV8838 (link to supplier) and DRV8833 (link to supplier) where 2 wires are needed per motor channel.  As a bonus, these drivers are also significantly more compact than L298N.


text:
Stuck in a loop when reading from EEPROM, works if I clear it first
EDIT: The problem was caused by storing a pointer in the EEPROM. Thanks to @KIIV for helping out
Sorry for the enormous of wall of text, I'm trying to pare it down a bit.
I have two Arduino Megas that are misbehaving. Both boards produce identical output, so I'm certain it's not a hardware issue.
I'm trying to store user configuration data on the EEPROM and load it when the arduino boots. I have an object which contains flags for user settings like baud rates and serial port modes.
During void setup(), it fails to load the config from the EEPROM. It gets stuck looping through a few functions, even though those functions are not loops at all.(more details below)
However if I clear the EEPROM during void setup(), I can then save and load configurations later on, using menus invoked by the user during void main(). This works flawlessly. I'm calling the same load function in both cases, it just causes the arduino to shit itself if I call it during setup().
Here is a condensed version of my code:
struct UserCfg {/* config options */}

void ConfigController::load_eeprom_cfg()
{
    Serial3.println("loading from eeprom");
    EEPROM.get(gp::config_address, UserCfg);
}

void ConfigController::write_user_config()
{
    Serial3.println("writing user config to eeprom");
    EEPROM.put(gp::config_address, UserCfg);
}

void ConfigController::apply_user_config()
{
    /* other serial ports omitted */
    Serial3.begin(UserCfg.serial_cfg_3.ser_speed, UserCfg.serial_cfg_3.ser_mode);
    Serial3.write("serial 3 up\n\r");

    // Allows users to set the admin terminal to any serial port
    Admin_Serial = UserCfg.admin_serial_port;
    Admin_Serial->write("Admin terminal up on this port\n\r");
}

/// checks and loads config at system boot
void ConfigController::startup()
{
    Serial3.begin(9600);
    Serial3.println("loading...");

    load_eeprom_cfg(); //<----- Not working when called here.

    // prevents loading non-existent config. Not robust, but it works for now.
    if (UserCfg.admin_port_str == nullptr)
    {
        Serial3.println("No valid config found. Using defaults.");
        write_default_cfg();    // puts hard coded defaults in the EEPROM.
        load_eeprom_cfg();      // works just fine when called here
    }
    Serial3.println("Applying...");

    apply_user_config(); //<----- Also not working when called here.
}

// Main code:

void setup()
{
    // erase_EEPROM() is is copied from the official arduino tutorial.
    ConfigController.erase_EEPROM();     // If I comment this line out, it breaks.
    ConfigController.startup();
    Serial3.print("startup done");
}

If I remove the call to erase_EEPROM from void setup(), the arduino gets stuck in a loop:
loading...
loading from eeprom
Applying...
serial 3 up

Those lines just repeat over and over.
However, when I call it exactly as you see above in void setup(), it works perfectly. The EEPROM is erased, the IF statement in ConfigController::startup() catches the bogus value, and writes the default config to the EEPROM. Once it's done, it reads it back from the EEPROM into the UserCfg, which is displayed in the menus. I can then save / load values to my hearts content from the menu like this:
write_user_config();
load_eeprom_cfg();
apply_user_config();

or for loading defaults:
write_default_cfg();
load_eeprom_cfg();
apply_user_config();
print_menu_prompt();  // This includes values from UserCfg, so I can confirm that changes are saved and then loaded.

I fail to see a functional difference between calling load_eeprom() during void setup(), vs calling it during void main(). It's the exact same function that put the value in the EEPROM to begin with.
Any help?

My guess it isn't looping at all, it resets whole mcu, or calling that Admin_serial->write with invalid pointer jumps somewhere near to reset vector. Definitely not good idea to call some variable exactly the same as type (=> UserCfg)

Earlier I tried adding in a bunch of null pointer checks to Admin_Serial, like this:
if(Admin_Serial == nullptr) Serial3.print("bad pointer to ser3");
No dice. If the pointer is bad, it is at least not null.

It doesn't have to be nullptr. It can be anything

Of course! I should add a check to see if it's equal to Serial, Serial1, Serial2, or Serial3.

You've gotten me thinking about something. I'm storing a pointer in the EEPROM. That seems like a really bad idea. I cannot imagine there being any guarantee whatsoever that a pointer will be at the same memory address every time.
Even if this is not the cause of the problem, I should probalby switch to storing an enum value, and using that to set the serial pointer when I load the settings.

I'd go for port nuber instead and getting pointer in each run. You can get different pointers if you upload changed code.

Btw, you skipped that UserCfg definition and it might be much faster to figure it out you are storing pointers.


text:
buiReliable time in ISR
I'm using a Nano. The code below is a simplified workup of my problem code.
The point of it is asynchronous debounced button press detection. The actual code sets a volatile bool to tell the main loop it saw a press, but this simplified version toggles the state of the built-in LED. Another LED follows the state of the pushbutton to make it possible to see whether the ISR is firing appropriately.
#define SHORT_PRESS_MS 50
#define PUSHBUTTON_PIN 2
#define BUILTIN_LED_PIN 13
#define OTHER_LED_PIN 12
volatile unsigned long fallTime = 0;
volatile int builtinLedState = LOW;
void isr_change()
{
    unsigned long now = millis();
    int pushbuttonState = digitalRead(PUSHBUTTON_PIN);
    // show switch state with LED and 120 Ohms on D12
    digitalWrite(OTHER_LED_PIN, pushbuttonState);
    if ((pushbuttonState == LOW) || (fallTime == 0))
    { // change to low => falling edge
        fallTime = now;
    }
    if (pushbuttonState == HIGH)
    { // change to high => rising edge
        long pressMs = now - fallTime;
        if (pressMs > SHORT_PRESS_MS)
        {
            builtinLedState = !builtinLedState;
            digitalWrite(BUILTIN_LED_PIN, builtinLedState);
        }
    }
}
void setup()
{
    pinMode(PUSHBUTTON_PIN, INPUT_PULLUP);
    pinMode(BUILTIN_LED_PIN, OUTPUT);
    pinMode(OTHER_LED_PIN, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(PUSHBUTTON_PIN), isr_change, CHANGE);
}
void loop() {}

When this runs, OTHER_LED slavishly follows the button. There is no perceptible lag and it never gets out of synch no matter how machine-gun my antics with the button.
However, toggling of the built-in LED is not reliable. That OTHER_LED remains in sync with the button state implies that the event is always firing and the state is always what I expect, so it seems like there is a problem with my attempt to measure time.
What is the right way to measure time inside an ISR?

Applying suggested diagnostics confirmed the hypothesis of the accepted answer. Having determined the nature of the problem, I rewrote the ISR as follows.
void isr_change()
{
    static long fallTime = 0;
    static int lastPushbuttonState;
    int pushbuttonState = digitalRead(PUSHBUTTON_PIN);
    if (lastPushbuttonState != pushbuttonState)
    {
        long now = millis();
        if (pushbuttonState == LOW)
        { // change to low => falling edge
            fallTime = now;
        }
        if (pushbuttonState == HIGH)
        { // change to high => rising edge
            long pressMs = now - fallTime;
            if (pressMs > SHORT_PRESS_MS)
            {
                digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
            }
        }
    }
}

Testing reveals that the problem is resolved and the intended behaviour is occurring (reliably detect presses of minimum duration).
Also of interest is the use of static to carry values between ISR invocations with local scope, rather than using global volatile variables.

but you alternate the state of the LED. how should it be in sync with the other LED? and there could be more fast changes (bounce) which you can't see on other LED

The onboard LED toggles with every press. The other LED illuminates while the button is pressed and does not when it isn't. It's in sync with the button. To address your valid concern about bounce I will count both rising and falling edges and illuminate only when they are equal.

It's bound to CHANGE. It fires when it goes LOW (button press) and it fires again when it goes HIGH (release button). I read the button state and write it to the OTHER_LED.

I cannot make sense of this:
if ((pushbuttonState == LOW) || (fallTime == 0))

Why || (fallTime == 0)? Other than this, your ISR looks fine to me.
And your way of measuring the time is correct. The only scenario I can
imagine that can make the toggling unreliable is the ISR missing
transitions, which can happen if the input pin gives very short spikes.
Here is my scenario:
The button is pressed, fallTime holds the correct value, you release
the button. At this point, the bouncing button generates a very short
positive pulse: LOW → HIGH → LOW. The first transition triggers an
interrupt request. However, there is some latency in handling the
request. By the time the ISR starts running, the pin has already toggled
back to LOW, and the ISR then incorrectly updates fallTime.
A little bit later, the pin toggles back to HIGH for good. However,
now is very close to fallTime, and the rising edge gets ignored.
You can check whether you have missed transitions by toggling the LED
every time you see the same state as in the previous ISR run:
void isr_change()
{
    static uint8_t previous_pin_state;
    uint8_t pin_state = digitalRead(PUSHBUTTON_PIN);
    if (pin_state == previous_pin_state)
        digitalWrite(LED_BUILTIN, !digiatlRead(LED_BUILTIN));
    previous_pin_state = pin_state;
}

|| (fallTime == 0) is in case the first thing it sees is a rising edge. I'm about to try your diagnostic suggestion.

I took it out because in the larger program that needs this there is deferred initialisation anyway so I can discard any pending press at that stage.

I confirm your hypothesis. I guess I should skip handling when there's no change of direction.

you toggle the state of the main LED on CHANGE to HIGH. how should it be in sync with the other LED? and there could be more fast changes (bounce) which human eye can't see on LED
result of the sketch:

The LEDs are not intended to be in sync with each other. I never said they were. One toggles to indicate recognition of a pulse of the desired minimum duration, the other follows the button state to provide visual feedback showing that the ISR is responding to button activity.

@PeterWone, there are bounce toggles of LED, which you can't see on other LED. so you never know the right state of LED


text:
Receive whole string in serial sending data?
I connect my NodeMCU to Arduino Uno. The goal is to receive the whole string for example "12", every 1 sec.
This is my code on Arduino Uno side ( the sender)
int mock = 0;

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

void loop() {
    //Write mock to NodeMCU
    s.print((int)mock,DEC);
    s.println();

    mock++;
    delay(1000);
}

On NodeMCU side ( the receiver)
 char data; //Initialized variable to store recieved data
 String line;
 void setup() {
   Serial.begin(115200);
   s.begin(115200);
   while (!Serial) {
    ;
  }
}

void loop() {

    if( s.available() >= 2) {
        for (int i = 0; i< 2; i++ ) {
            data = s.read();
            line += data;
        }
        delay(1000);
    }

    Serial.print(line);

}

But the result on the serial panel is not what I expected

How can I make it so that I can receive something like
12
(wait one sec)
13
(wait one sec)
....

Node MCU just prints the whole thing, I can't delay it.

I don't see you printing what you have read. Also line is not defined in your code. Please provide a full minimal example

@chrisl Sorry i forgot to include the variable's declaration. I plan to use "line" to store all data that received and then print it to the console.

in your nodemcu use
void loop() {
    if(s.readBytesUntil('\n',data ,2)>0)
      Serial.println(data);
    delay(1000);
}

Serial.readBytesUntil(character, buffer, length)

Serial.readBytesUntil() reads characters from the serial buffer into an array. The function terminates (checks being done in this order) if the determined length has been read, if it times out , or if the terminator character is detected (in which case the function returns the characters up to the last character before the supplied terminator). The terminator itself is not returned in the buffer.
Serial.readBytesUntil() returns the number of characters read into the buffer. 0 means that the length parameter <= 0, a time out occurred before any other input, or a termination character was found before any other input.

readBytesUntil waits a second for the data. it is better to wait for the first character with Serial.available(). and you don't handle \r

yeah he is going to print it in console \r\r means twice return to beginning of line no diffrence in result
if he wants a better approach he needs to define two bytes or more  header and a checksum then define a constant size packet so he can reach a better solution with even faster speed beside I would change sender s.print((int)mock,DEC);
s.println(); to s.print((int)mock,DEC);
s.print('\n')

If you send "12" you send 4 characters/bytes: '1', '2' and a new line which is two characters:  ('\r', '\n').
On the receiver side you check for two characters (not the new line), so you should take it into account.
Actually, since you will eventually reach "100" you will receive 5 characters ('1', '0', '0', '\r', \'n').
So it is better to change the receiver side to store the bytes in line UNTIL a new line is received (than you can support values of any length).
Also remove the delay on the receiver side, or at least decrease it a lot, because it doesn't matter to check (too) often. if there is no byte available, it will check again. Now it can happen at time 1001 ms a byte would be received, but at time 1000 ms it is checked and it will not be checked again until time 2000 ms.

println() is \r\n

@Juraj Thanks (I should have known).


text:
Completing an action on button release help with delaying to give other modules time to repond
I'm currently having problems with my code it has several modules within the main one is my current keypad one working of a mcp23017. what I needed it to do is count how long a key is pressed and upon button release it sets that variable so other modules can read it and complete an action they are required to do for example a seven segment to display a number. However, as you will see currently in cases 1 - 12 as soon as the button has been released it sets the varaible back to notPRESSED.
Code below:
{ // module keypad

  switch (module_keypad_i) {

    case 0:

      setRow(0); // Pull row 0 Low

      if (!(ColumnNum & B00000100)) { // 1 detected
        keypadDebounceTime = millis();
        module_keypad_i = 1;
        break;
      }

      if (!(ColumnNum & B00000010)) { // 2 detected
        keypadDebounceTime = millis();
        module_keypad_i = 2;
        break;
      }

      if (!(ColumnNum & B00000001)) { // 3 detected
        keypadDebounceTime = millis();
        module_keypad_i = 3;
        break;
      }

      rowSet(1); // Pull row 1 Low

      if (!(nColumnNum & B00000100)) { // 4 detected
        keypadDebounceTime = millis();
        module_keypad_i = 4;
        break;
      }

      if (!(ColumnNum & B00000010)) { // 5 detected
        keypadDebounceTime = millis();
        module_keypad_i = 5;
        break;
      }

      if (!(ColumnNum & B00000001)) { // 6 detected
        keypadDebounceTime = millis();
        module_keypad_i = 6;
        break;
      }

      setRow(2); // Pull row 2 Low

      if (!(ColumnNum & B00000100)) { // 7 detected
        keypadDebounceTime = millis();
        module_keypad_i = 7;
        break;
      }

      if (!(ColumnNum & B00000010)) { // 8 detected
        keypadDebounceTime = millis();
        module_keypad_i = 8;
        break;
      }

      if (!(ColumnNum & B00000001)) { // 9 detected
        keypadDebounceTime = millis();
        module_keypad_i = 9;
        break;
      }

      setRow(3); // Pull row 3 Low

      if (!(ColumnNum & B00000100)) { // * detected
        keypadDebounceTime = millis();
        module_keypad_i = 10;
        break;
      }

      if (!(ColumnNum & B00000010)) { // 0 detected
        keypadDebounceTime = millis();
        module_keypad_i = 11;
        break;
      }

      if (!(ColumnNum & B00000001)) { // # detected
        keypadDebounceTime = millis();
        module_keypad_i = 12;
        break;
      }

      else lcd.setCursor(0, 1);
      break;

    case 1: // Read button 1 press
      key = 1;
      Keypad_Debounce_Time(0);
      setRow(0);

      if (ColumnNum & B00000100) {
        //keypad_state = notPRESSED;
        //Serial.println(keypad_state);
        keypadStatus[0] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 2: // Read button 2 press
      key = 2;
      Keypad_Debounce_Time(1);
      setRow(0);

      if (ColumnNum & B00000010) {
        keypadStatus[1] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 3: // Read button 3 press
      key = 3;
      Keypad_Debounce_Time(2);
      setRow(0);

      if (ColumnNum & B00000001) {
        keypadStatus[2] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 4: // Read button 4 press
      key = 4;
      Keypad_Debounce_Time(3);
      setRow(1);

      if (ColumnNum & B00000100) {
        keypadStatus[3] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 5: // Read button 5 press
      key = 5;
      Keypad_Debounce_Time(4);
      setRow(1);

      if (ColumnNum & B00000010) {
        keypadStatus[4] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 6: // Read button 6 press
      key = 6;
      Keypad_Debounce_Time(5);
      setRow(1);

      if (ColumnNum & B00000001) {
        keypadStatus[5] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 7: // Read button 7 press
      key = 7;
      Keypad_Debounce_Time(6);
      setRow(2);

      if (ColumnNum & B00000100) {
        keypadStatus[6] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 8: // Read button 8 press
      key = 8;
      Keypad_Debounce_Time(7);
      setRow(2);

      if (ColumnNum & B00000010) {
        keypadStatus[7] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 9: // Read button 9 press
      key = 9;
      Keypad_Debounce_Time(8);
      setRow(2);

      if (ColumnNum & B00000001) {
        keypadStatus[8] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 10: // Read button * press
      Keypad_Debounce_Time(9);
      setRow(3);

      if (ColumnNum & B00000100) {
        keypadStatus[9] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 11: // Read button 0 press
      key = 0;
      Keypad_Debounce_Time(10);
      setRow(3);

      if (ColumnNum & B00000010) {
        keypadStatus[10] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    case 12: // Read button # press
      Keypad_Debounce_Time(11);
      setRow(3);

      if (ColumnNum & B00000001) {
        keypadStatus[11] = notPRESSED;
        module_keypad_i = 0;
      }
      break;

    default: module_keypad_i = 0;
  }
}

void Keypad_Debounce_Time(int status_num) {  {
n = millis() - keypadDebounceTime;
Serial.println(n);
if (n < 300)keypad_status[status_num] = partialPRESSED;
else if (300 <= n && n < 1000) keypad_status[status_num] = normalPRESSED;
else if (1000 <= n && n < 5000) keypad_status[status_num] = heldPRESSED;
else keypad_status[status_num] = stuckPRESSED;
  }
}

void setRow(byte RowNum){
//Set row
Wire.beginTransmission(MCP_ADDRESS);
Wire.write(MCP_GPIOA);
Wire.write(sRowPattern[RowNum]);
Wire.endTransmission();

// Read the column value
Wire.beginTransmission(MCP_ADDRESS);
Wire.write(MCP_GPIOA);
Wire.endTransmission();
Wire.requestFrom(MCP_ADDRESS, 1);
nColumn = Wire.read();
}

The keypad status for each is set up like this:
enum button_type { notPRESSED, partialPRESS, normalPRESS, heldPRESS, stuckPRESS};
button_type keypadStatus[12];

So all my segment module is doing is reading each key pressed.
I've tried adding some simple non blocking delays in the cases to try and delay it and give the other module time to react to the change like below for one of my cases:
case 12: // Display button # presses
      n = millis() - keypadDebounceTime;

      SetRow(3);

      if (nColumn & B00000001) {
        pressDuration(11);
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval) {
          previousMillis = currentMillis;
          keypadStatus[11] = notPRESSED;
          module_keypad_i = 0;
        }
      }
      break;

The pressDuration function works similar to the keypadDebounceTime but just calculates what kind of press it is sets it when the button is released then waits a set interval to set it back to notPRESSED. However, even when I have set my interval to 5 seconds I get no response from the segment display which all it is doing is waiting for the different button press states. I have older code that does the action on button release but all that does is set it to the next number not set the number wait some time then clear it. Is there something fundamental I am missing I have been scratching my head at this for a couple days now.

I honestly don't understand your code. It seems very complicated to me. Also it seems as if you mixed different functionalities into the same code elements.

I also don't understand your code, can you remove the irrelevant parts? Generally, this is a standard case for using a state machine


text:
Variable sets to 32767 - MATLAB Arduino
I am running out of ideas of what may be causing this problem, and I would appreciate some help identifying anything I am overlooking.
Quick Problem Summary
A variable gets set to 32767 quite often and I am unsure why. I tried checking if it was a types problem, if there was somewhere in my code it could overflow, any division by 0, initialising all variables in all sections of the code, and have now tried to cast all relevant variables to int. What else could I try?
This is how this variable gets set in a C++ function:
readValue = readAverage(A0);
targetValue = 2000; // Some constant number set beforehand
myVariable = targetValue - static_cast<int>(round(readValue));

// After some operations that only check if myVariable is within a range

// There are several states in which LOG_myVariable can get set in case there is an error where data wants to get logged
LOG_myVariable = myVariable

All of the variables above are public and get initialised to 0. See in the context section to see how the readAverage function works.
This code block above gets repeated thousands of times in a loop and exits when I send an interrupt. LOG_myVariable only gets set in the method above. Sometimes it gives me normal values that I would expect, but it is returning 32767 very often. Is this some C++ syntax or function I am overlooking?
Some context:
An Arduino Due is using the MATLAB 2019 - Arduino Support Package Add-on. The variables described above are stored in memory and are dynamically overwritten during every logging function. I send them back to MATLAB via the C++ commandHandler as:
byte dataOut[2] = {
                  highByte(LOG_myVariable),
                  lowByte(LOG_myVariable)
                  };
sendResponseMsg(commandID, dataOut, 2);

In MATLAB, I convert it within a method after requesting the dataOut via sendCommand:
[dataOut] = sendCommand(arduinoObj, arduinoObj.LibraryName, commandID, dataIn);
            % Converts the two High and Low bytes from [dataOut] into a single integer.
            myVariableMATLAB = 256 * dataOut(1) + dataOut(2);

readAverage works like this:
/*
Reads the raw ADC sampled value of a pin an averagePoints amount of times.
All the values get averaged and the function returns `outputAverage`.
Note
*/
int myClass::readAverage(const uint8_t pin) {
  int i = 1, outputAverage = 0;  // Iteration value, OutputAverage
  double sum = 0, runningAverage = 0;
  // Array Initialization
  int readings[70] = { 0 };

  for (i = 0; i <= 70; i++) {
    if ((runningAverage >= 0) && (runningAverage <= 4096)) {
      // First 10% readings to setup a runningAverage value
      if (i < 70 * 0.1) {
        readings[i] = static_cast<int>(analogRead(pin));
        sum += readings[i];
        runningAverage = static_cast<int>(sum/(i+1));

      } else if (i >= 70 * 0.1) {
        // Normal Operation
        readings[i] = static_cast<int>(analogRead(pin));

        // Filtering Outliers
        // If xReading is within [LOWER_PERCENTAGE, HIGHER_PERCENTAGE] * runningAverage range.
        if ((readings[i] >= LOWER_PERCENTAGE * runningAverage)
        && (readings[i] < HIGHER_PERCENTAGE * runningAverage)) {
          sum += readings[i];
          runningAverage = static_cast<int>(sum/(i+1));
        } else {
          // Enter Error/ Out of Bounds Log Mode, how?
          // Meant to filter out
        }
      }
    } else {
      /* Enter Unknown Error Mode
      Note it defaults to a single measurement, but no signal is sent to mention this.
      */
      runningAverage = static_cast<int>(analogRead(pin));
    }
  }
  outputAverage = static_cast<int>(round(runningAverage));
  return outputAverage;
}

Any tips on improving the code/logic are always appreciated too!

Some findings:

Your for loop iterates over 71 results, but your array has only the length 70.
You may overwrite variables in the memory behind the array.
You can use else instead of else if (i >= 70 * 0.1) because it is just the negation of the if (i < 70 * 0.1). In the else case (i >= 70 * 0.1) is always true.

What is the type of myVariable? If you assign incompatible types (signage or length) an over- or underflow can happen. 32767 = 2^15 - 1 = 0b0011111111111111 (14 bits on) that looks pretty much like an underflow and a conversion of incompatible types.
EDIT:
By a second read of your question I saw another possibility of failure:
You copy the bytes of a two byte signed integer into 2 bytes and send it to matlab.
byte dataOut[2] = {
  highByte( LOG_myVariable ),
  lowByte( LOG_myVariable )
 };

Let's say you have a negative number in LOG_myVariable. In Memory this is represented with a one in the highest bit (MSBit) and the complementary bit string plus one (two's complement: See Wikipedia).
An Example:
16 bit signed int -1 is represented as 0b1111111111111111 you split it in two bytes 0b11111111 and 0b11111111. The you send it to Matlab.
Now it depends on how Matlab interprets the bytes. Are that unsigned int8 or signed int8? you combine the bytes like so:
 myVariableMATLAB = 256 * dataOut(1) + dataOut(2);

If Matlab interprets the bytes as unsigned  you get 256*(-1) + (-1) == -257 but that's not -1. And if it interprets the bytes unsigned it gets 256*255+255 == 65535 which is also not -1. I bet there is a negative number that gives you 32767.

Thanks for the help!  myVariable is an int. Will write the for loop properly, check if there might be an issue with signage (I had not looked at that before) and again revise types equivalence.  Will update if it works.

@dquintero If myVariable is an int then, I doubt that you have problems with negative values. Did you try the correct  array size of 71. It's a buffer overflow, and that's a serious error.

I've added a new idea to the answer.

Though I haven't read the question fully, 65535 is the max value of a 16 bit unsigned int, which is all bits set to one. If you cast that to a 16 bit signed integer you get -1. 32767 is the max value of a 16 bit signed int, which is all bits except the highest (sign bit) set to 1

This helped a lot, thanks!


text:
Custom bootloader for battery level indicator
For a project I need to be able to read the battery level of the device regardless of the sketch currently running.
For this I plan on adding a custom routine in the Arduino bootloader that reads the battery level and shows it can be accessed even when the current sketch is overwritten with another sketch.
Is creating a custom bootloader a good solution for this? If so how should I go about create that bootloader?
Edit:
The battery level will be shown using 3 leds indicator every time a specific button is pressed; I don't want to store the battery level. I need this to happen in every sketch, that's why I think I should do this on the bootloader, having that code on the sketch isn't an option. This is needed because I am developing a custom board and this function will be default on each board.

How should be battery level be shown/accessed? And when? When you use a bootloader, it will only work while the bootloader is running

You will have to store the battery level somewhere safe. In the EEPROM for example. Then you can access it afterwards. So to me this sounds feasible. Even I don't understand why I has to live inside the bootloader. Is it supposed to prevent the sketch from being executed on low battery?

With out knowing the overall goal this is difficult to solve. Sure you could spend time to understand and modify the boot loader.  But the resulting code will likely leave less memory for the application. On top of that, @chrisl is correct, the application & boot loader do not run at the same time. This is not a real OS. So no new battery measurements unless you waste space duplicating the code or figure out a way to jump to boot loader code from the Application. Instead, consider using a 2nd Arduino to measure the battery level.  A much simpler and cheaper approach if this is a 1 off project.

if your Arduino board uses a second microcontroller for the USB interface, then you could use that for your battery monitor


text:
Can't get OC1B (pin 10) to output
I'm trying to get this program to use channel B for the output waveform using the phase correct PWM mode and using OCR1A as the top. With a 50% duty ratio I'm attempting to  get a 10 Hz freq. I'm able to adjust the OC1A (Pin 9) if I set TCCR1A to 0x43; but nothing comes from pin 10. Code:
include "avr/io.h"

void setup()
{
 DDRB = 0x6; //set pins 9 and 10 as output

 /*set operation Toggle mode; WGM13:0 = 1011 phase correct PWM
CS12:0 = 101 prescaler = 1024*/
 TCCR1A = 0x23;
 TCCR1B = 0x15;

 OCR1A = 0x187; //391 for 50% duty cycle
 TCNT1 = 0; //clear counter and update OCR1A
}
void loop()
{ }

It's much more readable to configure registers using bit operations like TCCR1A |= (1<<COM1A1);. Pin 10 refers to the arduino's pin 10?

Haven't looked into the spec but maybe you want to try setting OCR1AL = 0x87 and OCR1AH = 0x01 separately.

You are using Timer/Counter 1 in Fast PWM Mode with TOP set to OCR1A:
OCR1Aonly describes the number to what it counts up so, 0…391 in your case.
You have to define the duty cycle with OCR1B. 50% would be 195.


text:
My two ultrasonic sensors are reading inaccurately
I am having trouble getting two of my ultra sonic sensors to read accurate results in cm. I am using a HC-SR04 currently.
I get random numbers at different distances with an object in front (smooth cover book)
Test 1:
Real distance: 10 cm
Sensor 1: 0.00cm
Sensor 2: 82.42
Test 2:
Real distance: 10cm
Sensor 1: 92.11cm
Sensor 2: 95.03
Against the wall with no book:
Test 1:
Real distance: 10 cm
Sensor 1:0.00cm
Sensor 2: 13.20
Test 2:
Real distance: 10 cm
Sensor 1:24.37cm
Sensor 2:26.75
The numbers constantly fluctuate. I am trying to get accurate results.
I am not sure if the sensors are broken or if my code is incorrect.I appreciate any help.
Here is my set up: [
#define trigPin1 13
#define echoPin1 12
#define trigPin2 11
#define echoPin2 10

float duration, distance, duration1, distance1, duration2, distance2;

void setup() {
  Serial.begin (9600);
  pinMode (trigPin1, OUTPUT);
  pinMode (echoPin1, INPUT);
  pinMode (trigPin2, OUTPUT);
  pinMode (echoPin2, INPUT);

}

void loop() {

  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");
  delay(100);

}

void FindRange(int trigPin, int echoPin) {

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0345;
  delay(100);

}

Comments are not for extended discussion; this conversation has been moved to chat.

I am not sure but may be it helps just by checking principle of working of this sensors as it is depicted for low range distance you must be carefull about reflection from other source of ultrasonic. I think it would be a good Idea to place a delay between these two module so to make sure it get less noise from each other
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  delay(1000);//add delay
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  delay(1000);//add delay

the other reason for getting zero may be your controller could not measure reflection from wall due to lowspeed sampling (if you are polling) or reading time with low precision so I have a suggestion for you if you are familiar with STM32 there is a built-in hardware implementation for measure time of pulse using timers called one-pulse mode it may helps you get precision you need

In the loop you trigger trgPin1 then trigPin2 but in the first range find you read echoPin2 instead of echoPin1.
void loop() {

  FindRange(trigPin1, echoPin2);
  duration1 = duration;
  distance1 = distance;
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");
  delay(100);

}

must be
void loop()
{
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;

  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;

  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");

  delay(100);
}

Thank you I just changed and compile it but, when I use smooth book, The real distance: 15cm sensor 1: 0.00cm and sensor 2: 0.00cm.

What happens if you run the program in the loop and you move the book to and from the sensor. Do the values in the serial terminal smoothly change as you move the book or do they randomly flip around? In the latter case, I would say, there is something wrong with your setup. (broken wires, wrong connection, missing ground or vcc. Can you please add a picture of your setup? (I hope you have access to a smartphone with camera or a digital camera) Without seeing the setup I can not say much more.

When I move the book to and from the sensor the serial terminal it gave me 0cm for both sensors then it only read sensor 1 in random numbers while sensor 2 was still 0cm.

Look at your picture you connected Vcc and GND to the Vcc rail of you breadboard. Sensor one is not grounded. So it's transmitting behavior is not  specified. Perhaps the trigger or echo pin acts as ground when off and the sender speaker sends some weird signals the second sensor misinterprets.

@EmmeS I forgot to precede my last comment with you name. So you might not get informed.  Once again: Look at your picture you connected Vcc and GND to the Vcc rail of you breadboard. Sensor one is not grounded. So it's transmitting behavior is not specified. Perhaps the trigger or echo pin acts as ground when off and the sender speaker sends some weird signals the second sensor misinterprets

Where they are plugged in they won't work as the rows (like the other side) are connected. Example: http://wiring.org.co/learning/tutorials/breadboard/imgs/breadboard-02.jpg
They aren't connected to the other pins, and they are connected themselves.

change the MCU, that arduino is a chinese version.
Use a original or other original board.
I had the same problem with two diferents projects, and it happend the same to me. One with ultrasonic and other with RF24 module. In both projects, some really extrange things happens. But when i change for one original arduino, everything works perfect.

The working principle of HC-SR04 is based the reflection of ultrasonic wave. Therefore, It measures distance inaccurately in the following case:

The obstacle is something that can adsorbs the ultrasonic wave. For example, cotton wool.
The obstacle is faced in non-90-degree. In this case, the obstacle may reflect the ultrasonic wave to another direction
The obstacle's surface can diffuse the ultrasonic wave

You can see the working principle of HC-SR04 here.
One more thing: two ultrasonic sensor may interfere to each other if they work at the same time. Try to give delay(100); between two reads
void loop()
{
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;

  delay(100);

  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;

  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");

  delay(100);
}

An 100ms delay is included in the FindRange function

I tested your code as it currently is with my own HC-SR04s and a clone Arduino Nano (since that is, what I have here currently). It works like a charm. The values are rather good, maybe accurate about +-1cm. I checked in the change between 10 and 70cm with my desk plate and a wall as obstacle. (I just looked, if the values are plausible. I didn't investigate thoroughly, how accurate the values are).
So I guess, that your sensors are broken.


text:
ESP8266 Arduino MQTT callback with dynamic topics
I have a program that depending on user input, it creates one or several objects that will publish data to a MQTT broker, each one with a different topic. This is already done. The ESP8266 also has subscribe itself to the same topics it publishes.
Now, the problem is that I have to create a dynamic callback in the ESP8266 to read the all the posible arriving topics to which the ESP8266 has subscribed and I am having trouble with that.
The callback function model is:
void MQTTcallback(char* topic, byte* payload, unsigned int length) {

// handle message arrived

}

The possible topics can be:
ObjectTL/TL_1
ObjectTL/TL_2
ObjectTL/TL_3
...
ObjectTL/TL_X
The number (TL_X) depends of the user input I mention at the beginning.
Thanks!

Without knowing more about the structure of your program and objects this is impossible to answer. Do you employ polymorphism for your objects? Do you have some storage where these objects are stored and are accessible? Do you have some form of list or array of the topics and their relationship to the objects?

I think using sscanf may help you
void MQTTcallback(char* topic, byte* payload, unsigned int length) {

  sscanf(data, "ObjectTL/TL_%d", dynamicTopicName);
  // handle message arrived
  your_dynamic_function(dynamicTopicName,byte* payload, unsigned int length)

}


text:
C++ State Machine / Wpmf-convesion
I'm quite a newbie using C ++. I am trying to implement in C ++, the state machine described in this link for C language:
https://barrgroup.com/Embedded-Systems/How-To/Coding-State-Machines.
I have created an Fsm class, which implements the behavior of the state machine, and a Machine class, whose methods will be the states.
The code works, but it generates a warning (-Wpmf-conversions) when I try to save the memory address of a Machine method, in State state__
class Fsm
{
public:
    typedef void (*State)();
private:
    State state__;
public:
    Fsm(State state);
    void dispatch();
};

Fsm::Fsm(State state)
{
    state__ = state ;
} //Fsm

void Fsm::dispatch()
{
    (*state__)() ;
}

class Machine : public Fsm
{
public:
    Machine() : Fsm((State)&Machine::initial) {}       // ctor
};

I'm using an Atmega2560, with AVR-GCC compiler.

For what line of code is the warning generated? Also, why does your Fsm class have two "public" access specifiers. And why type-def (*State)() as void? It could be that I'm forgetting my C++, but I don't see what you're trying  to do here.

@Paul typedef void (*State)(); is a typedef for a function pointer to a function with no parameters and a void return type.  It is perfectly normal to have multiple public, protected or private sections in a class.

A "PMF" is a Pointer to a Member Function. In C++ this is not allowed.

A pointer to a member function is not allowed in C++. GCC can allow it, but moans at you because it's non-standard.
In C++ the normal way of dealing with the kind of thing you want is through class inheritance.
Typically you would create your base Fsm class that implements the basic functionality of your state machine control, then overlay over the top of that (create a new class that inherits the Fsm class) another class that implements your specific machine functionality.  You can declare functions in your base Fsm class that are pure virtual - that is, they exist, but have no body. It's then the job of the child class to actually implement that functionality.  The parent Fsm class then knows about those functions and can call them.
So you would have something like:
class Fsm {
    public:
        void dispatch();
    protected:
        virtual void initial() = 0;
};

void Fsm::dispatch() {
    initial() ;
}

class Machine : public Fsm {
    protected:
        void initial() {
             Serial.println("Here");
        }
};

Machine mach;

mach.dispatch(); // --> "Here"

Fsm knows about initial(), but the function hasn't been further defined.  Machine implements initial().  You then create an instance of Machine which contains everything needed.  Calling dispatch() runs the function in the Fsm parent class which then calls initial() in the child Machine class.


text:
Arduino IDE won't use selected port
I'm trying to program an ATtiny85, using an AVRISP mkII programmer (this one: https://www.amazon.de/dp/B00IYNAXUC/ref=cm_sw_r_sms_c_api_i_VXOWDb3H3N5ND) with the Arduino IDE (version 1.8.10 on Ubuntu 18.10). For the ATtiny, I've installed https://github.com/damellis/attiny using the board manager, as recommended in countless tutorials.
Now, everything seems to be recognized fine, and I've selected the programmers port in the IDE: /dev/ttyACM0.
But when I try to upload a sketch, the IDE instead trys to pass usb as the port to avrdude. This is only visble when enabling verbose output: (paths abbreviated)
/home/[...]/avrdude -C/home/[...]/avr/etc/avrdude.conf -v -pattiny85 -cstk500v2 -Pusb -Uflash:w:/tmp/arduino_build_728460/sketch.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/[...]/avrdude.conf"
         User configuration file is "/home/[...]/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : stk500v2
avrdude: usbdev_open(): did not find any USB device "usb" (0x03eb:0x2104)

avrdude done.  Thank you.

usb isn't even a selectable port in the IDE!
Simply pasting the avrdude command (first line in the output above) to a terminal and changing usb to /dev/ttyACM0 makes it program the IC perfectly (but of course, that's a rather cumbersome workaround).
Also, selecting another programmer in the IDE (like AVR ISP, without the mkII) makes it use the correct port (but of course it won't work, since it's the wrong programmer).
Am I doing something wrong, or is this an actual bug in the Arduino IDE?

upvote for well written question

Did you hold the Shift button while clicking upload?

@Coder_fox I tried that too (uploading with programmer instead of just uploading), but it didn’t seem to have any effect.

I would say you have to select  the Arduino as ISP Programmer. Not the mkII ISP. Perhaps the attiny board library can handle connection to attiny dev boards over usb if you use the standard programmer. But that's just a very very rough guess. But selecting the Arduino as ISP is a requirement.
Edit:
No you can not use the Arduino as ISP if you use an STK500 programmer.
D. A. Mellis' tool is designed for an Arduino as a programmer.
But if your work around does the programming, the mkII is the right tool. You have to find out, how the IDE builds the CLI string to start avrdude.
The tool you installed contains a text file called platform.txt:
name=ATtiny Microcontrollers

tools.avrdude.path={runtime.tools.avrdude.path}
tools.avrdude.erase.params.verbose=-v -v -v -v
tools.avrdude.erase.params.quiet=-q -q
tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m

tools.avrdude.bootloader.params.verbose=-v -v -v -v
tools.avrdude.bootloader.params.quiet=-q -q
tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params}

I would say the entry tools.avrdude.bootloader.pattern does the trick. Especially the variable {program.extra_params}. You have to find out how the IDE is building this variable. One of it's options must be -P<Port>. But why does the IDE use the value usb for <port>?
I'll try to find out. But I have no access to an IDE at the moment. If you (or someone else) find a solution before me, please add an answer and mark it as accepted, so I need not investigate further.

I‘m not trying to use an Arduino as a programmer. I have this one: https://www.amazon.de/dp/B00IYNAXUC/ref=cm_sw_r_sms_c_api_i_VXOWDb3H3N5ND Do I really have to select Arduino?

You do not use a Arduino for programmer as the documentation you pointed us to requires. That's a really interesting information. ;-) I would add it to the question. I'll edit my answer.

My bad, I thought AVRISP mkII was enough info. Question is updated.

The answer of @EdgarBonet gives you the Information, I was looking for.

And you are right, AVRISP mkII should have given me the hint. It was not your fault. Just I was too lazy to think. But it is always a good idea to give as much information as you can, to keep lazy people like me from wrong interpretations. ;-)

You mean that the STK500 v2 programmer uses an emulated serial port
rather than direct USB? Then I guess there is a bug in the Arduino IDE.
The file programmers.txt contains the following lines
describing the programmer:
avrispmkii.name=AVRISP mkII
avrispmkii.communication=usb
avrispmkii.protocol=stk500v2
avrispmkii.program.protocol=stk500v2
avrispmkii.program.tool=avrdude
avrispmkii.program.extra_params=-Pusb

You may locate this file in your Arduino installation and replace the
last line from this snippet by
avrispmkii.program.extra_params=-P{serial.port}

If that works, it would be a good idea to submit a pull request with the
fix to the Arduino team.
Alternatively, you may try selecting “Atmel STK500 development board” as
a programmer. This is supposed to autodetect the version of the STK500
protocol, and uses the correct serial port.
Edit: you may also have to replace
avrispmkii.communication=usb

by
avrispmkii.communication=serial

C.f. this bug report, which seems to cover the exact issue you are
facing.


text:
Is it possible to load both the arduino bootloader and a sketch onto an atmega328p via icsp?
i am familiar with uploading an arduino bootloader onto an atmega328p using another arduino via the arduino IDE. i have also installed software 'sketches' using that process which i believe leaves out the bootloader(meaning one wouldnt be able to upload new sketches in the future via usb). my question is: is it possible to load both the bootloader and a software program onto the chip via icsp? many thanks in advance.

The Arduino builder creates for AVR boards not only hex file for the sketch, but it creates a combined hex with bootloader and sketch too. It is for example for Blink.hex a Blink_with_bootloader.hex. If you use in IDE the "Export compiled binary" command in Tools menu, the builder puts the hex files next to ino file in your sketch folder.
If you want the command "Upload using programmer" to upload hex with the bootloader, modify in platform.txt the tools.avrdude.bootloader.pattern key to use "-Uflash:w:{build.path}/{build.project_name}_with_bootloader.hex:i"

Hi thanks very much for this. where can i find platform.txt?

it depends if it is the core bundled with IDE, then in IDE installation folder, or if it was installed with Boards Manager then packages are located in ~/.arduino15/packages/ on Linux and %userprofile%\AppData\Local\Arduino15\packages\ on Windows (AppData is a hidden folder).

yeah theres no txt file in there, just folder containing arduino cores i have installed...(i am on windows 10

something like packages/arduino/hardware/avr/1.6.21

hi i really appreciate this help by the way but am still having trouble. i tried editing the file but it had no effect (still uploading the hex file from the temp directory. i noticed that the platform.txt file was in a folder called 1.8.1 and the version of arduino i am running is 1.8.9 so i thought maybe i am editing the wrong document. so i removed the file from the folder, restarted arduino and tried uploading, expecting an error or something and it acted normally which makes me think that its not paying any attention to this file....?

the AVR core version is independent from IDE version. 1.8.1 is the latest AVR core and it is bundled with IDE 1.8.10. it is possible, you have one AVR core installation in C:\Program Files (x86)\Arduino\hardware\arduino\avr and other in Arduino15 folder

i have literally just got it working by switching over to my mac and uploading it using the terminal. (i tried it on my PC but the command kept being refused because windows cant handle spaces in a command, was drivingme nuts!) - thanks for all the help!


text:
Do some arduino pins give signals when the controller starts?
For example, on the ESP32 board there are several contacts that can issue pulses when the controller starts, which is connected with the operation of the chip itself. It is not recommended to connect devices that respond to input signals from the ESP to these contacts.
Tell me, are there any contacts on the Arduino UNO (Atmega328P) that give out any impulses at startup?
In particular, it is important for me to know about the following contacts:

PB1 (9 pin)
PD4 (4 pin)
PD5 (5 pin)

Thank you!

on ATmegas the pins are INPUT at startup

If the arduino is programmed with a sketch, it depends on the sketch if the pin are input or output. If it is a new arduino the bootloader does not setup any outputs. An ESP has mostly a firmware installed. So the flashing pins are probably driven by this firmware. An Arduino may have a program already installed, that could also flash pins.

Most Arduino boards come with a bootloader of some form.  This bootloader may do things with IO pins. However apart from that, no, nothing else happens to any IO pins.
The bootloader may:

Flash pin 13 (built in LED)
Configure and communicate on pins 0/1 (UART)

With no bootloader then absolutely nothing happens on any IO pins.

thank you for the answer!


text:
multiple invdividual servo controll arduino
I want to declare 11 servo motors in my code. Is there a better way to do that than just declare everyone under each other. The reason is that i have a code that will set the rotation for one at a time. The best would be a list so i could iterate over which server i want to move.
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
//etc
void moveServo(int n,int deg){
  servo[n].write(deg); //something like this
}

Generally, to control a servo motor you need to develop a fairly well timed pulse train.  Usually you use the PWM hardware inside the processor.  The consequence of using software?  The pulses may have a bit of jitter and this translates into the servos jittering.  If you are willing to use the correct hardware (processor) there are ways around this.  Do you wish for such an answer?

Its for a robot arm so i want to send message from a raspberry  pi, that i want to move servo[1] 20 degrees. so i can move a joint at a time.

Depending on the specific processor in the Arduino you are using, there may not be enough PWM hardware generators to provide the pulse train to control 11 servos.  You can resort to using software to create the pulse trains.  But this may end up causing some jitter in the servo motors.  Likely more so during serial communications with the Raspberry Pi.

Servo.h library can control 12 servos in a '328P, and 48 in a 2560.

Consider using a specific processor / Arduino-board.  In this thread there are references to using the Arduino 1280 board with the Arduino Servo Library to control up to 48 servos using a combination of hardware and software.
In C++ when you "instantiate" a class you are making good use of memory space as you do not really create duplicate code. All you create are copies of the variables necessary to support each instantiation. There should only be one copy of the code in memory.  To iterate over each instantiation consider using a switch/case statement.

First: Your code would not work, since servo is not defined and thus not an array to iterate over. You would need to first define the array and then fill it with Servo elements.
Servo servo[11];

void setup(){
    for(int i=0;i<11;i++){
        servo[i] = new Servo();
    }
}

The different Servo objects are created dynamically. In most cases it is bad to use dynamic allocation on a microcontroller with litte RAM, but it is ok, when you only use it once at the start.