message:
qMenuSystem Oled I2C can't make it work

I'm trying to make the qMenuSystem to work with my I2C Monochrome OLED display but without any luck.
To summarize all here's what's with it :
- the qMenuSystem is using a library called : DigoleSerial but has the things set as SPI connection
- the library itself can work with I2C but i'm receiving some strange errors like this :
```arduino

Arduino: 1.8.9 (Mac OS X), Board: "Arduino/Genuino Uno"

TestMenu:25:42: error: expected primary-expression before '_disp'
 DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
                                          ^
exit status 1
expected primary-expression before '_disp'

```
Here is the video of what i'm trying to display:

https://www.youtube.com/watch?v=rjON_enuOGs (I already tried what's suggested in the comments)

Here's the code so far:

```arduino
#define _Digole_Serial_I2C_
#include <DigoleSerial.h>
#include <Wire.h>

#include <qMenuDisplay.h>
#include <qMenuSystem.h>

#include "TestMenu.h"

//DigoleSerialDisp mydisp=DigoleSerialDisp(8,9,10);
//DigoleSerialDisp _disp(&Wire,'\x3C');

DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');
qMenuSystem menu=qMenuSystem(mydisp);

void setup()
{
  menu.InitMenu(mnuRoot,cntRoot,1);
  Serial.begin(9600);
}

void loop()
{
  int keycode=0;
  int clickedItem=0;

  if (Serial.available()>0)
  {
    switch(Serial.read())
    {
      case 97:
        menu.ProcessMenu(ACTION_DOWN);
        break;
      case 113:
        menu.ProcessMenu(ACTION_UP);
        break;
      case 115:
        clickedItem=menu.ProcessMenu(ACTION_SELECT);
        break;
    }
  }

  if (clickedItem>0)
  {
    // Logic for Root menu
    if (menu.CurrentMenu==mnuRoot)
      switch (clickedItem)
      {
        case 1:
          menu.InitMenu(mnuSubmenu1,cntSubmenu1,1);
          break;
        case 2:
          menu.InitMenu(mnuSubmenu2,cntSubmenu2,1);
          break;
        case 3:
          menu.InitMenu(mnuSubmenu3,cntSubmenu3,1);
          break;
        case 4:
          menu.MessageBox("Some message!");
          break;
      }
    // Logic for Submenu 1
    else if (menu.CurrentMenu==mnuSubmenu1)
      switch (clickedItem)
      {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
          menu.MessageBox("Item clicked");
          break;
        case 6:
          menu.InitMenu(mnuRoot,cntRoot,1);
          break;
      }
    // Logic for Submenu 2
    else if (menu.CurrentMenu==mnuSubmenu2)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("On");
          break;
        case 2:
          menu.MessageBox("Off");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,2);
          break;
      }
    // Logic for Submenu 3
    else if (menu.CurrentMenu==mnuSubmenu3)
      switch (clickedItem)
      {
        case 1:
          menu.MessageBox("Enabled");
          break;
        case 2:
          menu.MessageBox("Disabled");
          break;
        case 3:
          menu.InitMenu(mnuRoot,cntRoot,3);
          break;
      }

  }
}
```

and the progmem part :

```
// required for "prog_char" and "PROGMEM"
#define _PROG_TYPES_COMPAT_
#include <avr/pgmspace.h>

// texts for menus

const char itmBack[] PROGMEM = "< Back";
const char itmOn[] PROGMEM = "On";
const char itmOff[] PROGMEM = "Off";
const char itmEnabled[] PROGMEM = "Enabled";
const char itmDisabled[] PROGMEM = "Disabled";

const char itmRoot[] PROGMEM = "Root menu";
const char itmSubmenu1[] PROGMEM = "Submenu 1";
const char itmSubmenu2[] PROGMEM = "Submenu 2";
const char itmSubmenu3[] PROGMEM = "Submenu 3";
const char itmMessageBox[] PROGMEM = "Message box";
const char itmItem1[] PROGMEM = "Item 1";
const char itmItem2[] PROGMEM = "Item 2";
const char itmItem3[] PROGMEM = "Item 3";
const char itmItem4[] PROGMEM = "Item 4";
const char itmItem5[] PROGMEM = "Item 5";

////////////////////////////////////////////////////////////////
// menus - first item is menu title and it does not count toward cnt

const char* mnuRoot[] = {
  itmRoot,
  itmSubmenu1,itmSubmenu2,itmSubmenu3,itmMessageBox};
const int cntRoot = 4;

const char* mnuSubmenu1[] = {
  itmSubmenu1,
  itmItem1,itmItem2,itmItem3,itmItem4,itmItem5,itmBack};
const int cntSubmenu1 = 6;

const char* mnuSubmenu2[] = {
  itmSubmenu2,
  itmOn,itmOff,itmBack};
const int cntSubmenu2 = 3;

const char* mnuSubmenu3[] = {
  itmSubmenu3,
  itmEnabled,itmDisabled,itmBack};
const int cntSubmenu3 = 3;
```

I'm kinda new and I have no idea how can I make it work. Can anyone please help me figure it out what's wrong ?

Thank you for your time reading all of this.

body:
As the compiler is indicating, the line

    DigoleSerialDisp mydisp=DigoleSerialDisp _disp(&Wire,'\x3C');

is broken.

This part:

    DigoleSerialDisp _disp(&Wire,'\x3C')

declares and constructs an object named `_disp` of class `DigoleSerialDisp`.

You're trying to assign that to another variable, `mydisp` - that's not valid C++ - you can assign another variable, but you'd need to declare and construct it first, not in the assignment. There's also no need to construct it, name it `_disp` and then assign it to another variable.

Just do this:

    DigoleSerialDisp mydisp(&Wire,'\x3C');

You'll probably want to rewrite

    qMenuSystem menu=qMenuSystem(mydisp);

as

    qMenuSystem menu(mydisp);

as well.


sender: user

message:
How do I code the release of a momentary touch sensor in IDE?

I am a performing musician and quite new to the Arduino community.  Just learning as I go.  I am interested in using a momentary touch sensor with Adafruit's MP3 shield or Wave Shield.  I have successfully connected a touch sensor to the MusicMaker MP3 shield (which is sitting on the Adafruit Metro).  I combined some code from two independently working code sequences: one, to play MP3s and, two, to trigger with the sensor.  This works successfully except that the music starts but does not stop when I lift my finger off the sensor.  I want the music to stop when the touch sensor is not being touched.  When the sensor is touched again, I want the music file to start again from the beginning.  I'm printing the code IDE is running below and attaching an image of the touch sensor I am using.  I appreciate any advice on the code!  Thank you.

    /*
      AnalogReadSerial

      Reads an analog input on pin 0, prints the result to the Serial Monitor.
      Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
      Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

      This example code is in the public domain.

      http://www.arduino.cc/en/Tutorial/AnalogReadSerial
    */

    // include SPI, MP3 and SD libraries
    #include <SPI.h>
    #include <Adafruit_VS1053.h>
    #include <SD.h>

    // define the pins used
    //#define CLK 13       // SPI Clock, shared with SD card
    //#define MISO 12      // Input data, from VS1053/SD card
    //#define MOSI 11      // Output data, to VS1053/SD card
    // Connect CLK, MISO and MOSI to hardware SPI pins.
    // See http://arduino.cc/en/Reference/SPI "Connections"

    // These are the pins used for the breakout example
    #define BREAKOUT_RESET  9      // VS1053 reset pin (output)
    #define BREAKOUT_CS     10     // VS1053 chip select pin (output)
    #define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
    // These are the pins used for the music maker shield
    #define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
    #define SHIELD_CS     7      // VS1053 chip select pin (output)
    #define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

    // These are common pins between breakout and shield
    #define CARDCS 4     // Card chip select pin
    // DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
    #define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

    Adafruit_VS1053_FilePlayer musicPlayer =
      // create breakout-example object!
      //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
      // create shield-example object!
      Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
      Serial.println("Adafruit VS1053 Simple Test");

      if (! musicPlayer.begin()) { // initialise the music player
         Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
         while (1);
      }
      Serial.println(F("VS1053 found"));

       if (!SD.begin(CARDCS)) {
        Serial.println(F("SD failed, or not present"));
        while (1);  // don't do anything more
      }

      // Set volume for left, right channels. lower numbers == louder volume!
      musicPlayer.setVolume(20,20);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      // read the input on analog pin 0:
      int sensorValue = analogRead(A0);
      // print out the value you read:
      Serial.println(sensorValue);
      if(sensorValue > 100) {
        Serial.println(F("Playing track 001"));
      musicPlayer.playFullFile("/track001.mp3");
      }
     else(sensorValue < 100); {
        Serial.println(F("Paused"));
      musicPlayer.pausePlaying("/track001.mp3");
     }      }

sender: assistant

body:
You have a semicolon that doesn't belong in your code. Your current code (With the indentation cleaned up a little)

    void loop() {
      // read the input on analog pin 0:
      int sensorValue = analogRead(A0);
      // print out the value you read:
      Serial.println(sensorValue);
      if(sensorValue > 100) {
        Serial.println(F("Playing track 001"));
        musicPlayer.playFullFile("/track001.mp3");
      }
      else(sensorValue < 100); { // <<<--semicolon does not belong here.
        Serial.println(F("Paused"));
        musicPlayer.pausePlaying("/track001.mp3");
      }
    }

Should be:

    void loop() {
      // read the input on analog pin 0:
      int sensorValue = analogRead(A0);
      // print out the value you read:
      Serial.println(sensorValue);
      if(sensorValue > 100) {
        Serial.println(F("Playing track 001"));
        musicPlayer.playFullFile("/track001.mp3");
      }
      else(sensorValue < 100) { // <<<--semicolon removed from this line
        Serial.println(F("Paused"));
        musicPlayer.pausePlaying("/track001.mp3");
      }
    }

With the semicolon after the else, your code reads "...else do nothing" and then I would expect it to execute the pause logic no matter what value is in `sensorValue`.

You should pick an indentation style and then be absolutely consistent with it. Most C/C++ programmers use K&R style, which is what I used in my edit. (Opening braces are on the same line as the if statement/function that begins the scope, code inside braces is indented, and closing brace is at the same indentation level as the line that contains the opening brace.)


body:
As Sim Son have pointed it out, you need to use the proper function.
According to your library's [documentation][1]:

boolean playFullFile(char *trackname) - Play the complete file. This function will not return until the playback is complete.

You want to check your touch sensor, so this won't be enough for you.

boolean startPlayingFile(char *trackname) - Begin playing the specified file from the SD card using interrupt-driven playback. This allows your program to perform other tasks as the file is playing.

That documentation missed it, but in the source there is a function that stops your music:

void stopPlaying(void);

You can find this within your Arduino folder: Arduino/libraries/Adafruit_VS1053_Library's Adafruit_VS1053.h and Adafruit_VS1053.cpp files.

  [1]: https://learn.adafruit.com/adafruit-vs1053-mp3-aac-ogg-midi-wav-play-and-record-codec-tutorial/library-reference


message:
Can I do something like this to simplify the code for arduino?

Can I simplify the code in arduino where it doesn't promote any error.
Example:

    Int led =13;
    Blink = digitalWrite(led, HiGH);
                 delay(1000);
                 digitalWrite(led, LOW);
                 delay(1000);

    void setup(){
    pinMode(led, OUTPUT);
    }

    void loop(){
    Blink
    }

body:
There are indeed some errors.

First, you cannot assign a function body to a variable.

So you have to rewrite the Blink function:

    void blink()
    {
        digitalWrite(led, HIGH);
        delay(1000);
        digitalWrite(led, LOW);
        delay(1000);
    }

Also for calling a function, even without parameters, you should use ( and ):

    void loop()
    {
        blink();
    }

Also you need to use the correct capitals or not:

    int led = 13;

You can make it constant since it does not change:

    static const int led = 13;

So all together you get:

    static const int led = 13;

    void setup()
    {
        pinMode(led, OUTPUT);
    }

    void loop()
    {
        blink();
    }

    void blink()
    {
        digitalWrite(led, HIGH);
        delay(1000);
        digitalWrite(led, LOW);
        delay(1000);
    }

I suggest you read a book about C or C++ to get used to the syntax.

Also, note that int is written as int, not Int. Case matters.


body:
Your code

    Blink = digitalWrite(led, HiGH);
             delay(1000);
             digitalWrite(led, LOW);
             delay(1000);

Is attempting to define a function `Blink` that you can call later. You don't do that with an assignment (`=`)

You want to define a function. I'd suggest naming it `blink()`, not `Blink`. (all lower case.

Functions have parentheses after the name, which is where you put parameters if your function has any parameters. If not you still need the parentheses. The basic syntax of a function definition is:

    return_type function_name(param_type param_name)

If your function doesn't return a value, use the type `void` which means "no type."

So for a function `foo` that doesn't take any parameters and doesn't return any value, you'd use:

    void foo () {
       //Code for function foo()
    }

Michael's excellent answer (voted!) shows you what changes you need to make to your code to make it work. The above explains in a little more detail WHY you need to make those changes.


body:
Of course C++ has nice things.

For fun ad learn a working Arduino sketch based on the code from the Question:

    int led =13;

    auto Blink = []() { digitalWrite(led, HIGH);
                 delay(1000);
                 digitalWrite(led, LOW);
                 delay(1000);
    };

    void setup(){
    pinMode(led, OUTPUT);
    }

    void loop(){
    Blink();
    }

Note: use normal functions in your sketches and save lambdas for special occasions.


message:
Arduino I2C Wire.onReceive hangs after a few loops

I have an Arduino Leonardo (master) and a Polulu A-star 328 PB(slave). I intend to use the slave to actuate some servos. I've modified the code from https://www.arduino.cc/en/Tutorial/MasterWriter to also blink the builtin led of the slave and it hangs after a few loops. **Without the blink, it works fine. With blink, it hangs after a few loops.**

Master:
<!-- language-all: lang-cpp -->

    #include <Wire.h>

    void setup() {
      Wire.begin(); // join i2c bus (address optional for master)
    }

    byte x = 0;

    void loop() {
      Wire.beginTransmission(8); // transmit to device #8
      Wire.write("x is ");        // sends five bytes
      Wire.write(x);              // sends one byte
      Wire.endTransmission();    // stop transmitting
      x++;
      delay(2000);
    }

Slave:

    #include <Wire.h>

    void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    Wire.begin(8);                // join i2c bus with address #8
    Wire.onReceive(receiveEvent); // register event
    Serial.begin(9600);           // start serial for output
    }

    void loop() {
    delay(100);
    }

    void receiveEvent(int howMany) {
    while (1 < Wire.available()) {
      char c = Wire.read();
      Serial.print(c);
    }
    int x = Wire.read();
    Serial.println(x);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    }

Serial monitor:

    x is 16
    x is 17
    x is 18
    x

Any idea what's causing it and what can I do to further debug it or fix it?
Thank you!

body: After a bit of tinkering, I noticed that removing the delay() call in the slave fixed it and there were no more hangs. Also, when using the Servo library to move a servo instead of blinking the led, Servo.write() hangs while Servo.writeMicroseconds() doesn't. I'd mark the answer that has an explanation for this strange behavior.


body:
The `onReceive` callback get's called from an ISR (interrupt service routine). During the execution of this ISR, the MCU cannot react to other interrupts, since interrupts get automatically turned off at the start of an ISR.

Some functions like `delay()` and `millis()` rely on interrupts to work correctly, since the timekeeping in the Arduino framework is done via a timer interrupt. This means, that you cannot use `delay()` inside of an ISR. It will block forever, waiting for the internal time increment from the pointer, which will never come.

You can also get a problem with big `Serial.print()`s. These `Serial` functions fill the libraries internal buffer, and  the library will use interrupts to actually transmitt the data. If interrupts are turned off (like in an ISR), the buffer get's filled, until it is full. If you then again call `Serial.print()` or one of it's siblings, the library will block the execution, until there is enough space in the buffer, which will never happen. (You don't have this problem here, since you are only printing a few characters, but you should know this)

Generally ISR's should be as short as possible to prevent, that the Arduino misses an interrupt (which may mean data loss). Instead doing the blink in the ISR, you should simply set a flag variable, which you check in your `loop()` function and execute the blink correspondingly. That looks about like this:

    volatile byte flag=0;

    void loop(){
        if(flag){
            // Execute blink here
        }
    }

    void receiveEvent(int howMany) {
        // Do receiving here
        flag=1; //Set flag to a non-zero value to activate the corresponding code in loop()
    }


message:
Global JsonObject (ArduinoJson)

I know a global JsonObject shouldn't be used, but I have my reasons.

I have a JsonObject* functions and I want him to save the content of a file.
With
<!-- language-all: lang-cpp -->

    functions=new JsonObject(jsonBuffer.as<JsonObject>());

I can access the JsonObject, but not when I leave the method. Can someone help me to understand why?
(Don't give me a solution like: copy into a struct, I need a JsonObject ready to be read in all my code.

Full code:

    JsonObject* functions;

    void loadFunctions() {
      File file = SPIFFS.open("/functions.json", "r");
      if (!file) {
        Serial.println("Failed to open the file");
      }else{
        size_t size = file.size();
        if (size > 512) {
          Serial.println("File size is too large");
        }else{
          std::unique_ptr<char[]> buf(new char[size]);
          file.readBytes(buf.get(), size);
          DynamicJsonDocument jsonBuffer(256);
          DeserializationError error = deserializeJson(jsonBuffer, buf.get());
          if (error) {
            Serial.println("Failed to parse file ");
          } else {
            functions=new JsonObject(jsonBuffer.as<JsonObject>());
            Serial.println((*functions)["test"].as<String>()); //this doesn't work in another method
          }
        }
      }
    }

body:
`jsonBuffer` is local to the function. When you leave the function the contents of `jsonBuffer` are lost.

`functions` just points to the internals of `jsonBuffer` to get its data (to save memory).

You can either:

* Make the `jsonBuffer` global so it sticks around all the time, or
* Have a secondary `DynamicJsonDocument` or `StaticJsonDocument` that is global to which you copy your objects once read from `jsonBuffer`.


message:
Help with function template syntax

I am trying to understand the following code snippet from the Espressif OTABasic example for the ESP32 wireless/BT module (see [this repository][1] for the full code).

     ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });

The initial 'ArduinoOTA' looks kinda like an implied 'with ArduinoOTA' statement, but I can't find anything like that in the reference documents.  I know it has something to do with the way the function templates in 'ArduinoOTA.h', but it's beyond me to untangle the syntax.

May I buy a clue, please?

TIA,

Frank

  [1]: https://github.com/espressif/arduino-esp32/blob/master/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino

Thanks to all for the clues; I'm an old-time c/c++ programmer, but must have slept through the 'lambda function' class ;-).

To help my somewhat calcified brain, is it functionally equivalent (if more clunky) to write the above snippet as shown below with the handler functions 'unchained'?

     ArduinoOTA.onStart
 ([]() //lambda function
  {
   String type;
   if (ArduinoOTA.getCommand() == U_FLASH)
    type = "sketch";
   else // U_SPIFFS
    type = "filesystem";

   // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
   Serial.println("Start updating " + type);
  }
 );

 ArduinoOTA.onEnd
 ([]() //lambda function
  {
   Serial.println("\nEnd");
  }
 );

 ArduinoOTA.onProgress
 ([](unsigned int progress, unsigned int total) //lambda func with arguments
  {
   Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  }
 );

 ArduinoOTA.onError
 ([](ota_error_t error) //lambda func with arguments
  {
   Serial.printf("Error[%u]: ", error);
   if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
   else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
   else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
   else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
   else if (error == OTA_END_ERROR) Serial.println("End Failed");
  }
 );

TIA,

Frank

body:
This is called (by me, anyway) "method chaining".

It's nothing special, really.  ArduinoOTA is just an instance of the class ArduinoOTAClass.

Each method of that class does what it needs to do, then returns a reference to the object that the method is within.  Which means that you can then call a method on that returned reference ... and so on.

All the rest of it is "lambda" functions - that is, functions that are embedded within the parameters of the functions being called.

The basic result is something like:

    A.foo().bar().baz();

Where A.foo() returns A. A.bar() returns A. A.baz() returns A.

You can do the same with:

    A.foo();
    A.bar();
    A.baz();


message:
Why doesn't data return when I use Sim808 http request

Why is it that when i use this code for http request on DFRobot_sim808 , I get 'fetch over' message, that means that no data is being returned?

char strings:
```c
char http_cmd[] = " HTTP/1.0\r\n"
                        "Host: 5ac80719.ngrok.io\r\n"
                        "\r\n";
char first[] = "GET /index.php?lat=";

char requestion[100];
```

functions to join them:
```c

void setup() {
  float lat = 32.685362, lon = 48.411512;
  char char_coor[10];

  mySerial.begin(9600);
  Serial.begin(9600);

// Set Http Cmd
  strcpy(requestion,first);
// For Convert latitude float to char
  dtostrf(lat, 4, 6, char_coor);
  strcat(requestion,char_coor);
// For Convert longitude float to char
  dtostrf(lon, 4, 6, char_coor);
  strcat(requestion,"&long=");
  strcat(requestion,char_coor);
  strcat(requestion,http_cmd);

.
.
.
```

and fetching:
```c
sim808.send(requestion, strlen(requestion)-1);
  while (true) {
      int ret = sim808.recv(buffer, sizeof(buffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }

/*
The program stops at above
*/

      buffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(buffer);
      break;
  }
```

thanks

body:
One problem I can see is the `while` loop has a `break` statement in it that "exits" the `while` loop before printing the data. Removing that `break` and printing the data out where the `break` "was" may help. Here's an example of what I'm trying to say:

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

    void loop(){

      while(true){
        int ret = 0;
        if(ret <= 0){
          Serial.println("fetch over...");
          // Print out the received data here...
          Serial.print("Recv: ");
          Serial.print(ret);
          break;
        }
      }

    }


message:
LED strip brightness decreases when using multiple strips

Newbie question here.

I have bought a 5V, 40A power supply to externally power up some LED strips (WS2812B). The Arduino Nano is powered by a standard USB wall charger (5V).
So far I have tested with 4 LED strips (each of about 25 LED's). Each of the strips is connected to an individual data pin on the Arduino in addition to the power supply (5V and ground).

So, to the problem. For each LED strip that gets powered it seems that the brightness of the LED's decreases. Using for example "white color", all the LED's shows a "yellow"-ish color when all the LED strips are powered. If only one or two is powered it looks fine.
The Arduino by the way shares the same ground as the power supply.
What could the cause to this issue be? The power supple should be more than sufficient for the task. Is it the data pins that can't handle it?

Thanks for any help!

EDIT:

I more detail, each LED strip has 3 pins (1 for 5V, 1 for data input, and 1 for ground). Each for the LED strips 5V pin are connected to the + rail on a breadboard where the power supplies + is also connected. The same goes for the ground pin of the LED strips (they are connected to a ground rail on the same breadboard where also the ground of the power supply is connected).
The data pin on the LED strips are connected to 4 (when all are connected) different data pins on the Arduino Nano (A1,A2,A3 and A4).

The ground pin on the Arduino Nano is connected to the same breadboard ground rail as the rest. When I didn't do this the LED's had weird behaviour.
The wires going from the LED strips into the breadboard are standard 24 AWG stranded wires (each of about 50 - 80 cm in length).

Power supply used is "AC 110V-220V TO DC 5V 40A" from ebay.
https://www.ebay.com/itm/AC-110V-220V-TO-DC-5V-12V-24V-Switch-Power-Supply-Driver-Adapter-LED-Strip-Light/152134115704

LED strips that are used "5M WS2812B 5050 RGB, 150LEDS ip65 Waterproof"
https://www.ebay.com/itm/5M-WS2812B-Strip-LED-Lights-5050-RGB-30-60-LED-M-IC-Individual-Addressable-DC5V/113117301639?

body:
40 amps is a LOT of current.

24 AWG wire can't handle anywhere near 20A of current, nevermind 40A. (After a little googling, it looks like 24 AWG wire is limited to about 3.5A.)

Think about it. In the US, 15 amp branch circuits require 14 AWG wire. 20 amp circuits require 12 AWG wire. It looks like 40 amps requires 8 AWG, from the googling I did. (Voltage doesn't really matter when considering current carrying capacity.) So if you want to drive 40 amps, you need 8-gauge wire on both the +5 leg and the ground leg to your LED strip.

As I said in my comment, I found some 144 WS2812B LED strips on Amazon that draw 20A just for one strip. You say your strips have 150 WS2812B LEDs on them. Assuming it's 150 vs 144 of the same LEDS, you're going to need almost 21 amps per strip, so 2 strips will slightly exceed the 40A capacity of your power supply, and *VASTLY* exceed the current handling ability of your wiring. As a general rule you should have a power supply that offers a little **MORE** current that your max needs, never less.(When a power supply reaches its current limits its voltage may start to droop, or it may be slower to adjust to rapid changes in load.)

In addition, You're gonna need **BIG, THICK** 5V and ground wires to feed your LED strips, and you should wire the LED stips in parallel. (I suggest 8 AWG wires for 40A. Those are HUGE, but that's what you need for that much current.) You should not connect either the +5V supply or the ground wires through a breadboard.


message:
How do I convert this program to assembly from c++

I am trying to implement a program in assembly code for an Arduino UNO. A potentiometer is used on an ADC pin for variable time (t). LED1 flashes for t seconds, then stays on for t seconds, then goes off and another LED(LED2) goes on for t seconds and then the cycle repeats (t is variable time that comes from potentiometer). I have a working program in c++ but I want to convert it to assembly. I have just started learning assembly and am not very good at it.

The part I am really stuck on is the analogRead() function. I do not know how to implement this on assembly. Anyone know how to do this?

    #define led 3
    #define led2 2

    void setup()

    {

    Serial.begin(9600);

    //initializing pins
    pinMode(led,OUTPUT);

    pinMode(led2,OUTPUT);

    }
    void loop()

    {

    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);

    // Convert the analog reading(which goes from 0 - 1023) to a voltage(0-5V):
    int voltage = sensorValue * (5.0 / 1023.0);

    // print out the value you read:
    Serial.println(voltage);

    for(int i=0;i<2*voltage;i++)

    {

    digitalWrite(led,LOW);

    delay(100);

    digitalWrite(led,HIGH);

    delay(100);

    }

    //red stays on
    digitalWrite(led,HIGH);

    delay(voltage*500);

    digitalWrite(led,LOW);

    //green stays on
    digitalWrite(led2,HIGH);

    delay(voltage*500);

    digitalWrite(led2,LOW);

    }

body:
The obvious solution for converting any program to assembly is... to
compile it! You can disassemble the resulting binary with a command
like:

```shell
avr-objdump -S -C the_program.elf > the_program.lss
```

This will output a listing of the program, with the original source
interspersed with an hex dump of the binary and the corresponding
disassembly.

> The part I am really stuck on is the analogRead() function.

Here it goes:

```lisp
000003a6 <analogRead>:
 3a6: 8e 30        cpi r24, 0x0E ; 14
 3a8: 08 f0        brcs .+2       ; 0x3ac <analogRead+0x6>
 3aa: 8e 50        subi r24, 0x0E ; 14
 3ac: 87 70        andi r24, 0x07 ; 7
 3ae: 20 91 00 01  lds r18, 0x0100 ; 0x800100 <__data_start>
 3b2: 90 e4        ldi r25, 0x40 ; 64
 3b4: 29 9f        mul r18, r25
 3b6: 90 01        movw r18, r0
 3b8: 11 24        eor r1, r1
 3ba: 82 2b        or r24, r18
 3bc: 80 93 7c 00  sts 0x007C, r24 ; 0x80007c <__TEXT_REGION_LENGTH__+0x7e007c>
 3c0: 80 91 7a 00  lds r24, 0x007A ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3c4: 80 64        ori r24, 0x40 ; 64
 3c6: 80 93 7a 00  sts 0x007A, r24 ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3ca: 80 91 7a 00  lds r24, 0x007A ; 0x80007a <__TEXT_REGION_LENGTH__+0x7e007a>
 3ce: 86 fd        sbrc r24, 6
 3d0: fc cf        rjmp .-8       ; 0x3ca <analogRead+0x24>
 3d2: 80 91 78 00  lds r24, 0x0078 ; 0x800078 <__TEXT_REGION_LENGTH__+0x7e0078>
 3d6: 20 91 79 00  lds r18, 0x0079 ; 0x800079 <__TEXT_REGION_LENGTH__+0x7e0079>
 3da: 90 e0        ldi r25, 0x00 ; 0
 3dc: 92 2b        or r25, r18
 3de: 08 95        ret
```

Now, in order to more easily make sense of it, you need to know what all
those magic numbers mean. The command

```shell
avr-nm -nC the_program.elf
```

will dump the symbols associated with every RAM and flash address. In
order to tell those apart, 0x800000 is added to every RAM address. This
will tell you that, in this specific program, the RAM address `0x0100`
is actually the address of the variable `analog_reference` from the
Arduino core library. Thus, you can replace the line

```lisp
 3ae: 20 91 00 01  lds r18, 0x0100 ; 0x800100 <__data_start>
```

by

```lisp
    lds  r18, analog_reference
```

Then you can use the datasheet to get the names of the memory-mapped IO
registers, and the names of the bits from those registers. I have done
all this for you, so here is the cleaned-up disassembly of
`analogRead()`:

```lisp
analogRead:
    cpi  r24, 14
    brcs 1f
    subi r24, 14
1:  andi r24, 0x07
    lds  r18, analog_reference
    ldi  r25, 1<<REFS0
    mul  r18, r25
    movw r18, r0
    clr  r1
    or   r24, r18
    sts  _SFR_MEM_ADDR(ADMUX), r24
    lds  r24, _SFR_MEM_ADDR(ADCSRA)
    ori  r24, 1<<ADSC
    sts  _SFR_MEM_ADDR(ADCSRA), r24
2:  lds  r24, _SFR_MEM_ADDR(ADCSRA)
    sbrc r24, ADSC
    rjmp 2b
    lds  r24, _SFR_MEM_ADDR(ADCL)
    lds  r18, _SFR_MEM_ADDR(ADCH)
    ldi  r25, 0
    or   r25, r18
    ret
```

If you compare this with [the source code of `analogRead()`][source], it
should now make perfect sense.

> I am trying to implement a program in assembly

Now, if you want to write the assembly _yourself_, that's a whole
different story. If you allow yourself the use of the Arduino core, then
you can simply

```lisp
    ldi r24, 14  ; pin A0 is pin 14
    call analogRead
```

If you don't want to rely on external libraries, and really write
everything yourself, it's going to be a lot harder. I suggest you do
this as a two-step process:

**Step 1**: Learn how to program the ATmega328P in plain C, at the
register level, using no library other than the avr-libc. You can start
by reading this short tutorial about [direct port access][direct-port].
But then you should quickly move on to studying [the
datasheet][datasheet] and [the manual of the avr-libc][avr-libc]. Yes,
that's a lot to digest. I hope you didn't expect this to be quick and
easy. But note that, on those documents, you can skip all the chapters
related to functions you are not going to use.

> I am really stuck on is the analogRead() function.

In the specific case of your example program, you don't need a version
of `analogRead()` that can read any pin with any reference. You can
instead write a simpler version that just reads the currently selected
pin using the currently selected reference:

```c
int simple_analog_read(void)
{
    ADCSRA |= 1<<ADSC;                    // start the converion
    while (ADCSRA & (1<<ADSC)) continue;  // wait till it's done
    return ADC;                           // return the reading
}
```

Of course, this assumes you have appropriately initialized the ADC.

> `int voltage = sensorValue * (5.0 / 1023.0);`

You really, _really_ don't want to implement something like this in
assembly. The AVR hardware supports neither floating point nor
divisions. All this is handled by the compiler through supporting
libraries, and _they are not simple_. What you really want is something
like

```c++
int voltage = (sensorValue * 5) >> 10;
```

which is incidentally more correct, as the scaling factor is 5/1024, not
5/1023 (see the datasheet).

**Step 2**: Learn assembly, and rewrite your low-level C code in
assembly. If your C code is low-level enough this should not be too
hard. As a learning aid, you can ask the compiler to do it for you and
then try to make sense of what it did. If you just try to compile the
`simple_analog_read()` function I wrote above you will see the
translation to assembly is almost trivial.

[source]: https://github.com/arduino/ArduinoCore-avr/blob/1.6.23/cores/arduino/wiring_analog.c#L38
[direct-port]: https://www.arduino.cc/en/Reference/PortManipulation
[datasheet]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
[avr-libc]: https://www.nongnu.org/avr-libc/user-manual/index.html


message:
Using Arduino fix_fft or arduinoFFT library to filter some specific sound?

I would like to know if there is a way to filter some specific sound using **FFT** on arduino. For instance, there is wind sound frequency in my analysis and I want to take it off. I searched for that a lot, but I didn't find something useful to solve this problem.

body:
FFT is a tool for _analyzing_ sound. It is not very appropriate for
filtering, unless you have loads of computing power to spare. And it is
even less appropriate for _real-time_ filtering, if that is what you are
after.

Attempting to filter-out a noise based on its frequency is a reasonable
strategy for narrow-band noise, i.e. noise that lies in a narrow band of
frequencies. You can hope that, with some luck, removing this narrow
band doesn't affect too much the interesting part of the signal.

Alas, wind noise is very broad band, although it has more weight at low
frequencies:

![wind spectrogram](https://i.stack.imgur.com/N40sx.png)

([image source](https://www.reddit.com/r/askscience/comments/3tkdgg/is_it_possible_to_break_the_sound_of_roaring_wind/)).

If the frequencies that interest you are above ≈ 2 – 4 kHz, you could
try a simple high-pass filter. Something like this should work even on
an Arduino if the sample rate is not too high:

```c++
static uint16_t filter(uint16_t input)
{
    static uint16_t sum;
    uint16_t delta = input - (sum >> SCALE);
    sum += delta;
    return delta
}
```

where `SCALE` is a small constant that determines the cut-off frequency.

**Edit**: The Z-domain transfer function of this filter is

H = (z − 1) / (z − u)

where u = 1 − 2−SCALE. Its cut-off frequency is then
approximately fsamp ÷ (2 π 2SCALE).


message:
Powering SIM800L

With peak consumption at 2A, the SIM800L needs much more current than can be supplied by an Arduino or NodeMCU.

What is the best strategy to power this module, considering that you have access to a 100-240V outlet?

body:
The cleanest solution is to use separate power supplies for your MCU and your other high power devices. Get a 2.5A supply for the SIM800L, and a more modest supply for the Arduino/NodeMCU.

If you use the same power supply for both, you should use a bigger power supply than your max current needs to minimize "droop" as the load changes. You might also need to add filtering capacitors to the 5V rails of each device fed by the power supply.

## EDIT

I've used this 2A power supply in my projects before: https://www.amazon.com/gp/product/B01G6ZJ6DY/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

You could use one of those for your SIM800L, and a 0.5A supply for the Arduino (A USB power supply would be fine.) Just be sure to tie the ground lines of the separate power supplies together.


body: I am usually using 12V/1000 mA adapter source to power Arduino and adjustable step-down/buck converter which powers GPS and similar modules. Advantage of this is that these converters usually have big capacitors on input and output, so you do not have to use additional auxiliary capacitors.


body:
I had to design a board for a customer with a built in LTE modem module (similar to a SIM800), and the power circuitry was something that required special consideration.

One requirement of the board was that the modem should be able to be powered on and off to save power, but that powering it on shouldn't ever cause the rest of the board to brownout.

To this end a separate 5V power circuit was built with a "soft start" facility built in.  This was always on, and fed into a number of capacitors to act as a reservoir. From them the power went via a large P-channel MOSFET to switch the power on to the LTE module when needed.  The capacitors provided the extra inrush current the LTE module demanded at powerup, and the soft start of the power supply limited the initial inrush current of charging the capacitors.

The power supply also had a "power good" output on it which was monitored to know when the output voltage had risen to an acceptable level (and hence the capacitors were charged) and the LTE module was able to be safely enabled.

The basic circuit was:

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

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

<!-- End schematic -->

That is a somewhat overkill probably for your situation though, but you should understand how it's done in the "real world" in a proper device.  However for experimental / prototyping with an Arduino where you aren't wanting to turn the modem on and off, and aren't too worried about the odd brownout, and bulkiness isn't of as much of a concern, then simply using two suitably sized external power supplies is adequate.  One small one to power the MCU (Arduino), and one larger one to power the modem.

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

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

<!-- End schematic -->

Because the power supplies themselves should have plenty of capacitance, and they are separately powered from a low impedance source (the mains power) there should be no interference between the modem and the MCU.


message:
How do you write to a specific register using I2C communcation?

I am trying to write to a charging IC (BQ24193) and I am trying to figure out how to use I2C to write to a specific register so I can set up the charging IC properly. I have watched a few videos on the communication protocol, but I don't understand how to write to a register directly. Your help would be appreciated. Thanks.

Datasheet: http://www.ti.com/lit/ds/symlink/bq24193.pdf

body:
The Arduino uses the [`Wire.h` library](https://www.arduino.cc/en/reference/wire) to communicate on an I2C bus.

Writing to a register in I2C is usually done by sending two bytes to the correct I2C address.  The first byte is usually the register address, and the second is the value to place into the register:

    #define CHIP_ADDRESS     0x6B
    #define REGISTER_ADDRESS 0x12

    Wire.beginTransmission(CHIP_ADDRESS);
    Wire.write(REGISTER_ADDRESS);
    Wire.write(0x18);
    Wire.endTransmission();

Reading from a register is slightly more tricky, in that first you need to write to the chip to set the register address, then as a separate operation you need to read from that address:

    Wire.beginTransmission(CHIP_ADDRESS);
    Wire.write(REGISTER_ADDRESS);
    Wire.endTransmission();
    Wire.requestFrom(CHIP_ADDRESS, 1); // We want one byte
    uint8_t val = Wire.read();


message:
D1 Mini latch button using rst pin

I'm trying to use a Wemos D1 mini as a smart button that will boot up, perform a task, and then shut back down. I'd like to do this as a true power off as opposed to any sort of sleep mode.

I'm hoping I can do something similar to this post https://www.esp8266.com/viewtopic.php?f=11&t=4458

1. Tie RST pin to a Low GPIO pin so that it doesn't boot
2. Push a button that will run 3.3v to RST pin to make it go high and cause a boot up
3. Flip the GPIO pin that is tied to RST to high so that it stays running when button is no longer pressed
4. Run some code and flip GPIO back to LOW shutting down

Things I've tried:

1. Tie to GPIO15 (D8) - This stops the boot and starts booting when button is pressed but never finishes booting up. I'm assuming I am causing D8 to go high by pressing my button and interfering with the boot, but honestly not sure

2. Tie to GPIO4 or 5 (D2, D1). This doesn't prevent boot.

3. I've also tried #2 with a pull down resistor on the GPIO pin, but that doesn't seem to work either

Any help would be much appreciated.

body:
Try using D8, also follow this for selecting your pins to make sure the code runs as it is attended to work

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

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


body:
as far as I know, it's not possible [the way as simple as you said]. here's some notes :

 1. after a reset, GPIOs are set as inputs. if you connect a GPIO to RST and make it low, it resets the chip, but immediately sets the GPIOs as inputs and the RST is released.
 2. if you don't use appropriate resistors, you'll burn the GPIO driver by connecting an output GPIO to a supply line. e.g. when you are trying to connect 3.3v to RST and LOW GPIO which is holding RST down.
 3. sleep modes are very efficient. many times, the battery self discharge is much higher than an slept MCU
 4. if you insist, turn the chip off by cutting off it's supply using an external circuitry. a 555 with a mosfet without any res,cap will do the jb (using only it's internal flip flop)


body:
To do this you would usually use MOSFETs to control the power.

Take the following circuit, for example:

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

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

<!-- End schematic -->

M1 is normally off, having its gate pulled up by R1.

Pressing SW1 pulls the gate of M1 low, allowing current to flow through it to power the D1.

The D1 boots up, and immediately drives the GPIO high.

This then turns on M2 (which is normally off, having the gate pulled down by R2), which in turn pulls the gate of M1 low.

SW1 can now be released since M2 is doing the same job.

To turn off, simply drive the GPIO low, or allow it to float as an input, in which case R2 will turn off M2, which then turns off M1, which stops the current flowing.


message:
Arduino Uno not working after Short-circuit

While wiring up my new Arduino Uno R3, I accidentally shorted the 5V pin and the GND pin (for less than a sec). It was powered by a 12V 500mAh power supply through the Arduino DC power jack. ![Now the arduino looks like this ](https://i.stack.imgur.com/CvYwI.jpg). The ON, Rx, X1 and L LED's are glowing continuously, and also, pressing the reset button doesn't have any effect on the LED's and arduino doesn't restarts. How can I get my arduino working again?

body:
The regualator of that 5V Blew up or the diode you need to read the schemtics of the Arduino Uno and check the circuits.

https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf


body:
Chances are the cheap Chinese clone board you have has an inferior 5V regulator with no thermal protection.

These are notorious for breaking with a short circuit (over-current = over-temperature = meltdown).  And when they break they "fail short", which means that they end up working like a simple piece of wire - the voltage you put in is the voltage you get out.

That means that 12V has now been sent into the rest of the Arduino, and has destroyed everything - the main MCU, the USB interface chip, etc.

In short: your board is dead.


body: You can tell it's a fake Uno because the USB chip is not an Atmega32U4.


message:
Is it possible to put priorities between external interrupts?

My question is quite simple. I am using one external interrupt on the Mega2560 to wake it up with an alarm from the rtc DS3231 and record data from sensors for about 30 seconds and I would like also to use the other external interrupt to wake it up in case of shock detection to measure the signal.

The thing is that I know external interrupts have priority on internal interrupt but is it possible to put, in my case, the shock detection prior to the alarm ? In case the shock occurs during the alarm recording I would prefer to record the shock signal.

Thank you for your help !

body:
Interrupts are not the right place to handle priorities. The interrupt
handlers should be as short as possible. Then the likeliness of two of
them happening at the same time is very low. And even if it happens, the
lowest-priority interrupt will only be delayed by a handful of
microseconds, which should not be a big deal.

In this case, the sensible approach is to have the interrupt handlers
set a global flag and _do nothing else_. Then the main program will
check the flags and do the real work, handling the priorities as needed.

Conceptually, the code could be something along these rough lines:

```c++
// Global flags.
volatile bool alarmDetected;
volatile bool shockDetected;

// Interrupt handlers.
void onAlarmInterrupt() { alarmDetected = true; }
void onShockInterrupt() { shockDetected = true; }

void loop() {
    if (shockDetected) {  // check this first!
        measureShockData();
        if (gotEnoughShockData()) {
            shockDetected = false;
            alarmDetected = false;  // ignore the alarm
            goToSleep();
        }
    } else if (alarmDetected) {
        recordSensorData();
        if (gotEnoughSensorData()) {
            alarmDetected = false;
            goToSleep();
        }
    }
}
```

Note that you can remove the line that ignores the alarm in case of
shock. If you do so, the alarm will be handled _after_ all relevant
shock data has been recorded.


message:
Http request change delay

i'm noob in coding i try to make some led blink ( with succes ) and now i would like to add http request to change delay.

i have no error compiling the code but it dont work any idea ?

Thanks

     include SPI.h
     include Ethernet.h

    unsigned long maxTime = 4000;

    EthernetServer arduinoServer(81);
    EthernetServer httpServer(80);

    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network:
    byte mac[] = {
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    };
    IPAddress ip(192, 168, 8, 60);

    // Initialize the Ethernet server library
    // with the IP address and port you want to use
    // (port 80 is default for HTTP):
    EthernetServer server(80);

    ////CODE IS 11001010
    int led1 = 6;  // = 0
    int led2 = 7;  // = 1

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

      // Setup the 3 pins as OUTPUT
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);

      // You can use Ethernet.init(pin) to configure the CS pin
      //Ethernet.init(10);  // Most Arduino shields
      //Ethernet.init(5);   // MKR ETH shield
      //Ethernet.init(0);   // Teensy 2.0
      //Ethernet.init(20);  // Teensy++ 2.0
      //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
      //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
      Serial.println("Ethernet WebServer Example");

      // start the Ethernet connection and the server:
      Ethernet.begin(mac, ip);

      // Check for Ethernet hardware present
      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
        while (true) {
          delay(1); // do nothing, no point running without Ethernet hardware
        }
      }
      if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Ethernet cable is not connected.");
      }

      // start the server
      server.begin();
      Serial.print("server is at ");
      Serial.println(Ethernet.localIP());

    }

    void loop()
    {
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      delay(maxTime);
      digitalWrite(led2, LOW);
      delay(maxTime);
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      delay(maxTime);
       digitalWrite(led1, HIGH);
       digitalWrite(led2, LOW);
      delay(maxTime);
      digitalWrite(led1, LOW);
       delay(maxTime);

       digitalWrite(led1, HIGH);
       digitalWrite(led2, LOW);
      delay(maxTime);
       digitalWrite(led1, LOW);
       digitalWrite(led2, HIGH);
      delay(maxTime);
       digitalWrite(led1, HIGH);
       digitalWrite(led2, LOW);
      delay(maxTime);
       digitalWrite(led1, LOW);
       digitalWrite(led2, HIGH);
      delay(maxTime);
       digitalWrite(led1, HIGH);
       digitalWrite(led2, LOW);
      delay(maxTime);
         digitalWrite(led1, LOW);
       digitalWrite(led2, LOW);
      delay(5000);

     // listen for incoming clients
    }

    void receiveHttpRequest() {
      EthernetClient client = httpServer.available();
      String requestInputString;
      boolean resetArduino = false;
      boolean forceSolved = false;
      client.setConnectionTimeout(50);

      if (client)
      {
        Serial.println("new client");
        // an http request ends with a blank line
        boolean currentLineIsBlank = true;
        boolean firstLine = true;
        requestInputString = String("");
        while (client.connected())
        {
          if (client.available())
          {
            char c = client.read();
            if (firstLine)
            {
              requestInputString += String(c);
            }
            Serial.write(c);
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank)
            {

              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println("Connection: close"); // the connection will be closed after completion of the response
              client.println();
              client.println("<!DOCTYPE HTML>");
              client.println("<html><body>");

                int newMaxTime = requestInputString.substring(20).toInt();
                if (newMaxTime < 2000) {
                  newMaxTime = 2000;
                }

                maxTime = newMaxTime;

                client.print(String("New maxTime is: "));
                client.println(maxTime);
              }
            }
          }
        }
      }

body:
Inside `delay()` no other code can run. Which also means that no clients can be serviced.

Change that delay-laden function to a state machine mirroring blinkWithoutDelay.

That is you test `if(millis() - previousTimestamp < delay)` and if true progress to the next state in your blinks and update `previousTimestamp`.

After that `if` you call `receiveHttpRequest()` to see if any clients are waiting and process the input.


message:
Missing bytes sended through serial from C# app

I am trying to store values sended by C# app in EEPROM via Arduino UNO. Here is a C# code that reads bytes from file (I'm 100% sure that there are, and always will be 256 bytes) and sends the buffer via SerialPort

            SerialPort port = new SerialPort("COM3", 9600);
            const string fileName = @"filepath";
            port.Open();
            byte[] buffer = File.ReadAllBytes(fileName);
            port.Write("W");
            port.Write(buffer, 0, buffer.Length);

Here is Arduino Code

    int flag;
    int datasize = 256;
    byte byteBuffer[256];

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

      //read_write();
    }

    void loop() {
      readEEPROM();
      writeEEPROM();
      delay(500);
    }

    void readEEPROM() {
      if (Serial.available()) {
        flag = Serial.read();
        if (flag == 'R') {
          for (int i = 0; i < datasize; i++) {
            byteBuffer[i] = ME.read(i);
          }
          flag = 'S';
          Serial.write(byteBuffer, datasize);
        }
      }
    }
    void writeEEPROM() {
      if (Serial.available()) {
        flag = Serial.read();
        if (flag = 'W') {
          int bytesRead = 0;
          digitalWrite(LED_BUILTIN, HIGH);
          delay(500);
          while (bytesRead < 256) {
            if (Serial.available() > 0) {
              byteBuffer[bytesRead] = Serial.read();
              bytesRead++;
            }
          }
      digitalWrite(LED_BUILTIN, LOW);

      for (int i = 0; i < datasize; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(50);
        ME.writeEnable();
        ME.write(i, byteBuffer[i]);
        ME.writeDisable();
        digitalWrite(LED_BUILTIN, LOW);
        delay(50);
      }
      flag = 'S';
       }
      }
     }

As you can see in `writeEEPROM` function arduino turns on `BUILTIN_LED` before it starts reading serial, sadly the LED is never turning off, which makes me think like there are never 256 bytes in SerialPort, whats more, when i turn the c# program on again, the arduino successfully leaves the while loop, but the data is deformed, I mean the values are different.

body:
There's two basic things wrong here.

First is your way of opening the serial port and immediately sending data.  The Arduino is reset when you open the serial port and the bootloader runs. This takes a second or so, and during that time any data that you send is lost.

Secondly you're not checking for a flag of "W" but instead you're assigning "W" to the flag, which always succeeds.

The line

    if (flag = 'W') {

should read

    if (flag == 'W') {

To get around the first problem you can either just put a delay (however you do that in C#) after opening the port and before sending the "W", or you could implement a "Are you there?" handshake to look for the Arduino.

One example would be to add an extra flag of (say) "?" to which the Arduino simply responds "Y".

The PC then sends "?" and, if it doesn't receive "Y" within a certain timeout it loops sending "?" again.

Once it receives "Y" then it knows the Arduino is there and ready to receive data, so you can send the "W" command and the data.


message:
is there any archives of melody tones for buzzer used in arduino?

I am using buzzer in my arduino and I read some articles about using array of tones(notes in music) with different frequencies to play play pleasant melodies.however, I do not find any site and archives for tones used in industrial, such as Start,Stop,warning,danger,next level,.... is there any site that collects these things and if not how can I create my own array of tones?

this is notes I have

    #define NOTE_B0  31
    #define NOTE_C1  33
    #define NOTE_CS1 35
    #define NOTE_D1  37
    #define NOTE_DS1 39
    #define NOTE_E1  41
    #define NOTE_F1  44
    #define NOTE_FS1 46
    #define NOTE_G1  49
    #define NOTE_GS1 52
    #define NOTE_A1  55
    #define NOTE_AS1 58
    #define NOTE_B1  62
    #define NOTE_C2  65
    #define NOTE_CS2 69
    #define NOTE_D2  73
    #define NOTE_DS2 78
    #define NOTE_E2  82
    #define NOTE_F2  87
    #define NOTE_FS2 93
    #define NOTE_G2  98
    #define NOTE_GS2 104
    #define NOTE_A2  110
    #define NOTE_AS2 117
    #define NOTE_B2  123
    #define NOTE_C3  131
    #define NOTE_CS3 139
    #define NOTE_D3  147
    #define NOTE_DS3 156
    #define NOTE_E3  165
    #define NOTE_F3  175
    #define NOTE_FS3 185
    #define NOTE_G3  196
    #define NOTE_GS3 208
    #define NOTE_A3  220
    #define NOTE_AS3 233
    #define NOTE_B3  247
    #define NOTE_C4  262
    #define NOTE_CS4 277
    #define NOTE_D4  294
    #define NOTE_DS4 311
    #define NOTE_E4  330
    #define NOTE_F4  349
    #define NOTE_FS4 370
    #define NOTE_G4  392
    #define NOTE_GS4 415
    #define NOTE_A4  440
    #define NOTE_AS4 466
    #define NOTE_B4  494
    #define NOTE_C5  523
    #define NOTE_CS5 554
    #define NOTE_D5  587
    #define NOTE_DS5 622
    #define NOTE_E5  659
    #define NOTE_F5  698
    #define NOTE_FS5 740
    #define NOTE_G5  784
    #define NOTE_GS5 831
    #define NOTE_A5  880
    #define NOTE_AS5 932
    #define NOTE_B5  988
    #define NOTE_C6  1047
    #define NOTE_CS6 1109
    #define NOTE_D6  1175
    #define NOTE_DS6 1245
    #define NOTE_E6  1319
    #define NOTE_F6  1397
    #define NOTE_FS6 1480
    #define NOTE_G6  1568
    #define NOTE_GS6 1661
    #define NOTE_A6  1760
    #define NOTE_AS6 1865
    #define NOTE_B6  1976
    #define NOTE_C7  2093
    #define NOTE_CS7 2217
    #define NOTE_D7  2349
    #define NOTE_DS7 2489
    #define NOTE_E7  2637
    #define NOTE_F7  2794
    #define NOTE_FS7 2960
    #define NOTE_G7  3136
    #define NOTE_GS7 3322
    #define NOTE_A7  3520
    #define NOTE_AS7 3729
    #define NOTE_B7  3951
    #define NOTE_C8  4186
    #define NOTE_CS8 4435
    #define NOTE_D8  4699
    #define NOTE_DS8 4978
    #define REST      0

    // DURATION OF THE NOTES
    #define BPM 480      //you can change this value changing all the others
    #define H 2*Q //half 2/4
    #define Q 6000U/BPM //quarter 1/4
    #define E Q/2   //eighth 1/8
    #define S Q/4 // sixteenth 1/16
    #define W 4*Q // whole 4/4

body:
    #define NOTE_C4  262
    #define NOTE_CS4 277
    #define NOTE_D4  294
    #define NOTE_DS4 311
    #define NOTE_E4  330
    #define NOTE_F4  349
    #define NOTE_FS4 370
    #define NOTE_G4  392
    #define NOTE_GS4 415
    #define NOTE_A4  440
    #define NOTE_AS4 466
    #define NOTE_B4  494
    #define REST      0

    int piezoPin = 13;
    int numTones = 15;
    int tempo = 2.5;

    //Twinkle Twinkle Little Star:

    int tones[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4, REST};

    int duration[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500, 500, 500, 1000, 4000};

    void setup()
    {
      for (int i = 0; i < numTones; i++)
      {
        tone(piezoPin, tones[i], duration[i] / tempo);
        delay(duration[i] / tempo);
      }
      noTone(piezoPin);
    }

    void loop()
    {
    } // Reset to play the song again


message:
Wiring power new power button to UPS power module for raspberry pi

I have a UPS Power Module Expansion Board for Raspberry Pi 3B/3B+(Plus) and removed the power button because it is in the way and would like to attach this read button instead. But it is not working, they board does not turn on?

Am i wiring the incorrectly?

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

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

  [1]: https://i.stack.imgur.com/xPwxN.jpg
  [2]: https://i.stack.imgur.com/3XRvJ.jpg

body: This looks like a momentary push-button; use a latching button (push-on/push-off) instead.


message:
ESP8266 using EEPROM to store a value of 100,000

I'm using Wemos mini in my project. I wish to store a Boolean value in cell #0, which changes every boot.

Since writing to EEPROM is limited to roughly 100,000 cycles - I want to store in cell #1 the amount of writing cycles done so far, so when reaching 100,000 , value will be stored in cell#2 and writing cycles will be stored in cell#3 and so on.

Reading and writing using `#include <EEPROM.h>` is done as needed, but since each cell can store a byte, it can only reach 255.

My question is how to store a value of 10^6 (except of convert it to a*2^0 + b*2^1 + c*2^2 + d*2^3....).

Guy

**EDIT1**

Part or relevant code:

    void setup() {
            Serial.begin(9600);
            Serial.println("BEGIN:");
            if (HARD_REBOOT) {
                    EEPROM.begin(1024);
            }
            if (HARD_REBOOT) {
                    EEPROM.write(0,100000);
                    EEPROM.commit();
                    delay(50);
                    Serial.print("value in flash: ");
                    Serial.println(EEPROM.read(0));
            }
    }

and its output:

    Ȥl⸮⸮BGS[⸮<b8ɗ⸮BEGIN:
    22:40:58.732 -> value in flash: 160

body:
The esp doesn't have an eeprom, but emulates it in its flash. Therefore 100.000 cylces will not apply, it's more like 10.000 cycles for flash.

The easiest way to prepare a datatype to be stored as bytes is to use [union][1] like follows:

    union Converter{
      uint32_t ui32;
      byte eeprom_bytes[4];
    }convert;

    void convert_for_eeprom (uint32_t your_number) {
      convert.ui32=your_number;
      // convert.eeprom_bytes contains the 4-byte represenstation of your number, write those to eeprom
    }

    uint32_t convert_from_eeprom () {
      // read four bytes from eeprom and assign those to convert.eeprom_bytes
      return convert.ui32;
    }

Note that this isn't a type conversion and the value of convert.eeprom_bytes are not meant to be processed, as they are simply interpreted as if they were a four-byte array, indeed those bytes contain "dumb" values. This way you can "convert" **any datatype** for byte-wise storage and read-back respectively.

Another option to convert a 32 bit integer to 4 bytes is by using bit-wise operations:

    uint32_t your_number=100000;
    byte b1=your_number;
    byte b2=your_number>>8;
    byte b3=your_number>>16;
    byte b4=your_number>>24;

But this only makes sense for integers and I suggest taking a look at `union`.
  [1]: https://en.cppreference.com/w/cpp/language/union


body:
to save any variable to EEPROM use [`EEPROM.put()`][1], to read it use `EEPROM.get()`. example

`EEPROM.put(EEPROM_COUNT_ADDR, count);`

`EEPROM.get(EEPROM_COUNT_ADDR, count);`

On esp8266 EEPROM is emulated in flash and there **the whole page wears out**. [The EEPROM library][2] of esp8266 does what can be done to protect the flash pages used for EEPROM emulation.

  [1]: https://www.arduino.cc/en/Reference/EEPROMPut
  [2]: https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom


message:
SD card reader and lcd display

I have sd card reader and lcd display. I want to display bitmap with u8g2 library. My bitmap looks like:

    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00

If i write it in arduino ide like:

    static unsigned char bytes[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00
    };
Everything works fine. So how can i read it from sd card to have same result as in second code?

body:
This is talked about in multiple Arduino threads.  [This thread][1], [this thread][2] & [this thread][3] are just 3 found.

It appears reading and SDCard using an Arduino results in a text like character string.  The task is to parse this (if necessary) and convert it to the desired individual values.

The most efficient way to do this might be to use the [toCharArray()][4] to copy the String’s characters to a character array (buffer).  However, this implies the data is stored exactly as needed in the SDCard.  Which may be difficult to do.  Simply put, the program would read in a string (of likely unprintable letters) from the SDCard.  Then use the above function to convert that string into the supplied character array (buffer).

(Some more experienced readers might say if one used a [union][5] here, that the character string and the array of type characters would occupy the same memory and hence have the same data.  So no call to a conversion function is needed.  Once you read in the data as a string, it would be available to read out as an array of characters.)

More often it is preferred to store SDCard data for Arduino's in a (printable) text format.  Further it appears most store data using the [CSV][6] format.  When reading back this format the strings have to be parsed.  That is, the commas need to be found and the printable numbers between the commas need to be individually converted from short character strings to values.  The function atoi() is used to convert a character string like "123" to the integer value 123.  Then you can cast that number from an integer to an unsigned character to store in your array.

Another and perhaps easier approach is to use the [toint()][7] function call.  It would appear reading a number followed by a carriage return from the SDCard then unsung this function will result in an integer value.  You would not have to look and remove delineation characters as the toint() function is looking for carriage returns as the delineating character for you.

Many times working with an unknown amount of data is a problem.  If your data will always be a fixed size of 36 bytes - this should not concern you.

  [1]: https://forum.arduino.cc/index.php?topic=260983.0
  [2]: https://forum.arduino.cc/index.php?topic=492359.0
  [3]: https://forum.arduino.cc/index.php?topic=216587.0
  [4]: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/tochararray/
  [5]: https://en.wikipedia.org/wiki/Union_type#C/C++
  [6]: https://en.wikipedia.org/wiki/Comma-separated_values
  [7]: https://www.arduino.cc/en/Tutorial.StringToIntExample


message:
Does MFRC522 supports native SPI of Arduino Due?

Does [MFRC522 library][1] support native SPI interface of Arduino Due?

By native SPI I mean this one:
[![enter image description here][2]][2]

I came here with this question because the initializer asks for 2 pins: SS and Reset:

    MFRC522(byte chipSelectPin, byte resetPowerDownPin);

SS pin can be any, but what about Reset?

  [1]: https://github.com/miguelbalboa/rfid
  [2]: https://i.stack.imgur.com/exsHn.png

body:
There is no reason why it wouldn't support the Due's SPI. It just uses the default SPI.h library as the interface.

The `resetPowerDownPin` can be anything you like. It is not part of the SPI protocol but specific to that library. It is just controlled with `digitalWrite()` internally.

If you don't want to use the functionality you can set it to `MFRC522::UNUSED_PIN` and it will be disabled.


message:
What does (byte*)variable_name mean in C++?

Gentlemen,
  I am a novice C++ programmer, When I was trying to learn how to use EEPROM with Arduino, I came across this statement

> i2c_eeprom_write_page(0x57, 0, (byte *)somedata, sizeof(somedata));

where I need to know what does (byte*) somedata mean?, please let me know if someone know the answer

Regards,

Mr.B

body:
It means "Interpret this pointer as a pointer to byte data".  It's called "Casting" and allows you to fool the compiler into thinking that one type of data is another.

For example, your function expects a `byte *` (a pointer to byte data), and if you have `char *` as your variable you can change it on the fly to `byte *` by casting it like that.


message:
Soft wdt reset error on NodeMCU (ESP8266)

I am getting error on Serial monitor Soft WDT reset. I decoded the error code also and found the following stacktrace.

I am using SIM808 module and DFRobot_sim808 as the library.

> 0x4010030d: millis at <Directory>AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/core_esp8266_wiring.c line 180
>
> 0x401003b9: __digitalWrite at <Directory>AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/core_esp8266_wiring_digital.c line 82
>
> 0x40202863: sim808_wait_for_resp(char const*, DataType, unsigned int, unsigned int) at <Directory>Documents\Arduino\libraries\DFRobot_SIM808-master/sim808.cpp line 172
>
> 0x402027a4: sim808_send_byte(unsigned char) at <Directory>Documents\Arduino\libraries\DFRobot_SIM808-master/sim808.cpp line 118
>
> 0x402028ce: sim808_check_with_cmd(char const*, char const*, DataType, unsigned int, unsigned int) at <Directory>Documents\Arduino\libraries\DFRobot_SIM808-master/sim808.cpp line 191
>
> 0x402025dc: DFRobot_SIM808::init() at <Directory>Documents\Arduino\libraries\DFRobot_SIM808-master/DFRobot_sim808.cpp line 63
>
> 0x402024c1: setup at G:\Development\ESP8266\SIM Module\sim_module/sim_module.ino line 41 (discriminator 1)
>
> 0x40203248: loop_wrapper() at <Directory>AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/core_esp8266_main.cpp line 122
>
> 0x40100e8d: cont_wrapper at <Directory>AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/cont.S line 81

I tried to find solution for the same everywhere but none found it. But the same code I am trying on arduino it works but not for ESP8266. I dont have long waiting loop(). But still it gives me error.

Below is the code for the same

    #include <DFRobot_sim808.h>
    #include <SoftwareSerial.h>

    #define PHONE_NUMBER "********"

    #define MESSAGE  "hello,world"

    #define PIN_TX D1
    #define PIN_RX D0

    SoftwareSerial mySerial(PIN_RX, PIN_TX);
    DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

    void setup() {
      delay(1000);
      mySerial.begin(9600);
      Serial.begin(9600);

      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB
      }
      while(!sim808.init()) {
          delay(1000);
          Serial.print("Sim808 init error\r\n");
      }
      Serial.println("Sim808 init success");
      Serial.println("Start to send message ...");

      sim808.sendSMS(PHONE_NUMBER,MESSAGE);
    }

    void loop() {

    }

body:
The culpret is the SIM808 library. It's not written to work well with the ESP8266.

The problem lies in [this function](https://github.com/DFRobot/DFRobot_SIM808/blob/master/sim808.cpp#L158):

    boolean sim808_wait_for_resp(const char* resp, DataType type, unsigned int timeout, unsigned int chartimeout)
    {
        int len = strlen(resp);
        int sum = 0;
        unsigned long timerStart, prevChar;    //prevChar is the time when the previous Char has been read.
        timerStart = millis();
        prevChar = 0;
        while(1) {
            if(sim808_check_readable()) {
                char c = serialSIM808->read();
                prevChar = millis();
                sum = (c==resp[sum]) ? sum+1 : 0;
                if(sum == len)break;
            }
            if ((unsigned long) (millis() - timerStart) > timeout * 1000UL) {
                return false;
            }
            //If interchar Timeout => return FALSE. So we can return sooner from this function.
            if (((unsigned long) (millis() - prevChar) > chartimeout) && (prevChar != 0)) {
                return false;
            }

        }
        //If is a CMD, we will finish to read buffer.
        if(type == CMD) sim808_flush_serial();
        return true;
    }

It has a loop that can take some time to run, and it doesn't `yield()` at any point to allow the ESP8266's housekeeping routines to run and "kick the dog".

Adding a call to `yield()` inside the `while(1)` loop should cure the problem.


message:
LCD displays bad character while counting rotation

I have been practicing RPM and rotation counter in arduino using infrared optocoupler. I try to implement number of rotation for drill machine but whenever drill starts to rotate, LCD prints bad characters instead of displaying rotation.
Here is my code:

    #include<LiquidCrystal.h>

     LiquidCrystal lcd(A0,A1,A2,A3,A4,A5);
                 int SensorPin=      13;

                 int Counter = 0;
    void setup() {
      lcd.begin(16,2);
      pinMode(SensorPin,INPUT);
        lcd.setCursor(0,0);

    }

    void loop() {

               lcd .setCursor(0,0);

              if(digitalRead(SensorPin))
      {
        Counter = Counter+1;
        while(digitalRead(SensorPin));

      }
      lcd.setCursor(0,1);
         lcd.print(Counter);
      // put your main code here, to run repeatedly:

    }

Here is my lcd at initial step:

[![lcd on start][1]][1]

When I start my drill, LCD changes to this:

[![lcd with bad charcters][2]][2]

  [1]: https://i.stack.imgur.com/2iDuU.png
  [2]: https://i.stack.imgur.com/IJXZW.png

body:
I suspect you get electrical noise on the leads from the optocoupler. A few test to help find cause:
1) Does the counter work if you rotate it by hand?
2) Does the LCD go funnny if you just have the optocoupler approximatly in the same position, but not count anything.


message:
Everything is ready for project . I have one doubt! I am using transmitter + Arduino *Uno*..and receiver + arduino *nano* will it work?

Everything is ready for project except hardware!

 I have one doubt!

I am planning to use transmitter of Arduino *Uno* and receiver of Arduino *Nano*.  Will it work? Both Uno and Nano obey for same program? (The transceivers used are  Nrf24lO1 pa+lna!)

body: Yes, it will work, in much the same way that you can send an email from a Mac to a Windows PC. The type of PC doesn't matter as long as they use the same protocol. As you haven't shared any details in that direction, I would say that if you have coded correctly, then it will work.


body: That cannot be determined until a much better description of your project is given. The parts you named are compatible with both processors. It could fail for a simple software mistook or a bad connection. Generally speaking the UNO and Nano are interchangeable electrically but not mechanically. The nano gives you two additional analog channels. Start by getting the RF to work, this probably will be the most problematic to get going. Use seperate power supplies for the RF devices.


message:
Nodemcu Server with multiple sensors

I am trying to connect my nodemcu client with nodemcu server, while my client is connected with two sensors (DHT11 and Soil Moisture) and it is workign perfectly, but on the server side I am unable to get all values, it is only giving me value of one parameter.
Server Side Code
<!-- language-all: lang-cpp -->
```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
String apiWritekey = "PBD5LAJC4BSV3OKC"; // replace with your THINGSPEAK WRITEAPI key here
const char* ssid = "Dhamaal";// your wifi SSID name
const char* password = "03334204224" ;// wifi pasword
///~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~///

///~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~///
const char* httpserver = "api.thingspeak.com";
ESP8266WebServer server;
WiFiClient client;

// Configuration parameters for Access Point
char * ssid_ap = "ESP_AP";
char * password_ap = "123456789";
IPAddress ip(192,168,11,4); // arbitrary IP address (doesn't conflict w/ local network)
IPAddress gateway(192,168,11,1);
IPAddress subnet(255,255,255,0);
// Set up the server object

// Keep track of the sensor data that's going to be sent by the client
float t1=0.0;
float h1=0.0;
float s1=0.0;

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

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(ip,gateway,subnet);
  WiFi.softAP(ssid_ap,password_ap);

  // Configure the server's routes
  server.on("/",handleIndex); // use the top root path to report the last sensor value
  server.on("/update",handleUpdate); // use this route to update the sensor value
  server.begin();
}
void handleIndex() {
    server.send(200,"text/plain",String(t1));
    server.send(200,"text/plain",String(h1));
    server.send(200,"text/plain",String(s1));// we'll need to refresh the page for getting the latest value
}

void handleUpdate() {

  // The value will be passed as a URL argument
 t1 = server.arg("value").toFloat();
  h1 = server.arg("value").toFloat();
  s1 = server.arg("value").toFloat();

  delay(100);
  WiFi.begin(ssid, password);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("");
  Serial.print("NodeMcu connected to wifi...");
  Serial.println(ssid);
  Serial.println();
  Serial.println(WiFi.localIP() );

  delay(1000);
  ///~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~///
 float t2 = t1;
 float h2 = h1;
 float s2 = s1;
  if (client.connect(httpserver,80))
  {
         String tsData = apiWritekey;
           tsData+="&field1=";
           tsData+=String(t2);
           tsData+="&field2=";
           tsData+=String(h2);
           tsData +="&field3=";
           tsData += String(s2);
           tsData += "\r\n\r\n";

     client.print("POST /update HTTP/1.1\n");//command to update
     client.print("Host: api.thingspeak.com\n");//host name here thingspeak.com
     client.print("Connection: close\n");//closing connection
     client.print("X-THINGSPEAKAPIKEY: "+apiWritekey+"\n");
     client.print("Content-Type: application/x-www-form-urlencoded\n");
     client.print("Content-Length: ");
     client.print(tsData.length());
     client.print("\n\n");  // the 2 carriage returns indicate closing of Header fields & starting of data
     client.print(tsData);

     Serial.print("Temp: ");
     Serial.print(t2);//printing on serial monitor
     Serial.print("Humi: ");
     Serial.print(h2);
     Serial.print("Soil: ");
     Serial.print(s2);
     Serial.println("uploaded to Thingspeak server....");//dialogue box
  //}
  digitalWrite(D4, LOW);

  client.stop();//stopping client

  Serial.println("Waiting to upload next reading...");
  Serial.println();
  delay(5000);

} }

void loop() {
server.handleClient();

}
```
and the output of it is
[![Server side output][1]][1]

while the code of my client is
```
#include <DHT.h>
#include <ESP8266WiFi.h>

// Initialize sensor parameters
// Initialize network parameters
const char* ssid = "ESP_AP";
const char* password = "123456789";
const char* host = "192.168.11.4"; // as specified in server.ino

#define DHTPIN 0          //pin where the dht11 is connected

DHT dht(DHTPIN, DHT11);

// Set up the client objet
WiFiClient client;

// Configure deep sleep in between measurements
const int sleepTimeSeconds = 2;

void setup() {

  // Connect to the server
  WiFi.begin(ssid,password);
  Serial.begin(115200);
  dht.begin();
  while(WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("IP Address (AP): "); Serial.println(WiFi.localIP());

void loop() {
  // put your main code here, to run repeatedly:
   while (WiFi.status() == WL_CONNECTED) {
    delay(500);
    int s = analogRead(A0);
    float h = dht.readHumidity();
    float t = dht.readTemperature();
  Serial.print("Temperature: "); Serial.println(t);
  Serial.print("Humidity: "); Serial.println(h);
  Serial.print("Soil Moisture: "); Serial.println(s);
  // Connect to the server and send the data as a URL parameter
  if(client.connect(host,80)) {
    String url = "/update?value=";
    url += String(t);
    String url1 = "/update?value=";
    url1 += String(h);
    String url2 = "/update?value=";
    url2 += String(s);
    client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host +  "\r\n" +
                 "Connection: keep-alive\r\n\r\n"); // minimum set of required URL headers
     client.print(String("GET ") + url1 + " HTTP/1.1\r\n" + "Host: " + host +  "\r\n" +
                 "Connection: keep-alive\r\n\r\n"); // minimum set of required URL headers
     client.print(String("GET ") + url2 + " HTTP/1.1\r\n" + "Host: " + host +  "\r\n" +
                 "Connection: keep-alive\r\n\r\n"); // minimum set of required URL headers
    delay(5000);

  }
    // Read all the lines of the response and print them to Serial
    Serial.println("Response: ");
    while(client.available()){
      String line = client.readStringUntil('\r');
      Serial.print(line);
  }
}
}
```
and its output is
[![Client side output][2]][2]

Kindly help me to get all values at server side, Thanks

  [1]: https://i.stack.imgur.com/l7mV5.png
  [2]: https://i.stack.imgur.com/KdAr8.png

body:
You use the same name `value` for all `/update?` parameters. And the format of url parameters is `?name1=value1&name2=value2`

Use

    String url = "/update?t=";
    url += String(t);
    String url1 = "&h=";
    url1 += String(h);
    String url2 = "&s=";
    url2 += String(s);

send it as one GET request

and read `server.arg("t")`,  `server.arg("h")` and  `server.arg("s")`.

Note 1: Sending more responses with `serverSend` to one request from browser has no effect. Only the first will work.

Note 2: this kind of use of String class will fragment the memory and cause a crash

Note 3: You don't need to use HTTP to communicate between your devices over TCP network. You can use [simple TCP socket connections][1] without HTTP protocol overhead.

  [1]: https://arduino.stackexchange.com/questions/60819/esp8266-tcp-ip-communication/60821#60821


message:
Playing Audio from SD - Get VU, or audio waveform

I am using the library [SimpleSDAudio][1] to play a song from my SD card to an op-amp later in the circuit. I would like to take a sample from the audio pin (possibly with a Analog read) to power some visualizations (VU, etc.), although I am getting some unexpected readings off the audio pin.

I tried to bias the audio [using this post][2], but got the same results.

I'm not sure if I am headed in the wrong direction here, any help would be amazing.

    #include <SimpleSDAudio.h>
    int ReadPin = A0;
    int AudioValue = 0;

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

      Serial.print(F("\nInitializing SD card..."));

      if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER)) {
        Serial.println(SdPlay.getLastError());
        while(1);
        } else {
        Serial.println(F("Wiring is correct and a card is present."));
      }

      Serial.print(F("Looking for THRILLER.WAV... "));
      if(!SdPlay.setFile("THRILLER.WAV")) {
          Serial.println(F(" not found on card! Error code: "));
          Serial.println(SdPlay.getLastError());
          while(1);
      } else {
         Serial.println(F("found."));
      }

      Serial.print(F("Playing... "));
      SdPlay.play();

    }

      void loop() {
        AudioValue = analogRead(ReadPin);
        Serial.println(AudioValue);
        delay(50);

    }

[![Output of analogRead ][3]][3]

My expected output of sampling the output from A0:
[![enter image description here][4]][4]

  [1]: https://github.com/isramos/mico-shield/tree/master/libraries/SimpleSDAudio
  [2]: https://forum.arduino.cc/index.php?topic=508537.0
  [3]: https://i.stack.imgur.com/jDmxI.png
  [4]: https://i.stack.imgur.com/TOWIU.png

body:
You are sampling your audio signal with only 20Hz. That is very low frequency for an audio signal, that humans can hear. Generally you need to sample your signal with double of the highest containing frequency at minimum, or you will only get nonsense (you can google Nyquist Rate for more information). Also a Nano does not have a real DAC, so the audio is generated via a PWM signal, which turn the line on and off very fast, so you only see the waveform only, if you apply a low pass filter (like a speaker will do, because it cannot move that fast).

But directly sampling the audio signal is overly complex, only for making a VU meter visualization. These visualizations are way slower, than the actual audio signal. So you need to take the mean value over a specific time interval. Best you can reach this by building a low pass filter using a resistor and a capacitor. You can sample the output of that filter, which will only have lower frequencies. The sampling frequency then should be double of the cut of frequency of the filter at minimum.

Of course it is also possible to do all this in software, but for this you would have to change the library and I guess you don't want to do this.


message:
Impossible to connect ESP32 with Mosquitto on Raspberry using certificates

I installed [Mosquitto broker](https://mosquitto.org/) in Raspberry in my local network.
I generated certificates in Raspberry as follows:

    sudo openssl genrsa -out ca.key 2048
    sudo openssl req -new -x509 -days 3600 -key ca.key -out ca.crt
    sudo openssl genrsa -out server.key 2048
    sudo openssl req -new -out server.csr -key server.key
    sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3600

I modified the Mosqutto configuration file (.conf) as follows:

    allow_anonymous false
    cafile /etc/mosquitto/certs/ca.crt
    certfile /etc/mosquitto/certs/server.crt
    keyfile /etc/mosquitto/certs/server.key
    tls_version tlsv1.2

I restarted Mosquitto everything ok

I downloaded the ca.crt file from Raspberry to my PC with Filezilla
from my PC I use MQTT.fx to connect I set the certificate.
**WORKS WELL**

The problem:
with ESP32 I can't connect when I set the certificate with `espClient.setCACert(ca_cert);`
MQTT connecting ...
> [E] [ssl_client.cpp: 33] handle_error (): X509 - Certificate
> verification failed, e.g. CRL, CA or signature check failed

Someone can help me, I can't understand if something is missing in the code or there is some error in generating the certificates

Please help
many thanks Michael

this is my code:

    #include <WiFi.h>
    #include <WiFiClientSecure.h>
    #include <PubSubClient.h>
    #include <ESPmDNS.h>

    /* change it with your ssid-password */
    const char* ssid = "XXXXXX";
    const char* password = "XXXXXXX";
    /* this is the MDNS name of PC where you installed MQTT Server */
    const char* serverHostname = "home";

    const char* ca_cert = \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIDmDCCAoCgAwIBAgIJAKV4GE+4y/G4MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV\n" \
    "BAYTAlRWMRAwDgYDVQQIDAdUcmV2aXNvMRUwEwYDVQQHDAxDYXN0ZWxmcmFuY28x\n" \
    "DDAKBgNVBAoMA1BTUzEMMAoGA1UECwwDUFNTMQ0wCwYDVQQDDARob21lMB4XDTE5\n" \
    "MDkwODE3NDIzOFoXDTI5MDcxNzE3NDIzOFowYTELMAkGA1UEBhMCVFYxEDAOBgNV\n" \
    "BAgMB1RyZXZpc28xFTATBgNVBAcMDENhc3RlbGZyYW5jbzEMMAoGA1UECgwDUFNT\n" \
    "MQwwCgYDVQQLDANQU1MxDTALBgNVBAMMBGhvbWUwggEiMA0GCSqGSIb3DQEBAQUA\n" \
    "A4IBDwAwggEKAoIBAQC2rPN7VQXtzLCl1LufJkzLK9xedrbW72K2vBZ34VNOl+tG\n" \
    "ffNx2QQLQC0Jh5GzB79dZweqAjCRBbIEpx0IGvHWrHDUQMJrvg4BcmDr0eqNCup/\n" \
    "tBItlEcCdvmWFfm3IBezOVBDFiQWmC4jvAC/G3DPlftHiPI1k3cDewKNJEJykxeD\n" \
    "8H/4KTAz+wJXyGZiviZYv8OYOTRMa3nEhg1vaQTMgCwEVBavg5fsEQkZLArBNJQM\n" \
    "Gmw0qDdJEMDGOGWPogxRAKrxvNnXr4mIebzPj9/UTrJnfzVOPEHZ9Uz5BU/psGCL\n" \
    "cnMkBeNEa/JyLR14Hu8e+xa/pOCpJ9Dqhi/BTji5AgMBAAGjUzBRMB0GA1UdDgQW\n" \
    "BBRIz+15SpOBqo0O+vOtgYvPj4LqWDAfBgNVHSMEGDAWgBRIz+15SpOBqo0O+vOt\n" \
    "gYvPj4LqWDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC08Crs\n" \
    "w7LPX+Bd80NwPuxgBmMU4U/pCw8AyzzSgckHmay0K8KuHXhSvZjdl6i0gjG/2xLa\n" \
    "ghCtfFGIXPu1Lu226bhTWigmuFLYasG1MivTDz2LeUTFPQrtEO8KdsRUarPZW3Fj\n" \
    "nOMyVDdzE4+HxvzvARDc1QbE9SX2ozQcNKQp4oRpunfT2+/OyzYgfMVA7MVKvehX\n" \
    "VH49fRF1P1Ajizqr2eHDFImcMQTzepRT7IjfOiQ/8PoqrZGvGenMj5so1I9MtgyK\n" \
    "gVUf1ZWPBgxmhVfla6vYBZiTGuZMHSDuF6/yFC1QnoXVq7K+bbIhAE8lsPNuOY7V\n" \
    "dKidKIfBJiN378CC\n" \
    "-----END CERTIFICATE-----\n";

    /* create an instance of WiFiClientSecure */
    WiFiClientSecure espClient;
    PubSubClient client(espClient);

    /*LED GPIO pin*/
    const char led = 5;

    /* topics */
    #define COUNTER_TOPIC    "smarthome/room1/counter"
    #define LED_TOPIC     "smarthome/room1/led" /* 1=on, 0=off */

    long lastMsg = 0;
    char msg[20];
    int counter = 0;

    void receivedCallback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message received: ");
      Serial.println(topic);

      Serial.print("payload: ");
      for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
      }
      Serial.println();
      /* we got '1' -> on */
      if ((char)payload[0] == '1') {
        digitalWrite(led, HIGH);
      } else {
        /* we got '0' -> on */
        digitalWrite(led, LOW);
      }

    }

    void mqttconnect() {
      /* Loop until reconnected */
      while (!client.connected()) {
        Serial.print("MQTT connecting ...");
        /* client ID */
        String clientId = "ESP32Client";
        /* connect now */
        if (client.connect(clientId.c_str(),"XXXXX","XXXXXX")) {
          Serial.println("connected");
          /* subscribe topic */
          client.subscribe(LED_TOPIC);
        } else {
          Serial.print("failed, status code =");
          Serial.print(client.state());
          Serial.println("try again in 5 seconds");
          /* Wait 5 seconds before retrying */
          delay(5000);
        }
      }
    }

    void setup() {
      Serial.begin(9600);
      // We start by connecting to a WiFi network
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      /* set led as output to control led on-off */
      pinMode(led, OUTPUT);

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
      /*setup MDNS for ESP32 */
      if (!MDNS.begin("esp32")) {
          Serial.println("Error setting up MDNS responder!");
          while(1) {
              delay(1000);
          }
      }
      /* get the IP address of server by MDNS name */
      Serial.println("mDNS responder started");
      IPAddress serverIp = MDNS.queryHost(serverHostname);
      Serial.print("IP address of server: ");
      Serial.println(serverIp.toString());
      /* set SSL/TLS certificate */
      espClient.setCACert(ca_cert);
      /* configure the MQTT server with IPaddress and port */
      client.setServer(serverIp, 26391);
      /* this receivedCallback function will be invoked
      when client received subscribed topic */
      client.setCallback(receivedCallback);

    }
    void loop() {
      /* if client was disconnected then try to reconnect again */
      if (!client.connected()) {
        mqttconnect();
      }
      /* this function will listen for incomming
      subscribed topic-process-invoke receivedCallback */
      client.loop();
      /* we increase counter every 3 secs
      we count until 3 secs reached to avoid blocking program if using delay()*/
      long now = millis();
      if (now - lastMsg > 3000) {
        lastMsg = now;
        if (counter < 100) {
          counter++;
          snprintf (msg, 20, "%d", counter);
          /* publish the message */
          client.publish(COUNTER_TOPIC, msg);
        }else {
          counter = 0;
        }
      }
    }

body:
@sempaiscuba and Bruno I solved by regenerating the certificates in this way
you have to do this comfortably script in Raspiberry

    #!/bin/bash

    IP="192.168.0.11"
    SUBJECT_CA="/C=SE/ST=Italy/L=Roma/O=himinds/OU=CA/CN=$IP"
    SUBJECT_SERVER="/C=SE/ST=Italy/L=Roma/O=himinds/OU=Server/CN=$IP"
    SUBJECT_CLIENT="/C=SE/ST=Italy/L=Roma/O=himinds/OU=Client/CN=$IP"

    function generate_CA () {
       echo "$SUBJECT_CA"
       openssl req -x509 -nodes -sha256 -newkey rsa:2048 -subj "$SUBJECT_CA"  -days 365 -keyout ca.key -out ca.crt
    }

    function generate_server () {
       echo "$SUBJECT_SERVER"
       openssl req -nodes -sha256 -new -subj "$SUBJECT_SERVER" -keyout server.key -out server.csr
       openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
    }

    function generate_client () {
       echo "$SUBJECT_CLIENT"
       openssl req -new -nodes -sha256 -subj "$SUBJECT_CLIENT" -out client.csr -keyout client.key
       openssl x509 -req -sha256 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
    }

    function copy_keys_to_broker () {
       sudo cp ca.crt /etc/mosquitto/certs/
       sudo cp server.crt /etc/mosquitto/certs/
       sudo cp server.key /etc/mosquitto/certs/
    }

    generate_CA
    generate_server
    generate_client
    copy_keys_to_broker

as you see OU changes for each file.
Remember to restart Mosquitto

    sudo systemctl stop mosquitto.service
    sudo systemctl start mosquitto.service

let me know how it goes
bye
Michele


message:
Arduino random LED on

I have a project which has two options
No. 1 Randomly turn on one LED from a group of 6 LED (Relay Board)
No.2 randomly turn on one LED from a group of 2 LED (Relay Board)
The selection of the desired option happens with a switch.

I found this code online which is just perfect for 6 LED but I don't know how to add the selection of the options in it, how to do it?

 int timeShowRandom = 3000;
 int timeShowDecision = 6000;
 int timeBlink = 100;
 int buttonPin = 2;
 int buttonPress = false;
 int randomNumber;
 int previousNo = 0;
 int timePassed = 0;

 void setup() {
   // Set button pin
   pinMode(buttonPin, INPUT);
   // Set output pins
   pinMode(12, OUTPUT);
   pinMode(11, OUTPUT);
   pinMode(10, OUTPUT);
   pinMode(9, OUTPUT);
   pinMode(8, OUTPUT);
   pinMode(7, OUTPUT);
 }

 void getRandomNo() {
  int rand = random(7,13);
   if (rand == previousNo) {
    getRandomNo();
   } else {
  randomNumber = rand;
  previousNo = randomNumber;
   }
 }

 void loop() {
  if (digitalRead(buttonPin) == HIGH && buttonPress == false ) {
   buttonPress = true;
   } if (buttonPress == true && timePassed <= timeShowRandom) {
  getRandomNo(); // Get random pin number
  digitalWrite(randomNumber, LOW);
  delay(timeBlink);
  digitalWrite(randomNumber, HIGH);
  delay(timeBlink);
    timePassed = timePassed + (timeBlink * 2);
   } else if(buttonPress == true) {
  digitalWrite(random(7,13), LOW); // Set random pin on
  delay(timeShowDecision); // For x seconds
  buttonPress = false; // Set button to be enabled again
  timePassed = 0;
   }
   else {
  // Reset all output pins
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(7, HIGH);
   }
 }

body:
Various suggestions:

Create 2 different arrays of pin numbers: 1 for the first group of relay pins, and the 2nd for the second group of relay pins:

    byte firstRelayPins[] = [7, 8, 9, 10, 11, 12];
    byte secondRelayPins[] = [13, 14]; //Replace values with your relay pins

Write a function that returns a random index from one or the other of the arrays based on a bool:

    byte randomPin(bool useSecondArray) {
        int max;
        int index;
        if useSecondArray {
           return secondRelayPins[random(sizeof(secondRelayPins))]; //Fetch random pin from array
        } else {
           return firstRelayPins[random(sizeof(firstRelayPins))]; //Fetch random pin from array
        }
    }

Based on the state of your switch, set useSecondArray when you call that function to determine which relay's pin you turn on.

Use the returned value to set the desired relay pin.

In your "turn everything off" code, use the arrays of index pins rather than hard-coded indexes.

You should also refactor your code to use `millis()` rather than using `delay()`. (Search on "Arduino blink without delay" for guidance on how to do that.)

Note that this is a rough outline of what to do. The code above will likely need to be adjusted to fit your needs. Don't expect to be able to copy/paste it into your project.