message:
"previous declaration of 'HTTPMethod HTTP_HEAD'"

I'm getting the following error when I try to compile my code on my  LOLIN(WeMos) D1 R1:

```
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:19: error: 'HTTP_ANY' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                   ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:69:3: note: previous declaration 'WebRequestMethod HTTP_ANY'
   69 |   HTTP_ANY     = 0b01111111,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:29: error: 'HTTP_GET' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:62:3: note: previous declaration 'WebRequestMethod HTTP_GET'
   62 |   HTTP_GET     = 0b00000001,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:39: error: 'HTTP_HEAD' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                       ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:67:3: note: previous declaration 'WebRequestMethod HTTP_HEAD'
   67 |   HTTP_HEAD    = 0b00100000,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:50: error: 'HTTP_POST' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                  ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:63:3: note: previous declaration 'WebRequestMethod HTTP_POST'
   63 |   HTTP_POST    = 0b00000010,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:61: error: 'HTTP_PUT' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:65:3: note: previous declaration 'WebRequestMethod HTTP_PUT'
   65 |   HTTP_PUT     = 0b00001000,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:71: error: 'HTTP_PATCH' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                       ^~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:66:3: note: previous declaration 'WebRequestMethod HTTP_PATCH'
   66 |   HTTP_PATCH   = 0b00010000,
      |   ^~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:83: error: 'HTTP_DELETE' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:64:3: note: previous declaration 'WebRequestMethod HTTP_DELETE'
   64 |   HTTP_DELETE  = 0b00000100,
      |   ^~~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:96: error: 'HTTP_OPTIONS' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:68:3: note: previous declaration 'WebRequestMethod HTTP_OPTIONS'
   68 |   HTTP_OPTIONS = 0b01000000,
      |   ^~~~~~~~~~~~
exit status 1
Error compiling for board LOLIN(WeMos) D1 R1.

```

Here is my code:

```
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WiFiManager.h>

AsyncWebServer server(80);

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
    .button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
   .button2 {background-color: #195B6A;}</style>
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1" style="background-color: #195B6A; border: none; color: white; padding: 16px 40px;
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>
  <h1>SmartHomeHarris-CoLTD</h1>
  <p>GPIO 1 - State off</p>
  <p><a href="/1/on"><button class="button">ON</button></a></p>
  <p>GPIO 2 - State off</p>
  <p><a href="/2/on"><button class="button">ON</button></a></p>
  <p>GPIO 3 - State off</p>
  <p><a href="/3/on"><button class="button">ON</button></a></p>
  <p>GPIO 4 - State off</p>
  <p><a href="/4/on"><button class="button">ON</button></a></p>
  </body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFiManager wm;
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  bool res;
  // res = wm.autoConnect(); // auto generated AP name from chipid
  // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
  res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

  if (!res) {
        Serial.println("Failed to connect");
        // ESP.restart();
  }
  else {
        // if you get here you have connected to the WiFi
        Serial.println("connected...yeey :)");
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
                                     + inputParam + ") with value: " + inputMessage +
                                     "<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  server.begin();
}

void loop() {

}
```

I tried different version of WiFiManager but still it doesn't work.

body:
As the error messages tell you, there are two declarations of `HTTP_OPTIONS` via two includes. Apparently you cannot use these at the same time.

"WiFiManager.h" has the `enum HTTPMethod` that has these constants.

And "ESPAsyncWebServer.h" has another declaration of the same constants.

You might need to read their documentation to learn whether work-arounds are possible.


sender: user

message:
Arduino Nano: HUGE voltage drop on VIN

I am building a small automated indoor greenhouse. I want to use an Arduino Nano to control some LEDs und a fan (both through relays) and a water Grove Water Atomization module. Everything works fine, as long as I power the LEDs and the fan with a 12v supply (3 watts) and the Nano through USB. But I want to power the Nano through the 12v supply, too.

So I built a voltage divider that delivers 7.25v. I measured it with a multimeter. But when I connect it to the VIN of the Nano, the voltage drops to 1.16v. Wich – of course – means that the Nano doesn't start. When I tried it, only the Nano and the relays were connected to the 12v power supply. The relays through voltage divider delivering 5v.

I tried it with an original Arduino and a chinese compatible and got the exact same result both times.

Does anyone have an idea, what I am missing?

sender: assistant

body: You just can't use a couple of resistors to deliver a reliable voltage source like that. The voltage divider effectively works as advertised with zero current. Your Nano will take more than zero current. See [here](https://electronics.stackexchange.com/questions/388450/voltage-divider-as-supply-voltage) for one discussion.


body: If you do not place more than a few mA load on the Nano 5V pin you can wire 'Vin' directly to 12V. Your resistor idea sounds great however when you add the fluctuating current requirement you cannot get a stable output it will change with the load. Note the divider circuit resistance has to be very low in value to stay close making it not practical.


message:
Why does Arduino Nano 33 IoT always choose the weakest WiFi BSSID?

I have an Arduino Nano 33 IoT configured to connect to my WiFi network with a pretty straightforward code:

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

int status = WL_IDLE_STATUS;
status = WiFi.status();
while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    if (status == WL_CONNECTED) break;
    delay(5000);
}
```

My problem is that in an environment with multiple access points sharing the same SSID (roaming environment) my Arduino is constantly connecting to the weakest one of the access points.

I verified with WiFi Explorer on my laptop that multiple access points are in reach at the same location where the Arduino is placed and for some reason my Arduino decides to connect to the base station with BSSD ending **:CA:81**, which is paradoxly the weakest one:

[![WiFi explorer][1]][1]

Is there a way to address this issue?

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

body:
On Nano 33 IoT the WiFi network adapter is NINA esp32 module with Arduino's nina-fw. nina-fw is written with the use of ESP-IDF framework by the esp32 manufacturer Espressif.

To connect to an AP the ESP-IDF has [a configuration function][1], which takes a structure with settings. One of the settings is wifi_scan_method and [nina-fw uses][2] WIFI_FAST_SCAN. The alternative is WIFI_ALL_CHANNEL_SCAN.

> WIFI_FAST_SCAN Do fast scan, scan will end after find SSID match AP

There is no simple solution for this. I don't know why they changed the setting. If it should be configurable then the firmware and the WiFiNINA library have to change to support it.

Or you can get the sources of the firmware, change the setting, build the firmware (it is not trivial) and flash it to NINA on your Nano.

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv419esp_wifi_set_config16wifi_interface_tP13wifi_config_t
  [2]: https://github.com/arduino/nina-fw/blob/c84aa3406717af771653733fb9c3480bdf5e1a64/arduino/libraries/WiFi/src/WiFi.cpp#L188


message:
Is it possible to connect 2 PLC which have Ethernet interfaces using Ethernet shield, arduino Nano and SX1278?

I need to connect 2 PLC which have Ethernet interfaces over 1 km and i was thinking of connecting via SPI an ethernet shield and an SX1278 module to a arduino nano (UNO) board.

Do i need logical converter between Nano and SX ? (I saw a lot of videos showing people doing it without the logical converter)

Is it Nano capable of handling the information passing from Ethernet to SX ?

If possible,  where can i find an example of such setup ?

body:
The simple fact you are asking this question means you don't have the skills or knowledge to comprehend what it is you are asking (I don't mean this in a nasty way, just that in having to ask it shows you lack some of the basic knowledge you will first need to accomplish the task).

Firstly you need to understand what Ethernet is.  The cable itself is just one layer (the "Physical" or lowest layer) of the 7-layer OSI model.

On top of that are 6 more layers at increasing levels of abstratcion.

You will need to understand *what* is being communicated between the two PLCs and at what layer of the OSI model it makes the most sense to create your bridge.

Do you do it at the application level, where you receive the data that is sent by a PLC and interpret it, then send that interpretation over the bridge to be reconstructed at the other and? Or do you do it at the socket layer where you capture the raw information and send that, or at the transport layer where you take the network data and forward that, or at the data layer where you take the ethernet electrical signals and pass that logical data to the other end to be replicated?

But then of course there is the other question: Is it actually Ethernet? Or is it some other protocol that just happens to use CAT5 (or similar) cables to transfer the data? If that is the case you first need to what that protocol is before you can even consider connecting anything to the wire.

Only once you have answered those questions can you go on to ask more about implementing your setup.  Things like:

* What hardware do I need to connect to the PLC
* What protocol do I need to implement
* What high level facilities would the Arduino need to provide for the connection to function

Etc. Lots of questions.

So:

* Is it actually Ethernet or some other protocol carried by CAT5 cables, such as RS-485 / RS-422
* Given the actual protocol, what interface do you need to get?
* If it is Ethernet, does it use IP or something else (IPX?)
* If it is IP does it use TCP or UDP for communication? Or both?
* If it is IP what controls the IP addresses? Will you need to implement a DHCP server, or hijack the IP address of the "remote" end of the bridge?
* Once you understand the protocols, is timing critical in your system? Does PLC A expect a response from PLC B within a finite defined time frame?
* Given how unreliable a wireless connection is, how will you handle dropped or corrupted packets?
* Does your chosen connection technology have enough bandwidth to transmit the data fast enough to prevent a backlog of data and lost information?

As you can see there is a *huge* amount of things to consider when designing this kind of thing.

If you have a list of 20 steps to go through to implement this, you are trying to start at maybe step 15 or 16. You need to rewind right back to step 1 and look at the absolute basics of what it is you are trying to do and what it is you are trying to do it to.


message:
Using prototype PCBs as Arduino shield

Is is possible to use prototype PCBs (PCB with grid of unconnected holes with copper around them, usually with pitch 2.54 mm) as Arduino shield, when they are fitted with appropriate pin headers?

I am asking this question because I am not sure whether the Arduino UNO pin headers (which are split) will fit to the headers on the prototype PCB where I will “leave out” one pin on the header.

(Yes, I ho not have a Arduino board to try it out now.)

body:
For the UNO style boards, no it's not possible. The digital headers have a 0.16 inch gap between them which offsets one set of headers 0.06" from the holes in the shield.

For this reason you can buy specific Arduino prototyping shields that have the headers in the right locations.


message:
Char array filling with blanks

When I run this code, my `pin` and `pinCheck` arrays are not being filled with the results of `keypad.getKey()`. If I print the value at each index, the result is blank. As far as I can tell, I am either not writing a char to the array, I am misreading the array when it comes time to print to the serial monitor, or `.getKey()` only works in the main or loop functions.

```
#include <Key.h>
#include <Keypad.h>

void armDisarm(void);
boolean array_cmp(char, char, int, int);

bool isArmed = 0;
char pin[3];
char pinCheck[3];
const byte ROWS = 4; // number of rows
const byte COLS = 4; // number of columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'#','0','*','D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {5, 4, 3, 2};    // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

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

void loop()
{
  if (isArmed == 1)
  {
    Serial.println("SYSTEM ARMED! ENTER PIN TO DISARM!");
  }
  else
  {
    Serial.println("SYSTEM DISARMED! ENTER PIN TO ARM!");
  }
  armDisarm();
}

void armDisarm(void)
{
  while(true)
 {
    if (isArmed == 0)
    {
      for (int i = 0; i < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pin[i] = keypad.getKey();
        Serial.println(pin[i]);
        i++;
      }
      isArmed = 1;
      return;
    }
    else if (isArmed == 1)
    {
      for (int j = 0; j < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pinCheck[j] = keypad.getKey();
        Serial.println(pin[j]);
        j++;
      }
      for (int k = 0; k < 4; k++)
      {
        if(pinCheck[k] != pin[k])
        {
          isSame = 0;
          break;
        }
        else
        {
          isSame = 1;
        }
      }

      if (array_cmp(pin, pinCheck, sizeof(pin), sizeof(pinCheck)) == 1)
      {
        Serial.println("same pin"); //used for bebugging
        isArmed = 0;
        return;
      }
      else
      {
        Serial.println("INCORRECT PIN! CLAYMORE ROOMBA DEPLOYED!");
      }
    }
  }
}

boolean array_cmp(char a[sizeof(pin)], char b[sizeof(pinCheck)], int len_a, int len_b)
{
  int n;

  // if their lengths are different, return false
  if (len_a != len_b)
  {
    return false;
  }

  // test each element to be the same. if not, return false
  for (n = 0 ;n < len_a; n++)
  {
    if (a[n]!= b[n])
    {
      return false;
    }
  }

  //ok, if we have not returned yet, they are equal :)
  return true;
}
```

body:
First of all, there is one essential feature of the Keypad library you
have to understand: it is non-blocking. When you call `keypad.getKey()`,
it returns immediately, and almost always returns `NO_KEY` to signal
that no key was pressed since the last time you checked. If a key was
pressed, `keypad.getKey()` returns that key and then, _on the next
call_, it again returns `NO_KEY` because no key was pressed _since the
last time you checked_.

It is important to realize that, whenever a key is pressed, that key is
returned _only once_ by `keypad.getKey()`. You should manage to not miss
it!

Now consider this loop:

```c++
for (int i = 0; i < 4;)
{
    if (keypad.getKey() == NO_KEY)
    {
        continue;
    }
    pin[i] = keypad.getKey();
    Serial.println(pin[i]);
    i++;
}
```

This will run very fast, and almost always looping through the
`continue` statement. When a key is pressed, `keypad.getKey()` returns a
value different from `NO_KEY` (and this value _is lost_), the test
within the `if` is false, and the statement that follows gets executed,
namely:

```c++
    pin[i] = keypad.getKey();
```

But this is _another_ call to `keypad.getKey()`, which returns `NO_KEY`,
so this is what gets saved in the array.

This is how I would write that loop:

```c++
for (int i = 0; i < 3; i++)
{
    char key = NO_KEY;
    while (key == NO_KEY)
    {
        key = keypad.getKey();
    }
    pin[i] = key;
    Serial.println(pin[i]);
}
```

Please note that:

* The value returned by `keypad.getKey()` is _always_ saved into a
  variable, you do not want to loose it! When we get something other
  than `NO_KEY`, the value previously saved into the variable is stored
  in the array.

* I moved the `i++` where it belongs, in order to avoid that very
  confusing way of controlling the loop.

* The `if` has become a `while`, because we do not want to move to the
  next iteration until we have actually read a valid key.

* The loop does only three iterations, because this is the length of the
  array `pin`, which we would otherwise overflow.


body:
As an addition ToEdgar Bonets answer. I should warn you that your code keeps adding position in as each time you check array you are increasing the value of i. As a result you are filling arrays with NO_KEY.

Also having have build a security alarm on arduino before (Or shouldnt we know thats what you are doing?) I should warn you that waiting for Keyboard inputs mean that you are not checking tamper or alarm even when its armed because you are stucked inside nonloop function waiting for imput.
I have personally made input a global struct
```
struct foo{
   char digits[4];
   byte digit=0;
} pinCode;
```
You can either take instance of the struct as a parameter to your function or because its global use it internaly.
```
bool addDigit(char button){
  /*here deal with many potential inputs*/
```
you can then inside your function assign the button pressed as
```
pinCode.digits[pinCode.digit]=button;
pinCode.digit++;
```
if you are passing the instance of the struct as a pointer then it will change to
```
pinCode->digits[pinCode->digit]=button;
pinCode->digit++;
```
you can then inside this funtion test if password is confirmed (OK is pressed) and return true.

While the end of the password isn't reached, just return false.
SO within the loop you would have something like:
```
key = keypad.getKey();
if(key!=NO_KEY){
   if(addDigit(key)) //Here take an action based on inputs
}
// Do all the other stuff alarm has to do


message:
Read SD card on ATMEGA328 from ESP826

I have a ATMEGA328 with ESP826 (like this http://arduinolearning.com/hardware/atmega328-esp8266-arduino-board.php) and can successfully send information from the ATMEGA328 to the ESP826 via serial.
I can also record information from the ATMEGA328 to SD card.
What I would like to do is read data from the SD card with the ESP826 so I can upload it to a server..

When I try to connect directly:

    #include <ESP8266WiFi.h>
    #include <SPI.h>
    #include <SD.h>

    File myFile;

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

      Serial.print("Initializing SD card...");

      if (!SD.begin(10)) {
        Serial.println("initialization failed!");
        return;
      }

      myFile = SD.open("/");

      printDirectory(myFile, 0);

      Serial.println("done!");

    }

    void loop(){
    }

    void printDirectory(File dir, int numTabs) {
      while (true) {

        File entry =  dir.openNextFile();
        if (! entry) {
          // no more files
          break;
        }
        for (uint8_t i = 0; i < numTabs; i++) {
          Serial.print('\t');
        }
        Serial.print(entry.name());
        if (entry.isDirectory()) {
          Serial.println("/");
          printDirectory(entry, numTabs + 1);
        } else {
          // files have sizes, directories do not
          Serial.print("\t\t");
          Serial.println(entry.size(), DEC);
        }
        entry.close();
      }
    }

It doesn't find the card. This is regardless of whether I have pins 1&2 ON or not.

Is there any way to write to the SD card using the ATMEGA328 and read that from the ESP826 (to send the files to the cloud)?

body:
You can't. There's no connection between the ESP8266 and the SD card.

However you can program the ATMega328 to read the SD card then send that data to the ESP8266 for forwarding to the internet.


body:
Have you consider something like nodeMCU?
Is there a reason why you using such a complicated board?
This would enable you to connect your SD card reader directly to nodeMCU, which can read the data  from same inputs as atmega328 (watch for voltage differences) including the sensors which has the capability of uploading data to the cloud without the need of additional MCU, while making debugging far easier.

I know that I am going to get dislikes here, but it looks to me like one of those cases when you connect two things that would work better of alone, making something does doesn't do either ones job very well.
Maybe you can get a refund...
If not contact your card issuer for "Cardholder not present" claim that bot VISA and Master card have.

Is there any reason why wouldn't standard nodeMCU be enough for your project? (probably superior)

If its not enough:

If you connect node-mcu (5-15 Eur/Pounds/Dolars) and a nano (About half of the price) on a breadboard and connect them together via (software) serial pin, (using jumper cables and resistive divider), you can program them without messing with pointless dip switches  and learn something usefull for future projects. latter you can replace nano for 3V3 pro miny to remove even the divider.
There is this absurd idea from Arduino core team developers of using superiour Esp32 MCU as a secondary tool to inferiour ATMEGA328, while logically you should do the opposite.
This is amplified by the fact that I would personaly consider Esp8266 core arduino libraries superior to those made for atmel...
You might even find that the 2-3MB FS you can create on ModeMCU might be enough without the need of SD card.

I had a quick look through the site and a combination defaulting to http and nonstandard hardware, combined with low standard of explanation, **But what I find really imoral is harvesting excessive number of domain names on a similar subject** which could have been used for other projects makes me think if these tutorials are designed to increase the sales of badly designed boards... I would recommend you to change the tutorial source...


message:
I cannot communicate using RS232 between Arduino and Lakeshore Fluxmeter. How do I get data back from the fluxmeter?

I am using an Arduino Leonardo and the DFrobot RS232 shield to try and communicate with a flux meter. I am trying to write "UNITS?", which would have the fluxmeter send back a single byte that would translate to which units it is using.

The problem is, I can see from the Arduino side it is writing those 6 bytes, but at the `if (Serial1.available())`, there is nothing there. I have the switch on the shield to on, and I did the tutorial on the DFrobot wiki to make sure my shield works.

I think it has to do with how the `Serial1.write()` is done. I don't think it is receiving the command correctly, so it does not respond.

Shown below is my code:

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

// Define pins, so you only need to change them in one spot
#define BUTTON 7

bool runner = 0;

void setup() {
  // Begin Serial communication at 9600 baud rate
  Serial1.begin(9600);
  pinMode(BUTTON, INPUT);
  // create an interrupt that will call send_command() whenever the button pin has a rising edge
  attachInterrupt(digitalPinToInterrupt(BUTTON), send_command, RISING);
  // start the Keyboard process
  Keyboard.begin();
}

// called when button is clicked
// will use Serial.write() to send commands
// then will write the data with the keyboard
void send_command() {
  runner = 1;
  return;
}

void loop() {
  if (runner) {
    char pkneg, pkpos;
    // This next section writes the commands to the 480,
    // then reads the data and prints it to the Serial Monitor
    int sent = Serial1.write("UNITS?");
    Keyboard.println(sent);
    if (sent <= 0) {
      Keyboard.print("Fort Myers we got a problem\n");
    }
    //Keyboard.print(marker);
    delay(5000);

    if (Serial1.available()) {
      Keyboard.print("Here!\n");
      pkpos = Serial1.read();
  }
  else pkpos = 'x';
  pkneg = 'x';

  char pkneg1[10], pkpos1[10];
  // dtostrf(pkpos, 4, 3, pkpos1);
  // dtostrf(pkneg, 4, 3, pkneg1);

  Keyboard.print(pkneg);
  Keyboard.print('\t');
  Keyboard.print(pkpos);
  Keyboard.print('\n');

  // for testing

  runner =0;
  }
}
```

body:
You are lacking the line terminators from your serial writing. As it says in the manual:

> * Terminators are fixed to CRLF.

And in the example code (the Quick Basic is probably the easiest to follow):

```
CMD$ = CMD$ + TERM$
PRINT #1, CMD$;
```

(where `TERM$` is "\r\n").

So changing your `Serial1.write` to include the terminators should help the device to recognize that you have finished sending the command and it should respond to it:

```
Serial1.write("UNITS?\r\n");
```

By the way, testing the return value of the `Serial1.write` is pointless. It will always return the number of characters in the string you supplied - serial data over the UART pins is always sent even if there is nothing there to receive it.


message:
Invalid use of non-static member function

In order to explain my problem I used 3 classes: `Actions`, `Triggers`, and `Combine`.

`Actions` simulates an action function, that is defined externally.

`Triggers` has that function that needed to be executed.

`Combine` combines `Actions` and `Triggers`.

Now, `void combine_funcs()` is a member function of `Combine` class, when the match between `Triggers` and `Actions` happen -> passing a function to be executed.

Here `void combine_funcs()` is show with `std::bind`, but is was also tested straight foreward.

Error outsput is given below code.

    class Actions
    {
      typedef void (*cb_func)(uint8_t resaon);

    private:
      cb_func exter_func;

    public:
      void get_external_func(cb_func func)
      {
        exter_func = func;
      }
      void callAction(uint8_t i)
      {
        exter_func(i);
      }
    };

    class Triggers
    {
    public:
      void this_is_external_func(uint8_t i)
      {
        Serial.println(i);
      }
    };

    class Combine
    {
    public:
      Actions a;
      Triggers b;

      void combine_funcs()
      {
        a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
      }
      void loop()
      {
        if (millis() > 10000)
        {
          a.callAction();
        }
      }
    };

    Combine combo;

    void setup()
    {
      // put your setup code here, to run once:
      Serial.begin(115200);
      Serial.println("Start!");
      combo.combine_funcs();
    }

    void loop()
    {
      // put your main code here, to run repeatedly:
      combo.loop();
    }

Compilation output:

```
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
    sketch_jul26a:36:34: error: cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}
       36 |     a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
          |                         ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |                                  |
          |                                  std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:9:34: note:   initializing argument 1 of 'void Actions::get_external_func(Actions::cb_func)'
        9 |   void get_external_func(cb_func func)
          |                          ~~~~~~~~^~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::loop()':
    sketch_jul26a:42:20: error: no matching function for call to 'Actions::callAction()'
       42 |       a.callAction();
          |                    ^
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note: candidate: 'void Actions::callAction(uint8_t)'
       13 |   void callAction(uint8_t i)
          |        ^~~~~~~~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note:   candidate expects 1 argument, 0 provided
    exit status 1
    cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}
```

**EDIT_1 : Change `Combine` class to inherete other classes**

    class Combine : public Actions, Triggers
    {
    public:
      void combine_funcs()
      {
        get_external_func(this_is_external_func);
      }
      void loop()
      {
        if (millis() > 10000)
        {
          callAction(13);
        }
      }

yeilds same error:

    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
    sketch_jul26a:33:23: error: invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'
       33 |     get_external_func(this_is_external_func);
          |                       ^~~~~~~~~~~~~~~~~~~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:22:8: note: declared here
       22 |   void this_is_external_func(uint8_t i)
          |        ^~~~~~~~~~~~~~~~~~~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: At global scope:
    sketch_jul26a:60:6: error: redefinition of 'void setup()'
       60 | void setup()
          |      ^~~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:46:6: note: 'void setup()' previously defined here
       46 | void setup()
          |      ^~~~~
    sketch_jul26a:68:6: error: redefinition of 'void loop()'
       68 | void loop()
          |      ^~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:54:6: note: 'void loop()' previously defined here
       54 | void loop()
          |      ^~~~
    exit status 1
    invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'

    };

body:
The problem is, that the return type of bind is not the same type as the type of the original function so you can't set it with `void get_external_func(cb_func func)`.

But it looks like in X->Y problem. If you do OOP, use objects.

I take the sketch in the question as a test so I want comment on other parts and how to do them properly. I just made minimal changes to pass the object and call the method (member function) with the object.

```

class Triggers
{
public:
  void func(uint8_t i)
  {
    Serial.println(i);
  }
};

class Actions
{
  Triggers* trigers;

public:
  void set_triggers(Triggers* t)
  {
    trigers = t;
  }

  virtual void callAction(uint8_t i)
  {
    trigers->func(i);
  }
};

class Combine
{
public:
  Actions a;
  Triggers b;

  void combine_funcs()
  {
    a.set_triggers(&b);
  }
  void loop()
  {
    if (millis() < 10000)
    {
      a.callAction(1);
    }
  }
};

Combine combo;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Start!");
  combo.combine_funcs();
}

void loop()
{
  // put your main code here, to run repeatedly:
  combo.loop();
}
```


message:
Using ESP32 GPIO, Serial.printf(...) prints weird characters when input is larger than 12 characters

Learning C with the Freenove WSP32-WROVER starter kit and there's an issue I cannot find an answer to. Using the provided code to input some data with UART, it would seem to have a strange behavior whenever I input string that is larger than 12 characters. Under 12, everything is fine.

```
/**********************************************************************
  Filename    : SerialRW
  Description : Use UART read and write data between ESP32 and PC.
  Auther      : www.freenove.com
  Modification: 2020/07/11
**********************************************************************/
String inputString = "";      //a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

void setup() {
  Serial.begin(9600);
  Serial.println(String("\nESP32 initialization completed!\n")
                + String("Please input some characters,\n")
                + String("select \"Newline\" below and click send button. \n"));
}

void loop() {
  if (Serial.available()) {         // judge whether data has been received
    char inChar = Serial.read();         // read one character
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  if (stringComplete) {
    Serial.printf("inputString: %s \n", inputString);
    inputString = "";
    stringComplete = false;
  }
}
```

The output of any larger than 12 characters string is sometimes a little bit different, but always seems to follow a similar pattern. For any 13 characters long string, I get :

>⸮⸮?

The ouput changes if I add characters, for example 20 characters is this :

>D⸮⸮?

I assume the unprintable character is a new line.

The baud rate is set at the same value both in the code and in the serial monitor and I get the same results if I change the baud rate.

Any explanation regarding this behaviour and how to avoid it would be most welcomed.

body:
Change:

```c++
Serial.printf("inputString: %s \n", inputString);
```

to:

```c++
Serial.printf("inputString: %s \n", inputString.c_str());
```

`%s` expects a `const char *` which is not what `inputString` yields.

What you're seeing in the difference between strings larger and smaller than 12 characters is down to whether or not [small string optimization](https://github.com/espressif/arduino-esp32/blob/2.0.4/cores/esp32/WString.h#L307-L313) is in use and how structures are passed in the ESP32's calling convention.


message:
Arduino/ESP8266 How to give users updated compiled code without using Arduino IDE

I have an Arduino project using an ESP8266 dev board.

I want to be able to give users updates to my software in the future and I don't want them to have to download the code and the Arduino IDE to do so.

Is there a way to take the compiled code from the Arduino IDE and use some other software to upload the compiled code to the ESP8266 dev board?

body:
I figured it out! After getting some comments, **I have decided to got with Option B.**

**Firstly for both options, you will need to:**
 1. Using the Arduino IDE
 2. Under the "Sketch" tab; click "Export compiled Binary", then click "Show Sketch Folder" (This is where your .bin file is)

**Option A - Using an application**

 3. Download the ESPEasyFlasher code from below.
 4. You will probably have to open this with Visual Studio and compile it yourself.
 5. Make sure your .bin file and esptool.exe are included in your bin/release folder or  wherever you want to have the "FlashESP8266.exe" program permanently.
 6. Run the "FlashESP8266.exe" program; select your com port, select your bin file, select the upload rate, then click flash.

So you just have to make sure that your user has;
  - Python installed
  - Provide them a copy of the "FlashESP8266.exe"
  - Provide them a copy of the "esptool.exe"

I don't know if this will work the exact same for an ESP32 as I believe they have two .bin files...

Resources:

https://nerdiy.de/en/howto-esp8266-mit-dem-esptool-bin-dateien-unter-windows-flashen/

https://github.com/BattloXX/ESPEasyFlasher

**Option B - Using OTA Update**

   3.You will need to first implement OTA Updates as @StarCat has pointed out
    in the comments.

   4.Navigate to the URL you implemented.

   5.Choose the File System, select your .bin file.

   6.Click Update FileSytem

   7.Should take a couple seconds or so and should be updated!

I can confirm this works when your ESP8266 is set to host a Soft Access Point.

**Koudos to @StarCat.**

Resources:

https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#web-browser


message:
How to control 1 servo with 2 potentiometer?

I have been building a RC plane completely from scratch using an arduino but I am fairly new to this.

Essentially I have been able to make my two arduinos communicate with each other so that when one joystick is moved, the brushless motor is activated, and when the other joystick is moved up or down, 2 servos are activated to push my plane flaps up or down.
The problem I am running into is I am not sure how to control the same servo motors when I move the joystick left and right. Ideally when moved left, one servo would push a flap up and the other down, and vice versa.

The closest thing I have come across on the internet is using a push button to switch between the two control methods but I would ideally like everything to work more smoothly together w/o the push button if that makes sense.

If anyone has any ideas what to write in my code please let me know or if I need to clarify anything else.

Thank you so much for the help in advance.

body:
First you should make sure that your inputs and outputs are separated in code. This means that the inputs (like the joystick potis) only change variables in your code. Then below the input code block you output these variables to the servos and motors. This makes the code in your situation easier, since the inputs don't trigger actions, but only set the variables for the actions, which then get executed by another code block.

Your up-down joystick sets the position for the flaps (as you have already coded). The left-right joystick then only creates a deflection from that position. You can code this like the following (in pseudo code):

    Read up-down joystick
    Map value from analog value to range 0 to 180 and save in variable "flap_pos"
    Read left-right joystick
    Map value from analog value to range -90 to 90 and save in variable "flap_deflection"
    Write servo1 value as "flap_pos+deflection"
    Write servo2 value as `flap_pos-flap_deflection"

Note that `flap_deflection` can be negative or positive (depending on joystick direction) and can thus deflect in both directions. And the different signs in the servo commands make sure that the deflection will behave inverted between the servos (one side moving down when the other is moving up). You will need to adjust the value mapping depending on your flap hardware. And you might want to restrain the values to a specific range (also depending on your hardware).

As you can see there is no `if` statement or similar in the pseudo code above. All the magic is in the mapping of the read analog values and the addition and subtraction.


message:
How to connect a 4 channel relay switch directly to a 5V power source?

When connecting a 4 channel relay to a Arduino Pro mini, there is a noticeable power drain from the board when relays are active. This is clearly visible as the 16x2 LCD dims. I remember reading that this could damage the Arduino, is this true?

In any case, since the entire project will be powered by a rechargeable 12V battery, I bought some buck converters to lower the voltage from 12V to 4.66V (this is what I identified the output to be from the Arduino, I even tried increasing it to 4.8V), so I can power the relay switch directly instead of going through the Arduino.

However, the relay does not power on and I have no idea why.
Can someone help me understand? I'm new to this.

[![Connections specs][1]][1]

## Parts
* [eBoot Mini MP1584EN DC-DC Buck Converter](https://www.amazon.com/dp/B01MQGMOKI/ref=psdc_10967761_t1_B00WQ6V0F0?th=1)
* [4 Channel 5V Relay Shield Module](https://www.amazon.com/SunFounder-Channel-Shield-Arduino-Raspberry/dp/B00E0NSORY/ref=sxin_16_ac_d_bv?ac_md=0-0-QnVkZ2V0IFBpY2s=-ac_d_bv_bv_bv&content-id=amzn1.sym.14453ffd-7768-40d0-9a7f-8d0063113f56:amzn1.sym.14453ffd-7768-40d0-9a7f-8d0063113f56&crid=FKND3XEVJV9X&cv_ct_cx=4+channel+relay&keywords=4+channel+relay&pd_rd_i=B00E0NSORY&pd_rd_r=28bf80b6-e864-4fb2-8642-62fbecc615ab&pd_rd_w=P7Hpq&pd_rd_wg=Ud6Hy&pf_rd_p=14453ffd-7768-40d0-9a7f-8d0063113f56&pf_rd_r=FAVKZ916TYSNE357TN5B&psc=1&qid=1659216124&sprefix=4+channel+relay,aps,94&sr=1-1-270ce31b-afa8-499f-878b-3bb461a9a5a6)
* [Mini Nano V3.0 ATmega328P Microcontroller Board](https://www.amazon.com/Deegoo-ATmega328P-Microcontroller-Board-Arduino/dp/B07R9VWD39/ref=sr_1_16?crid=DOE6GRRRCSV8&keywords=arduino+pro+mini&qid=1659216199&sprefix=arduino+pro+mini,aps,99&sr=8-16)

## Edit

I found [this answer](https://electronics.stackexchange.com/questions/505318/how-to-properly-use-a-relay-module-with-jd-vcc-from-arduino-raspberry) but I do not know if it applies and, if it does, what changes I would need to make with my current connections.

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

body:
OK,

 1. You should not ever use inductive load from voltage regulator shared with MCU.
 2. Relays are massive eaters, and the 4.6 volts were actually caused by arduinos NTC kicking in to protect arduinos supply, the relays on your picture are designed for power around 5DC so you should design your circuit in that regards. I am impressed by the fact that little regulator on pro miny even survived it, meaning its likely to be reasonably made board.
The Pro miny voltage regulator is nowhere near as powerful as thatone on Nano or UNO and only barely manages to run anything more then the MCU itself.
 3. Watch your current. I am not sure whats the max current of your buck converter. Amazon specifications usually do not concern themselves with petty things like reality. SO it might not be strong enough to run all 4 relays. Though Colour is matching more often then wrong
 4. Again relays are massive power eaters and the lower voltage, the higher current so you can often lower your consumption by using relays made for higher voltage.
 5. Next batteries don't store that much power, get influenced by external influences and their capacity further decreases as the life goes. you can save a lot of power by using transistors/mosfets where possible.

It takes considerable additional design steps to make project run on a battery and replacing relays for bigger transformers or mosfets is often part of it.

Set any of the relays on, in arduino code and measure its voltage against ground.
If its 5V then arduino is sending signal fine.

If it is not, then check the resistance between its and arduinos ground. if its just few ohms look for issues on the arduino.
if resistance between grounds is big or even unmeasurable, then connect the arduino ground with relay board ground.
If you can measure 3-5V (Dependant on a pro mini version) between arduinos output and the ground then you don't have enough power on the relay modules supply.

Extra note:Make sure the arduino is not powered from buck converter as volage regulator has minimum voltage diference it can drop and could not be powered via regulator from a supply of less then 6.something Volts

As stated in Jroberts answer once everithing is working, you might want to disconnect the suplly to arduino from 12 volt source to Vin; and connect your arduino to your buck converter set at 5V (4.95ish-5.05ish) to 5V pin adding 10uF capacitor between the 5V and GND on arduino.
The buck converters are more efficient in dropping voltage, then voltage regulators, so that would extend your battery life. (this isnt majourisue as compared to the arduinos consuption is tiny compared t the consumption of the relays


body:
I'm not a double-E but I'll take a stab at it.

Arduinos' on-board voltage regulators are not particularly efficient; they sink to ground whatever the board doesn't draw, dissipating it as heat. And they usually are not provided with heat sinks, meaning the regulator is heat-limited. You're powering the Arduino with 12v, so whatever current the Arduino does draw, that same current times 7 volts (the voltage drop from 12v to 5v) is waste heat. Driving four relay coils draws (using the specs on the Amazon page) adds 80mA (times 7v) to that heat dissipation.

It looks like at least some Pro Minis (yours?) use a Micrel 2095 voltage regulator which has internal current limiting which may include thermal protection(?) -- shutting off your Arduino when the regulator gets too hot.

Despite that some of the above is speculative on my part, it does suggest an experiment. You've got a regulated 5v source - instead of powering the Arduino at Vin from the 12v source, try powering it's +5v pin with +5, which would significantly reduce the regulator's power dissipation (and therefore, its temperature).


message:
ESP32 cam and MB code uploaded but nothing in Serial Monitor

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

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

The code works successfully but nothing happens in the serial monitor, what do I do as I've tried almost everything.

body:
## No longer an issue.

**Any fully released version of the 2.X IDE including the original 2.0.0 release should work. If you're having a problem these days it is probably because you've selected the wrong board causing problems as explained below.**

At the time the original answer was given the 2.0-rc9.1 release candidate was current. IDE version 2.0-rc9.3 bundled arduino-cli version 0.27.0-rc.1 which contains [code to make the relevant settings work][1]. So every version form the official 2.0.0 release to current (version 2.1.1 as of this update).

## Original Answer

**In short, use the 1.X series IDE instead of the 2.X series IDE. As of writing, this would be IDE version 1.8.19.**

---

In version 1.8.4 support for a board properties called `.serial.disableDTR` and `.serial.disableRTS` were added.

Certain boards, like the ESP32-CAM combined with the ESP32-CAM-MB require this feature in order for the Serial Monitor to see traffic (actually it's worse than that, which I'll explain below). The current 2.X series IDE (2.0-rc9.1 as of writing), which has a completely different code base, appears not to have re-implemented this feature. Presumably they will eventually.

**When you install the 1.X series IDE, make sure you test the Serial Monitor with the ESP32-CAM selected.** It may be counterintuitive that testing an Arduino UNO as your selected board wouldn't just work, given that you're *only* using the Serial Monitor and not actually compiling or uploading. But it will, no kidding, fail to work as this board's definition does not specify these `.serial.disableDTR` and `.serial.disableRTS` properties that the ESP32-CAM board description does.

In case you're wondering, ESP32 upload tool controls DTR and RTS itself irrespective of these board definition properties that affect the Serial Monitor and Serial Plotter. That's why your uploading works but your Serial Monitor fails under the current IDE 2.0 release candidate.

Without going into detail on what DTR and RTS are supposed to do, and what they can be made to do, etc, typical operating configurations for a serial port are such that when the port is open these signals are going to go active. The ESP32-CAM-MB board design is such that having both active DTR and RTS both active is effectively pushing down both the GPIO0 and rather crucially the EN/RESET buttons. In other words, without this additional fiddling that the 1.X series IDEs (*with* correct board selected) and esptool do, opening the serial port has the effect of holding your ESP32-CAM in reset (or NOT-enabling it if you like). So not only are you not getting any serial traffic, the board is simply not executing any code at all.

---

You have other options also, but each kind of requires an explanation in its own right. But, I can give you hints as to what they are:

It is possible to continue using the 2.0 IDE to do your development and upload but use something else instead of the 2.0 IDE's Serial Monitor. But it will introduce complexity, confusion, and annoyance into your setup. Whatever that "something else" is must allow for the disabling for DTR and RTS. *Note that disabling DTR and RTS is **not** merely turning off flow control; that will not manipulate them and it will ignore their counterpart signals, but it will also leave them in the wrong state.*  One candidate is IDE 1.x's Serial Monitor.  Another is [RealTerm](https://sourceforge.net/projects/realterm/), which will allow you to clear DTR and RTS (in that order) to then work as a serial monitor. In any case you will need to close the serial connection yourself prior to each upload as the 2.0 IDE will be unable to do that on your behalf as it would normally do its own internal monitor.

You can also interrupt the DTR an RTS signals in hardware before the get to the ESP32-CAM board. Having done that, it no longer matters whether any software controls DTR and RTS, but you then need to manually operate GPIO0 and EN/RESET yourself to enter the bootloader. To accomplish that you'll either need to use a mess of jumpers and the ESP32-CAM-MB (or any other 3.3V serial transceiver) not mounted to the ESP32-CAM and construct push button circuits for GPIO0 and EN/RESET.  Alternately you can physically modify the ESP32-CAM-MB in a way that interrupts DTR and RTS from the transceiver but keeps operational buttons. This can be done by desoldering a pair of diodes or cutting the traces on the way to the buttons and headers.

It may also only take a few well placed lines in one of the 2.0 IDE's javascript/typescript to crudely hack in a disabling of DTR and RTS, if you don't care what else it breaks. If I get bored maybe I'll look into that. Doing it properly in response to the correct board properties is a more involved project though.

  [1]: https://github.com/arduino/arduino-cli/blob/0.27.1-rc.1/arduino/cores/packagemanager/loader.go#L527-L561


body:
If you use the command line, you can use this command to open a serial console to the esp32:

```
arduino-cli monitor -p /dev/ttyUSB0 --discovery-timeout 60s --config 'rts=off' --config 'dtr=off' --config 'baudrate=115200'
```

If you use the IDE, see the answer of timemage.


message:
I want a Rotary Encoder to make 10 steps at once, but my code isn't working. What am I doing wrong?

I'm using a rotary encoder on my Arduino Micro, that is supposed to do single steps or ten steps at once, depending on which position a switch is in.

The Rotary: https://www.reichelt.de/drehimpulsegeber-15-impulse-30-rastungen-vertikal-ec11mvbfx-p315144.html?&nbc=1 (on this site are pictures and datasheets as well.)

The Switch:
https://www.reichelt.de/miniatur-kippschalter-ein-aus-ein-3-a-250-v-goobay-10023-p285990.html?&nbc=1

Wiring: (image following later)

>             1--------Pin16 |  Pin A3----Switch
>     Rotary  2--------GND   |  GND-------|
>             3--------PIN17 |

The rotary encoder gives no output, neither the Serial.print nor the gamecontroller. Also there is no output in either switch position.

**EDIT:**
After using arrays and loops like @jsotola teached me, it works nearly the way its supposed to, but sometimes, although the switch is off, it clicks ten times.
The code looks like this shortened **now**

    #include <Arduino.h>
    #include <Joystick.h>
    #include <BasicEncoder.h>
    #include <TimerOne.h>

    int EncoderPins[] = {
      4, 5, 6, 7, 8, 9, 10, 11
    };
    int EncoderCount = 8;

    BasicEncoder encoder4(EncoderPins[6], EncoderPins[7], HIGH, 2);

    void timer_service() {
      encoder4.service();
    }

    #define joyButton16 EncoderPins[6]  // Rotary4
    #define joyButton17 EncoderPins[7]  // Rotary4
    #define joyButton18 21              // HDG_SWITCH := Switch to select between single and 10 steps

    //Joystick(Joystick HID ID, Joystick Type, Button Count, Hat Switch Count, Include X, Include Y, Include Z, Include Rx, Include Ry, Include Rz, Include Rudder, Include Throttle, Include Accelerator, Include Brake, Include Steering)
    Joystick_ Joystick(0x15, JOYSTICK_TYPE_JOYSTICK, 19, 0,
                       true /*X*/, false/*Y*/, false/*X*/,
                       false/*Rx*/, false/*Ry*/, false/*Rz*/,
                       false/*Rudder*/, false/*Throttle*/, false/*Acc*/,
                       false/*Brake*/, false/*Steer*/);

    const bool initAutoSendState = true; // code is sends continuously and doesnt wait for polling

    int EncoderState[] = {
      0, 0, 0, 0
    };

    void setup() {
      for (int q  = 0; q < EncoderCount; q++)
      {
        pinMode(EncoderPins[q], INPUT_PULLUP);
      }

      Serial.begin(9600);
      Joystick.begin();

      Timer1.initialize(100);
      Timer1.attachInterrupt(timer_service);
    }

    void loop() {
      GET_CHANGE();

      int CurrentButton18State = !digitalRead(joyButton18);
      switch(CurrentButton18State){
        case 0:
          switch(EncoderState[3]){
            case  1: clickButton(15); Serial.println(EncoderState[3]); break;
            case -1: clickButton(16); Serial.println(EncoderState[3]); break;
            } break;
        case 1:
          switch(EncoderState[3]){
            case  1: clickTen(15); break;
            case -1: clickTen(16); break;
            } break;
      }
    }

    void clickButton(int pin) {
      Joystick.setButton(pin, 1);
      delay(2);
      Joystick.setButton(pin, 0);
    }

    void clickTen(int pin) {
      for (int ii = 0; ii < 10; ii++)
      {
        clickButton(pin);
        Serial.println("step: "); Serial.println(ii);
        delay(10);
      }
    }
    void GET_CHANGE()
    {
      for(int E = 0; E<4; E++)
      switch(E) {
        case 3: EncoderState[E] = encoder4.get_change(); break;
      }
    }

body:
This is not an answer to the question, but a tip about simplifying your code.

This is a snippet of your code.

```lang-cpp

void loop() {

// some more code here

  int encoder1State = encoder1.get_change();
  switch (encoder1State) {
    case 1:
      Joystick.setButton(8, 1);
      delay(25);
      Joystick.setButton(8, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(9, 1);
      delay(25);
      Joystick.setButton(9, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int encoder2State = encoder2.get_change();
  switch (encoder2State) {
    case 1:
      Joystick.setButton(10, 1);
      delay(25);
      Joystick.setButton(10, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(11, 1);
      delay(25);
      Joystick.setButton(11, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int encoder3State = encoder3.get_change();
  switch (encoder3State) {
    case 1:
      Joystick.setButton(12, 1);
      delay(25);
      Joystick.setButton(12, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(13, 1);
      delay(25);
      Joystick.setButton(13, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int currentButton20State = !digitalRead(joyButton20);
  int encoder4State = encoder4.get_change();
  switch (currentButton20State) {
    case 0:
      switch (encoder4State) {
        case 1:
          Joystick.setButton(14, 1);
          delay(25);
          Joystick.setButton(14, 0);
          Serial.println(encoder4State);
          break;
        case -1:
          Joystick.setButton(15, 1);
          delay(25);
          Joystick.setButton(15, 0);
          Serial.println(encoder4State);
          break;
        case 0:
          break;
      } break;
    case 1:
      switch (encoder4State) {

        case 1:
          TenRotaryStepsUP();
          break;
        case -1:
          TenRotaryStepsDOWN();
          break;
        case 0:
          break;
      } break;
  }

  //GetParamFromFS2020();
  //ShowFlightParam();

  delay(10);

}

void TenRotaryStepsUP()
{
  for (int i = 0; i < 10; i++)
  {
    Joystick.setButton(14, 1);
    delay(25);  //for testing set on higher number e.g. 500
    Joystick.setButton(14, 0);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}

void TenRotaryStepsDOWN()
{
  for (int i = 0; i < 10; i++)
  {
    Joystick.setButton(15, 1);
    delay(25);
    Joystick.setButton(15, 0);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}
```
It can be simplified by putting repeated code into functions.

```lang-cpp

void loop() {

// some more code here

  int encoder1State = encoder1.get_change();
//Serial.println(encoder1State);
  switch (encoder1State) {
    case 1:
      clickButton(8);
      break;
    case -1:
      clickButton(9);
      break;
    case 0:
      break;
  }

  int encoder2State = encoder2.get_change();
  switch (encoder2State) {
    case 1:
      clickButton(10);
      break;
    case -1:
      clickButton(11);
      break;
    case 0:
      break;
  }

  int encoder3State = encoder3.get_change();
  switch (encoder3State) {
    case 1:
      clickButton(12);
      break;
    case -1:
      clickButton(13);
      break;
    case 0:
      break;
  }

  int currentButton20State = !digitalRead(joyButton20);

  int encoder4State = encoder4.get_change();
  switch (currentButton20State) {

    case 0:
      switch (encoder4State) {
        case 1:
          clickButton(14);
          break;
        case -1:
          clickButton(15);
          break;
        case 0:
          break;
      } break;

    case 1:
      switch (encoder4State) {
        case 1:
          clickTen(14);
          break;
        case -1:
          clickTen(15);
          break;
        case 0:
          break;
      } break;
  }

  //GetParamFromFS2020();
  //ShowFlightParam();

  delay(10);

}

void clickButton(int pin) {
  Joystick.setButton(pin, 1);
  delay(25);
  Joystick.setButton(pin, 0);
}

void clickTen(int pin) {
  for (int i = 0; i < 10; i++)
  {
    clickButton(pin);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}
```

You can even format your code like this.

```lang-cpp
switch (encoder3State) {
  case  1:      clickButton(12);      break;
  case -1:      clickButton(13);      break;
  case  0:                            break;
}
```

EDIT

Also refer to the following about the use of arrays as variables, to specify pins, instead of individual variable names

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Arrays

eg. use `lastButtonState[1]` instead of `lastButton1State` and `joyButton[1]` instead of `joyButton1`

that will allow the use of `for` loops to repeat the same action for multiple pins

```lang-cpp
int currentButton2State = !digitalRead(joyButton2);
if (currentButton2State != lastButton2State) {
  Joystick.setButton(1, currentButton2State);
  if (currentButton2State == 1) {
    delay(1);
    Joystick.setButton(1, 0);
  }
  lastButton2State = currentButton2State;
}
```

becomes

```lang-cpp
int currentButtonState[pin] = !digitalRead(joyButton[pin]);
if (currentButtonState[pin] != lastButtonState[pin]) {
  Joystick.setButton(pin-1, currentButtonState[pin]);
  if (currentButtonState[pin] == 1) {
    delay(1);
    Joystick.setButton(pin-1, 0);
  }
  lastButtonState[pin] = currentButtonState[pin];
}
```


message:
The RF 433MHz receiver code is working only when I reset the Arduino

I'm working on RF modules using Arduino but I observed the `if` statement is only running once and I need to reset the receiver every time to make it work with real-time changes in the transmitter.

I connected the 16X2 LCD display for displaying the data.
If I start the transmitter and started sending data as "1", it's showing "Bye" but when I change the transmitter data to "0", then also it is showing "Bye" only.

I changed a code a little bit but I felt it is the problem with the previous data stored in `buf` variable.

I'm expecting the LCD should display "Hi" when I changed the transmitting data to "0" from "1" which is not happening only "Bye" is displaying every time.

Here is the Arduino receiver code:

```c++
#include <RH_ASK.h>
#include <SPI.h>
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
RH_ASK rf_driver;
char message[2];

void setup()
{
    rf_driver.init();
    Serial.begin(9600);
    lcd.begin(16,2);
}

void loop()
{
    uint8_t buf[2];
    uint8_t buflen = sizeof(buf);

    buf[1] = '\0';

    if (!rf_driver.recv(buf, &buflen))
    {
        if (strcmp((char*)buf, "0") == 0) {
            Serial.println("Hi");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Hi");
            }

            lcd.display();
        }
        else if (strcmp((char*)buf, "1") == 0) {
            Serial.println("Bye");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Bye");
                lcd.display();
            }
        }
    }
    message[0] = (char*)buf[0];
}
```

Here is the transmitter code:

```
#include <RH_ASK.h>
#include <SPI.h>
RH_ASK rf_driver;

void setup()
{
    rf_driver.init();
    Serial.begin(9600);
}

void loop()
{
    const char *msg = "1";
    rf_driver.send((uint8_t *)msg, strlen(msg));
    rf_driver.waitPacketSent();
    delay(1000);
}
```

The Serial monitor output is as follows:
[![enter image description here][1]][1]

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

body:
I pointed this out in a comment thinking the question would probably get closed when this was understood to be a typo, but I guess it's not a typo.

> `char message[2];` ... `if (strcmp(message[0],` You should be getting
> a warning for this. If not, turn your warning level up in the
> preferences.

If you increase the warning level you should see something that at least hints at some of what I'm saying below.

Cutting your code down to a part relevant to the description of the problem:

```c++
char message[2];
// ...
uint8_t buf[2];
// ...
if (strcmp(message[0], (char*)buf[0]) != 0) {
```

`strcmp()` expects a *pointer* to a character for both its first and second arguments. However, `message[0]` is of type `char` and `buf[2]` is of type `uint8_t` (ultimately an `unsigned char`). The individual characters being used are being interpreted as pointer values (as in memory addresses) which `strcmp()` expects to refer to the first characters of strings.  In other words, it's going to some pair of memory addresses between 0 and 255 and trying to interpret whatever it finds at those locations as strings and compare them. The combination of what you're doing being undefined and not having a strong expectation of what to find at these memory addresses, it's not really surprising (to me anyway) how your comparisons are evaluating.

A minimal change that should bring the `strcmp` closer to making sense is:
```c++
if (strcmp(message, (char*)buf) != 0) {
```

`message` and `buf` here will end up evaluating to the actual locations of their strings.
 You were already doing half of this line correctly in your other use of buf in `if (strcmp((char*)buf, "0") == 0)`; note no `[0]` usage there.

---

In the above I'm addressing this directly and taking it for granted that you have some reason to want to use string that have one (non-null) character in them, that you intended to expand this code to longer messages somehow. Otherwise it makes more sense to just dispense with strings altogether and have `rh_driver.recv` read directly into a single character type and then use the equality comparison `==` rather than `strcmp()`.

The sections of code would look more like:

```c++
char message; // now individual char
// ...
uint8_t buf;  // now individual char
// ...
if (!rf_driver.recv(&buf, sizeof buf)) { //sizeof buf is 1
    if (buf == '0') { // now simple application of ==
        Serial.println("Hi");
        if (message != buf) {  // now simple application of !=
            lcd.print("Hi");
        }
// ...
message = buf; // no longer using [0] because no longer an array
```


message:
How to wire an ESP32-S2 Dev KitM-1 for power?

I'm putting an [Espressif ESP32-S2 Dev KitM-1][1] into a project box. The box will have 12VDC power and a 5V buck converter for the Dev Kit.

Do I need to use the USB port to power the Dev Kit or can I directly wire 5VDC to the 5V pin (and ground, of course) to power it?

  [1]: https://www.mouser.com/ProductDetail/Espressif-Systems/ESP32-S2-DevKitM-1?qs=DPoM0jnrROXzO8seOHN%2BOQ==

body:
The [official documentation][1] has

>Power Supply Options
>
>There are three mutually exclusive ways to provide power to the board:
>*   Micro-USB Port, default power supply
>*   5V and GND pin headers
>*   3V3 and GND pin headers

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-devkitm-1-v1.html


message:
Duplicate Arduino SD Library

I need to have two independent arduino sd libraries so that I can modify one and have the other one intact. I struggle to do so.
Does anyone know if this is even possible?
What should be the path to properly do so?

I tried a lot of things but I always end up in a spot where I dont know what code is working and what is not. Last try I duplicated all the files and renambed all the functions to whatever"2" but couldn't make it work

body:
If you want to use two SD card than instead of copying the whole library just create another instance of the class like

```
SDClass SD2;
```

Now you can call SD2.begin(CS_PIN_2) or any other function of the sd library.


message:
ESP8266 SDCard initialization bug

I have an ESP8266 wich is connected to an SDCard module, an SHT21 sensor and an BMP280. The idea is that I want to log data from the sensors to the SD Card, but if I initialize the SD Card with SD.begin(chipSelect), all the data from sensors become NaN or random values. If I initialize it, it is logging only NaN on the sd card, so the card is working, and if I dont initialize it, I get good and normal values into the serial monitor.
The Card Module is connected to D5,D6,D7,D8, and the two sensors are connected to D1 and D2, and all powered from 3v.
Any idea?
This is the code:

    #include <Wire.h>
    #include <SPI.h>
    #include <Sodaq_SHT2x.h>
    #include <Adafruit_BMP280.h>
    Adafruit_BMP280 bmp;
    #include <SD.h>
    File myFile;
    float pressure;
    float temperature;
    float altimeter;
    float humidity;
    float dewPoint;
    float temperature2;
    float humidity2;
    float dewPoint2;
    int chipSelect = 5;
    float QNH = 1015;
    const int BMP_address = 0x76;

    int ledB = D4;
    int ledG = D3;
    int ledR = D0;

    void setup()
    {

      Serial.println("initialization done.");
      Wire.begin();
      Serial.begin(9600);
      bmp.begin(BMP_address);
      Serial.println("PTHBox Logger");
        //Checking if SDCard is alive
        if (SD.begin(5)){
        Serial.println("SD card is alive");
      }else{
        Serial.println("SD card is ded");
        while(1); //halt program
      }

    //Checking the logfiles from the SDCard and deleting them
      if (SD.exists("/csv.txt"))
      {
        Serial.println("Removing csv.txt");
        SD.remove("/csv.txt");
        Serial.println("csv.txt is fresh and ready to log");
      }

    //  Writing headers to csv.txt
       myFile = SD.open("/csv.txt", FILE_WRITE);
       if (myFile) // it opened OK
        {
        Serial.println("Writing headers to csv.txt");
        myFile.println("Altitude,Pressure,Temperature,Humidity,DewPoint");
        myFile.close();
        Serial.println("Headers written");
        }else {
        Serial.println("Error opening csv.txt");
      }
    //  Setting pinModes for the LED
      pinMode(D0, OUTPUT);
      pinMode(D3, OUTPUT);
      pinMode(D4, OUTPUT);
      //Set PWM frequency 500, default is 1000
      //Set range 0~100, default is 0~1023
      analogWriteFreq(500);
      analogWriteRange(100);

    }

    void loop()
    {
      // Testing the led
      analogWrite(ledR, 100);
      analogWrite(ledG, 0);
      analogWrite(ledB, 60);

      Serial.print("Humidity(%RH): ");
      Serial.print(SHT2x.GetHumidity());
      Serial.print("     Temperature(C): ");
      Serial.print(SHT2x.GetTemperature());
      Serial.print("     Dewpoint(C): ");
      Serial.print(SHT2x.GetDewPoint());
      pressure = bmp.readPressure()/100;  //and conv Pa to hPa
      Serial.print("     BMP PRESSURE");
      Serial.print(pressure);
      Serial.print("     BMP ALT");
      Serial.println(bmp.readAltitude (QNH));
      Serial.print("     BMP TEMP");
      Serial.print(bmp.readTemperature());

    //  Assigning values to variables

     pressure = bmp.readPressure()/100;  //and conv Pa to hPa
     temperature = (bmp.readTemperature()); //temperature from bmp
     altimeter = bmp.readAltitude (QNH); //QNH is local sea lev pressure
     humidity = (SHT2x.GetHumidity());
     dewPoint = (SHT2x.GetDewPoint());
     temperature2 = (SHT2x.GetTemperature());

    //  Writing the values to SDCARD
    myFile = SD.open("/csv.txt", FILE_WRITE);
        // if the file opened okay, write to it:
        if (myFile)
        {
          Serial.println("Writing to csv.txt");
          myFile.print(altimeter);
          myFile.print(pressure);
          myFile.print(temperature);
          myFile.print(humidity);
          myFile.println(dewPoint);
          myFile.close();
        }
        else
        {
          Serial.println("error opening csv.txt");
        }
      delay(1000);
    }

body:
You're calling

    if (SD.begin(5)){

GPIO5 is not necessarily `D5`. Use the `D5` constant; it will evaluate to whatever GPIO number `D5` actually is. So,

    if (SD.begin(D5)){

Although you don't appear to be using the variable, you also have:

    int chipSelect = 5;

which should be

    int chipSelect = D5;

The difference between GPIO numbers and pin labels leads to problems for a lot of people. `GPIOx` is specific to the ESP8266 - it corresponds to a pin number and function on the actual chip; `Dx` is specific to the particular breakout board and is not always the same GPIO number (or the same between breakout boards).


message:
Code explanation when pH sensor is connected to Arduino

I have to measure the pH value for some experiment. I have checked various codes and all include the average of pH values.

    #define SensorPin 0          // the pH meter Analog output is connected with the Arduino’s Analog
    unsigned long int avgValue;  //Store the average value of the sensor feedback
    float b;
    int buf[10],temp;

    void setup()
    {
      Serial.begin(9600);
      Serial.println("Ready");    //Test the serial monitor
    }
    void loop()
    {
      for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
      {
        buf[i]=analogRead(SensorPin);
        delay(10);
      }
      for(int i=0;i<9;i++)        //sort the analog from small to large
      {
        for(int j=i+1;j<10;j++)
        {
          if(buf[i]>buf[j])
          {
            temp=buf[i];
            buf[i]=buf[j];
            buf[j]=temp;
          }
        }
      }
      avgValue=0;
      for(int i=2;i<8;i++)                      //take the average value of 6 center sample
      avgValue+=buf[i];
      float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
      phValue=3.5*phValue;                      //convert the millivolt into pH value
      Serial.print("pH:");
      Serial.println(phValue,2);
      delay(5000);
    }

Kindly explain the meaning of these two lines. Why take constant values as in bold (**5/1024**/6) and (**3.5***pH)? Can I use some other value instead of these?

    float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
      phValue=3.5*phValue;                      //convert the millivolt into pH value

body:
This is a fine example why magic numbers are bad. Always use symbolic constants.

**Concerning the first line:**

1. The "5.0" is the reference voltage of the ADC, apparently 5.0 volts.

1. The "1024" is the width of the range of values returned by the ADC.

1. The "6" is the number of samples summed up in the two lines before.

The ADC returns values in the range from 0 to 1023, giving you 1024 different values. If it measures 0% of its references voltage, it returns 0. If it measures 100% of its references voltage, it returns 1023. Actually the value "1024" should be "1023", but considering the accuracy it does not really matter.

By dividing the measured value by 1024, a single ADC value ranges from 0.0 (0%) to 0.999 (nearly 100%).

Multiplication by "5.0" gives the voltage, if we suppose that the reference voltage is 5.0 volts.

As 6 samples are summed up, another division by 6 is necessary to obtain the average.

In contrary to the comment the result of the first line is the measured and averaged voltage in volts, not in millivolts.

If the author had used smybolic constants, no comment would have been necessary and thus could not become erroneous.

**Concerning the second line:**

Apparently this is the factor of the sensor between voltage and pH value. A voltage of 0 volts means a pH value of 0, and a voltage of 4 volts means a pH value of 14. _Note: pH can only range from 0 to 14._

Since you did not post a link to the data sheet of the used sensor, we cannot check this. But you can.

**A first approach with symbolic constants:**

```c++
static const int FIRST_INDEX_FOR_AVERAGE = 2;
static const int NUMBER_OF_VALUES_TO_AVERAGE = 6;

static const float FULL_SCALE_IN_VOLTS = 5.0;
static const int ADC_MAXIMUM = 1023; // was 1024

static const float PH_PER_VOLT = 3.5; // or even better 14.0 / 4.0

// ...

avgValue = 0;
for (int i = FIRST_INDEX_FOR_AVERAGE;
     i < FIRST_INDEX_FOR_AVERAGE + NUMBER_OF_VALUES_TO_AVERAGE;
     i++)
{
    avgValue += buf[i];
}

float phValue = avgValue * FULL_SCALE_IN_VOLTS / ADC_MAXIMUM / NUMBER_OF_VALUES_TO_AVERAGE;

phValue = phValue * PH_PER_VOLT;
```

There is no need to cast `avgValue` to `float` since `FULL_SCALE_IN_VOLTS` is `float` and so the calculations are done in floating point.


message:
Define a custom baudrate in Serial Monitor

Is there a way to define a different baud rate from the ones we are shown in the dropdown menu of the Serial Monitor? I want to define a custom value.

body:
There is no easy way to do so. The list of available baud rates [is
hard-coded in the Java source][src] of the Arduino IDE. To add a custom
rate, you would have to modify the source code and [rebuild the
IDE][build].

I suggest you consider using a [terminal emulator][term] instead of the
serial monitor. On Linux, I like [picocom][]: not a real terminal
emulator, but a minimal program that “connects” the terminal emulator
you are already using (gnome-terminal, rxvt...) to the serial port. It
supports [custom baud rates][custom], which it rounds to the nearest
rate the hardware can provide. Picocom works on Mac too.

For Windows, [Adafruit recommends][adafruit] Putty or X-CTU. [Sparkfun
recommends][sparkfun] quite a few options for Windows, Mac and Linux.

[src]: https://github.com/arduino/Arduino/blob/1.8.19/app/src/processing/app/AbstractMonitor.java#L24
[build]: https://github.com/arduino/Arduino/wiki/Building-Arduino
[term]: https://en.wikipedia.org/wiki/Terminal_emulator
[picocom]: https://github.com/npat-efault/picocom
[custom]: https://github.com/npat-efault/picocom#some-notes-on-custom-baudrate-support
[adafruit]: https://learn.adafruit.com/windows-tools-for-the-electrical-engineer/serial-terminal
[sparkfun]: https://learn.sparkfun.com/tutorials/terminal-basics/all


body:
If you are growing out of the Arduino IDE consider swaping to PlatformIO, baud-rate is just one of the many extra things you will get a chance to tweek.
If you are on X64 architecture, you can although use eclipse, but I find platformIO bit better for Arduino.
Arduino IDE is an OK starter, but to grow you will need to move further.

To add to Edgar Bonets answer, there are many other serial terminals including but not limited to: pyserial (multiplatform),screen (UNIXes), even good old Putty (runs on nearly everything that can blink I believe even on comodore)...


message:
Not enough memory error using OneSheeld.h

I'm a dairy farmer and I'm new to playing around with Arduino's. I created a code to send me SMS's when my equipment stops working as it should, but I run into a "Not enough memory" error. Here's my code:

    #include <OneSheeld.h>
    int IPFeed = 13;
    int IPScraper = 12;
    int IPPump = 11;
    int XVal = 0;
    int TFeedCharge = 0;
    int TFeedRun = 0;
    int TScraper = 0;
    int TPump = 0;
    int TLFeedCharge = 60;
    int TLFeedRun = 60;
    int TLManure = 2;
    int TInc = 60000;

    void setup() {
      pinMode(IPFeed, INPUT);
      pinMode(IPScraper, INPUT);
      pinMode(IPPump, INPUT);
      OneSheeld.begin();
    }

    void loop() {
      XVal = digitalRead(IPFeed);
      if (XVal == HIGH) {
        TFeedRun = 0;
        TFeedCharge = TFeedCharge +1;
        if (TFeedCharge == TLFeedCharge) {
          delay(150);
          SMS.send("613xxxxxx6","ProFeed 2020 is stoped at the charging station.");
          delay(150);
          SMS.send("613xxxxxx9","ProFeed 2020 is stoped at the charging station.");
          TFeedCharge = 0;
        }
      }
      else {
        TFeedCharge = 0;
        TFeedRun = TFeedRun +1;
        if (TFeedRun == TLFeedRun) {
          delay(150);
          SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");
          delay(150);
          SMS.send("613xxxxxx9","ProFeed 2020 is stopped away from the charging station.");
          TFeedRun = 0;
        }
      }

      XVal = digitalRead(IPScraper);
      if (XVal == HIGH) {
        TScraper = TScraper +1;
        if (TScraper == TLManure) {
          delay(150);
          SMS.send("613xxxxxx6","The manure scraper has stopped working.");
          delay(150);
          SMS.send("613xxxxxx9","The manure scraper has stopped working.");
          TScraper = 0;
        }
      }

      XVal = digitalRead(IPPump);
      if (XVal == HIGH) {
        TPump = TPump +1;
        if (TPump == TLManure) {
          delay(150);
          SMS.send("613xxxxxx6","The manure pump has stopped working.");
          delay(150);
          SMS.send("613xxxxxx9","The manure pump has stopped working.");
          TPump = 0;
        }
      }

      delay(TInc);
    }

Here is the error message:

    Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P"

    Sketch uses 24812 bytes (80%) of program storage space. Maximum is 30720 bytes.

    Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.

    Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint.

    data section exceeds available space in board

    Error compiling for board Arduino Nano.

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

Any ideas on how to fix this issue?

body:
Including the whole library, which is what you are doing, does not work on small boards like yours. Instead you have to only use the parts of the library that you need.

Fortunately the OneSheeld library provides a simple way of doing that, through the use of a couple of `#define` directives *before* you include the library.

Since you are only using the SMS functionality you only need to turn on that functionality - so start your sketch with:

```c++
#define CUSTOM_SETTINGS
#define INCLUDE_SMS_SHIELD
```

before the `#include <OneSheeld.h>` line and it will compile.


body:
Your problem is caused by using too much RAM, not program memory, as the error message says:

`
Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.
`

The library you are using is likely occupying a large amount of RAM. However, currently your alert messages are stored in RAM as well, causing the limit to be exceeded.
To make the compiler store the strings in program memory (flash) instead of RAM, you can wrap each string in an `F()` macro. For example,

```SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");```

becomes

```SMS.send("613xxxxxx6",F("ProFeed 2020 is stopped away from the charging station."));```

(You can also wrap the phone number to save even more RAM, but as the limit has only been exceeded by 39 bytes/characters it is unnecessary.)

Majenko's answer might potentially work too as the excluded parts of the library might happen to save just enough RAM, but the `F()` technique is still handy.


message:
Esp8266-01 and Arduino

I recently bought an ESP8266 (ESP-01s). When I first connected it to Arduino,AT commands showed. Then when I uploaded other code,the commands stopped showing. I flashed it using many flashing tools and firmwares and the flashing was successful but AT commands still not showing. ESP is not responding to any code I execute in Arduino.

body:
This is a common problem with newcommers to the ESP8266. It ships with AT commands working and as soon as you try putting your own code on it the AT commands stop working.

Well, of course they do.

The AT commands aren't something the ESP8266 does. It's something the software installed on the ESP8266 does, and you just deleted that software and put your own software on.

You can *either* have AT commands (by installing the correct AT firmware for your board) *or* run your own software on it - not both (unless, of course, you write your software in such a way that it responds to AT commands, but that's a completely separate thing...)


message:
Mouse.move: how do I move the mouse to the center of a screen?

I have a program operating in full screen mode. I would like to move the mouse to the center of the screen. Is this something I can do with the functionality of Mouse.h?
https://www.arduino.cc/reference/en/language/functions/usb/mouse/

Mouse.move moves fixed increments. maybe I should change the mouse start location in the computer program.

my issue, is that the "circuit playground" is the primary interface, using the accelerator for position. Once the computer is running the software, the Arduino has to be centered to work properly.

alternatively, is there a command I can send that could center the mouse?

body:
There are two ways of working with HID mice - absolute and relative. The Arduino `Mouse` library only works in relative mode, but you want absolute.

There's another library **[https://github.com/NicoHood/HID](https://github.com/NicoHood/HID)** which does do considerably more than the normal Arduino HID libraries - including "Absolute Mouse".


message:
Arduino + ESP8266 to send MQTT messages

I'm wondering if an Arduino Uno (or any other 328 family) that connects via Serial to an ESP8266 can send MQTT messages, rather than AT commands.

body:
*I didn't use MQTT yet so I didn't try any of the following options. I only know they exist.*

1) AT firmware version 2 has a set of [AT commands for MQTT][1]. But development of [AT 2 for esp8266][2] was ended with version 2.2. It requires an esp8266 with a 4 MB flash.

2) a very old esp8266 firmware called [ESPLink][3] has support to register to a MQTT topic and then use it in Arduino with [the EL-link library][4]. (The main goal of the ESPLink firmware was OTA update for Uno)

3) PubSubClient library is a very popular Arduino library for MQTT. It works over any standard Arduino networking library. For esp8266 there are multiple options for a firmware+library combination. I can only recommend my WiFiEspAT library (all others have too many problems). WiFiEspAT works with AT firmware in esp8266. Best is to use [AT 1.7.5][5] or the 'fake' AT firmware [ESP_ATMod][6], which is an Arduino sketch.

The third option will take much more flash and RAM than the first two, but it is a standard and portable way. You can port it to other networking library or other MCU type.

EDIT: Another option is to write a sketch with MQTT for the esp8266 directly and communicate the data with Uno or not use the Uno at all.

  [1]: https://docs.espressif.com/projects/esp-at/en/latest/esp32/AT_Command_Set/MQTT_AT_Commands.html
  [2]: https://github.com/JAndrassy/WiFiEspAT#at-2-1
  [3]: https://github.com/jeelabs/esp-link
  [4]: https://github.com/jeelabs/el-client
  [5]: https://github.com/JAndrassy/WiFiEspAT#at-17-1
  [6]: https://github.com/JiriBilek/ESP_ATMod


message:
Why does keyboard.h add 136 to each key?

I want to create a custom keyboard mapping in the [official arduino keyboard library](https://www.arduino.cc/reference/en/language/functions/usb/keyboard/)

Why do the key definitions add 136 to each number?

[See Keyboard_es_ES.h on github](https://github.com/arduino-libraries/Keyboard/blob/master/src/Keyboard_es_ES.h#L37-L42
)

```
#define KEY_MASCULINE_ORDINAL    (136+0x35)
#define KEY_INVERTED_EXCLAMATION (136+0x2e)
#define KEY_GRAVE                (136+0x2f)
#define KEY_N_TILDE              (136+0x33)
#define KEY_ACUTE                (136+0x34)
#define KEY_C_CEDILLA            (136+0x31)
```

Looking at the [ascii table](https://www.asciitable.com/), I see nothing special about value 136

body:
It could be argued that this is an implementation detail of the library,
that does not need to be documented. ;-) Anyway, here is the reason...

The keyboard library uses a custom encoding scheme for representing
_both_ characters and keys. The public methods `press()`, `release()`,
`write()`, `print()` and `println()` interpret the user-provided data
according to this scheme. With this encoding, the interpretation of a
byte depends on which of these three ranges it belongs to:

* Bytes in the range [0, 127] are understood to be ASCII
  characters. This is what enables you to write things like
  `Keyboard.println("Hello!");`. The library uses a keyboard layout
  array to map those characters to key scan codes¹, possibly modified by
  Shift or AltGr. You provide a pointer to this array as an argument to
  `begin()`.

* Bytes in the range [128, 135] are interpreted as modifier keys,
  such as `KEY_LEFT_CTRL`, `KEY_RIGHT_SHIFT`, etc. Note that these keys
  do not have proper scan codes, as their state is transmitted to the
  host as a bit map (one byte for the eight keys) rather than as codes
  added to a list.

* Bytes in the range [136, 255] are interpreted as raw scan codes
  in the range [0, 119], shifted by 136. This is what lets you
  actuate arbitrary keys such as `KEY_PRINT_SCREEN` or `KEY_LEFT_ARROW`.
  All scan codes of a standard full-size PC keyboard (ANSI 104 or
  ISO 105) lie in the range [4, 101]: you can access all of
  them, and even some more like `KEY_F24`.

Regarding the file Keyboard\_es\_ES.h: the codes in there are for keys
that match ASCII characters in the US layout but not in the Spanish
layout. The purpose is to ensure that every key of a ISO 105
keyboard can be actuated using either an ASCII character (like
`Keyboard.press('a');`) or a `KEY_*` macro.

¹ The USB standard calls them “usage codes”, but the old term “scan
codes” seems more prevalent.


message:
One LED in 4x4 matrix does not turn on

I'm an art student and absolute beginner to electronics/code  -  my broader goal is to learn how to control individual LEDs when there are many of them (like 64 or more even, so am learning about shift registers, multiplexing etc. also).

I have been working with a [4x4 matrix example][1] by Jon Fox. I have breadboarded it as below and checked it multiple times.

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

For the most part it's successful; the code runs and I get the LED animations in his code. I am also able to anticipate which parts of the code refer to which LEDs when I test by commenting out parts of the code - for example `r1c1()` refers to the top row, right-most LED.

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

However, the top row, second from the left LED does not turn on.

I have tested the individual LEDs before starting, tested the connections of the wires in case they don't make good connection in the breadboard, and tried adding 330 Ω resistors to the rows (instead of the orange connection wire in the image), and tried with 1 kΩ resistors instead of 220 Ω. The reason I tried those values was that I have been successful when I've used another set up I have, image below.

[![enter image description here][4]][4]

The blue and the white LEDs draw similar voltage so as far as I understand this wouldn't affect anything. The code runs great on this also.

I understand I could still be making some human error, especially as I've been going crazy with this. However, because I really want to understand the factors involved in controlling LEDs, I'd love to know if at all there are other variables at play.

For one, I was looking into 'floating inputs' hence tried adding the other set of resistors, and tried colour LEDs (more bulbs were either off or dim) as well as 3 mm white LEDs (same result as 5mm). The most difficult thing in this process is wondering what I don't know, so if anyone can direct me towards things I should consider for my purpose, or help me solve my current problem, I'd be really grateful.

  [1]: https://github.com/FoxJon/Arduino4x4LEDMatrix
  [2]: https://i.stack.imgur.com/Did77.png
  [3]: https://i.stack.imgur.com/8PqpU.jpg
  [4]: https://i.stack.imgur.com/ZoUkU.jpg

body:
It is very difficult to be certain.  You state that the second from the left LED in to top row is not turning on as expected.  In the bread-board diagram this LED is plugged into holes D7 and D8.  However, in the image it appears this LED is plugged into holes D8 and E8.

The exact letter/number may not matter if you are not following your bread-board diagram precisely.  However all pins in a row (i.e. A8, B8, C8, ... , E8) are shorted together.  So plugging in an LED into holes D8 and E8 would prevent it from lighting up.

Also, you have added resistors to your matrix which are not in the bread-board diagram.  The column resistors appear correct but the row resistors are questionable.  In practice, if you are going to light only 1 LED in a column at a time, then you might get by with only column resistors.  For such a configuration (only column resistors) you may see the LEDs dim if you light more than 1 per column.  If you do want to light more then one LED per column, the trick is to let the software switch LEDs on and off such that there is only one lit per column at a time. But fast enough so that a human eye can not see it.  So a bit faster than 100ms.