message:
Stuck with bad sketch

How can I get my programmer board/windows computer to recognize my board again. I am using the esp32 cam and have put two boards in a state where I am unable to flash them anymore. here is the error:

    serial.serialutil.SerialException: could not open port 'COM5'WindowsError(2,'The system cannot find the file specified.')Failed to execute script esptoolthe selected serial port Failed to execute script esptool

I tried reinstalling the drivers and understand that the com port is a separate chip
https://gist.github.com/wybiral/2a96c1d1605af7efa11b690586c4b13e

Here is the sketch I used. I uploaded it using the dev module board setting as well as with 80mhz and 112500 speed. I uploaded with 3v and then provided 5v to the board to run the sketch. The sketch runs but prints out gibberish.

Edit:

Here is a schematic of the board
https://github.com/SeeedDocument/forum_doc/raw/master/reg/ESP32_CAM_V1.6.pdf

body:
This very much looks like the Serial-over-USB-Driver has chosen another port than COM5 on reconnecting the board. Assuming you are using the Arduino IDE, check whether COM5 still shows up in the Board -> Port menu -- or, in other words, go there and select the port that is listed there *while the board is plugged in*.

Usually, I'd expect this port to be COM3 on Windows, but that may change when you...

* physically disconnect and reconnect the board too fast (i.e. the driver has not yet shut down the old COM port when a "new device on USB!" event comes in)
* still have the Serial Monitor open when disconnecting and reconnecting (because the driver cannot remove the virtual COM port device while the Serial Monitor has it opened, in which case the driver creates another virtual COM port device on a different number)
* disconnect and reconnect while the esptool process is still working (same reason as above).

It also might help to enable verbose output for compiling and uploading (see preferences dialog in Arduino IDE).


sender: user

message:
How to wire a hall effect sensor to arduino?

it's a [UGN3503][1] hall effect sensor, in some schematics they used a 100uf capacitors and data connected to analog pin and in some a pull up resistor and data connected to digital pin.

as someone new to both electronics and arduino i'm a bit confused on how to wire the sensor to the arduino.

what i want is just simply read the data from sensor and if the number is above or under defined value do something.

do i need a pull up resistor and/or capacitor?

what's the right and standard way to wire a UGN3503 to arduino?

  [1]: http://www.bristolwatch.com/hall_effect/ugn3503.pdf

sender: assistant

body:
The UGN3503 that you use gives out a analog voltage that changes when there's a magnetic field present. So this sensor needs to be connected to an analog pin.

If there is no field present the voltage is around 2.5Volt. If the south pole of a magnetic field is present the voltage will be higher that 2.5V. With a north pole the voltage will be lower that this 2.5Volt. The amount of higher/lower voltage is based on the strength of the field.

A capacitor near the sensor could help reduce, so called, noise. Though 100µF is too high. I think you mean 100nF (0.1µF).

The pull-up is for other types of hall-effect sensors. Some of these sensors just give a HIGH of LOW output, based on whether a magnetic field is present. Those you connect to a normal input pin.


message:
Combining code for multiple sensors in one program (Arduino)

I need to operate 2 different sensors (gas and DHT11) simultaneously. I have managed to run each one of them separately and I don't know how to manipulate the code so they could work together.

Here are the sketches:

Gas sensor MQ2 code :

    int redLed = 12;
    int greenLed = 11;
    int buzzer = 10;
    int smokeA0 = A5;
    // threshold value
    int sensorThres = 400;

    void setup() {
      pinMode(redLed, OUTPUT);
      pinMode(greenLed, OUTPUT);
      pinMode(buzzer, OUTPUT);
      pinMode(smokeA0, INPUT);
      Serial.begin(9600);
    }

    void loop() {
      int analogSensor = analogRead(smokeA0);

      Serial.print("Concentration: ppm ");
      Serial.println(analogSensor);
      // Checks if it has reached the threshold value
      if (analogSensor > sensorThres)
      {
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
        tone(buzzer, 1000, 200);
      }
      else
      {
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
        noTone(buzzer);
      }
      delay(100);

This is the DHT11 code :

    #include <SimpleDHT.h>

    int pinDHT11 = 7;
    SimpleDHT11 dht11(pinDHT11);

    void setup() {
        // start working...
      Serial.begin(9600);
      Serial.println("Temperature and Humidity Data");
    }

    void loop() {

      delay (250);
      // read without samples.
      byte temperature = 0;
      byte humidity = 0;
      int err = SimpleDHTErrSuccess;
      if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
        Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
        return;
      }
      Serial.print((int)temperature); Serial.print(" *C, ");
      Serial.print((int)humidity); Serial.println(" H");

      // DHT11 sampling rate is 1HZ.
      delay(1500);
    }

body:
You need to combine the 3 major area's of the code, the include/declaration section where files are included and global variables are declared.  Then combine the setup() functions and then combine the loop() functions. Ends up looking something like below. However you may have to tweek the timing of your delays

    #include <SimpleDHT.h>
    int redLed = 12;
    int greenLed = 11;
    int buzzer = 10;
    int smokeA0 = A5;
    // threshold value
    int sensorThres = 400;
    int pinDHT11 = 7;
    SimpleDHT11 dht11(pinDHT11);

    void setup() {
      pinMode(redLed, OUTPUT);
      pinMode(greenLed, OUTPUT);
      pinMode(buzzer, OUTPUT);
      pinMode(smokeA0, INPUT);
      Serial.begin(9600);
      Serial.println("Starting");
    }

    void loop() {
      int analogSensor = analogRead(smokeA0);
      Serial.print("Concentration: ppm ");
      Serial.println(analogSensor);
      // Checks if it has reached the threshold value
      if (analogSensor > sensorThres)
      {
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
        tone(buzzer, 1000, 200);
      }
      else
      {
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
        noTone(buzzer);
      }
      delay(250);
      // read without samples.
      byte temperature = 0;
      byte humidity = 0;
      int err = SimpleDHTErrSuccess;
      if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
        Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
        return;
      }
      Serial.print((int)temperature); Serial.print(" *C, ");
      Serial.print((int)humidity); Serial.println(" H");

      // DHT11 sampling rate is 1HZ.
      delay(1500);
    }

The other way you can do it, which keeps it easyer to read, is move the contents of each main loop into its own function, and then call the two functions from inside loop().  This allows you to easly comment out one of the functions to trouble shoot somthing, or even allow you to call one more often then the other depending upon your needs, (can look at the blink without delay example for how to manage timing)

    #include <SimpleDHT.h>
    int redLed = 12;
    int greenLed = 11;
    int buzzer = 10;
    int smokeA0 = A5;
    // threshold value
    int sensorThres = 400;
    int pinDHT11 = 7;
    SimpleDHT11 dht11(pinDHT11);

        void setup() {
          pinMode(redLed, OUTPUT);
          pinMode(greenLed, OUTPUT);
          pinMode(buzzer, OUTPUT);
          pinMode(smokeA0, INPUT);
          Serial.begin(9600);
          Serial.println("Starting");
        }

    void loop1(){
       int analogSensor = analogRead(smokeA0);

      Serial.print("Concentration: ppm ");
      Serial.println(analogSensor);
      // Checks if it has reached the threshold value
      if (analogSensor > sensorThres)
      {
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
        tone(buzzer, 1000, 200);
      }
      else
      {
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
        noTone(buzzer);
      }
      delay(100);
    }

    void loop2(){
      delay (250);
      // read without samples.
      byte temperature = 0;
      byte humidity = 0;
      int err = SimpleDHTErrSuccess;
      if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
        Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
        return;
      }
      Serial.print((int)temperature); Serial.print(" *C, ");
      Serial.print((int)humidity); Serial.println(" H");

      // DHT11 sampling rate is 1HZ.
      delay(1500);
    }

    void loop() {
      loop1();
      loop2();
    }


message:
How to modify a created byte?

I have created a `byte` for 16x2 LCD. It is basically a custom character which I will have to change later.
<!-- language-all: lang-cpp -->

    byte char[8]{
     B10000,
     B01000,
     B00100,
     B00010,
     B00001,
     B11000,
     B11100
    };

I want to edit the third number from fourth row. So, the fourth row will become `B00110` from `B00010`. Is this possible? Are there any alternatives for this?

body:
Well first of all you are trying to name the variable char? which is already a keyword for the variable type of char.   But you can access it by the index of the array. Also not sure if you intended to make the array 8 bytes in length, and then only use 7, but thats what you had done in your example

    //define it all at once
    // byte byteArray[8] = {B10000,B01000,B00100,B00010,B00001,B11000,B11100};
    //or by index
    byte byteArray[8];
    byteArray[0]=B10000;
    byteArray[1]=B01000;
    byteArray[2]=B00100;
    byteArray[3]=B00010;
    byteArray[4]=B00001;
    byteArray[5]=B11000;
    byteArray[6]=B11100;

    //if you need to change one in the code elsewhere
    byteArray[3]=B00110;
    //or
    byteArray[3]=6;
    }


body:
You can use the following array initialization:

In the setup I shows how to set a bit. For this, the bit operator or (|) is used. To reset a bit, you can use &. You can set/reset multiple bits this way.

Also you can use 1 << 2 which means 1 (most right bit) shifted left two places (thus B100).

Btw, it is common practice to initialize all values.

    byte lcd[8] =
    {
      B10000,
      B01000,
      B00100,
      B00010,
      B00001,
      B11000,
      B11100,
      B00000  // Also initialize last element
    };

    void setup()
    {
       lcd[3] |= B100; // Set 4th row (element 3), 3th bit (from the right)
       lcd[3] |= 1 << 2; // Alternative
    }

    void loop()
    {
    }

Explanation about the `or` arithmetics: OR means: if at least one bit is 1, the result is 1, otherwise 0.

Truth table:

    A | B | A or B
    --+---+-------
    0 | 0 |   0
    0 | 1 |   1
    1 | 0 |   1
    1 | 1 |   1

For your example it means:

    Original value of lcd[3]: B00010
    Or mask (in setup):       B00100
                              ------ OR
    Result                    B00110


message:
Connecting Function Generator to Arduino

I want to send a function generator's signal to an Arduino UNO Analog pin. Can I use an Oscilloscope probe connected to the function generator output BNC, set to 1x to connect to the Arduino headers using jumper wires? I did read through the manuals of the function generator, but couldn't find a solution.

The function generator available is Tenma 72-14110.

body:
Sure, you can connect the function generator to an analog pin of the Arduino. The probe and the jumper wires are just wires here, nothing special. You should also connect the function generators ground to the Arduinos ground (!).

But: Be sure to stay in the Arduinos voltage range (0 to 5V) with the function generators signal. If you apply a higher or negative voltage, you can destroy the Arduino. As long, as you stay inside that range, nothing bad will happen.


body:
As a complement to chrisl's answer, I would recommend putting a
10 kΩ series resistor in series between the function generator and
the Arduino.

This is just for safety: if the function generator accidentally goes out
of the  Arduino's safe voltage range, the resistor will limit the
current that flows through the input pin's protection diodes. These
diodes are rated to only 1 mA, and a 10 kΩ resistor should
greatly expand the range of voltages you can send without frying them.


message:
How to stringtok this long string?

I have a string,

"id,port,password,ssid,delay,flag,class,category"

Please tell me how can stringtok this and find out the "flag" value(0 or 1)?

Here is what I tried:

```c++
void setup()
{
    char input[] = {"id,port,password,ssid,delay,flag,class,category"};
    char *ptr;
    Serial.begin(115200);
    ptr = strtok(input, ",");
    Serial.println(ptr);
    while (ptr != NULL) {
        ptr = strtok(NULL, ",");
        Serial.println(ptr);
    }
}

void loop(){}
```

body:
For strings with a fixed format like that (I assume it's a fixed format...) I normally just do a manual strtok of the whole thing into a set of pointers. No need for a loop.  You can then just test the last one to see if the whole thing tokenised properly, since if anything before that fails then all other subsequent ones will fail and the last one will have failed.

    void setup()
    {
        char input[] = {"id,port,password,ssid,delay,flag,class,category"};
        char *ptr;
        Serial.begin(115200);

        char *id = strtok(input, ",");
        char *port = strtok(NULL, ",");
        char *password = strtok(NULL, ",");
        char *ssid = strtok(NULL, ",");
        char *delay = strtok(NULL, ",");
        char *flag = strtok(NULL, ",");
        char *class = strtok(NULL, ",");
        char *category = strtok(NULL, ",");
        if (category != NULL) { // Everything up to and including category worked
            Serial.print("Flag: ");
            Serial.println(flag);
        }
    }

    void loop(){}

As an aside: if there is ever a chance any of the fields could be empty ("flag,,category" for example) then you should use `strsep()` instead of `strtok()` as I detail in my [tutorial on splitting strings in C](https://majenko.co.uk/blog/splitting-text-c).


message:
ESP8266 Webserver not reachable after 2 minutes from reset

I have a [Keyes Espressif ESP8266][1] NodeMCU, I have two LEDs that I want to control which are connected to the ESP. When I open the webpage `http://10.0.0.5/5` after uploading the sketch it works fine. If I don't open and close the website before ~ 02:30[mm:ss] the server becomes unreachable even if I close the existing connection and open a new connection in a new tab the same error yields: `ERR_CONNECTION_TIMED_OUT`

If I don't open a web page before ~ 02:30[mm:ss] I also receive error `ERR_CONNECTION_TIMED_OUT`

The web server is only made available when I hard reset the board then the same rules apply as above.

    ESP.getFullVersion() outputs:
    SDK:2.2.1(cfd48f3)/Core:2.5.1=20501000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020

Question:

How can I make the web server accessible constantly?

With the help of @Juraj I tried changing to SDK V3 which made no difference I also tried:

 - All lwip variants

My Code:

    // Load Wi-Fi library
    #include <ESP8266WiFi.h>

    // Replace with your network credentials
    const char* ssid     = "DO_231455";
    const char* password = "0828842107";

    // Set web server port number to 80
    WiFiServer server(80);

    // Variable to store the HTTP request
    String header;

    // Auxiliar variables to store the current output state
    String output5State = "off";
    String output4State = "off";

    // Assign output variables to GPIO pins
    const int output5 = 16;
    const int output4 = 4;

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

      // Initialize the output variables as outputs
      pinMode(output5, OUTPUT);
      pinMode(output4, OUTPUT);
      // Set outputs to LOW
      digitalWrite(output5, LOW);
      digitalWrite(output4, LOW);

      Serial.print(ESP.getFullVersion());
      //WiFi.disconnect() ;
      //WiFi.persistent(false);
      //WiFi.setSleepMode(WIFI_NONE_SLEEP);
      // Connect to Wi-Fi network with SSID and password
      Serial.print("Connecting to ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      // Print local IP address and start web server
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
      server.begin();
    }

    void loop(){
      WiFiClient client = server.available();   // Listen for incoming clients
      if (client) {                             // If a new client connects,
        Serial.println("New Client.");          // print a message out in the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        while (client.connected()) {            // loop while the client's connected
          if (client.available()) {             // if there's bytes to read from the client,
            char c = client.read();             // read a byte, then
            Serial.write(c);                    // print it out the serial monitor
            header += c;
            if (c == '\n') {                    // if the byte is a newline character
              // if the current line is blank, you got two newline characters in a row.
              // that's the end of the client HTTP request, so send a response:
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println("Connection: close");
                client.println();

                // turns the GPIOs on and off
                if (header.indexOf("GET /5/on") >= 0) {
                  Serial.println("GPIO 5 on");
                  output5State = "on";
                  digitalWrite(output5, HIGH);
                } else if (header.indexOf("GET /5/off") >= 0) {
                  Serial.println("GPIO 5 off");
                  output5State = "off";
                  digitalWrite(output5, LOW);
                } else if (header.indexOf("GET /4/on") >= 0) {
                  Serial.println("GPIO 4 on");
                  output4State = "on";
                  digitalWrite(output4, HIGH);
                } else if (header.indexOf("GET /4/off") >= 0) {
                  Serial.println("GPIO 4 off");
                  output4State = "off";
                  digitalWrite(output4, LOW);
                }

                // Display the HTML web page
                client.println("<!DOCTYPE html>");
                client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                client.println("<link rel=\"icon\" href=\"data:,\">");
                // CSS to style the on/off buttons
                // Feel free to change the background-color and font-size attributes to fit your preferences
                client.println("");

                // Web Page Heading
                client.println("
ESP8266 Web Server
");

                // Display current state, and ON/OFF buttons for GPIO 5
                client.println("
GPIO 5 - State " + output5State + "
");
                // If the output5State is off, it displays the ON button
                if (output5State=="off") {
                  client.println("
<button class=\"button\">ON</button>
");
                } else {
                  client.println("
<button class=\"button button2\">OFF</button>
");
                }

                // Display current state, and ON/OFF buttons for GPIO 4
                client.println("
GPIO 4 - State " + output4State + "
");
                // If the output4State is off, it displays the ON button
                if (output4State=="off") {
                  client.println("
<button class=\"button\">ON</button>
");
                } else {
                  client.println("
<button class=\"button button2\">OFF</button>
");
                }
                client.println("");

                // The HTTP response ends with another blank line
                client.println();
                // Break out of the while loop
                break;
              } else { // if you got a newline, then clear currentLine
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }
          }
        }
        // Clear the header variable
        header = "";
        // Close the connection
        client.stop();
        Serial.println("Client disconnected.");
        Serial.println("");
      }
    }
Worth noting (while debugging):
The new client disconnects.

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

  [1]: https://wiki.keyestudio.com/KS0367_keyestudio_ESP8266_WiFi_Board
  [2]: https://i.stack.imgur.com/VTXEh.png

body:
**The short answer: Config a static IP!**

After looking at Git Issue [#2371][1] I found out that I need to create a static IP address to fix this issue. I can do this by inserting `WiFi.config(ip, gateway, subnet)` just before `WiFi.mode(WIFI_STA)` in the code above.

 - First I found the information `gateway` & `subnet` I needed by opening the command prompt on a computer that's connected to the access point(router) as the one connected to the ESP8266 which functions in station mode. I did this on Windows by searching `Command Prompt` then typing `ipconfig` to obtain the following information:

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

**Replace the points with commas!** See [this][3] references for more information regarding other parameters and DNS.

----------

 - To create an IP address you need to see your IP address in the red square in the picture above taken from the command prompt. The first three octects (numbers) of your router IP (probably `10.0.0.x`, `192.168.0.x`, or `192.168.1.x`) must match your chosen static IP. For my example the numbers to match would be `10.0.0`.

 - Next, I needed to obtain the DCHP range for my router. My router is a [Netgear Wireless ADSL2+ Modem Router DG834Gv5][4]. To obtain the range I needed to access my router settings. To access this I looked for an HTTP link under the router. For my router it was `http://10.0.0.2` along with the username and password which was `admin`, `admin` respectively. This is what it looks like:

[![enter image description here][5]][5]

This will vary according to your router - Then I went into Advanced settings and saw the DHCP range. **This is an error on my part noted by @djsfantasi. Please see his answer regarding DHCP range selection.**<strike>The new static IP needs to be within the DHCP range According to one of the comments `brendanmatkin` made in Git Issue [#2371][1] the last number of my static IP (which is `ZZ` in `WW.XX.YY.ZZ`) needs to be **outside** of this range. For me it didn't work, it worked when I used a value **inside** this range but `brendanmatkin` knows much more than me, I'm just a novice. There might be implications that I am not aware of so I think it's worth looking into.</strike> A DHCP range looks like this below:

[![enter image description here][6]][6]

My inserted code looks like this below:

    void setup(void) {
      .
      .
      .
      Serial.begin(115200);
      //WiFi.disconnect();  //Prevent connecting to wifi based on previous configuration
      IPAddress ip(10,0,0,15); // this 3 lines for a fix IP-address
      IPAddress gateway(10,0,0,2);
      IPAddress subnet(255,255,255,0);
      //WiFi.hostname("ESP8266");      // DHCP Hostname (useful for finding device for static lease)
      WiFi.config(ip, gateway, subnet);
      //Station mode:
      WiFi.mode(WIFI_STA);
      .
      .
      .
    }

Please comment for more info :)

**Additional information and changes I've made to IDE:**

OS : Windows 8.1

IDE : Arduino IDE V1.9.8

Board : [Keyes ESP8266][7]

Arduino IDE > Tools >Board (in boards manager) : Generic ESP8266 Board

Arduino IDE > Tools >lwip : V2 Low Memory

Arduino IDE > Tools >Esp FW:"nonos.." : nonos-sdk pr-3(known issues)*

Power Supply : USB COM from 300Watt desktop power supply. ~ 1.5A current output.

Much appreciation to @Juraj.  Juraj

  [1]: https://github.com/esp8266/Arduino/issues/2371
  [2]: https://i.stack.imgur.com/2iNxr.png
  [3]: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#config
  [4]: https://www.downloads.netgear.com/files/GDC/DG834GV5/DG834Gv5_UM_11Mar10.pdf
  [5]: https://i.stack.imgur.com/9EU2Q.png
  [6]: https://i.stack.imgur.com/r5l3W.png
  [7]: https://wiki.keyestudio.com/KS0367_keyestudio_ESP8266_WiFi_Board


body:
It worked when the IP was in the range because there are no valid IP addresses outside the range.

WW.XX.YY.0 and WW.XX.YY.255 are reserved. The router is using the .1 and .2 addresses. That leaves 3-254 available, which as we see are the addresses within the DHCP range.

You can assign a static IP address within the DHCP range, but you run the risk of disabling 1 or 2 devices. DHCP doesn’t know you’ve used one of it's addresses, so can assign it to another device. Boom! Two devices with the same address and both will not function.

The correct way to resolve this is to log into the router and change the DHCP range. For example, increase the lower limit of 3 to (random pick) 20. Now, DHCP won’t be disturbed and will happily give out addresses to your devices. But if you need a static IP address, you’ve defined a pool, from WW.XX.YY.3 to WW.XX.YY.19


message:
cross correlation of two analogread value on arduino?

I am working on a final project called sound source localization using Arduino Uno. I want to use two sound sensor to capture a sound. The nature of the sound is clap or speech sound. I want to use the cross correlation method to estimate the time delay between the microphones then find the position and angle. My supervisor said to me you have to store the values on analogRead in two arrays then cross correlation the element of two arrays. But i am struggle the cross correlation part. I will appreciate any help from you guys.

```c++
#define LED_NORTH 2
#define LED_SOUTH 4

#define MIC_NORTH A0
#define MIC_SOUTH A2

/* let's said we want to read 100 samples */
const unsigned int numReadings = 100;
unsigned int analogVals[numReadings];
unsigned int i = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_NORTH, OUTPUT);
  digitalWrite(LED_NORTH, LOW);
  pinMode(LED_SOUTH, OUTPUT);
  digitalWrite(LED_SOUTH, LOW);
}

void loop() {
  int north = analogRead(MIC_NORTH);
  Serial.println(north);
  int south = analogRead(MIC_SOUTH);
  Serial.println(south);
  /* take numReadings # of readings and store into array */
  for(unsigned int i = 0; i < numReadings; i++)
  {
    analogVals[i] = analogRead(A0);
    delay(1000);
  }
```

body:
I am not going to directly answer the question, as I think it is
ill-posed. Before posting a question here, you are supposed to have done
your research, and come with very _specific_ problems you cannot solve
by your own. I may be mistaken, but it looks to me like you are at a
very preliminary stage where you barely started to _think_ about the
project.

So, instead of trying to answer an overly broad question, I will try to
provide some guidance by asking questions back to you. Below is a list
of some problems and challenges you will have to consider for advancing
your project. It may not be complete: it's just what I can think off the
top of my head. This will hopefully help you tackle the right problems.

## Non-stereo sampling

Your Arduino is incapable of stereo sampling. Since it has only one ADC,
it can only sample one channel at a time. This means you will have to
alternatingly sample the left channel, then the right channel, then the
left channel... Since the left and right samples are not taken at the
same time, this will have an implication on how you interpret the
results from the cross-correlation. Did you think about how you will
handle this? Is this acceptable? Will you have to instead use external
ADC chips in order to have real stereo sampling?

## Slow sampling rate

If you `analogRead()` in a tight loop, you are taking at most one sample
every 112 µs. And since you are alternating between the channels,
on each channel you get one sample every 224 µs. This is a sampling
rate of 4.46 kHz, and a Nyquist frequency of 2.23 kHz. Is this
fast enough for your application?

In 224 µs, the sound travels about 76 mm, which is thus the
spatial resolution of your cross-correlation. How does this translate into
angular resolution? Is this resolution satisfactory? Do you plan to use
interpolation methods to try to improve it?

If the time resolution is not good enough, you can speed up the ADC by a
factor 2 or 4 at the cost of lowered accuracy. You will have to dig on
the MCU datasheet (or the Internet...) in order to learn how to do that.

## Inconsistent sampling rate

When you use `analogRead()`, the time between consecutive samples can
depend on the code you run between the consecutive calls to
`analogRead()`. It can also depend on how your code gets interrupted by,
say, the timer interrupt, or the UART interrupt if you are sending data
out. An inconsistent sampling rate is something you want to avoid when
doing cross-correlations.

You could try to mitigate this problem by running the acquisition with
interrupts disabled. However, the only way to guarantee periodic
sampling is by configuring the ADC to be triggered automatically, either
by a timer or by itself (free running mode). Walking this path will
require you to forego the comfort of the Arduino library (`analogRead()`
is just so easy to use...), and carefully study the datasheet, which
would be a very significant time investment.

Do you have the time and energy for this? If you end up learning all
this low-level details on the configuration of the ADC, will this
learning be relevant to the course for which this is a project?

## Finite data arrays

Mathematically, the cross-correlation is typically defined for infinite
series of samples. In your experiment, you will have to deal with finite
arrays, and this makes a subtle difference. Did you think about how you
will deal with the finiteness of the arrays? Are you going to zero-pad?
Remove the average before zero-padding? Apply a windowing function?

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

I hope it is clear by now that the “cross correlation part” is only one
of the many issues you will have to face. I suggest you discuss all
these questions with your supervisor. He might be able to advise you on
how to tackle them, whether it's worth it, where you may cut corners...


message:
20x4 LCD shows up as 20x2

I need help with my LCD. I have a 20x4 LCD and it shows up as 20x2. The LCD address said "// Set the LCD address to 0x27 for a 16 chars and 2 line display". I changed it which says "// Set the LCD address to 0x27 for a 20 chars and 4 line display" and uploaded it, thinking it would show up as 20x4 as it should. But it didn't work:

[![Photo of the issue][1]][1]

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

body:
Nori, just ignore every code that's after the //, they are just comments and the compiler will just discard them.

Look at the LCD rear, you should see your I2C chip, search google typing
["chip's code"  20x4 arduino]. You'll see which I2C address you most likely need to use. For instance, the PCF8574 has addresses fromm 0x20 to 0x27, the PCF8574A has addresses from 0x38 to 0x3F...

Without this info you are only shooting blindfolded, the 0x27 it's only the "standard" address of the most common PCF8574 module but there are plenty of modules.

Another way to find the address is to upload [this code][1], it's an I2C scanner that will write on the serial monitor any I2C device that replies a "ping" signal.

If you find the address and still it doesn't work or if you can't find the address, check and double and triple check the wiring, especially the false contact.

  [1]: https://playground.arduino.cc/Main/I2cScanner/


message:
Activating a Relay with Wemos D1

I have a problem similar to these questions:

https://arduino.stackexchange.com/questions/52945/wemos-d1-doesnt-drive-relay

https://arduino.stackexchange.com/questions/65941/wemos-d1-is-not-triggering-relay

I got this BC548B transistor from an old apparatus I scratched. The transistor saturation voltage is 0.6V  according to the datasheet:

https://alltransistors.com/pdfdatasheet_fairchild_semi/bc548_bc548a_bc548b_bc548c.pdf

When I set up my circuit the wemos d1 inboard leds dim and the board resets so I guess something is going really wrong. Can someone advise if my design makes sense?

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

UPDATE
======

I replaced the 12V relay with a 5V one but still can't get it to work. Basically, the 3.3V signal seems to be too low to activate the solenoid. How can I raise the 3V3 signal to 5V? What was wrong with my idea of using a transistor to do it?

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

  [1]: https://i.stack.imgur.com/zA0i3.png
  [2]: https://i.stack.imgur.com/WqbGB.png

body:
That appears to be a 12 "solid state" relay. That means that it is designed to be both powered by and switched by 12V. You're trying to drive it with slightly more than 1/3 of its rated voltage. Don't do that.

## Edit:
Note that none of the relays being discussed are true solid state relays. These are are all conventional coil relays that include cicuitry that allows them to be driven by CMOS logic signals. A true solid state relay does not have any moving parts, but uses solid state components to do the job of a relay. Those cost significantly more money however.)

----
It might be that you can get away with driving a 5V solid state relay with 3.3V, or 12V relay with 5V, but you shouldn't do those things either.

Also note that even if you are using the correct relay, your relay almost certainly takes more current than the 5V pin on an Arduino can provide (When driven from USB, the entire system is limited to 500 mA, including the power needed to the Arduino.)

## Edit:

These solid state relays come in 12V, 5V, and 3V flavors. Get a 3V one: https://www.adafruit.com/product/3191?gclid=EAIaIQobChMIyY_dxM344gIVELbICh1ufwivEAQYBSABEgI3wPD_BwE


message:
What is causing this warning in Arduino IDE?

I'm using [DS3231 module][1] with [rinkydink library][2] and it is working just fine, however every time i want to compile the code Arduino IDE shows this warning:
```
C:\Program Files (x86)\Arduino\libraries\DS3231\DS3231.cpp:291:106:
warning: ISO C++ forbids converting a string constant to 'char*'
[-Wwrite-strings]
```

What is this warning and how to solve it?

  [1]: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
  [2]: http://www.rinkydinkelectronics.com/library.php?id=73

body:
The warning was caused by this line:

```c++
char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
```

In C++, the content of a character string such as `"Jan"` cannot be
modified. Thus, if you assign the string to a pointer, the pointer
should be declared as **const** char \*:

```c++
const char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
```

The same applies to the other arrays of strings: `daysLong`, `daysShort`
and `monthLong`. As a consequence, the prototypes of the methods
`getDOWStr()` and `getMonthStr()` should be changed in order to return a
`const char *`.

BTW, are you sure this library is still maintained? This should have
been fixed a long time ago, and it seems the source was last modified in
2015. You may be better off using a more modern alternative. For
instance, in the Arduino library manager, you can find [DS3231][] and
Adafruit's [RTClib][].

[DS3231]: https://www.arduinolibraries.info/libraries/ds3231
[RTClib]: https://www.arduinolibraries.info/libraries/rt-clib


body:
The DS3231 library from Rinky Dink is the best RTC library there is...I know, I tried them ALL.  This library allows one to print date and time strings with only 3 Arduino print statements:  Serial.print(rtc.getDateStr());
      Serial.print(" -- ");
      Serial.println(rtc.getTimeStr());
Other RTC libraries force user to make the strings up themselves, at a cost of about 12 lines of useless Serial.print commands.


message:
RTClib library the second, second

I'm using [RTClib][1] for my DS3231 module, the problem is the library is displaying the second without zero behind it: `22:1:1` and when i print the time on my 16x2 LCD time is displaying like this:

> 22:22:59
>
> 22:23:19
>
> 22:23:29
>
> ...
>
> 22:23:59
>
> 22:23:10
>
> 22:23:11

the second number of seconds is not getting cleared.
i know one solution to this is to use `lcd.clear()` function to update the LCD in each loop but is there any other way to clear that second number or do something so library show zero behind second?

  [1]: https://github.com/adafruit/RTClib

body:
It's your responsibility to format the time properly, not the library. The library just gives you a number. If you want a leading zero then it's up to you to provide that leading zero.

For example:

    if (now.seconds() < 10) {
        lcd.print("0");
    }
    lcd.print(now.seconds());

Or:

    char timestr[9];
    snprintf(timestr, 9, "d:d:d", now.hours(), now.seconds(), now.minutes());
    lcd.print(timestr);


message:
Can an Arduino Pro Mini interface with a full-sized WiFi shield?

We have an Arduino Pro Mini on a breadboard connected to a 9V battery and a sensor, reading data. We also have a full-sized [Adafruit WINC1500 WiFi Shield with PCB Antenna][1]. I would like to know if they can be connected and, if so, how.

I understand that a shield is usually stacked on a similarly sized board, but can we place the shield on the breadboard with the Mini and use jumper wire to connect the necessary pins so the Mini can use the WiFi (actually, we want to write to the SD card on the WiFi shield)? If so, how would we know which pins are used, and would we need to provide additional power? Or is connecting a Mini to a full-sized shield a ridiculous idea?

  [1]: https://www.adafruit.com/product/3653

body:
> I would like to know if they can be connected and, if so, how.

Yes.

> but can we place the shield on the breadboard

No, the pins are misaligned and won't plug in.

> and use jumper wire to connect the necessary pins so the Mini can use the WiFi

Yes - connect the jumper wires directly to the WiFi shield pins.

> If so, how would we know which pins are used,

Read the manual or schematic for your WiFi shield. It probably uses the SPI pins plus a few more.

> and would we need to provide additional power?

It will need a power connection, yes - though "extra" power? Not sure what you mean.


message:
Person (phone) detector that trigger an event esp32 cam

So me and my dad are trying to catch would be thieves and also someone leaving behind alcohol bottles. At his storage business the cameras don't reach to these spots.

Without being too invasive I want to sense bluetooth and/or wifi signals of relatively close phones sort of like a pax counter. This is in lue of using a pir sensor which I have always found finicky and I want to make use of the esp32' cam's wifi/ble chip.

So to start I researched for the past few days or week. I found that most phones don't use ble so maybe that is out. I also found that the esp32 cam is a bit finicky and I'm not sure if it is compatible with other code I have found.

One time I was able to get the light to come on when my phone was near using code I found for the esp32.

Any help or direction would be nice

Edit: I understand this sounds weird but mostly I would just like to get proximity of bluetooth or wifi to trigger an event. The device is powered by battery and I understand not everyone carrys phones.

body:
Detecting a phone could be easily done by [capturing](https://github.com/brannondorsey/sniff-probes) WiFi probe requests which are sent by phones having at least one saved WiFi network. Note that such requests alone are often enough to identify the person, if their home WiFi SSID is set to something like "Davids_wifi".

Software-wise, this would be much easier to do on Linux (think Raspberry Pi or a similar device) which already have all the network sniffing software like `tcpdump`, which you would otherwise have to find or implement on ESP32.

I'm leaving out the legal implications of what you're trying to do as I don't know what country you are in, but bear in mind that hidden surveillance may be illegal in some cases.


message:
Is it possible to execute a code in runtime when gets updated over the air (OTA)?

I would like to build a lib like ArduinoOTA but with no downtime at runtime. To achieve that I am wondering if it is possible to create a simple setup and loop code to

1. Check for new releases
2. If we have a new one start download it
3. As download routine is not finished keep running the current release
4. When download has finished, swap current release to the new one.
5. Now the normal routine is running the new release.

I am pretty interested if it is possible to do by myself something like that.

I didn't find any paper or articles similar to this and I don't known if this is a challenge for Arduino scope or C/C++.

Maybe I am saying something bizarre but I have been thinking of save new release into flash memory, point to it and discard the old release from flash memory.

body:
On many Arduinos the processor is only a few dollar part.  You are asking for a feature that only starts appearing on platforms where the processor is over an order of magnitude higher in price.  Further, such inexpensive processors normally run a single program.  Running a sketch while managing a download & update would best be done by two programs existing in an operating system.  Again, likely requiring a processor an order of magnitude higher in price.

Instead, consider implementing your design using two different Arduinos.  Swapping one out for the other after updating.   Hot swapping may not be trivial.  This really depends on how your application interfaces with the world. But likely will be much easier than solving the problem of designing the supporting software to make sketch updates transparent to the Arduino user.


message:
DS3231 and EEPROM

Currently to get time/date i'm using DS3231 module with the [RTClib][1] library, i want to use the Atmel 24C32 chip on the module to store some small values (temperature etc).

Can i use the current library AND an external EEPROM library (which one?) OR i need to change my RTC library in order to use EEPROM feature?

  [1]: https://github.com/adafruit/RTClib

body:
> Can i use the current library AND an external EEPROM library (which one?)

Yes. Devices on an I2C bus are separate devices and use their own separate libraries.

* https://playground.arduino.cc/Main/LibraryForI2CEEPROM/


message:
Get 5V output from NodeMCU

I have a sensor that requires used of 5V as input to Vcc. But I dont see any 5V output pins on the NodeMCU 1.0(12E). Is there a way I could get 5V output pins?

Its not a duplicate question. I want a 5V output and not provide 5V input to NODEMCU.

body:
The `VIN` pin outputs 5V approximately (dependent on USB input voltage) from the NodeMCU board.

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

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


message:
What is the use of reserved pins and SDD2, SDD3 pins of the NodeMCU?

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

How to use the reserved pins on the NODEMCU? What is their use? Also what is the use of SDD pins?

Thanks.

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

body:
The ESP8266 uses an external flash memory chip to store your program. It communicates with this flash chip over a 4 bit SDIO interface, on GPIO6-11. These pins are labeled SDDn, SDCLK and SDCMD.
Usually, the interface uses all 4 data lines (QIO), but you can also configure it to use only 2 of the 4 lines (DIO), giving you access to two more GPIO pins (9 & 10).
The reserved pins are not mentioned in the schematic. They cannot be IO pins, because there simply are no other pins on the ESP8266/ESP-12. It could be pins connected to the USB chip, connected to power lines, or not connected at all. The designers probably wanted to allow for extra pins on next iterations of the board, without changing the form factor. A quick search online didn't yield any results, so your best bet is to trace the connection on the PCB, or measure it with a multimeter. You probably shouldn't be using them anyway, because they are "reserved".


message:
ESP8266-01 is not working and it's hot

it has been so long since I tried to connect the esp8266 through Arduino Uno and get it to work my goal is to send data from the Arduino Uno to web site, I have tried everything and a lot of codes but none worked at first I could get a response  but sometimes it does and sometimes it does not I even bought an other one but the new one did not respond at all so I flashed the old one following the instructions in [here][1] and I got response the next day I tried to reuse it and it does not respond at all not even when I put the serial on 115200 and both NR&CR and tried AT but nothing showed in return .i found this [tutorial][2]
and I tried to get it to work using a mobile app but as usual, it does not work

    AT
    AT+RST
    ATE0
    AT+CWMODE=1
    AT+CWQAP
    AT+CWDHCP=1,1
    AT+CWJAP="RemoteXY","12345678"
but i did not get hte name of it wifi in my wifi list
this is the code

    // RemoteXY select connection mode and include library
    #define REMOTEXY_MODE__ESP8266_HARDSERIAL

    #include <RemoteXY.h>

    // RemoteXY connection settings
    #define REMOTEXY_SERIAL Serial
    #define REMOTEXY_SERIAL_SPEED 115200
    #define REMOTEXY_WIFI_SSID "RemoteXY"
    #define REMOTEXY_WIFI_PASSWORD "12345678"
    #define REMOTEXY_SERVER_PORT 6377

    // RemoteXY configurate
    #pragma pack(push, 1)
    uint8_t RemoteXY_CONF[] =
      { 255,2,0,0,0,30,0,8,13,0,
      2,0,70,25,22,11,2,26,31,31,
      79,78,0,79,70,70,0,1,0,10,
      26,12,12,2,31,88,0 };

    // this structure defines all the variables of your control interface
    struct {

        // input variable
      uint8_t switch_1; // =1 if switch ON and =0 if OFF
      uint8_t button_1; // =1 if button pressed, else =0

        // other variable
      uint8_t connect_flag;  // =1 if wire connected, else =0

    } RemoteXY;
    #pragma pack(pop)

    /////////////////////////////////////////////
    //           END RemoteXY include          //
    /////////////////////////////////////////////

    #define PIN_SWITCH_1 2
    #define PIN_BUTTON_1 12

    void setup()
    {
      RemoteXY_Init ();

      pinMode (PIN_SWITCH_1, OUTPUT);
      pinMode (PIN_BUTTON_1, OUTPUT);

      // TODO you setup code

    }

    void loop()
    {
      RemoteXY_Handler ();

      digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
      digitalWrite(PIN_BUTTON_1, (RemoteXY.button_1==0)?LOW:HIGH);

      // TODO you loop code
      // use the RemoteXY structure for data transfer

    }

i wired it like this

[![enter image description here][3]][3]
one last thing is it gets hot every time so what could be the problem what's wrong with is what should I do

  [1]: http://remotexy.com/en/help/esp8266-firmware-update/
  [2]: https://www.youtube.com/watch?v=2cjufbgOBYo
  [3]: https://i.stack.imgur.com/ag3PU.png

body:
when a chip gets hot as soon as the VCC/GND is connected, it means :

 1. **The VCC/GND are internally connected due to a previous failure** (it
    gets hot AFTER the accident).

 2. **An output pin, is connected to a supply rail through a very low resistance load (or short circuited).** pins usually sink or
    source as low as 20mA of current. so if you connect them to a load
    less than (3.3/20)*1000 ~= 150 ohms (in your case with 3.3v supply),
    you are going to fry the output driver. always be sure that a pin, even if it's defined as an input, has a little resistor (a 220 ohms res).
this accident happens between output/supply or output/output pins.

you may have misconnected TX pin to a wrong pin.


message:
esp8266 esp01s EEPROM and flashing

which flash option do I need to take to use EEPROM?

Can I flash with 1MB and no SPIFFs and still write data to EEPROM?

thanks T

body:
> Can I flash with 1MB and no SPIFFS and still write data to EEPROM?

Yes. The EEPROM emulation is saved into different part of the flash, not to SPIFFS.

    |--------------|-------|---------------|--|--|--|--|--|
    ^              ^       ^               ^     ^
    Sketch    OTA update   File system   EEPROM  WiFi config (SDK)

the memory map is from [esp8266 SPIFFS docs][1]

> which flash option do I need to take to use EEPROM?

There is no special option in Tools menu for EEPROM emulation. Only use the library.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html


message:
How to write a float value EEPROM

I'm using this [library][1] for my DS3231 which have a Atmel 24C32 on it.
i have a float value which increases by 0.5, like:

27.50

28

28.50
...

the code is like this:

    float lowTemp= 10.5

    float highTemp= 10.5

    void setup(){
      lowTemp = i2c_eeprom.read(100);
      highTemp = i2c_eeprom.read(101);
    }
    void loop(){
      if ((menuswtichStatus == HIGH) && (lcdWelcome == HIGH)) {
        previousMillis = millis();
        lcd.clear();
        menuScroll++;
        lcdClear = 1;
        lcdClear2 = 1;
      }
      if (menuScroll == 1) {
        lcd.setCursor(0, 0);
        lcd.print("Temperature set:");
        lcd.setCursor(0, 1);
        lcd.print("Minimum  ");
        lcd.print(lowTemp);
        lcd.print((char)223);
        lcd.print("C ");
        if (plusSwitchstatus == HIGH) {
          lowTemp += 0.5;
        }
        if (minusSwitchstatus == HIGH) {
          lowTemp -= 0.5;
        }
      }
      if (menuScroll == 2) {
        lcd.setCursor(0, 0);
        lcd.print("Temperature set:");
        lcd.setCursor(0, 1);
        lcd.print("Maximum  ");
        lcd.print(highTemp);
        lcd.print((char)223);
        lcd.print("C ");
        if (plusSwitchstatus == HIGH) {
          highTemp += 0.5;
        }
        if (minusSwitchstatus == HIGH) {
          highTemp -= 0.5;
        }
      }
      if (menuScroll == 3) {
        lcd.setCursor(0, 0);
        lcd.print("   Saving the");
        lcd.setCursor(0, 1);
        lcd.print("   Settings...");
        delay(1000);
        i2c_eeprom.write(100, lowTemp);
        i2c_eeprom.write(101, highTemp);
        delay(1000);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("    SETTINGS");
        lcd.setCursor(0, 1);
        lcd.print("     SAVED!");
        delay(2000);
        menuScroll = 0;
        lcdClear = 0;
        lcdClear2 = 0;
      }
    }
*i have the library and stuff up there, it's just an example of my code...*

The float value is not saving(written), what's the solution?

  [1]: https://github.com/QuentinCG/Arduino-I2C-EEPROM-library

body:
You have multiple options:

1. According to jsotola's remark: the easiest is to multiply your value by 2, store it, and after reading, divide it by 2. In one byte you can store a value from 0 to 127.5 (255 / 2), or if you use signed from -64.0 to +63.5. Of course you also can use an offset in case you know the value cannot be less than e.g. -20.
2. If you need a higher range, you can still multiply it by 2, but store it in two bytes. Split the value in a 'high value' (value % 256) / 256, and a 'low value' (value % 256).
3. If you want to store the value completely, than use sizeof(float) to find the length, and a for loop to write each byte, starting from the first byte of the float until the last one.


message:
Arduino MKR 1010 WiFi as BLE central/client

I'm trying to use my new Arduino MKR 1010 WiFi as a Bluetooth Low Energy **central**/**client**, however I could only find information on how to use it as a *peripheral/server* (for example with the [ArduinoBLE library][1], which only supports peripheral mode).

Is this possible? Maybe with a different library or firmware for the integrated NINA-W102 chip?

  [1]: https://github.com/arduino-libraries/ArduinoBLE

body:
In case this thread turns up in a search, the [ArduinoBLE][1] library now includes central and peripheral support.

  [1]: https://github.com/arduino-libraries/ArduinoBLE


message:
Firmware backup and restore

I need to have the firmware stored somewhere on the board in order to get back to it after flashing a new firmware.

Is there a way to store a backup of the firmware somewhere, and use a button to erase a newer firmware and get back to the old one, without re-flashing the old firmware again ?

body:
Yes. You need to create a `factory` partition and upload your bin file to there.

You can read more about ESP32 partitions [here](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html)

Note that none of the partition schemes in the ESP32 core have factory partitions, so you will need to create a custom one and link it to a menu entry (look at the boards.txt file to see how that is done).

The existing partition files are just `.csv` files within the ESP32 core. Copy one and modify it, then link that to a menu entry using the new file name.


message:
Any possible way to stack Motor Driver shield L293D with Xbee Shield v03 on arduino?

So i am trying to stack these two shield on arduino, now the problem here is that i guess there is a conflict between the pins of arduino being used by both shields, so can anyone suggest a solution?

body:
Read the documentation for both boards. They should list the pins used. Their associated libraries will define variables to which you can assign non-conflicting pins. Review the sample code provided as well. Usually, the sample code included setting the pins to use, even if the code only sets them to their default.

There is another possibility. I don’t think this is the case, but I’ve run into this issue with different shields. If the shields use I2C, they may need to have jumpers shorted to set an address.


message:
Arduino OSX Mojave - Serial port only shows sometimes

I've found lots of issues about serial ports not showing up at all, but none about what I'm experiencing.

Sometimes I can see my Arduino Mega 2560 in the ports list, and sometimes I can't. I've tried unplugging, replugging, rebooting my PC, and installing various CH34X USB drivers

Is there some way I can troubleshoot this issue to work out where things are going wrong?

EDIT: I have a Macbook Pro 2017 with Thunderbolt 3.0 ports connected to an adapter that lets me plug in USB. The Mega is a CH340G -> Wemos® Mega +WiFi R3 Module ATmega2560+ESP8266 32Mb Memory USB-TTL CH340G Compatible For Arduino Mega NodeMCU ESP8266.

EDIT #2: It looks like it's working again, all I did was switch around some of the DIP switches and change it from RX/TX0 to RX/TX3, sometimes when that stops working ill change it back to RX/TX0 and itll start working again. I suspect it has something to do with the USB-C adapter but haven't nailed it down yet.

body:
A colleague at work was struggling with a similar problem just two days ago.

He said he resolved it by reinstalling the USB driver. I did not pay much attention to more details (because I did not have that problem). If you can not work how to reinstall and none can advise how, I can ask him on Monday.

In the meantime here are a couple of reinstall the USB driver links:

https://www.roland.com/global/support/support_news/18091014/

https://forum.arduino.cc/index.php?topic=570440.0

https://support.serato.com/hc/en-us/articles/115001883474-macOS-High-Sierra-10-13-macOS-Mojave-10-14-and-above-driver-install-process

Hopefully one of these will help you.

Here is the link that my colleague followed:

https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver

All I can add is that this one worked for him. He has I have High Sierra (version 10.13.3) and needed to reboot after the installation.


message:
Getting "spikes" from an array of values - measure rpm using accelerometter

For a project where I intend to use an arduino and an accelerometer to get rpm of an diesel / gasoline engine i intend to use following solution.
I glued an mma8453 accelerometer to a neodium magnet which will be placed on a metallic part of the engine.
Using an arduino I am reading values from accelerometter and calculate one final value which is sqrt (acc.x^2 + acc.y^2 + acc.z^2), and also get millis for each value.
The values looks like this:

First column = millis, second acc value and third I identified maximums and millis since last maximum for them. Assuming that for an engine you have to max's per revolution I can calculate rpm of the engine.

My issue is that I have no idea how to write a function to do that.

Any help really appreciated

Thanks

    269503 310
    269504 303
    269506 334
    269507 326
    269509 331
    269510 330
    269512 380
    269513 377
    269514 392
    269516 400
    269517 339
    269519 393
    269520 368
    269521 353
    269523 346
    269524 316
    269527 330
    269528 281
    269530 196
    269531 195
    269532 162
    269534 119
    269535 140
    269537 132
    269538 90
    269539 99
    269541 122
    269542 168
    269544 224
    269545 219
    269546 211
    269548 268
    269549 301
    269551 334
    269552 332
    269554 316
    269555 329
    269556 379
    269558 363
    269559 381
    269561 388
    269562 403
    269564 400
    269565 420 49
    269566 388
    269569 360
    269570 346
    269572 259
    269573 276
    269574 284
    269576 242
    269577 207
    269579 192
    269580 145
    269582 119
    269583 113
    269584 45
    269586 125
    269587 142
    269589 123
    269590 205
    269591 243
    269593 304
    269594 308
    269596 305
    269597 298
    269599 321
    269600 340
    269601 360
    269603 380
    269604 384
    269606 370
    269607 372
    269608 413
    269611 441 46
    269612 395
    269614 355
    269615 332
    269617 290
    269618 317
    269619 286
    269621 227
    269622 190
    269624 172
    269625 199
    269627 146
    269628 154
    269629 177
    269631 176
    269632 156
    269634 136
    269635 174
    269636 212
    269638 260
    269639 318
    269641 291
    269642 321
    269644 304
    269645 315
    269646 343
    269648 339
    269649 360
    269651 393
    269652 390
    269654 305
    269656 405
    269657 458 46
    269659 358
    269660 372
    269662 339
    269663 277
    269664 298
    269666 241
    269667 203
    269669 208
    269670 185
    269672 130
    269673 165
    269674 105
    269676 87
    269677 109
    269679 128
    269680 176
    269681 229
    269683 226
    269684 271
    269686 343
    269687 307
    269688 320
    269690 318
    269691 322
    269693 322
    269694 369
    269697 363
    269698 413
    269699 399
    269701 388
    269702 426 45
    269704 395
    269705 380
    269707 342
    269708 311
    269709 309
    269711 315
    269712 221
    269714 227
    269715 198
    269716 113
    269718 111
    269719 88
    269721 44
    269722 69
    269723 107
    269725 158
    269726 200
    269728 232
    269729 247
    269731 313
    269732 338
    269733 348
    269735 366
    269736 339
    269739 348
    269740 377
    269741 378
    269743 385
    269744 394
    269746 403
    269747 447
    269749 454 47
    269750 398
    269751 380
    269753 302
    269754 245
    269756 299
    269757 310
    269758 238
    269760 206
    269761 180
    269763 108
    269764 81
    269766 83
    269767 11
    269768 119
    269770 106
    269771 169
    269773 245
    269774 270
    269775 311
    269777 338
    269778 341
    269780 332
    269782 337
    269783 337
    269785 380
    269786 387
    269788 382
    269789 373
    269791 398
    269792 414 43
    269793 408
    269795 387
    269796 374
    269798 285
    269799 290
    269801 326
    269802 266
    269803 211
    269805 221
    269806 191
    269808 120
    269809 175
    269810 63
    269812 147
    269813 59
    269815 120
    269816 183
    269817 196
    269819 252
    269820 301
    269822 334
    269824 325
    269826 334
    269827 310
    269828 351
    269830 354
    269831 358
    269833 373
    269834 379
    269835 332
    269837 386
    269838 404 46
    269840 383
    269841 385
    269843 332
    269844 266
    269845 301
    269847 282
    269848 188
    269850 199
    269851 182
    269852 128
    269854 163
    269855 119
    269857 120
    269858 140
    269860 120
    269861 129
    269862 212
    269864 230
    269865 241
    269868 290
    269869 304
    269871 340
    269872 350
    269873 327
    269875 323
    269876 351
    269878 369
    269879 387
    269880 379
    269882 380
    269883 421 45
    269885 373
    269886 364
    269888 360
    269889 305
    269890 302
    269892 266
    269893 249
    269895 202
    269896 229
    269897 136
    269899 122
    269900 128
    269902 49
    269903 98
    269904 107
    269906 158
    269907 211
    269910 235
    269911 225
    269913 269
    269914 314
    269915 341
    269917 335
    269918 325
    269920 348
    269921 410
    269923 375
    269924 404
    269925 419
    269927 425
    269928 442 45
    269930 436
    269931 400
    269932 393
    269934 326
    269935 259
    269937 307
    269938 265
    269940 220
    269941 199
    269942 183
    269944 86
    269945 83
    269947 98
    269948 23
    269949 65
    269952 124
    269953 152
    269955 221
    269956 249
    269957 287
    269959 350
    269960 331
    269962 323
    269963 341
    269964 338
    269966 389
    269967 388
    269969 380
    269970 370
    269972 358
    269973 415 45
    269974 403
    269976 377
    269977 381
    269979 338
    269980 328
    269982 284
    269983 246
    269984 197
    269986 178
    269987 230
    269989 162
    269990 171
    269991 141
    269993 258
    269995 138
    269997 111
    269998 163
    270000 212
    270001 192
    270002 304
    270004 287
    270005 294
    270007 349
    270008 309
    270009 334
    270011 332
    270012 364
    270014 361
    270015 408
    270017 336
    270018 421
    270019 432 46
    270021 361
    270022 361
    270024 342
    270025 271
    270027 288
    270028 310
    270029 235
    270031 218
    270032 166
    270034 136
    270035 146
    270036 102
    270039 78
    270040 99
    270042 122
    270043 105
    270044 181
    270046 222
    270047 293
    270049 299
    270050 299
    270052 318
    270053 349
    270054 344
    270056 349
    270057 382
    270059 381
    270060 412
    270062 380
    270063 397
    270064 425 45
    270066 381
    270067 367
    270069 332
    270070 272
    270071 291
    270073 296
    270074 178
    270076 177
    270077 190
    270080 123
    270081 146
    270082 107
    270084 85
    270085 108
    270087 117
    270088 148
    270089 234
    270091 223
    270092 238
    270094 283
    270095 301
    270097 332
    270098 331

body:
A simple approach would be to filter the signal using a low-pass filter, and then just calculate the time between two zero crossings.

Here's an example that works on your data. It's written in Python for easy testing and plotting, but trans-coding it to C++ should be trivial.

[![Plot of original data, filtered data using an EMA, and the calculated RPM][1]][1]

I used an [Exponential Moving Average low-pass filter](https://tttapa.github.io/Pages/Mathematics/Systems-and-Control-Theory/Digital-filters/Exponential Moving Average/Exponential-Moving-Average.html) to get rid of the noise. Depending on the frequencies involved, you can change the shift factor. The higher this factor, the lower the cut-off frequency, and the greater the phase shift.

I chose a fixed DC offset, but if necessary, you could use another (very slow) filter to get rid of it before applying the zero-cross detection.

If you want to, you could use both zero crossings. Use the average of the two last RPM measurements in that case, to compensate for asymmetric waveforms.

You could add another EMA to smooth out the RPM measurements.

```python
class ZeroCrossRPMCounter:
    def __init__(self,
                 max_rpm: float):
        self.min_distance = int(round(60_000 / max_rpm))

        self.first_crossing = True
        self.time_of_last_crossing = 0
        self.rpm = float('nan')
        self.previous_value = 0

    def __call__(self, time_ms: int, value: int):
        new_crossing = self.previous_value >= 0 and value < 0
        if new_crossing:
            if self.first_crossing:
                self.time_of_last_crossing = time_ms
                self.first_crossing = False
            elif (time_ms - self.time_of_last_crossing) >= self.min_distance:
                self.rpm = 60_000 / (time_ms - self.time_of_last_crossing)
                self.time_of_last_crossing = time_ms
            else:
                new_crossing = False
        self.previous_value = value
        return new_crossing

class EMA_shift_round:
    def __init__(self, shiftfac: int, initial: int = 0):
        self.shiftfac = shiftfac
        self.fixedPointOneHalf = 1 << (shiftfac - 1)
        self.z = initial << shiftfac

    def __call__(self, x: int):
        self.z += x
        shifted = (self.z + self.fixedPointOneHalf) >> self.shiftfac
        self.z -= shifted
        return shifted

if __name__ == '__main__':
    import numpy as np
    from matplotlib import pyplot as plt

    # Load the data
    data = np.genfromtxt('rpm-ctr-data.csv', delimiter='\t', dtype=np.int)
    time, signal = data[:, 0], data[:, 1]
    t_start, t_end = time[0] * 1e-3, time[-1] * 1e-3

    # Find the DC offset
    offset = int(round(np.mean(signal)))
    print(offset)

    # Initialize the filter and RPM counter
    lp_filter = EMA_shift_round(3)
    counter = ZeroCrossRPMCounter(2000)

    # Iterate over the data, filter it, and count the RPM
    peaks = []
    rpms = []
    filtered = np.zeros(len(time))
    for n in range(len(time)):
        filtered[n] = lp_filter(signal[n] - offset)
        new_crossing = counter(time[n], filtered[n])
        if new_crossing:
            peaks.append(time[n] * 1e-3)
            rpms.append(counter.rpm)

    # Plot the results
    plt.figure(figsize=(10, 6))
    plt.subplot(3, 1, 1)
    plt.title('Original signal')
    plt.plot(time * 1e-3, signal)
    for peak in peaks:
        plt.axvline(peak, color='red')
    plt.xlim((t_start, t_end))
    plt.subplot(3, 1, 2)
    plt.title('Filtered signal')
    plt.plot(time * 1e-3, filtered)
    for peak in peaks:
        plt.axvline(peak, color='red')
    plt.axhline(0, color='black', linestyle=':')
    plt.xlim((t_start, t_end))
    plt.subplot(3, 1, 3)
    plt.title('RPM measurements')
    plt.plot(peaks, rpms, '-o')
    plt.axhline(np.mean(rpms[1:]), color='red', linestyle=':')
    plt.xlim((t_start, t_end))
    plt.xlabel("Time [s]")
    plt.tight_layout()
    plt.show()
```

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


body:
I think most cars use a magnetic pickup next to the fly wheel to derive engine timing.  The method picked here is likely to have several problems.  For example, how to avoid picking up the shock of more than one cylinder compressing and exploding.  Or, perhaps the motor developed on is out of balance.  And a more nominal motor vibrates less making the project difficult to apply universally.

That said, using [FFTs (Fast Fourier Transforms)][1] is an alternative but fundamentally similar approach to detecting zero crossings for finding fundamental frequencies, and hence the engine's RPM.

This ["FFT on an Arduino"][2] article describes how to implement Fast Fourier Transforms on an Arduino.  It uses the FFT libraries hosted [here on github][3].

  [1]: https://en.wikipedia.org/wiki/Fast_Fourier_transform
  [2]: https://www.norwegiancreations.com/2017/08/what-is-fft-and-how-can-you-implement-it-on-an-arduino/
  [3]: https://github.com/kosme/arduinoFFT


body:
The approach suggested by tttapa is an excellent suggestion. But just to
give you more options, you can consider using an [hysteretic][] crossing
detector instead of a filter. The hysteresis in a comparator consists of
having one threshold value for detecting the high → low transition, and
another, higher value, for the low → high transition. This tends to
provide good immunity against noise, as noise spikes will not be able to
trigger false transitions as long as they are smaller than the
hysteresis (i.e. the difference between the thresholds).

Here is an example function that performs this detection. If you feed it
all your data samples, it will always return `false`, except exactly
_once_ per signal period.

```c++
const int LOW_THRESHOLD = 220;
const int HIGH_THRESHOLD = 300;

/* Returns true when a high threshold crossing is detected. */
void crossing_detector(int x)
{
    static enum { BELOW, ABOVE } state;
    if (state == BELOW && x >= HIGH_THRESHOLD) {
        state = ABOVE;
        return true;
    }
    if (state == ABOVE && x < LOW_THRESHOLD) {
        state = BELOW;
    }
    return false;
}
```

Now, it is perfectly possible to combine tttapa's filter idea with this
hysteretic crossing detector. The issue with the low pass filter is that
it is tricky to find the right time constant. If you filter too
aggressively, you may kill the signal at high RPMs. If you don't filter
enough, you may end up keeping enough noise to trigger false zero
crossings. If you use an hysteretic detector instead of a plain
zero-crossing detector, then you will be able to use less aggressive
filtering, as you will not be sensitive to the small residual noise.

[hysteretic]: https://en.wikipedia.org/wiki/Hysteresis


message:
Is this the right way of using an RF communication?

I have a [433Mhz Superheterodyne receiver][1] and a hand set remote of similar frequency, I'm using the [RC-Switch library][2] and I couldn't find a better way than using the "numbers" that I'm receiving like this:
<!-- language-all: lang-cpp -->

    #include <RCSwitch.h>

    RCSwitch mySwitch = RCSwitch();

    void setup() {
      Serial.begin(9600);
      mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
      pinMode(13, OUTPUT);
    }

    void loop() {
      if (mySwitch.getReceivedValue() == 7264305) {
        digitalWrite(13, LOW);
      }
      if (mySwitch.getReceivedValue() == 7264308) {
        digitalWrite(13, HIGH);
      }
      if (mySwitch.getReceivedValue() == 7264306) {
        mySwitch.resetAvailable();
      }
    }

Is there any other (better?) way than just using the "numbers" simply like that or everyone are using their remote commands like I'm using?

  [1]: https://www.aliexpress.com/item/Wholesale-433-Mhz-Superheterodyne-RF-Receiver-and-Transmitter-Module-ASK-kits-with-antenna-For-Arduino-Diy/32799575156.html
  [2]: https://github.com/sui77/rc-switch

body:
Credits for this answer are mainly for jsotola (see his remarks above). But I want to show an alternative to the `if` statements, and a way to get the last 4 bits:

1. In case you want to check for the least significant bits, use `((mySwitch.getReceivedValue() & 0xFFFFF0)`
2. TO check for the least significant four bits (the data you want to act upon), use `((mySwitch.getReceivedValue() & 0xF)`
3. Use a switch statement instead of the `if` statement; also in theory (I don't know the code of `mySwitch.getReceivedValue()` does not need to be executed multiple times.

So you get something like this:

    void loop()
    {
      unsigned long receivedValue = mySwitch.getReceivedValue(); // Call function only once

      if ((receivedValue & 0xFFFF0) == 0x6ED830)
      {
        // Process action
        switch (receivedValue & 0xF)
        {
        case 0x5:
          digitalWrite(13, LOW);
          break;

        case 0x8:
          digitalWrite(13, HIGH);
          break;

        case 0x6:
          mySwitch.resetAvailable();
          break;

        default: // All other values
          break; // Ignore
      }
    }


message:
What is the best delay to use between characters sent to the serial port

I have an Arduino Uno. It's role is to echo back what it receives.
But if I send it a stream of ascii characters it starts to error after the first one. Occasionally it gets the second character correct but often not.

If I delay each character then it works ok. I couldn't see this limitation mentioned in the SoftwareSerial library: https://www.arduino.cc/en/Reference/SoftwareSerial

The Arduino is running the following code:
<!-- language-all: lang-cpp -->

    #define BT_RX_PIN 16 // A2
    #define BT_TX_PIN 17 // A3
    #include <SoftwareSerial.h>
    SoftwareSerial OtherSerial(BT_RX_PIN, BT_TX_PIN);

    void setup()
    {
      Serial.begin(9600);  // not used
      OtherSerial.begin(9600);
    }

    void loop()
    {
      if (OtherSerial.available()) {
        char value = OtherSerial.read();
        String stri = "Received: ";
        stri += value;
        OtherSerial.println(stri);
      }
    }

The limitations do say "If using multiple software serial ports, only one can receive data at a time.".  I don't have multiple software serial ports though I do have an instance of the "normal" serial port but I'm not sending any data to it... but perhaps even just initialising it is enough to disrupt seamless communication with the SoftwareSerial port?

Using the following test code for serial communication from a Raspberry Pi (using logic level conversion to go from 5V -> 3.3V and visa versa):

    import time

    def write(msg, delay):
      for char in msg:
        with open("/dev/ttyAMA0", "w") as f:
          f.write(char)
          time.sleep(delay)

    write("hello", 0.01)

I got the following results (repeated 10 times at each delay time and averaged):

    Delay (ms)   |   Success rate
    10           |   100 %
    9            |   100 %
    8            |     0 %
    5            |     0 %
    1            |     0 %

A delay of 9 ms between each character means the communication rate falls from ~ 960 characters per second (9600 baud / 10 bits per 7 bit character) to ~ 100 characters per second (1 / (1 / 960 characters per second + 9ms)).  Is this right?  Perhaps I'm doing something else wrong / set it up wrong in software / hardware?

body:
SoftwareSerial has a considerable overhead. It can often send at 115200 successfully but 9600 is about its limit for receiving, and you're trying both send and receive. In addition, for each character your code receives, it transmits considerably more than that 1 character (11 characters, by my count). It isn't too surprising that it would fall behind. You will need to either reduce the size of what you echo or reduce the rate at which you send characters to it (which is what you accomplished with your delay) so that the transmission (echo) rate can keep up.

Update:

The OP reports success with continuous reception by, and transmission from, the Arduino at 57600 baud (but not at the same time). The transmission rate would be consistent with my experience transmitting at 115200 baud (blindly and for short bursts, to reconfigure ESP8266-01s that were shipped with a preset 115200 rate.


body:
Simply put, a serial port implemented in software requires the program to sample the input pin fast enough to detect every transition.  To satisfy the [Nyquist frequency rate][1] we need the program to sample the data twice as fast as we expect the data to change.

A serial port implemented in hardware might only need to be sampled at 1/16 this rate assuming the data size is 8 bits.

Your program implements a serial port in software which is admirably keeping up with the received data.  However, when you tell the program to send the message "Received" plus the string that was received, the program stops looking at the serial input pin long enough for data to go missing.

By far the easiest solution would be to use a hardware implemented serial port.  If this is not possible consider approaching the problem using interrupts.  However, while a powerful programming tool, interrupts can be difficult to implement and hard to debug.

  [1]: https://en.wikipedia.org/wiki/Nyquist_frequency


message:
Parsing Arduino Receiving Strings

I'm currently using google geolocation to get location data to one nodemcu and sending it through serial to another Arduino.
The serial command I'm getting right now is,
<!-- language-all: lang-cpp -->

    1.450187T103.824745

I'm using the following code to parse it.

     if (Serial.available())  {
        char c = Serial.read();  //gets one byte from serial buffer
        //if (c == '\n') {  //looks for end of data packet marker
        if (c == '\n') {
         // Serial.println(readString); //prints string to serial port out
          //do stuff
          substring = readString.substring(0,8);
          lati = substring;
          loc = readString.indexOf("T");
          substring = readString.substring(loc+1, loc+11);
         longi = substring;
           readString=""; //clears variable for new input
          substring="";

        }
        else {
          readString += c; //makes the string readString
        }
      }

It works most of the time but sometimes I get 'T' inside the string as well.
like this

    lat=1.450146&longi=102464T103
What's wrong in my code?

body:
You could use a `for` loop to get the location of the "T", then split the `String` into 2 `Strings`.
<!-- language-all: lang-cpp -->

    // 4104 bytes.
    String readString = "1.450187T103.824745";
    String lati, longi;

    void setup(){

      Serial.begin(9600);

      //do stuff code
      for(int i = 0; i < readString.length(); i++){
        if(readString.charAt(i) == 'T'){
          lati = readString.substring(0, i);
          longi = readString.substring(i + 1);
          break;
        }
      }

      Serial.print("lati=");
      Serial.println(lati);
      Serial.print("longi=");
      Serial.println(longi);

    }

    void loop(){}


body:
with readBytesUntil and C string

    if (Serial.available()) {
      char buff[32];
      int l = Serial.readBytesUntil('\n', buff, sizeof(buff));
      if (l > 0 && buff[l - 1] == '\r') {
        l--; // to remove \r if it is there
      }
      buff[l] = 0; // terminate the string
      char* p = strchr(buff,'T'); // returns pointer in string
      if (p != NULL) {
        *p = 0; // write 0 as char at pointer to terminate the first part
        p++; // move the pointer to next char
        Serial.println(buff);
        Serial.println(p);
      } else {
        Serial.println(buff);
      }
    }


message:
Using 8bit ports as 8bit I/O variable (while using USB,I2C, SPI and Serial) - keyboard

**I am seeking HW.**

I would like to make keyboard with enhanced functions (RGB backlite, macros, programmed profiles etc) driven by some small MCU (Arduino Micro Pro or something similar).

To support communication, it needs to use **I2C** and **SPI**(for display and other devices), use **USB** (to communicate with PC) and use **Serial** to communicate with other Arduinos/MCUs.

The main function would be scanning keyboard matrix (like from 8x8 to 16x8 in maximal variant). The matrix would use diodes for NKRO (not ghosting, any key combination possible).

It would be really nice to have HW, where I could use 3 full ports as input (or as output) with benefit of reading/writing them with only one assembly instruction for 8bit manipulation, not to cycle over array of pins and manipulate each one independently (digitalRead/digitalWrite, which use tons of instructions to determine ports and pin and then combine them together to obtain one 8bit variable). Something like:

    byte dataout,datain1,datain2;
    PORT_A=dataout;
    datain1=PORT_B;
    datain2=PORT_C;

**Does anyone know, if there is such nonexpensive MCU and which type it is?**

On typical Arduino each port is "poluted" by some importaint communications pins, so none of them can be used as full 8bit I/O.

**Second question: Is there a reason, why are the most used communication pins spread over range of different ports and not collected on one port, while leaving other ports as full 8bit GPIO useable?**

Thank for all answers.

body:
The expander MCP23S17 (spi), with a CS, is a good extention (16 I/O configurable)
That should do it !


body: I'd go with a Mega2560. Up to 86 IO if you use a board that breaks out all IO pins, otherwise 70 on the Arduino version. With a little attention to the physical chip pin mapping to the board you can have several full 8-bit ports while also using SPI, I2C, and Serial via one of 4 UARTs. I'd recommend keeping Tx(0)/Rx(0) free for comm's with PC via USB adapter for code download/debug. Tx1/Rx1, Tx2/Rx2, Tx3/Rx3 are them free for 0/5V level comm's, or other levels via USB adapter, RS232 adapter, etc.


message:
esp32 cam and PIR sensor

I have tried all the GPIO pins listed here:[![This is a schematic of the ESP32 cam pinouts. I have tried every one of the GPIO pins with errors in initializing the SD Card][1]][1]I am following this tutorial to save a picture using the ESP32 cam board. I am trying to add a PIR sensor.
https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card/

whenever I try to use any pins to enable wake on external pin high, there is an error either because of interruption with the camera initiation or sd card.

here is my PIR sensor
https://www.robotshop.com/en/wide-angle-pir-motion-sensor.html?gclid=EAIaIQobChMI0Y7QuaOA4wIVl_5kCh3zYA4OEAQYASABEgJFPvD_BwE[![PIR sensor schematic][2]][2]
here is the code I am using

        /*********
          Rui Santos
          Complete project details at https://RandomNerdTutorials.com/esp32-cam-    take-photo-save-microsd-card

          IMPORTANT!!!
           - Select Board "ESP32 Wrover Module"
          - Select the Partion Scheme "Huge APP (3MB No OTA)
        - GPIO 0 must be connected to GND to upload a sketch
        - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET  button to put your board in flashing mode

       Permission is hereby granted, free of charge, to any person obtaining a copy
      of this software and associated documentation files.
      The above copyright notice and this permission notice shall be included in all
      copies or substantial portions of the Software.
    *********/

     #include "esp_camera.h"
     #include "esp_timer.h"
     #include "img_converters.h"
     #include "Arduino.h"
     #include "fb_gfx.h"
     #include "fd_forward.h"
     #include "fr_forward.h"
     #include "FS.h"                // SD Card ESP32
     #include "SD_MMC.h"            // SD Card ESP32
     #include "soc/soc.h"           // Disable brownour problems
     #include "soc/rtc_cntl_reg.h"  // Disable brownour problems
     #include "dl_lib.h"
     #include "driver/rtc_io.h"
     #include <EEPROM.h>            // read and write from flash memory

        // define the number of bytes you want to access
         #define EEPROM_SIZE 1

         // Pin definition for CAMERA_MODEL_AI_THINKER
         #define PWDN_GPIO_NUM     32
         #define RESET_GPIO_NUM    -1
         #define XCLK_GPIO_NUM      0
         #define SIOD_GPIO_NUM     26
         #define SIOC_GPIO_NUM     27

         #define Y9_GPIO_NUM       35
         #define Y8_GPIO_NUM       34
         #define Y7_GPIO_NUM       39
         #define Y6_GPIO_NUM       36
         #define Y5_GPIO_NUM       21
         #define Y4_GPIO_NUM       19
         #define Y3_GPIO_NUM       18
         #define Y2_GPIO_NUM        5
         #define VSYNC_GPIO_NUM    25
         #define HREF_GPIO_NUM     23
         #define PCLK_GPIO_NUM     22

         int pictureNumber = 0;

         void setup() {
           WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

           Serial.begin(115200);
           //Serial.setDebugOutput(true);
           //Serial.println();

           camera_config_t config;
           config.ledc_channel = LEDC_CHANNEL_0;
           config.ledc_timer = LEDC_TIMER_0;
           config.pin_d0 = Y2_GPIO_NUM;
           config.pin_d1 = Y3_GPIO_NUM;
           config.pin_d2 = Y4_GPIO_NUM;
           config.pin_d3 = Y5_GPIO_NUM;
           config.pin_d4 = Y6_GPIO_NUM;
           config.pin_d5 = Y7_GPIO_NUM;
           config.pin_d6 = Y8_GPIO_NUM;
           config.pin_d7 = Y9_GPIO_NUM;
           config.pin_xclk = XCLK_GPIO_NUM;
           config.pin_pclk = PCLK_GPIO_NUM;
           config.pin_vsync = VSYNC_GPIO_NUM;
           config.pin_href = HREF_GPIO_NUM;
           config.pin_sscb_sda = SIOD_GPIO_NUM;
           config.pin_sscb_scl = SIOC_GPIO_NUM;
           config.pin_pwdn = PWDN_GPIO_NUM;
           config.pin_reset = RESET_GPIO_NUM;
           config.xclk_freq_hz = 20000000;
           config.pixel_format = PIXFORMAT_JPEG;

           if(psramFound()){
             config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ +  QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
            config.jpeg_quality = 10;
            config.fb_count = 2;
          } else {
            config.frame_size = FRAMESIZE_SVGA;
            config.jpeg_quality = 12;
            config.fb_count = 1;
          }

          // Init Camera
          esp_err_t err = esp_camera_init(&config);
          if (err != ESP_OK) {
            Serial.printf("Camera init failed with error 0x%x", err);
            return;
          }

          //Serial.println("Starting SD Card");
          if(!SD_MMC.begin()){
            Serial.println("SD Card Mount Failed");
            return;
          }

          uint8_t cardType = SD_MMC.cardType();
          if(cardType == CARD_NONE){
            Serial.println("No SD Card attached");
            return;
          }

          camera_fb_t * fb = NULL;

          // Take Picture with Camera
          fb = esp_camera_fb_get();
          if(!fb) {
            Serial.println("Camera capture failed");
            return;
          }
          // initialize EEPROM with predefined size
          EEPROM.begin(EEPROM_SIZE);
          pictureNumber = EEPROM.read(0) + 1;

          // Path where new picture will be saved in SD Card
          String path = "/picture" + String(pictureNumber) +".jpg";

          fs::FS &fs = SD_MMC;
          Serial.printf("Picture file name: %s\n", path.c_str());

          File file = fs.open(path.c_str(), FILE_WRITE);
          if(!file){
            Serial.println("Failed to open file in writing mode");
          }
          else {
            file.write(fb->buf, fb->len); // payload (image), payload length
            Serial.printf("Saved file to path: %s\n", path.c_str());
            EEPROM.write(0, pictureNumber);
            EEPROM.commit();
          }
          file.close();

          // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
          pinMode(4, OUTPUT);
          digitalWrite(4, LOW);
          rtc_gpio_hold_en(GPIO_NUM_4);

          delay(2000);
          Serial.println("Going to sleep now");
          delay(2000);
          esp_deep_sleep_start();
          Serial.println("This will never be printed");
        }

        void loop() {

        }

This is the thing I am trying to add. but no matter which pins i chose there are errors. I can add the error if that would be helpful.

    esp_sleep_enable_ext0_wakeup(GPIO_NUM_X, level)

  [1]: https://i.stack.imgur.com/ksS4E.png
  [2]: https://i.stack.imgur.com/FRWs1.png

body:
Software:

It may be that one of the included libraries (software) you are using depends on pin 3 (E32_RST) of the ESP32 going low in order to operate as expected (wake up and take a picture).  Using an alternate pin may wake up the ESP32 but may not behave as expected.

Hardware:

[This schematic of the ESP32 Camera][1] shows how switch K1 is connected to pin 3 of the ESP32.  There is a capacitor C7 and resistor R6 likely used to mitigate K1 switch bouncing and to pull pin 3 high when switch K1 is not pressed.  When switch K1 is pushed it pulls pin 3 to ground waking up the ESP32 to take a picture.

The PIR specified changes its output to high when activated according to its data sheet.  This is opposite of what the ESP32 needs to see at pin 3 in order to take a picture.  It appears an inverter is needed between the PIR and pin 3 of the ESP32.  An open collector type of inverter would be best as this type of driving circuit can be attached where K1, C7 & R6 come together with out interfering with the their (the existing components') operation.  This is the subject of [this stackexchange question / answer][2].

  [1]: https://i.redd.it/yv050peu22p21.png
  [2]: https://electronics.stackexchange.com/questions/30238/how-to-invert-a-digital-signal


message:
class enum was not declared in this scope

I am programming an Arduino.  In the same .ino file as `setup()` and `loop()` I have defined the following:

    void setup()
    {
      // setup code
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void loop()
    {
      // loop code
    }

But on compiling it gives the error:

    sketch_v1:37:22: error: 'CYCLE' was not declared in this scope
     String cycleToString (CYCLE cycle) {
                          ^
    /Users/.../sketch_v1.ino: In function 'String cycleToString(CYCLE)':
    sketch_v1:37:31: error: 'String cycleToString(CYCLE)' redeclared as different kind of symbol
     String cycleToString (CYCLE cycle) {
                                      ^
    /Users/.../sketch_v1.ino:37:8: note: previous declaration 'String cycleToString'
     String cycleToString (CYCLE cycle) {
            ^

Note that the `enum class` is fine and works as intended but if I try to add the function relying on the `CYCLE` type it then errors.

body:
Note this is not an answer, since your code compiles perfectly. (adding a default/empty setup/loop function).

However, I want to give some improvements that cannot fit in a comment:

1. (optional) Align { and } under each other. Some put the { behind the line, some on a new line; this is mostly preference. But aligning { and } is mostly more clear.
2. Put each type/enum value on a new line; this makes it easier to add comments above/after it.
3. Except for trivial cases, never return from a statement, except the last one. In your case the function is quite simple, but still it's better to keep the return only at the end of a function.
4. Use a `switch` statement instead of multiple `if` statements.

So you get:

    enum class CYCLE
    {
      TypeA,
      TypeB
    };

    String cycleToString (CYCLE cycle)
    {
      String str;

      switch (cycle)
      {
      case CYCLE::TypeA:
        str = "TypeA";
        break;

      case CYCLE::TypeB:
        str = "TypeB";
        break;

      default:
        str = "Undefined";
        break;
      }

      return str;
    }


body:
This is a known bug of Arduino builder, if you have functions before structs, classes or enums in sketch.

The sketch:

    void foo() {
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void setup() {
    }

    void loop() {
    }

is processed to this .cpp file

    #include <Arduino.h>
    #line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    #line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"

    #line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void foo();
    #line 7 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    String cycleToString(CYCLE cycle);
    #line 17 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void setup();
    #line 22 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void loop();
    #line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
    void foo() {
    }

    enum class CYCLE { TypeA, TypeB };

    String cycleToString (CYCLE cycle) {
      if (cycle == CYCLE::TypeA) {
        return "TypeA";
      }
      else if (cycle == CYCLE::TypeB) {
        return "TypeB";
      }
      return "Undefined";
    }

    void setup() {
    }

    void loop() {
    }

as you can see the forward declarations of functions are before the first function so before the enum.

The workaround for this bug is to follow good practice and declare all the structs, enums and classes before the first function definition.


message:
Sim800L Uploading issues, HTTPACTION returns 0, 302, 701

I'm using the Sim800L module and the NEO6M GPS Module in combination with an Arduino nano to create a simple tracking device. I get the data from the GPS and try to upload it to my site with some simple PHP scripts. I'm using this code down here:
<!-- language-all: lang-cpp -->

    //the function - which is responsible for sending data to the web server
    void sendLocation(String lat, String lon){
     Sim800l.listen();
     //The line below sets the URL we want to connect to
     Sim800l.println("AT+HTTPPARA=\"URL\", \"http://" + ipAddress +  "/log_info.php?dev_id=13&lat=" + lat + "&lon=" + lon + "\"");
     waitUntilResponse("OK");
     //GO
     Sim800l.println("AT+HTTPACTION=0");
     waitUntilResponse("200");
     Serial.println("Location sent");
     gpsPort.listen();
    }

Unfortunately, when I try to use this code, in my serial monitor I get this message:

    AT+HTTPACTION=0
    OK
    +HTTPACTION: 0,302,171
    error

I Looked it up in the datasheet for the Sim800L, and the number 302 means "Found". I'm expecting the number 200 for "OK". I have no idea what I did wrong, the data is not being send to the web server for some reason. I hope you can help.
Thanks in advance!

EDIT:
The datasheet with all the errors for the Sim800L
https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf

body: 302 is HTTP code returned by the server. It is used for redirection. Print the response with AT+HTTPREAD to see where does it redirectd.


message:
PWM delay without blocking the code

I want my LED to turn on gradually without using the `delay()` function and blocking the code.

Here's the code i came up with:

    int led_pin = 6;
    unsigned long millisTimer = 0;
    int PWMdelay = 5000;
    int condition = 0;
    int i = 0;
    void setup() {
     pinMode(led_pin, OUTPUT);
    }
    void loop() {
     if(condition == 1){
     if ((millis() - millisTimer) > PWMdelay){
      if(i<255){
       i++;
       millisTimer = millis();
      }

     }
      analogWrite(led_pin, i);
     }
    }

Is this the "right way" of slowing the PMW duration from 0 to 255 or there are alternative/better/easier ways?

body:
Here is my take at this - I've followed the example code mentioned by other members and here is "FadeWithoutDelay"

```Arduino

const int ledPin = 11;
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 100;               // fade interval (milliseconds)
int brightness = 0;                      // how bright the LED is
int fadeAmount = 5;                      // how many points to fade the LED by

void setup()
{
  pinMode(ledPin, OUTPUT);  // set the digital pin as output:
}
void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;         // save the last state
    analogWrite(ledPin, brightness);        // Set the brightness
    brightness = brightness + fadeAmount;   // change the brightness for next time through the loop
    // reverse the direction of the fading at the ends of the fade:
    if (brightness <= 0 || brightness >= 255)
    {
      fadeAmount = -fadeAmount;
    }
  }
}

```


message:
Millis() does not back to zero after woke up from deep sleep mode

I am going to make a project that needs four boards of Arduino which synchronization in time is needed. The project is about capturing the timestamp (in ms resolution) whenever something is crossing ultrasonic proximity sensor. The following are the modules I am going to use:

 1. Arduino Uno R3 4 units
 2. Ultrasonic Proximity sensor 4 units
 3. DS1302 RTC modules 4 units
 4. Micro SD Card modules 4 units

The boards will be placed in 4 different places which it is quite far from each other that makes it is hard to make wired connection. The detecting object will move back and forth during a certain interval of time, so that is why the time synchronization is needed.

My idea is, by using the timestamp from RTC modules, I turn all the boards together into deep sleep mode at the time I have set in the code and wake them up together after 10 seconds. I don't have any problem with RTC modules, but my problem lies in the millis() function which did not back to zero after woke up from deep sleep mode. I need this function since the DS1302 RTC does not provide ms resolution, yet I can not achieve sync if the millis() function does not back to zero.

I tried the code (edited with millis() added in the loop) from here:
https://www.youtube.com/watch?v=8fiYvnBDsDE

Do you have any solutions? Or another RTC module which provides ms resolution instead. Thank you

body: Store millis() at boot, and if (resetCause == "Deep-Sleep Wake") zero out the stored copy of millis().


body: I do not understand how you will get them to sync with each other. The RTC modules work great but there is no communications to set or update them and they do drift. With the RTC it will be easy to generate a timestamp using Unix time. There is a lot of information posted on how to do this.  syncing (making all the clocks the same) is where I believe your problem is. Consider adding WiFi to each and use NTP to sync everything, it would be automatic.


message:
Can I use the PWM pins as regular digital input/output pins?

In regards to the arduino which has pwm pins, can I use these pins as normal input/output digital pins or not? Thanks in advance.

body:
Yes you can use them as ordinary digital io pins. PWM is essentially a normal digital output pin that is repeatedly turned on and off at a high rate.

The magic is that the turning off and on is done in the hardware according to the duty cycle  (I.e. there is no need for software to perform the on/off operations) . This is why only some pins can do h/w PWM, because the PWM hardware is not added on to all pins.

If you are not using the pin for PWM, it is available for you to use as required.