message:
Mega 2560 does not play audio file when I want. It plays when the first condition is met, but not the other

<!-- language-all: lang-arduino -->

Okay, so I am making a jewelry box for my niece that will spin a necklace holder with a stepper motor, play an audio file and turn on LED lights. I am using an Arduino MEGA 2560.

The flow is this:

1. **ringDoor open and necklaceDoor closed:** LED on, stepper spin, audio plays.
1. **ringDoor closed and necklaceDoor open:** LED on and audio plays, no stepper
motor.
1. **Both doors closed:** Everything off or off after delay.
1. **Both doors open:** LED on and music plays, no stepper motor.

My issue is that with the doorLatch open, the audio plays as it should. No issues, but if I only open doorLatch2, no audio plays. If I open doorLatch and then doorLatch2, audio will play. If I open in reverse, no audio will play. I have tried adding an `if` statement by itself with an "or" in the loop section to check for either door open and I cannot put it in the setup section because that just continuously plays with latches open or closed. I currently have it to where music plays with doorLatch open. The extremely strange portion to me is that if I put the tmrpcm.play in the first else statement, the audio will play after opening and closing doorLatch2.

So what I would like is for audio to play and loop as long as either door is open. PLEASE HELP! WHAT AM I DOING WRONG?!?!?!?!?!

Code:

    #include <SD.h>
    #include <TMRpcm.h>
    TMRpcm tmrpcm;

    #include <Stepper.h>
    const int stepsPerRevolution = 2048;
    const int doorLatch=2;   //Ring door
    const int doorLatch2=6;  //Necklace door
    const int relayPower=13; //Turn relay on

    Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

    void setup() {
      Serial.begin(9600);
      Serial.print("\nInitializing SD card...");

      // set this to your card type and cs pin
      if (!SD.begin(53)) {
        Serial.println("failed!");
        return;
      }
      Serial.println("done.");

      tmrpcm.speakerPin = 46;

      myStepper.setSpeed(5);
      pinMode(doorLatch,INPUT);
      pinMode(doorLatch2,INPUT);
      pinMode(relayPower,OUTPUT);
      digitalWrite(doorLatch,HIGH);
      digitalWrite(doorLatch2,HIGH);

    }

    void loop() {

      if ((digitalRead(doorLatch)==HIGH)&&(digitalRead(doorLatch2)==HIGH)) {
        //ring door and necklace door is closed
        digitalWrite(relayPower,LOW);

      }
      else {
        //ring door is open, lights on, stepper motor spinning, music playing
        digitalWrite(relayPower,HIGH);

      }

      if ((digitalRead(doorLatch2)==HIGH)&&(digitalRead(doorLatch)==LOW)) {
        //ring door open and necklace door closed

        digitalWrite(relayPower,HIGH);

        myStepper.step(stepsPerRevolution);
        delay(500);
        myStepper.step(-stepsPerRevolution);
        delay(500);

      }
      else {
        tmrpcm.play("music.wav");
      }
    }
****NEW CODE, NEW PROBLEM, but closer******Updated names and notes for easier following*****
New problem is if I open the necklaceDoor first, nothing happens. I have to open the ringDoor first. That turns everything on. Then with the necklaceDoor open, the stepper motor will turn off and the lights and music will continue to play. But I want to be able to open the necklaceDoor first and play the music with the lights. I do not want it to matter which one is opened first. I also realized that if I can get an or statement to work within an and statement I could do away with the fourth if statement completely. Both ringDoor open and necklaceDoor open, as well as ringDoor closed and necklaceDoor open have the same outcome.
Now if I switch the door states in the third if statement, I get necklaceDoor only plays audio after closed(original problem) but if both doors are open and then ringDoor is closed, the music will shut off after the stepper timer is done and then start again after necklaceDoor is closed?!?!?!?

    #include <SD.h>
    #include <TMRpcm.h>
    #include <Stepper.h>
    TMRpcm tmrpcm;

    const int stepsPerRevolution = 2048;   //Number of pulses per revolution
    const int ringDoor=2;                  //Ring door
    const int necklaceDoor=7;              //Necklace door
    const int relayPower=22;               //Turn relay on

    Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

    void setup() {
      Serial.begin(9600);                         //Start connection with computer

      if (!SD.begin(53))                         //Chip pin on card
      {
        Serial.println("failed!");                //SD card did not read
        return;
      }

      tmrpcm.speakerPin = 46;                      //Speaker output pin
      myStepper.setSpeed(5);                       //Stepper speed
      pinMode(ringDoor,INPUT);                     //Check state of ring door magnetic switch, NO
      pinMode(necklaceDoor,INPUT);                 //Check state of necklace door magnetic switch, NO
      pinMode(relayPower,OUTPUT);                  //Relay enable for 12V LED
      digitalWrite(ringDoor,HIGH);                 //Make door closed read high on start up
      digitalWrite(necklaceDoor,HIGH);             //Make door closed read high on start up
      digitalWrite(relayPower,LOW);                //Make relay off on start up
    }

    void loop() {

      if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==HIGH))
      {                                                                                //ring door and necklace door is closed, everything is off
        digitalWrite(relayPower,LOW);
      }

      if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH))
      {                                                                                //ring door is open and necklace door is closed, lights on, stepper motor spinning, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
        myStepper.step(stepsPerRevolution);
        delay(500);
        myStepper.step(-stepsPerRevolution);
        delay(500);
      }

      if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==LOW))
      {                                                                                //ring door closed and necklace door open, lights on, stepper motor off, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
      }

      if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==LOW))
      {                                                                                //ring door and necklace door open, lights on, stepper motor off, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
      }
    }

*****Please and thank you to any and all who help. It is greatly appreciated*****

body:
Your code doesn't match your desired output. You say you want to:

    doorLatch open and doorLatch2 closed: LED on, stepper spin, audio plays.
    doorLatch closed and doorLatch2: LED on and audio plays, no stepper motor.
    Both latches closed: Everything off or off after delay.
    Both latches open: LED on and music plays, no stepper motor.

Note that both latches open and and doorLatch closed  DoorLatch2 open result in the same state: LED on and audio plays, no stepper motor.

Your code says

    if doorLatch & doorLatch2 are both closed (high)

        relayPower = low (off)

    else

        relayPower = HIGH (on). This in ALL cases other than both latches HIGH

Next, a second if statement:

    if doorLatch2 == HIGH && doorLatch == LOW
         relayPower = HIGH (on)
         step motor back and forth
    else
         play sound

So you play the sound if doorlatch2 is low or doorLatch is high

You turn off the relay if doorLatch & doorLatch2 are both closed (high)

You turn on the relay if doorLatch is low or doorlatch2 is low.

    void loop() {
       int latchState digitalRead(doorLatch);
       int latch2state = digitalRead(doorLatch2);
       if (latchState = LOW && latch2Sate == HIGH) {        //0 - 1
          //turn on led
          //spin stepper
          //play audio
       } else if (latchState = HIGH && latch2Sate == LOW) { //1 - 0
          //Turn LED on
          //play audio
          //turn off stepper
       } else if (latchState = HIGH && latch2Sate == HIGH) {//1 - 1
         //turn everything off (after delay?)
       } else if (latchState = LOW && latch2Sate == LOW {   //0 - 0
         //LED on
         //play music
         //turn off stepper
       }
    }


sender: user

message:
Uno - ESP32 SoftwareSerial communication won't work

I have two boards, Uno and ESP32 and my goal is to send data from the Uno to the ESP. I made a voltage divider so my ESP doesn't get fried and I use the communication only in **ONE** way, strictly UNO -> ESP32. I use PIN 9 from my UNO to send data and RX2 (16) from my ESP to receive the data. How ever, I get errors and can't make it work.

This is my Uno code:

    #include <SoftwareSerial.h>

    SoftwareSerial softPort(-1, 9);

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

    void loop() {
    softPort.print("100");
    delay(2000);

    }

and my ESP code:

    #include <SoftwareSerial.h>

    #define RXD2 16
    #define TXD2 -1

    SoftwareSerial Serial2(RXD2, TXD2); // RX, TX

    void setup() {
    Serial.begin(115200);
    Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);

    }

    void loop() {
    Serial.println("Data received:");
    Serial.println(Serial2.read());
    delay(200);

    }
I'm getting an error that says

> no matching function for call to 'SoftwareSerial::begin(int, int, int, int)'

sender: assistant

body:
On the ESP32 you would *never* use SoftwareSerial except under *exceptional* circumstances.

The ESP32 has three hardware UARTs that can be mapped to *any* pin combination on the board.

The general usage is:

```
HardwareSerial Serial2(1); // Use UART channel 1

void setup() {
    Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}
```

UARTs are numbered 0-2 where 0 is pre-assigned to the TX/RX (USB connection) pins and is used for debugging and programming.  UARTs 1 and 2 are not normally assigned to anywhere and you can use them as you see fit.


message:
How to properly put a u8g2 handle in a class

I'm trying to create a small battery powered alarm clock using an Arduino MKRZero and a generic SH1106-controlled, 128x64 pixel oled.

I started out just dumping all code into a single file named `Clock.ino`. As the code got bigger, I started to split out functionality into separate classes. This went fine for timekeeping and alarms, but when I tried to do the same for the display functionality, I ran into an issue.

Now I wanted to split out my display code into a separate class. The working code before the refactor looks a bit like this:

`Clock.ino`
-----------
```c++
//Display stuff
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8x8.begin();
}

void print_clock([...]) {
  [...]
  u8x8.setCursor(0,3);
  u8x8.print("23:59:59");
  [...]
}

void loop(void) {
  [...]

  // Main clock
  print_clock(clk.datetime);

  [...]
}
```

I tried to split it out like this:

`Clock.ino`
-----------
```c++
#include "Display.h"

Display disp;

void setup(void) {}

void loop(void) {
  [...]

  // Main clock
  disp.print_clock([...]);

  [...]
}
```

`Display.cpp`
-------------
```c++
#include "Display.h"

Display::Display() {
  this->u8x8.begin();
}

void Display::print_clock([...]) {
  [...]
  this->u8x8.setCursor(0,3);
  this->u8x8.print("23:59:59");
  [...]
}
```

`Display.h`
-----------
```C++
//Display stuff
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

class Display {
  public:
    Display();
    void print_clock([...]);
  private:
    U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
}
```

That didn't work, gave me a whole list of errors, all similar to these:

```
  5 In file included from /home/simon/Arduino/libraries/U8g2/src/U8x8lib.h:45:0,
  6                  from sketch/Display.h:9,
  7                  from sketch/Display.cpp:1:
  8 /home/simon/Arduino/libraries/U8g2/src/clib/u8x8.h:323:23: error: expected identifier before numeric c    \>onstant
  9  #define U8X8_PIN_NONE 255
 10                        ^
 11 sketch/Display.h:26:55: note: in expansion of macro 'U8X8_PIN_NONE'
 12      U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
 13                                                        ^~~~~~~~~~~~~
 14 /home/simon/Arduino/libraries/U8g2/src/clib/u8x8.h:323:23: error: expected ',' or '...' before numeric    \> constant
 15  #define U8X8_PIN_NONE 255
 16                        ^
 17 sketch/Display.h:26:55: note: in expansion of macro 'U8X8_PIN_NONE'
 18      U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
 19                                                        ^~~~~~~~~~~~~
 20 sketch/Display.cpp: In constructor 'Display::Display()':
 21 Display.cpp:8:9: error: invalid use of member function 'U8X8_SH1106_128X64_NONAME_HW_I2C Display::u8x8    \>(int)' (did you forget the '()' ?)
 22    this->u8x8.begin();
 23    ~~~~~~^~~~
```

So I tried rewriting it in such a way that the `u8xu` var is global like it was before, defining it in `Display.cpp` and getting rid of the `this->` before the `u8x8.` method calls in the `Display::` methods. That didn't work either. It compiles, but my display stays blank and the arduino gets stuck (does not interface with serial anymore until I hard-reset it).

At some point I rewrote the code such that I passes on the variable to the Constructur for `Display`, but I think I completely botched that as I couldn't get it to compile.

so, main question: **how do I instantiate an object inside my class, so it becomes available as a private variable?**

If anyone wants to look at the full code, it's right here:
https://github.com/ffective/wake-up/tree/master/Clock

The latest commit is the way of splitting up I described last: using a global variable. The previous commit is the working code with all Display methods just globally in `Clock.ino`. Unfortunately I didn't save my attempts for putting it as a private variable.

body:
You need to create a "blank" object in your class and then instantiate it in your constructor initializer list:

```
class Display {
    private:
        U8X8_SH1106_128X64_NONAME_HW_I2C u8x8;

    public:
        Display() : u8x8(U8X8_PIN_NONE) {}
        void print_clock([...]);
};
```

The object in `private` is not instantiated until the constructor is called by the calling of the `Display()` constructor.

From then on you can use `u8x8.whatever()` as you would normally.


body:
First errors aren't much helpful, but the last one about member function explains it all. You are not creating member variable of that type, you are trying to create member function (with invalid parameter list) that returns `U8X8_SH1106_128X64_NONAME_HW_I2C` value.

This code is perfectly valid:

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

    class Display {
      public:
        Display() { u8x8.begin(); }

        // you can also use different initializer for u8x8 object (default one is never executed in this case):
        Display(uint8_t resetPin) : u8x8{resetPin} { u8x8.begin(); }

      private:
        U8X8_SH1106_128X64_NONAME_HW_I2C u8x8 { U8X8_PIN_NONE };
    };

and in the sketch:

    // creating instance:
    Display disp{ 5 };

    // or with default constructor and reset pin value
    Display disp2;


message:
declaration of 'varDay' as array of references error

I am trying to write a function to store the date and time data from an RTC module. I have used char arrays to implement the function. I get "*declaration of 'varDay' as array of references*" error upon compilation.

I am still learning about char arrays and manipulating them so may be I am making a very obvious mistake. Could you please explain what I am doing wrong?

    #include <RTClib.h>

    RTC_DS3231 rtc;

    void setup() {
      Serial.begin(115200);
    #ifndef ESP8266
      while (!Serial); // wait for serial port to connect. Needed for native USB
    #endif

      if (! rtc.begin()) {
        Serial.println("Couldn't find RTC");
        Serial.flush();
        abort();
      }

      if (rtc.lostPower()) {
        Serial.println("RTC lost power, let's set the time!");
        // When time needs to be set on a new device, or after a power loss, the
        // following line sets the RTC to the date & time this sketch was compiled
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      }

    }

    void loop() {
      unsigned long newTime = millis();
      static unsigned long oldTime = 0;

      char varYear [] = "1234";
      char varMonth [] = "00";
      char varDay [] = "00";
      char varHour [] = "00";
      char varMinute [] = "00";
      char varSecond [] = "00";
      unsigned int varEpoch;
      char varDate [] = "123456789";
      char varTime [] = "12345678";
      char dash [] = "-";
      char colon [] = ":";

      if (newTime - oldTime >= 60000) {
        oldTime = newTime;

        getDate(varDay, varMonth, varYear, varDate, dash, colon);
      }

    }
    void getDate (char &varDay[3], char &varMonth[3], char &varYear[5], char &varDate[11], char &dash[2], char &colon[2]) {

      DateTime now = rtc.now();
      strcpy (varDay, now.day());
      strcpy (varMonth, now.month());
      strcpy (varYear, now.year());

      strcat (varDate, varDay) ;
      strcat (varDate, dash);
      strcat (varDate, varMonth);
      strcat (varDate, dash);
      strcat (varDate, varYear)

      Serial.println(varDate);
    }

body:
`char &varDay[3]` is an array of 3 references to type char, not a reference to type char of size 3.

Instead just pass a pointer:

```
void getDate (char *varDay, char *varMonth, char *varYear, char *varDate, char *dash[2], char *colon[2]) {
```

Also:

```
strcpy (varDay, now.day());
strcpy (varMonth, now.month());
strcpy (varYear, now.year());
```

That won't work. You can't copy a number into a string. now.day() etc need converting to a string first.

It would be better to format your string with snprintf:

```
snprintf(varDate, 11, "d-d-d", now.day(), now.month(), now.year());
```


message:
Connecting BMP280 sensor to microcontroller

I am building my own board with integrated pressure sensor.
(microcontroller is 3V3 logic)

I want to know which parts do i need. In datasheet there are only 2 capacitors but on breakout board there are also 4 resistors.

Also in datasheet are 2 100 nF capacitors and on breakout board are 1uF and 0,1uF.

schematics from datasheet:
[![enter image description here][1]][1]

breakout board schematics:

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

  [1]: https://i.stack.imgur.com/OVdBW.png
  [2]: https://i.stack.imgur.com/IXFyK.png

body:
The capacitors are just decoupling capacitors. The value is not that critical. 100nF are good values to use.  On the breakout they have used just one pair of decoupling capacitors but use that pair for both power pins. The datasheet has one decoupling capacitor for each pin. You can do it either way. Personally I'd do it the datasheet way, but for a small board it really doesn't make much difference.

The resistors are a different matter. The BMP280 can work in a number of communication modes, and which mode you have it in dictates what resistors are needed.

R1 is used to place it into I2C mode. R4 is used to set the I2C address. R2 and R3 are the pullup resistors on the I2C bus. They aren't really part of the BMP280 circuit, but part of any I2C circuit in general.

R1 and R4 could be replaced by direct connections to VCC and GND respectively, but by having resistors gives you the ability to override them and use SPI instead of I2C should you wish it.


message:
printing the analogRead() functions result crashes Arduino

I have created a curcuit which reads the analog pin 3 auf the arduino nano and does other things dependant on the returned value. However I have problems regarding the analogRead() function. Whenever I use a piece of wire to short the "Analog_UpDownHorn_Signal" and do it fast paced so that the arduino reads 0V and 5V repeatedly the serial communication stops. Sometimes it resumes. Sometimes it doesn't and when it does the value is always 1023.

I have managed to reduce the problem to the following 2 lines of code, which leads me to believe its my curcuit or a bug in the functions used. Before the arduino gets stuck it sometimes puts out random '?' or other wierd characters on the serial monitor.

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

void loop()
{
  Serial.println(analogRead(A3));
}
```

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

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

body:
The capacitor you have is rather large on the Analogue input, normally at this position it would be for debounce. Try something in the range of 100nF. Another idea would be to increase R8 to 10k.

[https://www.g7smy.co.uk/2015/09/multiple-buttons-on-one-pin-with-an-arduino/][1]

  [1]: https://www.g7smy.co.uk/2015/09/multiple-buttons-on-one-pin-with-an-arduino/


body:
I have fixed the issue by connecting the two grounds on the opposite site of the arduino nano with a thick solder connection on the bottom side of my perfboard. Seems like it really had to do with the big capacitance an the rapid discharge when shorting it to ground.

Maybe it had a "charge pump" like effect  with decoupling cap and the debouncing cap, because those are on the same side of the board.

To further avoid this problem i will not short the cap an discharge it through a low ohm resistor. Furthermore i could lower the capacitance as it was stated before and up the resistor values.


message:
Why my code isn't working?

I wrote this code, but it doesn't work (what I want is that the program choose a random color and turn on or off an RGB led) I use transistors to turn the led strip on or off and analogWrite(pin, random(0, 255) doesn't work
```
int red = 11;
int green = 10;
int blue = 9;

int color = 1;
int stat = 1;

void setup() {
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
}

void loop() {
  color = random(1, 3);
  stat = random(0, 1);

  if (color == 1 and stat == 0) {
    digitalWrite(red, LOW);
  }

  if (color == 1 and stat == 1) {
    digitalWrite(red, HIGH);
  }

  if (color == 2 and stat == 0) {
    digitalWrite(green, LOW);
  }

  if (color == 2 and stat == 1) {
    digitalWrite(green, HIGH);
  }

  if (color == 3 and stat == 0) {
    digitalWrite(blue, LOW);
  }

  if (color == 3 and stat == 1) {
    digitalWrite(blue, HIGH);
  }

  delay(1000);

}
```

body:
From Arduino reference: [random](https://www.arduino.cc/reference/en/language/functions/random-numbers/random/)

In short:

> **Syntax**
>
> random(max)
>
> random(min, max)
>
> **Parameters**
>
> min: lower bound of the random value, inclusive (optional).
>
> max: upper bound of the random value, exclusive.
>
> **Returns**
>
> A random number between min and max-1. Data type: long.

Basically your first random returns values {1,2} and second one is even better {0}


message:
How to push two values to the same key from Arduino to Firebase

I would like to push two values at the same time (to the same node) from arduino to firebase. I tried to create an array and push the array to firebase, however, that is not working.

Here are the two values that I'm pushing, but I would like to push them to the same unique key:
```
temp1 = sensors.getTempCByIndex(0);
 StaticJsonBuffer<50> jsonBuffer;
JsonObject& timeStampObject = jsonBuffer.createObject();
timeStampObject[".sv"] = "timestamp";

Firebase.push("Sensors/20/temperatures/001", temp1);
Firebase.push("Sensors/20/temperatures/001", timeStampObject);
```
[How it should look like in Firebase][1]

Thanks in advance!

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

body:
@hcheung thanks for your help! It solved the problem. This is my code now:

    StaticJsonBuffer<256> jsonBuffer;
    JsonArray& array = jsonBuffer.createArray();
    array.add(timeStampObject);
    array.add(temp1);
    Firebase.push("Sensors", array);


message:
Wifi strength Automation . Help. Noobie here

<!-- language-all: lang-arduino -->

    #include <ESP8266WiFi.h>
    const char *SSID = "mr_lazy_boei";
    const char *pass  = "usalusal";

    WiFiClient client;

    // Relay pin number
    int ignition=2;
    int self=0;

    //   Return RSSI(Received Signal Strength Indicator) or 0 if target SSID not found
    int32_t getRSSI(const char* target_ssid) {
     byte available_networks = WiFi.scanNetworks();

     for (int network = 0; network < available_networks; network++) {
       if (WiFi.SSID(network).compareTo(target_ssid) == 0) {     //stringOne.compareTo(stringTwo) < 0
         return WiFi.RSSI(network);
       }

     }
     return 0;
    }

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

     Serial.println("Connecting to ");
     Serial.println(SSID);

     WiFi.begin(SSID,pass);
     while(WiFi.status() !=WL_CONNECTED)
     {
       delay(500);
       Serial.print(".");
     }
     Serial.println("");
     Serial.println("WiFi connected");

    pinMode(ignition,OUTPUT);
    pinMode(self,OUTPUT);
    }

    void loop(){

    int32_t rssi = getRSSI(SSID);

     // For debugging purpose only
     Serial.print("Signal strength: ");
     Serial.print(rssi);
     Serial.println("dBm");

     if (rssi > (-55) && rssi != 0) // if rssi is greater then -55 dbm or it's 0 dbm, then the light will turn
     {
       digitalWrite(ignition, LOW);
       Serial.println("ON");
    }
    else

    {
     digitalWrite(ignition,HIGH);
     Serial.println("OFF");
    }
    if (rssi > (-55) &&rssi !=0)
    {
     digitalWrite(self,LOW);
     delay(750);
     digitalWrite(self,HIGH);
     Serial.println("SELF OFF");

    }

    }

Above is my code written. As you can see, I have two variables: `ignition` and `self`. `ignition` works the way I want, but the `self` variable turns on and and then off. That is correct. But it again turns on because of `void loop()`.

Let me explain further:

If wifi signal is strong the `ignition` should turn on and the `self` should turn on for less than a second and then turn off. It should not turn on again. When the signal goes weak the `ignition` turns off. Again, when signal gets strong the `ignition` turns on and I need `self` to turn on for not even a second and turn off.

I tried my best getting that. I tried moving it to `void setup()`, but that just works when I power up the device. After that it doesn't turn on or off. Please kindly help me. I know here I am having very talented brothers who would help me out on this issue.

body:
You need to design your program using a Finite State Machine.

First start off by defining each *state* that your program can be in, and what is allowed to happen in each of those states.

For example:

1. **IDLE**

The only thing that is allowed to happen here is detecting the RSSI and deciding whether or not to start the engine.

2. **IGNITION**

The RSSI has got strong enough and you want to start the car. The only thing you want to do is turn on the ignition and wait a moment. Nothing more.

3. **CRANK**

Once you've waited a moment you can crank the engine. That means turning on the starter motor and waiting a moment.

4. **RUNNING**

Now the engine has started you can release the starter motor and leave the engine to idle. It's now that you want to start watching the RSSI gain.

5. **STOP**

The RSSI has dropped below your threshold, so now you can stop the engine.

6. **IDLE**

Now the engine's stopped you can go back to the start and idle looking for the RSSI to get high enough again.

These are all the *states* of a *Finite State Machine*. You move from state to state depending on different *inputs* or *triggers*.  One input is your RSSI value - or more strictly your RSSI value being above or below a threshold.  Another input is (less obviously) time. Waiting for some time to pass.

So you start in state 1. In that state all your program is doing is watching the RSSI. When that rises you move to state 2. At that point it performs whatever actions are needed (turn on the ignition) and record the time. When enough time has elapsed you move on to state 3, and do the same.

It could actually be simplified by compressing states 2 and 3 together:

* Turn on ignition
* Delay
* Turn on starter motor
* Delay
* Turn off starter motor
* Delay
* Move to next state

You could then increase the complexity again a little (while increasing the safety) by adding extra steps when you're watching the RSSI. You can then check to see if the RSSI has been above (or below) the threshold for a certain amount of time before moving on to the next step:

1. IDLE - watching RSSI
   * If RSSI rises above threshold go to state 2.
   * Else stay in state 1
2. Record the time and keep watching the RSSI
   * If RSSI drops below threshold: Go back to 1.
   * If Enough time has passed: Go to state 3.
   * Else stay in state 2
3. Start the engine.
   * Go to state 4
4. RUNNING - watching RSSI
   * If RSSI falls below threshold go to state 5.
5. Record the time and keep watching the RSSI
   * If the RSSI rises above threshold: Go back to 4
   * If enough time has passed: go to state 6.
   * Else stay in state 5.
6. Stop the engine.
   * Go to state 1.

... etc ...


message:
WS2811 lights only turn red

I've connected a strand of WS2811 to a 5V power supply and an Arduino Uno and no matter what I do the lights are always red. I'm using the fast led library and for some reason, the WS2811 lights are only red.

body: I had this same issue, turns out I had 12v WS2811's. Changing power supply fixed it for me!


message:
ESP8266 - ESP01S with relay. Toggling the relay with http (GPIO0) and GPIO2 at the same time

I have an ESP8266 module with a relay like this: https://aliexpress.com/item/4000348370586.html.
I have been able to control the module, I can deactivate and activate the relay by means of an http request, with the following code.

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>

    #ifndef STASSID
    #define STASSID "wifi_name"
    #define STAPSK  "wifi_password"
    #endif

    const char* ssid = STASSID;
    const char* password = STAPSK;

    ESP8266WebServer server(80);

    IPAddress ip(192, 168, 0, 101); //ESP static ip
    IPAddress gateway(192, 168, 0, 1);   //IP Address of your WiFi Router (Gateway)
    IPAddress subnet(255, 255, 255, 0);  //Subnet mask
    IPAddress dns(8, 8, 8, 8);  //DNS
    const char* deviceName = "ligth101";

    const int relayPin = 0;

    void handleOn() {
        digitalWrite(relayPin, LOW);
        setCrossOrigin();
        server.send(200, "text/plain", "Ligth on");
    }

    void handleOff() {
        digitalWrite(relayPin, HIGH);
        setCrossOrigin();
        server.send(200, "text/plain", "Ligth off");
    }

    void handlePing() {
        setCrossOrigin();
        server.send(200, "text/plain", "ligth");
    }

    void configPin(){
        pinMode(relayPin, OUTPUT);
        digitalWrite(relayPin, HIGH);
    }

    void configWifi(){
        WiFi.setAutoConnect(false);
        WiFi.disconnect();
        WiFi.hostname(deviceName);
        WiFi.config(ip, subnet, gateway, dns);
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        }
    }

    void setCrossOrigin(){
        server.sendHeader(F("Access-Control-Allow-Origin"), F("*"));
        server.sendHeader(F("Access-Control-Max-Age"), F("600"));
        server.sendHeader(F("Access-Control-Allow-Methods"), F("PUT,POST,GET,OPTIONS"));
        server.sendHeader(F("Access-Control-Allow-Headers"), F("*"));
    }

    void sendCrossOriginHeader(){
        setCrossOrigin();
        server.send(204);
    }

    void configServerPaths(){
        server.on(F("/ping"), HTTP_OPTIONS, sendCrossOriginHeader);
        server.on(F("/ping"), HTTP_GET, handlePing);

        server.on(F("/on"), HTTP_OPTIONS, sendCrossOriginHeader);
        server.on(F("/on"), HTTP_GET, handleOn);

        server.on(F("/off"), HTTP_OPTIONS, sendCrossOriginHeader);
        server.on(F("/off"), HTTP_GET, handleOff);

        server.begin();
    }

    void setup() {
        configPin();
        configWifi();
        configServerPaths();
    }

    void loop() {
        server.handleClient();
    }

Now, I want to use the GPIO2 pin to also turn the relay on and off. The desired behavior is to change the state of the relay regardless of whether it comes from the button or from an http request.

I have tried the following modifications to the code:

    const int buttonPin = 2;
    int buttonState = 0;

    void configPin(){
        ...
        digitalWrite(buttonPin, LOW);
    }

    void handleButton(){
        buttonState=digitalRead(buttonPin);
        if(buttonState == HIGH) {
            digitalWrite( relayPin, !digitalRead(relayPin) );
            delay(1000);
        }
    }

    void loop() {
        server.handleClient();
        handleButton();
    }

With these modifications to the code, I have tested the following two modifications to the hardware:

 1. Placing a switch between ground and GPIO2. As a result of this, each time I activate the push-button, the relay remains intermittent, going from one state to the other infinitely.
 2. Placing a switch between ground and GPIO2, but adding a resistor between the switch and the GPIO2 pin, but this also does not work.

Is there a way to deactivate / activate the relay using GPIO2 with a push button and via http as well?

Thanks!

body:
Contrary to esp-01, on the esp-01S io 0 and io 2 pins have a pull-up resistor.

Wire a button between io 2 and ground and you will read LOW if the button is pushed.

Use a state variable for the state of the relay, don't read back the pin (does it even work to read the state of an output pin with digitalRead on esp8266?).


message:
I cannot get my code to play music in a or manner. I have to open one switch then the other. Music should play with either door open

[![enter image description here][1]][1]Problem is if I open the necklaceDoor first, nothing happens. I have to open the ringDoor first. That turns everything on. Then with the necklaceDoor open, the stepper motor will turn off and the lights and music will continue to play. But I want to be able to open the necklaceDoor first and play the music with the lights. I do not want it to matter which one is opened first. I also realized that if I can get an or statement to work within an and statement I could do away with the fourth if statement completely. Both ringDoor open and necklaceDoor open, as well as ringDoor closed and necklaceDoor open have the same outcome. Now if I switch the door states in the third if statement, I get necklaceDoor only plays audio after closed(original problem) but if both doors are open and then ringDoor is closed, the music will shut off after the stepper timer is done and then start again after necklaceDoor is closed?!?!?!?

    #include <SD.h>
    #include <TMRpcm.h>
    #include <Stepper.h>
    TMRpcm tmrpcm;

    const int stepsPerRevolution = 2048;   //Number of pulses per revolution
    const int ringDoor=2;                  //Ring door
    const int necklaceDoor=7;              //Necklace door
    const int relayPower=22;               //Turn relay on

    Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

    void setup() {
      Serial.begin(9600);                         //Start connection with computer

      if (!SD.begin(53))                         //Chip pin on card
      {
        Serial.println("failed!");                //SD card did not read
        return;
      }

      tmrpcm.speakerPin = 46;                      //Speaker output pin
      myStepper.setSpeed(5);                       //Stepper speed
      pinMode(ringDoor,INPUT);                     //Check state of ring door magnetic switch, NO
      pinMode(necklaceDoor,INPUT);                 //Check state of necklace door magnetic switch, NO
      pinMode(relayPower,OUTPUT);                  //Relay enable for 12V LED
      digitalWrite(ringDoor,HIGH);                 //Make door closed read high on start up
      digitalWrite(necklaceDoor,HIGH);             //Make door closed read high on start up
      digitalWrite(relayPower,LOW);                //Make relay off on start up
    }

    void loop() {

      if ((digitalRead(ringDoor)==HIGH)&&(digitalRead(necklaceDoor)==HIGH))
      {                                                                                //ring door and necklace door is closed, everything is off
        digitalWrite(relayPower,LOW);
      }

      if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH))
      {                                                                                //ring door is open and necklace door is closed, lights on, stepper motor spinning, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
        myStepper.step(stepsPerRevolution);
        delay(500);
        myStepper.step(-stepsPerRevolution);
        delay(500);
      }

      if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==HIGH))
      {                                                                                //ring door closed and necklace door open, lights on, stepper motor off, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
      }

      if ((digitalRead(ringDoor)==LOW)&&(digitalRead(necklaceDoor)==LOW))
      {                                                                                //ring door and necklace door open, lights on, stepper motor off, music playing
        digitalWrite(relayPower,HIGH);
        tmrpcm.play("music.wav");
      }
    }

Please and thank you to any and all who help. It is greatly appreciated.
Yes, I asked the the original question and the answer I received not only did not work, somehow neither latch worked anymore.

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

body:
First of all, you have to find out how your magnetic switches work. Are they opened or closed if you attach a magnet to them? Do they behave the same or is one closed and the other opened if you attach a magnet?
Your code above is written for active LOW switches i.e. if the respective door is closed the switch is opened and therefore the logic level of the pin is HIGH. The level is LOW if the door is opened (activated; hence active LOW).

In order your code had a chance to work, the switches must be connect the right way: on one side connect them to GND and on the other side to the respective Arduino pin. If this is not the case, the code must be changed or the switches must be conneted the right way. You did not show us your schematic, so I can not check it for you.

Here is some code to try: But first find out if the switches you use are LOW or HIGH active. I also have no access to an IDE at the moment, so I can not try out the code. Take it as a hint on how to do it.

And one tip from a guy that does the job for 30 years now: Don't comment variables if their names say it all:

    //  this sort of comments makes the code unreadable --V
    const int ringDoor=2;                          //Ring door

I know it is a common behavior in the Arduino community, but don't write comments after a statement. In your code above I did realize that there are comment for the `if` statements only when I copied the code in my answer. Comments are only usefull if they say something new and can be read without problems.

    #include <SD.h>
    #include <TMRpcm.h>
    #include <Stepper.h>
    TMRpcm tmrpcm;

    const int stepsPerRevolution = 2048;
    const int ringDoor = 2;
    const int necklaceDoor = 7;
    const int relayPower = 22;

    Stepper myStepper = Stepper( stepsPerRevolution, 8, 10, 9, 11 );

    void setup()
    {
      Serial.begin( 9600 );
      if ( ! SD.begin( 53 ) )
      {
        Serial.println( "failed!" );
        return;
      }

      tmrpcm.speakerPin = 46;
      myStepper.setSpeed( 5 );
      pinMode( ringDoor, INPUT );
      pinMode( necklaceDoor, INPUT );
      pinMode( relayPower, OUTPUT );

      digitalWrite( ringDoor, HIGH );
      digitalWrite( necklaceDoor, HIGH );

      digitalWrite( relayPower, LOW );
    }

    void loop() {

      // the following code works if both switches are LOW active
      // (i.e. LOW if the door is open)
      // if the "ringDoor-switch is HIGH active change
      // digitalRead( ringDoor ) == LOW to
      // digitalRead( ringDoor ) == HIGH
      // if the "necklaceDoor-switch is HIGH active change
      // digitalRead( necklaceDoor ) == LOW to
      // digitalRead( necklaceDoor ) == HIGH
      // and
      // digitalRead( necklaceDoor ) == HIGH to
      // digitalRead( necklaceDoor ) == LOW

      if ( ( digitalRead( ringDoor )     == LOW ) ||
           ( digitalRead( necklaceDoor ) == LOW ) )
      {
        // one of the doors is open
        digitalWrite( relayPower, HIGH );
        tmrpcm.play( "music.wav" );
        if ( digitalRead( necklaceDoor ) == HIGH )
        {
          // only the ring door is opend
          myStepper.step( stepsPerRevolution );
          delay( 500 );
          myStepper.step( -stepsPerRevolution );
          delay( 500 );
        }
      }
      else
      {
        digitalWrite( relayPower, LOW );
      }
    }


message:
Using different processors when it comes to arduino

I decided to learn Arduino in this quarantine so I am still a newbie when it comes to micro controllers. Basically I been doing all my projects based on the ATMEGA328P-PU:

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

I even converted my breadboard designs to custom PCBs like this one:

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

**I am running out of Atmega328P-PU processors and I am about to buy more. But instead of going with the traditional Atmega328P should I buy other processors?**

This are my alternatives:

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

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

-----

They all are about the same price. For example the ESP32 is 10 times faster and it was a lot more sram and pins. Anyways this are my questions:

1) Why do people buy the Atmega328P when there are faster and more powerfull processors for the same price?

2) I been saving a lot of money by buying the Atmega328P processor by itself and then building Arduino using the crystal, ceramic capacitors etc. There are so many tutorials on how to build that such as on [THIS LINK][5] and many more. But how can I build an ESP32 running arduino code on a breadboard? I have not been able to find that tutorial. All the tutorials I find use the ESP32 already soldered to a PCB. I want to build my custom PCB using a ESP32 for example. Where can I find that tutorial?

3) If I decide to buy the ESP32 or ESP8266 should I build my code using the arduino IDE? I will have to add stuff to arduino IDE so it works with the ESP32. What are the benefits of using other IDEs?

4) I am thinking about the ESP32 and ESP8266 because I see a lot of people using them on the internet and they are much more powerfull than the Atmega328P for the same price. What other processors do you guys recommend?

  [1]: https://i.stack.imgur.com/bPk6S.png
  [2]: https://i.stack.imgur.com/gm4n7.jpg
  [3]: https://i.stack.imgur.com/rBeUe.png
  [4]: https://i.stack.imgur.com/GCA36.png
  [5]: https://www.arduino.cc/en/main/standalone

body:
1. Sometimes faster and more powerful is not needed. If you just needed a simple timer, and it needed to be battery operated, a processor like the ATmega328 would be the better choice. It really depends on the application.

The ESP32 is a great device. But the A/D converter on it is less than stellar. It is not as consistent compared to the A/D in the Atmega328P.

2. The ESP32 is more fussy about the power supply requirements compared to the Atmega328P. Lots of people get themselves into trouble when they use poor design practices with the ESP32/ESP8266 modules. Poor practices that worked well enough for lower power and lower speed processors like the Atmega328P. Most people don't bother with reading the datasheet for the processors. They just try and copy stuff they fine on the Internet. And the Internet is full of poor quality information by people who don't really understand much of what they are working with.

If you want to start using the ESP32, then do yourself a favor and buy a working board with a power supply and not just buy a module. It will save you many hours of grief.

3. The Arduino IDE makes it easy to get stuff working. There also is Python, but it is less popular. There is a lot more information available for the Arduino IDE, and available libraries. And that makes development a lot easier. There are other ways, but the learning curve is much steeper.

4. The "Blue Pill" STM32F103C8T6 based board is a lot of capability for little money. The CPU runs on 3.3 volts like the ESP devices. It has gain a lot of popularity in the last few years but there isn't as much information as for the Atmega328P.

The STM32F103C8T6 and the ESP devices are 3.3 volt based designs. And they require 3.3 volt devices to interact with. There are some devices that are mostly 5 volt only devices. Like a character LCD. It is easier to interface that to a 5 volt processor.

There is lots that I could still say but it would take hours. But what you should do before deciding on a part is to decide what the needs of the project are. That will often guide you towards the part you should use.

One more note. The ESP devices are running a lot of code on top of the Setup and Loop functions. There is lots of stuff going on in the background to support the WiFi capability. And you don't have the kind of control that you could have with a non-ESP device. But if you want that part then you need to accept that limitation.


body:
For learning it really doesn't matter much of which MCU to choose from. For actually embedded project development, it really depends on what you want to do with your dev board. I thought that I would just offers some of my thoughts and experiences here as a reference, there is no right or wrong answers. I'm sure many people have their own favourites and considerations when picking their MCU.

> Why do people buy the Atmega328P when there are faster and more powerfull processors for the same price?

ATmega328p get popular for its long history (it is 2-decades old) and Arduino, personally I feel that there are better MCU with compatible features, memory size, etc. even within the AVR series to replace ATmega328p, I actually developed an [ATtiny3217-based Arduino board](https://www.e-tinkers.com/2020/07/arduino-compatible-development-board-with-attiny3217/) last month, it is cheaper (on chip BOM cost) and it does not need crystal for running at 20MHz with decent accuracy, it offers almost similar I/O pins, memory size, UART/I2C/SPI as ATmega328, but it is a much modern chip with many features that are not available in ATmega328 (such as DAC, touch support, event system, etc.). [ATmega3208/4809](http://ww1.microchip.com/downloads/en/DeviceDoc/40002017A.pdf) is another interesting candidate for my next project.

>All the tutorials I find use the ESP32 already soldered to a PCB. I want to build my custom PCB using a ESP32 for example. Where can I find that tutorial?

ESP32 (and ESP8266 like ESP-12F as well) come with a compact form factor that is ready to be integrated into your design, most of the design needs are USB-interface, power supply and some peripheral (such as auto-reset circuitry, power and blinking LEDs, etc.). You can take a look at [Adafruit HUZZAH ESP8266](https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout?view=all) which is basically based upon an ESP-12E module with added circuit for reset, voltage regulator.

> If I decide to buy the ESP32 or ESP8266 should I build my code using the arduino IDE? I will have to add stuff to arduino IDE so it works with the ESP32. What are the benefits of using other IDEs?

Arduino IDE is not the only IDE for programming an Arduino, [PlatformIO](https://platformio.org) is one of the alternatives IDE for Arduino programming, one of the main benefits is better project and dependency(libraries) management and the flexibility on compiling/building process (e.g. pull in the floating point supports on AVR chips). Take a look at these two YouTube videos to see how it looks like and how to set it up:

 - [A Better Arduino IDE – Getting Started with PlatformIO](https://www.youtube.com/watch?v=EIkGTwLOD7o)
 - [PlatformIO – Using External Libraries](https://www.youtube.com/watch?v=EBlHNBNHESQ)

> I am thinking about the ESP32 and ESP8266... What other processors do you guys recommend?

As I mentioned at the beginning, it really depend on your selection criteria. ESP8266 and ESP32 is generally the choice for its WiFi capability, however, you won't chose ESP8266 for anything related to ADC because it has only one ADC with a reference voltage of 1v. ESP32 looks great for for its faster CPU, it however generated a lot of noise when you want to reading sensor data even though it offers 12-bit ADC resolution versus 10-bit in ATmega328p. Its ADC also has [non-linear issue](https://www.e-tinkers.com/2019/10/using-a-thermistor-with-arduino-and-unexpected-esp32-adc-non-linearity/) on some of the old batch of ESP32 chips.

On the question of "what other processors do you guys recommend"? If no requirements for wireless connectivity, I personally like STM32F103 Blue Pill, for its better ADC (12-bit), more memory, and multiple UARTs, and cheap but there are things that you need to be [aware of](https://www.e-tinkers.com/2020/01/getting-started-with-stm32-and-things-you-need-to-be-aware-of/) (such as fake STM32 chip and design faults).

Whatever you decided for your next choice of MCU, I'm sure it won't be your last one, as your experience grow and your project get more complex, you will know that there is no perfect MCU that fit it all.


message:
Linux can not open arduino IDE - java.lang.NullPointerException

I use arch linux. I installed arduino ide with pacman. When I try to run it, loading window will show for few socends and than program crashes. There are logs:

```
john@arch-thinkpad ~ [1]> arduino
Picked up JAVA_TOOL_OPTIONS:
Set log4j store directory /home/john/.arduino15
java.lang.NullPointerException
 at processing.app.Base.rebuildProgrammerMenu(Base.java:1705)
 at processing.app.Base.<init>(Base.java:286)
 at processing.app.Base.main(Base.java:150)
john@arch-thinkpad ~ [255]>
```
```
john@arch-thinkpad ~> arduino --version
Picked up JAVA_TOOL_OPTIONS:
Loading configuration...
Initializing packages...
Preparing boards...
Arduino: 1.8.13
```
What should I do to fix it ?
Thank you for your help

body:
The first thing to do is delete your `preferences.txt` file. This is the most common cause of startup issues - some corruption or an invalid setting in that file can break the IDE completely.

    rm ~/.arduino15/preferences.txt

If that doesn't fix it then you can delete your entire Arduino working directory, which will remove all installed cores and boards and give you a fresh installation:

    rm -rf ~/.arduino15


body:
I had to install `arduino-avr-core` package:

```
sudo pacman -S arduino-avr-core
```

Now it works fine


message:
ESP32 send data to another ESP32 without establishing a wifi connection

Originally I was creating a project consisting of the Atmega328P and NRF24L01 to create multiple arduinos that could talk to each other.  Basically I was creating something like this:

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

As the network grows I am starting to run out of memory when using the atmega328P. I have to be careful about allocating memory and more. So I will like to replace the NRF24L01 with the ESP32.  The price of the ESP-WROOM-32 by itself is also cheaper than buying an NRF24L01 + the atmega328.

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

Question
-----

**How can I send data from one ESP32 to another ESP32 without establishing a WiFi connection?** Just like the NRF24L01 where you specify a writting pipe where you want to send the data and the other NRF24L01 is listening on that pipe.

-----

I know I can do that with ESP-NOW. [This video explains how][2]. The problem with ESP NOW is that I have to know in advance the mac address of the ESP32 where I intend to send a message. I plan to be able to keep adding smart home devices without having to know the mac address.

My algorithm with NRF24 that I already created is as follows:

1. There is a master node listening on address 2
2. If I add a new  node `A` to the network it listens on address 1.
3. Master discovers all devices that have address 1 every few seconds.
4. So eventually node `A` receives a discovery packet message that comes from master. Node `A` listens now on a random address and replies to master with that random anddress.
5. So node `A` is now connected to the network.

The cool thing about this algorithm is that I can keep adding new nodes to the network without knowing in advance its address. I will like to do the same thing with the ESP32. **How can I send a simple message betweenn 2 ESP32 modules?**

  [1]: https://i.stack.imgur.com/0MBQ4.png
  [2]: https://www.youtube.com/watch?v=qxwXwNS3Avw

body:
Finally I found a way how to do it. If you use the mac address FF:FF:FF:FF:FF:FF that works as a broadcast address. This is the working code on how to send a message from the master to another esp32 without knowing its mac address. Later the slave can reply with its real mac address:

**Code for master (tx)**

    #include <Arduino.h>
    #include <esp_now.h>
    #include "WiFi.h"

    uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
      Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success 1" : "Delivery Fail 1");
      if (status ==0){
        Serial.println("Delivery Success 2");
      }
      else{
        Serial.println("Delivery fail 2");
      }

      Serial.println();
    }

    void setup()
    {

      Serial.begin(115200);

      Serial.println("Starting...\n");

      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);

      Serial.println(WiFi.macAddress());

      // Init ESP-NOW
      if (esp_now_init() != ESP_OK) {
        Serial.println("Error initializing ESP-NOW");
        for(;;) {      delay(1);  } // do not initialize wait forever
      }

      Serial.println("initialized ESP-NOW");

      // Once ESPNow is successfully Init, we will register for Send CB to
      // get the status of Trasnmitted packet
      esp_now_register_send_cb(OnDataSent);

       // Register peer
      esp_now_peer_info_t peerInfo;
      memcpy(peerInfo.peer_addr, broadcastAddress, 6);
      peerInfo.channel = 0;
      peerInfo.encrypt = false;

       // Add peer
      if (esp_now_add_peer(&peerInfo) != ESP_OK){
        Serial.println("Failed to add peer");
        for(;;) {      delay(1);  } // do not initialize wait forever
      }
    }

    int dataToSend = 1;
    void loop()
    {
        dataToSend++;

        // Send message via ESP-NOW (size of an int is 4 bytes on ESP32)
        esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &dataToSend, 4);

        if (result == ESP_OK) {
          Serial.println("Sent with success");
        }
        else {
          Serial.println("Error sending the data");
        }

        //Serial.println(WiFi.macAddress());
        delay(1000);
    }

**Code for slave (Rx)**

    #include <Arduino.h>
    #include <esp_now.h>
    #include "WiFi.h"

    // Callback when data is received
    void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
    {
      int dataReceived;
      memcpy(&dataReceived, incomingData, sizeof(dataReceived));

      Serial.print("Data Received: ");
      Serial.println(dataReceived);

      Serial.println();
    }

    void setup()
    {

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

      Serial.println("Starting...\n");

      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);

      // print our mac address
      Serial.println(WiFi.macAddress());

      // Init ESP-NOW
      if (esp_now_init() != ESP_OK) {
        Serial.println("Error initializing ESP-NOW");
        for(;;) {      delay(1);  } // do not initialize wait forever
      }

      Serial.println("initialized ESP-NOW");

      // Register for a callback function that will be called when data is received
      esp_now_register_recv_cb(OnDataRecv);

    }

    void loop()
    {
    }

You can also reply back on the receiver code if you want. It will be the same code.


message:
Detecting different objects closeness

iam currently working on a new project, where i would like to detect the existence/closeness of several objects around the arduino up to like 1 meter. I was thinking about an rfid setup, but as the objects could have different sizes like 5 centimetre tall and only 3 centimetre wide, i think this won't work for the max distance. I was also thinking about a ble beacon, but as this one has to be activley powered all the time, it wouln't be the perfect solution. As the base could be fully customized, it may have some kind of sensors/wires overall the surface, but iam a bit lacking of a good idea for this.

I hope someone might had a similar setup, or a good idea to go.

PS: When i think about it twice, it would be better, if it can be differentiate between some areas within the one meter and the different objects, entering each area. I've added some image, hope this helps to understand, what i want to archive at the end.

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

Thank you and greetings,
Sebastian

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

body:
As you might have already seen, a position sensing system can be really complex. Here I will list some possibilities, that come to my mind and might be fitting for your case or not.

 - **Matrix based solutions:** Here I mean sensors a some sort arranged in a matrix underneath the game table, which can sense the object placed on them. As you know from your wiring, where a specific sensor is located, you know from the triggered sensor, where the object was placed. The resolution directly corresponds to the numbers of sensors, that you place. You can use different sensors, which will give you different information, but are also very different in handling and costs:

 - Reed switches and magnets on the bottom of the objects. The magnet on the object would close the reed switch. A read switches are rather cheap (have seen 40 pieces for about 10€ on amazon; on aliexpress or others you might get them even cheaper) and can be easily placed in an electrical matrix or (depending on the number and places of object at any time) checked via shift registers, which are also not very pricey.

 - Hall sensors and magnets on the bottom of the objects. You would measure the magnetic field of the magnets with the hall sensors. You could use different magnet strengths to get different readings and thus directly distinguish between different object types. The hall sensors will be not that easy to read. Mostly they have an analog output, thus you would need extra ADCs and multiplexers to read them all.

    - RFID readers and RFID chips in each object. Very pricey and rather low resolution. Also very difficult to read from all of them with the Arduino. But you could go for the reed switch version and use a single RFID reader to first tell the Arduino, which object you are placing. In the game you would first hold the object to the reader, then place it on the board.

 - Lidar system: A Lidar scanner could scan over your board (it measures the distance in a circle around it). Each object would be a negative peak in the measured distance distribution. From the angle and the distance, you could calculate the position on the board. Though you would need to carefully place the sensor, as one object might hide the other behind it. You can tackle that with an additional Lidar scanner, but the processing will also be rather complex. And Lidar scanners are rather expensive.

 - Ultrasonic sensors out the board: If you place enough ultrasonic sensors around the board and measure with one after the other, you might also get fitting results. But I would guess, that you won't get good positioning results with them, especially for the rather small objects and distances used on a game table.

 - Computer Vision: Away from Arduino you could use OpenCV on a Raspberry Pi together with a small camera above your board to detect objects. General object detecting is rather easy with OpenCV and python; getting it's position in the camera image is trivial then (from where you can calculate the position on the board easily). With more work it should also be possible to detect the object themselves (meaning distinguishing between different objects). We might need to train OpenCV with top-down images of the objects for that. If you don't get good results with the normal camera mode, you could try the IR camera mode (by removing the IR filter of the Pi's camera) and put some good IR reflective stuff on the top of the objects. Then OpenCV only has to find the bright spots in the image. All that is possible, though I cannot help you with that and also it is off-topic on this site.

- If you can have a board with fixed positions, you could make direct electrical connections between the objects and the board. Though that means, that you would have metal contacts all over the board. I recently used such electrical connections to distinguish between different objects, which can be put into a small number of bays. I have 7 pins on each object, one of them ground. On the object I connected some of the other pins to the ground pin to create a binary pattern. The pins of each bay get read by a shift-in register. All registers are chained together and connected to the Arduino with a total of 4 pins.

Depending on your needs you could combine some of these options. I would try the OpenCV solution, or alternatively the reed switch with one RFID reader solution.


message:
How to convert my Arduino setup to a PIC setup?

I have an arduino setup with LCD, RTC, EEPROM, Reed Switch, AC/DC Buck Converter, 4X4 Keypad.
What PIC IC will let me connect with all these(40 Pins), and yet accept Arduino Code.
I don't want to rewrite the code. I learn Arduino only recently, So shifting to another coding language is near impossible, since am not a coder.

body:
The PIC32 has full (or nearly full) support for the Arduino API through the chipKIT project.  If you want to use one of the smaller PIC chips (PIC16 / PIC18 etc) then you're out of luck. There just isn't a freely available C++ compiler for those chips, so the Arduino API can never really be ported to them.

I have, in the past, cobbled together an Arduino-style API layer for a handful of selected PIC18s which uses structs to emulate a couple of the Arduino C++ objects, but it only worked in a very basic way with no function overloading for things like `Serial.print()`.

One of the problems from a low-end user's perspective is that the PIC32 only comes in harder to use TQFP and QFN etc packages in anything larger than 28 pins. That means you can't breadboard without a development board. Fortunately there are some breadboard friendly options in the chipKIT ecosystem, such as the Fubarino series of boards. For more pins though you'd be wanting one of the bigger boards, such as the MAX32 which is in a Mega footprint (but with even more pins).

It's important to note though that the PIC32 is a 3.3V device and, owing to physical differences in the way that some of the internals work, there are incompatibilities in some of the libraries and functionality (such as no "LOW" or "CHANGE" interrupt support, only "RISING" and "FALLING").


message:
Assigning value to a struct byte order

So i have struct:

    typedef struct sendPacketStruct {
      byte header = headerByte;//0x55
      unsigned int time;//2 bytes
      int height;//2 bytes
    };

And i do this:

        sendPacketStruct sendPacket;

        sendPacket.time = 84;//0x54
        sendPacket.height = 100;//0x65

        Serial.write((byte*)&sendPacket, sizeof(sendPacket));

But when i receive it at the other end the hex bytes are:

55 54 00 64 00

So the first byte is correct as the header 0x55, but the 2x 2 byte values time and height are there but shifted.

eg it should be 00 54 not 54 00

body: The answer is that arduino is little endian, so the byte order is correct. I was just expecting big endian order as ive seen in some other network protocols. If that is desired instead I can just do some bit shifting and re-arranging.


message:
Which Arduinos support ATOMIC_BLOCK?

Is there a definitive list of which Arduino architectures support the `ATOMIC_BLOCK()` macro, and a list of `#defines` for each architecture?

I've tried searching through the [Arduino cores](https://github.com/search?q=org:arduino+ArduinoCore&unscoped_q=ArduinoCore) on GitHub to see where `ATOMIC_BLOCK` is used. If it's not used in a core, I've assumed it's not supported. I generated this list based upon that assumption, but how accurate is it?

```none
ArduinoCore         Supported       Archived    #define
-------------------------------------------------------
  samd
  avr                  Yes                      __AVR__
  arc32
  sam                  Yes
  primo                               Yes
  megaavr              Yes
  API
  nRF528x-mbedos
  mbed
```

I would like to write some code, something like this (edited in response to comments):

```c++
#define ATOMIC_BLOCK_SUPPORTED (__AVR__ || __MEGAAVR__ || __SAM__)
.
.
.
#if ATOMIC_BLOCK_SUPPORTED
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
#endif

        // Do not disturb.

#if ATOMIC_BLOCK_SUPPORTED
    }
#endif
```

For architectures that don't support `ATOMIC_BLOCK`, I would like to write my own code to save, disable and restore the global interrupt flag, something like this.

```c++
    asm
    {
        // Save interrupt flag.
    }
    // Clear interrupt flag.
    // Do not disturb.
    // Restore interrupt flag.
```
Potential Solution?
===================
```c++
#ifdef __AVR__
#include <util/atomic.h>
#elif defined(__ARCH2__)
#define ATOMIC_BLOCK(/* for architecture 2 */)
#elif defined(__ARCH3__)
#define ATOMIC_BLOCK(/* for architecture 3 */)
// etc
#endif
.
.
.
#ifdef ATOMIC_BLOCK
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
#endif

        // Do not disturb.

#ifdef ATOMIC_BLOCK
    }
#endif

```
Is there a definitive list of code that saves, disables and restores the global interrupt flag for every Arduino architecture that could be dropped into each `#elif` branch?

body:
This answer covers: **Which Arduinos support ATOMIC_BLOCK? And how can I duplicate this concept in C with `__attribute__((__cleanup__(func_to_call_when_x_exits_scope)))` and in C++ with class _constructors_ and _destructors_?**.

# Which Arduino's support the `ATOMIC_BLOCK` macros?

> Which Arduinos support ATOMIC_BLOCK?

Only [AVR (ATmel AVR architecture) microcontrollers][1] support the `ATOMIC_BLOCK` macros, because these macros are part of the [avr-libc][2] library, which, you guessed it!, supports only AVR microcontrollers.

AVR-based Arduinos include those based on the ATmega328 microcontroller (Arduino Uno, Nano, Mini, etc.), ATmega2560 (Arduino Mega 2560), ATmega32U4 (Arduino Leonardo, Pro Micro), etc.

# How are the `ATOMIC_BLOCK` macros implemented in C with the gcc compiler, and where can I see their source code?

avr-libc is available for download here: https://www.nongnu.org/avr-libc/ --> "source code and documentation" link under the "Downloads" section. Ex: here is the tarball for v 2.0.0: http://download.savannah.gnu.org/releases/avr-libc/avr-libc-2.0.0.tar.bz2.

The entire source code for the `ATOMIC_BLOCK` macros is contained in **avr-libc-2.0.0/include/util/atomic.h**.

`ATOMIC_BLOCK` is an ingenious macro written in C and relying upon the gcc "cleanup" attribute C extension which can call a function you define when a variable goes out of scope. Essentially, this is identical to a C++ class destructor which gets called when an instance of a class in C++ goes out of scope. The gcc "cleanup" attribute extension is a way to get C++-like behavior in C.

Here is the official gcc documentation: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html. It states:

> cleanup (cleanup_function)
>
> The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
>
> If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.

Its format is like this:

    int x __attribute__((__cleanup__(func_to_call_when_x_exits_scope))) = 0;

You use it like this:
[RUN A REAL EXAMPLE OF THIS CODE IN C ONLINE HERE.][3]

    static __inline__ void cleanup_my_byte(uint8_t *my_byte_p)
    {
        Serial.print("my_byte is going out of scope! Its value is ");
        Serial.println(*my_byte_p);
    }

    void setup()
    {
        uint8_t my_byte __attribute__((__cleanup__(cleanup_my_byte))) = 7;
    } // The following function call occurs automatically here as `my_byte`
      // exits its scope!:
      //    `cleanup_my_byte(&my_byte);`

Studying the **avr-libc-2.0.0/include/util/atomic.h** file referenced above, you can see how the `ATOMIC_RESTORESTATE` macro is implemented, using this attribute. I've put just the relevant pieces from that file here:

    #include <avr/io.h>
    #include <avr/interrupt.h>

    #define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
                               __ToDo ; __ToDo = 0 )

    static __inline__ uint8_t __iCliRetVal(void)
    {
        cli();
        return 1;
    }

    #define ATOMIC_RESTORESTATE uint8_t sreg_save \
        __attribute__((__cleanup__(__iRestore))) = SREG

    static __inline__ void __iRestore(const  uint8_t *__s)
    {
        SREG = *__s;
        __asm__ volatile ("" ::: "memory");
    }

Note that `cli()` clears (turns off) interrupts, and `sei()` sets (turns on) interrupts.

So, you can see that `ATOMIC_RESTORE_STATE` gets replaced by `uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG`, which backs up the global interrupt state from the AVR `SREG` 8-bit register into `sreg_save`, then calls this function call when `sreg_save` exits its scope: `__iRestore(&sreg_save);`. That function call to `__iRestore()` then sets the `SREG` register back to where it was, restoring the interrupt state (turning it ON if it was ON before, or OFF if it was OFF before).

The official documentation for `ATOMIC_BLOCK` is here: https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html. An example usage is this:

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
        my_var_copy = my_var;
    }

The `ATOMIC_RESTORESTATE` part backs up the `SREG` register and sets up the call for `__iRestore(&sreg_save);` to occur when `sreg_save` exits this block scope, as we've already discussed, and the `ATOMIC_BLOCK` part gets converted into this: `for ( ATOMIC_RESTORESTATE, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )`. This means that the entire block is now an ingenious `for` loop which runs only once! Prior to entering the `for` loop block, `__iCliRetVal()` is called once, clearing (turning OFF) interrupts, and `__ToDo` is set to `1`, or `true`, so the `for` loop runs at least once, and then at the end of the first run it is set to `0`, or `false`, to stop the `for` loop after one single run! As we've already gone over, the `sreg_save` variable now goes out-of-scope at the closing brace and the call to `__iRestore(&sreg_save);` is made, via the gcc extension, to restore the interrupt state! Ingenious!

# How could you implement the `ATOMIC_BLOCK` functionality in Arduino in C++ (as opposed to avrlibc's gcc C version)?

In C++ (Arduino is C++, so we don't have to be limited to just C plus gcc extensions, as was the constraint in the avrlibc `ATOMIC_BLOCK` macros), you can get a similar effect using destructors in structs or classes (or, just use the avrlibc pattern shown above if you like, as that gcc C code is also perfectly valid gcc C++ code!).

## Option 1: example to create a usage style similar to C++'s [`std::lock_guard`][4]

This, for example, would implement a form of `ATOMIC_BLOCK(ATOMIC_FORCEON) {}`, using a simple class in C++:

It relies on Arduino's built-in functions [`interrupts()`](https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/) (same as avrlibc's [`sei()`][5] function) and [`noInterrupts()`](https://www.arduino.cc/reference/en/language/functions/interrupts/nointerrupts/) (same as avrlibc's [`cli()`][5] function). _I wish that Arduino also had built-in `saveInterrupts()` and `restoreInterrupts()` functions, but unfortunatley they don't. Someone will have to go file a feature request and request them, or implement them themselves and do a Pull Request (PR) on GitHub to try to get them back into the main Arduino branches._

[RUN A REAL EXAMPLE OF THIS CODE IN C++17 ONLINE HERE.][6]

    #define ATOMIC_BLOCK_FORCEON AtomicBlockForceOn atomicBlockForceOn_

    class AtomicBlockForceOn
    {
    public:
        // Constructor: called when the object is created
        inline AtomicBlockForceOn()
        {
            noInterrupts(); // turn interrupts OFF
        }

        // Destructor: called when the object is destroyed (ex: goes
        // out-of-scope)
        inline ~AtomicBlockForceOn()
        {
            interrupts(); // turn interrupts ON
        }
    };

That's it! Now use it like this:

    uint16_t my_var_copy;
    {
        ATOMIC_BLOCK_FORCEON;
        // now do whatever you want here, with interrupts disabled; ex:
        my_var_copy = my_var;
    } // the `atomicBlockForceOn_` object's destructor is called here
      // and interrupts are automatically turned back ON!

Pretty cool!

This, I imagine, is probably exactly how C++'s [`std::lock_guard`][4] is implemented! Its usage is very similar:

    void safe_increment()
    {
        const std::lock_guard<std::mutex> lock(g_i_mutex);
        ++g_i;

        std::cout << std::this_thread::get_id() << ": " << g_i << '\n';

        // g_i_mutex is automatically released when lock
        // goes out of scope
    }

## Option 2: example to create a usage style similar to avrlibc's `ATOMIC_BLOCK` macros

To obtain a usage style of `ATOMIC_BLOCK(ATOMIC_FORCEON) { }` in C++ one can definitely use the gcc C style which avrlibc uses, since that is also valid C++, but let's continue with the C++ class style shown just above instead, with just a few tweaks. We will add a couple more helper macros and a couple more functions to the class to make this work. Here it is, with a usage example shown at the end which is _identical_ to how avrlibc's `ATOMIC_BLOCK` can be used! I think this is pretty cool too.

[RUN A REAL EXAMPLE OF THIS CODE IN C++17 ONLINE HERE.][7]

    #define ATOMIC_BLOCK(type) for(type; type##_OBJECT_NAME.run(); \
        type##_OBJECT_NAME.stop())
    #define ATOMIC_FORCEON_OBJECT_NAME atomicBlockForceOn_
    #define ATOMIC_FORCEON AtomicBlockForceOn ATOMIC_FORCEON_OBJECT_NAME

    class AtomicBlockForceOn
    {
    public:
        // Constructor: called when the object is created
        inline AtomicBlockForceOn()
        {
            noInterrupts(); // turn interrupts OFF
        }

        // Destructor: called when the object is destroyed (ex: goes
        // out-of-scope)
        inline ~AtomicBlockForceOn()
        {
            interrupts(); // turn interrupts ON
        }

        // Can we run? Returns true to run the `for` loop or
        // `false` to stop it.
        inline bool run()
        {
            return run_now;
        }

        // Tell the `for` loop to stop
        inline void stop()
        {
            run_now = false;
        }

    private:
        bool run_now = true;
    };

Use it like avrlibc's `ATOMIC_BLOCK() { }` macro!

Usage example:

    uint16_t my_var_copy;
    ATOMIC_BLOCK(ATOMIC_FORCEON)
    {
        // now do whatever you want here, with interrupts disabled; ex:
        my_var_copy = my_var;
    } // the `ATOMIC_FORCEON_OBJECT_NAME` (`atomicBlockForceOn_`) object's
      // destructor is called here and interrupts are automatically
      // turned back ON!

## Further reading:
1. Nick Gammon's excellent "Interrupts" page, which is how I first got started learning about interrupts in 2012~2014 or so: https://gammon.com.au/interrupts.
1. Other answer's I've done about interrupts, locks/guards, and things:
    1. https://arduino.stackexchange.com/questions/67512/global-volatile-variable-not-being-updated-in-isr/77512#77512
    1. My own race condition problem: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why
    1. My own race condition solution, demonstrating 3 (or 4, depending on how you look at it) ways to enforce **"atomic access guards"** on AVR-based 8-bit Arduinos: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why/39693278#39693278
1. What's that weird `type##_OBJECT_NAME` thing I did in the macro anyway? Read more about _macro token concatenation_ using the `##` preprocessor operator in the official gcc C++ user manual here: https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html. Note: this also works in C of course.
1. gcc `inline` or `__inline__`, and `static inline` or `static __inline__` rules:
   https://gcc.gnu.org/onlinedocs/gcc/Inline.html

  [1]: https://en.wikipedia.org/wiki/AVR_microcontrollers
  [2]: https://www.nongnu.org/avr-libc/
  [3]: https://onlinegdb.com/HJwH1qTfw
  [4]: https://en.cppreference.com/w/cpp/thread/lock_guard
  [5]: https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
  [6]: https://onlinegdb.com/r1Cw19pGD
  [7]: https://onlinegdb.com/ByNKyc6Gv


message:
How can i develop a fish tank automation using arduino

As a part of my final year Engineering project I would like to develop a  fish tank automation system. In my project I need to check the quality  of water concurrently and also I need to check the sedimentation of my fish tank. Which are the different types of sensors  used for this?
How can i connect it to my arduno uno?

body:
You're starting from the wrong end of the problem (the electronics).

First, you need to decide the requirements for your system.

 - Write down what your system is supposed to do: measure something? When & how often? Save or display the measurements? Control something based on the data? How precise must that control be (e.g. +/- .5 degC) (precision can be expensive)? Control something based on something other than measurements (except, perhaps, time?

 - Once you understand the requirements, then you can write down the steps the system should take to meet them; it doesn't need to be code (and probably shouldn't be, just yet).

- Decide on what to measure and how to measure it. Can't figure out a sensor for something? Maybe you can infer it from something you can sense. Or perhaps learn how quickly or how often that 'something' goes out of spec and restore it without a measurement (e.g. you presumably already know how often and how much to food to dispense).

- Now you can start thinking about electronics, sensors, and code, having a pretty good idea of what you will need to know, to acquire, and to create, to build your project (whether or not you'll be expected to actually build one).

This is an Engineering approach to design and it is almost certain your project is intended to show that you know how to do this, much more than to show you can run a fish tank.


message:
Can we control other servos with common servo code Arduino

I am trying to control MG996R using code for a typical servo (SG90)

I used an external power supply, 5V,2A
I connected the servo signal line to Arduino slot 7,
servo positive to external power supply positive,
servo ground to external power supply ground,
while leaving the Arduino power supply and ground unconnected.

I tried the below code.
it works for SG90, while MG996R is not moving at all.

```cpp

#include <Servo.h>
Servo myservo;

void setup()
{
  myservo.attach(7);  //pin 7 is the one control servo

}

void loop()
{

  for (int pos=0; pos<=60; pos++)
  {
    myservo.write(pos);
    delay(15);
  }

}

```

Is it because the different servos need different code?

body:
They work with same control signal, so the same code should work for both of them

You need make sure the ground of servo is both connected with the Arduino ground and the power supply ground (power supply ground for power supply positive, Arduino ground for the signal line)

I think SG90 worked even not connecting the Arduino ground is because the difference in design.

But you should always connect Servo ground to the Arduino ground.


message:
Better way for connecting to Arduino pins to a sensor than jumper cable

Well I have an dht21 and arduino mega. Dht21 leads look like this

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

If I use jumper cable and soldering dht21 leads with jumper cable than plug-in my arduino's socket. it looks like this below image. It dont looks safe. If the device falls to the ground or something, the cables may come out of place or the place may loosen over time. If I solder the cables under the arduino, it will be hard and looks like ugly. What is the best solution to plug-in a sensor to arduino board.

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

  [1]: https://i.stack.imgur.com/3WsYN.png
  [2]: https://i.stack.imgur.com/Z0jsg.jpg

body:
Remember the Arduino is a prototyping system and it should be easy to plug, unplug and move around connectors.

If you want a permanent solution, you should make your own PCB and you will have a huge choice of connectors suited for all imaginable purposes (for example the [JST family of connectors](https://en.wikipedia.org/wiki/JST_connector)).

There are some connectivity systems like the [Grove](https://wiki.seeedstudio.com/Grove_System/) connector that have attempted to standardize connectivity on Arduino and related platforms.


body:
One option you have is to solder your sensor leads to a set of header pins. The friction of multiple pins secured in a header will be greater than that of individual jumpers. When soldering to the header pins, use a method to secure the pins from movement, as the heat of the soldering iron may soften the plastic holding the pins.

The image below, from Digikey, is representative and does not imply correct spacing or fit for an Arduino.

[![header pine][1]][1]

Arduino solder shields are also available. This is a complete circuit board, akin to StarCat's recommendation of a custom PCB, but off-the-shelf. It allows access to all pins on the specific Arduino for which it was designed. I consider this option excessive for three connections, but include it for completeness.

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


body:
There is also the option of a [Prototyping Screw Shield](https://learn.adafruit.com/adafruit-proto-screw-shield) which converts the Arduino pins into terminal screw blocks. This makes a more permanent connection without being completely permanent.

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

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


message:
Animation of led strip with ESP32 does not work when WiFi is in use

I am using the ESP32 for a simple project. I know how to animate an led strip using atmega328p with arduino but when I animate it on the ESP32 it does not work that great. It will be nice if I can use the same ESP32 to run my entire project without having to include another MCU. **Has someone managed to be able to animate an led strip meanwhile using wifi on the ESP32** ?

This is the code I use to animate an LED stip meanwhile using wifi. I wrote this code myself so maybe I am doing something wrong. It works better than any of the libraries I have found online. The library that works best is [esp32WS2811-master][1]. But still this code works better than that library in my case.

    #include <Arduino.h>
    #include "WiFi.h"
    #include <Adafruit_NeoPixel.h>

    // we will runt the task that animates led strip on a separate core of arduino
    TaskHandle_t Task1;

    // where led pin is connected and number of leds to animate
    #define PIN 32
    #define NUM_LEDS 80

    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

    // mutex that helps enter critical sections meanwhile we animate led strip
    portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;

    // it will run on core 0 of esp32. Responsible for animating led strip.
    void loop2(void *parameter)
    {
       uint32_t _color = strip.Color(0, 0, 0);

       for (;;) // infinite loop
       {
          _color = strip.Color(0, 0, 255);

          // animation 1
          for (uint16_t i = 0; i < strip.numPixels(); i++)
          {
             strip.setPixelColor(i, _color);

             //portDISABLE_INTERRUPTS();      // arternative to portENTER_CRITICAL
             portENTER_CRITICAL(&mux);        /* start critical section */

             strip.show();

             //portENABLE_INTERRUPTS();       // alternative to portEXIT_CRITICAL
             portEXIT_CRITICAL(&mux);         /* end critical section */

             vTaskDelay(15);                  // one tick delay (15ms) in between reads for stability
          }

          // animation 2
          _color = strip.Color(0, 255, 0);
          for (uint16_t i = 0; i < strip.numPixels(); i++)
          {
             strip.setPixelColor(i, _color);

             //portDISABLE_INTERRUPTS();      // arternative to portENTER_CRITICAL
             portENTER_CRITICAL(&mux);        /* start critical section */

             strip.show();

             //portENABLE_INTERRUPTS();       // alternative to portEXIT_CRITICAL
             portEXIT_CRITICAL(&mux);         /* end critical section */

             vTaskDelay(15);                  // one tick delay (15ms) in between reads for stability
          }
       }
    }

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

       // disabling wifi helps but we need it
       // WiFi.mode(WIFI_OFF);

       // init led strip
       strip.begin();
       strip.setBrightness(4);
       strip.show(); // Initialize all pixels to 'off'

       // create a task that runs on core 0 of esp32
       xTaskCreatePinnedToCore(
           loop2,
           "Task_1",
           1000,
           NULL,
           2, // priority of 0 is the lowest.
           &Task1,
           0 // use core 0. Core 1 is the default core
       );

       // continue running code on default core 1 of esp32

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

       Serial.println("Setup done");
    }

    // on main loop scan network just to show how led strip does not work great when wifi is in use
    // This code I copied and pasted from the WiFi examples of the esp32
    void loop()
    {
       Serial.println("scan start");

       // WiFi.scanNetworks will return the number of networks found
       int n = WiFi.scanNetworks();
       Serial.println("scan done");
       if (n == 0)
       {
          Serial.println("no networks found");
       }
       else
       {
          Serial.print(n);
          Serial.println(" networks found");
          for (int i = 0; i < n; ++i)
          {
             // Print SSID and RSSI for each network found
             Serial.print(i + 1);
             Serial.print(": ");
             Serial.print(WiFi.SSID(i));
             Serial.print(" (");
             Serial.print(WiFi.RSSI(i));
             Serial.print(")");
             Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
             delay(10);
          }
       }
       Serial.println("");

       // wait 5 seconds for next network scan
       auto end = millis() + (unsigned long)5000;
       while(millis() < end)  {
          vTaskDelay(1);
       }

    }

When I run this code the first led flickers. The other LEDs animate great 99.99% of the time. When I disable WiFi this code works great. I still need `portENTER_CRITICAL(&mux);` or `portDISABLE_INTERRUPTS();` for it to work even if I disable WiFi. Has anyone managed to be able to animate an led-strip with the ESP-32 successfully meanwhile using WiFi?

If I am required to use a separate micro controller which one do you guys recommend? The [ATtiny85][2]?

  [1]: https://github.com/bertmelis/esp32WS2811
  [2]: https://www.microchip.com/wwwproducts/en/ATtiny85

body:
I used the FastLed library and it works now. For some reason the adafruit library only works when I am not using the WiFi. This code works:

    #include "Arduino.h"
    #include <FastLED.h>
    #include "WiFi.h"

    // we will runt the task that animates led strip on a separate core of arduino
    TaskHandle_t Task1;

    #define LED_PIN 32
    #define NUM_LEDS 108
    #define BRIGHTNESS 10
    #define LED_TYPE WS2811
    #define COLOR_ORDER GRB
    CRGB leds[NUM_LEDS];

    #define UPDATES_PER_SECOND 100

    // scan the network every 5 seconds
    void loop2(void *parameter)
    {
        for (;;)
        {
            Serial.println("scan start");

            // WiFi.scanNetworks will return the number of networks found
            int n = WiFi.scanNetworks();
            Serial.println("scan done");
            if (n == 0)
            {
                Serial.println("no networks found");
            }
            else
            {
                Serial.print(n);
                Serial.println(" networks found");
                for (int i = 0; i < n; ++i)
                {
                    // Print SSID and RSSI for each network found
                    Serial.print(i + 1);
                    Serial.print(": ");
                    Serial.print(WiFi.SSID(i));
                    Serial.print(" (");
                    Serial.print(WiFi.RSSI(i));
                    Serial.print(")");
                    Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
                    delay(10);
                }
            }
            Serial.println("");

            vTaskDelay(5000);
        }
    }

    void setup()
    {

        Serial.begin(115200);

        delay(1000); // power-up safety delay
        FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
        FastLED.setBrightness(BRIGHTNESS);

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

        // create a task that runs on core 0 of esp32
        xTaskCreatePinnedToCore(
            loop2,
            "Task_1",
            1000,
            NULL,
            2, // priority of 0 is the lowest.
            &Task1,
            1 // use core 0. Core 1 is the default core
        );

        Serial.println("Setup done");
    }

    void loop()
    {

        // red
        for (int i = 0; i < NUM_LEDS; i++)
        {
            leds[i] = 0xFF0000;
            FastLED.show();
            FastLED.delay(25);
        }

        // green
        for (int i = 0; i < NUM_LEDS; i++)
        {
            leds[i] = 0x00FF00;
            FastLED.show();
            FastLED.delay(25);
        }

        // blue
        for (int i = 0; i < NUM_LEDS; i++)
        {
            leds[i] = 0x0000FF;
            FastLED.show();
            FastLED.delay(25);
        }

        // rgb red green blue

        //ChangePalettePeriodically();
        //FillLEDsFromPaletteColors( startIndex);
    }


message:
How to ssh via USB Ethernet adapter

For a few days now, I have been connecting to my board which is hooked up to my router through a clutter of wires, over Wi-Fi. To spare my family from the risk of tripping, or hogging the extension cords all to myself, I'm looking for a way to establish an ssh connection directly from my computer (either via a USB Ethernet or a Thunderbolt Ethernet adapter).

My question is *what address* will I be looking for? Is it something like `arduinoname.local`?

body:
    ssh root@[arduinoname].local

does the trick. Just replace [arduinoname] with your board's name: `ssh root@myboard.local`

Seems to take a minute or two to initialize, so if it doesn't work immediately don't give up right away!

This however won't allow you to access your internet, so I'll still have to connect to my router if I'm going to be downloading anything.


message:
4-digit 7-segment display not showing value properly

I'm trying to add a 4-digit 7-segment display to an existing project (a temperature & relative humidity sensor) to show the temperature on the display.

I bought the display a long time ago and I it doesn't have any ID and I don't have any reference to a schematic, so I followed [this article][1] to find out both if it's a common cathode or anode and the pinout.

It turns out it's a common cathode display and the pinout goes like this (numbered from upper left):

1 -> D1
2 -> A
3 -> F
4 -> D2
5 -> D3
6 -> B
7 -> E
8 -> D
9 -> DP
10 -> C
11 -> G
12 -> D4

Where D{1,2,3,4} are the digit control pins and the rest are the segments.

So I added the [SevSeg][2] library to my project. And the sketch compiles, but when I upload it to my Arduino Uno all the LEDs in the digits 1 and 4 light up and digits two and three remain off.

I checked the pinout twice, with the same results and the display doesn't seem to be damaged. Do you see any issue on [my code][3]?

Thanks in advance!

  [1]: https://www.circuitbasics.com/arduino-7-segment-display-tutorial/
  [2]: https://github.com/DeanIsMe/SevSeg
  [3]: https://gitlab.com/phase-5-labs/nido/-/blob/master/sketches/am2302_blynk_selfhosted_display/am2302_blynk_selfhosted_display.ino

body:
Your issue could be in code or in your hardware.

To work out which one, try running one of the example sketches like the `testWholeDisplay.ino` that comes with the library you are using. This way you have known working code and you are testing that your hardware is wired up correctly. If this step doesn't work, then you need to look into your wiring and/or setup.

If using the example sketch works, then you can start looking into your sketch. Divide it into chunks and test each chunk independently. If any chunk doesn't work then work out what is different from the example sketches compared to your code.


body:
What caused the problem of the digit that driven by pin 12 is quite obvious to me. You use pin 11, 12, 13, 14 for driving the 7-segment digits. While SPI library by default uses pin 10, 11, 12, 13 as SS, MOSI, MISO and SCK, and set pin  12 (MISO) as `INPUT` which is in conflict with your pin 12 (as an `OUTPUT`) for driving the digit.

Pin 13 is also used by the interval blinking LED (i.e. `BUILTIN_LED`) when defined as a digital i/o.

Your code uses quite a few libraries, and those libraries could uses some of the I/O pins, I would suggest you reduce your code to only the code related to SevSeg, set the display to all '8888', and add each library one by one back to find out what caused the problem.


body:
Reverse engineering your code, which is generated by [https://examples.blynk.cc][1], I have found that you are using:

 - an Arduino Uno
 - [W5100 Ethernet shield][2] (or [Arduino Ethernet Rev3][3])
 - [DHT11][4]
 - 4-digit 7 segment display

Your Blynk example code looked something like [this][5].

For the 7 segment display you are using pins 3, 5, 6, 7, 8, 9, 11, 12, 13, A0, A1, A2.

    byte digitPins[] = { 11, 12, 13, A2};
    byte segmentPins[] = {3, A0, 5, 6, 7, 8, 9, A1};

However, the W5100 Ethernet controller uses pins 10, 11, 12 and 13 as seen on the [Arduino Ethernet webpage][3]:

> NB: Pins 10, 11, 12 and 13 are reserved for interfacing with the Ethernet module and should not be used otherwise. This reduces the number of available pins to 9, with 4 available as PWM outputs.

Pins 2 & 4 are used for the DHT11 and SD card chip select respectively.

All you have to do is change the wiring of the seven segment display to not use pins 11, 12 and 13, and then adjust your sketch accordingly. For example, you could use A3, A4 & A5.

  [1]: https://examples.blynk.cc
  [2]: https://www.arduino.cc/en/Main/ArduinoEthernetShieldV1
  [3]: https://store.arduino.cc/usa/arduino-ethernet-rev3-without-poe
  [4]: https://learn.adafruit.com/dht?view=all
  [5]: https://examples.blynk.cc/?board=Arduino Uno&shield=Ethernet Shield W5100&example=More/DHT11


message:
Reading SNMP V2 OID from ESP8266/ESP32

i need to read from my ESP32/ESP8266 some SNMP V2 OID values from my home printer: it exists a library/method that can do that?

I've seen some SNMP agents, but they works only with the devie as server and not as SNMP client.

Any thoughts?

body:
Not sure if you found it, but there I created an SNMP Manager: https://github.com/shortbloke/Arduino_SNMP_Manager

There is also an SNMP Agent: https://github.com/0neblock/Arduino_SNMP

I know this is a bit later than when you requested this info. But posting here in case it's still helpful to you or others that stumble over this question.