message:
Pressure Switch 4-20mA

Im working on a project trying to read the pressure value from an Allen Bradley Pressure Transmitter 836P-D2NFGB20PA-D4 Ser.A
[![enter image description here][1]][1]

However the pin configuration that comes on the description along with the schematics its way different that the one i used before

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

And the circuit im using is like this one, on the top its the circuit from the pressure documentation, and the bot one it the one im wiring on my Arduino Uno.

However on arduino im reading a constant value of 230 that does not increase nor decrease when i apply pressure to mi sensor even when the lcd on my sensor displays the correct psi value.

[![enter image description here][3]][3]

    #include <LiquidCrystal.h> //libreria
    int V0 = 3;
    int RS= 4;
    int E = 5;

    int D4 = 6;
    int D5 = 7;
    int D6 = 8;
    int D7 = 9;
    LiquidCrystal lcd(RS, E, D4, D5, D6, D7); //Indicar los pins de la interfaz

    //Variables globales
    int SensorPin= 0; //Variable del pin de entrada del sensor
    int indice; //posicion del array de textos
    int presion; //variable para almacenar el valor obtenido del sensor(0 a 1023)
    int outputValue = 0;
    int state = 0;
    int prv_state = -1;

    #define ARRAYTXT 4 //Numero de textos a escribir

    void setup() {
      // put your setup code here, to run once:

    Serial.begin(9600);
    analogWrite(V0, 50);

    //lcd.begin(16, 2);
    //lcd.clear();
    //lcd.begin(Cols, Rows);
    }

    void loop() {

     //Configuramos un comando de textos
      String textos[ARRAYTXT] = {"Baja presion", "Presion normal", "Alta presion", "Apagar Maquina"};

      presion = analogRead(SensorPin); //obtenemos datos del sensor
        outputValue = map(presion, 175, 1023, 0, 367);

    //Indicamos los textos que se definieron en el comando texto al principio("Baja presion" = 0)
      if(outputValue < 50){
        indice = 0;
      } else{
        if(outputValue >=50 && outputValue < 100){
          indice = 1;
        }else{
          if(outputValue >=100 && outputValue < 200){
            indice = 2;
          }else{
            if(outputValue >=200 && outputValue < 350){
              indice= 3;
            }
          }
        }
      }
      //lcd.clear(); // se borran pantallas
      //lcd.setCursor(0, 0); //Escribimos en la fila de abajo
      Serial.print("PRESION: "); // escribimos mensaje en el lcd
      Serial.print(outputValue,DEC);
      Serial.println(" PSI");
      //lcd.setCursor(0, 1); //Escribimos en la fila de abajo
      Serial.println(textos[indice]); // Indicamos que imprima los indices
      //Serial.print("Psi ");
      //Serial.println(outputValue);
      delay(200); //Tiempo para repetir el mensaje(1 segundo)
      //lcd.clear();
    }

  [1]: https://i.stack.imgur.com/bIsj8.jpg
  [2]: https://i.stack.imgur.com/9dMJP.jpg
  [3]: https://i.stack.imgur.com/NImDe.jpg

body:
Your drawing is different from the drawing in the wiring diagram of that sensor: the resistor has to be connected right like the "4-20mA"-block in the drawing, (-) goes to ground. Measure the voltage directly at pin 2.
When reading the sensor's analog signal you can probably leave pin 4 floating.


sender: user

sender: assistant

body:
I think this is the connection you want. Leave out the OUT connection completely and use a 250 ohm resistor (the datasheet says < 0.5 kiloohm).[![enter image description here][1]][1]

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


message:
Motor does not rotate smoothly ( Even in High speed )

I am bhanuka and i am new to Stepper motors and to this library.

I am trying to control 4 NEMA 17 motors ( Different speeds in same time ) using 4 (four)  DM320t stepper driver. Actually i want to move the robot ( Robot has omni wheels) to coordinates according to the Gcode.
It seem like code is ok, but when i enter a G-code, motors start to rotate to correct direction but they don't give smooth rotation ( I can hear  clicking sound , motor seems jumping from step to step and motor get hot too much ).

I think the problem for this case is motor miss some steps.
here i have attach the code. Can someone help me to overcome this problem.
Thank you.

```
#include <AccelStepper.h>
#include <math.h>

int Gval;
int Xval, Yval, Zval;
int Fval;
int Ival, Jval;
String Gvalstr, Xvalstr, Yvalstr, Zvalstr, Fvalstr, Ivalstr, Jvalstr;
char Key;
String code; // parameters of G code Translator, It will execute the code
String ab; // Para of G code translator, For come to Gcode function

AccelStepper w1(1, 2, 3); // pin 3 = step, pin 6 = direction
AccelStepper w2(1, 49, 51); // pin 4 = step, pin 7 = direction
AccelStepper w3(1, 5, 6); // pin 3 = step, pin 6 = direction
AccelStepper w4(1, 8, 9); // pin 4 = step, pin 7 = direction

int w1_enb = 4;
int w2_enb = 53;
int w3_enb = 7;
int w4_enb = 10;
char x ; // x cordinate
char y ; // x cordinate
char command; // case vari.
char com;

String inString = "";

void setup() {
  digitalWrite(w1_enb, HIGH);
  digitalWrite(w2_enb, HIGH);
  digitalWrite(w3_enb, HIGH);
  digitalWrite(w4_enb, HIGH);

  Serial.begin(9600);
  Serial.println("G code");

}

void loop() {
  Gvalstr = "";
  Xvalstr = "";
  Yvalstr = "";
  Zvalstr = "";
  Fvalstr = "";
  Ivalstr = "";
  Jvalstr = "";

  String code;
  if (Serial.available() > 0 ) {
    ab = Serial.readString();
    Gcode();
  }
  else {}

}

void Gcode () {
  code = ab;
  Serial.println("code is " + ab);
  //Serial.println(code);
  //String code = "G01 X1 Y1 F200 T01 M03 S500";
  int len = code.length();
  for (int i = 0; i < len; i++) {

    if (code[i] == 'G')Key = 'G';
    else if (code[i] == 'X')Key = 'X';
    else if (code[i] == 'Y')Key = 'Y';
    else if (code[i] == 'Z')Key = 'Z';
    else if (code[i] == 'F')Key = 'F';
    else if (code[i] == 'i')Key = 'i';
    else if (code[i] == 'j')Key = 'j';
    else if (isdigit(code[i]) || code[i] == '-') {
      if (Key == 'G') {
        Gvalstr += code[i];
      }
      else if (Key == 'X') {
        Xvalstr += code[i];
      }
      else if (Key == 'Y') {
        Yvalstr += code[i];
      }
      else if (Key == 'Z') {
        Zvalstr += code[i];
      }
      else if (Key == 'F') {
        Fvalstr += code[i];
      }
      else if (Key == 'i') {
        Ivalstr += code[i];
      }
      else if (Key == 'j') {
        Jvalstr += code[i];
      }

    }
    else
    {
      Key = '-1';
    }

  }

  Gval = Gvalstr.toInt();
  Xval = Xvalstr.toInt();
  Yval = Yvalstr.toInt();
  Fval = Fvalstr.toInt();

  Serial.println( Gval);
  Serial.println (Xval);
  Serial.println (Yval);
  Serial.println (Fval);

  switch (Gval) {

    case 0:
      motor_setup(Xval, Yval);
      //Serial.println("**********");
      break;
    case 1:
      motor_setup(Xval, Yval);
      //Serial.println("**-------");
      break;

    case 2:
      motor_setup(Xval, Yval);
      break;

    case 3:
      motor_setup(Xval, Yval);
      break;

    case 90:
      motor_setup(Xval, Yval);
      break;

    case 91:
      motor_setup(Xval, Yval);
      break;

    case 92:
      motor_setup(Xval, Yval);
      break;

  }
}

void motor_setup (int Xval , int Yval) {

  double Xprojection;
  double Yprojection;

  if (Yval == 0 ) {

    if (Xval > 0) {
      Xprojection = '1';
    }

    else if (Xval == 0) {
      Xprojection = 0;

    }

    else {

      Xprojection = -1;
    }
    Serial.println("Xprojection in if ");
    Serial.println(Xprojection);

    Yprojection = 0;

  }
  else {
    float alpha = Yval / Xval;
    Serial.println("CALCULATING");
    Serial.println(alpha);

    double atanval = atan(alpha);
    Xprojection = cos(atanval);
    Yprojection = sin(atanval);

    Serial.println("X_projection : ");
    Serial.println(Xprojection);

    Serial.println("Y_projection : ");
    Serial.println(Yprojection);
  }

  float W1, W2, W3, W4;  // Radial Velocity required to move to Position

  W1 = float ( -0.35 * Xprojection + 0.35 * Yprojection) ;
  W2 = float (-0.35 * Xprojection - 0.35 * Yprojection );
  W3 = float ( 0.35 * Xprojection - 0.35 * Yprojection );
  W4 = float (0.35 * Xprojection + 0.35 * Yprojection );

  Serial.println ("Velocity components ");
  Serial.println (W1);
  Serial.println (W2);
  Serial.println (W3);
  Serial.println (W4);
  Serial.println('\n');

  long c = 20;    // these values for testing
  long d = 20;
  long e = 20;
  long f = 20;

  w1.setMaxSpeed(2);
  w1.setAcceleration(12);
  w1.moveTo( Xval );

  w2.setMaxSpeed(2);
  w2.setAcceleration(12);
  w2.moveTo( Yval);

  w3.setMaxSpeed(2);
  w3.setAcceleration(12);
  w3.moveTo( -Xval);

  w4.setMaxSpeed(2);
  w4.setAcceleration(12);
  w4.moveTo( -Yval );

  while (w1.distanceToGo() != 0 || w2.distanceToGo() != 0 || w3.distanceToGo() != 0 || w4.distanceToGo() != 0) {
    w1.run();
    w2.run();
    w3.run();
    w4.run();

  }

  Serial.println("Executed");
  Serial.println("Next GCODE");
  Serial.flush();

}

```

body: The problem was the Supply Voltage. I have connected it to 24DC V. when i connect it to 12V problem was solved.


message:
How should I connect 5 buttons to arduino so that I can use the least number of inputs all the buttons are connected to ground

The problem here is that I want to connect 5 input buttons to an Arduino but I do not want to utilize 5 input pins of Arduino, is there any matrix like connection using which I can reduce the number of inputs used. The conditions here are:

 - All the buttons will be connected to ground and initialized using:

   `pinMode(PIN_NUMBER, INPUT_PULLUP)`

 - Only digital input is required and not analogue

body:
If all switches have one input grounded, you cannot use matrixing.

In any case, the best you could do would be a 2 * 3 matrix, which uses 5 signals, the same as individual switching (though you may be able to share the strobes with other signals e.g. display strobes)

If you are allowed to use an analog input you can pull the input high with one resistor, and allow each switch to pull it low with a different resistance. Then each switch results in a different analog voltage and you can decipher an ADC reading into a switch input. That way, only one input is required.


body:
If you do not want to use analog input but not opposed to adding one more component then you can get by with 3 digital pins, two connected to shift register (e.g. [SN74HC164][1]) and one reading common return from all buttons. Binary counter can also be used, but with rather high latency.

If you are OK with complicating things even more, you can use external logic for initializing the register, in which case two pins would be sufficient - one for clock output and another for feedback input.

Here is a simple circuit that can be extended to scan any number of buttons by chaining registers or choosing chips with more bits.

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

Unlike the answers stretching "digital input" function (as implied by OP) to include PWM and Serial communication, this method uses simplest digital I/O: one pin cyclically selects the button, another reads whether it is pressed or not.

The same 2-pin principle (selector output + feedback input) can be used in many different combinations. For example, you can have one side of each switch connected to the ground, as you mentioned in your question. The other sides are fed back to Arduino via analog MUX (e.g. 74HC4051). The MUX address is selected by binary counter (e.g. 74HC193) and the counter is reset by its own QD pin when it reaches 0x08.

  [1]: http://www.ti.com/lit/ds/symlink/sn74hc164.pdf
  [2]: https://i.stack.imgur.com/RSPLO.png


body:
> Only digital input is required and not analogue

I'd consider arranging the switches to produce different voltages depending on which button was pressed and feed the resulting analogue signal level into one of these (the MOD input): -

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

It doesn't need to run at 1 MHz of course; RSET can be chosen to make it free run at (say) 1 kHz. The resulting duty cycle (set by the switches) can be read under software control via a digital input line.

  [1]: https://i.stack.imgur.com/KXaMm.png


body:
If you have only one digital pin available, you might consider the [1-wire](https://playground.arduino.cc/Learning/OneWire/) bus. For example, the [DS2408](https://www.maximintegrated.com/en/products/ibutton/memory-products/DS2408.html) provides 8 open-drain GPIO pins.

---

If you can use an analog input pin, then [Brian's answer](https://arduino.stackexchange.com/a/71642/614) is correct.

Some simple adjustments of the resistor values create equal-size voltage steps for the A/D converter as shown below.

[![schematic][1]][1]

For the 4-switch case, this gives 5V for no switch pressed, and 0-3.75V in approximately equal steps for a switch press. This approach works well up to 16 switches and beyond.

The general approach for calculating the resistor values is as follows:

1. Select the pullup resistor value; say, 10K ohms.
2. Decide how many switches are required: N = 16.
3. The top switch generates 0 volts by shorting the A/D input to ground.
4. The next switch down will generate Vcc / N volts:

 R = 10k × 1/(N-1) = 666.7 Ω

5. Select the nearest standard 5% value: 680 ohms
6. Repeat for switches i = 2 through N - 1:

  - The next switch down will generate Vcc × i / N volts, but you must subtract out the values of the resistors above it. This helps avoid cumulative errors.

      R = 10K × i/(N - i) - 680 Ω - ...

  - Select the nearest standard 5% value.

For the specific example of 16 switches, you should end up with the following resistor values: 680, 750, 910, 1000, 1200, 1500, 1800, 2200, 2700, 3900, 5600, 7500, 13K, 27K and 82K. Even with 5% resistors, all of the resulting voltages are within 0.25% of full scale of their nominal values.

  [1]: https://i.stack.imgur.com/3og9b.gif


message:
How to send data from PC to arduino?

How can I read data in Arduino IDE from a text file, if I have a text file which has the angle of arm at the different time intervals? If I want to read a text file from PC, can anyone please show the demonstration code as well? I am attaching a code where I am writing a position to servo1 whose values I want to give via text file.

    #include <Servo.h>

    Servo myservo1 ;
    int pos1 = 0;

    void setup() {
      myservo1.attach(4);   //inner
    }

    void loop() {
       myservo1.write(pos1); // pos1 I will give different angles via text file
    }

If I am not using SD card module, how can I do this with PC only? Someone please help.

body:
I assume you want to store multiple values in the text file, and then
have the Arduino IDE (not the Arduino itself) read the file and insert
the data into your sketch. If this is really what your question is
about, a quick and dirty solution would be as follows:

1. Format the text file as a list of comma-separated numbers, either in
one or several lines. For example:

```text
1, 12, 23, 34, 45, 56, 67,
78, 89, 100
```

2. Include this file in your sketch as the body of an array initializer:

```c++
#include <Servo.h>

const int positions[] = {
#include "full_path_of_the_file_holding_the_positions"
};
#define positions_length (sizeof positions / sizeof positions[0])

Servo myservo1;

void setup() {
    myservo1.attach(4);
}

void loop() {
    for (int i = 0; i < positions_length; i++) {
        myservo1.write(positions[i]);
        delay(200);
    }
}
```


message:
Connecting an Arduino Nano to a Raspberry Pi Zero

I'm working with an [Arduino Nano Every][1], and I'm trying to connect it to the [Raspberry Pi Zero][2] for data collection from I2C sensors and writing/program code from the Pi to the Arduino. Typically, I would use a USB cable to connect from the Pi to the Arduino. However, this is going to be in an area where space is limited, so I'm looking for ways to connect the Arduino to the Pi that does not involve a USB cable. Are there other ways for the Pi and the Arduino to communicate the same way as if they were connected together via USB cable, perhaps through the Raspberry Pi's GPIO pins? What are some advantages/disadvantages of doing it in other ways?

EDIT: Something that also occurred to me: When connecting the Arduino to the Pi, to ensure that the Arduino has enough power, is there no choice but to use USB?

  [1]: https://store.arduino.cc/usa/nano-every
  [2]: https://www.adafruit.com/product/2885

body:
You can connect via:

* UART
* I2C
* SPI

All are available on the Pi's GPIO header and on the Arduino. You will of course need logic level translation for a 5V Arduino.

Using UART is probably simplest for you since that is identical to using the USB - you just use /dev/ttyS0 (or /dev/ttyAMA0 on older Raspberries) instead of /dev/ttyUSB0 or /dev/ttyACM0.  Just connect the Pi TX to the Arduino RX, and the Arduino TX to the Pi RX through logic level translation (voltage divider is a possibility).


body:
![enter image description here](https://i.stack.imgur.com/K0s1a.jpg)

The pi zero w has micro usb and the arduino nano has mini usb.

Can we use mini-micro usb cable to connect them?


message:
Arduino AT not working (Arduino UNO and HC-06)

Recently had issues with HC-06 AND Arduino UNO. Turned out that the last module was not working, this module keeps flashing and it appeared in the Bluetooth list.
I'm trying to work with some AT commands but for some reason this doesn't work. This module is brand new (ZS-040).
[![enter image description here][1]][1]

    #include <SoftwareSerial.h>

    SoftwareSerial btSerial(2, 3); // RX, TX
    /*
     * Connect pin 2 Arduino to pin TX HC-06
     * Connect pin 3 Arduino to pin RX HC-06
     */
    void setup() {

    Serial.begin(9600);

    Serial.println("Enter AT commands:");

    btSerial.begin(9600);

    }

    void loop()

    {

    if (btSerial.available())

    Serial.write(btSerial.read());

    if (Serial.available())

    btSerial.write(Serial.read());

    }

I uploaded the code, went into Serial Monitor. When I type a command, I get no reply. I opened "Arduino Bluetooth" app,connected to my phone and when I type something in the terminal on my phone I see the text on my PC's Serial Monitor screen.
Any ideas what I should do next? Could it be something to do with the RX pin? Should I use voltage divider? I have 1k and 2k Ohm resistors, how should I connect them if that's the solution?

  [1]: https://i.stack.imgur.com/rvVJf.png

body:
1. Use a macro like this to send AT commands:

        #include <SoftwareSerial.h>

        SoftwareSerial btSerial(2, 3); // RX, TX
        /*
         * Connect pin 2 Arduino to pin TX HC-06
         * Connect pin 3 Arduino to pin RX HC-06
         */
        void setup() {

        Serial.begin(9600);

        Serial.println("Enter AT commands:");

        btSerial.begin(9600);

        }

        void loop()

        {

        if (btSerial.available())

        Serial.write(btSerial.read());

        if (Serial.available())

        btSerial.write(Serial.read());
        delay(1000);
        //btSerial.print("AT+PIN4321");
        //btSerial.print("AT+NAMEAlibaba");
        //btSerial.print("AT+BAUD4");

        }

2. You may have another port set on the HC 06 instead of 9600, like I had.
If so, try this code with all the possible port numbers and changing something like the password, and everytime you run the code - go check if it worked, this way you will find in wich port number you have your module.

good luck


message:
Serial Monitor is printing out weird values and skipping strings

I am currently working on a project with some friends. In short, we want to create a setup where when a button is pressed a thermal printer prints out a random sentence.

I am currently trying to get my code to work and to debug it with the Serial Monitor, but it prints out weird stuff.

The baud rate is the same for the monitor and the Serial.begin().

```
int checkSum[] = {-1, -1};

String stringPool[] =
                      {
                        "Satz 1", "Satz 2",
                        "Satz 3", "Satz 4",
                        "Satz 5", "Satz 6",
                        "Satz 7", "Satz 8",
                        "Satz 9", "Satz 10",
                        "Satz 11", "Satz 12",
                        "Satz 13", "Satz 14",
                        "Satz 15", "Satz 16",
                        "Satz 17", "Satz 18",
                        "Satz 19", "Satz 20",
                        "Satz 21", "Satz 22"
                      };

String chooseRandom ()
{
  bool isMaybeThreeTimes;
  int randomInt;

  do
  {
      randomInt = random( 0, sizeof( stringPool ) -1 );

      // first and further random number chosen
      if( checkSum[0] == -1 ) { checkSum[0] = randomInt; }
      else
      {
        checkSum[1] = checkSum[0];
        checkSum[0] = randomInt;
      }

      if( randomInt == checkSum[0] && randomInt == checkSum[1] )
      {
        isMaybeThreeTimes = true;
      }
      else
      {
        isMaybeThreeTimes = false;
      }

      Serial.print("Current random value: " + randomInt);
      delay(1000);
      Serial.print("Last random value: " + checkSum[0]);
      delay(1000);
      Serial.print("Last last random value: " + checkSum[1]);
      delay(1000);
      Serial.print("Three times in row?: " + isMaybeThreeTimes);
      delay(1000);

   } while ( isMaybeThreeTimes );

  return stringPool[randomInt];
}

void buttonPressed()
{
  String stringToPrint = chooseRandom();
  // Send the string to the adafruit printer.
  Serial.println(stringToPrint);
}

void setup()
{
    Serial.begin(19200);
    delay(2000);
    Serial.println("Setup finished");
    randomSeed(analogRead(0));

}

void loop()
{
    buttonPressed();
}
```

Any ideas why this is happening? I switched the baud rates changed delays and changed the places on where and how often and in which frequeny the method buttonPressed() is called.

Here a picture of the output:
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/PMtsg.png

body:
    int checkSum[] = {-1, -1};

    const String stringPool[] = {
                            "Satz 1", "Satz 2", "Satz 3", "Satz 4",
                            "Satz 5", "Satz 6", "Satz 7", "Satz 8",
                            "Satz 9", "Satz 10", "Satz 11", "Satz 12"
                          };

    const String& chooseRandom () {
      bool isMaybeThreeTimes;
      int randomInt;

      do {
          randomInt = random( 0, sizeof(stringPool) / sizeof(stringPool[0]));
          isMaybeThreeTimes = (randomInt == checkSum[0] && randomInt == checkSum[1] );

          Serial.print("Current random value: "); Serial.println(randomInt);
          delay(1000);
          Serial.print("Last random value: "); Serial.println(checkSum[0]);
          delay(1000);
          Serial.print("Last last random value: "); Serial.println(checkSum[1]);
          delay(1000);
          Serial.print("Three times in row?: ");
          Serial.println(isMaybeThreeTimes?"Yes":"No");
          delay(1000);
          checkSum[1] = checkSum[0]; // for next run
          checkSum[0] = randomInt;
      } while (isMaybeThreeTimes);
      return stringPool[randomInt];
    }

    void buttonPressed()
    {  // has nothing to do with button presses, just a test
      const String& stringToPrint = chooseRandom();  // waits 3 seconds
      // Send the string to the adafruit printer.
      Serial.println(stringToPrint);
    }

    void setup() {
        Serial.begin(19200);
        delay(2000);
        Serial.println("Setup finished");
        randomSeed(analogRead(0));
    }

    void loop() {
        buttonPressed();
    }

Some fixes, not tested.
Edit: some more fixes, tested.


message:
Error compiling code for Arduino/Genuino Uno. "multiple definition of `__vector_7"

#include <PulseSensorPlayground.h>

    int pulsePin = A0;                 // Pulse Sensor purple wire connected to analog pin A0
    int Redled = 7;  // The pin for the Red LED which notifies you if you're heart rate is increasing.
    int Greenled = 8; // The pin for the Green LED which notifies you if you're heart rate is stable.
    int buzzer = 9; // The pin for the piezo which plays music when you're heart rate is increasing.
    int music[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};//The frequency the piezo will play.

    // the follow variables are long's because the time, measured in miliseconds,
    // will quickly become a bigger number than can be stored in an int.
    long time = 0;         // the last time the output pin was toggled
    long debounce = 200;   // the debounce time, increase if the output flickers
    //push button part stop

    // Volatile Variables, used in the interrupt service routine!
    volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS
    volatile int Signal;                // holds the incoming raw data
    volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
    volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
    volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

    static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

    volatile int rate[10];                      // array to hold last ten IBI values
    volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
    volatile unsigned long lastBeatTime = 0;           // used to find IBI
    volatile int P = 512;                      // used to find peak in pulse wave, seeded
    volatile int T = 512;                     // used to find trough in pulse wave, seeded
    volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
    volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
    volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
    volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

    void setup()
    {

     pinMode(Redled, OUTPUT); //This defines the pin to be an output
     pinMode(Greenled, OUTPUT);//This defines that the Green Led will be an output.
     pinMode(buzzer,OUTPUT);//This defines that the piezo pin will be an output.

      Serial.begin(115200);
      interruptSetup();                // sets up to read Pulse Sensor signal every 2mS
                                        //   analogReference(EXTERNAL);

    }

    //  Continuous and does not stop
    void loop()
    {

       serialOutput();

      if (QS == true) // A Heartbeat Was Found
        {
          // BPM and IBI have been Determined
          // Quantified Self "QS" true when arduino finds a heartbeat
          serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
          QS = false; // reset the Quantified Self flag for next time
        }
       if (BPM > 50){ //If the heart rate is more than 55 BPM(Beats Per Minute) then...

        digitalWrite(Redled, HIGH);//The Red Led will turn on
        digitalWrite(Greenled, LOW);//Green Led will turn off

       }
       else if(BPM < 50)//If the heart rate is below 55 BPM then...
       {
       digitalWrite(Redled, LOW);//The Red Led will stay off
       digitalWrite(Greenled, HIGH);//The Green Led will stay on
       tone(3, 500, 1000);

       }
      delay(20); //  take a breakx

      }

    void interruptSetup()
    {
      // Initializes Timer2 to throw an interrupt every 2mS.
      TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
      TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
      OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
      TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
      sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
    }

    void serialOutput()
    {   // Decide How To Output Serial.
     if (serialVisual == true)
      {
         arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
      }
     else
      {
          sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
       }
    }

    void serialOutputWhenBeatHappens()
    {
     if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
       {
         Serial.print(" Heart-Beat Found ");  //ASCII Art Madness
         Serial.print("BPM: ");
         Serial.println(BPM);

         delay(300);

       }
     else
       {
         sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
         sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
       }
    }

    void arduinoSerialMonitorVisual(char symbol, int data )
    {
      const int sensorMin = 0;      // sensor minimum, discovered through experiment
      const int sensorMax = 100;    // sensor maximum, discovered through experiment
      int sensorReading = data; // map the sensor range to a range of 12 options:
      int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
      // do something different depending on the
      // range value:
    }

    void sendDataToSerial(char symbol, int data )
    {
       Serial.print(symbol);
       Serial.println(data);
    }

    ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
    {
      cli();                                      // disable interrupts while we do this
      Signal = analogRead(pulsePin);              // read the Pulse Sensor
      sampleCounter += 2;                         // keep track of the time in mS with this variable
      int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                                  //  find the peak and trough of the pulse wave
      if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
        {
          if (Signal < T) // T is the trough
          {
            T = Signal; // keep track of lowest point in pulse wave
          }
        }

      if(Signal > thresh && Signal > P)
        {          // thresh condition helps avoid noise
          P = Signal;                             // P is the peak
        }                                        // keep track of highest point in pulse wave

      //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
      // signal surges up in value every time there is a pulse
      if (N > 250)
      {                                   // avoid high frequency noise
        if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
          {
            Pulse = true;                               // set the Pulse flag when we think there is a pulse

            IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
            lastBeatTime = sampleCounter;               // keep track of time for next pulse

            if(secondBeat)
            {                        // if this is the second beat, if secondBeat == TRUE
              secondBeat = false;                  // clear secondBeat flag
              for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
              {
                rate[i] = IBI;
              }
            }

            if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
            {
              firstBeat = false;                   // clear firstBeat flag
              secondBeat = true;                   // set the second beat flag
              sei();                               // enable interrupts again
              return;                              // IBI value is unreliable so discard it
            }
          // keep a running total of the last 10 IBI values
          word runningTotal = 0;                  // clear the runningTotal variable

          for(int i=0; i<=8; i++)
            {                // shift data in the rate array
              rate[i] = rate[i+1];                  // and drop the oldest IBI value
              runningTotal += rate[i];              // add up the 9 oldest IBI values
            }

          rate[9] = IBI;                          // add the latest IBI to the rate array
          runningTotal += rate[9];                // add the latest IBI to runningTotal
          runningTotal /= 10;                     // average the last 10 IBI values
          BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
          QS = true;                              // set Quantified Self flag
          // QS FLAG IS NOT CLEARED INSIDE THIS ISR
        }
      }

      if (Signal < thresh && Pulse == true)
        {   // when the values are going down, the beat is over
          Pulse = false;                         // reset the Pulse flag so we can do it again
          amp = P - T;                           // get amplitude of the pulse wave
          thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
          P = thresh;                            // reset these for next time
          T = thresh;
        }

      if (N > 2500)
        {                           // if 2.5 seconds go by without a beat
          thresh = 512;                          // set thresh default
          P = 512;                               // set P default
          T = 512;                               // set T default
          lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
          firstBeat = true;                      // set these to avoid noise
          secondBeat = false;                    // when we get the heartbeat back
        }

      sei();                                   // enable interrupts when youre done!
    }// end isr

This is the error code I get

    Arduino: 1.8.10 (Windows 10), Board: "Arduino Uno"

    Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':

    (.text+0x0): multiple definition of `__vector_7'

    sketch\Heart_Beat_Sensor_Code.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

    collect2.exe: error: ld returned 1 exit status

    Multiple libraries were found for "PulseSensorPlayground.h"
     Used: C:\Users\amaan\Documents\Arduino\libraries\PulseSensor_Playground
    exit status 1
    Error compiling for board Arduino Uno.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

body:
Both the `tone()` command and the `PulseSensor_Playground` library use Timer 0's interrupt.  That means there are two implementations of the ISR for that interrupt. However you can only have one implementation of a function or ISR, so it conflicts.

You will have to modify the `PulseSensor_Playground` library to use a different timer. There may be a way in the code already (some libraries implement such a thing) - if not then you'll have to rewrite the library to use another timer.


message:
Arduino Nano Fried on Music Reactive Led Strip

I'm doing a project that involves an Arduino Nano, a sound detection microphone module and a RGB Led strip (individually adressable leds). I also bought an accumulator so I can connect everything straight to the outlet.

The problem is that on 12V this accumulator cannot power the led strip at all and when I connected it to the laptop the Nano micro USB fried after I did about 4 tests.

My question is why can't the accumulator power everything and why the Nano got fried from the laptop which should have even less power? Would an Arduino Mega solve the problem or is it something about the wiring? (the wiring was checked by someone with experience)

body:
I assume you are powering the Nano through VIN or USB, and you are then powering the LED strip from the Nano's 5V pin.

* From the 12V battery the current flows through an LM1117 linear voltage regulator. Draw too much current (>800mA) and it will overheat and either shut down (if it's a good one) or melt (if it's an inferior Chinese clone).
* From USB the current flows through an SS1P3L diode with a maximum rating of 1.5A. If you draw more than that you will blow the diode and the board will appear dead.

So basically you're drawing too much current.

The proper way of powering a setup like this is:

* USB connection to power the Arduino *only*
* 12V into a 5V switching ("buck") regulator rated for *at least* the maximum current the LED strip needs
* 5V switching regulator into the LED strip directly
* Connect the ground of the 5V to the ground of the Arduino

**or**

* 12V into a 5V switching ("buck") regulator rated for *at least* the maximum current the LED strip needs
* 5V switching regulator into the LED strip directly
* 5V switching regulator *also* to the 5V (and ground) pin of the Arduino to power the Arduino

**or**

As above but with a 5V power supply instead of the 12V and switching regulator

Note that it is important that your supply can provide you with *at least* as much current as the *peak* current your system will need.  If that is a problem then you can split the LED strip into chunks and power each chunk separately from a lower current supply.


message:
How many I2C lines does the Arduino Due have?

According to the [Arduino pin Mapping][1]

    20 PB12 SDA 3 6
    21 PB13 SCL 3 6
    70 PA17 SDA1 3 6
    71 PA18 SCL2 15 9

The first one seems pretty obvious, the second one though is confusing. They have different labels. I also do not see other SDA or SCL in the table. So is this a typo?

  [1]: https://www.arduino.cc/en/Hacking/PinMappingSAM3X

body:
According to the Wire library documentation https://forum.arduino.cc/index.php?topic=132130.0:

> The Arduino Due has two I2C / TWI interfaces SDA1 and SCL1 are near to
> the AREF pin and the additional one is on pins 20 and 21.

And the table:

Arduino Due: 20 (SDA), 21 (SCL), SDA1, SCL1

So it seems in your table SCL2 should be SCL1.


message:
EthernetClient not initializing properly

I am trying to make a connection with the EthernetClient, but it always fails with code 0. I decided to write a small code just to test if the client ever becomes ready, and as I suspected it does not.

```lang-cpp
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0x2A, 0x27, 0x55, 0x08, 0x1E, 0x6A};
IPAddress ip(172, 16, 48, 133);
EthernetClient client;

void setup() {
  Ethernet.init(10);
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  while (!Serial) {;}

  for (auto link = Ethernet.linkStatus(); link != LinkON; link = Ethernet.linkStatus()) {;}
  Serial.println("Link ON");

  while(!client){
    Serial.println("Client not ready");
    delay(1000);
  }

  Serial.println("Client ready!");
}

void loop() {}
```

If I try to run the code above, it gets stuck at the "Client not ready" loop, and I can't figure it out what I'm missing for it to work.

Obs.: I have already configured a web server with success with my shield, so I'm guessing the problem is not with it.

body:
An `EthernetClient` expects to connect to a remote socket. At no point do you instruct it to connect to a socket, so it never succeeds.

At some point before checking for a connection you need to initiate that connection:

    // arduino.cc is 100.24.172.113
    IPAddress server(100, 24, 172, 113);
    client.connect(server, 80);

The `if (client)` operation relies on `sockindex` having been assigned a valid value, and that is only ever done either by `EthernetClient::connect()` or by being explicitly set by `EthernetServer::available()`.


message:
MD5 Password in Sketch

I'm playing with Over The Air (OTA) updates in my LoLin. I can make connections to my router and OTA updates seem to work well.

I'm uncomfortable storing my WiFi router SSID and password unencrypted in every sketch. Can I store an encrypted password instead for use in `WiFi.begin()`?

For example, Linux has wpa_pasphrase, which generates a 32-byte number which is an encrypted version of the password which can safely be stored in plaintext configuration files.

body:
> Can I store an MD5 password hash instead

No. MD5 is a "trapdoor" algorithm. It's one-way. You can make a hash from a password but you *cannot* make a password from a hash.

You could AES encrypt it, but you would need to have the AES key in your sketch to decrypt the password, which just moves the problem elsewhere.

Typically in a real-world situation you wouldn't have either the SSID or the password in the sketch. Instead you'd create a configuration system which would allow you to set (and of course change) both the SSID and password at runtime, and have the data stored somewhere (either EEPROM or in a file in SPIFFS, for example).

You might want to take a look at [WiFiManager](https://github.com/tzapu/WiFiManager) which automates that process for you.


body:
I laud your intention and wish there were a good solution on the ESP8266 for what you're trying to do.

MD5 is a one-way hash function, so you won't be able to simply recover the original string to use in `WiFi.begin()`.

MD5 is also considered to be ["cryptographically broken and unsuitable for further use"][1] as of 2008. So if you're concerned about more than just a casual eavesdropping attack sniffing out your password, MD5 isn't considered good for any kind of security application these days.

You'd need to use some form of reversible encryption, but you'd still need to store the key somewhere. If you were using an ESP32, it has the capability of encrypting its flash storage, but the ESP8266 can't do that, so you'll always be vulnerable to someone recovering keys or passwords if they get sufficient access to the CPU.

  [1]: https://www.kb.cert.org/vuls/id/836068


body:
While it *IS* possible to reverse a password hash, especially MD5 (https://md5decrypt.net/en/), it doesn't buy you anything in the way of security since everyone else can also reverse them.

If you happen to have a second LoLin, you could set it up as an Access Point and have the first device connect to it instead of having it connect to your router. Then you could relay the communication to a PC over USB.

Sure, it's a bit of a pain, but it at least means that you don't have to expose your router's password on a device that someone can pick up and walk off with.


body:
I use Tzapu's WiFiManager https://github.com/tzapu/WiFiManager.

That starts your ESP as a WiFi access point (AP mode) which presents a web page at http://192.168.4.1 where you enter your WiFi SSID and password. It then stores the password and restarts WiFi as a station (STA mode).

On restart if the password is already stored then it just connects as a station.

If the SSID can't be found it runs the access point again.


message:
Can I put a T-mobile sim card into the SIM800L Module?

I am trying to connect my SIM800L module to my arduino, but am confused what kinds of sim cards work. My phone currently is an IPhone XS, and I would like to take my tmobile sim card from there and put it into the module. I talked to a tmobile rep and they said my card could handle 2G devices. Would this work? Thanks!

body: It might work but you'd be better off getting a 2G dedicated card.  Hologram.io has a developer card that is $5 and free 1MB / month or something.


message:
Maximum frequency that can be converted with Arduino Uno?

Arduino Uno Board use successive approach ADC of 12 bits and 16 MHz frequency clock. What is the maximum voice frequency can be converted using arduino uno board? I want the step by step solution with calculations.

body:
First of all, the ADC on the Uno is 10 bits, not 12.

The naive approach of having `analogRead()` in a tight loop can give you
up to 8.9 kS/s (112 µs per sample), but you won't be able to
do much else, as the CPU spends most of it's time just waiting for the
ADC to do its job. If you configure the ADC manually, then you can set
it into the so called “free running mode”. You then get about
9.6 kS/s (104 µs/S), but then the CPU is free to process one
sample while the next one is being converted.

If you need to go faster, you can tweak the frequency of the internal
ADC's clock. Then it's a compromise between speed and accuracy: the
faster you go the less accurate. You may get rough but kind of usable
samples at up to 77 kS/s (13 µs/S).

For a detailed comparison of the different clocking options, with speed
and accuracy estimation, see the article [ADC conversion on the Arduino
(analogRead)][gammon], by Nick Gammon.

[gammon]: https://www.gammon.com.au/adc


message:
Is it permissible to use strlcpy to copy an array to itself?

**Task:** delete "\n" at the beginning of the array.

**Example:**

    char s_msg[15] = "\nHello world!";

    void setup()
    {
      Serial.begin(115200);
      Serial.println("Load");
      // Search \n
      if(strstr(s_msg, "\n") != NULL) {
        Serial.println(s_msg);
        strlcpy(s_msg, &s_msg[1], sizeof(s_msg));
        Serial.println(s_msg);
      }
    }

    void loop() {}

**Description:**
If the \ n character is present at the beginning of the message, then we copy the original character to the same character, but without \ n.

**Question:** is it ok to copy char to itself (s_msg is the destination buffer and the source string at the same time)

body:
This [manual page of `strlcpy()`][strlcpy] is quite clear:

> If the `src` and `dst` strings overlap, the behavior is undefined.

This means you should avoid it, even if it works on some tests. The
advice you got of just trying is _not_ good advice. Use
[`memmove()`][memmove] instead.

[strlcpy]: https://www.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3
[memmove]: https://www.freebsd.org/cgi/man.cgi?query=memmove&sektion=3


message:
How to configure 8*8 Dot Matrix LED display with this particular code?

I'm making a cryptocurrency ticker using NodeMCU ESP8266 and have this code so far,  I don't know how to configure a dot matrix led 4 segments of 8*8 each with this particular code. The only thing I need is correction is the initialization of the display.

Here's the code:

```
/*******************************************************************
    A project to display crypto currency prices using an ESP8266

    Main Hardware:
    - NodeMCU Development Board (Any ESP8266 dev board will work)
    - dot matrix led 4 segments of 8*8

    Written by Brian Lough
    https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA
 *******************************************************************/

// ----------------------------
// Standard Libraries - Already Installed if you have ESP8266 set up
// ----------------------------

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#define MATRIX32
#include  <SPI.h>

// ----------------------------
// Additional Libraries - each one of these will need to be installed.
// ----------------------------

#include <CoinMarketCapApi.h>
// For Integrating with the CoinMarketCap.com API
// Available on the library manager (Search for "CoinMarket")
// https://github.com/witnessmenow/arduino-coinmarketcap-api

//#include "SH1106.h"
// The driver for the OLED display
// Available on the library manager (Search for "oled ssd1306")
// https://github.com/squix78/esp8266-oled-ssd1306

#include <ArduinoJson.h>
// !! NOTE !!: When installing this select an older version than V6 from the drop down
// Required by the CoinMarketCapApi Library for parsing the response
// Available on the library manager (Search for "arduino json")
// https://github.com/squix78/esp8266-oled-ssd1306

// ----------------------------
// Configurations - Update these
// ----------------------------

char ssid[] = "rum1";       // your network SSID (name)
char password[] = "@@mywifi34@@";  // your network key

// Pins based on your wiring
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA PIN 11
#define CS_PIN 10

//#define SCL_PIN D5
//#define SDA_PIN D4

// CoinMarketCap's limit is "no more than 10 per minute"
// Make sure to factor in if you are requesting more than one coin.
// We'll request a new value just before we change the screen so it's the most up to date
unsigned long screenChangeDelay = 10000; // Every 10 seconds

// Have tested up to 10, can probably do more
#define MAX_HOLDINGS 10

#define CURRENCY "eur" //See CoinMarketCap.com for currency options (usd, gbp etc)
#define CURRENCY_SYMBOL "E" // Euro doesn't seem to work, $ and £ do

// You also need to add your crypto currecnies in the setup function

// ----------------------------
// End of area you need to change
// ----------------------------

WiFiClientSecure client;
CoinMarketCapApi api(client);

display.begin(CS_PIN, MAX_DEVICES);

MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES);

//MD_Parola.h display(0x3c, SDA_PIN, SCL_PIN);

unsigned long screenChangeDue;

struct Holding {
  String tickerId;
  float amount;
  bool inUse;
  CMCTickerResponse lastResponse;
};

Holding holdings[MAX_HOLDINGS];

int currentIndex = -1;
String ipAddressString;

void addNewHolding(String tickerId, float amount = 0) {
  int index = getNextFreeHoldingIndex();
  if (index > -1) {
    holdings[index].tickerId = tickerId;
    holdings[index].amount = amount;
    holdings[index].inUse = true;
  }
}

void setup() {

  Serial.begin(115200);

  // ----------------------------
  // Holdings - Add your currencies here
  // ----------------------------
  // Go to the currencies coinmarketcap.com page
  // and take the tickerId from the URL (use bitcoin or ethereum as an example)

  addNewHolding("bitcoin");
  addNewHolding("dogecoin");
  addNewHolding("ethereum");

  // ----------------------------
  // Everything below can be thinkered with if you want but should work as is!
  // ----------------------------

  // Initialising the display
  display.init();
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, F("HODL Display"));
  display.setFont(ArialMT_Plain_10);
  display.drawString(64, 18, F("By Brian Lough"));
  display.display();

  // Set WiFi to station mode and disconnect from an AP if it was Previously
  // connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  ipAddressString = ip.toString();
}

int getNextFreeHoldingIndex() {
  for (int i = 0; i < MAX_HOLDINGS; i++) {
    if (!holdings[i].inUse) {
      return i;
    }
  }

  return -1;
}

int getNextIndex() {
  for (int i = currentIndex + 1; i < MAX_HOLDINGS; i++) {
    if (holdings[i].inUse) {
      return i;
    }
  }

  for (int j = 0; j <= currentIndex; j++) {
    if (holdings[j].inUse) {
      return j;
    }
  }

  return -1;
}

void displayHolding(int index) {

  CMCTickerResponse response = holdings[index].lastResponse;

  display.clear();

  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, response.symbol);
  display.setFont(ArialMT_Plain_24);
  double price = response.price_currency;
  if (price == 0) {
    price = response.price_usd;
  }
  display.drawString(64, 20, formatCurrency(price));
  display.setFont(ArialMT_Plain_16);
//  display.setTextAlignment(TEXT_ALIGN_CENTER);
//  display.drawString(64, 48, " 1h:" + String(response.percent_change_1h) + "%");
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.drawString(64, 48, "24h: " + String(response.percent_change_24h) + "%");

  display.display();
}

void displayMessage(String message){
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawStringMaxWidth(0, 0, 128, message);
  display.display();
}

String formatCurrency(float price) {
  String formattedCurrency = CURRENCY_SYMBOL;
  int pointsAfterDecimal = 6;
  if (price > 100) {
    pointsAfterDecimal = 2;
  } else if (price > 1) {
    pointsAfterDecimal = 4;
  }
  formattedCurrency.concat(String(price, pointsAfterDecimal));
  return formattedCurrency;
}

bool loadDataForHolding(int index) {
  int nextIndex = getNextIndex();
  if (nextIndex > -1 ) {
    holdings[index].lastResponse = api.GetTickerInfo(holdings[index].tickerId, CURRENCY);
    return holdings[index].lastResponse.error == "";
  }

  return false;
}

void loop() {
  unsigned long timeNow = millis();
  if ((timeNow > screenChangeDue))  {
    currentIndex = getNextIndex();
    if (currentIndex > -1) {
      if (loadDataForHolding(currentIndex)) {
        displayHolding(currentIndex);
      } else {
        displayMessage(F("Error loading data."));
      }
    } else {
      displayMessage(F("No funds to display. Edit the setup to add them"));
    }
    screenChangeDue = timeNow + screenChangeDelay;
  }
}
```
And here's the error:

```
crytodisplayDraft1:82:1: error: 'display' does not name a type

 display.begin(CS_PIN, MAX_DEVICES);

 ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void setup()':

crytodisplayDraft1:130:3: error: 'display' was not declared in this scope

   display.init();

   ^

crytodisplayDraft1:131:28: error: 'TEXT_ALIGN_CENTER' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_CENTER);

                            ^

crytodisplayDraft1:132:19: error: 'ArialMT_Plain_16' was not declared in this scope

   display.setFont(ArialMT_Plain_16);

                   ^

crytodisplayDraft1:134:19: error: 'ArialMT_Plain_10' was not declared in this scope

   display.setFont(ArialMT_Plain_10);

                   ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void displayHolding(int)':

crytodisplayDraft1:191:3: error: 'display' was not declared in this scope

   display.clear();

   ^

crytodisplayDraft1:193:28: error: 'TEXT_ALIGN_CENTER' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_CENTER);

                            ^

crytodisplayDraft1:194:19: error: 'ArialMT_Plain_16' was not declared in this scope

   display.setFont(ArialMT_Plain_16);

                   ^

crytodisplayDraft1:196:19: error: 'ArialMT_Plain_24' was not declared in this scope

   display.setFont(ArialMT_Plain_24);

                   ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void displayMessage(String)':

crytodisplayDraft1:212:3: error: 'display' was not declared in this scope

   display.clear();

   ^

crytodisplayDraft1:213:19: error: 'ArialMT_Plain_10' was not declared in this scope

   display.setFont(ArialMT_Plain_10);

                   ^

crytodisplayDraft1:214:28: error: 'TEXT_ALIGN_LEFT' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_LEFT);

                            ^

Multiple libraries were found for "Wire.h"
 Använd: C:\Users\SUDU0005\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.6.3\libraries\Wire
Oanvänd: C:\Users\SUDU0005\Documents\Arduino\libraries\Wire
exit status 1
'display' does not name a type
```
So, how do I configure the display?

body:
First and major point, is that if you want to repeat existing device, then you have wrong hardware. Comments in the code tell us:

     Main Hardware:
    - NodeMCU Development Board (Any ESP8266 dev board will work)
    - **OLED I2C Display (SH1106)**

You have dot matrix display with MAX7219 chip (most likely), which uses completely different library to work with. Microcontrollers are not like PCs, if you change a display, you should seriously rework the code. All code like `display.something()` has to be re-written. MD_Parola seems to be a library for interfacing your dot matrix display. You instantiate an object of that library: `MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES);` but then never use created object `P` anywhere (also, this a bad name for an object. `display` or `matrix` are much better). Instead, code uses object `display`, which is never created - that's exactly what compiler is trying to tell you:

    error: 'display' was not declared in this scope
So. to summarize: in order to change your code, you have to study MD_Parola lib, and seriously change all functions related to display. Obviously, that's beyond a scope of a simple question...

  [1]: https://github.com/nickgammon/MAX7219


message:
How to use the Osepp proximity module with arduino uno

I have recently purchased an [Osepp proximity module](https://www.osepp.com/electronic-modules/sensor-modules/75-ir-proximity-sensor-module) at Radio Shack and am attempting to use it with my Arduino Uno. How should I connect it to the
Arduino, and what library do I use?

body:
> How should I connect it to the Arduino

Refer to the schematic in the page you link to. That shows you which pin is which.  It's I2C, so there's just 2 data pins, power, and ground.

> and what library do I use?

The Osepp board is a GP2Y0D805Z0F connected to a PCA9534 IO expander. There is a library [here](https://github.com/alotaiba/PCA9534).


message:
Help, I want to turn relay constantly on until a difference is detected, but triggered only one instead

Help, I want to use arduino to control relay for electricity, i get data from a sensor and when a value is detected it should be constantly on until another detection triggered again, i can get the program to work but triggered only once instead when it should be constantly turned on, here'e my code:

```c++
int Pinout = 13;

void setup() {
    Serial.begin(9600);
    pinMode(Pinout, OUTPUT);
}

void loop() {
    int val = analogRead(A0);
    if (val <= 500) {
        digitalWrite(Pinout, LOW);
    }
    else {
        digitalWrite(Pinout, HIGH);
    }
}
```

the relay i am using is a chinese relay module with 3 pin and VCC and GND connected to external power supply, and INput pin to 13 digital pin Arduino and the relay is which i believed is Active LOW, and for analog read i am using moisture sensor

body:
As far as I can see, the relay will stay on when `val` is less or equal than 500, and stay off when `val` is higher than 500.

However, there might be a problem when `val` keeps fastly moving around 500; it will switch on and off quite fast.

To prevent this, you should make two 'triggers', e.g. turn it on when the value <= 480, and turn it off when the value >= 520. When it is in between 480 and 520 it will not change. This will cause less fast changes of the relay. Of course if the initial value is already between 480 and 520 you have to make a choice yourself.


message:
SD Library function doesnt work while using second SPI port with ESP32

i work on a group project with an ESP32. We have a lcd display and a sd card connected via the two SPI ports of the ESP32.

The card gets initialized with no problem using this code:

     bool EKG_recording::initialisation_sd() {

      SPIClass * hspi = new SPIClass(HSPI);

      if (!SD.begin(CS_Pin, *hspi))
      {
        Serial.println("No valid SD card!");
        return 0;
      }

      else if (SD.begin(CS_Pin, *hspi))
      {
        Serial.println("SD card initialized!");
        return 1;
      }
      else return 0;
    }

One function i have a problem with is used to count every file on the SD card, simple enough right?

    unsigned short EKG_recording::count_files_from_SD(File dir) {
      while (true)
      {
        File entry = dir.openNextFile();
        if (!entry)
        {
          // Serial.println("Anzahl der Daten");
          return counter;
        }
        counter++;
        entry.close();
      }
    }

It once worked without a problem, then we integrated the two SPI ports and now i cant figure out why its not working.
This part:
`File entry = dir.openNextFile();`
returns false on the first call even though i am 100% sure there are 3 files on the SD card.

I call the function like this :

`File root = SD.open("/");
EKG_recording_1.count_files_from_SD(root);
`

But why? Any help is very appreciated.

This is the begin function of the display. Since i didnt write it, i know next to nothing about it.

        void EKG_display_control::begin()
    {
      // Backgroundlight off
      pinMode(TFT_LED, OUTPUT);
      disable_display_backlight();

      // Initialise Display
      tft.begin(40000000);
      touch.begin();
      tft.setRotation(ROTATION);

      layout_start_screen();
    }

[![THE PINOUT:][1]][1]

[![The MC+SD Adapter][2]][2]

  [1]: https://i.stack.imgur.com/wV7S0.jpg
  [2]: https://i.stack.imgur.com/urotx.jpg

body:
Ok i found the solution. It was not too complicated. I just assumed the problem was in the code. This works well enough (dont ask me about the counter--)

      unsigned short EKG_recording::count_files_from_SD() {

      root = SD.open("/");
      root.rewindDirectory(); //Sets to beginning of directory

      while (true)
      {
        File entry = root.openNextFile();

        if(!entry){
          Serial.println("Anzahl der Daten");
          counter--;
          return counter;
        }
        counter++;
        entry.close();
      }
    }

It was just because i used SD.open() always inside the class-functions, so every file root was bound to the class.


message:
PlatformIO :collect2.exe: error: ld returned 1 exit status

I am trying some library files for esp8266. I created hpp and .cpp files. But i try to compile program i got this error on VSCode.
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\huzzah\firmware.elf] Error 1
I put files in src folder but still got this. What are points that i missed?

    Building in release mode
    Linking .pio\build\huzzah\firmware.elf
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::Neotimer()':
    main.cpp:(.text._ZN8NeotimerC2Ev+0x0): multiple definition of `Neotimer::Neotimer()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerC2Ev+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::Neotimer()':
    main.cpp:(.text._ZN8NeotimerC2Ev+0x0): multiple definition of `Neotimer::Neotimer()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerC2Ev+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::Neotimer(unsigned long)':
    main.cpp:(.text._ZN8NeotimerC2Em+0x0): multiple definition of `Neotimer::Neotimer(unsigned long)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerC2Em+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::Neotimer(unsigned long)':
    main.cpp:(.text._ZN8NeotimerC2Em+0x0): multiple definition of `Neotimer::Neotimer(unsigned long)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerC2Em+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::~Neotimer()':
    main.cpp:(.text._ZN8NeotimerD2Ev+0x0): multiple definition of `Neotimer::~Neotimer()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerD2Ev+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::~Neotimer()':
    main.cpp:(.text._ZN8NeotimerD2Ev+0x0): multiple definition of `Neotimer::~Neotimer()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8NeotimerD2Ev+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::init()':
    main.cpp:(.text._ZN8Neotimer4initEv+0x0): multiple definition of `Neotimer::init()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer4initEv+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::repeatReset()':
    main.cpp:(.text._ZN8Neotimer11repeatResetEv+0x0): multiple definition of `Neotimer::repeatReset()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer11repeatResetEv+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::done()':
    main.cpp:(.text._ZN8Neotimer4doneEv+0x4): multiple definition of `Neotimer::done()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer4doneEv+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::set(unsigned long)':
    main.cpp:(.text._ZN8Neotimer3setEm+0x0): multiple definition of `Neotimer::set(unsigned long)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer3setEm+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::get()':
    main.cpp:(.text._ZN8Neotimer3getEv+0x0): multiple definition of `Neotimer::get()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer3getEv+0x0): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::stop()':
    main.cpp:(.text._ZN8Neotimer4stopEv+0x4): multiple definition of `Neotimer::stop()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer4stopEv+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::reset()':
    main.cpp:(.text._ZN8Neotimer5resetEv+0x8): multiple definition of `Neotimer::reset()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer5resetEv+0x8): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::repeat()':
    main.cpp:(.text._ZN8Neotimer6repeatEv+0xc): multiple definition of `Neotimer::repeat()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer6repeatEv+0xc): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::repeat(int)':
    main.cpp:(.text._ZN8Neotimer6repeatEi+0x8): multiple definition of `Neotimer::repeat(int)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer6repeatEi+0x8): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::repeat(int, unsigned long)':
    main.cpp:(.text._ZN8Neotimer6repeatEim+0x4): multiple definition of `Neotimer::repeat(int, unsigned long)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer6repeatEim+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::start()':
    main.cpp:(.text._ZN8Neotimer5startEv+0x4): multiple definition of `Neotimer::start()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer5startEv+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::debounce(bool)':
    main.cpp:(.text._ZN8Neotimer8debounceEb+0x8): multiple definition of `Neotimer::debounce(bool)'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer8debounceEb+0x8): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::restart()':
    main.cpp:(.text._ZN8Neotimer7restartEv+0x4): multiple definition of `Neotimer::restart()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer7restartEv+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::waiting()':
    main.cpp:(.text._ZN8Neotimer7waitingEv+0x4): multiple definition of `Neotimer::waiting()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer7waitingEv+0x4): first defined here
    c:/users/dogan/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio\build\huzzah\src\main.cpp.o: in function `Neotimer::started()':
    main.cpp:(.text._ZN8Neotimer7startedEv+0x0): multiple definition of `Neotimer::started()'; .pio\build\huzzah\src\communication.cpp.o:communication.cpp:(.text._ZN8Neotimer7startedEv+0x0): first defined here

Sorry, i am new on stackexchange community so i can do basic mistakes about usage.

Now, i am adding my main.cpp,communication.cpp and communication.h files. As i said before, i didnt included neotimer and deleted. I used to add this library to my project, PIO library interface. I am thinking this problem coming from this. Great thanks for your patient and advises.

communication.cpp:

    #include "communication.h"
    #include "database.h"
    #include "management.h"
    #include "wifi.h"

    String GetCommand(String data, char separator, int index)
    {
      int found = 0;
      int strIndex[] = {0, -1};
      int maxIndex = data.length() - 1;

      for (int i = 0; i <= maxIndex && found <= index; i++)
       {
        if (data.charAt(i) == separator || i == maxIndex)
        {
          found++;
          strIndex[0] = strIndex[1] + 1;
          strIndex[1] = (i == maxIndex) ? i + 1 : i;
        }
      }
      return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
    }

    void checkStream(WiFiServer tcpServer,WiFiClient tcpClient, Neotimer timer,boolean pulseCheck)
    {

     // WiFiClient _tcpClient;
      tcpClient.setTimeout(200);
      tcpClient  = tcpServer.available();

      if(tcpClient && tcpClient.connected())
      {
        Serial.println("Timer Off");
        timer.stop();
        String requestStr = tcpClient.readStringUntil('\r');
          if(requestStr.length()>=8)
          {
            tcpClient.print(ParseStream(requestStr));
            pulseCheck = false;
            delay(3000);
             String requestSplitStr = GetCommand(requestStr, ' ', 0);
             if(requestSplitStr == "ayg_set_modem_info")
             {
              Serial.println("Device is going to sleep now!");
              Sleep();
             }
          }
      }
      else
      {
        return;
      }
    }

    String ParseStream(String content)
    {
      String requestSplitStr = GetCommand(content, ' ', 0);
      if(requestSplitStr == "ayg_set_modem_info")
      {
        String ssid = GetCommand(content, ' ', 1);
        String pass = GetCommand(content, ' ', 2);
        Serial.println("SSID,PASS TAKING");
        delay(200);
        ClearEP();
        boolean resSsid = WriteEPSsid(ssid);
        boolean resPass = WriteEPPass(pass);
        Aprint("SSID: "+ReadEPSsid());
        Aprint("Pass: "+ReadEPPass());
        //_tcpClient.flush();
        if(resPass)
        {
          if(STATest())
          {
            return JsonResult("true");

          }
          else
          {
            return JsonResult("false");
          }

        }
        else
        {
          return JsonResult("false");
        }

      }

      else if(requestSplitStr == "ayg_get_vbatt")
      {
        return JsonResult(GetBattery());
       // _tcpClient.flush();
       // _tcpClient.stop();
      }

communication.h

    #ifndef communication_h
    #define communication_h
    #if ARDUINO > 100
    #include "Arduino.h"
    #else
    #include "WProgram.h"
    #endif
    #include <WiFiServer.h>
    #include <WiFiClient.h>
    #include <neotimer.h>
    #include "ArduinoJson.h"

    //VARIABLES

        String GetCommand(String data, char seperator, int index);
        String ParseStream(String content);
        void checkStream(WiFiServer tcpServer,WiFiClient tcpClient, Neotimer timer,boolean pulseCheck);
        String JsonResult(String result);

    #endif

main.cpp:

    #include <stdlib.h>
    #include <HX711.h>
    #include <Arduino.h>
    #include <ESP8266WebServer.h>

    #include <string.h>
    #include "communication.h"
    #include <management.h>
    #include <wifi.h>
    #include <database.h>

    #define DOUT 13 // D7
    #define SCK 15 // D8
    #define led1 5 // D1- Color?
    #define led2 4 // D2-Color?
    #define led3 0 // D3-Color?
    #define led4 2 // D4 Color?
    #define led5 14 // D5 Color_?
    #define button 12 //Button-D5
    #define VERSION "1.0"
    #define CALIBRATIONWEIGHT 5.0
    #define LPG  12.2

    struct rst_info *rtc_info = system_get_rst_info();
    ADC_MODE(ADC_VCC);
    WiFiServer _tcpServer(41400);
    WiFiClient _tcpClient;
    //HTTPClient http;
    HX711 scale;

    /*Scale Values*/
    float tareValFromclient;
    float calibration_factor = 26845.0;
    float grossWeight;
    char sGrossWeight[10];
    int ledPercentage;
    /*Sleep Values*/
    bool sleepPulseCheck=false;

    /*Timers and Intervals*/
    /*const unsigned long sleepInterval = 200000; // Seconds to sleep
    const unsigned long scaleInterval = 2000; // Interval for scaling tank
    const unsigned long ledInterval = 200;
    Neotimer sleepTimer(sleepInterval);
    Neotimer scaleTimer(scaleInterval);
    Neotimer ledTimer(ledInterval);*/

    #pragma region PROTOYPES
    /*PROTOTYPES*/
    void Initialize();
    String checkTankTare();
    void powerUpScale();
    void powerDownScale();
    bool Tare();
    void getGrossWeight(float *fGross, char*sGross);
    String getDeviceTare();
    float calculateFirstNetWeight();
    float getNetWeight();
    int calculatePercentage();
    void ledDrivePercentage(int percentage);
    String calibrateScale();
    #pragma endregion

    /*---------------------------------------*/

    void setup() {
      ESP.eraseConfig();
      Initialize();
      Serial.println("started");
    }

    void loop() {
      //Serial.printf("connected:%d\n", WiFi.softAPgetStationNum()); // bağlı client sayısı
     calibrateScale();
    // checkStream(_tcpServer,_tcpClient,/*sleepTimer*/sleepPulseCheck);
     ledDrivePercentage(calculatePercentage());
     WriteEPGross(sGrossWeight);

     if(sleepPulseCheck == false)
     {
       sleepPulseCheck = true;
      // sleepTimer.start();
       Serial.println("Sleep Fired");

     }
    }

body:
The problem stems from the fact that the author of the Neotimer "library" defined the methods *in the header file*, see [neotimer.h][1].

If you include this header in more than 1 source of your project, you will get these "multiple definition" errors.

To solve this issue you have (at least) these options:

1. Make Neotimer a *correct* library with separated header and source files. Compile the source into a library file. Since I'm not experienced with Arduino I don't know how other libraries do this.
   - Disadvantage: You're messing with 3rd-party code. Commonly this is discouraged. You'll have to maintain your copy of the library yourself, which renders some benefits of using libraries void.
1. Don't include `neotimer.h` in a *header* file of yours, include it only in *one of your source* files. If you need some declaration like the `Neotimer` type in other modules, add a forward declaration but don't include its header file.
1. Use another library that is better implemented.

You might say that you include `neotimer.h` in only one module. That's wrong. You included it in your own header file `communication.h`, which you include in *both* source files. This way it sneaks into *both* modules. You can't do anything about this with preprocessor "magic" because both modules are compiled independently from each other.

---

This is the class declaration of `Neotimer` as of 2020-01-12 18:40 UTC. Use as much as you need from it as forward declaration. You could even put this in decent header file.

    class Neotimer{
     public:
     //Methods
     Neotimer();
     Neotimer(unsigned long _t);      //Constructor
     ~Neotimer();            //Destructor

     void init();            //Initializations
     boolean done();         //Indicates time has elapsed
     boolean repeat(int times);
     boolean repeat(int times, unsigned long _t);
     boolean repeat();
     void repeatReset();
     boolean waiting();   // Indicates timer is started but not finished
     boolean started();   // Indicates timer has started
     void start();   //Starts a timer
     unsigned long stop();   //Stops a timer and returns elapsed time
     void restart();
     void reset();           //Resets timer to zero
     void set(unsigned long t);
     unsigned long get();
     boolean debounce(boolean signal);
     int repetitions = NEOTIMER_UNLIMITED;

     private:

     struct myTimer{
      unsigned long time;
      unsigned long last;
      boolean done;
      boolean started;
     };

     struct myTimer _timer;
     boolean _waiting;
    };

  [1]: https://github.com/jrullan/neotimer/blob/master/src/neotimer.h


message:
Black boxes are appearing on the second row of my LCD

the black boxes on the LCD are only on both rows and appear only when I attach the heart rate sensor to my body and blink with a delay of about 2 seconds and my contrast and wiring are perfect, the backlight of my LCD is on...

but when I attach the heart rate sensor they repeat for four or five seconds and the black boxes too would disappear leaving behind only the backlight on...
[![How it looks like][1]][1][![disappearance of black boxes][2]][2]
but then why do the black boxes appear???
please help me out
this is the code, schematics, and a picture of how it looks like.

        #include <LiquidCrystal.h>
    #define IN1  8
    #define IN2  9
    #define IN3  10
    #define IN4  7
    int Steps = 4096; //4096 or 768
    int cstep = 10;
    const int rs = 7, en = 8, d4 = 3, d5 = 4, d6 = 5, d7 = 6;
    const int buzzer = 2;
    LiquidCrystal lcd(7, 8, 3, 4, 5, 6);

    int pulsePin = A3;                 // Pulse Sensor purple wire connected to analog pin A0
    int blinkPin = 13;                // pin to blink led at each beat
    // Volatile Variables, used in the interrupt service routine!
    volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS
    volatile int Signal;                // holds the incoming raw data
    volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
    volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
    volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

    static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

    volatile int rate[10];                      // array to hold last ten IBI values
    volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
    volatile unsigned long lastBeatTime = 0;           // used to find IBI
    volatile int P = 512;                      // used to find peak in pulse wave, seeded
    volatile int T = 512;                     // used to find trough in pulse wave, seeded
    volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
    volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
    volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
    volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

    void setup()
    {
       pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT);
      pinMode(IN4, OUTPUT);
       pinMode(buzzer,OUTPUT);
      pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
      Serial.begin(115200);             // we agree to talk fast!
      interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
                                        // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
                                        // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
                                        //   analogReference(EXTERNAL);
     lcd.begin(16, 2);
     lcd.clear();
    }

    //  Where the Magic Happens
    void loop()
    {
       serialOutput();
        lcd.print("DEVICE-STATE");
         lcd.setCursor(1,1);
         lcd.print("UPDATING... ");
         lcd.setCursor(5,1);
         delay(3000);
         lcd.clear();
      if (QS == true) // A Heartbeat Was Found
        {
          // BPM and IBI have been Determined
          // Quantified Self "QS" true when arduino finds a heartbeat
          serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
          QS = false; // reset the Quantified Self flag for next time
          state();
          buzer();
          inject();
        }

      delay(20); //  take a break
    }

    void interruptSetup()
    {
      // Initializes Timer2 to throw an interrupt every 2mS.
      TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
      TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
      OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
      TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
      sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
    }

    void serialOutput()
    {   // Decide How To Output Serial.
     if (serialVisual == true)
      {
         arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
      }
     else
      {
          sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
       }
    }

    //Heart Attack Preventer

    void serialOutputWhenBeatHappens()
    {
     if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
       {
         Serial.print(" Heart-Beat Found ");  //ASCII Art Madness
         Serial.print("BPM: ");
         Serial.println(BPM);
         lcd.print("Heart-Beat Found ");
         lcd.setCursor(1,1);
         lcd.print("BPM: ");
         lcd.setCursor(5,1);
         lcd.print(BPM);
         delay(3000);
         lcd.clear();
       }
     else
       {
         sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
         sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
       }
    }

    void arduinoSerialMonitorVisual(char symbol, int data )
    {
      const int sensorMin = 0;      // sensor minimum, discovered through experiment
      const int sensorMax = 1024;    // sensor maximum, discovered through experiment
      int sensorReading = data; // map the sensor range to a range of 12 options:
      int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
      // do something different depending on the
      // range value:
    }

    void sendDataToSerial(char symbol, int data )
    {
       Serial.print(symbol);
       Serial.println(data);
    }

    ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
    {
      cli();                                      // disable interrupts while we do this
      Signal = analogRead(pulsePin);              // read the Pulse Sensor
      sampleCounter += 2;                         // keep track of the time in mS with this variable
      int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                                  //  find the peak and trough of the pulse wave
      if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
        {
          if (Signal < T) // T is the trough
          {
            T = Signal; // keep track of lowest point in pulse wave
          }
        }

      if(Signal > thresh && Signal > P)
        {          // thresh condition helps avoid noise
          P = Signal;                             // P is the peak
        }                                        // keep track of highest point in pulse wave

      //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
      // signal surges up in value every time there is a pulse
      if (N > 250)
      {                                   // avoid high frequency noise
        if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
          {
            Pulse = true;                               // set the Pulse flag when we think there is a pulse
            digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
            IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
            lastBeatTime = sampleCounter;               // keep track of time for next pulse

            if(secondBeat)
            {                        // if this is the second beat, if secondBeat == TRUE
              secondBeat = false;                  // clear secondBeat flag
              for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
              {
                rate[i] = IBI;
              }
            }

            if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
            {
              firstBeat = false;                   // clear firstBeat flag
              secondBeat = true;                   // set the second beat flag
              sei();                               // enable interrupts again
              return;                              // IBI value is unreliable so discard it
            }
          // keep a running total of the last 10 IBI values
          word runningTotal = 0;                  // clear the runningTotal variable

          for(int i=0; i<=8; i++)
            {                // shift data in the rate array
              rate[i] = rate[i+1];                  // and drop the oldest IBI value
              runningTotal += rate[i];              // add up the 9 oldest IBI values
            }

    //Heart Attack Preventer
    rate[9] = IBI;                          // add the latest IBI to the rate array
          runningTotal += rate[9];                // add the latest IBI to runningTotal
          runningTotal /= 10;                     // average the last 10 IBI values
          BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
          QS = true;                              // set Quantified Self flag
          // QS FLAG IS NOT CLEARED INSIDE THIS ISR
        }
      }

      if (Signal < thresh && Pulse == true)
        {   // when the values are going down, the beat is over
          digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
          Pulse = false;                         // reset the Pulse flag so we can do it again
          amp = P - T;                           // get amplitude of the pulse wave
          thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
          P = thresh;                            // reset these for next time
          T = thresh;
        }

      if (N > 2500)
        {                           // if 2.5 seconds go by without a beat
          thresh = 512;                          // set thresh default
          P = 512;                               // set P default
          T = 512;                               // set T default
          lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
          firstBeat = true;                      // set these to avoid noise
          secondBeat = false;                    // when we get the heartbeat back
        }

      sei();                                   // enable interrupts when youre done!
    }// end isr
    void buzer(){
      // dangerous situation or pressed button
      if (BPM < 60 )
       {
         lcd.print("hypotension");
         lcd.setCursor(1,1);
         lcd.print("BPM: ");
         lcd.setCursor(5,1);
         lcd.print(BPM);
         delay(3000);
         lcd.clear();
       digitalWrite(buzzer,HIGH);
        delay(500);
       digitalWrite(buzzer,LOW);
        delay(500);

    }

    }
    void inject()
    {
       if (BPM>60)
       {
         lcd.print("Hypertention");
         lcd.setCursor(1,1);
         lcd.print("BPM: ");
         lcd.setCursor(5,1);
         lcd.print(BPM);
         delay(5000);
         lcd.clear();
      for(int x=0;x<Steps;x++)
      {
       switch(cstep)
      {
       case 0:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, HIGH);
       break;
       case 1:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, HIGH);
       break;
       case 2:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, LOW);
       break;
       case 3:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, LOW);
       break;
       case 4:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break;
       case 5:
         digitalWrite(IN1, HIGH);
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break;
         case 6:
         digitalWrite(IN1, HIGH);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break;
       case 7:
         digitalWrite(IN1, HIGH);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, HIGH);
       break;
       default:
         digitalWrite(IN1, LOW);
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break;
      }

       cstep=cstep+1;
       if(cstep==8)
         {cstep=0;}

      delayMicroseconds(2500);

       }
    }
    }
    void state()
    {
      if (BPM > 60 & BPM < 74){
       lcd.print("VERY-GOOD");
         lcd.setCursor(1,1);
         lcd.print("BPM: ");
         lcd.setCursor(5,1);
         lcd.print(BPM);
         delay(3000);
         lcd.clear();
      }
    }

[![this is the schematic of my project][3]][3]

  [1]: https://i.stack.imgur.com/iksrt.jpg
  [2]: https://i.stack.imgur.com/KcBti.jpg
  [3]: https://i.stack.imgur.com/eo6NJ.png

body:
I think it was because the charge of the battery was less and therefore the contrast of it was less and so I couldn't see the characters displayed...

Thanks to all those people who helped me with this problem and thanks to stack overflow

Now it is working as I used a different battery