body:
Relays, motors, and other inductive loads release a surge of reverse current when you remove power from them. You have to connect a suitably sized “flyback diode” across the coil, wired backwards from the normal current flow direction to protect the other devices on the circuit from that reverse current or they will likely be damaged.

Relays and motors also draw a large in-rush of current when they are first connected, which can cause the supply voltage to droop.

You can buy relays that are made to be controlled by logic levels. They take a low power 5V or 3.3V logic level input, plus a separate power supply, and use the logic input to switch the relay on and off safely. The relay modules I’m using have optical isolation for the logic lines for extra protection.


sender: user

message:
Esp8266 Vin pin

I've read that Vin pin is directly connected to usb cable in esp8266 (which is 5V). I wonder if I can power a relay 5V and a servo motor Sg90  with this pin? And is there any danger of doing that ?

sender: assistant

body:
(Answering in more detail, as this is the top search hit for "ESP8266 Vin", at least for me)

**TL;DR**: `Vin` is NOT directly connected to USB power. There is a protection diode between USB+/VU and `Vin`, which has a limited current capacity.
If your board provides `VU`, that one _is_ directly connected to USB power.
As long as you only _power_ 1-2 tiny devices, it should be OK. (_controlling_ will need additional components, or it will fry your ESP)

---

Since you talk about 'Vin' and '5V', I'm going to assume you have a devboard, not a 'naked' ESP8266. If your "esp8266" has a USB-connector and flash/reset buttons, then its a devboard-version. If it is only a fingernail-sized metal cover with a 1mm edge with solderpads, then its 'naked'.

The `Vin` pin is a power _**in**put_ for the onboard regulator.
On all common devboards, there is a protection diode between the USB+ wire, and `Vin`.
Some devboards also provide a `VU`-pin, which is directly connected to the USB+ wire without anything in-between.

The 3.3V regulator converts any input voltage (5V-19V) connected to `Vin` into the 3.3V needed by the ESP chip and the `3V3`-pins. The regulator has capacity (barely) for the ESP and a (large) handful of leds, not much more.

---

There is **always danger** when connecting mechanical/magnetic 'power'-devices (relays, servos and motors) in the same circuit with 'sensitive' microcontrollers/logic gates.
'power' devices are noisy and cause feedback which must be filtered, blocked and absorbed so it will not fry 'small' electronics. (even a toothbrush motor is 'power', compared to microchips).
'Power' devices are also hungry, causing voltage drops when activated. These drops can cause glitches, bugs and even resets in logic-level electronics.

This not stop many people from trying it anyway, and it will _often_ work, for a while, until it someday 'mysteriously' stops working because the chip finally gave out under the repeated abuse.

(side note: as other have mentioned: You also cannot _control_ magnetic/mechanical devices directly from the signal pins. Microcontroller outputs are too weak. Trying anyway can destroy your microcontroller with the feedback.)

----

A detailed background explanation for powering ESP devboards, including wiring schematics and explanations, can be found here:
https://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/powering-the-esp-12e-nodemcu-development-board/


message:
Measure small capacitances with ATtiny85 (Digispark board)

I have successfully run the code provided [here][1] on an Arduino Nano. If nothing is connected, it will output a very small capacitance (~ 1 pF).

Then I tried to migrate the code to the ATtiny85 (using a Digispark USB Development Board), but I fail to get anything reasonable out of the code. The first `analogRead` will always give 1023, whereas on the Nano it gives a very small value (again for nothing connected to the input pins).

It's a bit trickier on the ATtiny85 because the pin numbers are different for digital and analog, but I thought I got that right, so what went wrong in the migration?

    const int OUT_PIN = 2; // digital pin PB2 is 2, positive pin of C
    const int IN_PIN  = 5; // digital pin PB5 is 5, negative pin of C
    const int OUT_ANA = 1; // analog read PB2 is 1
    const int IN_ANA  = 0; // analog read PB5 is 0

    const float IN_STRAY_CAP_TO_GND = 24.48;
    const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
    const float R_PULLUP = 34.8;
    const int MAX_ADC_VALUE = 1023;

    #include "DigiKeyboard.h"

    void setup() {
      pinMode(1, OUTPUT);
      pinMode(OUT_PIN, OUTPUT);
      pinMode(IN_PIN, OUTPUT);
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);
      DigiKeyboard.update();
    }

    void loop() {

        pinMode(IN_PIN, INPUT);
        digitalWrite(OUT_PIN, HIGH);
        int val = analogRead(IN_ANA); // IN_PIN in Nano version
        digitalWrite(OUT_PIN, LOW);

        DigiKeyboard.println(val);
        if (val < 1000) {
          pinMode(IN_PIN, OUTPUT);
          float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);
          DigiKeyboard.print(capacitance);
          DigiKeyboard.println(" pF");
        } else {
          pinMode(IN_PIN, OUTPUT);
          delay(1);
          pinMode(OUT_PIN, INPUT_PULLUP);
          unsigned long u1 = micros();
          unsigned long t;
          int digVal;

          do {
            digVal = digitalRead(OUT_PIN);
            unsigned long u2 = micros();
            t = u2 > u1 ? u2 - u1 : u1 - u2;
          } while ((digVal < 1) && (t < 400000L));

          pinMode(OUT_PIN, INPUT);
          val = analogRead(OUT_ANA); // OUT_PIN in Nano version
          digitalWrite(IN_PIN, HIGH);
          int dischargeTime = (int)(t / 1000L) * 5;
          delay(dischargeTime);
          pinMode(OUT_PIN, OUTPUT);
          digitalWrite(OUT_PIN, LOW);
          digitalWrite(IN_PIN, LOW);

          float capacitance = -(float)t / R_PULLUP / log(1.0 - (float)val / (float)MAX_ADC_VALUE);

          if (capacitance > 1000.0) {
            DigiKeyboard.print(capacitance / 1000.0);
            DigiKeyboard.println(" uF");
          } else {
            DigiKeyboard.print(capacitance);
            DigiKeyboard.println(" nF");
          }
          DigiKeyboard.println(val); // usually ~ 520 (because we wait until digVal == 1?)
          DigiKeyboard.println(t); // depends on C: ~ 26000 for 1 µF, ~ 2600 for 100 nF, ~ 250000 for 10 µF
      }

      digitalWrite(1, 1);
      delay(10);
      while (micros() % 1000 != 0);
      digitalWrite(1, 0);

    }

  [1]: http://www.electronoobs.com/eng_arduino_tut10_1.php

body: The reason this doesn't work is that PB5 is pulled high (as it's used as -RESET pin on the board). The code can be rewritten to use only one ADC pin though.


message:
Can a Lithium Polymer battery charging circuit on Arduino boards also charge Lithium Lion batteries?

I have a project that the form factor of 18650 batteries works well for. The board I'm using is a esp32 based board with built in battery charging:
https://www.amazon.com/gp/product/B072HBW53G/ref=ppx_yo_dt_b_asin_title_o00_s02?ie=UTF8&psc=1

1. I've heard that the flatpack type Lithium Polymer batteries have built in over charge circuitry. Is this generally true?
2. Can I directly charge a 18650 battery from Arduino type boards that have built in battery charging functionality?

EDIT:  So from looking at the battery circuit schematic from the Wemos link and the board itself it uses a TP4054 "Standalone Linear **Li-lon** Battery Charger with Thermal Regulation in SOT".  And since I can confirm the board works with 3.7V batteries and my 18650 is a 3.7V type I think I'm good.

EDIT:  Found info on this board:
http://www.raspberrypiwiki.com/index.php/WEMOS_ESP32_Board_with_OLED

Also by "Arduino type" boards I mean any popular micro controller board that has a battery charging function such as the Adafruit feather boards.

EDIT:  To clarify:
Reading here Li Poly and Li Ion batteries are essentially the same
https://scottiestech.info/2015/06/21/lithium-polymer-vs-lithium-ion-batteries-whats-the-deal/

I believe the board is a Wemos D32 with an attached display though I can't find any specific info on this exact board.
https://wiki.wemos.cc/products:d32:d32#technical_specs

I basically want to know if I can charge a Lithium Ion battery with this type of board.  As this is potentially a safety concern I wanted to ask some experts.

body:
There are Lead based, Nickel-based and Lithium-based batteries (there are actually more, but these ones are the most popular). Each need a different charger, but since lithium polymer and lithium ion are in the same group, it **should** work but I don't have the option to test it out for you.

Q1: Not every battery has a built in over- and undercharge function. Some do, some don't. To find out if yours does, if the internet can't help, tear it apart (be extremely careful about it).

Q2: Depends what you mean by " built in battery charging functionality". If that includes the over- and undercharge functionality, then it will work (tested).

Looking at the board (https://wiki.wemos.cc/products:d32:d32#technical_specs) it seems doable.

The most important thing is to check, if the supported voltage of the li ion battery equals the supported voltage of the li polymer battery that can be charged with the li polymer charger. Since it says 3.7V on the data sheet, don't get a li ion battery with 3.7V+


message:
delay() not working inside loop() block

Edited and attached code here.
This section didn't execute.
The `delay(15000);` doesn't execute, I mean the sketch didn't execute this line no matter where to put it.

```c++
    // include the SPI library:
    #include <SPI.h>

    // set pin 53 as the slave select for the digital pot:
    const int slaveSelectPin = 53; //WAS 10 on Arduino uno.
    const int shutdownPin = 7; // was 7 on uno.
    const int wiper0writeAddr = B00000000;
    const int wiper1writeAddr = B00010000;
    const int tconwriteAddr = B01000000;

    const int tcon_0off_1on = B11110000;
    const int tcon_0on_1off = B00001111;
    const int tcon_0off_1off = B00000000;
    const int tcon_0on_1on = B11111111;

    const int analogInPin_c = A5;  // center Vc=Vss/2 from the PAD, use for set ini V. here no use, Vc directly goes to pad.

    const int analogInPin_x = A1;  // Analog input pin that the potentiometer is attached to
    const int analogInPin_y = A2;  // Analog input pin that the potentiometer is attached to

    const int analogOutPin_x = wiper0writeAddr; // write MCP POT
    const int analogOutPin_y = wiper1writeAddr; // write MCP POT

    int sensorValue_c = 0;        // value read from the PAD, Vc=Vss/2
    int sensorValue_x = 0;        // value read from the PAD, Vc=Vss/2
    int sensorValue_y = 0;        // value read from the PAD, Vc=Vss/2

    //?int outputValue_c = 0;        // value output to the PWM (analog out)
    int outputValue_x = 0;        // mid variable stored the value from 'sensorValue_c' and MAP that for use
    int outputValue_y = 0;        // mid variable stored the value from 'sensorValue_c' and MAP that for use

    int Vcr = 0;        // value read from the PAD, Vc=Vss/2
    int Vc = 0;        // value read from the PAD, Vc=Vss/2
    const int LEDpin1 = 47;
    const int LEDpin2 = 46;
    int count = 0;

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

      // set the slaveSelectPin as an output:
      pinMode (slaveSelectPin, OUTPUT);
      // set the shutdownPin as an output:
      pinMode (shutdownPin, OUTPUT);
      // start with all the pots shutdown
      digitalWrite(shutdownPin, LOW);
      // initialize SPI:
      SPI.begin();
      Serial.println("Setup complete");
      //??
      Serial.println("Starting loop");
      digitalWrite(shutdownPin, HIGH); //Turn off shutdown
    }

    void loop() {
      AnalogInOut(); //
      ArduinoDAC(); //
    }
    void AnalogInOut() {
      // take from some where used for testing joystick control LED,
      //need change to get date fron RC and write to MCP pots
      // read the analog in value:

      Vcr = analogRead(analogInPin_c);
      delay(1000);
      Serial.print("Vcr= ");
      Serial.println(Vcr);
      Vc = map(Vcr, 0, 1023, 165, 225);
      Serial.print("Vc = ");
      Serial.println(Vc);
      delay(10);
      Serial.print("count_ini= ");
      Serial.println(count);

      if (count = 0)  {

        if (Vc > 188)   {

          digitalWrite(LEDpin1, HIGH);
          Serial.print("Vc TOO HIGH: ");
          Serial.println(Vc);
          exit(0);
          delay(100);
        }

       if (Vc < 165) {

          digitalWrite(LEDpin2, HIGH);
          Serial.print("Vc TOO LOW = : ");
          Serial.println(Vc);
          exit(0);
          delay(10);
        }
        else {

          Serial.print("analogInPin_c_T00: ");
          Serial.println(analogInPin_c);

          /// digitalPotWrite(wiper0writeAddr, Vc);
          ///digitalPotWrite(wiper1writeAddr, Vc);

          digitalPotWrite(wiper0writeAddr, 100);
          digitalPotWrite(wiper1writeAddr, 220);

          count = 1;
          Serial.print("count_new= ");
          Serial.println(count);
        }
        delay(15000);
      }

      ////////////////////////////////////////////////////////////////////////////////////////////////////////////

      sensorValue_x = analogRead(analogInPin_x);
      sensorValue_y = analogRead(analogInPin_y);
      // map it to the range of the analog out:
      outputValue_x = map(sensorValue_x, 0, 1023, 70, 248);
      outputValue_y = map(sensorValue_y, 0, 1023, 70, 248);  // change the analog received to the value suite for PAD joystick

      //   print the results to the Serial Monitor:
      Serial.println("sensor_x =_T10 ");
      Serial.println(sensorValue_x);
      Serial.println("sensor_y = ");
      Serial.println(sensorValue_y);
      Serial.println("\t output = ");
      Serial.println(outputValue_x);
      Serial.println(outputValue_y);

      // wait 2 milliseconds before the next loop for the analog-to-digital
      // converter to settle after the last reading:
      delay(2);
    }

    void ArduinoDAC() {
      Serial.println("Starting loop");
      digitalWrite(shutdownPin, HIGH); //Turn off shutdown

      digitalPotWrite(wiper0writeAddr, outputValue_x); // Set wiper 0 to 200

      delay(5);

      digitalPotWrite(wiper1writeAddr, outputValue_y); // Set wiper 1 to 200

      delay(5);
    }

    // This function takes care of sending SPI data to the pot.
    void digitalPotWrite(int address, int value) {
      /// Serial.print("wiper0 position_t30: ");////
      /// Serial.println();////
      // take the SS pin low to select the chip:
      digitalWrite(slaveSelectPin, LOW);
      //  send in the address and value via SPI:
      SPI.transfer(address);
      SPI.transfer(value);
      delay(30);
      // take the SS pin high to de-select the chip:
    }

    int digitalPotRead(int address) {
      // take the SS pin low to select the chip:
      digitalWrite(slaveSelectPin, LOW);
      //  send in the address via SPI:
      SPI.transfer(address);
      // send zero to read data from the address
      delay(30);
    }
```

body:
Basically it works.

Here you find a little sketch to see how it works. Try to transfere it to your solution.

```c++
#include <M5Stack.h>  // only necessary for my board (M5Stack)

bool condition_while = true;
bool condition_loop = true;
int condition_if = 0;

void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
}

void loop() {
   while (condition_while) {
       if (condition_if == 0) {
           Serial.println("testcase #1: if path reached");
           condition_if = 1;
       }
       else if (condition_if == 1 ) {
           Serial.println("testcase #2: if else path reached");
           condition_if = 2;
       }
       else {
           Serial.println("testcase #3: else path reached");
           condition_while = false;
       }
       Serial.println("testcase #4: path reached inside while");
   }
   if (condition_loop) {
       Serial.println("testcase #5: path reached outside while");
       condition_loop = false;
   }
}
```

This is the output on COM3

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

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


body:
I would suggest you go through the coding tutorials on arduino website. It would be absolutely possible to have the above `structure` in an arduino code.

This link has a working and validated example showing `while` loop calling other function using `if-else-if` structure.

https://www.arduino.cc/en/Tutorial/WhileStatementConditional?from=Tutorial.WhileLoop

Please go through the tutorials and post specific problem if and when you encounter them.


body: If the code (not shown) within the if/else if/else structure doesn't affect the flow of control, then either delay() placement will work.  But the placement within the loop will delay at every cycle of the loop. The placement below the loop will only delay after the loop finishes executing.


message:
making power harmonics analyser which will measure the amplitudes of the fundamental and its multiples (like 50hz, 100hz, 150hz,200 hz,...) there are)

i have been  intendng to make a power frequency harmonics analyser which will measure the amplitudes of the fundamental and its multiples (like 50hz, 100hz, 150hz,200 hz,...) there are examples for making spectrum analyser with fft library's here is the example for the kosome made fft library

       #include <arduinoFFT.h>

       #define SAMPLES 128             //Must be a power of 2
       #define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC

       arduinoFFT FFT = arduinoFFT();

       unsigned int sampling_period_us;
       unsigned long microseconds;

       double vReal[SAMPLES];
       double vImag[SAMPLES];

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

            sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
       }

       void loop() {

            /*SAMPLING*/
            for(int i=0; i<SAMPLES; i++)
            {
                microseconds = micros();    //Overflows after around 70 minutes!

                vReal[i] = analogRead(0);
                vImag[i] = 0;

                while(micros() < (microseconds + sampling_period_us)){
                }
            }

            /*FFT*/
            FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
            FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
            FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
            double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

            /*PRINT RESULTS*/
            //Serial.println(peak);     //Print out what frequency is the most dominant.

            for(int i=0; i<(SAMPLES/2); i++)
            {
                /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/

                //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
                //Serial.print(" ");
                Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins
            }

            //delay(1000);  //Repeat the process every second OR:
            while(1);       //Run code once
       }

how can i seperate the amplitudes for particular frequencies like amplitude of 50hz = ?, 150hz = ? and store them in other variables

body:
The general idea of your code looks OK, but consider using a hardware timer rather than the `for` loop for data acquisition.  The sampling rate will be much more accurate and uniform because you eliminate (possibly cumulative) errors in timing.  See [this post][1] for an example.

Do you know how the `FFT.MajorPeak` function works?  If it simply finds the frequency of the largest point in the magnitude spectrum, this may not be a good measure of the 50 Hz peak etc.  Instead, consider taking the area under the curve around the frequency of interest `f_0`, say `f_0 - 2 Hz` to `f_0 + 2 Hz`.  The same code should be usable to measure the spectral power around any of the harmonics.

Also note that the mains electricity frequency is not exactly 50 Hz / 60 Hz.  The short-term variation is around plus/minus 1 Hz.  The above approach will also help make reliable readings.

  [1]: https://arduino.stackexchange.com/questions/50045/uniform-timing-when-using-arduino-for-data-acquisition


message:
Arduino and Solenoid Water Valve

I use Arduino UNO and two SPST Relay (Wemos Mini D1 Relay) to make the reverse polarity circuit. I use this circuit to open and close the Solenoid Water Valve (SWV), which work with 9 to 12 volt. The connections are as follows:

    NO (Relay1) --> NC (Relay2) --> +12 Volt
    NC (Relay1) --> NO (Relay2) --> 0
    D1 (Relay1) --> D1 (Relay2) --> Digital pin 3 of Arduino
    COM (Relay1) --> SWV1
    COM (Relay2) --> SWV2
    GND Relay1) --> GND (Relay2) --> GND of Arduino
    5V (Relay1) --> 5V (Relay2) --> 5 Volt of Arduino

the circuit work perfectly with Arduino boar. But the problem is that when I use ATMEGA328p-PU on breadboard as explained in [LINK][1], Relays are not working properly. Actually, relays connecting and disconnecting continuously when ATMEGA328p sends 1 to D1 pins of Relays.

The point is when I de-attach the SWV, relays work properly. but if the SWV is connected it still is not working.

I've checked the connection many times and they are correct.

I used the following code in arduino:

    int Relay = 3;
    void setup() {
      // put your setup code here, to run once:
      pinMode(Relay, OUTPUT);
      digitalWrite(Relay, LOW);

    }

    void loop() {
      // put your main code here, to run repeatedly:
      delay(2000);
      digitalWrite(Relay, HIGH);
      delay(2000);
      digitalWrite(Relay, LOW);

    }

Any help is highly appreciated.

Thanks in advance.

  [1]: https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard

body:
An [inductor][1] can create large pulses of power when turned off and on such as in a relay or a solenoid.  A [flyback diode][2] is usually added across inductors to suppress these pulses.  Indeed if you look at the schematic of the [Wemos Relay Board][3] used in this project you see where D1 is used in just such a way.  Unfortunately the voltage is being applied in both directions across the solenoid so a flyback diode can not be used directly across the solenoid.  However, it may be possible to add a flyback diode before the relays where the voltage is not reversing.

It is almost always better to mitigate electrical noise such as [Electromagnetic Field (EMF)][4] interference at its source.  Hence the flyback diode.  However, many combination logic and processor designers add [decoupling capacitors][5] as close as possible to the power terminal of each logic chip. This may be the reason a real Arduino board works while the bread board does not.

  [1]: https://en.wikipedia.org/wiki/Inductor
  [2]: https://en.wikipedia.org/wiki/Flyback_diode
  [3]: https://wiki.wemos.cc/_media/products:d1_mini_shields:sch_relay_v2.0.0.pdf
  [4]: https://en.wikipedia.org/wiki/Electromagnetic_field
  [5]: https://en.wikipedia.org/wiki/Decoupling_capacitor


body:
The problem is most likely EMI (electromagnetic interference) from the switching of the inductive load by the relays.

The fact that you have your setup on a breadboard means that each and every pin of the ATMega328 is connected to a little antenna. That massively increases its susceptibility to falling prey to EMI.  Add to that the fact that there is absolutely no decoupling of the power supply (thanks to Arduino producing shoddy worthless tutorials) makes the whole chip very fragile.

When running with a real Arduino board you have decoupling on the power which helps to reduce induced power rail bounce which can cause the chip to fail.

There are two things that can help mitigate this:

* Add decent decoupling to the ATMega328

This means adding capacitors between each VCC pin and ground. At the bare minimum a 100nF capacitor on each VCC pin is needed. Additionally a 1nF capacitor can be beneficial. A 10µF capacitor should also be added on the breadboard's power rails to act as a board-level reservoir.

* Snubber networks on the switching

A snubber network, in its most simple form, is a resistor and capacitor in series.  It is placed across the switching terminals of a device that is switching an inductive load to absorb the sudden spike of back-EMF from the collapsing magnetic field whenever the load is switched off.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/Tunzs.png)

<!-- End schematic -->

Note that the capacitors here should be rated for at least 400V since the voltages involved are quite high.


message:
Sending command through SPI on Arduino UNO

I am assuming the default pin configuration is pin 10(SS), 11(MOSI), 12(MISO), 13(CLK) from a default setup, SPI.begin(). The code compiles OK. Not sure about the int valuex and using the SPI.transfer() function.

    #include <SPI.h>

    int value1 = 0x8026;
    int value2 = 0x0801;
    int value3 = 0x8027;
    int value4 = 0x0000;

    void setup (void)
    {
      Serial.begin (9600);
      Serial.println ("Starting");
      digitalWrite(SS, HIGH);  // ensure SS stays high for now

      // Put SCK, MOSI, SS pins into output mode
      // also put SCK, MOSI into LOW state, and SS into HIGH state.
      // Then put SPI hardware into Master mode and turn SPI on
      SPI.begin ();

      // Slow down the master a bit
      SPI.setClockDivider(SPI_CLOCK_DIV4);

    }  // end of setup

    void loop (void)
    {
      // enable Slave Select
      digitalWrite(SS, LOW);

      SPI.transfer (1);   // initiate transmission
      SPI.transfer (value1);
      SPI.transfer (value2);
      SPI.transfer (value3);
      SPI.transfer (value4);

      // disable Slave Select
      digitalWrite(SS, HIGH);

    delay (1000);
    }

body:
> Not sure about the int valuex and using the SPI.transfer() function.

A couple of things to know:

1. You are storing an unsigned 16-bit literal into a signed 16-bit variable. You should be using `uint16_t value1 = 0x8026;` etc. Also, unless you are planning to change the values, they should be `const`.
2. `SPI.transfer()` transfers only 8 bits of data. You are only sending the lowest byte of your `valuex` variables. `SPI.transfer16()` sends an unsigned 16-bit value.

To illustrate, this is how your program should look:

    #include <SPI.h>

    const uint16_t value1 = 0x8026;
    const uint16_t value2 = 0x0801;
    const uint16_t value3 = 0x8027;
    const uint16_t value4 = 0x0000;

    void setup(void) {
     Serial.begin(9600);
     Serial.println("Starting");
     digitalWrite(SS, HIGH);  // ensure SS stays high for now
     // Put SCK, MOSI, SS pins into output mode
     // also put SCK, MOSI into LOW state, and SS into HIGH state.
     // Then put SPI hardware into Master mode and turn SPI on
     SPI.begin();
     // Slow down the master a bit
     SPI.setClockDivider(SPI_CLOCK_DIV4);
    }  // end of setup

    void loop(void) {
     // enable Slave Select
     digitalWrite(SS, LOW);
     SPI.transfer(1);    // initiate transmission
     SPI.transfer16(value1);
     SPI.transfer16(value2);
     SPI.transfer16(value3);
     SPI.transfer16(value4);
     // disable Slave Select
     digitalWrite(SS, HIGH);
     Delay(1000);
    }

That will transfer the stream of 8-bit values:

    0x01 0x80 0x26 0x08 0x01 0x80 0x27 0x00 0x00


message:
Can ESP8266 send AT commands to self?

I'm having some problems with my ESP8266 stopping transmission of MQTT messages after a while.
Therefore I'm writing some error handling messages, and I want to publish some AT data to MQTT.

It's probably a simple solution, but how can I, though the code, send AT messages from my 'own' device?
Also, does AT messages get parsed at a higher level than any other user input, so it can't get stuck in any user made input loop?

Many thanks!

body:
The AT command set for the ESP8266 is implemented through [custom firmware][1] which has to be flashed to the chip to use.

If you've written your own software which is running on the ESP8266 then that's what's flashed to it - the AT command set will not be available because you've overwritten it with your own software. So there's no way to send AT commands to yourself because if you've written software that could do that, then it's present and the AT command-interpreting software is not.

In that case you should look deeper into [the Arduino core for the ESP8266][2] to find the equivalents to the AT commands you wanted to use. This is the code that calls `setup()` and `loop()` and implements Arduino-compatible functions like `pinMode()`. It also provides libraries like `ESP8266WiFi`. There are many un- and under-documented functions in the code. You can almost certainly find the equivalents to anything that you can do with an AT command in here.

  [1]: https://github.com/espressif/ESP8266_AT
  [2]: https://github.com/esp8266/Arduino


message:
What should the cut-off frequency be?

To convert a PWM signal to a DC voltage it must be filtered with a low pass filter. How can you know which cut-off frequency should be used and how do you calculate the values for the resistor and capacitor belonging to that cut-off frequency. I do know that the cut-off frequency needs to be much higher/lower in comparison to the PWM signal, for example a factor 100 lower/higher.

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

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

body: The PWM frequency on the Arduino is about 500Hz by default, so you want your -3dB frequency to be below that. How far below? That's subjective. Lower gives a smoother output but a lower response speed. Since you want DC out then you can afford to go very low, unless you need it to respond to changes in the set point quickly.


message:
Replace Arduino bootloader

My Arduino board is malfunctioning in its bootloading and I thought weather I can overwrite the previous bootloader on the atmega. I mean to ask than can I simply reinstall bootloader on a chip that already has a bootloader installed.

body: Yes you can. A Programmer that is driven from a PC and connects to SCK/MOSI/MISO/Reset/Power/Gnd (the ICSP header on an Uno/Mega), or a Standalone Programmer that can program a bootload program stored on an SD card and connects to the same ICSP pins, is needed to access the bootload memory to load/reload the bootloader.


message:
invalid conversion from 'uint16_t* error when creating an array of uint16_t items

I'd like to create an array of remote control codes provided by the raw read feature of the irlib2 library.

irlib2 provides the following uint16t arrays using the following format:
```
#define RAW_DATA_LEN 68

const uint16_t powerOff[RAW_DATA_LEN]={
  8550, 4306, 530, 1606, 530, 566, 502, 1610,
  530, 566, 502, 574, 506, 1630, 506, 566,
  506, 1630, 506, 566, 502, 1610, 530, 566,
  502, 1634, 506, 1606, 530, 570, 498, 1634,
  506, 570, 510, 562, 506, 566, 502, 1634,
  506, 1606, 530, 1610, 530, 562, 538, 538,
  530, 542, 538, 1598, 538, 1570, 558, 542,
  538, 538, 530, 542, 538, 1598, 530, 1578,
  558, 1578, 562, 1000};
```

I'd like create an array of these arrays using the code below, but get the following errors.

**CODE**
```
#define RAW_DATA_LEN 68

const uint16_t powerOff[RAW_DATA_LEN]={
  8550, 4306, 530, 1606, 530, 566, 502, 1610,
  530, 566, 502, 574, 506, 1630, 506, 566,
  506, 1630, 506, 566, 502, 1610, 530, 566,
  502, 1634, 506, 1606, 530, 570, 498, 1634,
  506, 570, 510, 562, 506, 566, 502, 1634,
  506, 1606, 530, 1610, 530, 562, 538, 538,
  530, 542, 538, 1598, 538, 1570, 558, 542,
  538, 538, 530, 542, 538, 1598, 530, 1578,
  558, 1578, 562, 1000};

uint16_t sourceCD[RAW_DATA_LEN]={
  8546, 4310, 558, 1578, 562, 538, 498, 1638,
  530, 542, 506, 570, 502, 1634, 502, 570,
  498, 1638, 534, 538, 498, 1638, 530, 542,
  506, 1606, 554, 1582, 558, 538, 510, 1602,
  554, 546, 506, 566, 502, 570, 510, 1602,
  554, 1582, 558, 538, 510, 566, 502, 1606,
  554, 546, 502, 1610, 558, 1574, 554, 546,
  502, 570, 510, 1602, 526, 1610, 526, 574,
  506, 1602, 526, 1000};

uint16_t sourceAUX[RAW_DATA_LEN]={
  8550, 4310, 526, 1634, 506, 566, 502, 1634,
  506, 566, 502, 574, 506, 1626, 510, 566,
  506, 1630, 506, 566, 502, 1634, 506, 566,
  502, 1634, 506, 1606, 530, 566, 506, 1630,
  506, 566, 502, 1634, 506, 1630, 506, 1630,
  510, 1602, 526, 570, 510, 566, 502, 1634,
  502, 570, 502, 570, 510, 566, 502, 570,
  510, 562, 506, 1630, 506, 1630, 510, 562,
  506, 1630, 510, 1000};

uint16_t sourceCDR[RAW_DATA_LEN]={
  8550, 4306, 530, 1606, 534, 566, 502, 1606,
  534, 566, 502, 570, 510, 1602, 526, 570,
  510, 1602, 534, 566, 502, 1606, 534, 566,
  506, 1602, 530, 1606, 534, 566, 502, 1610,
  530, 570, 498, 574, 506, 566, 502, 570,
  510, 1602, 526, 570, 510, 566, 502, 570,
  510, 1602, 526, 1610, 526, 1606, 534, 1602,
  534, 566, 502, 1610, 530, 1602, 534, 1602,
  526, 574, 506, 1000};

//This is the problem code:
uint16_t sources[3] = {sourceCD, sourceAUX,  sourceCDR};
```

**ERRORS**
```
warning: invalid conversion from 'uint16_t* {aka unsigned int*}' to 'uint16_t {aka unsigned int}' [-fpermissive]
 uint16_t sources[3] = {sourceCD, sourceAUX,  sourceCDR};
warning: invalid conversion from 'uint16_t* {aka unsigned int*}' to 'uint16_t {aka unsigned int}' [-fpermissive]
warning: invalid conversion from 'uint16_t* {aka unsigned int*}' to 'uint16_t {aka unsigned int}' [-fpermissive]
```

I gather this has something to do with mixing and converting invalid types, but I'm not quite sure where to go from here

body:
You have two options.

1. You can make an array of arrays like this:

<!-- language-all: lang-c++ -->

    const uint16_t sources[3][RAW_DATA_LEN] = {
        { 8546, 4310, 558, ... }, // CD
        { 8550, 4310, 526, ... }, // AUX
        { 8550, 4306, 530, ... }  // CDR
    };

But then you don't have the `sourceCD`, etc. variables any more. If you
want, you could `#define` aliases for them like this:

    #define sourceCD  (sources[0])
    #define sourceAUX (sources[1])
    #define sourceCDR (sources[2])

2. You can make an array of pointers, as suggested in the comments:

<!-- language-all: lang-c++ -->

    const uint16_t sourceCD[RAW_DATA_LEN]  = { 8546, 4310, 558, ... };
    const uint16_t sourceAUX[RAW_DATA_LEN] = { 8550, 4310, 526, ... };
    const uint16_t sourceCDR[RAW_DATA_LEN] = { 8550, 4306, 530, ... };
    const uint16_t *sources[3] = { sourceCD, sourceAUX,  sourceCDR };

This works because, in the last line, the array identifiers such as
`sourceCD` implicitly “decay” to pointers to their first elements. Note
the `const` keyword in the last line, needed for consistency with the
types of the arrays declared above.


message:
Im trying to get a 3 button password sequence working

I'm trying get a password system working that when you click 3 buttons in a certain order (1, 2, 3, 3, 1) then an LED will light up. But as I'm going to implement this into a larger code I can't just have the void loop() going forever to wait for it.

I think my issue is in the while loops and making it wait for one of the buttons to be pressed but I don't know how to get it to work.

thanks

    #define greenLED A0
    #define redLED A1

    int button1 = 5;
    int button2 = 4;
    int button3 = 3;

    void setup() {
      // put your setup code here, to run once:
      pinMode(A0, OUTPUT);
      pinMode(A1, OUTPUT);
      pinMode(button1, INPUT_PULLUP);
      pinMode(button2, INPUT_PULLUP);
      pinMode(button3, INPUT_PULLUP);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      int total = 0;
      while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
        while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
          while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
            while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
              while(digitalRead(button1) == LOW && digitalRead(button2) == LOW && digitalRead(button3) == LOW){
                if(digitalRead(button1) == HIGH){
                  total = total + 1;
                }
              }
              if(digitalRead(button2)==HIGH){
                total = total+1;
              }
            }
            if(digitalRead(button3)==HIGH){
              total = total + 1;
            }
          }
          if(digitalRead(button3)==HIGH){
            total = total+1;
          }
        }
        if(digitalRead(button1) == HIGH){
          total = total+1;
        }
      }
      if(total == 5){
        digitalWrite(A0, HIGH);
        delay(2000);
        digitalWrite(A0, LOW);
      }else{
        digitalWrite(A1, HIGH);
        delay(2000);
        digitalWrite(A1, LOW);
      }
    }

body:
Without programming everything out, use something like this:

- Initialization:
  - Create a (global) variable of string ("12331") which is the code
  - Create a (global) variable of int that shows the number of correct numbers so far (initially 0)

- In the while loop:
  - Check which button is pressed
  - If it is the correct button
    - increase the int variable
    - If that variable is 5 (meaning all numbers ok), light up the LED
    - Delay
    - Make the variable 0 again
    - Clear the LED
  - If the wrong button is pressed
    - If it is equal to the first value ('1')
      - Set the variable to 1 (since the wrong number is the first correct number)
    - Else
      - Set the variable to 0


body:
For something like this, a state machine would probably be useful. Since this is software, we can skip the register assignment and use a state table directly.

    The table would look as follows:
    1. If button 1 is pressed, 2. Else 1.
    2. If button 2 is pressed, 3. Else 1.
    3. If button 3 is pressed, 4. Else 1.
    4. Run task, go to 1.

The code would require you to add an integer or byte outside `setup` or `loop`.
This would then contain the state number.

Inside `loop`, you can add the if statements for reading the button pins.

If one of the buttons is pressed (the if-statement fires), you can compare the state with the condition listed above. If the state and the correct condition match, set the state to the new state.

Otherwise, reset it to the initial state (0 is default if you do not explicitly change it when programming, and most things are 0-indexed. You can also use 1, but you have to remember to initialize it to 1 when declaring the state variable. i.e. `byte state=1;`)

The below sample code presumes that the buttons are connected between GND and the GPIO input pin on the Arduino. Since it's using the internal pullup resistors, no external ones are needed. The one minor issue is that it inverts the state of the buttons -- 0==pressed, 1==released (not pressed).

    byte state = 0;
    bool pressed=false;//used to prevent repeats

    void setup(){
      pinMode(pin1,INPUT_PULLUP);
      //Repeat for other pins. Replace pin# with the number.
    }

    void loop(){
      if (digitalRead(pin1)==0 && !pressed){
        pressed=true;
        if (state==0){
          state=1; //go to next state.
        }
        else{
          state=0; //reset state. Needed even here since the button might be
                   //pressed later at the wrong time. Add 'else if (state==#)'
                   //sections if the button needs to be reused again in later states.
       }
       if (digitalRead(pin1) && pressed){
         pressed=false;
       }
       //Add more if statements here, following the pattern, for any more buttons you need.
    }

Further improvements may involve getting independent press-detection variables (one for each button), but being only able to register one button press at a time is probably a good thing, actually.


body:
You can split this into two different problems, and I suggest you track
them one at a time.

The first problem is to detect the button presses. This is not as
trivial as it sounds. For once, `digitalRead()` tells you whether the
button is pressed, but that's not quite what you want. You want to
detect the discrete press “events”. In other words, you have to remember
the previous state of the button, and record a press event only when the
state _changes_ from `HIGH` to `LOW`. This is called “edge detection”.
When doing this on mechanical buttons, you _absolutely must_ do some
kind of debouncing.

I will not elaborate on this topic, as there are a few Arduino libraries
available for debouncing buttons that also do edge detection. Once you
have sorted this out, each of your buttons will have a `.fell()` method
that tells you whether that button has just been pressed. Then, inside
`loop()`, you can do something like

    char key = 0;  // key pressed by the user, 0 = none
    if (button1.fell()) key = '1';
    else if (button2.fell()) key = '2';
    else if (button3.fell()) key = '3';
    if (key) {  // some key has been pressed
        // process key...
    }

The “process key...” part should initially be a simple
`Serial.write(c);`. This way you can use the serial monitor to check
that this part of the program is working properly. Only when this is the
case you can move to the second part.

The second problem is to process the key presses in order to detect
whether the correct code has been entered. There are various possible
approaches. One of them is to store in an array the 5 last keys
entered by the user, and compare that array with the correct code to
know whether the entry was correct. This is not very elegant, as it will
require storing more information than necessary, and shifting the array
each time a new key is typed.

A more elegant solution is given by Michel Keijzers. Let me paraphrase
it in C++. Inside `loop()`:

    if (key) {  // some key has been pressed
        if (check_code(key)) {  // correct code typed
            digitalWrite(LED, HIGH);
            delay(1000);
            digitalWrite(LED, LOW);
        }
    }

where the logic for checking the correctness of the typed code is:

    bool check_code(char key)
    {
        const char code[] = "12331";
        const uint8_t length = sizeof code - 1;
        static uint8_t i = 0;  // number of correct characters so far

        if (key == code[i]) {  // correct key
            ++i;               // one more correct character
            if (i == length) {
                i = 0;         // reset
                return true;   // report entry is correct
            }
        } else {               // wrong key
            if (key == '1')
                i = 1;
            else
                i = 0;
        }
        return false;
    }

Note that the part that handles a wrong key press is specific to that
particular code. If you want the program to be generic, so that you can
change the secret code just by changing the string `code`, it can get
more complicated. For example, if the correct code is “12313” and the
user has so far typed “1231”, he has so far 4 correct keys. Then,

* if he types 1, he now has 1 correct key press
* if he types 2, he has 2 correct keys (namely “12”)
* if he types 3, he completed the code.

Handling this generically requires walking back the code string and
searching for the longest possible match. Here is my take at it: replace
the `else` part in the function above with:

    // ...
    } else {               // wrong key
        for (int j = i-1; j >= 0; j--) {
            if (key == code[j]) {
                int k;
                for (k = 0; k < j; k++) {
                    if (code[k] != code[i-j+k])
                        break;
                }
                if (k == j) {  // found a partial match
                    i = j + 1;
                    return false;
                }
            }
        }
        i = 0;  // no partial match
    }
    // ...

Here `j` is the position, within the code string, where the key typed by
the user may match.


body:
As Edgar Bonet mentions in his answer, button debouncing is a critical component, and there are libraries available to simplify this part of the requirement. I used the [Bounce2][1] library with three N.O. push button switches. The following sketch works, but it still needs one or two improvements.

One issue occurs if the user enters 4 button presses, then leaves and comes back in 1 hour. All they have to do press the last correct button in the sequence, then they are authenticated. This could easily be fixed by introducing a `millis()` based timer that starts on the first button press, and stops after 5 seconds, for example. This timer would reset the `counter` variable and the `buttonsPressed[]` byte array.

Perhaps a "enter" code button and/or a "cancel" button would be useful.

  [1]: https://github.com/thomasfredericks/Bounce2

    #include <Bounce2.h>

    const byte sequenceLength = 5;
    byte sequence[sequenceLength] = {1, 2, 3, 3, 1};

    byte buttonsPressed[sequenceLength];
    byte counter = 0;
    const byte ledPinCodeAccepted = 2;
    const byte ledPinCodeDenied = 3;
    const byte button1Pin = 10;
    const byte button2Pin = 11;
    const byte button3Pin = 12;
    const unsigned long debouncerInterval = 50;

    Bounce button1 = Bounce();
    Bounce button2 = Bounce();
    Bounce button3 = Bounce();

    void setup(){
      pinMode(ledPinCodeAccepted, OUTPUT);
      pinMode(ledPinCodeDenied, OUTPUT);
      button1.attach(button1Pin, INPUT_PULLUP);
      button1.interval(debouncerInterval);
      button2.attach(button2Pin, INPUT_PULLUP);
      button2.interval(debouncerInterval);
      button3.attach(button3Pin, INPUT_PULLUP);
      button3.interval(debouncerInterval);
    }

    void loop(){

      if(button1.update()){
        if(button1.read() == 0){
          buttonsPressed[counter] = 1;
          counter++;
        }
      }

      if(button2.update()){
        if(button2.read() == 0){
          buttonsPressed[counter] = 2;
          counter++;
        }
      }

      if(button3.update()){
        if(button3.read() == 0){
          buttonsPressed[counter] = 3;
          counter++;
        }
      }

      if(counter == sequenceLength){
        counter = 0;
        digitalWrite(ledPinCodeAccepted, LOW);
        digitalWrite(ledPinCodeDenied, LOW);
        for(byte i = 0; i < sequenceLength; i++){
          if(sequence[i] == buttonsPressed[i]){counter++;}
          else{break;}
        }
        if(counter == sequenceLength){
          digitalWrite(ledPinCodeAccepted, HIGH);
        }
        else{
          digitalWrite(ledPinCodeDenied, HIGH);
        }
        counter = 0;
      }
    }


message:
Please explain the void loop() section of the sketch

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

int PWMB = 5; //Speed control

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

  //receiver setup
  vw_set_rx_pin(2);
  vw_set_ptt_inverted(true);
  vw_setup(2000);
  vw_rx_start();
}

void loop(){
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    int column = 0;
    String message;
    int commands[30];

    for (i = 0; i < buflen; i++)
    {
      //DEBUG:
      Serial.print(char(buf[i]));

      if(char(buf[i]) == '|'){
        commands[column] = message.toInt();
        message = "";
        column++;
      } else {
        message += char(buf[i]);
      }
    }

  commands[column] = message.toInt();
  }
}
```

This topic is the receiver side of my last topic: https://arduino.stackexchange.com/questions/62576/please-explain-the-sketch-attached/62579?noredirect=1#comment134324_62579
that one sending date and this is a receiver.

questions:

1. The transmitter transfer date array of [60] like: 523 | 487, here `int commands[30];` just 30, is it OK?
2. `if(char(buf[i]) == '|') / commands[column] = message.toInt();`, seems just convert the date before '|'?
3. What is the result of `message += char(buf[i]);`?

Thanks

body:
> The transmitter transfer date array of [60] like: 523 | 487, here " int commands[30];" just 30, is it OK?

If you have a maximum of 59 characters (59 printable characters plus the NULL at the end equals 60), and each number is separated by a `|` character, then the maximum possible numbers you can have, if they are all single digit, is 30. So yes, an array of 30 integers is fine.

> " if(char(buf[i]) == '|') / commands[column] = message.toInt();", seems just convert the date before '|'?

Yes. It takes whatever has been placed in `message` and converts it to an integer, then empties `message` ready for the next number.

> what is the result of " message += char(buf[i]);"? Thanks

It adds the current character from the buffer (pointed to by `i`) to the end of the `message` string.

It's not the best way of doing it, and it can make a mess of your heap causing your Arduino to crash after a while.

Personally I would use `strtok()` directly on the buffer:

    int i = 0;
    char *part = strtok(buffer, "|");
    while (part) {
        command[i] = atoi(part);
        i++;
        part = strtok(NULL, "|");
    }

This of course assumes that `buffer` is properly NULL terminated.


message:
Run website / Javascript game from a Arduino UNO device?

I apologise if this is a dumb question, but I'm trying to find information on whether or not this is possible. I'd like to build a arcade machine to play my custom Javascript 2D game. The game currently runs in the browser (of course), but is it possible to execute the code in the Arduino. I'd like to make an arcade machine that runs from the Arduino and connect the game controls to a joystick. Can anyone tell me is this is possible, or any suggestions about how I can achieve this without rewriting the application.

I found the below link that has some information but this is for a PI
https://www.raspberrypi.org/forums/viewtopic.php?t=194808

body:
The Arduino cannot run Javascript, no.

It could *serve* Javascript from an SD card to a web browser running on a PC / Pi / Phone, etc, but there is no way it can run it itself.


message:
16 X 2 LCD display blank with Arduino Uno

So I am following [this tutorial][1] to make my arduino display hello world and `millis()`, I got it to work for a minute, but then it stopped updating the milliseconds, and when I pushed the reset button it went blank. since then, It has been blank but I have double, triple, and qaudruple checked checked my wiring, and it is flawless. I tried it with both of my 16 segment displays, but to no avail. I have redone the wiring, but it is still blank. Does anybody know what I could be doing wrong?

I followed this diagram [![Fritzing diagram][2]][2]
this is my code:

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

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}
```

This is the result (the screen is lit up, but there is no text even when turning the potentiometer)
[![Picture of the Arduino connected to the LCD display][4]][4]

  [1]: https://www.arduino.cc/en/Tutorial/HelloWorld
  [2]: https://i.stack.imgur.com/YKBcb.png
  [3]: https://i.stack.imgur.com/ps8aK.png
  [4]: https://i.stack.imgur.com/LRoZ1.png

body:
It is most likely that I wasn't providing enough power to the arduino, and or had the potentiometer set to the wrong point. according to [this post][1], you shouldn't run the arduino and display off of USB, because it may not actually be providing 5 volts. So I plugged it into the wall using a DC adapter. It now works.

  [1]: https://arduino.stackexchange.com/questions/29179/lcd-16x2-blank-display


message:
Switch Statement stuck in loop

I am writing a code for a user to enter a 4 digit pin, then use this pin later to unlock a box. The loop is stuck between the "ready to unlock box" and "enter pin" it just keeps flipping between values but i want both to be displayed, just at different times.
<!-- language-all: lang-cpp -->

    #include <Keypad.h> //install keypad library
    #include <LiquidCrystal.h> //install LCD screen library

    const byte ROWS = 4; //include four rows of keypad
    const byte COLS = 4; //indclude four cols of keypad

    char keys[ROWS][COLS] = { //set keypad array equal to numbers on keypad
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };

    int pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8;
    int code[] = {pin1, pin2, pin3, pin4};

    byte rowPins[ROWS] = {45,43,41,39}; //connect to the row pins of keypad
    byte colPins[COLS] = {37,35,33,31}; //connent to the column pins of keypad

    LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //set up pins lcd will be connected to
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //set keypad up to use as variable

    int solenoidPin = 1; //connect motor pin to code

    bool in_press = false;
    void setup() {
       Serial.begin(9600); //start code
       lcd.begin(16,2); //start screen with dimensions
    }

    void loop() //loop of functions to run through
    {
      int key; //initialize key as integer

      lcd.setCursor(0,0);
      lcd.print("Press # to lock,");//welcome screen
      lcd.setCursor(0,1);
      lcd.print("or * to unlock.");

      key = keypad.getKey(); //let arduino know it is waiting for a value

        while (in_press && key == NO_KEY) //check if they want to begin
        {
          in_press = false; //if no key was clicked
          return; //exit the loop and restart
        }

        while (key != NO_KEY){ //if a key was clicked
          switch(key){
          case '#':
            lcd.clear();
            lcd.setCursor(0,0);
            *lcd.print("Ready to lock"); //let user know ready for next step of process
            lcd.setCursor(0,1);
            lcd.print("keys!");
            delay(1000);
            EnterPin1();
            break;*

          case '*':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Ready to unlock"); //let user know ready for next step of process
            lcd.setCursor(0,1);
            lcd.print("keys!");
            delay(1000);
            EnterPin5();
            break;

           default:
           lcd.clear();
           lcd.setCursor(0,0);
           lcd.print("No input");
           lcd.setCursor(0,1);
           lcd.print("detected.");
           break;
      }
     }
    }

    void EnterPin1()
    {
      Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
      bool in_press = false;
      int pin1;

      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Enter your pin.");//let user know you are waiting for input
      delay(1000);

      pin1 = keypad.getKey(); //let arduino know it is waiting for a value

        while (in_press && pin1 == NO_KEY) //check if they want to begin
        {
          in_press = false; //if no key was clicked
          return; //exit the loop and restart
        }

        while (pin1 != NO_KEY) //if a key was clicked
        {
          switch(pin1){
          case '1':
            pin1 = 1;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*"); //let user know ready for next step of process
            EnterPin2(); //go to enter pin function
            break;

          case'2':
            pin1 = 2;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*"); //let user know ready for next step of process
            delay(1000);
            EnterPin2();
            break;

          case '3':
            pin1 = 3;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '4':
            pin1 = 4;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '5':
            pin1 = 5;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '6':
            pin1 = 6;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '7':
            pin1 = 7;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '8':
            pin1 = 8;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;

          case '9':
            pin1 = 9;
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("*");
            EnterPin2();
            break;
       }
      }
     }

body:
Your primary loop code sets `key`, and then has a `while (key != nokey) {}` loop after, but the value of key never changes inside the while loop. Thus, if key is not equal to noKey, the while loop will never exit.

    key = keypad.getKey();

    while (key != noKey) {
      //code that does not change key
    }

That is an endless loop. The fact that there’s a switch statement inside the while loop is immaterial. None of that code changes the value of `key`, so the loop will never exit.

Write it like this instead:

**EDIT**

    key = keypad.getKey();
    while (key != noKey) {
      //Your current code
      key = keypad.getKey();
    }

You have the same logic problem in your `enterPin1` function. You don’t provide the code for your `enterPin2` function, but I would guess it **also** has the same logic problem.


message:
Force TCNT to stay below OCRxA on ATmega328P

I'm using a timer and the `TIMERx_COMPA` ISR to generate a signal in "the background".

This ISR is triggered when the timer reaches a certain value (`OCRxA`), which in turn can be changed by the user.
Once the ISR triggers, the timer is reset and the next waiting period occurs.

If the compare value (`OCRxA`) is changed to a value below the current timer value before having hit the old compare value, the timer keeps running until it overflows back to 0 and hits the new `OCRxA` value. This results in no signal being generated until the timer has looped around, which can be quite long for the 16-bit `TIMER1` timer.

There are multiple way to get around this:

 1. Reset `TCNTx` to zero whenever `OCRxA`. Easy, but one signal will always be off-clock
 2. If `TCNTx` is greater than `OCRxA` (after changing `OCRxA`), reset it to just below `OCRxA`
 3. If `TCNTx` is greater than `OCRxA`, trigger the interrupt manually, where the signal is generated and `TCNTx` is reset

I belive the third option would be the cleanest, both in checking whether the issue has occured as well as for the signal quality.

This is certainly an `X -> Y` problem, so I'm open for other approaches.

My question, for now, would be:
**Can I manually jump to an ISR regardless of its "normal" trigger?**

body:
> Can I manually jump to an ISR regardless of its "normal" trigger?

This should be possible, but is probably not the best solution.

> This is certainly an `X -> Y` problem, so I'm open for other
> approaches.

It would seem you are using the timer in CTC mode. In this mode, when
you write to `OCRxA`, the register is updated immediately, which leads
to the problem you are experiencing. The solution is to instead set the
timer to “fast PWM” mode. In fast PWM mode, the `OCRxA` register is
double buffered: you will be actually writing to a buffer register, and
`OCRxA` is automatically updated from that buffer on the same timer
clock cycle that clears the counter.

It may sound counter-intuitive to use a PWM mode when you do not need
the PWM feature. However, as long as the “compare output mode” is set to
“normal port operation” for both channels, the timer will not generate
any PWM output, and you can legitimately use the fast PWM mode only for
its double buffer feature.


message:
Reading NFC card (PN532) with Arduino Uno

I am trying to detect a RFID card using the NFC-PN532 module and Adafruit_PN532 library.

Initialization code:-

    #include <Adafruit_PN532.h>
    #include <Wire.h>

    #define SCK  (13)
    #define MISO (12)
    #define MOSI (11)
    #define SS   (10)
    Adafruit_PN532 nfc(SCK, MISO, MOSI, SS);

    void setup()
    {
      Serial.begin(9600);
      Serial.println("Initializing please wait.......");
      delay(3000);
      nfc.begin();

      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata)
      {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
      }

      Serial.print("Device Found PN5 Chip");
      Serial.println((versiondata>>24) & 0xFF, HEX);
      Serial.print("Firmware version > ");
      Serial.print((versiondata>>16) & 0xFF, DEC);
      Serial.println((versiondata>>8) & 0xFF, DEC);
      nfc.SAMConfig(); //Set to read RFID tags
      Serial.println("Waiting for RFID Card ...");
    }

Main loop:-

    void loop()
    {
      uint8_t success = 0;
      uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
      uint8_t uidLength;
      success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
      if (success)
      {
          Serial.println("Card Detected!");
      }
      else
      {
          Serial.println("Card Not Detected or Removed!");
      }
    }

Whenever i place a valid card on the PN532, *Card Detected!* is printed on the serial monitor.

However, when i remove the card, *Card Not Detected or Removed!* does not get printed.

How can i make the program  to loop in such a way that it can detect when the card is present/removed?

body:
The default behaviour of `readPassiveTargetID` is to wait "forever" for a card - which is why your code only sees when there is a card present

So, in setup() add `nfc.setPassiveActivationRetries(0x10);` as follows - comments came from my own code, but I'm sure they were originally in some example or other :p

    // Set the max number of retry attempts to read from a card
    // This prevents us from waiting forever for a card, which is
    // the default behaviour of the PN532.
    nfc.setPassiveActivationRetries(0x10);

    // configure board to read RFID tags
    nfc.SAMConfig();

As for "detecting" removal

    void loop()
    {
      static bool wasSuccess = false;
      uint8_t success = 0;
      uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
      uint8_t uidLength;
      success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
      if (success)
      {
          wasSuccess = true;
          Serial.println("Card Detected!");
      }
      else if (wasSuccess)
      {
          wasSuccess = false;
          Serial.println("Card Removed!");
      }
      else
      {
          // you may want to remove this, it will flood the output :p
          Serial.println("Card Not Detected!");
      }
    }


message:
my LM35 temperature sensor gives weird measurements,

Board: esp32

I know my wiring is correct because I get data from the sensor, but the data is a bit weird.

At 22 celcius I get 140, even though if I do the voltage calculation (* 0.473372) it still doesn't work.

the number 0.473372... comes from taking the voltage 4.7v / 1024 * 1000 / 10

My code:

     Serial.print("temp: ");
     float temp = (analogRead(A13) * 0.473372781065088);
     Serial.println(temp);
     delay(2000);

Any answers?

body:
ok, the problem is that i used to the wrong voltage conversion, just use:

    RawValue = analogRead("your analog input pin");
    Voltage = (RawValue / 2048.0) * 3300;
    Serial.println(Voltage);

this should print the tempeture in celcious


message:
Parsing data in arduino?

I just started working with Arduino and in my project I am trying to achieve the COMM between two Arduino using HC-05 in master and slave mode respectively, I configured it all successfully.

Now I want to send three HCSR-04 distance sensors data from master Arduino to slave Arduino via HC-05. I am sending each sensor data separated by " | ". following is the example format., which I got in serial monitor by connecting the master Arduino directly to PC via USB.

168|200|76

167|200|68

166|200|76

168|200|77

Now the problem is I am not able to read and parse this on the slave side. I tried with serail.readbytesuntill but I could not succeed. Please help me out that how I can read it and parse it.

Thanks in advance.

body:
As you can see from the comments Birender Brar, we need more information to be able to help you.

One way to accomplish your goal would be to:

Use `Serial.readBytesUntil('\n', buffer, length)` on the slave device to "read" the data in to a `char` array. The serial monitor can be set to automatically send a `\n` character for testing purposes, but your code on the master will have to do this. Send the data **168|200|76** with a **\n** appended to the end of the data: **168|200|76\n**

Parse the data. Here is a example sketch that parses the data in to a `integer` array.

    // Use Serial.readBytesUntil('\n', buffer, length)
    // to fill the char array / string.
    char str[] = "168|200|76\n";

    // Set array size to maximum number of integers you will receive.
    uint16_t myArray[3];

    void setup(){

      Serial.begin(9600);

      int counter = 0;
      char* pch = strtok(str, "|");

      while(pch != NULL){
        myArray[counter] = atoi(pch);
        pch = strtok(NULL, "|");
        counter += 1;
      }

      // Print out the contents of the integer array.
      for(int i = 0; i < counter; i++){
        Serial.println(myArray[i]);
      }
    }

    void loop(){}


message:
How to use 2 serial port when WifiEsp library uses one of both

I try without success to receive datas from DataPort and transmit them to my computer via WifiPort, using ESP8266 wifi module. Each second, serial datas income on DataPort from another device.

Initialization as follow:

    #include <SoftwareSerial.h>
    #include "WiFiEsp.h"
    SoftwareSerial DataPort(10, 11); // RX, TX
    SoftwareSerial WifiPort(8, 9); // RX, TX

In setup:

    Serial.begin(9600);
    DataPort.begin(9600);
    WifiPort.begin(9600);
    WiFi.init(&WifiPort);

In loop, i do:

    //WIFI PART
    WifiPort.listen();
    WiFiEspClient client = server.available();
    if (client) {
     //.... bla...bla...bla...
    }

    //INCOMING SERIAL PART
    DataPort.listen();
    while (DataPort.available() > 0)
    {
       char c = DataPort.read();
       str += c;
       if(c == '/')
       {
          Serial.println(str);
          str="";
          break;
       }
    }

WIFI PART runs fine if i isolate INCOMING SERIAL PART and INCOMING SERIAL PART runs fine without WIFI PART.
So how can i receive datas on DataPort and transmit them when my computer ask them via the ESP8266 on WifiPort ?

body:
The esp8266 AT firmware doesn't wait until you listen on the SoftwareSerial instance. If there is a connection to the server it sends +IPD and data. If the SoftwareSerial instance doesn't listen the information about client connection is lost.

You must listen to esp8266 all the time, so you can't use two SoftwareSerial instances.

You could use the RX pin of Uno to received data over hardware Serial, if you only receive on DataPort and only print to SerialMonitor.


message:
Simple code to define pins used for Shift Register control - Error: a function-definition is not allowed here before '{' token

I'm simply trying to light up some pins on a customized circuit board via Arduino.
 My code below has the seemingly common error "a function-definition is not allowed here before '{' token".  I've scoured my code for open/close curly brackets and semi-colons. I also regularly do a quick ctrl+T to format it.  Now I am at a loss - any info/advice greatly appreciated!  The error occurs at the '{' after the 'void loop()' line towards the bottom:

    // serially read in 32 bytes at a time to send to shift registers.
    // currently updating every 0.1s in Matlab

    // Define which pins will be used for the Shift Register control
    int dataPin = 2;
    int latchPin = 3;
    int clockPin = 4;

    #include <SPI.h>

    void setup()
    {
      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode(SPI_MODE0);

      SPI.setClockDivider(SPI_CLOCK_DIV16);
      SPI.begin();

      //Configure each IO Pin
      pinMode(dataPin, OUTPUT);
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);

      Serial.begin(115200);
      delay(1000);

      int seq
      [32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

      int timeElapsed = 2000;
      int timeOld = 0;
      int interval = 100;

      void loop()
      {
        Serial.flush();
        Serial.println('K');
        for (int i = 0; i < 32; i++)
        {
          while (Serial.available() == 0);
          {
            seq[i] = Serial.read();
          }
        }
        digitalWrite(latchPin , HIGH);
        digitalWrite(latchPin , LOW);
        for (int i = 0; i < 32; i++)
        {
          SPI.transfer(seq[i]);
        }
        digitalWrite(latchPin , HIGH); //necessary to tramsit to board
      }

body: There's no closing bracket for your `setup()` function and your `loop()` function is inside `setup()`. Close off `setup()` with a `}`and then start `loop()`!


message:
WifiClient and aREST on esp32 - loop until new instructions recieved?

I've created a simple sketch for an esp32 that hosts a REST API that can be accessed via HTTP. Based on the instructions received from the client, the esp32 controls some neopixels with some various animations I've written.

Everything worked as expected until I got to an animation that runs in a while loop. The loop breaks when a new client is detected so that the light can switch functions. However, when the new client is detected, the client seems to be discarded or consumed, and i just end up back in the loop() function until I make a second HTTP request, then the changes to show up.

I'm sure it's something obvious, but what have I done wrong?

**Code:**

    #include "WiFi.h"
    #include "FastLED.h"
    #include "aREST.h"
    #include "ArduinoJson.h"

    #define NUM_LEDS 64
    #define DATA_PIN 18

    CRGB leds[NUM_LEDS];
    int LED_COUNT = 64;
    int MAX_BRIGHTNESS = 200;

    const char* ssid = "wifi";
    const char* password = "password";
    aREST rest = aREST();
    WiFiServer server(80);
    WiFiClient client;

    void setup() {
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, LED_COUNT);
      flashAll(CRGB::Black);
      // Bind urls to the handling functions
      rest.function("random-strobe", randomStrobe);
      rest.function("solid-color", solidColor);
      rest.function("reset", reset);

      // Connect to WiFi and wait until we're connected to continue
      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        flashAll(CRGB::Cyan);
        delay(500);
        flashAll(CRGB::Black);
        delay(500);
      }
      server.begin();
      flashAll(CRGB::Green);
      delay(2000);
      flashAll(CRGB::Black);
    }

    void loop() {
      if (checkForTask()) {
        rest.handle(client);
      }
    }

    boolean checkForTask() {
      // I have tried making this reassignment conditional
      // when the global 'client' is false, but it did not help
      //if (!client) { client = server.available(); }
      client = server.available();
      if (client) {
        return true;
      }
      return false;
    }

    int randomStrobe(String params){
      client.println("HTTP/1.1 200 OK");
      client.println("Content-type:application/json");
      client.println();
      client.stop();
      StaticJsonDocument<200> jsonDoc;
      Serial.println(params);
      Serial.println("params recieved. parsing...");
      auto error = deserializeJson(jsonDoc, params);
      if (!error) {
        // some setup stuff
        while(!checkForTask()){
          // do stuff in here
        }
        return 0;
      }
    }

body:
`server.available()` doesn't return an already 'claimed' connection again. It returns a new connection or an empty WiFiClient object.

The esp8266 and esp32 Arduino core WiFi library close the underlying connection if the last referring WiFiClient instance is freed. The assignment of empty WiFiClient object frees the previous reference to underlying socket and if it was the last referrence, the library closes the socket.

You get a client with `server.available()` in `checkForTask()` and then you call `server.available()` again. It returns an empty WiFiClient object and you assign it to your WiFiClient object. The library closes the referred connection.

The solution is not to check `server.available` until WiFiClient is valid.

    if (!client) {
      client = server.available();
    }


body:
Okay, I've managed to resolve the issue with some general direction from @juraj.

I now have TWO WifiClient instances:

    WiFiClient client;
    WiFiClient newClient;
This allows me to use the newClient instance to check for a new client:

    boolean checkForTask() {
      newClient = server.available();
      if (newClient) {
        Serial.println("new client detected.");
        return true;
      }
      return false;
    }
and only reassign the main client instance when a new client is actually detected:

    void loop() {
      if (!newClient.connected()) {
        checkForTask();
      } else {
        client = newClient;
        runTask();
      }
    }
This seems to work without any discernible side effects or additional resource usage, but if there is a more efficient way to accomplish this, please share. Thanks!


message:
Any idea why my LED fails to operate with the if statement

I have tried several workarounds without success.

    #include <LiquidCrystal.h>
    float tempC;
    int tempPin = 0;// BS E D4 D5 D6 D7
    int buzzer = 4;
    int LED =2;
    LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
    unsigned char i;
    void setup()
    {
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Temp        C ");
    pinMode(LED, OUTPUT);
    pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
    }
    void loop()
    {
    tempC = getTemperature();
    lcd.setCursor(6, 0); // Display Temperature in C
    lcd.print(tempC);
    delay(500);
    }
    float getTemperature()
    {
    int tempReading = analogRead(tempPin); // This is OK
    double tempK = log(1000000.0 * ((1024.0 / tempReading - 1)));
    //Temperature in Kelvin
    tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
    return (tempK - 273.15);

    if (tempC>0)
    digitalWrite(LED,HIGH);
    else
    digitalWrite(LED, LOW);
    }

body:
The LED fails to operate with the if statement because calling the `return` statement [Terminates a function and returns a value from a function to the calling function, if desired][1]. Try your sketch with the `return` statement as the "last thing" in the function.

    #include <LiquidCrystal.h>

    float tempC;
    int tempPin = 0; // BS E D4 D5 D6 D7
    int buzzer = 4;
    int LED = 2;
    LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
    unsigned char i;

    void setup() {
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.print("Temp C ");
      pinMode(LED, OUTPUT);
      pinMode(buzzer,OUTPUT);//initialize the buzzer pin as an output
    }

    void loop() {
      tempC = getTemperature();
      lcd.setCursor(6, 0); // Display Temperature in C
      lcd.print(tempC);
      delay(500);
    }

    float getTemperature() {
      int tempReading = analogRead(tempPin); // This is OK
      double tempK = log(1000000.0 * ((1024.0 / tempReading - 1))); //Temperature in Kelvin
      tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK );
      if (tempC>0) digitalWrite(LED,HIGH); else digitalWrite(LED, LOW);
      return (tempK - 273.15);
    }

  [1]: https://www.arduino.cc/reference/en/language/structure/control-structure/return/


message:
Program Upload Loading problem

Please help me about this program uploading problem.
 Arduino: 1.6.13 (Windows 10), Board: "Arduino Nano, ATmega328P"

Sketch uses 930 bytes (3%) of program storage space. Maximum is 30,720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.
avrdude: ser_open(): can't open device "\\.\COM1": The system cannot find the file specified.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

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

body:
It can have many options, the main reason is it cannot communicate with the Nano.

I try to create a list with options:

  - Hardware issues
    - Nano is broken (solution: change Nano)
    - USB cable is broken (solution: change cable)
    - USB port is broken (solution: change USB port)
  - Software issues
    - USB port 'corrupt' (solution: use another USB port)
    - USB connection incorrect (solution: reconnect USB cable)
    - IDE is corrupt (solution: reinstall IDE)
    - Nano in illegal state (solution: reset/reconnect power of Nano)
    - Serial communication is used (remove RX/TX wires)


message:
Control Air Pump Depending on Pressure Sensor

I am working with an Arduino Mega, a 12V micro air pump, and a MP3V5050 air pressure sensor. The sensor outputs an analog voltage depending on the pressure reading in an inflatable member. I'd like to turn on the micro air pump when the pressure is too low and turn off the pump when the pressure exceeds a determined threshold (exact pressure ranges are currently undetermined).

I have been looking for similar tutorials but this is my first experience working with Arduinos and most existing tutorials are either sensing or pump control, not both. I only have minor coding experience with MATLAB, so any help with this is appreciated. Thank you!

body:
So you basically want a hysteresis control for the air pump.

    const int lowerLimit;//fill in as needed
    const int upperLimit;

    void loop(){
        int pressure = readPressureSensor();
        if(pressure < lowerLimit) turnPumpOn();
        if(pressure > upperLimit) turnPumpOff();

    }

The helper functions I used should be easy to implement based on the tutorials you found.


message:
Verifiy NTP server update - at start

I have function to start an NTP service, right after obtaining wifi connection ( using ESP8266 board ).

from time to time, I get an error saying date and time is`01-01-1970`... which I assume is due to not reaching the server as intended.

A retry counter was added to give few more retries, but somehow I does not do the trick since I never get the expected message `NTP CHECK: #` and retry number ( while get an invalid date ).
I know that `NTP.begin()` returns a bool to describe success/ failure obtaining a NTP server

**EDIT1**: using `NtpClientLib`

How can it be done ?
<!-- language-all: lang-cpp -->

    void startNTP() {
            int counter = 0;
            while ( !NTP.begin("pool.ntp.org", 2, true) && counter <=2){
              Serial.print("NTP CHECK: #");
              Serial.println(counter);
              counter +=1;
              delay(1000);
            };
            NTP.setInterval(clockUpdateInt); // in seconds
    }

body:
> Having read the NTPClientLib code, I would say that the first sync is not even attempted for 1 second after `NTP.begin()` is called anyway.

You could do this

    void startNTP() {
        NTP.begin("pool.ntp.org", 2, true);
        delay(2000); // there seems to be a 1 second delay before first sync will be attempted, delay 2 seconds allows request to be made and received
        int counter = 2;
        while ( !NTP.getLastNtpSync() && counter <=2) {
            Serial.print("NTP CHECK: #");
            Serial.println(counter);
            counter +=1;
            delay(1000);
        };
        NTP.setInterval(clockUpdateInt); // in seconds
    }

or, you could do this

    void loop() {
        // code that doesn't rely on valid time
        //
        // lets say this bit of code requires sync'd time
        if (NTP.getLastNtpSync()) {
            // this will only run once NTP has been sync'd at least once
        }
        // more code that doesn't require sync'd time
    }

Now, you may want to check how long time hasn't been sync'd for in your code and *do something* if it's been too long


message:
Correct Pins for Nodemcu 8266

I am building a small electronic project, and I am incorporating module nodeMcU 8266 in a box.
I would like to know which pins are for "flash" and for "reset"
I know there are 2 buttons on the module for those 2 actions, but I would like to add 2 external buttons for those function on the case of the project, like that I will not need to open the box everytime. I looked on the net, and I guess that for "reset", I must connect to pin "Rst" and pin "Grd", I mean those 2 pin must be shorted, but I prefere to get confirmation before to go further.
And also for the "flash", what are both pins that I must connect the external push button to, to replicate the button present on the module itself.

Also I would like to connect an external LED to the module, following the state of the blue SMD led.
The thing is that there is an SMD blue led on the module, I want to know what are the 2 pins that are similar to the contacts of the blue SMD led.
I want the External LED that I plan to incorporate to the case of the project, to light up when the SMD blue led on the module is on, and when the led to be off when the blue SMD led is off. I want that both follow the same state.
Blue SMD led "On" >>> external led "On"
and
Blue SMD led "Off" >>> external led "Off"

Sorry for the little confused explanation, and thanx in advance for any help and support.

body:
The v0.9 and v1.0 NodeMCU boards have 2 LEDs: One on the AIthinker module, and one on the actual NodeMCU board.

The AIthinker module's LED is connected between Vcc (3.3V) and `GPIO2` (labeled `D4` on nodeMCU). It turns ON when `D4` is set `LOW`.

The NodeMCU LED is connected between Vcc (3.3V) and `GPIO16` (labeled `D0` on nodeMCU).  It turns ON when `D0` is set `LOW`.

The pin labeled `RST` is the Reset signal from the AIthinker module, and is active-high, meaning you connect `RST` to `GND` to put the device in a reset state.

The pushutton labeled `FLASH` is connected between GND and `GPIO0` (labeled `D3` on nodeMCU). When the this pin is `LOW` when the ESP8266 comes out of a reset state, the chip is in flash-bootloader mode, meaning it is ready to receive a new sketch. On a NodeMCU, however, the ESP8266 chip is placed in flash mode by the USB chip and the flashing software, so there is not a need to manually press this button.


message:
Compare incoming message from ESP8266

If there's one thing I never managed to do: it's comparing strings.
So I have the incoming message saved here

    String Message2 = IClient[i].readStringUntil('\n');

And every time I try to compare it with

    strcmp(Message2.c_str(),"Red"); //Hopefully comparing the Message2 with "Red"

I never get 0 returned.

I know from printing the Message2 to Serial that Message2 contains the word "Red".

I've tried using different methods (`string.equal(string2);` etc.) but it never said that they are equal. What am I missing out on?

body:
Found the answer!

After testing around with changing the terminator of the `readStringUntil('\n')` method it appears that there were leading and trailing white spaces, though not being displayed on the serial monitor they still had an impact on the `strcmp(string1, string2)` method.

I could solve this problem by "trimming" the received string before comparing it by using the `String1.trim();` method.

In the end looking like:

    String Message2 = IClient[i].readStringUntil('\n');

    Message2.trim();

    strcmp(Message2.c_str(),"Red");


message:
HD44780 display incorrectly black-on-blue instead of white-on-blue

I have a generic HD44780 compatible 16x2 LCD display, with an already soldered on PCF8574 module. Its backlight is blue, and the characters are supposed to be white (on blue).

It is connected to a generic "Lolin" ESP8266 module which is working fine and is not related to the problem, I hope.

Using the LiquidCrystal_I2C library available at https://github.com/lucasmaziero/LiquidCrystal_I2C, I uploaded the simple "Hello, World" sketch provided, and it works. Used the most current libraries and Arduino IDE as of 2019-03-20.

However, the text displayed is a *very dim black-on-blue* instead of a *bright white-on-blue*.

I do not have any clue on why it happens and how to fix it (and that's my question).

What I know is that if I somehow "glitch" the display (for example by disconnecting and reconnecting the power lead) it will sometimes display gibberish, but in a *very clear white-on-blue*, so I know the LCD hardware is not defective *per se*.

I also tried a few other libraries to the same effect: LiquidCrystal_PCF8574 and LiquidCrystal_I2C (the version available directly from the Arduino IDE, source at https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library)

Below, the example sketch used to generate the problem. Be aware it is for the first LiquidCrystal_I2C library I referred above, but with changes, works with the others I tried.

    #include <LiquidCrystal_I2C.h>

    // Set the LCD address to 0x27 for a 16 chars and 2 line display
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    void setup()
    {
      // initialize the LCD
      lcd.begin(); // Init with pin default ESP8266 or ARDUINO
      // lcd.begin(0, 2); //ESP8266-01 I2C with pin 0-SDA 2-SCL
      // Turn on the blacklight and print a message.
      lcd.backlight();
      lcd.setCursor(0, 0);

    #if defined(ESP8266)
      lcd.print("ESP8266");
    #else
      lcd.print("ARDUINO");
    #endif

      lcd.setCursor(0, 1);
      lcd.print("Hello, world!");
    }

    void loop()
    {
      // Do nothing here...
    }

And a photo of the anomalous display. Turning the constrast potentiometer does not help.

[![anomalous display][1]][1]

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

body:
There is a chance that this LCD would need a negative voltage on contrast PIN. Below there is a simple schematic. You would need to provide pulses on the 'Pulse in' branch. Use Negative voltage branch and potentiometer to feed your contrast pin.

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

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


body:
This answer is just to complement @smajli's answers posted (and accepted) before.

The problem lies in that the contrast pin has to be fed negative voltages when the module is powerered via a 3.3V supply to be able to show text in the correct white-on-blue setting and not on the faint black-on-blue.

@smajli correctly showed how the negative voltage may be generated from the normal positive supply and a pulse generator. However, in my scenario, the pulse generator was connected to the +3.3V rail instead of +5V and the pulses where generated via the ESP8266's PWM feature. Using a duty cycle of 50% it generates about -2V. I'll not reproduce his schematic here, though, but below is a photo of it assembled and in action.

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

The updated code is exactly the same, with only the PWM generation added inside the setup() function:

      pinMode(D8, OUTPUT);
      analogWrite(D8, 512);   // 10-bit!

Finally, the photo below illustrates the final result.

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

Again, thanks again to @smajli for the previous insights and answer.

P.S.: Keen readers will notice the module used now is NOT the same used when I asked the question originally. It is another generic HD44870 module, but without the I2C interface, working in 4-bit mode. However, the exact same problem (black-on-blue text) occurs when the contrast pin is set to anywhere between +3.3V and GND and is promptly solved when using negative voltage.

  [1]: https://i.stack.imgur.com/zbNTo.jpg
  [2]: https://i.stack.imgur.com/Vmyxa.jpg


body:
I have a similar LCD display (I assume it's virtually identical, hard to confirm).  In my case, driving the display VCC (and SCK and SDA) at 3.3v produced the same behaviour you described (dim black text on blue background), but setting VCC to 5v gave me the correct white-on-blue display (even with SCK and SDA still driven at 3.3v, since those are the outputs of the MCU I was using).

It's curious that setting the VCC to 5v did not work in your case.