message:
Broken USB connection

When I connected an external power supply to my Arduino Uno R3 (it was connected to PC via USB cable too), I heard Windows disconnected device sound and the device isn't visible since then (nothing happens when I plugin the USB). Cable is ok, because it works with the second Arduino. TX/RX LEDs don't blink anymore.

[Following this guide][1], I checked two things:

 - I was able to flash ATMEGA328 with LED blinking program using external ICSP programmer and it worked
 - I was able to flash ATMEGA16U2 with [the official firmware][2] and it completed without any error

Is there anything else I can check? I'm not really desperate to fix it - I just want to know which component is broken.

  [1]: https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/13293#13293
  [2]: https://github.com/technologiescollege/arduino/blob/master/hardware/arduino/avr/firmwares/atmegaxxu2/Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex

body: Is it possible you connected the 12V to the 5 volt pin. This would probably blow the port on windows and destroy the arduino but it appears you got lucky with the arduino. Try something else not related to the Arduino stuff after powering down and restarting the windows computer. If that does not work the odds are high the Windows port is blown. If it now is working try again you may be all set.


sender: user

message:
Arduino Leonardo - Setting up bluetooth - AT command from terminal does not return anything

I am trying to setup bluetooth with a board that contains **Arduino Leonardo** chip.

My full setup is:

The main board: [https://www.dfrobot.com/product-1148.html][1]

The base shield: [https://coolcomponents.co.uk/products/grove-base-shield-for-arduino-v2][2]

The bluetooth module: [https://wiki.seeedstudio.com/Grove-Serial_Bluetooth_v3.0/][3]

The bluetooth module is connected to D8 port of the base shield.
The reason is "not all pins on the Leonardo and Micro support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)." as explained here: https://www.arduino.cc/en/Reference/SoftwareSerial

Here is the full code.

    #include <SoftwareSerial.h>   //Software Serial Port

    /*Connect your Bluetooth Module to D8 otherwise it will not work due to Arduino Leonardo */

    #define RxD         8
    #define TxD         9

    SoftwareSerial blue(RxD,TxD);

    void setup()
    {
        Serial.begin(9600);
        blue.begin(9600); //anything other than 9600 will not work

        // wait for serial port to connect. Needed for native USB
        while(!Serial){
        ;
        }

        pinMode(RxD, INPUT);
        pinMode(TxD, OUTPUT);

        Serial.print("Started\n");
        setupBlueToothConnection();

    }

    void loop() {
    char recvChar;
        while(1)
        {
            if(blue.available())
            {//check if there's any data sent from the remote bluetooth shield
                recvChar = blue.read();
                Serial.print(recvChar);

            }
            if(Serial.available())
            {//check if there's any data sent from t he local serial terminal, you can add the other applications here
                recvChar  = Serial.read();
                blue.print(recvChar);
                delay(400);
            }
        }
    }

    void setupBlueToothConnection()
    {
      //blue.begin(9600);

      blue.print("AT");
      delay(400);

      blue.print("AT+ROLES");  // set the role as slave
      delay(400);

      blue.print("AT+NAMESlave");   // set the bluetooth name as "Slave" ,the length of bluetooth name must less than 12 characters.
      delay(400);

      blue.print("AT+AUTH1");
      delay(400);
      blue.flush();
    }

The output from the Serial Monitor (set as BOTH NL & CR, 9600) as follows:

    Started
    OKOK+Set:SOK+Set:SlaveOK+Set:1

The problem is when I send AT commands from terminal I get nothing in return.
However if I send AT command from the IDE, I am getting feedback from the bluetooth.

  [1]: https://www.dfrobot.com/product-1148.html
  [2]: https://coolcomponents.co.uk/products/grove-base-shield-for-arduino-v2
  [3]: https://wiki.seeedstudio.com/Grove-Serial_Bluetooth_v3.0/

sender: assistant

body:
The issue is fixed.

**Note:** This is the version includes **Serial1** rather than **SoftwareSerial**. The rest is the same.

**Serial.read()**

> Returns the first byte of incoming serial data available.

So, when I send AT command from terminal, it does send "A" and then "T" rather than "AT" as a string which Bluetooth expects as stated in the [product's documentation][1]:

> AT Command format: Uppercase AT command format. string format, without any other symbol. (e.g. \r or \n).

Hence, I have added the following function:

    String SerialString() {   // Function to generate string from chars sent via Serial Monitor

      String inputString = "";  // to hold the string

      while (Serial.available()) {

        char inputChar = (char)Serial.read(); // get the new byte:
        inputString += inputChar;             // add it to the inputString:
        }

        return inputString;     // returns completed string
    }

Then inside `void loop():`

    String WholeCommand = "";
    if(Serial.available() > 0){
        WholeCommand = SerialString();
        Serial1.print(WholeCommand);
      }
Now, when I send AT from Serial Monitor, I can get OK from Bluetooth.

  [1]: https://files.seeedstudio.com/wiki/Bluetooth_Shield_V2/res/Bluetooth_en.pdf


message:
RFID reading function returning null

I have a function that reads an RFID card and returns the RFID string. The function reads thr string well but I am using the ArduinoJson library to generate json.

This is the function that I am using to read RFID cards:

```c++
String rfidOku() {
  String kartid= "";
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
        kartid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
        kartid.concat(String(mfrc522.uid.uidByte[i], HEX));
    }
    kartid.toUpperCase();
    //Serial.println(kartid);
  }
  kartid.trim();
  return kartid;
}
```

And in the loop function, if a button is pressed I am getting an RFID and I am creating json using it.

```c++
    const size_t capacity = JSON_OBJECT_SIZE(4);
    DynamicJsonDocument doc(capacity);
    const String str_rfid = rfidOku();
    doc["id"] = odeme.id;
    doc["fiyat"] = odeme.fiyat;
    doc["rfid"] = str_rfid;

    serializeJson(doc, Serial);
```

When I look to serial monitor the RFID field is null. Why does this happen? I tried to write another string there, it works well with the other string  but why doesn't it with str_rfid?

I also print the value of str_rfid using Serial.print, str_rfid getting RFID card id from function well.

body:
It could be that your JSON object capacity is too small because of *string duplication* when you deserialise it to print it.

You should try a capacity like `JSON_OBJECT_SIZE(3) + 500` for deserialising, and see what happens.

Also, try: `doc["rfid"] = str_rfid.c_str();` to see if that works better (CString instead of String object).

More information on object capacity can be found [here][1]; there's a calculator [here][2].

  [1]: https://arduinojson.org/v6/how-to/determine-the-capacity-of-the-jsondocument/
  [2]: http://arduinojson.org/v5/assistant


message:
Else Statement Never Functions As Expected

I've been working on a rather simple Arduino-breadboard project, that is supposed to imitate a traffic light intersection. There are two sets of lights, one called the North-South lights, and then the East-West lights (quite similar to the traffic lights your would see at an intersection on the road). The goal is to get the traffic lights to turn their correct colors at the correct times; however, one of my yellow lights is not turning on at all, and the breadboard LEDs I'm using completely skip over the yellow light in question and go straight to the red-green configuratin that is supposed to happen after.

Here is the code I have:
```
void setup() {

  pinMode(2, OUTPUT); //R-ns
  pinMode(3, OUTPUT); //Y-ns
  pinMode(4, OUTPUT); //G-ns
  pinMode(5, OUTPUT); //R-ew
  pinMode(6, OUTPUT); //Y-ew
  pinMode(7, OUTPUT); //G-ew

}

void loop() {

  for(int count = 0; count<16; count++) {

    if (count<7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, HIGH);
      }

     else if (count==7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      }

     else if (7<count<15) {
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

     else {
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

    delay(1000);
    }

}
```
As you can see, the North-South traffic light is supposed to turn on at the 16th second, except I don't see it happen on the physical LED. I don't understand why this is happening; can anyone explain what is happening?

body:
`7<count<15` is interpreted as `(7<count)<15`.  `7<count` will result in a false or true, which will be interpreted as 0 and 1 when later involved in the `< 15` part of the expression, which means `7<count<15` is always true.

What you're probably looking for is `7 < count && count < 15`.


message:
I can't find what I did wrong

```c++
int lightPin = 13;
int buttonPin = 2

void setup() {
  pinMode(lightPin, OUTPUT); //red
  pinMode(buttonPin, INPUT);
}

void loop() {
  int buttonValue = digitalRead(buttonPin);

  if (buttonValue == HIGH) {
    digitalWrite(13, HIGH);
  }  //red

  digitalWrite(13, LOW);//red
}  //red
```

body:
In this example your missing a semi-colin after ```int buttonPin = 2```, and your if statement should probably look like this
```
if (buttonValue == HIGH){
  digitalWrite(lightpin, HIGH);
}//red

else{
  digitalWrite(lightpin, LOW);//red
}//red/*
```

Also if you go into the examples in the Arduino IDE, under "digital", this sketch is called button.


message:
NodeMCU, Failed to compile code because of multiple library errors

i was getting multiple errors and cannot able to figure out what it is

```
   Arduino: 1.8.13 (Windows 10), Board: "NodeMCU 0.9 (ESP-12 Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

In file included from E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:29:0:

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.h:27:7: error: redefinition of 'class WiFiUDP'

 class WiFiUDP : public UDP {

       ^

In file included from E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\utility/wifi_drv.h:26:0,

                 from E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:26:

C:\Users\ben\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi\src/WiFiUdp.h:32:7: error: previous definition of 'class WiFiUDP'

 class WiFiUDP : public UDP, public SList<WiFiUDP> {

       ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In constructor 'WiFiUDP::WiFiUDP()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:35:22: error: class 'WiFiUDP' does not have any field named '_sock'

 WiFiUDP::WiFiUDP() : _sock(NO_SOCKET_AVAIL) {}

                      ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual uint8_t WiFiUDP::begin(uint16_t)':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:45:9: error: '_sock' was not declared in this scope

         _sock = sock;

         ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:46:9: error: '_port' was not declared in this scope

         _port = port;

         ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::available()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:56:7: error: '_sock' was not declared in this scope

   if (_sock != NO_SOCKET_AVAIL)

       ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual void WiFiUDP::stop()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:66:8: error: '_sock' was not declared in this scope

    if (_sock == NO_SOCKET_AVAIL)

        ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:69:26: error: '_sock' was not declared in this scope

    ServerDrv::stopClient(_sock);

                          ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::beginPacket(IPAddress, uint16_t)':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:88:7: error: '_sock' was not declared in this scope

   if (_sock == NO_SOCKET_AVAIL)

       ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:90:7: error: '_sock' was not declared in this scope

   if (_sock != NO_SOCKET_AVAIL)

       ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::endPacket()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:101:32: error: '_sock' was not declared in this scope

  return ServerDrv::sendUdpData(_sock);

                                ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual size_t WiFiUDP::write(const uint8_t*, size_t)':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:111:27: error: '_sock' was not declared in this scope

  ServerDrv::insertDataBuf(_sock, buffer, size);

                           ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::read()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:125:23: error: '_sock' was not declared in this scope

    ServerDrv::getData(_sock, &b);

                       ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::read(unsigned char*, size_t)':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:137:31: error: '_sock' was not declared in this scope

    if (!ServerDrv::getDataBuf(_sock, buffer, &size))

                               ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual int WiFiUDP::peek()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:152:22: error: '_sock' was not declared in this scope

   ServerDrv::getData(_sock, &b, 1);

                      ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual IPAddress WiFiUDP::remoteIP()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:166:25: error: '_sock' was not declared in this scope

  WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort);

                         ^

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp: In member function 'virtual uint16_t WiFiUDP::remotePort()':

E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi\src\WiFiUdp.cpp:176:25: error: '_sock' was not declared in this scope

  WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort);

                         ^

Multiple libraries were found for "WiFi.h"

 Used: E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\WiFi

 Not used: E:\Programming\Electronics lab\ARDUINO\sketch\libraries\WiFiNINA

Multiple libraries were found for "HttpClient.h"

 Used: E:\Programming\Electronics lab\ARDUINO\sketch\libraries\HttpClient

 Not used: E:\Programming\Electronics lab\ARDUINO\sketch\libraries\ArduinoHttpClient

 Not used: E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\Bridge

 Not used: E:\Programming\Electronics lab\ARDUINO\arduino-1.8.13-windows\arduino-1.8.13\libraries\HttpClient

 Not used: C:\Users\ben\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\HttpClient

exit status 1

Error compiling for board NodeMCU 0.9 (ESP-12 Module).

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

Please help me to fix this

Thanks & Regardsm
Ben

body: Remove `#include <WiFi.h>`; it is not intended to be used with your NodeMCU.


message:
Making HTTPS requests using ESP8266 AT commands

I am trying to make HTTPS GET/POST requests to the following server using AT commands.

    AT+CIPSTART="TCP","54.166.71.140 ",443

I get errors when i use port 443 but on port 80 the requests are successful.

How can i get around this issue ? what could be potential solutions ?

body:
HTTPS requires that you make an SSL connection not a TCP connection.  To do that you need to use

```
AT+CIPSTART="SSL","54.166.71.140 ",443
```

You also need to configure SSL itself.

However the SSL support is not great and struggles with some sites (no SNI support by all accounts).

So you're better off programming the ESP8266 directly with your own sketch to make any HTTPS requests and process the data for you.


message:
Arduino Due: JTAG and SWD do not work after pressing erase button

I have an Arduino Due board. I can successfully upload code to it using Arduino upload via USB.
However I am also exploring another approach, which is to upload code via Atmel studio using an Atmel ICE and JTAG connection. Usually this works fine (the code uploads, and a simple "blink" sketch makes the onboard LED flash).

However when I press the erase button, and then try to upload the same sketch via Atmel Studio and JTAG, something strange happens. The code uploads fine:

    Erasing device... OK
    Programming Flash...OK
    Verifying Flash...OK

But then the program on the Due does not actually execute. The LED does not start to 'blink'. If I then again upload via USB (programming port) and the Arduino IDE, the blink program does work. And when I then upload via Atmel Studio and JTAG again without pressing the erase button, everything happens as expected too (LED blinks etc).
Does anyone have any idea what might be going on? The reason I ask is because I would like to design a board using only a JTAG connection. Do you think the above problem could cause issues when using a 'blank' factory SAM MCU as well?

EDIT: the same problem applies to SWD.

Blink sketch that i am uploading:

    #define led LED_BUILTIN

    // the setup routine runs once when you press reset:
    void setup() {
      // initialize the digital pin as an output.
      pinMode(led, OUTPUT);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(600);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(600);               // wait for a second
    }

body:
After uploading via Microchip Studio, go to the GPNVM bits section of "device programming" window. Make sure boot mode is set to "boot from flash". Also check that GPNVMBITS register is set to 0x00000002. Then press "program". The sketch you uploaded to the MCU should now work.

So it seems what happens is that pressing the erase button resets the GPNVM bits so that the MCU boots from ROM, but then Atmel ICE + JTAG/SWD does not set the boot mode back to flash after (succesfully) programming the MCU.


message:
FastLED-driven strip acts weird when using PN532

A LED-strip (WS2812B, 46 pieces, PIN 8) and an Adafruit PN532 RFID shield (IRQ 2) are attached to my Arduino Mega 2560.

The GRB based strip seems to be working fine with FastLED in the beginning, I can confirm this by cycling through all three base colours in `setup()`.

Once I call `nfc.readPassiveTargetID(...)` and use an NFC tag on it, things start to get weird. Whenever I comment out the line, it works properly again.
The colors RGB are randomly swapped (as if I had passed a different color ordering), brightnesses may change randomly as well, and sometimes a few LEDs in the beginning or end of the strip have different brightness/color as the rest.

As I have put the brightness down to 32, I'm sure it's not a power problem.

My assumption is that there is either some memory corruption, or some PIN interference with the two libraries, although I don't know why it would do it. Please find my code below, any help is appreciated.

      #include <FastLED.h>
      #include <Adafruit_PN532.h>

      #define LED_COUNT 46
      #define LED_DATA_PIN 8
      CRGB leds[LED_COUNT];

      #define PN532_IRQ (2)
      #define PN532_RESET (3) // Not connected

      Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

      void setLeds(CRGB color) {
        Serial.print("setLeds("); Serial.print(color.r, DEC ); Serial.print(","); Serial.print(color.g, DEC ); Serial.print(","); Serial.print(color.b, DEC ); Serial.println(")");
        for (int i = 0; i < LED_COUNT; i++) {
          leds[i] = color;
        }
        FastLED.show();
      }

      void ledStartSequence() {
        setLeds(CRGB::Black);
        for (int crtLed = 0; crtLed < 23; crtLed++) {
          leds[crtLed] = CRGB::Blue;
          leds[crtLed + 23] = CRGB::Blue;
          FastLED.show();
          delay(20);
        }
        Serial.println("Red");
        setLeds(CRGB::Red);
        delay(1000);
        Serial.println("Green");
        setLeds(CRGB::Green);
        delay(1000);
        Serial.println("Blue");
        setLeds(CRGB::Blue);
        delay(1000);

        Serial.println("Off");
        setLeds(CRGB::Black);
      }

      void initLeds() {
        FastLED.addLeds<WS2812B, LED_DATA_PIN, GRB>(leds, LED_COUNT);
        FastLED.setBrightness(32);
      }

      void initSerial() {
        Serial.begin(9600);
        Serial.println("Hello!");
      }

      void initNFC() {
        nfc.begin();
        uint32_t versiondata = nfc.getFirmwareVersion();
        Serial.print(versiondata);
        if (! versiondata) {
          Serial.print("Error: Didn't find PN53x board");
          while (1); // halt
        }
        // Got ok data, print it out!
        Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
        Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
        Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

        nfc.SAMConfig();
      }

      void setup() {
        initSerial();
        initLeds();
        initNFC();
        ledStartSequence();
      }

      void loop(void) {
        Serial.println("Waiting for an ISO14443A Card ...");
        setLeds(CRGB::Red); // only displayed correctly in the first iteration
        uint8_t success;
        uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
        uint8_t uidLength;

        success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
        /*
         *  Here's where things start to go nuts!
        */
        delay(1000);
        setLeds(CRGB::Green); // usually not displayed correctly
        delay(1000);
        setLeds(CRGB::Blue); // usually not displayed correctly
        delay(1000);
      }

body:
After spending way too much time on the code, I figured that it had to do with something entirely different:

The RFID reader created an RF interference on the data wire towards the LED strip... Shielding it properly did the trick, no matter which pin is being used.

Thanks for the help anyway.


message:
What's wrong? FastLED and WS2812B simulation works, physical build doesn't

I'm new to Arduino coding and FastLED. When it comes to coding, I'm a complete novice, however, I've been watching YouTube tutorials to help my knowledge. I have successfully run my code on [Wokwi](https://wokwi.com/playground/fastled?utm_source=reddit&utm_medium=social&utm_campaign=r_fastled), however, when I upload my code to my Arduino, it uploads without error, yet the WS2812B doesn't run the code correctly and appears to freeze after the first pattern.

The LED strip works just run with my Adafruit code, running a very basic set of patterns I created (different than the below code).

Any help would be greatly appreciated! The code below is what I wrote up in Wokwi and the simulation works flawlessly. The only change when uploading to my Arduino is: NUM_LEDS  135

    #include <FastLED.h>
    #define NUM_LEDS  16
    #define LED_PIN   5
    #define BRIGHTNESS  255
    #define caseCount 7
    CRGB source1[NUM_LEDS];
    CRGB source2[NUM_LEDS];
    CRGB output[NUM_LEDS];

    DEFINE_GRADIENT_PALETTE (christmasBlue_gp) {
      0, 0, 0, 255,
      64, 0, 0, 135,
      127, 255, 255, 255,
      191, 0, 0, 135,
      255, 0, 0, 255
    };
    CRGBPalette16 bluePal = christmasBlue_gp;

    uint8_t blendAmount = 0;
    uint8_t patternCounter = 0;
    uint8_t source1Pattern = 0;
    uint8_t source2Pattern = 1;
    bool useSource1 = false;

    void setup() {
      FastLED.addLeds<WS2812B, LED_PIN, GRB>(output, NUM_LEDS);
      FastLED.setBrightness(BRIGHTNESS);
    }

    void loop() {

      EVERY_N_MILLISECONDS(5) {
        blend(source1, source2, output, NUM_LEDS, blendAmount);
        if (useSource1) {
          if (blendAmount < 255) blendAmount++;
          } else {
          if (blendAmount > 0) blendAmount--;
          }
      }

      EVERY_N_SECONDS(5) {
        nextPattern();
      }
      runPattern(source1Pattern, source1);
      runPattern(source2Pattern, source2);
      FastLED.show();
    }

    void nextPattern() {
      patternCounter = (patternCounter + 1) % caseCount;
      if (useSource1) source1Pattern = patternCounter;
      else source2Pattern = patternCounter;
      useSource1 = !useSource1;
      }

    void runPattern(uint8_t pattern, CRGB *LEDArray) {
      switch (pattern) {
        case 0:
          movingDots(LEDArray);
          break;
        case 1:
          whiteFill(LEDArray);
          break;
        case 2:
          greenFill(LEDArray);
          break;
        case 3:
          whiteFill(LEDArray);
          break;
        case 4:
          redFill(LEDArray);
          break;
        case 5:
          greenBlueTwinkle(LEDArray);
          break;
        case 6:
          greenRedSplit(LEDArray);
          break;
      }
    }

    void movingDots(CRGB *LEDarray) {
      uint16_t posBeat = beatsin16(30, 0, NUM_LEDS -1, 0, 0);
      uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS -1, 0, 0);
      uint16_t posBeat3 = beatsin16(25, 0, NUM_LEDS -1, 0, 127);
      uint16_t posBeat4 = beatsin16(45, 0, NUM_LEDS -1, 0, 127);
      LEDarray[(posBeat + posBeat2) / 2] = CHSV(0, 255, 255);
      LEDarray[(posBeat3 + posBeat4) / 2] = CHSV(120, 255, 255);
      LEDarray[(posBeat3 + posBeat2) / 2] = CHSV(120, 255, 255);
      LEDarray[(posBeat2 + posBeat4) / 2] = CHSV(0, 255, 255);
      LEDarray[(posBeat2 + posBeat4 + posBeat) / 3] = CHSV(0, 0, 255);
      fadeToBlackBy(LEDarray, NUM_LEDS, 1);
    }

    void whiteFill(CRGB *LEDarray) {
      fill_solid(LEDarray, NUM_LEDS, CRGB::White);
    }

    void greenFill(CRGB *LEDarray) {
      fill_solid(LEDarray, NUM_LEDS, CRGB::Green);
    }

    void redFill(CRGB *LEDarray) {
      fill_solid(LEDarray, NUM_LEDS, CRGB::Red);
    }

    void greenBlueTwinkle(CRGB *LEDarray) {
      EVERY_N_MILLISECONDS(50){
        LEDarray[random8(0, NUM_LEDS-1)] = ColorFromPalette(bluePal, random8(), 255, LINEARBLEND);
        }
      fadeToBlackBy(LEDarray, NUM_LEDS, 1);
      FastLED.show();
    }

    void greenRedSplit(CRGB *LEDarray) {
      for(int i = 0; i < NUM_LEDS; i++) {
        LEDarray[i] = CHSV(0, 255, 255);
        LEDarray[(NUM_LEDS-1-i)] = CHSV(120, 255, 255);
        FastLED.show();
        delay(100);
        LEDarray[i] = CHSV(0, 255, 255);
      }

      for(int i = NUM_LEDS - 1; i >= 0; i--) {
        LEDarray[i] = CHSV(120, 255, 255);
        LEDarray[(NUM_LEDS-1-i)] = CHSV(0, 255, 255);
        FastLED.show();
        delay(100);
        LEDarray[i] = CHSV(120, 255, 255);
      }
    }

body:
Consider what would happen if your power supply is not powerful enough.  Depending on the number of WS2812B you are lighting at the same time you may be exceeding the current rating of your power source.  Using the following quote from [this source][1]:

> ... consider how much current your LED strip is going to pull. With every
> single LED on at full brightness, each breakout board can pull about
> 60mA (20mA per color channel).

We can calculate for a string of 15 WS2812 set to full brightness it would take 15 x 60mA or almost 1 Amp of power.  People commonly source power supply which can handle twice the expected high current load.  So, in this case you would need a supply which can source at least 2 Amps

Also consider not using the Arduino's linear voltage regulator for large current loads.  Not only does it have current limitations but it is also not as effective as a switching power supply. Instead use a power supply of the correct voltage and capable current rating for large current loads.

Try lighting only 1 LED at a time in the strip and stick to one color at a time.  If this works it is likely your power supply is not capable of supplying the necessary current to operate your project as expected.

  [1]: https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide/hardware-hookup


message:
SIM7000E 0 voltage at SIM_VDD

I have problem with my SIM7000E. My PCB scheme and design is aveliable here https://easyeda.com/jaka87/new-vetercek While sending AT commands I get error as if sim card is not connected.

I also put oscilloscope on SIM_VDD and did some measurement. To my surprise i always measure 0V even or reset and when changing from `AT+CFUN=0 to AT+CFUN=1`.
It should at least send some bursts right ?
Any idea why this is happening?

Scheme:
[![Scheme][1]][1]

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

body: After weeks i finally found the source of the issue. It turns out i mixed two labels on the PCB and therefore had wrong capacitors on VCC and data...


message:
Which sensor bus best to use?

I am working on a project which requires a dozen VL53l0X I2C-TOF sensors to be polled by one master MCU over a few meters of cable.

Thus, I decided to accompany each TOF by an Atmega8 acting as a gateway between the TOF and a Modbus (using a MAX485), which is managed by an ESP32 (the master). Since I require fairly low latency (~10 reads / sensor / second) I am a bit disappointed by the Modbus RTU performance (mostly caused by the forced 1.75ms delay between frames).

My question: Is there any quicker, more suitable, Atmega-bearable bus protocol for long distances? Ethernet is sadly not an option due to the limited slaves computing power and cost...

body: CAN for the Phy (physical) layer would be good for several thousand feet. You can use whatever baud and protocol on the CAN layer you like within reason. I am assuming (maybe in error) that they all communicate on the same bus. This CAN Phy was designed for this. It would be possible for you to write your own protocol and simply address each by a unique number or whatever. There is also the option of using a CAN controller but I think that would be a lot of time not needed to design your solution. By placing a Atmega8 at each sensor opens up a lot of possibilities for you.


message:
Help with millis to get accurate timing

I'm essentially trying to create a music box which is light activated using an LDR. When it's open a song plays, while a servo rotates a figurine back and forth, and an LED dims and illuminates in sync with the servo. The code sort of works when I don't include the analogWrite for the LED, but even then the music timing is not great. When I do include analogWrite for the LED the music is completely distorted and doesn't work whatsoever. **Is there some obvious mistake I've made? Is millis just bad for keeping time?** I'm sure there is a better way to approach this overall, but I'm still an amateur at arduino. My code works by using an array for the notes and the duration of each. I refer to the duration array and use it as dynamic intervals for my millis to keep time. Hopefully that makes sense, my coding jargon is pretty basic!
```
    #include <Servo.h>

//defining the value of the notes
#define NOTE_C4  262
#define NOTE_D4  294
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_G4  392
#define NOTE_A4  440
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
#define NOTE_A5  880
#define NOTE_B5  988

//order of the notes
int melody[] = {
   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
   NOTE_A4, NOTE_G4, NOTE_A4, 0,

   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
   NOTE_A4, NOTE_G4, NOTE_A4, 0,

   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
   NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
   NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
   NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,

   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_D5, NOTE_E5, NOTE_A4, 0,
   NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
   NOTE_C5, NOTE_A4, NOTE_B4, 0,

   NOTE_A4, NOTE_A4,

   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
   NOTE_A4, NOTE_G4, NOTE_A4, 0,

   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
   NOTE_A4, NOTE_G4, NOTE_A4, 0,

   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
   NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
   NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
   NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,

   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
   NOTE_D5, NOTE_E5, NOTE_A4, 0,
   NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
   NOTE_C5, NOTE_A4, NOTE_B4, 0,

   NOTE_E5, 0, 0, NOTE_F5, 0, 0,
   NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
   NOTE_D5, 0, 0, NOTE_C5, 0, 0,
   NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4,

   NOTE_E5, 0, 0, NOTE_F5, 0, 0,
   NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
   NOTE_D5, 0, 0, NOTE_C5, 0, 0,
   NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4
};

// duration of each note
int duration[] = {
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 125,

  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 125,

  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 125, 250, 125,

  125, 125, 250, 125, 125,
  250, 125, 250, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 375,

  250, 125,

  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 125,

  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 125,

  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 250, 125, 125,
  125, 125, 125, 250, 125,

  125, 125, 250, 125, 125,
  250, 125, 250, 125,
  125, 125, 250, 125, 125,
  125, 125, 375, 375,

  250, 125, 375, 250, 125, 375,
  125, 125, 125, 125, 125, 125, 125, 125, 375,
  250, 125, 375, 250, 125, 375,
  125, 125, 125, 125, 125, 500,

  250, 125, 375, 250, 125, 375,
  125, 125, 125, 125, 125, 125, 125, 125, 375,
  250, 125, 375, 250, 125, 375,
  125, 125, 125, 125, 125, 3000
};

Servo myservo;  // create servo object to control a servo

int servoPin = 9;
int ledPin = 11;
int buzzerPin = 3;
int sensorPin = A4;
int sweep = 0; // variable to control which direction the servo is moving
int sensorValue = 0;
int counter = 0; //a counter to keep track of which note the song is up to
float tempo = 1; // a variable for the tempo - lower number = faster temp (2 =  double speed)
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
int threshold = 500;

void setup()
{
  myservo.attach (servoPin);
  pinMode (ledPin, OUTPUT);
  pinMode (buzzerPin, OUTPUT);
  pinMode (sensorPin, INPUT);
  Serial.begin(9600);
}

void loop(){

sensorValue = analogRead (sensorPin);
if (sensorValue > threshold)
{

  if (sweep == 0)
  {

    for (int pos = 0; pos <= 180; pos ++) // goes from 0 degrees to 180 degrees in steps of 1 degree
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      analogWrite(ledPin, map(pos, 0, 180, 0, 255)); //mapping the value from the for loop to get the full range of PWM for led fading

        currentMillis = millis();
        if (currentMillis - previousMillis > duration[counter]/tempo)
        {
          tone(buzzerPin, melody[counter], duration[counter]/tempo);
          counter++;
          previousMillis = currentMillis;
        }

          if (counter == 196)
          {
            counter = 0; //reset the counter so the song starts again
          }

            if (pos == 179)
            {
              Serial.println("SWEEP 1");
              sweep = 1;
            }

              sensorValue = analogRead (sensorPin);
              if (sensorValue < threshold)
                {
                  break;
                }
     }
  }

  if (sweep == 1)
  {

    for (int pos = 180; pos >= 0; pos --)  // goes from 180 degrees to 0 degrees
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      analogWrite(ledPin, map(pos, 0, 180, 0, 255));

       currentMillis = millis();
       if (currentMillis - previousMillis > duration[counter]/tempo)
        {
          tone(buzzerPin, melody[counter], duration[counter]/tempo);
          counter++;
          previousMillis = currentMillis;
        }

          if (counter == 196)
          {
            counter = 0;
          }

            if (pos == 1)
            {
              sweep = 0;
              Serial.println("SWEEP 2");
            }

              sensorValue = analogRead (sensorPin);
              if (sensorValue < threshold)
                {
                  break;
                }
    }
  }
}

   if (sensorValue <= threshold) //if the light is low turn the servo back to starting point and stop doing anything
   {
    Serial.println("OFF");
    noTone(buzzerPin);
    myservo.write(0);
    counter = 0;
   }
}
```

body:
If you're still interested in refactored code, here is your code with `for` loops removed and restructured so state is tracked/updated appropriately in the `void loop()` as below:

```
[your variable declaration code as given]
...
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
int threshold = 500;

int pos = 0;
int dir = 1;

void setup()
{
  myservo.attach (servoPin);
  pinMode (ledPin, OUTPUT);
  pinMode (buzzerPin, OUTPUT);
  pinMode (sensorPin, INPUT);
  Serial.begin(9600);
  pos = 0;
  dir = 1;
  previousMillis = millis();
}

void loop(){

 sensorValue = analogRead (sensorPin);
 if (sensorValue > threshold)
 {
  pos += dir;
  if (pos == 180) || (pos == 0)
  {
   dir *= -1;
  }

  myservo.write(pos);
  analogWrite(ledPin, map(pos, 0, 180, 0, 255));

  currentMillis = millis();

  if ((currentMillis - previousMillis) > duration[counter]/tempo)
  {
   tone(buzzerPin, melody[counter], duration[counter]/tempo);
   counter += (counter > 195) ? -196 : 1;
   previousMillis = currentMillis;
  }
 }
 else
 {
  Serial.println("OFF");
  noTone(buzzerPin);
  myservo.write(0);
  counter = 0;
  pos = 0;
  dir = 1;
 }
}
```


message:
Difference between FreeRTOS libary (AVR_ATmega328PB_Xplained_mini_GCC) Versus FreeRTOS compatible for Arduino boards from Richard barrey

I am researching about different IoT development boards and found that espressif uses IDF framework. When looked at the source code it uses FreeRTOS libraries. I have Arduino Uno and i wanted to use FreeRTOS for programming Arduino Uno. After search i found that FreeRTOS has multiple libraries that supports different micro controllers. Arduino Uno has ATMega328P and FreeRTOS has libraries for ATMega328P (link below)

https://github.com/FreeRTOS/FreeRTOS/tree/master/FreeRTOS/Demo/AVR_ATmega328PB_Xplained_mini_GCC

I also found that libraries created for Arduino family of boards (link below)
https://www.arduino.cc/reference/en/libraries/freertos/

I just wanted to what is the difference between these two libraries?

body:
**ATmega328PB** is not the same MCU as used by Arduino boards. Those use **ATmega328P** (no B). [ATmega328PB][1] is a mostly compatible successor and offers more timers, built-in touch functionality and more but does not come in large DIP packages. Arduino uses the older [ATmega328P][2].

  [1]: https://www.microchip.com/wwwproducts/en/atmega328pb
  [2]: https://www.microchip.com/wwwproducts/en/atmega328p


message:
Trouble with Arduino Nano Every and radio transmission using RH_RF69.h

I give some help for students working on the Cansat Contest.

I am trying to connect a RFM69 Radio Module to an Arduino Nano Every.

Nothing works : compiling the simpliest program:

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

void setup() {}

void loop() {}
```

gives the answer:

<pre>[BlaBlaBla...]
exit status 1
Erreur de compilation pour la carte Arduino Nano Every
</pre>

while everythings works on arduino M0 Feather Express or Arduino Uno.

Is there a specific problem with the Nano Every?

body:
The Nano Every uses an ATMega4809 processor, so it is different from most Arduino's. It could well be that it isn't supported by the Radiohead library.

The error you shortened to *[BlaBlaBla...]* could possibly give more information on that.

A full list of what is supported by the Radiohead library is [here][1]; you should check if the Arduino Nano Every or the ATMega4809 is on there; alternatively, all the `#define`s for the supported boards are in the [header file][2].

If it turns out your board is not supported, you could ask the library's authors if they would consider supporting it, or you could use a different board (it should work with an Arduino Nano 33 IoT, I think, but please check first).

  [1]: http://www.airspayce.com/mikem/arduino/RadioHead/
  [2]: https://github.com/adafruit/RadioHead/blob/master/RadioHead.h


body:
I was never able to make this work with the RadioHead library but did get it to work with LowPowerLab RFM69 library.  Not here to debate which one is better just stating which one i got to work without having to change any of their code.

The environment used was VSCode on M2 Mac with latest PlatformIO plugin.

Transmitter
MCU = Arduino Nano Every (just because i had it)
Radio = Adafruit RFM69HCW (915Mhz) Breakout

Receiver
MCU+Radio = Adafruit RFM69HCW Feather

For LowPowerLab libary there were two items that where gotchas for me.  The first is that I was trying to use a different IRQ pin.  Once i learned that the default defined in RFM69.h was 2 then things were easy going and more or less followed all the code examples that used no arg constructors for radio.

The second was that i needed to reset the radio.  I got this from some example adafruit(thank you) code.

```
#define RFM69_RST     4
...
...
...
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);
```
So here is my working receiver code (with a bunch of other junk)
```
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RFM69.h>
#include <SPI.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      3   // My node ID
#define FREQUENCY     RF69_915MHZ
#define RFM69_RST     4

// SPIClassMegaAVR ccc(12, 13, 11, RFM69_CS, 0);
RFM69 radio;//(RFM69_CS, RFM69_INT, true, &SPI);

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

  // put your setup code here, to run once:
  // pinMode(LED, OUTPUT);
  // digitalWrite(LED, HIGH);

  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID)) {
    Serial.println(F("radio init failed"));
    for(;;); // Don't proceed, loop forever
  }
  radio.setHighPower(); // Always use this for RFM69HCW

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.display();
  delay(2000); // Pause for 2 seconds

  display.setTextSize(2);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  display.print(F("Kris"));
  // display.startscrollright(0x00, 0x0F);

  display.display();
  Serial.println("Starting up");
  // radio.spyMode(true);
}

bool displayOnTop = true;
void displayMsg(char* msg) {
  display.clearDisplay();
  if (displayOnTop)
    display.setCursor(0,0);
  else
    display.setCursor(0, 16);
  displayOnTop = !displayOnTop;
  display.print(msg);
  display.display();
}

void loop() {

    if (radio.receiveDone()) // Got one!
  {
    // Print out the information:

    Serial.print("received from node ");
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");

    // The actual message is contained in the DATA array,
    // and is DATALEN bytes in size:

    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);

    // RSSI is the "Receive Signal Strength Indicator",
    // smaller numbers mean higher power.

    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);

    char rssi[12];
    sprintf(rssi, "RSSI: %d\0", radio.RSSI);
    displayMsg(rssi);

    // Send an ACK if requested.
    // (You don't need this code if you're not using ACKs.)

    if (radio.ACKRequested())
    {
      radio.sendACK();
      Serial.println("ACK sent");
    }
  }
}

#platformio
[env:nano_every]
platform = atmelmegaavr
board = nano_every
board_build.mcu = atmega4809
framework = arduino
lib_deps =
 adafruit/Adafruit SSD1306@^2.5.7
 lowpowerlab/RFM69@^1.5.2
monitor_speed = 115200
```

and here is my working tranmitter code (a little cleaner)
```
#include <Arduino.h>
#include <Wire.h>
#include <RFM69.h>
#include <SPI.h>

const int LED = 13;

#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      4   // My node ID

// RFM69 frequency, uncomment the frequency of your module:

#define FREQUENCY     RF69_915MHZ

#define RFM69_RST     4

RFM69 radio;

void notifyme() {
  Serial.println("I got the call!");
}

void setup() {
radio.setIsrCallback(notifyme);
  Serial.begin(115200);

  // put your setup code here, to run once:
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);

  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  pinMode(RFM69_INT, INPUT);

  if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID)) {
    Serial.println(F("radio init failed"));
    for(;;); // Don't proceed, loop forever
  }
  radio.setHighPower(); // Always use this for RFM69HCW

  Serial.println("Starting up");
}

void loop() {
  if (!radio.sendWithRetry(3, "hello", 5, 1)) {
    Serial.println("Failed to send on radio");
    digitalWrite(LED, LOW);
  } else {
    Serial.println("message sent");
    digitalWrite(LED, HIGH);
  }

  delay(5000);
}
```

Keep in mind, i'm a copy/paste warrior with the mindset of a Donkey.  If I think it can be done then i will find a way, but it won't mean I understand anything about it.  With that in mind, happy to answer any questions.  :-)


message:
How do I convert Arduino to an ATmega328P-based project?

I have an Arduino board where I am using some of the peripherals like LCD with I2C.

Now I want to convert this Arduino-based circuit to an atmega328p based circuit, i.e. atmega328p with LCD and I2C.

Here is my actual question: Can I use the same sketch (binary) that I have compiled and uploaded for the Arduino board for the atmega328p and does it work? Or do I need to write atmega328p based C++ code?

body:
Unable to write in the comments. If you are looking at using just a raw atmega328p, you can use the Arduino as ISP sketch and then upload your existing sketch to the new chip. I use it for programming ATTiny 85 chips for small stand alone projects. Here is a [Link][1]  to the Arduino site which explains this in detail.

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


body:
A compiled sketch will run just fine on a bare ATmega328p, if all the necessary surrounding components are there, and if you have a way to program it.

This could be as simple as putting the chip on the Uno and programming it there. Don't do that too often; the socket isn't intended for that. You could get a 28-pin ZIF socket, though.

There are a few things to consider:

- The bare chip needs external components like a crystal, etc. to function; you can check the [Uno's schematic][1] to see what you want to copy to your PCB/breadboard;
- You may want to include a way to program the ATmega328p in-circuit using an ISP or a USB-to-serial chip;
- The pin numbers will be different, a minor annoyance;
- Possibly things I forgot.

There is a [how-to][2] on the Arduino site, and also a [description][3] of how to build a "whole" Arduino on a breadboard.

  [1]: https://content.arduino.cc/assets/UNO-TH_Rev3e_sch.pdf
  [2]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoToBreadboard
  [3]: https://www.arduino.cc/en/Main/Standalone


body: Yes, you can use the same sketch and also the same HEX file. Though the uploading depends on your actual setup. If you include a UART USB bridge, like the Arduino has, then you can upload over USB (assuming you have burned the bootloader to the Atmega328p). Otherwise you can use your Arduino as an ISP programmer and burn your sketch onto the Atmega through it. Google for Arduino as ISP for more information


body:
The Arduino has already a 328p chip on the board, but with a bootloader and a 16MHz crystal.

If you use only the chip, you need to create a board like the arduino.
Or you can extend the IDE with this board library:
https://github.com/MCUdude/MiniCore

So you can still use the same sketch but remove the crystal for example.


body:
I've built PCBs with a standalone ATMega328p chip on them before for situations where I wanted all my electronics embedded onto a single board. It can be a great learning experience imo.

I would suggest first creating a schematic and implementing it on a breadboard with DIP packages as seen on the photo. You will need a crystal, loading caps (22 pF), as well as bypass caps (100nF) and pull-up resistors. Plus any other components your application requires.
![enter image description here](https://i.stack.imgur.com/QDVFb.jpg)

After that typically you would burn a boot loader onto the chip so it can be programmed with the Arduino IDE.

Nick Gammon has provided an excellent tutorial on all of this. His article was my main resource when I made my PCBs: http://www.gammon.com.au/breadboard

Once you get everything working on a breadboard, you may want to look into laying out a PCB for a more permanent solution. Best of luck!


message:
Code Optimization: Interrupt when a value reaches 0

I have a working program and I wish to improve its efficiency as much as possible.

It will blink slow, then faster and faster  until it restarts.

It works, but my main concern is, currently, I am using a `if` statement in the `void loop()`, and I am certain that, using an interrupt when a specific variable has reached 0, would improve efficiency.

    byte amp = 0;

    void setup() {
      pinMode(13, OUTPUT);
      reset();
    }

    void loop() {            // The following
      digitalWrite(13,HIGH); // code is for the sake of example
      delay(amp*100);        // Simplified to focus on the loop
      digitalWrite(13, LOW);
      delay(amp*100);
      amp--;
      if (!amp) {reset();}     // <-This right here
    }

    void reset() {amp = 10;}

My understanding is, the `if` statement is called every time the loop restarts.

 - Is it possible to set up an interrupt for when a certain variable reaches 0?
 - Which option would require less computing power, a continually called if loop, or an interrupt?

body:
Simple `if` statements are very fast and won't affect performance much even when used in every looping of the loop.

Using an interrupt to implement something simple like `if (!amp) amp = 10;` will probably make things slower:
- something will have to keep track of the counter to generate an interrupt, and this "something" takes MCU time, unless it is a peripheral;
- interrupts have overhead;
- on single-thread MCUs, interrupts stop regular code execution until they are done;
- `amp = 10;` will still have to be executed, in the regular code, or, if you must, in the interrupt.

You would gain more by getting rid of the function call to `reset()`, but the compiler probably does that for you.

Also, I wouldn't know how to replace a regular `if` with an interrupt, unless the counter is kept by a (timer) peripheral.


body:
You did not specify the kind of Arduino you are using but, based on another recent question of yours, I will assume it is an AVR-based Arduino.

You cannot have an interrupt automatically triggered by a variable reaching zero. What you can do, instead, is trigger an interrupt by software, by toggling a pin that is configured both as an output and as an interrupt source:

```c++
const uint8_t int_pin = 2;  // pin used for interrupt

void setup() {
    digitalWrite(int_pin, LOW);
    pinMode(int_pin, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(int_pin, reset, RISING));
}

static inline void trigger_interrupt() {
    digitalWrite(int_pin, HIGH);
    digitalWrite(int_pin, LOW);
}

// Within loop():
if (!amp) trigger_interrupt();
```

However, if you do that, you will discover that interrupts are slow; **awfully slow** compared with a simple `if` test:

1. `digitalWrite()` itself is awfully slow. This can be overcome by using direct port access, but that is still two cycles for toggling the pin in each direction.

2. You will lose an extra cycle in the pin synchronizer.

3. Once the IRQ is raised, the CPU needs four cycles to prepare itself for servicing it.

4. The interrupt vector is a `jmp` instruction, which takes 3 cycles.

5. The ISR then has to save every single register it is going to use, including the status register. That takes two cycles per register. And there are quite a lot of registers to save...

6. This ISR, which is provided by the Arduino core, will then look for the interrupt handler you provided with `attachInterrupt()`. This also involves checking that the pointer to the handler is not zero (the kind of test you seem to be worried about). It then has to `call` (4 cycles) your handler, which will have to `ret`urn (4 cycles) to the ISR. You could avoid this indirection by defining the ISR yourself instead of relying on `attachInterrupt()`.

7. Once the job is done, all the saved registers have to be restored (2 cycles times many register), and the `reti` instruction (4 cycles) is issued in order to restore control to the interrupted program.

8. Last but not least, since `amp` will be modified in interrupt context, you will have to qualify it as `volatile`. This keyword prevents the compiler from perform optimizations that are unsafe in this situation, and you will loose _a lot_ of time to these missed optimization opportunities.

In contrast, this line:

```c++
if (--amp == 0) amp = 10;
```

would be translated by the compiler into something like this:

```lisp
   dec  amp     ; --amp, as amp is likely already in a register
   brne 1f      ; if (amp != 0) skip the following
   ldi  amp, 10 ; amp = 10
1:
```

The whole sequence takes 3 cycles, irrespective of whether the `if` condition was true or false. That is at least one order of magnitude faster than the interrupt-based solution.


message:
How to add two assembly arrays in arduino

Hey guys what I'm trying to do is to sum two arrays and return a new array; for example if given

      uint8_t a[] = {2, 4, 6};
      uint8_t b[] = {1, 2, 3};
I should get `{ 3, 6, 9}` What I'm trying to do is have a .ino file call on an assembly file that will do this in assembly and not in C and this is what I currently have in assembly:

    // mimics void sumArrays(uint8_t *a, uint8_t *b, uint8_t *c, byte length){} method
        .global sumArrays
        sumArrays:
          //r18 is the byte length
          //r24 and r25 first  array 31,30
          //r23 and r22 second array 29,28
          //r21 and r20 third  array 27,26

          mov r30, r24
          mov r31, r25
          mov r28, r22
          mov r29, r23
          mov r26, r20
          mov r27, r21
          ldi r17, 0 //counter variable
          ldi r19, 1
          call printRegs
          //jmp sumLoop

          ret

        sumLoop:
          cp r17, r18
          brge endSumLoop
          ldi r16, 0
          add r16, Z+
          add r16, Y+
          st X+, r16
          add r17, r23
          jmp sumLoop:

        endSumLoop:
          ret

However, I get `sketch/assignment13.S:65: Error: constant value required` which is most likely from the

    add r16, Z+
    add r16, Y+

Lines but otherwise, how would I add it to a temporary variable while progressing the pointer?

body:
> ```text
> add r16, Z+
> ```

You probably meant something like

```text
add r16, memory[Z+]
```

However, the AVR is a RISC processor. It has instructions to address the
memory, and instructions to do arithmetics, but it has no “complex”
instructions that both address the memory _and_ do arithmetics with the
addressed data. So you have to use separate instructions to:

1. Load (`ld`) the data from RAM

2. do the arithmetics

3. store (`st`) the result in RAM

Now, looking at your assemble code, I have a few comments:

1. If you are mixing assembly and C/C++, you should pay attention to the
   [ABI conventions][abi]. Specifically, some registers, like r28 and
   r29, “belong” to the caller. If your function needs to use them, it
   should save their contents (typically by `push`ing them to the
   stack) before clobbering them, and restore them (`pop`) before
   returning.

2. For adding two 8-bit numbers (a + b), a single addition is enough.
   There is no point in starting the addition with zero (i.e. computing
   0 + a + b).

3. For managing the counter, it can be more convenient to decrement the
   initial count you where given (like in C: `if (--length) return;`)
   rather than using an extra variable that is incremented.

4. There is no need to split such a simple function into smaller
   functions.

[abi]: https://gcc.gnu.org/wiki/avr-gcc


message:
Connect 4 HC-12 transmitters to 1 HC-12 receiver

I am currently receiving data from HC-12 modules via USB-TTL that are working in pair . But I want to receive data simultaneously from 4 Hc-12 modules to a single HC-12 module via USB-TTL.

body:
When a HC-12 is transmiting all other HC-12 in his range (using same frequency) are receiving. So if you want your transmiter to talk to one specific HC-12 then to an other and so on, you have to create a kind of "message protocol".

Let's say you have an Arduino with a HC-12 and 4 buttons and want to turn on-off 4 lights, each connected to a HC-12. You can use a binary representation, so a byte, on which each bit as a meaning.

Bit 0 -> at 1 -> turn on the light at 0 turn off

Bit 1-2 -> give the number of the HC-12

So 00000111 -> message for HC12 number 4, tell it to turn on the light.
ALL HC-12 will receive the message. So each has to check the incoming byte to see if "it's for me" or nor.
If you want one HC-12 to receive from many HC-12, that's the same: the message must contain the "id" of "who is sending".


body:
The problem with multiple transmitter mostly resides in the collision risks. On networking contexts like Ethernet, There is a collision detection protocol making transceiver know that a problem arises, but that doesn't exist with HC-12, so you need something else.

In air contexts like this one, another solutions might to minimize chances of collisions restraining onself to a low bandwidth percentage (e.g.: not more that 10% of the total time) and just ignore lost packets.

However, if you cannot ignore lost packets, you need to implement a synchronisation protocol between receiver and transmitters. A solution would be to make some kind of token bus, where your receiver would poll each transmitter each on his turn to see if it has something to send.

However, since it is not recommended (and sometimes not even legal) to use to much time slices, you should avoid continuously polling all the transmitters.

In this case, what I suggest is that each transmitter can "wake up" the receiver by sending an unattended message. If this doesn't not cause reaction, this is interpreted as a collision detection. Then the transmitter wait for a specific delay (each one having a different delay value) - or a random delay.

When the receiver receives this packet it processes it, Then polls all the other transmitters, and then goes back to sleep mode, until the next time.

If the packets are long it might be better to have a short wake-up packet and to send the real data during the polling phase, and if the packets are short, you can just use the collision avoidance mechanisme alone.


message:
How to get rid of low quality sound out from DFPlayer plus amplifier?

I use my Seeeduino V4, DFPlayer mini, and [this][1] speaker module from AliExpress to create an automatic doorbell.  The problem is that it seems that this speaker module's Yurobot amplifier is not powerful enough to create a noise-free loud sound. Also, the bundled speaker is 0.5 W, 8 Ω.

There is a volume selector on the speaker module. If it is selected to a value a bit higher than 0 then the sound's quality is quite high (click [here][2] to listen), but the volume is not enough by far for a doorbell, even though the DFPlayer's programmed volume is set to maximum.

But if I increase the amplifier's volume selector to something near maximum, I start hearing some very scary noises (please click [here][3] to listen).

How can I increase the volume without having hard-to-listen-to noises? Maybe I need to buy another, better amplifier?

  [1]: https://aliexpress.com/item/1005001383483648.html?spm=a2g0s.9042311.0.0.264d33edTuDjJ5&_ga=2.178383712.550996950.1607518110-1523012225.1596878040&sku_id=12000015889248158
  [2]: https://youtu.be/VEp05yVo2UI
  [3]: https://youtu.be/GpeJw1ATuAY

body: Interesting! The wattage rating of the speaker does not affect its loudness, the efficiency does at a given wattage. Wattage is the maximum amount of power you can drive the speaker with, that does not indicate the source can provide more or less. The SPL (SPL stands for sound pressure level and is also commonly referred to as efficiency and sensitivity.  This parameter represents how loud a speaker is.  A higher SPL equates to a louder speaker). To get more volume out of a speaker you have to put more power in. Ohm's Law explained this. The impedance (AC Resistance) of the speaker varies with frequency but typically a nominal number such as 8 ohms is used.  Looking at Ohm's law the only way to get more power is to lower the impedance or increase the voltage with voltage being the most popular as well as the easiest. Putting more power into a speaker then it is rated at will eventually destroy it as well as distort the sound. This may not be noticeable to the human ear at low amounts but it is there.  Also the sound coming out is directly related to the signal going in. Clipping is a common occurrence when the amplifier is being over driven ie. it is asked to put out a higher voltage then it is capable of. There is an old saying garbage in garbage out. That includes the components as well. To solve your problem you probably need an amplifier capable of doing what you want and a speaker that will at a minimum handel the worse case power you will send it.


body:
The DFPlayer already has a 3 W amplifier on it, so you can connect a speaker directly to the DFPlayer. There is no need for an extra amplifier.

If you do connect an extra amplifier to the DPlayer, and turn the volume of the DFPlayer up too far, the input of the second amplifier will clip and it won't sound good.

Also, the output of the DFPlayer is probably from a class-D amplifier designed to be connected directly to a speaker; it won't play nice with other amplifiers.

You should try how the DFPlayer sounds when you connect a speaker directly to it. The 0.5 W speaker you have is not a good fit; it can't handle the power of the DFPlayer's amplifier.

A 3 W (or more), 8 Ω speaker would be good for this if you want to use the maximum power the DFPlayer can deliver. According to most publications on the interwebs a 2 W, 8 Ω speaker will also do, but I would be careful with turning the volume all the way up.

Note that the DFPlayer can pull a fair bit of current (about 25 mA in standby, and in the order of 200 mA when playing) and it needs a power supply that can deliver that.


body: i was experiencing the same phenomen in my project , and got to this page in my research . I am using a tda 2003 amplifier and the speaker is a intercom that i modify so changing the speaker is out of question also the amplifier is a good and versatile . The problem is in the gain setting of the amplifier . I was using a 220ohm resistance on the gain setting . going back an forth i was getting better sound with low gains. i hooked up a potetiometer in the place of the resistance to fine tune the gain aand at 8 ohms i get the sound that i want.


message:
Changing address of MPU 9250 connected to ESP32

Can I change the I2C address of a device (MPU9250) connected to ESP 32 using int pin. I understand that in arduino board if we connect the int pin to A0 the default I2C address of MPU 9250 changes from 0x68 to 0x69. Is something similar possible with ESP 32? Which Pin I should connect to?

body:
You have only two choices with this device on an I2C bus.  As stated in the datasheet:

[![MPU9250 Datasheet I2C Bus][1]][1]

So it's either:

1. 0b1101000
1. 0b1101001

The AD0 pin selects which of these two addresses are used.

The complete datasheet can be viewed at the following link as well as other places:

[Datasheet][2]

  [1]: https://i.stack.imgur.com/ukWVo.png
  [2]: https://media.digikey.com/pdf/Data Sheets/TDK PDFs/MPU-9250_Rev_1.1.pdf


message:
How to read an analog value on ESP32-CAM with the SD card reader enabled?

I use an ESP32-Cam module for a project for which I need both the SD card and the cam. According to [this page][1], the only pins that are not in use by either the camera or the SD card reader are GPIO0, GPIO2 and GPIO16. However, I need to read an analog value, which is only possible with the pins 12-15, 2 and 4, [as the Arduino forums state][2], which are all in use by the SD card reader.

However, I came across a way to make the SD reader leave the GPIO4 pin out, namely by initializing it with

    SD_MMC.begin("/sdcard", true);
Now the flashlight does not light up anymore when accessing the SD card, which means that there is no output anymore to GPIO4. However, it still does not allow me to read the pin after the SD card has been initialized. I also tried "converting" the pin to a GPIO through

    pinMode(4, FUNCTION_3);
but it did not make a difference.

So my question is: How can pin 4 be used to read analog values while still keeping the SD card reader functional? And if this is not possible, is there any other way to read an analog value into the ESP32-CAM?

  [1]: https://randomnerdtutorials.com/esp32-cam-ai-thinker-pinout/
  [2]: https://forum.arduino.cc/index.php?topic=634969.0

body:
According to the schematic and [pin notes](https://github.com/raphaelbs/esp32-cam-ai-thinker/blob/master/docs/esp32cam-pin-notes.md#gpio4---hs_data1), I don't think you can use GPIO4 as an ADC input (it can be used as a GPIO pin and technically it can be configured as an ADC pin), but it has a 47k pull-up resistor on it, making it not possible to be used as an ADC input.

Depend on your hardware wiring skill, one alternative is to use an external ADC chip with i2c interface (such as an [MCP3221](http://ww1.microchip.com/downloads/en/DeviceDoc/20001732E.pdf)) and connect it to TWI_SCL and TWI_SDA, but those pins are only available on cam-connector, not on the header pins.


message:
How can I have different routines fire off at different intervals

I'm making an interface that will have a digital clock....once a second..

I'd like to do other things at different intervals but if I `delay(1000)` then I have to wait that second which is now the minimum other things have to run at.

body:
As said in the comments: you should read up on State Machines and have a close look at the [Blink Without Delay example][1].

To get you started with an example closer to what you want to achieve, have a look at the code below; it will count seconds without blocking the loop.

```c++
unsigned long int secondsTimerMillis;
int seconds, minutes, hours = 0;
int secondsInterval = 1000; //ms

void setup() {
  Serial.begin(9600);
  // More setup() stuff goes here
  secondsTimerMillis = 0;
}

void loop() {
  if ((millis() - secondsTimerMillis) >= secondsInterval) {
    seconds++;
    secondsTimerMillis = millis();
    Serial.println(seconds);
    // More stuff you want to do every second goes here
  }
  // More loop() stuff goes here
}
```

This is just the basic mechanism, and it won't be very accurate without some way of adjusting the clock every now and again.

You will also have to add code for checking `seconds == 60` and increase `minutes` / reset `seconds` when needed; the same goes for hours.

Having/handling other events at other intervals is just more of the same.

Note that using a Real Time Clock as the basis for your timing would make your <strike>life</strike> programming much easier, and your clock more accurate, but I am assuming you want to do this "by hand".

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


body:
If you want a clock, your best option is... to buy a clock. Or, more
precisely, an RTC module. Not only will it be way more accurate than
your Arduino, it will also be able to keep the time off battery when
your project is powered off.

If you really want to rely on the (unreliable) timing capabilities of
your Arduino, you may want to try the `millis()`-based fake RTC provided
by the [Adafruit RTClib][RTClib] library: [RTC\_Millis][rtcm]. Example
usage:

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

RTC_Millis clock;

void setup() {
    Serial.begin(9600);
    clock.begin(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
    static DateTime last_time;
    DateTime now = clock.now();
    if (now != last_time) {
        char buffer[] = "hh:mm:ss";
        Serial.println(now.toString(buffer));
        last_time = now;
    }
}
```

Note the test `if (now != last_time)`, which is equivalent to the test
`if (currentMillis - previousMillis >= interval)` of the Blink Without
Delay tutorial (the RTC has a resolution of one second). It allows the
code to be non-blocking.

Note also that, if you are willing to measure you clock's drift rate,
you could calibrate-out that drift by using [RTC\_micros][rtcu] instead,
and calling the `adjustDrift()` method in `setup()`.

[RTClib]: https://github.com/adafruit/RTClib
[rtcm]: https://adafruit.github.io/RTClib/html/class_r_t_c___millis.html
[rtcu]: https://adafruit.github.io/RTClib/html/class_r_t_c___micros.html


message:
How the light brightness stays constant when we increase the frequency of stroboscope

Well I am trying to make a Stroboscop. I found [this code][1] at blow: and tried. It works normally. But if I increase the RPM so decrease the "strobeDelay" time, the brightness of the LEDs goes out. Even if I try the [GreatScott][2] code. The same problem persists at high RPM. I am using power LED.

On the other hand there is a stroboscop which is [Fluke 820][3], it says

> Features high-intensity 7-LED array—4,800 Lux @ 6,000 FPM/30cm

How they achieve that constant brightness under the high frequency?

        // Gray text are just helpful comments, you don’t need to type them. :)

    /******* -----=====!! EASY STUFF TO MESS WITH !!=====------ ******/

      // What analog pin should we use to read the value from the potentiometer?
      int analogPin = 2; // Yep, you heard right: The coolest of the Analog pins...

      // What pin is the LED connected to?
      int ledPin = 13; // Contains a built in resistor!

      // How much time should the light stay on between delays, in Microseconds (millionths of a second)?
        /* Big number = more blur, more perceived brightness
         * Small number = less blur, less perceived brightness  */
      long onTime = 250;

      // What should the minimum delay be in milliseconds (thousandths of a second)?
      // This sets the bottom delay range of the strobe, as a delay of 0 doesn't actually flash =P
      // The strobe starts with this as the "fastest" mode, and goes slower from there, adding to the delay
      int minDelay = 1; // 1 is the lowest we can actually do without a better delay function

      // What should the maximum delay be in milliseconds?
      // This is the longest time that the biggest potentiometer value will be mapped to, and longest
      // time between strobe flashes.
      int maxDelay = 100;

    /******* -----=====^^ EASY STUFF TO MESS WITH ^^=====------ ******/

    // Initialize the number to hold our strobe delay. Isn't used till we get to the main loop
    long strobeDelay = 0;

    void setup() {
     pinMode(ledPin, OUTPUT); // Setup ledPin as an output.
    }

    void loop() {
      // To make the math easier, we use map(value, fromMin, fromMax, toMin, toMax) to convert the
      // 0 to 1023 range we get from analogRead, into our strobe delay range of 1 to 100 :D
      strobeDelay = map(analogRead(analogPin), 0, 1023, minDelay, maxDelay);

      digitalWrite(ledPin, HIGH); // Switch the ledPin to HIGH, turn it on!
      delayMicroseconds(onTime); // Delay while on, for the given onTime.
      digitalWrite(ledPin, LOW); // Switch the ledPin to LOW, turn if off!
      delay(strobeDelay); // Delay while off, for given strobeDelay.
    }

For those who wonder there is a [video][4], but another brand same result, brightness constant even if RPM changes. I tried 2 different power LED. on of them is [this][5], the other LED is I found in a broken projector, I used them 2 working strip. No doubt in your mind, this led strip is very bright at low frequency. Both of them same result like this:

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

  [1]: https://gist.github.com/makersylvia/9b133cb2d38c4052bd55
  [2]: https://www.instructables.com/Make-Your-Own-LED-Stroboscope/
  [3]: https://www.fluke.com/en/product/mechanical-maintenance/vibration-analysis/fluke-820-2
  [4]: https://youtu.be/9NkzR-1tWj0?t=233
  [5]: https://www.robotistan.com/suruculu-3w-power-led-karti
  [6]: https://i.stack.imgur.com/yYIQq.png

body:
To keep the same brightness, you have to keep the same duty cycle (percent of on time over off time).  So to change the rate without changing the brightness, you have to increase
delayMicroseconds(onTime) by the same percent you increase delay(strobeDelay).  But note that as you go slower, the on time will be too long to freeze the motion you are trying to study.  (If it's just for a party effect this may not matter.)


message:
Trouble obtaining values from Nextion screen to Arduino

Currently I have a setup running an Arduino BME 280 sensor and a 4.3" Nextion screen. What my program does is sent all the calculated values from the BME to numbers and progress bars in my Nextion on a screen called "Run".

This page consists of 3 values: Delta T, Temperature and Humidity as well as 3 buttons for an alarm. Each of these displayed values is connected to their own progress bar. Each of the individual values has a lower and upper alarm setting which can be adjusted on a following Nextion screen called "Settings".

So basically what I am struggling with is obtaining the obtaining the values from my "settings" screen to write the "if" function in my Arduino i.e (if the button is enabled on the run page and the value is less than X on the "Settings" page or more than Y on the "Settings" page, sound the alarm).

I have used the .getValue function, but it does not return a value to my Arduino program. Can anyone please assist. It will be highly appreciated.

```c++
// Include required libraries
#include <NexTouch.h>
#include <NexDualStateButton.h>
#include <NexNumber.h>
#include <NexProgressBar.h>
#include <NexText.h>
#include <Nextion.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//Define BME parameters
#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C

//Define variables
int Delta_T;
int Temp_disp;
float Temp_wb;
float Temp;
int rh;

//Define NEXTION variables
//Transport Page
NexNumber Trans_deltaT = NexNumber(2, 10, "n0");
NexNumber Trans_T = NexNumber(2, 11, "n1");
NexNumber Trans_H = NexNumber(2, 12, "n2");

//Run Page
NexNumber Run_deltaT = NexNumber(3, 14, "n0");
NexNumber Run_T = NexNumber(3, 15, "n1");
NexNumber Run_H = NexNumber(3, 16, "n2");
NexDSButton Delta_Temp= NexDSButton(3, 12, "bt0");
NexDSButton Temperature= NexDSButton(3, 22, "bt1");
NexDSButton Hum= NexDSButton(3, 13, "bt2");

//Settings Page
NexNumber DT_min= NexNumber(4, 5, "n6");
NexNumber DT_max= NexNumber(4, 12, "n3");
NexNumber T_min= NexNumber(4, 6, "n7");
NexNumber T_max= NexNumber(4, 14, "n4");
NexNumber Hum_min= NexNumber(4, 7, "n8");
NexNumber Hum_max= NexNumber(4, 16, "n5");

NexTouch *nex_listen_list[] = {
  &Delta_Temp,
  &Temperature,
  &Hum,
  &Run_deltaT,
//  &DT_min,
//  &DT_max,
//  &T_min,
//  &T_max,
//  &Hum_min,
//  &Hum_max
    NULL
};

void Delta_TempPopCallback(void*ptr) {
  uint32_t DT = 0;          // Button State
  uint32_t DT_act = 0;
  uint32_t DelT_min = 0;    //Define DT_min setting
  uint32_t DelT_max = 0;    //Define DT_max setting

  DT_min.getValue(&DelT_min);
  DT_max.getValue(&DelT_max);
  Delta_Temp.getValue(&DT);
  Run_deltaT.getValue(&DT_act);

  Serial.println();
  Serial.println();
  Serial.println(DelT_min);

  // Read value of dual state button to know the state (0 or 1)

  if (DT == 0 && DT_act < DelT_min || DT_act > DelT_max) {  // If dual state button is equal to 1 (meaning is ON)...
    digitalWrite(2, HIGH);  // Turn ON internal LED
    Serial.println("ON");
  } else {                  // Since the dual state button is OFF...
    digitalWrite(2, LOW);   // Turn OFF internal LED
    Serial.println("OFF");
  }
}

void setup() {
  Serial.begin(9600);
  bme.begin();
  pinMode(2, OUTPUT);
  Delta_Temp.attachPop(Delta_TempPopCallback);
}

void loop() {
  Temp = bme.readTemperature();
  Temp_disp = Temp;
  // Serial.print("Temperature = ");
  // Serial.print(Temp);
  // Serial.println(" *C");

  rh=bme.readHumidity();
  // Serial.print("Humidity = ");
  // Serial.print(rh);
  // Serial.println(" %");

  Temp_wb = atan(0.151977 * pow(rh + 8.313659, 0.5)) * Temp + atan(Temp + rh) - atan(rh - 1.676331) + 0.00391838 * pow(rh, 1.5) * atan(0.023101 * rh) - 4.686035;
  // Serial.print("Wet Bulb Temp= ");
  // Serial.print(Temp_wb);
  // Serial.println(" *C");

  Delta_T=Temp-Temp_wb;
  // Serial.print("Delta T=");
  // Serial.print(Delta_T);
  // Serial.println(" *C");
  // Serial.println();

  Trans_deltaT.setValue(Delta_T);
  Trans_T.setValue(Temp_disp);
  Trans_H.setValue(rh);

  Run_deltaT.setValue(Delta_T);
  Run_T.setValue(Temp_disp);
  Run_H.setValue(rh);

  nexLoop(nex_listen_list);

  delay(50);
}
```

body:
I had to repeat the getvalue code multiple times, there seems to be a bug which a youtuber pointed out in his video.
https://github.com/rvxfahim/AHU-Firmware/blob/main/development_HMI.ino
you can see from line 133, I called it so many times to be safe because it sometimes returned nothing or probably returned zero I don't remember it was a long time ago.


message:
Is there any better choice other than using delay() for a 6-hours delay?

I am designing an incubator system and I need to drive a motor forward and reverse every 6 hours. Is there any better choice other than using `delay()`? A 6-hours delay seems a little unprofessional.

body:
Using `delay()` for a 6-hour delay is a bit awkward, but perfectly doable. It will, however, not be very accurate, because the accuracy depends on the accuracy of the Arduino's clock, and it will block all other code you may wish to run.

Using timing with `millis()` would allow your Arduino to do other things while waiting. It will be just as inaccurate, though.

For long periods, and especially if you want things to be more accurate, you could use an external Real Time Clock, like the [DS3231][1]. You can get these as modules on break-out boards, and libraries are also available.

These RTCs have a backup battery, so they also keep running a while without external power, and will also keep time when the Arduino resets. Most also have settable alarm times you could use.

For your application, I would also implement a simple *watchdog timer* to make sure the Arduino is still waiting and working, and hasn't crashed. Note that a watchdog timer won't play nice with `delay()`; a simple 6-hour delay will always trigger it, and timing with `millis()` or an external RTC is the way to go here.

  [1]: https://www.maximintegrated.com/en/products/analog/real-time-clocks/DS3231.html


body: Since this is for an incubator, I suspect that you don't need high precision.  So delay() will work perfectly well, if you don't want to do anything else in the meantime (like maybe monitor temperature, control a heater, and/or light LEDs for over/under temperature).  In that case you could use a loop that handled all those operations at some convenient rate like once per second or once per minute, using delay() in the loop. (I assume that your incubator is slow to respond to the heater, so slow sampling will be fine.)  Then let the loop run for 6 hours, which you can determine by simple count of the 1-minute (or whatever) loop delays.  And if you find that your 6-hour time is consistently high or low, adjust the count limit to compensate.


body:
There's nothing wrong with using delay here.

There is only a problem if you want to make the Arduino do something else as well. I that case you'd want to use `millis`, and use that to calculate how much time has passed (see [blink without delay](https://www.arduino.cc/en/pmwiki.php?n=Tutorial/BlinkWithoutDelay)).


body:
Several options here, and a couple folks have pointed out some challenges.

"Best" answer -- probably to use a real-time clock (RTC) board to assist your timing, and effectively set a target time (next motor run is at 23:14...) each time the cycle restarts.  By saving this target off (to the EEPROM or an SD card for instance), you'd protect against a potential shutdown and reset of the arduino in the middle.

Secondary answer; set your loop() to include a relatively short delay() statement, then check the elapsed time since the last motor engagement.  This would allow you to have other items processing, as someone else noted in this thread.  This I've pseudocoded below.

```
unsigned long lastMotorRunTime;

void loop()
{
    /*
     * do whatever
     */
    if(millis()-lastMotorRunTime > 21600000)  // 6 hours have passed
    {
         runTheMotor(); // placeholder for the motor movements you need
         lastMotorRunTime = millis();
    }
   /*
    * do other stuff
    */
   delay(100); // loop about every 1/10 second, or whatever works
}
```

Given you don't seem to need detailed precision -- a few seconds either way wouldn't matter -- this should work reasonably.  Note it WILL fail if the Ardiuno is reset -- then it will only (in my pseudocode) rotate the motor 6 hours after the last Arduino reset.  Probably better to assume that an arduino reset means move the motor 'now', if the point is to ensure periodic motion rather than precise timing.

For precise timing, as noted, the RTC would be required.

(Updated: Changed lastMotorRunTime to unsigned long)


body:
I have an automatic watering system that (among other things) trigger on time. I use the excellent [Timer Library](https://playground.arduino.cc/Code/Timer/) for this. It allows several useful timed interactions such as `Pulse` or `Oscillate` in addition to `After` which would solve your issue - or `Every` if you want a recurring 6 hour code block to execute

In the end - behind the screen - it is just as unprofessional as `millis()` - the library itself uses `millis()` and a scheduler. But the code looks cleaner and is easier to write and update.


message:
Connect 12V 38A battery to SIM800C GSM Module

I have a gsm module that is rated for 12V and 1A. And I also have a drone Battery that is 12V and 38A. Would it hurt the gsm module If I connect it to this high power Battery?

I heard It's voltage that goes through forcefully, but current doesn't force it self through. So would it be safe to connect?

body:
When choosing a battery there are three basic parameters that need to be considered:

1. Voltage
1. Capacity
1. Max. current draw

In your case you have listed the requirement as 12V 1A which means you need 12V and the maximum current need is 1 Amp.  You have said nothing about capacity, which is how much energy is stored in the battery so I assume it's not important here.

Your proposed 12V 38A battery will work just fine since it's still 12V and the 38A is simply the maximum current draw, not the minimum.  The battery will provide up to 38A but will also source less.

Be careful, though.  If you create an accidental short circuit there is a large amount of energy stored in a 38A type battery and it will be discharged very quickly indeed, possibly causing a fire.  Be sure to properly insulate your wires and connections.


body: I looked up the SIM800C GSM Module, and it seems it requires a Lithium Ion or Lithium polymer battery, and has a built-in charging circuit in it. (It sounds like it uses the battery to manage peak current demands.) Thus you MUST use a rechargeable lithium battery for it. Having a higher current battery should be fine as long as the voltage is correct.


message:
I2C communication between Arduino Uno and Nodemcu32-s (ESP32)

I want to send data between an ESP-32 (NODEMCU-32S) and an Arduino Uno but I haven't found any source on how to do that, so I tried this code:

ESP-32 code:
```c++
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(21, 22);      /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
  Wire.beginTransmission(8);
  Wire.write(3);  /* sends hello string */
  Wire.endTransmission();  /* stop transmitting */
  Wire.requestFrom(8, 18); /* request & read data of size 13 from slave */
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}
```
And Arduino code:

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

void setup() {
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onReceive(receiveEvent); /* register receive event */
  Wire.onRequest(requestEvent); /* register request event */
  Serial.begin(9600);           /* start serial for debug */
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  while (0 < Wire.available()) {
    int c = Wire.read();        /* receive byte as a character */
    Serial.print(c);            /* print the character */
  }
}

// function that executes whenever data is requested from master
void requestEvent() {
  Wire.write("hello esp");
}
```

But I found that no data was sent.

I connected pin 21 to A4 and 22 to A5 directly.

I cannot find where the problem is. Also, I don't know whether the device address is correct or not, since when I tried an I2C scanner it didn't discover any device.

Also, I hope that there is a similar method to have two-way UART communication between the Arduino and ESP as I found none since I need both chips to send data to each other.

body:
I'm working on something similar at the moment. Not a complete answer put some thoughts:

- Have you considered that the Uno is a 5v board and the ESP32 is 3.3v? You may need a signal level shifter (there are many to chose from) something like [Pololu-2595][1] which is breadboard friendly.

- There's a good ESP32 I2C explanation at [Random Nerd Tutorials][2].

  [1]: https://www.pololu.com/product/2595
  [2]: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/


message:
Ignoring the first high output from the sensor

If the vibration sensor with Arduino detects two high inputs within 1 minute, I want the led to flash in one second.

My ability to write Arduino code is very low; I tried with `millis()` but I couldn't.

I want it to ignore the first high entrance.

Thank you for all the information you will give.

```c++
const byte sensor = 7;
const byte LED = 13;
unsigned long sensorMillis;
unsigned long ledTurnedOnAt;
unsigned long high_1 = 60000UL;
bool ledState = false;

void setup() {
  pinMode(sensor, INPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (digitalRead(sensor) == HIGH) {
    sensorMillis = currentMillis;
    ledstate = true;
  }

  if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
    digitalWrite(8, HIGH);
    delay (1000);
    digitalWrite(8, LOW);
  }

  ledstate = false;
}
```

body:
    const int sensor = 7;
    const int LED = 13;
    unsigned long sensorMillis;
    unsigned long ledTurnedOnAt;
    unsigned long high_1 = 60000UL;
    bool ledState = false;
    void setup() {
      pinMode(sensor, INPUT);
      pinMode(LED, OUTPUT);
      delay(1000); //Warm up Time
    }

    void loop() {
      unsigned long currentMillis = millis();

      if (digitalRead(sensor) == HIGH) {
        sensorMillis = currentMillis;
        ledstate = true;
      }

      if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
        digitalWrite(8, HIGH);
        delay (1000);
        digitalWrite(8, HIGH);
      }

      ledstate = false;
    }

I haven't checked this because I don't have my hardware. However, I added a delay of 1 second in the setup as a warm up time. This in theory should ignore the first high. Hope it helped.


body:
Or what about adding another global boolean;

    bool firstTime = true;

and then amend you loop() code as follows;

    if (digitalRead(sensor) == HIGH) {
        if (firstTime) firstTime = false;
        else {
            sensorMillis = currentMillis;
            ledstate = true;
        }
      }


body:
One simple solution could be:

Start by noticing the first time you get the `HIGH` input whit a simple [if][1] statement:

```c
if (digitalRead(sensor) == HIGH) {
}
```
where `sensor` is the pin of the sensor according to your code.

When this statement is `True`, you are interested in remain here until one of two things happens:
- either you interrupt some kind of loop with another `HIGH` input,
- or the time you have set is passed.

One way of knowing elapsed times will be with the [`millis()`][2] function, that returns the milliseconds since the board began running.
We should get the elapsed time the first time we enter the loop:
```c
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
}
```
Then, as I have said, we need to remain here for a specific amount of time. We could use the [`while`][3] loop, but, which condition needs to be `true`?

So we have a start time, lets said `x` and you need to stay in the loop for, let's say, `y` milliseconds. This is the same as saying that you want to stay in the loop until the time we enter the loop and a specific amount of milliseconds, `x+y`. When the `millis()` function gives us a greater number, we should exit the loop:
```c
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000))
//                              ^ The second you are interested, 1000 milliseconds.
}
```
Now, we have to check if there is another interrupt during this time, by using the same statement of the beginning:
```c
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 interrupts in less than 1000 millis!
    }
  }
}
```
Summarizing is nicer to declare a global with the specific time we want, instead of the `1000` value we are using now:
```c
const long maxTimeInterval = 1000;
```
And changing it in our code (that is inside the `loop()`)
```c
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+maxTimeInterval)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 interrupts in less than 1000 millis!
      digitalWrite(LED, HIGH);
    }
  }
}
```
Hope this helps!

  [1]: https://www.arduino.cc/reference/en/language/structure/control-structure/if/
  [2]: https://www.arduino.cc/reference/en/language/functions/time/millis/
  [3]: https://www.arduino.cc/reference/en/language/structure/control-structure/while/


message:
Relays just switch ON and OFF on delay(), not on millis()

I use fuzzy logic for the running time of relays, but the relays just switch ON and OFF at the interval of the `delay()` I put at the end of loop.

This is my code:
```c++
void loop () {
  ph = -180/100.0;
  hasilec = -1.2;
  unsigned long now = millis();

  Serial.print("pH    ");
  Serial.print(ph);
  Serial.print("  ");
  Serial.print("EC ");
  Serial.print(hasilec);
  Serial.println("");
  Serial.print(ph);
  Serial.print(" ");
  Serial.print(hasilec);
  Serial.print(" ");
  Serial.println(" ");

  fuzzy->setInput(2, hasilec);
  fuzzy->setInput(1, ph);
  fuzzy->fuzzify();

  float pompa01 = fuzzy->defuzzify(1); //pHDOWN
  float pompa02 = fuzzy->defuzzify(2); //pHUP
  float pompa03 = fuzzy->defuzzify(3); //ABMIX

  long int pompa1 = pompa01 * 1000;
  long int pompa2 = pompa02 * 1000;
  long int pompa3 = pompa03 * 1000;

  Serial.println("Result= ");
  Serial.println("");
  Serial.print(" Pompa1 pHDOWN: ");
  Serial.println(pompa1);
  Serial.print(" pompa2 phUP  : ");
  Serial.println(pompa2);
  Serial.print(" pompa3 ABMIX : ");
  Serial.println(pompa3);
  Serial.println("");
  Serial.println("");
  Serial.println("");

  pump_periods[0] = pompa1;
  pump_periods[1] = pompa2;
  pump_periods[2] = pompa3;

  for (int i = 0; i < jml_pump; i++) {
    if (now - pump_last_actuations[i] >= pump_periods[i]) {
      pump_states[i] = (pump_states[i] == LOW) ? HIGH : LOW;
      digitalWrite(pump_pins[i], pump_states[i]);
      pump_last_actuations[i] = now;
    }
  }
  delay (20000);
}

```
The relay just switch ON and OFF on this delay `delay (20000);`.

What should I do?

body:
Check the values of `pompa1`, `pompa2`, and `pompa3` to see if they are always smaller than 20000 (I suspect they are).

The `delay(20000)` (why is it there anyway?) could well be messing up your timing of the toggling of the `pump_states` by always delaying longer than the values in `pompa1`, `pompa2`, and `pompa3`.

This would make the relays toggle every 20 s (on every loop).


message:
Question about button circuit

I'm quite a beginner at electronics, but thought I would try venture into it.
Currently I'm working on a project where I need to reuse a button module salvaged from some old hardware, but I can't figure out the wiring. The attached image is what I was able to track down on how the circuit is built. I'm not really sure how to wire it? Would it be possible to use this with an ESP32 and differentiate all the buttons?

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

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

  [1]: https://i.stack.imgur.com/592WU.jpg
  [2]: https://i.stack.imgur.com/63XDV.jpg

body:
Sure. Take a multimeter and measure the resistance between the left-most pin and each of the other pins with all the different combinations of button pairs pressed. Write down the results.

Then build a voltage divider for each output (Connect a resistor to ground on each output, and then connect that pin to an analog input on the Arduino. The resistor value to use will depend on the readings you get, but a 1K ohm resistor would be a good starting point.)

Then set up the 2 input pins on your Arduino as analog inputs and measure the voltage with no buttons, top button, bottom button, and both buttons pressed for each pair. Write those values down. Then write code that checks for voltages *roughly* equal to your measurements for each button press combo (You will need check for ranges of values, since the values will vary some.)