message:
Noise on piezo analog read due to Arduino power supply

I am making a device that measures temperature and vibrations and records the values onto an SD card. It will be a standalone device.

The hardware used:
- Arduino Uno
- PCF8523 RTC clock
- MAX3186 + PT100 RTD temperature sensor
- Adafruit data logger shield
- Typical bare piezo sensor

For the vibrations, a piezo sensor is used. Because it can produce a signal in two directions, I decided to use a voltage divider to offset the signal from GND. Two 5.1K resistors are connected from the piezo negative terminal to 5V and GND. A 1M resistor is placed in parallel with the piezo sensor. The positive terminal is connector to analog input 0.

[![Piezo circuit][1]][1]

The sensor is read 100 times per data point, the maximum and minimum values are stored and the final value is set to be the difference between the two (two times the amplitude).

**USB**

**9V wall adapter**

When the system is powered via a laptop USB port, the resting value has a jitter of a few bits. When a 9V wall adapter powers the arduino, the jitter is +/- 30 bits. Any small vibrations disappear in the noise.

**USB with piezo**

[![USB with piezo][2]][2]

**9V with piezo**

[![9V with piezo][3]][3]

**9V without piezo**

[![9V without piezo][4]][4]

I would like some help to find the best way forward.

_edit 29-10 17:53 Added better plots_

_edit 30-10 17:53 Added plots for 2.5V and 3.3V lines_

  [1]: https://i.stack.imgur.com/wFjDV.png
[2]: https://i.stack.imgur.com/JgVyc.png
[3]: https://i.stack.imgur.com/ZJ9vI.png
[4]: https://i.stack.imgur.com/lWc0U.png

body:
The 9V wall adapter is in most cases a switched power regulator with a high frequency. That's like a radio transmitter direct beside the wire. So there is nothing mystical, when the smooth USB Voltage does not show problems but the
"radio transmitter" does.

There are two ways the power supply can impact: over radio wave or as ripples over the regulated Voltage of your Arduino.

I asked myself, which one it is (or even both)? If you use the extra regulated analog voltage reference (AREF) as the +5V on your Voltage divider, it would be more likely that the problem comes through the air. Then it would help if you activate the shield of the wire by connecting it to GND.

If a rippled supply voltage is the problem, you have to smooth it. Perhaps with a low pass filter (a big Elko between Vcc and GND).

Perhaps you have a solenoid iron core. Then you can wrap the wire to the piezo sensor a few times around it (near the A0 Pin). This technique is often used in computer power supplies to prevent the switching frequencies from escaping to the public power lines.


sender: user

sender: assistant

body:
In addition to what [Peter Paul Kiefer](https://arduino.stackexchange.com/users/10285/peter-paul-kiefer) suggests, you will also want to place an RC [low-pass filter](https://en.wikipedia.org/wiki/Low-pass_filter), between the piezo transducer, and the analog input.

You mention that you'll be sampling this value 100 times per second. So the cutoff frequency, for the filter, should be set to 50 Hz (the [Nyquist frequency](https://en.wikipedia.org/wiki/Nyquist_frequency)).


message:
EEPROM.get returns bad data

I am using the attached code.
What I am trying to do is:

Test if there is a personalized "board serial number" written in the EEPROM (by previous code run)
If data found was not 7 characters (e.g `SN-XXXX`), then generate a serial number and save it to EEPROM

Problem is: it generates a serial correctly, it even stores and reads it a few times, but when I disconnect the USB cable and reconnect to test again, it returns some bad data from the EEPROM, like: `⸮^R⸮y⸮|` which seems to pass my 7 characters test and it doesn't generate a new one.

What am I doing wrong ?

```C++

#include <EEPROM.h>

// board SERIAL number
char serial_characters[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"};
// will be filled as SN-A2KH
String serial_number;

void setup() {

  Serial.begin(9600);

  // Get the float data from the EEPROM at position 0
  EEPROM.get(0, serial_number);

  // serial from EEPROM valid
  if (serial_number.length() == 7) {
    Serial.println("Found valid serial in EEPROM");
    Serial.println(serial_number);
  }

  // serial from EEPROM not valid (e.g not: SN-XYZ5)
  if (serial_number.length() != 7) {

    Serial.println("Serial from eeprom is NOT 7 chars, generating a random serial");
    Serial.println(serial_number);

    // if analog input pin 0 is not connected, use noise from it in order to generate a random seed, otherwise random is not so random
    randomSeed(analogRead(0));

    // serial might be empty now, set a "SN-" prefix
    serial_number = "SN-";
    for (int i = 1; i <= 4 ; i++) {
      serial_number = serial_number + serial_characters[random(0, 35)];
    }
    Serial.println("Generated serial now: " + serial_number);

    // save to eeprom if format is valid
    if (serial_number.length() == 7) {
      EEPROM.put(0, serial_number);
      Serial.println("Written serial to EEPROM");
    }

  } // <<< serial from eeprom not correct, generated one

}

void loop() {}
```

body:
You are saving a String object in EEPROM, which is useless. A string
object does not store the contents of your string. Instead, [it just
stores][string]:

* the memory address where the actual contents (the characters) is
  stored
* the amount of memory allocated for this contents
* the number of characters that actually make the string

This is what you are storing to, and retrieving from EEPROM. So you get
the correct number of characters (third item in the list above), but the
memory address now points to uninitialized RAM.

I suggest instead storing in the EEPROM a raw C string, i.e. an array of
8 chars (7 printable chars plus the terminating NUL). You could achieve
this by just changing the declaration of `serial_number`:

```c++
char serial_number[8];
```

For checking the validity, I would just check that it starts with "SN-"
and the last char is a NUL:

```c++
if (memcmp(serial_number, "SN-", 3) == 0 && serial_number[7] == '\0') {
    ...
}
```

You could do a more stringent validation though, and check that the
other 4 chars are within the valid set.

[string]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.1/cores/arduino/WString.h#L196-L198

**Edit**: to build `serial_number` with random chars:

```c++
strcpy(serial_number, "SN-");
for (int i = 3; i < 7; i++)
  serial_number[i] = serial_characters[random(0, 36)];
serial_number[7] = '\0'; // terminating NUL
```


body:
Just to have the full working code, I ended up with this:

```C++
#include <EEPROM.h>

char serial_characters[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"};
// 7 chars for serial and one for string end '\0'
char serial_number[8];

void setup() {

  Serial.begin(115200);

  EEPROM.get(0, serial_number);

  // check found format
  if (serial_number[0] == 'S' && serial_number[1] == 'N'  && serial_number[2] == '-' && serial_number[7] == '\0') {

    Serial.println("serial from eeprom is valid");
    Serial.println((char*)serial_number);

  } else {

    Serial.println("no valid serial found in eeprom, generating new serial");

    // if analog input pin 0 is unconnected, use noise from it in order to generate a random seed, otherwise random is not so random
    randomSeed(analogRead(0));

    // generate a new serial
    serial_number[0] = 'S';
    serial_number[1] = 'N';
    serial_number[2] = '-';

    // overwrite ending chars of serial with random values
    serial_number[3] = serial_characters[random(0, 35)];
    serial_number[4] = serial_characters[random(0, 35)];
    serial_number[5] = serial_characters[random(0, 35)];
    serial_number[6] = serial_characters[random(0, 35)];

    // end string with null as raw C strings ?!
    serial_number[7] = '\0';

    Serial.println((char*)serial_number);

    // write new serial to eeprom
    EEPROM.put(0, serial_number);

  }

}

void loop() {

}
```


message:
Calling functions from an array of pointers in a library causes 'undefined reference to' error

I am trying to create a library, where I have an array of pointers to functions in it. This array is used by other functions in the library. This is the code of the header file:

    class Lib {
      public:
        static void call();
        static void (*caller[])();
      private:
    };
This is the code of the .cpp-file:

    #include "Lib.h"

    void (*caller[2])();

    void Lib::call() {
      caller[0]();
    }
The sketch executing this is

    #include <Lib.h>

    void setup() {
      Lib::call();
    }

    void loop() {}
When I try to compile this, I get the following error:

> undefined reference to `Lib::caller'

collect2: error: ld returned 1 exit status

Mehrere Bibliotheken wurden für "Lib.h" gefunden

Another weird thing is that the error about the multiple found libraries goes away if I take away the line

    Lib::call();

However, if I put the same code directly into the sketch like so:

    void (*caller[2])();

    void call() {
      caller[0]();
    }

    void setup() {
      call();
    }

    void loop() {}

I get no error. What's the problem here?

body:
    void (*caller[2])();

should be:

    void (*Lib::caller[2])();

Since you are defining storage space for a static member variable you have to tell the compiler what class it's a static member of.


message:
Incompatible types in assignment of 'uint8_t {aka unsigned char}' to 'uint8_t [1] {aka unsigned char [1]}'

I'm trying to send custom data. But it doesn't seem to work. I can't find a way to parse my string to a unit8_t. I tried to follow other people's solutions but they don't seem to work for me.

```
// Declaration
uint8_t myData[] = "";

void loop(){
    myData = *(uint8_t*)atoi("custom string".c_str());
}
```

This is the error message that I keep getting:
Incompatible types in assignment of __uint8_t {aka unsigned char}' to 'uint8_t [1] {aka unsigned char [1]}__ .

body:
`atoi` is for converting a textual representation of a number ("123" for example) into an actual integer.

The c_str() function gives you a pointer to the internal buffer of the String (assuming you actually have a String) which is no different to a `uint8_t[]` or `uint8_t *` (other than the signedness).

Without knowing exactly what the destination function for this buffer requires it's very hard to help you, but you may want something like:

    LoRaWan.send((uint8_t *)myString.c_str(), myString.length());

If you need to copy the data into a fixed length buffer then you need to first create a buffer of that actual size - then copy the string data into it:

    // Create a buffer of 32 bytes
    uint8_t myBuffer[32];
    // Copy at most 32 bytes, but no more than there actually is, into the buffer
    memcpy(myBuffer, myString.c_str(), min(myString.length(), 32));


body:
Your code is a mess. It's clear you are badly confused between arrays, pointers, and C++ strings.

When you say

    uint8_t myData[] = "";

you make myData of type "array of uint8_t" and make it contain an empty string. You should not then change that value.

When you say

    uint8_t *myData;

it means that `myData` is a variable of type "pointer to uint8_t", but it doesn't point to anything yet.

With that declaration, you can later say:

    myData = "custom string";

That points the `myData` pointer to the address of your constant string. I think that's what you want:

    // Declaration
    uint8_t *myData;

    void loop(){
        myData = "custom string";
    }


body:
Firstly, arrays in C and C++ are not assignable. So, your attempts to assign something to `myData` array with `=` operator are bound to fail in any case. Copying data into naked arrays should be done either manually or using library functions.

Secondly, your `myData` array is declared with size `1`. It is just one byte. It is too small to store anything useful. It will not magically "stretch" by itself to accommodate more data. If you need to store more data in that array, it is your responsibility to declare with the appropriate size in advance.

Thirdly, what is `"custom string".c_str()` supposed to mean??? Something looking very similar to that can be expressed in modern C++ as

    #include <string>
    ...
    using namespace std::string_literals;
    "custom string"s.c_str();

but I see no reason for that at all. If your input is a C-string, then function `atoi` is directly applicable to C-strings. No need to convert such C-string to `std::string` and then back.

Fourthly, `atoi` is a "dead" function that exists for compatibility with legacy code only. You are not supposed to use `atoi` in your code. A C-style string-to-number conversion functions are functions from `strto...` group. E.g. `strtol` in your case. But in C++ you might have better options, like `std::stoi` and such.


message:
How many sensors can be used in arduino for my project?

I'm doing a project on water purity finder. I dont know which arduino board can be used for the project. It uses upto 15 sensor modules excluded display, WiFi module. Can you tell me which board is better for my project.

body:
It depends on what kind of sensors you're using. If you use I2C based sensors, and you can configure each with a separate I2C address, you could theoretically drive up to 128 of them. I say theoretically since you might not be able to push the signal across an I2C bus with that many devices on it. You could certainly manage 15 of them however.

The Mega 2560 has tons of I/O lines, so that might be a good choice if you need separate single lines for each sensor.

If you need a separate analog input for each of your sensors, you'd need to use an Arduino with at least 15 separate analog inputs. The Arduino Mega 2560 has 16, so that would work.

If you need 4 bit binary inputs, you'd need 4*15 or 60 inputs. The Mega 2560 has 54 digital inputs, which would not be enough for that situation.

You might also be able to use some sort of signal multiplexer and enable one sensor at a time.

Tell us which type of sensor you're using and we can provide more concrete help.


message:
Making a timer accurate to 1 millisecond possible? Using MAX7219 LED

I'm using the Max7219 (8 digits, 7bits) led display to try and make a timer.  I have downloaded an example code from the following site to set the led digits:

https://www.brainy-bits.com/arduino-countdown-timer-using-the-max7219-display/

However the original code simply loops as fast as possible and decriment the timer so it is not a true time.  I tried to add a 10 ms delay to make it decriment 10ms on the right most digit so the 3rd digit to the right would be seconds, however I found this to be inaccurate and taking slightly longer than 1 second .

**My question is is it possible to make a timer with 1ms accuracy using led display and if so how do I do it?**

    /* CountDown Timer version 2 using Max7219

    Created by Yvan / https://Brainy-Bits.com
    This code is in the public domain...
    You can: copy it, use it, modify it, share it or just plain ignore it!
    Thx!

    */

    #define Max7219DIN 7  // Pin 7 connected to DIN (DataIN)
    #define Max7219CLK 6  // Pin 6 connected to CLK
    #define Max7219CS 5   // Pin 5 connected to CS

    #define Buzzer 8  // Pin 8 connected to Buzzer +positive pin
    int BuzzTrigger=0;  // Variable to store buzzer trigger value

    #include "LedControl.h"  // LedControl Library created by Eberhard Fahle at http://playground.arduino.cc/Main/LedControl

    LedControl lc=LedControl(Max7219DIN,Max7219CLK,Max7219CS,1);   // Last number represent the number of Max7219 Modules connected

    long int countnumber=24001000 ; // Countdown timer start value HH:MM:SSSS

    // Variables to store individual numbers
    int  firstnum=0;
    int  secondnum=0;
    int  thirdnum=0;
    int  fournum=0;
    int  fivenum=0;
    int  sixnum=0;
    int  sevennum=0;
    int  eightnum=0;

    void setup() {
        lc.shutdown(0,false);  // Wake up the display
        lc.setIntensity(0,7); // Set Brightness 0-15
        lc.clearDisplay(0);  // Clear display
        pinMode(Buzzer, OUTPUT);
        digitalWrite(Buzzer, LOW);  //Buzzer Off at startup

    }

    void loop() {

        for (countnumber; countnumber != -1; countnumber--) {
            String mystring = String(countnumber); // Transform Counter Int to String for manipulation

            // Convert number to a time value
            for (int z = 0; z < 6; z++) {

                if (mystring.substring(z) == "999999") {
                    countnumber = (countnumber - 400000);
                }

                if (mystring.substring(z) == "9999") {
                    countnumber = (countnumber - 4000);
                }
            }

            //  Display number on Display depending on number of digits remaining
            if (countnumber > 9999999) {
                firstnum = ((countnumber / 10000000) % 10);
                secondnum = countnumber / 1000000 % 10;
                thirdnum = countnumber / 100000 % 10;
                fournum = countnumber / 10000 % 10;
                fivenum = countnumber / 1000 % 10;
                sixnum = countnumber / 100 % 10;
                sevennum = countnumber / 10 % 10;
                eightnum = countnumber % 10;

                lc.setDigit(0, 7, firstnum, false);
                lc.setDigit(0, 6, secondnum, false);
                lc.setDigit(0, 5, thirdnum, false);
                lc.setDigit(0, 4, fournum, false);
                lc.setDigit(0, 3, fivenum, false);
                lc.setDigit(0, 2, sixnum, false);
                lc.setDigit(0, 1, sevennum, false);
                lc.setDigit(0, 0, eightnum, false);
                delay(10); //<<<<<<<<<<< I ADDED THIS
            } else {
                if (countnumber > 999999) {
                    //      firstnum = ((countnumber/10000000));
                    secondnum = countnumber / 1000000 % 10;
                    thirdnum = countnumber / 100000 % 10;
                    fournum = countnumber / 10000 % 10;
                    fivenum = countnumber / 1000 % 10;
                    sixnum = countnumber / 100 % 10;
                    sevennum = countnumber / 10 % 10;
                    eightnum = countnumber % 10;

                    lc.setChar(0, 7, '-', false);
                    lc.setDigit(0, 6, secondnum, false);
                    lc.setDigit(0, 5, thirdnum, false);
                    lc.setDigit(0, 4, fournum, false);
                    lc.setDigit(0, 3, fivenum, false);
                    lc.setDigit(0, 2, sixnum, false);
                    lc.setDigit(0, 1, sevennum, false);
                    lc.setDigit(0, 0, eightnum, false);
                    delay(10); //<<<<<<<<<<< I ADDED THIS
                } else {
                    if (countnumber > 99999) {
                        //          firstnum = ((countnumber/10000000));
                        //          secondnum = countnumber/1000000;
                        thirdnum = countnumber / 100000 % 10;
                        fournum = countnumber / 10000 % 10;
                        fivenum = countnumber / 1000 % 10;
                        sixnum = countnumber / 100 % 10;
                        sevennum = countnumber / 10 % 10;
                        eightnum = countnumber % 10;

                        lc.setChar(0, 7, '-', false);
                        lc.setChar(0, 6, '-', false);
                        lc.setDigit(0, 5, thirdnum, false);
                        lc.setDigit(0, 4, fournum, false);
                        lc.setDigit(0, 3, fivenum, false);
                        lc.setDigit(0, 2, sixnum, false);
                        lc.setDigit(0, 1, sevennum, false);
                        lc.setDigit(0, 0, eightnum, false);
                        delay(10); //<<<<<<<<<<< I ADDED THIS
                    } else {
                        if (countnumber > 9999) {
                            //             firstnum = ((countnumber/10000000));
                            //             secondnum = countnumber/1000000;
                            //             thirdnum = countnumber/100000;
                            fournum = countnumber / 10000 % 10;
                            fivenum = countnumber / 1000 % 10;
                            sixnum = countnumber / 100 % 10;
                            sevennum = countnumber / 10 % 10;
                            eightnum = countnumber % 10;

                            lc.setChar(0, 7, '-', false);
                            lc.setChar(0, 6, '-', false);
                            lc.setChar(0, 5, '-', false);
                            lc.setDigit(0, 4, fournum, false);
                            lc.setDigit(0, 3, fivenum, false);
                            lc.setDigit(0, 2, sixnum, false);
                            lc.setDigit(0, 1, sevennum, false);
                            lc.setDigit(0, 0, eightnum, false);
                            delay(10);//<<<<<<<<<<< I ADDED THIS
                        } else {
                            if (countnumber > 999) {
                                //              firstnum = ((countnumber/10000000));
                                //              secondnum = countnumber/1000000;
                                //              thirdnum = countnumber/100000;
                                //              fournum = countnumber/10000;
                                fivenum = countnumber / 1000 % 10;
                                sixnum = countnumber / 100 % 10;
                                sevennum = countnumber / 10 % 10;
                                eightnum = countnumber % 10;

                                lc.setChar(0, 7, '-', false);
                                lc.setChar(0, 6, '-', false);
                                lc.setChar(0, 5, '-', false);
                                lc.setChar(0, 4, '-', false);
                                lc.setDigit(0, 3, fivenum, false);
                                lc.setDigit(0, 2, sixnum, false);
                                lc.setDigit(0, 1, sevennum, false);
                                lc.setDigit(0, 0, eightnum, false);
                                delay(10);//<<<<<<<<<<< I ADDED THIS
                            } else {
                                //              firstnum = ((countnumber/10000000));
                                //              secondnum = countnumber/1000000;
                                //              thirdnum = countnumber/100000;
                                //              fournum = countnumber/10000;
                                //              fivenum = countnumber/1000;
                                sixnum = countnumber / 100 % 10;
                                sevennum = countnumber / 10 % 10;
                                eightnum = countnumber % 10;
    a
                                lc.setChar(0, 7, '-', false);
                                lc.setChar(0, 6, '-', false);
                                lc.setChar(0, 5, '-', false);
                                lc.setChar(0, 4, '-', false);
                                lc.setChar(0, 3, '-', false);
                                lc.setDigit(0, 2, sixnum, false);
                                lc.setDigit(0, 1, sevennum, false);
                                lc.setDigit(0, 0, eightnum, false);
                                delay(10);//<<<<<<<<<<< I ADDED THIS
                            }

                        }
                    }
                }
            }

        }
    }

new implementation using millis

    #define Max7219DIN 7  // Pin 7 connected to DIN (DataIN)
    #define Max7219CLK 6  // Pin 6 connected to CLK
    #define Max7219CS 5   // Pin 5 connected to CS

    #include "LedControl.h"  // LedControl Library created by Eberhard Fahle at http://playground.arduino.cc/Main/LedControl

    LedControl lc=LedControl(Max7219DIN,Max7219CLK,Max7219CS,1);   // Last number represent the number of Max7219 Modules connected

    unsigned long countnumber;

    // Variables to store individual numbers
    int  firstnum=0;
    int  secondnum=0;
    int  thirdnum=0;
    int  fournum=0;
    int  fivenum=0;
    int  sixnum=0;
    int  sevennum=0;
    int  eightnum=0;

    void setup() {
      lc.shutdown(0,false);  // Wake up the display
      lc.setIntensity(0,7); // Set Brightness 0-15
      lc.clearDisplay(0);  // Clear display
      Serial.begin(9600);
    }

    void loop() {

      countnumber = millis();

      firstnum = countnumber / 10000000 % 10;
      secondnum = countnumber / 1000000 % 10;
      thirdnum = countnumber / 100000 % 10;
      fournum = countnumber / 10000 % 10;
      fivenum = countnumber / 1000 % 10;
      sixnum = countnumber / 100 % 10;
      sevennum = countnumber / 10 % 10;
      eightnum = countnumber % 10;

      lc.setDigit(0, 7, firstnum, false);
      lc.setDigit(0, 6, secondnum, false);
      lc.setDigit(0, 5, thirdnum, false);
      lc.setDigit(0, 4, fournum, false);
      lc.setDigit(0, 3, fivenum, false);
      lc.setDigit(0, 2, sixnum, false);
      lc.setDigit(0, 1, sevennum, false);
      lc.setDigit(0, 0, eightnum, false);

    }

body:
You generally cannot rely on a processor for correct time keeping without a real time clock somewhere in your circuit.  However, the best way of doing things at certain times, is to call millis() which will return the number of milliseconds since the program started.  With that number you can determine how long something has taken (eg. 1 second) and then do something in response.  You can, for example, print out how long your loop is taking by setting a long integer to millis() at the start of the sketch and then subtracting it from mills() at the end of the loop and printing out the result.

    void loop() {
       long start_time = millis();
       delay(500);
       long end_time = mills();
       Serial.println(end_time - start_time);
    }


message:
Is if statement correct?

if(temperature < baselineTemp)else{
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
    }else if(temperature >= baselineTemp+2 && temperature < baselineTemp+4){
      digitalWrite(2, HIGH)
      digitalWrite(3, LOW)
      digitalWrite(4, LOW)
    }else if(temperature >= baselineTemp+4 && temperature < baselineTemp+6){
      digitalWrite(2, HIGH)
      digitalWrite(3, HIGH)
      digitalWrite(4, LOW)
    }else if(temperature >= baselineTemp+6){
      digitalWrite(2, HIGH)
      digitalWrite(3, HIGH)
      digitalWrite(4, HIGH)

body:
No, the first lines should be:

    if(temperature < baselineTemp) {
      digitalWrite(2, LOW);

Thus the `else` should be removed; after the first `if` and later `else` or `else if` conditions, statements can be placed.

Next time align your code by selecting it and select ctrl-K.

Also, your code can be much more simplified.

Hence the following (reverse engineered) requirements:

- pin 2 is HIGH when temperature >= baselineTemp + 2, else LOW
- pin 3 is HIGH when temperature >= baselineTemp + 4, else LOW
- pin 4 is HIGH when temperature >= baselineTemp + 4, else LOW

So your entire code can be written as:

    digitalWrite(2, temperature >= baselineTemp + 2 ? HIGH : LOW);
    digitalWrite(3, temperature >= baselineTemp + 4 ? HIGH : LOW);
    digitalWrite(4, temperature >= baselineTemp + 6 ? HIGH : LOW);


message:
Is analogWrite() not affected by blocking codes and/or Interrupts?

Well just as the question say, is the analogWrite() function will continue generating near-consistent PWM when it encounters blocking codes or signal interrupts?

Is it the same case for both the classic arduinos(atmega chips) and the new arduinos(SAMD21 chips).

If analogWrite() does get affected by blocking codes, is there a way to create a uninterruptible PWM signal?

body:
> is the analogWrite() function
> continue generating near-consistent PWM when it encounters blocking
> codes or signal interrupts?

Yes for 'hardware' PWM used by analogWrite on AVR and SAMD Arduinos. The hardware PWM is handled by wave output of Timers, which are MCU peripherals running independently from CPU and other MCU peripherals.

> Is it the same case for both the classic arduinos(atmega chips) and
> the new arduinos(SAMD21 chips).

yes

> If analogWrite() does get affected by blocking codes, is there a way
> to create a uninterruptible PWM signal?

N/A


message:
Setting a number inside a struct causes timer to misbehave

The following code:

    struct l{
     uint8_t pin;
     uint8_t sensePin;
     float brightnessTarget;
     uint8_t PWMvalue;
     uint8_t inc;
    };
    typedef struct l led;

    led* redLed;
    led* whiteLed;
    unsigned long secondsOfDay = 79140;
    unsigned long minutesOfDay = 0;
    unsigned int hoursOfDay = 0;
    uint8_t interrupted=0;
    uint8_t runPID;
    int pin13=0;

    void setup() {
      cli();
      TCCR1A = 0;// set entire TCCR1A register to 0
      TCCR1B = 0;// same for TCCR1B
      TCNT1  = 0;//initialize counter value to 0
      // set compare match register for 1hz increments
      OCR1A = OCR1A_val;// = (16*10^6) / (1*1024) - 1 (must be <65536)
      // turn on CTC mode
      TCCR1B |= (1 << WGM12);
      // Set CS10 and CS12 bits for 1024 prescaler
      TCCR1B |= (1 << CS12) | (1 << CS10);
      // enable timer compare interrupt
      TIMSK1 |= (1 << OCIE1A);
      pinMode(13,OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      sei();
    }

    void loop() {
      if (runPID){
        PIControl(redLed);
        PIControl(whiteLed);
        pin13 = (~pin13 & 1);
        digitalWrite(13, pin13);
        runPID=0;
      }
    }

    SIGNAL(TIMER1_COMPA_vect){ //1 second timer fire
      runPID = 1;
    }

Toggles a pin. However, if I add:

    redLed->pin = 3;
    whiteLed->pin = 4;
    redLed->sensePin = 0;
    whiteLed->sensePin = 1;

In the setup anywhere (before cli(), after sei(), or within the block), the interrupt no longer toggles.

I'm absolutely baffled, and I have no idea what's going on.

Edit: everything but whiteLed->sensePin is fine. That line is what is causing the issue (and I still don't understand)

body:
This:

```c++
led* redLed;
```

defines a global variable implicitly initialized to zero (i.e. a NULL
pointer). This is an invalid pointer you are not allowed to use until
you properly initialize it.

Here:

```c++
redLed->pin = 3;
```

you are writing to the memory pointed to by this invalid pointer. This
invokes what the C and C++ standards call _undefined behavior_. What
that means is that, according to the definition of the C++ language, the
behavior of your program is not defined. In other words, _anything_ can
happen. Typically you get a program crash, but even that behavior is not
guaranteed.

Do not ever access memory through an invalid pointer.


message:
Can't use Arduino nano as ISP because it can't read the Device signature

I programmed the 8mhz internal oscillator Bootloader to a new Arduino Nano with another Arduino nano running the ISP Sketch, wich worked fine the first time(Arduino as ISP selected as programmer).
(I wanted to test it befor i want to burn this Bootloader on an Empty 328p-au uC.)
But now since I received the 328p-au uC's i tried the same thing, to burn the Bootloader to the epty uC's but somehow it can't read the device signature, neither from a fresh arduino Nano or another avr(At least that is what avrdude said). I wired everything exectly like it was written in the ISP Sketch.

Here is one of the error messages i received when I was trining to Burn the standard 16mhz Bootloader:
------------------------------------------------
         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

         Fehler beim Brennen des Bootloaders.
         avrdude: AVR device initialized and ready to accept instructions

         Reading | ################################################## | 100%          0.02s

         avrdude: Device signature = 0xff0000
         avrdude: Expected signature for ATmega328P is 1E 95 0F
         Double check chip, or use -F to override this check.

         avrdude done.  Thank you.

-------------------------

So what am I doing wrong?
(Using -F is what I tried but it didn't work, except the first time I programmed the 8Mhz Int. Oscillator Bootloader)

What stand out to me is that there was nothing happening on the MISO line. Here is a screenshot from my Logic Aalyzer software: ibb.co/hWXrpp7

And here is an Image of my setup(the right Arduino is the programmer and the left one has the empty uC soldered onto it): https://ibb.co/zXQFmwR
I am relative new to Arduino, so I hope some of you can help me with that.

body:
It seems that you are using too high programming speed. SCK period al of 0.1 us renders 10 MHz, which is to fast if crystal is working at 8 MHz. Not sure where to change it in Arduino environment, but you should add this key to avrdude.exe run string:

`avrdude.exe -B 8`

This will set programming speed to 125 kHz. Also I suggest you to buy a cheap USBasp programmer from eBay or AliExpress. It is well documented and have plenty GUI programs, running on top of the avrdude. In newest Arduino IDE you can generate hex files in the sketch directory, and burn it with programmer.


message:
HC-05 can not use lower pins only 8 and higher

#include <Arduino.h>
    #include <SoftwareSerial.h>

    char Incoming_value = 0;

    // SoftwareSerial BTSerial( 10, 11 ); // RX | TX +
    // SoftwareSerial BTSerial( 9, 10 ); // RX | TX +
    // SoftwareSerial BTSerial( 8, 9 ); // RX | TX +
    // SoftwareSerial BTSerial( 7, 8 ); // RX | TX - ???
    // SoftwareSerial BTSerial( 6, 7 ); // RX | TX - ???
    // SoftwareSerial BTSerial( 5, 6 ); // RX | TX - ???
    // SoftwareSerial BTSerial( 4, 5 ); // RX | TX - ???
    // SoftwareSerial BTSerial( 3, 4 ); // RX | TX - ???

    SoftwareSerial BTSerial( 8, 9 ); // RX | TX +

    void setup() {
            BTSerial.begin( 9600 );
            pinMode( 13, OUTPUT);
    }

    void loop() {
            delay( 1000 );
            BTSerial.println( "hello" );
            if( BTSerial.available() > 0 ) {
                    BTSerial.println( "BINGO!" );
                    Incoming_value = BTSerial.read();
                    BTSerial.println( Incoming_value );
                    if ( Incoming_value == '1' ) digitalWrite( 13, HIGH );
                    else if ( Incoming_value == '0' ) digitalWrite( 13, LOW );
            }
    }

My HC-05 Bluetooth module wont't work on lowers digital pins.

> BOARD_TAG = leonardo

 - It works fine on highers digital pins: 8-9, 9-10 or 10-11 - everything fine.
 - but 2-3, 3-4, 4-5, 5-6, 6-7 or 7-8 - no....

Why? Should I inject jumper somewhere or what?

And yes: @Majenko, "0,1 - is required to debug from host". I want to have Serial from PC and BTSerial from bluetooth - to have both accesses to device simultaneously.

@Peter_Paul_Kiefer, so, you think, this is impossible with lowest pins, lower than 8?

body:
From the official SoftwareSerial Site: https://www.arduino.cc/en/Reference/softwareSerial (Section Limitations)

> Not all pins on the Leonardo and Micro support change interrupts, so
> only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15
> (SCK), 16 (MOSI).


message:
ESP32 + Fastled + WS2801

I'm using the ESP32 DevkitC board with Fastlib and a WS2801 LED strip.
The LED strips works fine, i connected it properly (sometimes all LEDs are on, no flickering).

I Connected the light strip's Data cable (blue) to GPIO16 and Clock cable (red) to GPIO17.
Compiling works but at first shows this error:

    "No hardware SPI pins defined.  All SPI access will default to bitbanged output"

When the script starts, only the first 3 LEDs are glowing in light blue (instead of blinking) - here's my code:

    #include <FastLED.h>

    // How many leds in your strip?
    #define NUM_LEDS 42

    // For led chips like Neopixels, which have a data line, ground, and power, you just
    // need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
    // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
    #define DATA_PIN 16
    #define CLOCK_PIN 17

    // Define the array of leds
    CRGB leds[NUM_LEDS];

    void setup() {
          // Uncomment/edit one of the following lines for your leds arrangement.
          // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
         // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
          // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);

          // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);

           FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
          // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    }

    void loop() {
      // Turn the LED on, then pause
      leds[0] = CRGB::Red;
      FastLED.show();
      delay(500);
      // Now turn the LED off, then pause
      leds[0] = CRGB::Black;
      FastLED.show();
      delay(500);
    }

Any ideas what's wrong?

body:
This is hard to debug from afar...

Your sketch looks correct (hardly surprising, since it's just the Blink example). But I'd try to use IO18/SPI_CLK for clock and IO23/SPI_MOSI for data, as these are the hardware SPI pins of the ESP32. It might very well be that using these pins removes the warning about hardware SPI.

As I don't know all the variants of a WS2801 strip... is it maybe one of those strips that runs at 12V and can only be cut every three LEDs? This would explain why there are three LEDs lighting up instead of one (because then there would be one chip for three LEDs -- in other words, each "pixel" in your leds array corresponds to three physical LEDs)

Then there might be a problem with the voltage output of your ESP32 board. The ESP is running at Vcc=3.3V. The chips of the strip are running at Vcc=5V and expect 5V on their inputs. A logical 1 is assumed when the input in question is 0.7 * Vcc, i.e. the input signal may not be less than 3.3V. Now imagine that the power regulator on your ESP board drives the ESP at a teensy bit less (e.g. at 3.25V) and the power supply for the strip outputs a teensy bit more (e.g. 5.1V) -- suddenly, a logical 1 from the ESP is at 0.637 times the strips' Vcc and therefore in the undefined limbo between 0.3*Vcc (highest definition for logical 0) and 0.7*Vcc (lowest definition for logical 1). A level shifter module would help here to increase the ESP's output signal voltage (costs a few cents when ordered directly from China).

Then, at last, are you sure that the color order of the strip is RGB (as stated in your setup line)? I've seen more strips using GRB or BGR... which would explain why you see blue instead of red.


message:
IDE / Plugin / Compiler / Language: Which combination is closest to best-practice embedded development in C or C++?

Currently I'm pretty far out to sea with a combination of Visual Studio Code, the Platform.io extension, while writing new code in C++ using avr-gcc.

I'm hoping for a combination that would offer the most crossover educational value, in the event that I potentially **experiment** (if only to prove the Arduino platform's **superiority** to any doubters) with non-Arduino-specific embedded development.

The default IDE seemed to present me with less information about the remarkably sound underpinnings and marvelous overall artistry with which they've woven the many different design techniques and languages together. I'm mainly curious about other (**inferior** to Arduino, mind you), more widely used combinations / tool chains in the world of embedded programming.

body:
A great deal of what you learn with any comprehensive IDE will transfer to another one, if you need to. The IDEs that come to mind are Eclipse (listed first, only because it is my personal choice and has a broad range of application), Visual Studio, and others I have no experience with.

The Arduino IDE is as limited as you found it, primarily because it was written as (1) a learning tool for (2) AVR-based Arduinos, and goes to some lengths to offer an easier entry into embedded systems programming for non-programmer hobbyists. To that end, it achieves its goal very well. But as you have observed, you quickly run into its limitations, especially when your goal is to branch out onto other processors and other tool-sets.

Once someone is over the hump of basic programming and debugging, more advanced tools like a full-on IDE take most of those limitations out of your way, at the cost of less hand-holding, but by that time, you presumably need the freedom much more than the help!

I don't want to outright tell you "You need to use FiddleFoo 18.4 or you'll never get anywhere" - one (or a couple) of the industrial strength IDEs will appeal to your view of programming and your personal work-style. Try a few of them, paying attention to what toolsets and processors each one can target with OEM or third-party support, for the processors you think you might become interested in. It's quite likely T-H-E right IDE for you will stand out from the rest.

Update:

Eclipse *will* need a plug-in to target Arduino and other embedded system boards. The one I use - and the only one being maintained AFAIK - is Sloeber by Jan Baeyens, who occasionally posts here as jantje. It is pretty comprehensive, including the ability to write and import new board descriptors.

Memory limitations come with the hardware, and while compiler advances can help this out, it's pretty much governed by the numbers. An Arduino Uno still has only 2K of RAM and 32K of Flash minus whatever the bootloader uses (if you choose to use a bootloader). Heap is still problematic for all the usual reasons - fragmentation of free memory (positioned, as it is, between static area and the bottom of the stack), and reduction of available stack and/or data space. There are, of course, more embedded boards available, with larger memories, but that just helps you put off the inevitable. I view the use of heap in an embedded system as a reliability issue even more than as a memory limitation; it is all too easy for fragmentation and memory leaks to eventually take down your system, and a Blue Screen Of Death is a big no-no in embedded systems.


message:
Arduino uno + 5 IR obstacle sensor

I have IR sensor with current draw 100ma i have to connect 5 of them is i can connect all 5 with arduino directly or i have to use external power suplly for them

body:
An Arduino UNO has a max current of 20 mA per IO Pin and a max current of 200 mA of all Pins together. If you intent to drive the senders with the pins then this is impossible.

If you power the Arduino with USB, the VCC current is limited to 500 mA (thermo fuses). If you power it externally, it depends on the power supply. Using the voltage from the Vcc Pin is risky (IMHO), because the Arduino needs power too.

So with 100 mA per sensor I would definitively use an external power supply.


message:
Why should I connect GND to RST to send data through Rx using USB-TTL?

I've found that when I use Arduino Nano connected with USB everything is working great, and when I tryed to use it with USB to TTL connector I've understood that I can only read data. I tryed to connect **GND** to **RST** as it was on some picture in Internet, and it works! Now I can send data through my USB to TTL (and through another UART device). So I can't uderstand, why should I do it? Why can't I just send data through Rx Arduino pin? Why do I need an extra action? Is it related with Arduino microcontroller?

body:
The key here is to remember the simple rules:

1. One device can send to many devices
2. One device can receive only from one device

In your situation you have three devices that are communicating:

* The USB to UART chip
* The on-board ATMega, and
* The off-board ATMega connected to the TX/RX pins.

All three of those are connected together through the TX and RX pins.  This means that:

* The UART chip sends to the on-board ATMega, and
* The UART chip sends to the off-board ATMega

This fits with rule 1 above: one device can talk to many devices.

But:

* The UART chip receives from the on-board ATMega, and
* The UART chip receives from the off-board ATMega

This breaks rule 2 above. You can't have two devices sending to one receiver.

By connecting the RESET pin to GND you are effectively turning off the on-board ATMega. It's like you removed it from the board. It's not allowed to do anything - including communicating with the UART chip.

So that fixes rule 2 above, because now you only have one device sending to the UART chip, not two.


message:
12V but what Ampere?

So if my arduino will draw around 800mA @5V and the dc-dc buck converter around 266mA @5V plus solenoid 1.2A @12V, is it a good idea to get 12V 4A (48W) power supply? Since Filip Franik told me that it is a good practice to get 2 times the current I need just in case. Then what will happen to the current that are no in use?

body:
So you want to use the 5V voltage regulator on the Arduino serve as the supply for your 5V components, and feed the 5V regulator from the 12V supply that powers your solenoid?

The problem with that plan is heat. The voltage regulator on the Arduino is a poorly heat-sinked (heat-sunk?) "linear" regulator. A linear voltage regulator is basically a solid state circuit that converts excess voltage to heat.

The higher the supply voltage you provide to the voltage regulator, the more heat it generates for a given current load.

If you feed 12V into the Arduino's voltage regulator, it needs to reduce the voltage from 12V to 5V. 12V - 5V is 7V. So it will convert 7V to heat. You're only drawing ≈220 mA. Total power that will be converted to heat is 7V*0.22A, or around 1.54 watts of power. You should budget for at least 50% more current than you think you'll need, so lets use 330 mA. 7.0*0.33 is about 2.3 watts.

From a little research I did, it sounds like a typical Arduino voltage regulator can dissipate around 1 watt of heat. You're well over that limit even at your low ≈220mA number, so you need a solution that won't overheat your Arduino's voltage regulator.

If you were to instead supply the Arduino's voltage regulator with 7.5V, it would have a lot less work to do. That's a voltage drop of 2.5V. So for a 0.33 max current draw, that would be 2.5*0.33, or about 0.83 watts. That would be under the 1 watt ceiling. However, it sounds like your project is based on a 12V supply.

You could instead use an external switching voltage regulator to reduce 12V to 5V. (search for "boost voltage regulator".) Those are much more efficient, and don't generate nearly as much heat. You could then feed regulated 5V directly into the USB input on your Arduino, as well as supplying it to your other 5V components.


body:
If my supply increase from 12V 1.5A to 4A. My arduino will draw around 800mA @5V (571mA @7V) plus solenoid 1.2A @12V, is it a good idea to get 12V 4A (48W) power supply? Since Filip Franik told me that it is a good practice to get 2 times the current I need just in case.

I know there is the efficiency of the converter is calculated by dividing the output power (Pout) by its input power (Pin) and then times the input current to get output current.

So for example 7V divide 12V is around 58.3% x 4A = 2.33A. Even if the solenoid takes 1.2A @12V, the current left is 2.8A, so the current is 1.63A, @ 7V. If arduino current draw what it needs and as long as it doesn't draw more than 2A, I think it is sufficient and safe.


message:
Is there a way for keypad to stop the buzzer while it is running?

I am new to arduino, currently I am looking for a way to make the keypad able to stop the buzzer making a siren alarm when password are keyed in wrong and able to move into password screen by pressing any button on the keypad. From all the videos i have seen, only 1 fits the way i want it to work.

https://www.hackster.io/thehack904/motion-sensing-alarm-with-keypad-password-53f05c

Below is the code I have completed with but i want to try adding a siren alarm function that is able to stop using keypad. Can anyone please teach me how to use a keypad to stop the buzzer and move into master key screen.

```
//Libraries
#include <LiquidCrystal.h>
#include <Keypad.h>

/*-------------------------------KEYPAD---------------------------------------*/
const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad
char keypressed;
char keymap[numRows][numCols] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {2, 3, 4, 5};//Rows 0 to 3
byte colPins[numCols] = {6, 7, 8, 9};//Columns 0 to 3
//initializes an instance of the Keypad class
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

/*-------------------------------CONSTANTS------------------------------------*/
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //LCD
const int buzzer = 10;        //Buzzer/small speaker
int solenoidPin = 11;         //Solenoid

/*-------------------------------VARIABLES------------------------------------*/
String password = "0"; //Variable to store the current password
String master_key = "999"; //Variable to store the master key
String tempPassword = ""; //Variable to store the input password
int doublecheck;    //Check twice the new passoword
boolean armed = false;  //Variable for system state (armed:true / unarmed:false)
boolean input_pass;   //Variable for input password (correct:true / wrong:false)
boolean storedPassword = true;
boolean changedPassword = false;
boolean checkPassword = false;
int i = 1; //variable to index an array
unsigned char WrongAttempts = 0; //global variable to keep the number of wrong attempts done at the code.

/*----------------------------------------------------------------------------*/
void setup() {
  lcd.begin(16, 2); //Setup the LCD's number of columns and rows
  pinMode(solenoidPin, OUTPUT);
  pinMode(buzzer, OUTPUT);
  Serial.begin(9600);
}

void loop() { //Main loop
  unlockTheDoor();
}
/********************************FUNCTIONS*************************************/
void unlockTheDoor() {
lockAgain: //goto label
  digitalWrite(solenoidPin, HIGH);       //Switch Solenoid OFF
  tempPassword = "";
  lcd.clear();
  i = 6;
  noTone(buzzer);
  while (!checkPassword) {
    lcd.setCursor(0, 0);
    lcd.print("Open the door:  ");
    lcd.setCursor(0, 1);
    lcd.print("PASS>");
    keypressed = myKeypad.getKey();   //Read pressed keys
    if (keypressed != NO_KEY) {   //Accept only numbers and * from keypad
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
          keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
          keypressed == '8' || keypressed == '9' ) {
        tempPassword += keypressed;
        lcd.setCursor(i, 1);
        lcd.print("*");       //Put * on lcd
        i++;
        tone(buzzer, 800, 200); //Button tone
      }
      else if (keypressed == 'A') {
        changePassword();
        goto lockAgain;
      }
      else if (keypressed == 'D') {
        break;
      }
      else if (keypressed == '*') { //Check for password
        if (password == tempPassword) { //If it's correct...
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Correct Password");
          lcd.setCursor(0, 1);
          lcd.print("Door is unlocked");
          tone(buzzer, 100);   //Play a tone while door is unlocked
          delay(100);        // ...for 0.1 sec
          noTone(buzzer);     // Stop sound...
          digitalWrite(solenoidPin, LOW);      //Switch Solenoid ON
          delay(5000);
          WrongAttempts = 0;
          changePassword(); {
            setLocked (true); ///.......to lock again
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(100);        // ...for 0.1 sec
            noTone(buzzer);     // Stop sound...
            delay(1000);
            lcd.clear();
            goto lockAgain;
          }
          if (keypressed == '#') {
            setLocked (true); ///.......to lock again
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(100);        // ...for 0.1 sec
            noTone(buzzer);     // Stop sound...
            delay(1000);
            lcd.clear();
            goto lockAgain;
          }
        }
        else {           //if it's false, retry
          tempPassword = "";
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("*Wrong Password*");
          tone(buzzer, 500, 200);
          delay(300);
          tone(buzzer, 500, 200);
          delay(300);
          WrongAttempts++;  //ADDED
          Attempts();
        }
      }
    }
  }
}

//Change current password
void changePassword() {
retry: //label for goto
  tempPassword = "";
  lcd.clear();
  i = 1;
  while (!changedPassword) {      //Waiting for current password
    keypressed = myKeypad.getKey();   //Read pressed keys
    lcd.setCursor(0, 0);
    lcd.print("CURRENT PASSWORD");
    lcd.setCursor(0, 1);
    lcd.print(">");
    if (keypressed != NO_KEY) {
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
          keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
          keypressed == '8' || keypressed == '9' ) {
        tempPassword += keypressed;
        lcd.setCursor(i, 1);
        lcd.print("*");
        i++;
        tone(buzzer, 800, 200);
      }
      else if (keypressed == '#') {
        break;
      }
      else if (keypressed == 'D') {
        goto retry;
      }
      else if (keypressed == '*') {
        i = 1;
        if (password == tempPassword) {
          storedPassword = false;
          tone(buzzer, 500, 200);
          newPassword();          //Password is corrent, so call the newPassword function
          break;
        }
        else {              //Try again
          tempPassword = "";
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("*Wrong Password*");
          tone(buzzer, 500, 200);
          delay(300);
          tone(buzzer, 500, 200);
          delay(300);
          WrongAttempts++;  //ADDED
          Attempts();
          goto retry;
        }
      }
    }
  }
}

String firstpass;
//Setup new password
void newPassword() {
retry: //label for goto
  tempPassword = "";
  changedPassword = false;
  lcd.clear();
  i = 1;
  while (!storedPassword) {
    keypressed = myKeypad.getKey();   //Read pressed keys
    if (doublecheck == 0) {
      lcd.setCursor(0, 0);
      lcd.print("SET NEW PASSWORD");
      lcd.setCursor(0, 1);
      lcd.print(">");
    }
    else {
      lcd.setCursor(0, 0);
      lcd.print("One more time...");
      lcd.setCursor(0, 1);
      lcd.print(">");
    }
    if (keypressed != NO_KEY) {
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
          keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
          keypressed == '8' || keypressed == '9' ) {
        tempPassword += keypressed;
        lcd.setCursor(i, 1);
        lcd.print("*");
        i++;
        tone(buzzer, 800, 200);
      }
      else if (keypressed == '#') {
        break;
      }
      else if (keypressed == 'D') {
        goto retry;
      }
      else if (keypressed == '*') {
        if (doublecheck == 0) {
          firstpass = tempPassword;
          doublecheck = 1;
          newPassword();
        }
        if (doublecheck == 1) {
          doublecheck = 0;
          if (firstpass == tempPassword) {
            i = 1;
            firstpass = "";
            password = tempPassword; // New password saved
            tempPassword = ""; //erase temp password
            lcd.setCursor(0, 0);
            lcd.print("PASSWORD CHANGED");
            lcd.setCursor(0, 1);
            lcd.print("----------------");
            storedPassword = true;
            tone(buzzer, 500, 400);
            delay(2000);
            lcd.clear();
            break;
          }
          else {
            firstpass = "";
            newPassword();
          }
        }
      }
    }
  }
}

void setLocked(int locked) {
  if (locked) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("*** LOCKED ***");
  }
  else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("*** UNLOCKED ***");;
  }
}

void Attempts() {
  if (WrongAttempts >= 3) { //UPS....
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("TO UNLOCK PLEASE");
    lcd.setCursor(0, 1);
    lcd.print("INPUT MASTER KEY");
    digitalWrite(buzzer, HIGH);
    delay (5000);
    master();
  }
}

void master() {
lockAgain: //goto label
retry: //label for goto
  tempPassword = "";
  lcd.clear();
  i = 6;
  noTone(buzzer);
  while (!checkPassword) {
    lcd.setCursor(0, 0);
    lcd.print("***MASTER KEY***");
    lcd.setCursor(0, 1);
    lcd.print(">");
    keypressed = myKeypad.getKey();   //Read pressed keys
    if (keypressed != NO_KEY) {   //Accept only numbers and * from keypad
      if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
          keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
          keypressed == '8' || keypressed == '9' ) {
        tempPassword += keypressed;
        lcd.setCursor(i, 1);
        lcd.print("*");       //Put * on lcd
        i++;
        tone(buzzer, 800, 200); //Button tone
      }
      else if (keypressed == 'D') {
        goto retry;
      }
      else if (keypressed == '*') { //Check for password
        if (master_key == tempPassword) { //If it's correct...
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Correct Password");
          lcd.setCursor(0, 1);
          lcd.print("Door is unlocked");
          tone(buzzer, 100);   //Play a tone while door is unlocked
          delay(100);        // ...for 0.1 sec
          noTone(buzzer);     // Stop sound...
          digitalWrite(solenoidPin, LOW);      //Switch Solenoid ON
          delay(5000);
          WrongAttempts = 0;
          changePassword(); {
            setLocked (true); ///.......to lock again
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(100);        // ...for 0.1 sec
            noTone(buzzer);     // Stop sound...
            delay(1000);
            lcd.clear();
            unlockTheDoor();
          }
          if (keypressed == '#') {
            setLocked (true); ///.......to lock again
            tone(buzzer, 1000); // Send 1KHz sound signal...
            delay(100);        // ...for 0.1 sec
            noTone(buzzer);     // Stop sound...
            delay(1000);
            lcd.clear();
            unlockTheDoor();
          }
        }
        else {           //if it's false, retry
          tempPassword = "";
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("*Wrong Password*");
          tone(buzzer, 500, 200);
          delay(300);
          tone(buzzer, 500, 200);
          delay(300);
          WrongAttempts++;  //ADDED
          Attempts();
        }
      }
    }
  }
}

body:
Consider defining exactly what you want your Arduino application to do using a [state machine][1] approach.  Drafting a state machine diagram allows a developer to visualize the inputs to the state machine, the number & types of states necessary and the outputs of the state machine.  The following diagram from the above wikipedia.org link has two states:

[![enter image description here][2]][2]

A "Locked" and an "Unlocked" state.  You see that a "Coin" is necessary to change from the "Locked" to the "Unlocked" state.

For the number-coded-lock in the question there are likely many more state to consider.  For instance, there may be a state for each button number entered.  The correct number will advance to the next state.  The incorrect number will revert to the state where the state machine expects to see the 1st number in the code.  If all the numbers in the code have been entered correctly, the last state will likely be the state that unlocks the device. A buzzer may have a state of its own.  While in the buzzer state the buzzer will be making noise.  An input to the state machine indicating that 1/2 second has elapsed could be used to exit from the buzzer state.

In this way any desired behavior can be created.  In addition, by using a state diagram, the intentions of the final program are made clear.  And any logical errors are exposed before code creation.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine
  [2]: https://i.stack.imgur.com/LwGBV.png


message:
Function pointer call results in InstrFetchProhibited (ESP32)

I have the following issue which I'm unable to resolve by myself. Perhaps one of you could point me to issues in my code which I don't see.

There is a class called _communicator_ which handles an MQTT connection. I use ```PubSubClient``` as a MQTT client. The constructor of ```communicator``` looks like the following. Besides connection arguments, it also receives an array of structs ```SubscriptionHandler```. These structs define which topics should be subscribed to and also point to a callback method. When a ```communicator``` receives a MQTT message, it compares the topic to the known ones and calls the appropriate callback.

```cpp
Communicator(char * mqttBrokerIP, uint16_t mqttBrokerPort, char *mqttUsername, char * mqttPassword, char * mqttClientHostname, SubscriptionHandler subscriptionHandlers[], int lenHandlers);
```

**SubscriptionHandler**. is defined like this:

```cpp
typedef void (*callback)();

struct SubscriptionHandler
{
    char *Topic;
    callback Callback;
};
```

I tried the following: In the main file, I defined two methods for demonstration purposes:

```cpp
void enableHandler()
{
  Serial.println("enable handler");
}

void disableHandler()
{
  Serial.println("disable handler");
}
```

The ```communicator``` is created in the ```setup()```-Method:
```cpp
SubscriptionHandler handlers[] = {{&strEnable, enableHandler},
                                    {&strDisable, disableHandler}};
```
callback (in _communicator.h_) ```typedef void (callback)();```

strings : ```String strEnable = ("test/" + hostname + "/command/enable");``` and the same for disable. Those are also defined in main.cpp –

As soon as the ```communicator``` receives a MQTT message, the ESP32 crashes with the following message:
```
Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x3ffc9306  PS      : 0x00060c30  A0      : 0x8017e97c  A1      : 0x3ffb1ed0
A2      : 0x3ffc9306  A3      : 0x3ffc9306  A4      : 0x3ffc9306  A5      : 0x3ffc1318
A6      : 0x3ffb1f44  A7      : 0x00000000  A8      : 0x800d4df0  A9      : 0x3ffb1eb0
A10     : 0x0000000d  A11     : 0x0000000b  A12     : 0x3ffc24a4  A13     : 0xa98b32f8
A14     : 0x3ffc1318  A15     : 0xff000000  SAR     : 0x00000004  EXCCAUSE: 0x00000014
EXCVADDR: 0x3ffc9304  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff

Backtrace: 0x3ffc9306:0x3ffb1ed0 0x4017e979:0x3ffb1f00 0x400e280e:0x3ffb1f20 0x400d4f3e:0x3ffb1f70 0x400d5cff:0x3ffb1f90 0x400e4c45:0x3ffb1fb0 0x400889dd:0x3ffb1fd0
```

Therefore, something is wrong with how I use the function pointer (or somewhere which I don't even think about). Could anyone give me a hint where I could start?

body: I found the issue. After moving ```SubscriptionHandler handlers[] = ... ``` out of the ```setup()-```method, the function calls work. Perhaps ```handlers``` gets overwritten after leaving the setupfunction scope. Could anyone validate my suspected reason?


message:
How to use existing (non-arduino-specific) library with subfolders in Arduino IDE?

I have a generic c++ library that i'd like to use in an arduino project without making changes to the library code.
The library contains subfolders and files in the library include other files of the same library with includes of the form

    #include "libraryroot/subfoldername/header.h"

I tried putting 'libaryroot' into C:/Users/Username/Documents/Arduino/libraries but while I can include headers that lie directly inside 'libraryroot' using `#include <filename.h>` (not `#include <libraryroot/filename.h>`), Arduino fails to find the headers these files include

How can I make use of such a library in Arduino without having to change the library?

body:
To utilize subfolders with any name in an Arduino library, you must use [the 1.5 library specification][1].

In libraries folder in your sketch folder, create a folder for the library. In this folder create a `src` subfolder and put the library source code into that subfolder. Then create a [library.properties file][2] in the root folder of the library with some dummy information. Fill the `includes` key with the main .h file of the library.

    Documents/
      Arduino/
       libraries/
         FooLib/
          src/
           subfoldername/
            header.h
            some.h
            some.cpp
           foolib.h
           foolib.cpp
          library.properties

In code then use in `#include` the path with src folder as starting location.

`#include <subfoldername/header.h>`

  [1]: https://arduino.github.io/arduino-cli/latest/library-specification/#15-library-format-rev-22
  [2]: https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format


message:
Solar powered ESP8266. WiFi module usage optimizations

Above all, I am quite new to the ESP8266 and micro controllers development as a whole. I am now working on a project which is quite simple for now. It basically looks like this:

[![enter image description here][1]][1]

As you can see, I have an **ESP8266** and some input peripheral. Everything works perfectly fine for the moment, I can read the inputs from the **motion sensor** and **4x3 keypad**. And, respectively I can output on the **relay** and the **5mm LED**. In order to make it a real IOT, I have connected it to the internet via [Thinger.IO][2]. So, I have my **ESP8266** constantly connected to this platform and I can track it anytime, from anywhere.

This is great. But, my optimal goal is to **power my configuration from a solar panel** and make it independent of the electricity distribution network.

The average working current of the whole system is about **313mA** (10000 mAh battery gets completely drained for 32 hours. Its output is 5V, 2.1A).

So, I am now in a search of the best solar panel to fit my needs. An ultimate one would have the following maximal dimensions: **30x35** cm. *I am not sure there's a single panel that I can use but I am interested to hear your opinion in this.*

Another aspect, that **I'd like to optimize is the constant internet connectivity**. Basically, I need to have my configuration connected to the internet only when keypad input was made or motion sensor detected something. During the rest of the time, I don't need to be connected to the internet and I assume WiFi module could be suspended somehow. Currently, my code uses [SmartConfig][3] and is looks like this:

    #include <ESP8266WIFI.h>

    void connectToWifi() {
      WiFi.mode(WIFI_STA);
      WiFi.beginSmartConfig();

      while(!WiFi.smartConfigDone()){
        delay(500);
      }
    }

    void setup() {
      connectToWifi();

    }

    void loop() {

    }

Everything works well. But, as I said, I'd like to be able to start/stop the WiFi module. I tried using the following API:

    void toggleWifi(bool isWakeUpCall) {
      if(isWakeUpCall)
        WiFi.forceSleepWake();
      else
        WiFi.forceSleepBegin(30000000);

      delay(500);
    }

but without much of a success. Once it gets into this portion of code, it gets completely disconnected and doesn't get connected anymore. I am now struggling with it.

I've read about the **sleep modes** [offered][4] by the ESP8266 but I don't think they are suitable for my case because I can not simulate external interrupt (*or maybe I can?*).

*I am really curious to hear your opinion on this.* :)

  [1]: https://i.stack.imgur.com/9J2Vr.png
  [2]: http://thinger.io
  [3]: https://play.google.com/store/apps/details?id=com.cmmakerclub.iot.esptouch&hl=bg
  [4]: https://www.espressif.com/sites/default/files/9b-esp8266-low_power_solutions_en_0.pdf

body:
As described [here][1] the ESP8266 can be waken up using Timer Wake Up or external interrupt. The idea is simple: almost everything inside the ESP is powered down (including Wi-Fi and/or System clock or even the CPU) with only a timer running which was told when to activate before the ESP went to sleep. After the desired amount of time has passed the timer triggers GPIO 16 or D0 and if that is connected to the reset pin of the ESP is resets and starts executing code again until it goes to sleep again. For your case you can configure your motion sensor to output a LOW when motion is detected and connect is to a GPIO pin and the reset pin, so it will trigger a restart when motion is detected and in the startup sequence you look at the pin where the sensor is connected and do what you have to do. For the keyboard to work you can have the timer set to reset every 5 seconds, so you would have to hold a button for 5 seconds waiting for the ESP to wake up and accept your input or you could make a dedicated button for waking up the ESP if you want to enter the code. In that case the you don't need a timer, since as you described the ESP only has to do anything if the keyboard is activated or if the motion sensor is triggered and since they can be connected as external interrupts they will wake up the ESP if needed. I would recommend to check out this [link][1] for further details about the code and hardware.

  [1]: https://randomnerdtutorials.com/esp8266-deep-sleep-with-arduino-ide/


message:
Esp32: upload eeprom file

I'd like to flash the eeprom sector with content so that the eeprom already holds data when it boots the first time.
How do I upload such an eeprom file like I would do with avrdude on an atmega? Is there a tool that can be installed in the arduino IDE like the data uploader?

body:
The ESP8266 has no EEPROM.

Instead the flash memory is *partitioned* into different areas for different purposes. One of those areas is set aside for "EEPROM Emulation" data.

To upload to that area you first need to know where that area is in the flash memory, and that is dependent on what partitioning scheme you are using at the moment.

Once you have worked that out (look in the partition scheme files in the core for more information) you can then use `esptool` to upload data to the right area of flash.


message:
Arduino - manually ceate objects (e.g. WiFi library)

By default, if i include the WiFi library, the object WiFi will be registered globally. How can i disable this behavior without changing the library file itself? (removing the definition "extern ...")
Or is there a way to delete the objects right after the inclusion? I just want to create the object manually when needed to save memory.

body:
I am not sure, if it would save enought memory to be worth the problems (it is just few bytes, buffers are created anyway), but lets say so.
Then you need modify the library to not creating the object, as it is allocated statically and cannot be removed later (and reclaim its memory). To protect all other projects it would be probably best to use special `#define` to disable it only in memory critical projects - so the Wire.h should contain something like

    #ifndef EXCLUDE_WIRE
    extern TwoWire Wire;
    #endif

and your program (`critical.ino`) should start with

    #define EXCLUDE_WIRE
    #include <Wire.h>

and then somewhere in `loop` / other function use

    TwoWire Wire;

as local variable. If you need to call other functions with it, then you have to send its address as a parameter.

Anyway you will not save nearly any memory, as nearly all variables in TwoWire ((and namely buffers) are `static` and so class variables and so are common for all instacies of TwoWire and allocated automatically if there is (possibly used) any instance of TwoWire anywhere in your program.

So it would be better to create your own library to use the same functionality, but make sure, that all such variables are instance variables and properly created and released at the right time. This would also allowe for changing the buffer sizes, if needed.

As it is under LGPL 2.0+ you are legally allowed to do that (provided you fullfill all licence conditions).


message:
Serial.write without a receiver

I'd like to send  a monitoring information (temperature) to a serial receiver periodically. The problem is I don't know if there is any monitoring service (serial receiver) and how fast it is reading. I only need the latest value. The problem is that serial.write will block if the buffer is full. If I skip writing if the buffer is full, a receiver will only get old data on the first connect. How can I replace data in the buffer or make sure there is only one dataset in the buffer?

body:
> The problem is that serial.write will block if the buffer is full.

Only until the bytes get sent out through the TX pin.

> If I skip writing if the buffer is full, a receiver will only get old data on the first connect.

No it won't. There is no "old" data.

> How can I replace data in the buffer or make sure there is only one dataset in the buffer?

You don't need to.

You are showing a fundamental misunderstanding of how serial works.  When you send data it just twiddles the TX pin in the right way with the right timing. If there is something connected to it that understands that twiddling at the speed it's being twiddled then it interprets it as serial data. If there's nothing to see that twiddling it still twiddles.  The "blocking" is only if you try and send more data than the serial port can physically send out in the time you're sending it.

If a serial port transmits in a forest and there is no one there to hear it, yes, it still makes a noise.


message:
Arduino long distance cable tester

We have a 50 pair cable running about 1.5-2 KM with some services running on different pairs. One pair has recently become intermittent and is losing connection for 1-2 seconds at random. It might happen a few times an hour, so I jumped the service onto another pair. There is a modem connected to the pair for communication between two sites.

When resistance tested with a multi meter with a loop in one end it was reading 330 Ohms. When using an oscar meter it was reading -2.4db which is the same readings for other pairs.

I would like to use an Arduino to monitor the line resistance for a few days and see if there are any spikes or breaks in the line. I was going to use an analog input as a multimeter by using a known resistor and the looped pair as the other resistor.

Does anybody think this will not work?

How else could I go about this?

body:
Sure, no reason that wouldn't work. For best results you want a known resistor of about the same resistance as, or a little below, the one you are measuring.

However, if what you are seeing is an actual open circuit then there's little benefit to measuring the resistance - you may as well just treat it as a switch or button, give it a large pullup, and use a digital input (or even an interrupt) to give a simple "OK / ERROR" signal.


body:
For data communications the problem is often more complicated than DC resistance. Data signals are AC, and subject to impedance, (not simple resistance) inductance, and capacitance, as well as RF interference. A pair that's fine for slow on/off switching of DC signals may not be fine for higher frequency data signals.

You can also get intermittent shorts between wires in one pair and other pairs, even if the connection between the wires in the test pair are fine.

Back in the day I worked for a company that sold and serviced mini-computers to the US House of Representatives. The house offices would run serial cables up through walls and ceilings, and also under carpets. We had some flaky cables, and finally figured out that the offices would run the cables under the carpet, but over carpet tack strips. As people walked over the carpet, it would sometimes cause the tack strips to poke through the insulation, causing shorts and RF noise in the cables, which would mysteriously go away later.

Checking DC resistance will let you find breaks in your wires, but you can't assume that if the DC resistance looks good, the pair is good.

I would suggest using a simple voltage divider and one of the input lines on the Arduino for simple resistance testing, but that will only get you so far.

What you really want is a signal generator and an oscilloscope. You should send test signals (With voltages and signal patterns that resemble your data signals) down one pair at a time, and look at the signals on the far end, checking all the pairs. You should see your test signal come through, with the wave pattern still recognizable on the target pair, and no significant leaking of the signal to other pairs.


message:
Help with arduino code

Thank you for seeing my post.

I am trying to write a code that lets "A" displayed on row 1 and row 0 alternately on the LCD. starting from (0,1) then (1,0)  then (2,1), then (3,0) etc..
when it reaches the last point is becomes "B" and bouncing back the other way until reaching the starting point when it becomes "A" again and repeat again..

I wrote this code but I got stuck at the end, I don't know how to bounce it back:

---

    // include the library code:
    #include <LiquidCrystal.h>

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);   // initialize the library with the numbers of the interface pins

    int x = 0;
    int y = 1;

    void setup()
    {
        lcd.begin(16, 2);
        lcd.clear();
    }

    void loop()
    {
        {
            {
                while (x < 15)
                {
                    lcd.setCursor(x, y);
                    lcd.print("A");
                    delay(250);

                    lcd.clear();
                    x = x + 1;
                    lcd.setCursor(x, y - 1);
                    lcd.print("A");
                    delay(250);

                    lcd.clear();
                    x + x++;
                }
            }
            {
                while (x = 15)
                    lcd.setCursor(15, 0);
                lcd.print("B");
                delay(2000);
                x--;
            }
        }
    }

body:
To me it seems, as if you have no knowledge about C/C++. ( I might be wrong. ;-) )

If you plan to do more programming projects, I advice you to learn the basics of this programming language before proceed with the projects. It would be hard thinking about an algorithm, if you don't know the tools to implement it.

In case you just need this once for a (let's say arts project [or homework ;-)] ), I add some example code. At the moment I have no chance to test the code. So it's blind written, and there might be typos. In about 8 hours I will have access to a test setup then I'll correct it if necessary.

    #include <LiquidCrystal.h>

    // Here you setup your LCD display
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    // you initialize the position where the next character
    // will be displayed (0,1) (x,y)
    int x = 0;
    int y = 1;
    // setup is only done once
    void setup()
    {
        // initialize the lcd lib to be used with a 16x2 LCD
        lcd.begin(16, 2);
        // erase all character from the display
        lcd.clear();
    }

    // the loop is executed again and again and ...
    void loop()
    {
        // move forward
        // as long as the position is less than 15
        // you allow x = 0, 1, 2, ... ,15 because
        // you increase two times in each loop step
        while (x < 15)
        {
            lcd.clear( );

            lcd.setCursor( x, y );
            lcd.print( "A" );
            delay( 250 );

            // step to the next position
            x = x + 1;
            // toggle y
            y = toggle( y );

            lcd.clear();
            lcd.setCursor( x, y );
            lcd.print( "A" );
            delay( 250 );

            // step to the next position
            x = x + 1;
            // toggle y
            y = toggle( y );
        }

        // now move backward
        // x is still 15 and you want to go backwards until x == 0
        while ( x > 0 )
        {
            lcd.clear( );

            lcd.setCursor( x, y );
            lcd.print( "B" );
            delay( 250 );

            // step to the next position
            x = x - 1;
            // toggle y
            y = toggle( y );

            lcd.clear( );
            lcd.setCursor( x, y );
            lcd.print( "B" );
            delay( 250 );

            // step to the next position
            x = x - 1;
            // toggle y
            y = toggle( y);
        }
    }

    // this is a subroutine that toggles y = 0 <-> 1
    int toggle( int yval )
    {
       // I use a ternary operator
       // in case y == 1, I return 0 and a 1 otherwise
       return ( yval == 1) ? 0 : 1;
    }


message:
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[![Schematics][1]][1].

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.

  [1]: https://i.stack.imgur.com/7BWC7.jpg

body:
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. [![PIR Power Isolation][1]][1]

  [1]: https://i.stack.imgur.com/iDTOr.jpg