body:
You can do this, for quite simple sketches. It starts to become ugly if you add more features and conditions.

Therefore, the "correctTM" (read: _professional_) way is to implement a state machine. See in the IDE the non-delay blink example.

```c++
const unsigned long DELAY_MS = 1000;

int pin = 13;

enum State {
    WAITING, WORKING,
};

State state;

unsigned long startTime;

void setup()
{
    pinMode(pin, INPUT);
    state = WAITING;
    startTime = millis();
}

void loop()
{
    switch (state) {
    case WAITING:
        // You can put both conditions in one "if" with an "||" operator.
        // But it will look less clear.
        if (millis() - startTime > DELAY_MS) {
            state = WORKING;
        } else if (digitalRead(pin)) {
            state = WORKING;
        }
        break;
    case WORKING:
        // anything to do after the delay or the button
        break;
    default:
        // any error handling you see fit
        break;
    }
}
```

The function `loop()` is designed to be called endlessly in repetition. Use this to your advantage.


sender: user

message:
Using 1 ms delay() in a for loop to check inputs.. Bad?

So first off, I know millis() exists. Just asking out of curiosity. Say you have a button you wanna check for during a delay.. Maybe a 10 second delay. So you make a for loop that checks for input and delays 1 ms... 10,000 times. What's bad about this?

     int pin = 13;
        bool button = false;

        void setup()
        {
          pinMode(pin, INPUT);
        }

        void loop()
        {

         while(button == false) {
         for(int i = 0; i<10000; i++) {
         if(digitalRead(pin,HIGH){
         button = true;
    }
         delay(1);

        }
      }
    }

sender: assistant

body:
> I know millis() exists

Ok, millis is always the best way...

> Say you have a button you wanna check for during a delay..
> So you make a for loop that checks for input and delays 1 ms... 10,000 times.

Your code is not really doing what you want. Your while loop never ends until button is pressed so 10s delay has no sense. I suppose your code should exit after 10 seconds or if button is pressed.

> Just asking out of curiosity

You're code, without millis(), should be

```
bool button = false;
...
...
void loop() {
  uint16_t ms2wait = 10000;
  while (button == false && --ms2wait > 0) {
    if(digitalRead(pin,HIGH)
      button = true;
    delay(1);
  }
}
```


message:
String to unsigned 16-bit integer

I'm currently working on a project with a 4DSystems Display. Im talking to the Display over SoftwareSerial with an ESP32. As soon as I want to use a Unicode character it requires me to convert my whole String to a uint16_t. Can somebody help me I have no idea how I should go on with this?
```
  #include <genieArduino.h>
  void loop() {
    uint16_t tn[] = { 0x2126,0 }; // Ω
    genie.WriteStrU(0, tn);
  }
```
This works but how could I inset a variable into the uint16_t?

body:
As mentioned by chrisl in a comment, your best option is to to use the
regular `WriteStr()` method to print variables, and use `WriteStrU()` to
print Unicode string constants. For example:

```c++
float R = 12.34;  // dummy resistance value.
genie.WriteStr(0, "R = ");
genie.WriteStr(0, R);
genie.WriteStrU(0, (uint16_t *) u" Ω");
```

should print:

```text
R = 12.34 Ω
```

Note the use of the `u` string prefix to write UTF-16-encoded strings in
the source code.

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

**Edit**: You wrote
> the `WriteStr` always replaces the text inside a String object instead
> of adding on.

This makes things more complicated. The only option I see is to format
the whole message as UTF-16 beforehand, then send it with `WriteStrU()`.
Here is a class that does simple UTF-16 formatting. It inherits from the
`Print` class, meaning you can `print()` to it anything you could print
to `Serial`. In addition, it can print UTF-16 strings:

```c++
template <size_t max_length>
class UTF16Writer : public Print {
public:
    // Convert ASCII to UTF-16.
    size_t write(uint8_t c) {
        if (length >= max_length)
            return 0;  // buffer full
        buffer[length++] = c;
        buffer[length] = 0;  // terminate string
        return 1;
    }
    // Record UTF-16 data.
    size_t print(const char16_t *s) {
        size_t chars_written = 0;
        while (*s && length < max_length) {
            buffer[length++] = *s++;
            chars_written++;
        }
        buffer[length] = 0;  // terminate string
        return chars_written;
    }
    using Print::print;
    uint16_t buffer[max_length + 1];
private:
    size_t length = 0;
};
```

The template parameter is the capacity of the buffer. Once you have
written the whole message as UTF-16 using this class, you can pass its
`buffer` member to `WriteStrU()`. For example:

```c++
float R = 12.34;  // dummy resistance value.
UTF16Writer<16> writer;
writer.print("R = ");
writer.print(R);
writer.print(u" Ω");
genie.WriteStrU(0, writer.buffer);
```

**Note**: Do not forget the `u` prefix in the Unicode string, otherwise
the bytes of the string (UTF-8 in the source) would be interpreted as
latin1 by `UTF16Writer::print(const char*)`. A message such as `"martine
écrit en UTF-8"` would then be displayed as “martine Ã©crit en UTF-8”.


message:
Simulating a button press using the Serial Monitor to run a Servo

I'm kind of new to Arduino and C, and I was having trouble with this sketch. I'm working on a project to control 6 servos using virtual buttons. When I hold down the button, the servo moves forward smoothly to a certain fixed point, and when I release it, it comes back to a fixed point. I initially tested this with a single servo and an actual button on my breadboard using the following sketch.

```
#include<Servo.h>
int switch1;
float switch1Smoothed;
float switch1Prev;
Servo myservo1;
float a=1200.0; //lower angle limit

void setup() {

  Serial.begin(115200);
  pinMode(A1,INPUT_PULLUP);
  myservo1.attach(9);
  myservo1.writeMicroseconds(a);
  switch1Prev=a;
}

void loop() {
//Motor 1
  switch1 = digitalRead(A1);// read switch | will return 1 or 0 continuously
  //Serial.println(switch1);
  switch1 = switch1 * 2400;        // multiply by angle limit

  // *** smoothing ***

  switch1Smoothed = (switch1 * 0.05) + (switch1Prev * 0.95);
  if(switch1Smoothed>=a){
  switch1Prev = switch1Smoothed;
  }
  else{
    switch1Prev = a;
  }
  // *** end of smoothing ***

//  Serial.print(switch1);                  // print to serial terminal/plotter
//  Serial.print(" , ");
//  Serial.println(switch1Smoothed);
    myservo1.writeMicroseconds(switch1Smoothed) ;
    delay(10);                               // repeat loop 100 times per second
}
```

This works out just fine. Now, I'm working with NodeRed, a low code JavaScript flow creator, which is where my virtual button is, and I've set it up to send 0s or 1s as strings based on whether the button is pressed or not via serial communication. This is the config of the Serial Node on NodeRed:

[![Serial Port Config on NodeRed][1]][1]

And I wrote a short function on Arduino to parse the incoming string from the serial connection, convert it back to an integer, and then use that as my "button" input. However, it seems that either my logic is flawed, or my code is because my servo does not behave the same way it does with the physical button.

Here's the modified sketch:

```
#include <Servo.h>
int switch1;
float switch1Smoothed;
float switch1Prev;
Servo myservo1;
float a=1200.0;
String readString, mot1, mot2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(9);
  myservo1.writeMicroseconds(a);
  switch1Prev=a;
}

void captureChar(int& n1){ //using reference to pass the value

  while (Serial.available()) {
    delay(3);  //delay to allow buffer to fill
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {

      mot1 = readString.substring(0,1);
      mot2 = readString.substring(1,2);
      n1 = mot1.toInt();
      //n2 = mot2.toInt();
    readString="";

  }
}

void loop(){
  captureChar(switch1);
  switch1 = switch1 * 2400;        // multiply by maximum angle limit

  // *** smoothing ***

  switch1Smoothed = (switch1 * 0.05) + (switch1Prev * 0.95);
  if(switch1Smoothed>=a){
  switch1Prev = switch1Smoothed;
  }
  else{
    switch1Prev = a;
  }
  // *** end of smoothing ***

//  Serial.print(switch1);                  // print to serial terminal/plotter
//  Serial.print(" , ");
//  Serial.println(switch1Smoothed);
  myservo1.writeMicroseconds(switch1Smoothed);
  delay(15);
}

```
When I load this sketch and hold down the virtual button, i.e., send a continuous stream of string "1", the motor simply goes back and forth really fast, rather than slowly moving to the set maximum position and stopping there while the button is held.

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

body:
There may be a problem with your smoothing logic, which is quite
convoluted. However, if the first code works fine, you can keep it
_almost_ as-is, and only replace `digitalRead()` with a version that
reads the virtual button. It looks like that is what `captureChar()`
attempts to achieve. This function, however, has a couple of problems:

- it has a loop and a delay, thus breaking the timing of the original
  code
- its interface is very different from the one of `digitalRead()`, and
  thus cannot be used as a drop-in replacement.

Here is what I would propose as a `digitalRead()` replacement. It has
the same signature as the original `digitalRead()`, and can be used as a
drop-in replacement:

```c++
int virtual_switch_reading = LOW;

int virtualDigitalRead(uint8_t /* pin number ignored */) {
    int c = Serial.read();
    if (c == '0')
        virtual_switch_reading = LOW;
    else if (c == '1')
        virtual_switch_reading = HIGH;
    return virtual_switch_reading;
}
```

Note that calling `Serial.available()` is not useful: if no data is
available, `Serial.read()` returns `-1`, which is neither equal to `'0'`
nor equal to `'1'`.

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

**Edit**: addressing the requirement to have six virtual switches.

As stated in a comment, I suggest you encode the states of all the
switches, within NodeRed, as a single byte, with one bit per switch. You
would then send this byte to the Arduino, either periodically or
whenever any switch changes state.

On the Arduino, in order to simulate `digitalRead()` on a virtual
switch, you first have to map the pin numbers to the virtual switches:

```c++
// Map a pin number to a virtual switch.
const uint8_t virtual_switch_masks[NUM_DIGITAL_PINS] = {
    0,     // pin 0: not virtual
    0,     // pin 1: not virtual
    1<<0,  // pin 2: virtual switch 0
    1<<1,  // pin 3: virtual switch 1
    // etc...
};
```

Note that this table doesn't store switch numbers. It instead stores
_bit masks_. For example, virtual switch 1 is stored as `1<<1` =
`0b00000010`, i.e. all bits are clear except for bit number 1 (rightmost
being zero), which is set.

You can then simulate `digitalRead()` by extracting the relevant bit
from the byte you last received from NodeRed, which is done by a
_bitwise and_ with the relevant mask:

```c++
// States of all virtual switches, one bit per switch.
uint8_t virtual_switch_states = 0;

int virtualDigitalRead(uint8_t pin) {
    uint8_t mask = virtual_switch_masks[pin];

    // If this is not a virtual switch, do a regular digitalRead().
    if (!mask)
        return digitalRead(pin);

    // For a virtual switch, extract the relevant bit
    // from virtual_switch_states.
    if (virtual_switch_states & mask)
        return HIGH;
    else
        return LOW;
}
```

In order to update the states of the virtual switches from the data
received, you just have to add this somewhere within `loop()`:

```c++
if (Serial.available())
    virtual_switch_states = Serial.read();
```


message:
Pan and tilt bracket move to sound, control servo motors using microphone sound sensors

I'm trying to code the pan and tilt bracket to turn based on where I speak, I know how to move the servo motors, but I really need help with the sound sensing. This is the code I've got currently:

    #include <Servo.h>
    Servo myservo;  // create servo object to control a servo
         Servo myservo2;           // a maximum of eight servo objects can be created
    int sound1;
    int sound2;
    int pos = 0;    // variable to store the servo position

    void setup()
    {
      Serial.begin(9600);
      myservo.attach(5);  // attaches the servo on pin 9 to the servo object
      myservo2.attach(6);
    }

    void loop()
    {
      sound1 = analogRead(A0);
      sound2 = digitalRead(7);

      if (sound1 > 50)
      for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
      {                                  // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
      }
      for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
      {
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
      }

       if (sound2 > 50)
       for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
      {                                  // in steps of 1 degree
        myservo2.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
      }
      for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
      {
        myservo2.write(pos);              // tell servo to go to position in variable 'pos'
        delay(15);                       // waits 15ms for the servo to reach the position
      }
    }

I've been working on this for some time, but for some reason, whenever I try to code the sound sensor, it always ends up being ignored, so for example, If my code says, if sound sensor number 1 detects sound, move 90 degrees vertically or horizontally, it always ignores that if statement and just continuously moves 90 degrees to wherever. I need it to follow my voice, or if that's too advanced, it's fine if it just follows any sound. So if I more 30 degree to the right on the pan and tilt bracket, and speak, I need it to turn and face me. Also, the kind of sound sensor I'm using is KY-037, the red variation with 4 pins. Any advice would be really helpful, thanks.

body:
What you are trying to achieve is not easy. Expect to spend a lot of time
developing, testing and tuning it.

The first step would be to work the acoustics of your device. The sound
sensors are not sensitive to the direction of the incoming sound, so you
will to have to use two of them facing different directions, like the
ears on your head face different sides. It would help to have the polar
plot of your microphones: if they are not directional enough, you may
have to build some kind of sound obstacle between them (the “head”
between the ears, or maybe even a pair of “auricles”) to improve the
angular selectivity. With cardioid microphones, you may get away with
just facing them 180° apart.

Getting this right can take significant effort. A two-channel
oscilloscope and a sinusoidal sound source would help a lot: watch the
signals coming out of both mikes, and see how their amplitudes change as
you turn the head. You want them to be sensitive enough to that
orientation. Then, adjust the potentiometers within the sound modules in
order to have the same amplitudes when the head is facing the sound
source.

Next you will have to sample these signals with your Arduino. The
default Arduino sampling rate (`analogRead()` in a tight loop) is about
8.93 kHz for a single channel, or 4.46 kHz per channel if
alternating between two channels. This may be enough for getting a rough
estimate of the intensity of voice, but it is kind of borderline too
low. You may want to increase the sampling rate: the way to do so has
been discussed here, and is only a search away.

With `analogRead()`, the sampling rate is also inconsistent and
dependent on what the sketch is doing: the more the CPU works, the
slower the sampling rate. I would strongly recommend letting the ADC
work in free running mode, and retrieve the samples from an interrupt
service routine. For this, you will have to first read and understand
[the chapter on the ADC][ADC] from the datasheet of the microcontroller.

Next, you have to estimate the intensities from the samples you read. In
principle, this means low-pass filtering the square of the AC part of
the signal. If that is too much work, you may get away with a simple
peak-detection.

You may want to take a look at this [sound-meter sketch][meter] for
inspiration. It uses the free-running ADC technique and estimates a
sound amplitude using the proper “low-pass filtering the square of the
AC part of the signal”. It is single channel though, and you will have
to adapt it for tracking two channels. This would involve changing the
multiplexer setting within the ISR.

Lastly, you will have to make the pan servo respond to the difference in
intensities between the two ears. That is the easy part, it could
roughly go like this:

```c++
void loop() {
    float intensity_right = get_sound_intensity(RIGHT_MIKE);
    float intensity_left = get_sound_intensity(LEFT_MIKE);

    // Only move the head if we actually hear sound.
    if (intensity_right >= intensity_threshold
            || intensity_left >= intensity_threshold) {

        float difference = intensity_right - intensity_left;

        // Only move the head if the intensity difference is
        // significant.
        if (fabs(difference) >= difference_threshold) {
            if (difference > 0 && servo_position < 180) {
                servo_position += 1;
                servo.move(servo_position);
            } else if (difference < 0 && servo_position > 0) {
                servo_position -= 1;
                servo.move(servo_position);
            }
        }
    }
}
```

[ADC]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf#G3.1738641
[meter]: https://gist.github.com/edgar-bonet/e693799f58a545ca89a2


message:
MAX30100 and ESP8266 NodeMCU Serial Errors

This is my final year project and for some reason, the max30100 sensor defaults to static values once the HTTP post request has been performed.

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <SimpleTimer.h>

#define REPORTING_PERIOD_MS 1000

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

PulseOximeter pox;
uint32_t tsLastReport = 0;

SimpleTimer timer;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());

  if(!pox.begin())
  {
    Serial.println("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Pox Success");
  }
  pox.setOnBeatDetectedCallback(onBeatDetected);
  //pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  timer.setInterval(1000L , getsendata);
}

void loop() {
  // put your main code here, to run repeatedly:
  pox.update();
  if(millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    BPM = pox.getHeartRate();
    SpO2 = pox.getSpO2();
    Serial.print("Bpm: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.println(SpO2);
    tsLastReport = millis();
  }
  timer.run();
}

void onBeatDetected()
{
  Serial.println("Beat Detected");
}

void getsendata()
{
  while (Serial.available())
  {
    sensor_data = Serial.readString();
    Sr = true;

    int firstcommaindex = sensor_data.indexOf(",");
    int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
    int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
    int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

    systolic_pressure = sensor_data.substring(0, firstcommaindex);
    diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
    pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
    temperature_body = sensor_data.substring(thirdcommaindex + 1);

    HTTPClient http;
    http.begin(serverName);
    http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
    String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
    Serial.print("HTTP Request Data: ");
    Serial.println(httpRequestData);
    int httpResponseCode = http.POST(httpRequestData);

    if(httpResponseCode > 0)
    {
      Serial.print("HTTP Response Code: ");
      Serial.println(httpResponseCode);
    }
    else
    {
      Serial.print("Error Code: ");
      Serial.println(httpResponseCode);
    }
    http.end();

  }
}

```

The arduino mega is sending a string with the variable values set to 0 at startup. The MAX30100 sensor is doing its job of taking the readings however, as soon as the HTTP Post Request is done, the oximeter then defaults to it's static values and refuses to detect further readings.

Output:
This is output before HTTP Post
[![Output before HTTP Post][1]][1]

Output after HTTP Post
[![After post][2]][2]

  [1]: https://i.stack.imgur.com/MPy1L.png
  [2]: https://i.stack.imgur.com/kmTZZ.png

Once the http post request on arduino startup is done, or if i am taking readings from arduino after startup, the max30100 oximeter stops working and refuses to take further readings or update the values further.

The data is sent to mysql db where i will bbe fetching it on the website using php js and html css. This issue of the oximeter has been bothering me since so many days now and my final year project is nearing. Could anyone please guide me as to how to solve this problem?

Here is the library im using for the MAX30100: https://github.com/oxullo/Arduino-MAX30100

body:
Well. Finally. Figured it out. After countless hours of googling and reading the issues on the github library, i just had to insert one line. resetFifo to reset the module after http post and re enable it to take readings normally.
Updated code:

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100.h"
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

MAX30100 maxim;
PulseOximeter pox;

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

uint32_t tsLastReport = 0;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

HTTPClient http;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());
  if(!pox.begin())
  {
    Serial.print("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Success");
  }
  pox.setIRLedCurrent(MAX30100_LED_CURR_50MA);
  http.begin(serverName);
}

void loop() {
  // put your main code here, to run repeatedly:
    pox.update();
    if(millis() - tsLastReport > REPORTING_PERIOD_MS)
    {
      BPM = pox.getHeartRate();
      SpO2 = pox.getSpO2();
      Serial.print("Bpm: ");
      Serial.println(BPM);
      Serial.print("SpO2: ");
      Serial.println(SpO2);
      tsLastReport = millis();
    }
    while (Serial.available())
    {
      sensor_data = Serial.readString();
      Sr = true;

      int firstcommaindex = sensor_data.indexOf(",");
      int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
      int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
      int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

      systolic_pressure = sensor_data.substring(0, firstcommaindex);
      diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
      pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
      temperature_body = sensor_data.substring(thirdcommaindex + 1);

      String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
      Serial.println(httpRequestData);
      http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
      Serial.print("HTTP Request Data: ");
      Serial.println(httpRequestData);
      http.POST(httpRequestData);

      maxim.resetFifo();
    }
}
```

This code works flawlessly and i can now serial read from arduino, read from the oximeter and http post it to the database normally and again repeat these steps without any errors.


message:
Issue understanding timestamp generated using millis() function

I have this code uploaded to an Arduino Uno which is connected to a gyroscope and storing the data on an SD card. The code is from the OEM.

The delay() function was set to 500 by default but this was changed to 10 in order to get an output frequency of 100Hz.

The millis() function was added to observe whether the 100Hz frequency was being maintained.

```
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
File myFile;

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
int Addr = 105; // I2C address of gyro
int x, y, z;

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

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

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

 writeI2C(CTRL_REG1, 0x1F); // Turn on all axes, disable power down
 writeI2C(CTRL_REG3, 0x08); // Enable control ready signal
 writeI2C(CTRL_REG4, 0x80); // Set scale (500 deg/sec)
 delay(100); // Wait to synchronize
}
void loop(){
 myFile = SD.open("test.txt", FILE_WRITE);

 getGyroValues(); // Get new values
 // In following Dividing by 114 reduces noise
 Serial.print(millis());
 Serial.print(" Raw X:"); Serial.print(x / 114);
 Serial.print(" Raw Y:"); Serial.print(y / 114);
 Serial.print(" Raw Z:"); Serial.println(z / 114);

 myFile.print(millis());
 myFile.print(" Raw X:"); myFile.print(x / 114);
 myFile.print(" Raw Y:"); myFile.print(y / 114);
 myFile.print(" Raw Z:"); myFile.println(z / 114);

myFile.close();

 delay(10); // Short delay between reads
}
void getGyroValues () {
 byte MSB, LSB;
 MSB = readI2C(0x29);
 LSB = readI2C(0x28);
 x = ((MSB << 8) | LSB);
 MSB = readI2C(0x2B);
 LSB = readI2C(0x2A);
 y = ((MSB << 8) | LSB);
 MSB = readI2C(0x2D);
 LSB = readI2C(0x2C);
 z = ((MSB << 8) | LSB);
}
int readI2C (byte regAddr) {
 Wire.beginTransmission(Addr);
 Wire.write(regAddr); // Register address to read
 Wire.endTransmission(); // Terminate request
 Wire.requestFrom(Addr, 1); // Read a byte
 while(!Wire.available()) { }; // Wait for receipt
 return(Wire.read()); // Get result
}
void writeI2C (byte regAddr, byte val) {
 Wire.beginTransmission(Addr);
 Wire.write(regAddr);
 Wire.write(val);
 Wire.endTransmission();
}
```

However, these are the first few values that were saved onto the "test.txt" file:
[![Raw gyroscope values][1]][1]

This shows a change in time of approximately 0.03s between values and therefore a frequency of 33.3Hz. Does anyone know why this is the case?

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

body:
Your loop() function takes many milliseconds to execute because reading gyroscope, opening file on SD, and writing on serial are *slow* and blocking operations. On top of this, you add delay(10), so your final frequency will always be lower than 100Hz.

You should use the *while-millis* pattern, a standard and simple solution to overcome this issue. [Here](https://www.programmingelectronics.com/arduino-sketch-with-millis-instead-of-delay/) a complete explanation about it.


body:
The delay just adds time to the overall runtime of the `loop()` function. So you would have a frequency of 100Hz only if all the other code would take zero time. And what you are doing there does take a significant amount of time (communicating over I2C and SPI, writing to the SD card). Thus your overall runtime of one `loop()` iteration is considerably longer. From your data we can even say how much longer it took. You measured a 30ms interval between the samples. 10ms of that is the delay. So the rest of the code took 20ms to execute. That also means, that with your current code you can get only up to 50Hz (by removing the `delay()`).

First to explain how to go with a timing situation like this lets assume the targeted frequency is possible with your code:

You have 2 options to go with timing:

- Make the `delay()` smaller. With trail and error find a value that results in a 100Hz sampling frequency.
- Use `millis()` directly for the timing. That way it is not important how long your code took to execute (as long as it was shorter than your sampling interval). For this you can basically copying the code from the `BlinkWithoutDelay` example, which uses `millis()` to blink an LED. You can use it to instead collect data samples and write them to the SD card.

The second option is superior and also a very important concept to understand in programming for Arduinos (or any microcontroller).

---

Now lets have a look at the problem with 100Hz. As explained above your current code takes too long to execute, so that you cannot reach a sample rate of 100Hz. You should use `millis()` to also check, which part of the code does take the most time.

I suspect that its the file writing. One way to speed this up is to only open and close the file once, instead of in every `loop()` iteration (as Edgar Bonet mentioned in the comments). After that I don't think you can speed this up further. A technique, that is often used in such situation, is to first collect a defined number of samples at the wanted frequency - temporarily saving them in an array - and then stop the sampling for writing to the SD card. That can give you short bursts of faster sampling at the cost of needing to wait for writing after that. It depends on your application if that is OK for you.

For the I2C you might be able to speed it up a bit. If your gyroscope is supporting that you can set the I2C clock signal to a higher frequency, for example 400kHz instead of 100kHz, via `Wire.setClock()`. Note that only specific values are allowed with this function and if a value works depends on your microcontroller. I think the Uno supports up to 400kHz.

You need to test by yourself if you can get the execution time below 10ms per `loop()` iteration.


message:
FastLED fill_solid array

I'm having trouble in the fill_solid function with arrays. can you help give color to row3.

    int row3[]={1,2,3};
    uint8_t sizerow3 = sizeof(row3)/sizeof(row3[0]);

    void solid(){
      fill_solid(leds[row3[3]], sizerow3, CRGB :: Red);
      LEDS. show();
    }

[This][1] is my complete program.

Thank you

  [1]: https://pastebin.com/6erFAmRy

body:
`leds[row3[3]]` is not what you think it is. That is selecting one single LED depending on what is in element 4 (index 3) of the 3-element array `row3`. Since there is no index 3 in a 3 element array (only indexes 0, 1 and 2) the value it returns to use as an index to the `leds[]` array is unknown.

`fill_solid` is designed to fill a single uninterrupted string of LEDs starting at LED `n` and progressing for a number of LEDs after that. To set random LEDs all to the same colour you should simply loop through your list of target LEDs and set the colours individually. Something like:

```c++
for (int i = 0; i < sizerow3; i++) {
    leds[row3[i]] = CRGB::Red;
}
LEDS.show();
```


message:
Arduino to run and LED strip of up to 100m

I am working on a project to run an RGB strip around a large room and have the colour change driven by an Arduino Uno. I have encountered a number of issues and am looking for clarification.

The first strip I used was a 12V strip at 1A/m. This would work fine except the power requirement is slightly ridiculous and it seems I need to put my array of MOSFETs in at every power injection point.

This was when I decided to experiment with a 5V addressable strip to do it. Working with a 5V system gave me more ease as the power requirements are lower and the parts list is also minimal, but after some research, it seems that the signal line will degrade significantly on that many WS2812B's / line length.

I suppose I could but a transistor inline every n-number of 5m strips (similar to the power injectors), however I would like to ask for some opinions from the community around other issues I may encounter, and whether or not this is the right solution for the job.

The scope of the project is to hold a colour for a number of seconds then switch colour based on a predefined program. This program is defined on an external device that uses the Arduino's serial port to communicate the desired colour. The implementation itself is very simple.

The main issues I can see are the power requirements (I think I have this sorted for the 5V version but not the 12V version) and getting the signal to the final LED. On a 60 LED/m strip this could be in the order of around 6000 LED's and that seems like a lot.

What are your views/recommendations?

Cheers!

body:
**Signal degradation:** This is pretty much not a problem, as long as you just send the signal through the LED strip. Each WS2812B chip has circuitry to ensure, that the output signal is shaped correctly. As long as you don't have long runs of pure cable for the signal in between you will be good.

**Power requirements:** Using WS2812Bs lets you ditch your own MOSFET driving circuits, though the overall power will be in the same range. When you drive the LEDs at full intensity white (R, G and B full intensity) each LED will draw about 60mA. With 60 LEDs/m and 100m length you have 6000 LEDs, which equates to a max current of 360A. Thats a lot. You will probably need multiple power supplies. I think you can get 5V power supplies with like 70A from typical retailers. Of course there are also some which, provide more, but you will also want to reduce the max length of cable the current will flow (putting each power supply near the strip part, that it is powering).

Also you should inject power to the strip every 1 to 1.5m to stay safe. Above that you can see degradation after some time (I injected every 2.5m once and the LEDs still work, but you can see the degradation on the strip material and it gets hot when being on).

IMPORTANT: When you buy the typical brick power supplies, they often use a barrel connector. But with these currents you shouldn't use them. In one of my own projects I currently have to replace those with better connectors, because the barrel connectors started to melt from the heat and smoked. I know use small banana connectors, which are also used for drone motors. They can handle way more current without getting hot. Also your cable should be thick enough to handle the current without getting hot.

**Controller:**

As you already know you will get into the memory limit with the Uno. Your assessment of the needed memory for using the FastLED library (or the NeoPixel library) is correct. You will need 18kB only for the buffer (not including the rest of the programs variables).

Now you can either
- change to a microcontroller with enough RAM to handle that buffer
- or send the data out on demand instead of first filling it into a buffer.

The first option will definitely be easier with programming. The second option will require you to do some handwork. The libraries that I know of all use a buffer. Though I've once read [this article][1] about the timing on WS2812B LEDs. In the end the author also links to [his working code][2], which puts out the data directly without using a buffer. You might wanna have a look at it. Also you could look at the code of the FastLED or Neopixel library. They of course also have the code to send the data and you might be able to copy and adapt that code for your case.

  [1]: https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
  [2]: https://github.com/bigjosh/SimpleNeoPixelDemo/blob/master/SimpleNeopixelDemo/SimpleNeopixelDemo.ino


message:
Arduino Nano Atmega328P not sleeping with either <LowPower> or <avt/sleep.h>

I'm working on a battery powered Arduino Nano project. I really need it to save power for hours on end, so I turned to [Arduino LowPower Library][1] and [avr/sleep.h][2] to do the job.

However, whatever I do, it doesn't look like the board isn't going to sleep. I have a sample sketch that tries to put the board to sleep and then toggles a relay when it wakes up, but it always toggles the relay instantly after booting, so that means it hasn't gone to sleep.

I also measured the current going into the board, and it's drawing 14mA consistently. I would expect to see a much lower draw whilst it's asleep.

Here are the two pieces of code that I've tried, one with LowPower and the other one with avr/sleep.h

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

    void loop(){
        // This call doesn't seem to do anything
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        toggleRelay(); //This gets executed continuously, with no indication of sleep time
    }

Here's the other one with LowPower

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

        void loop(){
            // This call doesn't seem to do anything
            LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

            //This gets executed continuously, with no indication of sleep time.
            //I would expect it to see it toggle only every 8s
            toggleRelay();
        }

I'm probably doing something stupid, but I can't figure out what... Any help?
Thanks a lot!

  [1]: https://github.com/arduino-libraries/ArduinoLowPower
  [2]: https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html

body:
I don't know about the LowPower library. However, four your
avr-libc-based test, you forgot to actually put the device in sleep
mode with `sleep_mode()`:

```c++
void loop() {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // select a deep sleep mode
    sleep_mode();   // now go to sleep
    toggleRelay();  // executed at wake up
}
```

Beware that, if you haven't enabled a wakeup source that is active in
the mode you selected, the microcontroller may sleep until it is
power-cycled or receives an external reset.


message:
ESP32 Wifi not working when powered by battery

I'm quite new to ESP32 development. I've been using [this devkit](https://www.az-delivery.de/it/products/esp32-developmentboard) for a few small projects and everything was going smoothly until I decided to run it on battery. In particular, the ESP32 devkit I'm using, when connected to a battery, seems to have issues when trying to connect to the Wifi.

I'm using a 9V battery connected to a MB-V2 power supply to convert the output voltage to 3.3.V. The power supply board has the following specifics:

* Input voltage: 6.5-9v (DC) via 5.5mm x 2.1mm plug
* Output voltage: 3.3V/5v
* Maximum output current: 700 mA
* Independent control rail output: 0v, 3.3v, 5v to breadboard

As you can see in the picture, my multimeter measures an output voltage of about 3.3V

[![Voltage measurement][1]][1]

I built a sample project for debugging, here's the schematics:
[![Schematics][2]][2]
[![Pic of the setup][3]][3]

The battery is connected to the power supply which outputs 3.3V and powers the ESP32 through its **3.3V pin**. I don't have a schematic for this specific devkit I'm using so the devkit used in the schematics is the DOIT one, hence all of the pins are off. The code is quite simple, though, so it hopefully can clear things a bit:
```C++
#include <WiFi.h>

const int uS_TO_S_FACTOR = 1000000;
const int TIME_TO_SLEEP = 3;
const int RED_LED_PIN = 32;
const int BLUE_LED_PIN = 25;
const int YELLOW_LED_PIN = 26;
const char SSID[] = "SSID";
const char PASS[] = "PASS";

void startupSequence(){
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  // Sequence
  digitalWrite(RED_LED_PIN, HIGH);
  digitalWrite(BLUE_LED_PIN, HIGH);
  digitalWrite(YELLOW_LED_PIN, HIGH);
  delay(1000);
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  delay(500);
}

void setup(){
  Serial.begin(115200);
  while(!Serial){}
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  startupSequence();
  delay(500);
  digitalWrite(RED_LED_PIN, HIGH);
  delay(1000);
  Serial.print("Connecting to ");
  Serial.println(SSID);
  WiFi.begin(SSID, PASS);
  while ((WiFi.status() != WL_CONNECTED) && (millis()<10000)) {
      Serial.print(".");
      delay(500);
  }
  Serial.print("Connected. IP: ");
  Serial.println(WiFi.localIP());
  digitalWrite(RED_LED_PIN, LOW);
  if(WiFi.status() == WL_CONNECTED) //Run this only the first time
  {
    Serial.println("Connected");
    digitalWrite(YELLOW_LED_PIN, HIGH);
  } else
  {
    Serial.println("Not connected");
    digitalWrite(BLUE_LED_PIN, HIGH);
  }
  delay(3000);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  Serial.println("Going to sleep");
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

void loop(){}
```
In the code, the ESP32 first lights up all LEDs, then it lights up the red LED while it tries to connect to the Wifi. After at most 10 secs, it lights up the yellow LED if it successfully connected, otherwise it lights up the blue LED. Also, as a last thing I send the ESP32 into deep sleep, as my intention was to measure its power consumption during sleep.

When connected to the PC, everything runs smoothly, while when connected to the battery the ESP32 (apparently) never exits the while loop and the red LED stays always on. The RED led then starts flickering and the power LED start blinking. Resetting it throught the RST button on the devkit causes the power LED to start blinking and the red LED never lights up. This continues until I cut off the power, then the code seems to start again from the beginning (i.e. the startup sequence) and the this behavior repeats.

I've read a few posts about similar issues with ESP32 devkits, but the problem was always about batteries not having high enough voltage, which doesn't seem to be my case. What could be causing the issue?

  [1]: https://i.stack.imgur.com/sWtx8.jpg
  [2]: https://i.stack.imgur.com/elP6U.png
  [3]: https://i.stack.imgur.com/Zlwl2.jpg

body: I agree with chrisl, the battery does not have a low enough impedance to operate your project. What you are not taking into account is the transmitter current when it is transmitting to the wifi. I have been finding that when it wakes up it draws upwards of 500mA for a short time, measured with a scope and current probe. This appears during the " WiFi.scanNetworks()" function. Add on top of that all the LEDs and other electronics What do you think it will draw. The fact that it operates on the USB also helps confirm this. Try with 6 bigger batteries in series, I expect it to work properly. Check this link out from:Expressif, the manufacturer of the chip at https://esp32.com/viewtopic.php?t=2662


message:
How to pass non-static class member to callback on avr platforms?

I am using the PubSubClient library in my own Arduino library. I'm having trouble with trying to assign a class member as the client library setCallback callback function.

MyClass.cpp:

    #include <PubSubClient.h>
    #include <Wifi.h>
    #include "Arduino.h"
    #include "MyClass.h"

    WiFiClient wifiClient;
    PubSubClient mqttClient(wifiClient);

    void MyClass::connect(String host, int port) {
      mqttClient.begin(host, port, "/");
      mqttClient.setCallback(incomingEventHandler);
    }

    void MyClass::loop() {
      mqttClient.loop();
    }

    void MyClass::incomingEventHandler(char* type, byte *payload, unsigned int length) {
      // do stuff with incoming data
      // need to access other member functions and class variables
    }

MyClass.h:

    #ifndef MyClass_h
    #define MyClass_h

    #include <PubSubClient.h>
    #include <Wifi.h>
    #include "Arduino.h"

    class MyClass {
      public:
        void connect(String host, int port);
        void loop();
        void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
    };

    #endif

Error I see is:

    sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'PubSubClient::setCallback()'
    mqttClient.setCallback(incomingEventHandler);

If I move the incomingEventHandler function outside the class definition, it works as expected, however then I can't call other class members or access class properties in the same scope.

In arduino c++ how can I pass non-static class member properties as a callback? Is there a better way to approach this?

P.S. This code is only to show the intent. It might not be compile too.
There was a similar question like this at: https://arduino.stackexchange.com/questions/56026/how-to-pass-non-static-class-member-to-callback?newreg=428b933458674167be6de138c84d3617

but this is for esp-8266 and this is for avrmega4809 based board.

body:
You can't. On the AVR platform, `PubSubClient::setCallback()` expects a
raw function pointer as a callback, and that is what you have to
provide. A static method is equivalent to a raw function, a non-static
method is not, and neither are a functor or an `std::function`.

If you need more that one `MyClass` object, one solution might be to
modify the pubsubclient library in order for it to store a pointer to
your `MyClass` instance, and pass this pointer to your callback. If you
never have to instances of `MyClass` subscribe to the same topic, a
better solution might be to statically store a map from topics to
`MyClass` instances and, within the callback, use this map to find the
appropriate instance.


message:
Is there a good reference for Arduino Due memory architecture and usage?

It's been harder than I expected to find a reference source or usage guide.

There's a number of sources I've looked at along the road to this question:

 - The Due is listed [here][1] and [here][2] as having 512KB flash memory, 96KB SRAM and zero EEPROM.
 - The arduino foundation [tutorial][3] notes that Due memory architecture is different but doesn't expand further.
 - @Majenko's answer to [this][4] previous question notes, "*There is no PROGMEM required on ARM. There is no memory bus separation between Flash and RAM*"
 - The [SAM3x datasheet][5] block diagrams show a unified bus (i.e. [Von Neumann][6] architecture (not Harvard architecture like the AVR boards))

   [![SAM3X block diagram][7]][7]

 - [This][8] answer on the Arduino Forum suggests (regarding allocating constants to flash), "*[...] all you have to do is use "const" in the variable declaration. [...]  Everything that's "const" gets put into flash without consuming any RAM. PROGMEM, pgm_read_byte() and the other AVR names are defined only so code designed for AVR can compile. But they do absolutely nothing on [SAM3X MCUs]* "
 - The `F()` macro seems to still work.

So my question is searching for links to a reference or guide for memory usage on the Arduino Due. I hope a guide (or your answers) might explain the differences caused by the change to a Von Neumann architecture bus, what is stored where, highlighting which memory handling techniques developed for Harvard architecture AVR MCUs remain relevant on the Due.

If there is no guide I'm hoping this question and your answers may become a good reference point. Thanks for reading!

  [1]: https://store-usa.arduino.cc/products/arduino-due?selectedStore=us
  [2]: https://en.wikipedia.org/wiki/List_of_Arduino_boards_and_compatible_systems
  [3]: https://www.arduino.cc/en/Tutorial/Foundations/Memory
  [4]: https://arduino.stackexchange.com/a/46134/71575
  [5]: http://www.atmel.com/Images/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf
  [6]: https://en.wikipedia.org/wiki/Von_Neumann_architecture
  [7]: https://i.stack.imgur.com/wMa8c.png
  [8]: https://forum.arduino.cc/t/progmem/332587/5?u=rpatterson
  [9]: https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

body:
Yes, the Arduino Due uses a flat memory model with a single address space for Flash and RAM. Therefore all constant data sits in flash and does not need to be copied to RAM at startup, like the AVR-based arduinos do. The `progmem` stuff for the AVR-based CPUs is required because they need to use different instructions to read data from flash than from RAM. This is no longer the case on the Due (nor most other 32-bit MCUs, such as the ESP32), and a string address in an instruction works just the same whether its in RAM or in Flash (as long as it's not written to, of course).

The `F()` macro is available for convenience, so that you can more easily write code that works for all Arduino boards. On the Due, it is basically implemented as no-op.

When you're working on the memory model of the Due, I might point to [this question][1], showing that there's a bug in the memory management implementation of the Due, allowing unlimited memory allocation.

  [1]: https://arduino.stackexchange.com/questions/80535/memory-allocation-on-arduino-due-never-returns-null


body:
So (review feedback welcomed) in the **Arduino Due SAM3x memory architecture** compared to the AVR architecture:

**Non-volatile flash memory**

*contains:*

 - program instruction code (same as AVR)
 - bootloader (same as AVR)
 - all runtime C++ constants including incode string literals (different to AVR)

*is accessed by:*

 - C++ const data definition code and incode literals (different to AVR)
 - C++ instruction code (same as AVR)
 - `PROGMEM`, `PSTR()`, `F()`, pgmspace library `*_P` functions are *not* required and compile for platform compatibility only (different to AVR).

**Volatile SRAM memory**

*contains:*

 - variable dynamic storage, organised in a stack and heap structure (same as AVR)
 - *no* static/constant storage, which now stays in flash (different to AVR)

*is accessed by:*

 - C++ data definition code (same as AVR)

**Usage**

 - Heap fragmentation remains an issue to be managed. Preferencing local to global allocation, and avoiding dynamic heap allocation remains relevant to Arduino Due (e.g., Arduino strings)

 - Techniques to move constants to flash memory are not relevant for Due, but may be relevant for multi-board compatiblity.


message:
Can I flash hoodloader2 or HEX files on Arduino Simulators?

I want to make a HID Keyboard out of Arduino UNO, in UNO board the script runs perfectly fine, but the UNO board requires me to flash it every-time I want to put in a new script in it, so can I do the same on an Arduino Simulator? can I Flash Hoodloader2 on Arduino simulators by shorting the ICSP pins on UNO Board on a Simulator? if yes, please suggest the name of the application/ website.

body:
Only Arduino boards with ATmega16u2 as USB adapter can use Hoodloader. So not even all Uno clones can use it.

I doubt the simulator is so precise that it would simulate the second MCU on Uno to allow flashing it over its ICSP heeader (ICSP2). I guess it doesn't even support flashing the main MCU over ICSP.

If the simulator supports Arduino Lenonardo, then you can maybe use the HID library. Leonardo has ATmega32u4 which has native USB support.


message:
Can I improve EEPROM lifetime by not changing bits?

In my current project I need to store the current elapsed time in hours to retrieve it in case of power loss. Since I am using a Arduino Nano I would ideally like to use the built in EEPROM without additional hardware.

The written values and their order will always be:

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0 -> ....

If I write that on EEPROM per 0->0 full cycle the last bit will change 7 times and the other bits are pretty much idle. That's why I thought of distributing the changes more evenly by using instead the sequence

0 -> 1 -> 3 -> 7 -> 15 -> 31 -> 63 -> 0 -> ....

This would change every bit only once during a full 0->0 cycle. Does this improve EEPROM life expectancy or is the life expectancy linked to updating full bytes rather than individual bits?

edit: Since the question was closed for being off-topic, I altered the introduction a little bit. I am sorry if some of the comments are no longer fully valid. Since I don't fully understand why the question was closed (especially since there is EEPROM-tag), I would be grateful for a tip where on stackexchange the question would be best suited.

body: On your next design consider using FRAM, it is non volatile and supports almost unlimited (10 - 14th) read write cycles. The library I use or EEPROM supports the update function where it reads the memory first and does not write to it if it is to remain unchanged.


body:
It is possible to write to ATmega EEPROM address without clearing its previous value. The write mode is set with the EEPMx bits in the EECR register.

The avr-libc eeprom.h write functions only use the erase and write mode and the Arduino EEPROM library only uses avr-libc eeprom.h write function.

I modified the `EEPROM_write` example function from the datasheet to write without erase.

```
#include <EEPROM.h>

void setup() {

  Serial.begin(115200);

  int address = 0;

  EEPROM.write(address, 0b11111111);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111110);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111101);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11101111);
  Serial.println(EEPROM.read(address), BIN);

}

void loop() {

}

void EEPROM_write_no_erase(unsigned int uiAddress, unsigned char ucData) {
  /* Wait for completion of previous write */
  while (EECR & (1 << EEPE))
    ;
  /* Set up address and Data Registers */
  EEAR = uiAddress;
  EEDR = ucData;
  /* Write only */
  EECR |= (1 << EEPM1);
  EECR &= ~(1 << EEPM0);
  /* Write logical one to EEMPE */
  EECR |= (1 << EEMPE);
  /* Start eeprom write by setting EEPE */
  EECR |= (1 << EEPE);
}

```
the output is as expected:
```
11111111
11111110
11111100
11101100
```

I don't know if use of this feature improves the lifetime of the ATmega EEPROM.


message:
I2S pins don't output audio in ESP8266

I am trying to use the `ESP8266` to output some audio, but I'm having trouble making it work. I downloaded the library `ESP8266Audio` and am testing one of the examples they have in the repo, namely streaming MP3 from HTTP, ([link][1]). There is nothing however outputted from the I2S pins, D1 and D2, but only from RX pin. I have a dual amplifier, so I need the analog signals, not the digital. So I want to ask if there is something extra I need to add in the program, or if I'm using the wrong pins. Any help is appreciated :)

  [1]: https://github.com/earlephilhower/ESP8266Audio/tree/master/examples/StreamMP3FromHTTP

body: There might be a built-in I2S module, but an I2S module does not output an analog signal. The ESPs have no DAC, so you definitely need additional hardware in form of a I2C-DAC/codec IC. There's no software solution.


message:
Attach the Arduino ISR function to the class member

I intended to use a timer interrupt for limited instances of a class in my ESP32 Arduino project. My first code conception was as follows:

```cpp
portEXIT_CRITICAL_ISR(&lock0);
  }

hw_timer_t * timer[3] = NULL;

class myClass
{
private:
  irqCallback timmerCB;
  volatile uint8_t pri_var1, pri_var2;
  static uint8_t class_instance_number=0;
public:
  volatile uint8_t pub_var1, pub_var2;
  myClass(/* args */);
  ~myClass();
};

myClass::myClass(/* args */)
{
  timmerCB=timerCBArray[class_instance_number];
  timer[class_instance_number] = timerBegin(0, 80, true);
  timerAttachInterrupt(timer[class_instance_number], &timmerCB, true);
  class_instance_number++;
}
```

However, I have this problem: how can I change the variable inside the interrupt regarding to each class instance?

body:
# Interrupt Service Routine (ISR) outside a class

Let's consider a simple use of interrupts:

    volatile bool switchChanged;

    void switchPressed ()
      {
      switchChanged = true;
      }  // end of switchPressed

    void setup ()
      {
      pinMode (2, INPUT_PULLUP);
      attachInterrupt (0, switchPressed, CHANGE);
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

That compiles fine.

---

# ISR inside a class as a class function (method)

Now let's imagine we want to put the interrupt handling into a class for our convenience.

    class myClass
      {
      volatile bool switchChanged;

      public:

      void begin ()
        {
        pinMode (2, INPUT_PULLUP);
        attachInterrupt (0, switchPressed, CHANGE);   // <--- line 10
        }  // end of myClass::begin

      void switchPressed ()
        {
        switchChanged = true;
        }  // end of myClass::switchPressed

      };  // end of class myClass

    myClass foo;  // make an instance of myClass

    void setup ()
      {
      foo.begin ();
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

That does **not** compile:

    ISR_in_class_test.ino: In member function ‘void myClass::begin()’:
    ISR_in_class_test:10: error: argument of type ‘void (myClass::)()’ does not match ‘void (*)()’

What is going on here?

ISRs have to be static functions, taking no arguments. However (non-static) class functions have an implied **this->** pointer which points to the particular *instance* of the class.

For example, if we have two instances:

    myClass foo;
    myClass bar;

If we call foo.begin() then **this->** points to "foo", and if we call bar.begin then **this->** points to "bar".

However an ISR, when fired by the processor, cannot know whether **this->** is "foo" or "bar" or something else. Thus the compiler cannot compile that line.

---

# ISR inside a class as a static class function

We can try to work around this by making the class function **static**. Doing that means that the function is not tied to any particular instance, and thus the attachInterrupt line will compile.

    class myClass
      {
      volatile bool switchChanged;   // <--- line 3

      public:

      void begin ()
        {
        pinMode (2, INPUT_PULLUP);
        attachInterrupt (0, switchPressed, CHANGE);
        }  // end of myClass::begin

      static void switchPressed ()
        {
        switchChanged = true;   // <--- line 15
        }  // end of myClass::switchPressed

      };  // end of class myClass

    myClass foo;  // make an instance of myClass

    void setup ()
      {
      foo.begin ();
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

However now we have a different problem:

    ISR_in_class_test.ino: In static member function ‘static void myClass::switchPressed()’:
    ISR_in_class_test:3: error: invalid use of member ‘myClass::switchChanged’ in static member function
    ISR_in_class_test:15: error: from this location

A non-static class variable cannot be called from a static class function. Why? Because the compiler doesn't know *which* variable you want. Is it foo.switchChanged or bar.switchChanged?

---

# ISR inside a class as a static class function with static variables

To make the static function work, it can only access static variables. So we can make switchChanged static. Plus we need to define an instance of this static variable.

    class myClass
      {
      static volatile bool switchChanged;  // declare

      public:

      void begin ()
        {
        pinMode (2, INPUT_PULLUP);
        attachInterrupt (0, switchPressed, CHANGE);
        }  // end of myClass::begin

      static void switchPressed ()
        {
        switchChanged = true;
        }  // end of myClass::switchPressed

      };  // end of class myClass

    volatile bool myClass::switchChanged;  // define

    myClass foo;  // make an instance of myClass

    void setup ()
      {
      foo.begin ();
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

Now the class compiles. However we have thrown away most of the advantages of having a class in the first place, as we are forced to use a static function, and that static function can only access static variables.

---

# Glue routines

To work around this problem we can write short "glue" routines. These are functions that interface between an ISR and an **instance** of a class.

    class myClass
      {
      volatile bool switchChanged;

      static myClass * instances [2];

      static void switchPressedExt0 ()
        {
        if (myClass::instances [0] != NULL)
          myClass::instances [0]->switchPressed ();
        }  // end of myClass::switchPressedExt0

      static void switchPressedExt1 ()
        {
        if (myClass::instances [1] != NULL)
          myClass::instances [1]->switchPressed ();
        }  // end of myClass::switchPressedExt1

      public:

      void begin (const byte whichPin)
        {
        pinMode (whichPin, INPUT_PULLUP);
        switch (whichPin)
          {
          case 2:
            attachInterrupt (0, switchPressedExt0, CHANGE);
            instances [0] = this;
            break;

          case 3:
            attachInterrupt (1, switchPressedExt1, CHANGE);
            instances [1] = this;
            break;

          } // end of switch
        }  // end of myClass::begin

      void switchPressed ()
        {
        switchChanged = true;
        }

      };  // end of class myClass

    myClass * myClass::instances [2] = { NULL, NULL };

    // instances of our class
    myClass foo;
    myClass bar;

    void setup ()
      {
      foo.begin (2);   // pin D2
      bar.begin (3);   // pin D3
      }  // end of setup

    void loop ()
      {
      // whatever
      }  // end of loop

This is a bit fiddly, however what it is doing is remembering in an array which instance of the class is associated with which interrupt. The "glue" routines switchPressedExt0 and switchPressedExt1 call the appropriate instance of the switchPressed function by using the remembered class pointer.

Now the non-static function switchPressed can access non-static class variables.

---

This answer was reproduced from [my forum](http://www.gammon.com.au/forum/bbshowpost.php?id=12983), but I can't post link-only answers here.


body:
I know this is a late answer but I think it is possible to get past the problem with `this` if you use [std::bind][1]

Below is a full example but if that is too long to read,  here is a minimal example.

    class ISRClass {
    public:
      ISRClass(int pin) : pin_(pin) {}

      void setup() {
        attachInterrupt(digitalPinToInterrupt(pin_),
                        std::bind(&ISRClass::sensePinIsr, this), CHANGE);
      }

    private:
      int pin_;
      ulong change_count_;

      void IRAM_ATTR sensePinIsr() {
        // do something fast and simple
        change_count_++;
      }
    };

The function returned by std::bind takes no arguments, not even this.

Full example follows.

Here is an example.  This class uses interrupts to simply set the state of a member variable when the pin has changed state.  It then only reads the pin when needed.  You still have to query the member variable in the loop, but that is about 10x faster than reading the pin.

    #include "FunctionalInterrupt.h"
    #include <Arduino.h>
    #include <functional>
    #include <optional>
    #include <map>

    using CallBack = std::function<void(int)>;

    class PinMonitor {
    public:
      PinMonitor(int pin) : pin_(pin) {}
      void setup() {
        pin_state_ = digitalRead(pin_);
        attachInterrupt(digitalPinToInterrupt(pin_),
                        std::bind(&PinMonitor::sensePinIsr, this), CHANGE);
      }

      std::optional<int> CheckForNewPinState(int debounce) {
        if (!change_count_) {
          return std::nullopt;
        }
        if (!is_debouncing_) {
          is_debouncing_ = true;
          debouce_started_at_ = millis();
          return std::nullopt;
        }
        auto time = millis();
        if (time < debouce_started_at_) {
          debouce_started_at_ = time; // handle timer rollover
        }
        if (time < debouce_started_at_ + debounce) {
          return std::nullopt;
        }
        is_debouncing_ = false;
        change_count_ = 0;
        auto new_pin_state = digitalRead(pin_);
        if (new_pin_state != pin_state_) {
          pin_state_ = new_pin_state;
          for ( auto [_, callback] : callbacks_) {
            callback(pin_state_);
          }
          return pin_state_;
        }
        return std::nullopt;
      }

      int DoIfPinStateChanges(const CallBack callback) {
        next_callback_key++;
        callbacks_[next_callback_key] = callback;
        return next_callback_key;
      }

      void RemoveCallback(int key) {
        callbacks_.erase(key);
      }

    private:
      int pin_;
      int pin_state_;
      ulong change_count_;
      CallBack callback_ = [](auto a) {};
      std::map<int, CallBack> callbacks_;
      bool is_debouncing_{};
      ulong debouce_started_at_{};
      int next_callback_key{};

      void IRAM_ATTR sensePinIsr() { change_count_++; }
    };

Then in main you could use this like below.

    NetworkConnection networkConnection;
    OTAHandler otaHandler;
    Logger &logger = Logger::getInstance();

    PinMonitor pinMonitor1(16);
    PinMonitor pinMonitor2(17);

    int call_count{};
    int removable_callback{};

    void setup() {
      networkConnection.connect();
      logger.startWebSocket();
      otaHandler.setup();
      pinMode(16, INPUT_PULLDOWN);
      pinMode(17, INPUT_PULLDOWN);
      auto chip_id = ESP.getEfuseMac();

      pinMonitor1.setup();
      pinMonitor1.DoIfPinStateChanges([chip_id](auto a) {
        logger.infoln("chip llx, reports pin1 new state of %d detected", chip_id, a);
      });
      removable_callback = pinMonitor1.DoIfPinStateChanges([chip_id](auto a) {
        logger.infoln("second call back was called on pin1, new state of %d detected", a);
        call_count++;
      });
      pinMonitor2.setup();
      pinMonitor2.DoIfPinStateChanges([chip_id](auto a) {
        logger.infoln("chip llx, reports pin2 new state of %d detected", chip_id, a);
      });

    }

    void loop() {
      otaHandler.loop();
      logger.checkWebSocket();

      std::optional<int> new_pin_state1;
      std::optional<int> new_pin_state2;

      new_pin_state1 = pinMonitor1.CheckForNewPinState(100);
      if (new_pin_state1) {logger.infoln("new pin1 state is %d", *new_pin_state1);}

      new_pin_state2 = pinMonitor2.CheckForNewPinState(100);
      if (new_pin_state2) {logger.infoln("new pin2 state is %d", *new_pin_state2);}

      if (call_count > 5) {pinMonitor1.RemoveCallback(removable_callback);}

    }

  [1]: https://en.cppreference.com/w/cpp/utility/functional/bind


message:
Does anyone have code that successfully calculates velocity from an accelerometer

I'm trying to calculate the speed of a rocket for my project. I've been given the task of calculating this with an adxl3xxx accelerometer sensor. I'm not sure how to go about this as an accelerometer takes gravity acceleration into account. Can someone provide some form of code to help me understand. I've heard some theory like caliculatong yaw, pitch and roll then using trig to factor out gravity. Not sure how that works. I've also heard about quartenions not sure what they are. If someone could help me out that would be great thx

body:
Calculating velocity from acceleration is not easy.  Simply put, velocity is derived by calculating the integral of acceleration with respect to time.  In practice, however, this leads to accumulated errors which generally render the process impractical for any but the shortest amount of time.

For further reading, [this Wikipedia Kinematics page][1] does a good job at relating acceleration, velocity and position using math.

> … calculating yaw, pitch and roll then using trig to factor out
> gravity …

Essentially, this is the first of two steps in coding up a tilt compass (the type you find in your cell phone).  You need the yaw, pitch and roll information before you can make sense of the magnetometer data.  Consider reading the first half of a tilt compass description to understand how to calculate yaw, pitch and roll.  [Like this one][2].

> I've also heard about quartenions not sure what they are.

Quaternion are an alternative to using trigonometry to derive (in this case) yaw, pitch and roll.  There are two advantages (in this case).  First, Quaternions are easier for a computer to calculate. Second, Quaternion yaw, pitch and roll calculations do not go to infinity for certain situations.  In the real world using physical gyroscopes this is commonly known as [Gimbal lock][3].

Added later...

> How would i go about using trig?

Trigonometry is not necessary if it is physically arranged such that all acceleration to gain the velocity of interest occurs only in 1 of the X, Y or Z directions of the accelerometer.  Then all that is need is to integrate the accelerometer readings in that direction with respect to time.

If this happens to be in the same direction as earth's gravity, simply subtract 9.8m/s2 out.

If you can't physically arrange it, then you need to read all 3 (X, Y & Z) accelerometer values. From this data pitch and roll can be calculated.  The trigonometry equations for this is on page 21 of the  "tilt compass description" link above.

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

That said we notice on that same page an equation to calculate the magnitude of acceleration.

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

So it may be possible that we can calculate the velocity due to the magnitude of the overall acceleration by sampling the accelerometer X,Y & Z sensors over time.  And avoid trigonometry entirely.

However there is a problem.  We have not accounted for gravity.  Again, if we assume gravity is in the same direction as travel we can subtract it it out.  But if travel is, say, 45 degrees off from the gravity vector, we would only want to subtract cos(45) * 9.8m/s2.  Consider only knowing the overall acceleration magnitude does not supply enough information to determine the angle between the acceleration due to gravity and acceleration due to a change of velocity from zero to an unknown velocity with respect to earth.

At this point decisions need to be made regarding how to account for gravity.  9.8m/s2 may be trivial when compared to the vehicle's acceleration and therefor can be ignored.  Or it may be so critical that extreme measures like tracking where the sun is in the sky become a feasible way to find the actual pitch and roll of the vehicle.

  [1]: https://en.wikipedia.org/wiki/Kinematics
  [2]: https://www.st.com/resource/en/application_note/cd00269797-using-lsm303dlh-for-a-tilt-compensated-electronic-compass-stmicroelectronics.pdf
  [3]: https://en.wikipedia.org/wiki/Gimbal_lock
  [4]: https://i.stack.imgur.com/ieA7e.jpg
  [5]: https://i.stack.imgur.com/UQX1N.jpg


message:
Undefined reference to function in custom library

Hello I am making a private Arduino library but am having trouble understanding how it is linked. Why does this h file work, but when I move the definition of board_led to a matching c file, it throws an error at compilation: `In function loop: undefined reference to board_led(bool)`.

I am using the following board manager to compile in the Arduino IDE:
https://raw.githubusercontent.com/maximintegratedmicros/arduino-collateral/master/package_maxim_index.json

I am using the following board target: `MAXIM ARM 32bit boards > MAX32630FTHR`

```
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern void board_led(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}
```

body:
I suspect you're compiling from C++ code, and including that header.

When C++ links to C code, the C++ code needs to see `extern "C"` on the declaration, or surrounding the declaration (via `extern "C" { /* function declarations */ }`)

If you are compiling C++ code against the C code (and linking them together), try making sure `extern "C"` is used, for example like this:

```c
// arduino_lib.h
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern "C" void board_led(bool on);
```
While nothing changes in the .c file
```c
// arduino_lib.c
#include "arduino_lib.h"

const gpio_cfg_t s_board_led = /* some value */;

void board_leb(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}
```


body:
To complement Bob's answer it is good practice to add header guards for detecting C++ specifically:

```c++
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

// your function definitions here

#ifdef __cplusplus
}
#endif // __cplusplus
```

That way the `extern "C"` is only applied if the header file is included into a c++ file but not if it's included into a c file.


message:
Ways to detect if a ball has reached the wall?

I'm building a kind of pin ball machine, and I need to detect when the ball has hit the wall with the sensor attached.

The ball will hit the wall with a small impact, not large enough to push a button probably. What sensor would be the best to use in this case?

I thought about ultrasonic but I'm not a fan of the constant chirping. Can a light sensor be used here? Eg if there's 10% light left, we assume the ball has reached the wall.

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

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

body:
> The ball will hit the wall with a small impact...

Consider using the well proven pinball bumper design omitting the hammer feature:

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

In many pinball machines a "rubber ring" is stretched in front of one or more "leaf switches".  When the ball hits the "rubber ring" one or more of the "leaf switches" closes (or opens depending on if the "leaf switch" is N.O. or N.C.).  There are many [example for connecting switches to an Arduino][2].

  [1]: https://i.stack.imgur.com/dx8Gl.png
  [2]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button


message:
Guru meditation error load prohibited, esp32s. While using Fastled

I am encountering a Guru meditation error, Load prohibited on my current sketch for the esp32s.

Here is the code:
```
#include <FastLED.h>

#define NUM_LEDS 120
#define LED_PIN 3
CRGB leds[NUM_LEDS];

int H1[12][10] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
  {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
  {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
  {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
  {50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
  {60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
  {70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
  {90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
  {100, 101, 102, 103, 104, 105, 106, 107, 108, 109},
  {110, 111, 112, 113, 114, 115, 116, 117, 118, 119}

};

int connections[7][6] = { // dont forget to change 7 to the number of hubs
  {2,3,4,5,6,7},
  {1,7,3,0,0,0},
  {1,2,4,0,0,0},
  {1,3,5,0,0,0},
  {1,4,6,0,0,0},
  {1,5,7,0,0,0},
  {1,2,6,0,0,0}
};

int const life = 3;
int numHubs = 7;

void setup() {
}

void loop() {
  path_taker(path_picker(numHubs, connections), H1);
  delay(500);
}

int* path_picker(int numHubs,int connections[7][6]){ // dont forget to change 7 to the number of hubs!
  int hub = random(1,numHubs)-1;
  int i = 1;
  int path[life];
  int a = 0;
  path[0] = hub;

  while (i <= life){
    a = connections[hub][random(0,6)];
    if (a != 0){
      path[i] = a;
      hub = a;

      i = i+1;
    }

  }
  return path;
}

void path_taker(int path[life], int H1[12][10]){
    int ini = 0;
    int fin = 0;
    int rod[10];
    for (int i = 0; i < sizeof(path) - 1; i++){
      ini = path[i];
      fin = path[i+1];
      switch (ini){
        case 1:
        switch (fin){
          case 2:
          lightup(arrayBuilder(0, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(4, H1, false));
          break;

          case 4:
          lightup(arrayBuilder(3, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(5, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(8, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(9, H1, false));
          break;
        }
        break;

        case 2:
        switch (fin){
          case 1:
          lightup(arrayBuilder(0, H1, true));
          break;

          case 3:
          lightup(arrayBuilder(1, H1, false));
          break;

          case 7:
          lightup(arrayBuilder(11, H1, true));
          break;
        }
        break;

        case 3:
        switch (fin){
          case 1:
          lightup(arrayBuilder(4, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(1, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(2, H1, false));
          break;
        }
        break;

        case 4:
        switch (fin){
          case 1:
          lightup(arrayBuilder(3, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(2, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(6, H1, true));
          break;
        }
        break;

        case 5:
        switch (fin){
          case 1:
          lightup(arrayBuilder(5, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(6, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(7, H1, false));
          break;
        }
        break;

        case 6:
        switch (fin){
          case 1:
          lightup(arrayBuilder(8, H1, false));
          break;

          case 5:
          lightup(arrayBuilder(7, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(10, H1, true));
          break;
        }
        break;

        case 7:
        switch (fin){
          case 1:
          lightup(arrayBuilder(9, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(11, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(10, H1, false));
          break;
        }
        break;
      }
    }
  }

int* arrayBuilder(int row, int hexigon[12][10], bool reverse){
  int rod[10];
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
  return rod;
}

void lightup(int rod[10]){
  int i = 0;
  while (i<10){
    EVERY_N_MILLISECONDS(50){
      leds[rod[i]] = leds[i] = CHSV(255, 255, 255);
      fadeToBlackBy( leds, NUM_LEDS, 10);
    }
  }

  FastLED.show();
}
```

Here is the decoded exception from Exception Decoder:

     EXCVADDR: 0x00000000 Decoding stack results 0x400d0cc7:
    path_taker(int*, int (*) [10]) at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 75

    0x400d0d3e: loop() at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 44

    0x400d1315: loopTask(void*) at C:\Users\*****\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.6\cores\esp32\main.cpp line 23

    0x40085d81: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

I posted this on Reddit, and a user suggested that the error was occuring on line 201. The issue being that I am attempting to return a pointer to a local variable within the function, arrayBuilder.

I have been doing research on the topic, but I still can't figure out how to resolve the error.

I would greatly appreciate any advice!

body:
Instead of trying to return a pointer to a local variable (which is always doomed to fail, since you end up with a pointer to rubbish) you should create your array outside the function and pass a pointer to it as a parameter, then fill that array through the pointer:

```c++
void arrayBuilder(int row, int hexigon[12][10], bool reverse, int *rod){
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
}
```

Then...

```c++
int rod[10];
arrayBuilder(rownum, myhex, false, rod);
```


message:
Problems in running two solenoid together at the same time

I am trying to activate two solenoids (12V/350mA, connected to a 12V/1A adaptor) at the same time using the TIP120 NPN-transistor and 1kohm resistor using the UNO board. Using a simple program,

```c++
void loop()
{
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(5000);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(2000);
}
```

if I am using a big LED on the pin of the board, I am able to easily blink them but the solenoid is not working?

for powering the Arduino board, I am either using USB or a 12V/1A adaptor, and both result in the same output.

the schematic of the simple connections can be found here   https://www.arrow.com/en/research-and-events/articles/arduino-solenoid-project-control-solenoid-with-arduino-board

can someone please suggest what can I do to start two solenoids at the same time?

I have tried increasing the voltage and current as well from an externally powered source as well. but it did not actuated two valves together
[![enter image description here][1]][1]

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

body:
It will not work as you have it pictured. The ground of the 12V must be connected to the ground of the Arduino. You can put both resistors on the same pin of the Arduino, the one that is working (probably pin 13). Staying with what you have coded would be better. Since each of the solenoids require 1A each your power supply must supply at least 2 amps.

In your code setup() you need to define each pin you will use as an output, (int ledPin = 4; int ledPin = 5;) There are other ways but that follows the example.   then use the pinmode to declare them as an output, pinMode(led1, OUTPUT);  for each pin you want to drive the transistor. Then your code will work. Look at this link for an example: https://www.arduino.cc/en/Reference.digitalWrite.
I used pins 4 and 5, no reason other then 13 blinks with the on board led when it is booting. It is pre defined as an output in the Arduino start code (you normally do not have access to that), that is why it worked.

If you elect to use a MOSFET TheSource becomes the emitter, The Drain becomes the collector and the gate becomes the gate. You would need to pick an avalanche rated one that can


message:
Different meanings of pid and vid in boards.txt

Let's see the `leonardo` section in `boards.txt`:

    leonardo.name=Arduino Leonardo
    leonardo.vid.0=0x2341
    leonardo.pid.0=0x0036
    leonardo.vid.1=0x2341
    leonardo.pid.1=0x8036
    leonardo.vid.2=0x2A03
    leonardo.pid.2=0x0036
    leonardo.vid.3=0x2A03
    leonardo.pid.3=0x8036

    leonardo.upload.tool=avrdude
    leonardo.upload.protocol=avr109
    leonardo.upload.maximum_size=28672
    leonardo.upload.maximum_data_size=2560
    leonardo.upload.speed=57600
    leonardo.upload.disable_flushing=true
    leonardo.upload.use_1200bps_touch=true
    leonardo.upload.wait_for_upload_port=true

    leonardo.bootloader.tool=avrdude
    leonardo.bootloader.low_fuses=0xff
    leonardo.bootloader.high_fuses=0xd8
    leonardo.bootloader.extended_fuses=0xcb
    leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
    leonardo.bootloader.unlock_bits=0x3F
    leonardo.bootloader.lock_bits=0x2F

    leonardo.build.mcu=atmega32u4
    leonardo.build.f_cpu=16000000L
    leonardo.build.vid=0x2341
    leonardo.build.pid=0x8036
    leonardo.build.usb_product="Arduino Leonardo"
    leonardo.build.board=AVR_LEONARDO
    leonardo.build.core=arduino
    leonardo.build.variant=leonardo
    leonardo.build.extra_flags={build.usb_flags}

What are the meanings of the `leonardo.vid|pid.*` and of the `leonardo.build.vid|pid`?
Perhaps the first are for the USB serial device at runtime and the second for the bootloader?

body: The build ones are used when compiling the Arduino core. The others are used to identify the board when it resets into the bootloader so it can find the right com port to upload to


message:
Do passive buzzers require a PWM pin?

[This guide ][1]  Shows how to wire a passive buzzer to be used with tone(). I notice they have it wired to D9, which is a PWM pin. But is it required to use a PWM capable digital output pin to play tones from a passive buzzer?

  [1]: https://create.arduino.cc/projecthub/SURYATEJA/use-a-buzzer-module-piezo-speaker-using-arduino-uno-89df45

body: No, it doesn't need to be a PWM pin. `tone()` uses a timer and an interrupt to generate the audio signal and can work with any IO pin.


message:
Milliseconds using square wave RTC

i am trying to make a code that prints the time hh:mm:ss:ms using RTC,i have made it using millis() but it  is not accurate +/-2 milliseconds

ho can i make it using sq wave and intterupt

here is the code that i have used

    #include <Wire.h>
    #include "RTClib.h"

    RTC_DS1307 RTC;      // This is the DS1307 hardware RTC
    RTC_Millis SoftRTC;   // This is the millis()-based software RTC
    long startMS;  // This will hold the start time in milliseconds

    void setup ()
    {
        Wire.begin();
        RTC.begin();                       // Connect to the DS1307
        SoftRTC.begin(RTC.now());  // Initialize SoftRTC to the current time
        startMS = millis();  // get the current millisecond count
    }

    void loop()
    {
        DateTime now = SoftRTC.now();
        long nowMS = millis();

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(' ');
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.print(':');
        Serial.print((nowMS - startMS)00, DEC);  // print milliseconds
        Serial.println();

i tried to put this code that is based on ISR but with no luck

    volatile time_t isrUTC;         // ISR's copy of current time in UTC
    volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset

    void incrementTime()
    {
        millisecondsFromISR = millis();  //do first to get most accuracy
        ++isrUTC;
    }

    int getMilliseconds() {
        // need to make an atomic copy:
        nointerrupts();
        unsigned long t = millisecondsFromISR;
        interrupts();

        return millis() - t;
    }

body:
All you have to do is record the number of milliseconds at the moment the square wave toggles on its 1 second cycle. Then your milliseconds is the difference between that and the current.

In short: update `startMS` when triggered by the RTC's output.


message:
How do I solve the sensor’s abysmal abnormal output?

## Problem description
When XIAO microcontroller is connected to the sensor signal output pin, keep printing unexpected values.

Sketch
[![enter image description here][1]][1]
[![enter image description here][2]][2]
I haven't sensor circuit diagram, you can machine translate and read the page<https://www.yuque.com/cs/products/rwe87o>

## Detailed description:

The sensor has been outputting a raw value of about 4000. That is to say, the transformation of the function outputs is around  1600000~400000. Not the 0 to 30 values I expected to output.(I tried to use other development board ESP32 to read the sensor value using ADC and its own power supply pin, and still output the original value of 4000(output 1600000~400000), as shown in the figure below.)

### Abnormal output

![Vendor-supplied sample code](https://aws1.discourse-cdn.com/arduino/original/4X/e/9/9/e9939564973468d73ca65706dff0df430504bc72.gif)

### Normal output:

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

This is the output I expect, but I can't reproduce the normal output (last month was very occasionally normal output, I don't know why it can't normal output now and the environment has not changed...Analog circuits are too much like witchcraft...)

### I try to do:

1. Measured with a digital multimeter to ESP32 and XIAO, the power supply pin(to measure voltage between 3.3V and GND pin) is about 3.1V~3.3V(maybe my positive and negative probes are not accurate).

![](https://tupian.li/images/2022/04/04/new1.gif)
![](https://i.stack.imgur.com/Lk9oY.png)

2. Check XIAO's ADC using ADC pin to GND pin for any problems with Analog pins read GND and VCC respectively, with 12bit resolution and output of 100 and 4000 + respectively.XIAO is fine.

3. The Sensor connects the `TTL to USB` power supply pin, but the output is still abnormal.(I used PWM pin by esp32 or xiao MCU to output analog 3.3V, results  same to abnormal output)
[![enter image description here][4]][4]

4. If the sensor signal output is connected to MCU, the high value of 4000 is output(The original value).  Seems to be the power problem, someone tell me how to minimize the power ripple effect and make the 3.3V stable output provided by the battery?
But when I unplug the sensor, the MCU outputs random values, and I don't want the sensor output to be affected by other factors.

![gif](upload://9HX2jdkzyDmOlOL7EKuT28SLOsQ.gif)

5. DMM Checks the sensor output and GND pin separately, using only the DMM, sensor, 3.3V battery module, and breadboard：
(This is one 3P Dupont line and the colors are random.I didn't have a wiring error. If the wiring is wrong neither the MCU nor the sensor will work properly, let alone output signals)
![22-04-04-23-35-46.gif](https://tupian.li/images/2022/04/04/22-04-04-23-35-46.gif)
![](https://iili.io/MRCnSa.gif)
The quality of my DMM is poor, I will measure it when my FLUKE17B+ arrives.

Use MCU to read the value, sure enough, the output value is not affected by the power on or off, because the output value is more than 100000(raw value is 4000,12 bit).

## other
Asked the store, customer service said this is not normal, the sensor should output the value of 0~500, if the sensor monitors the current output of 200~400, not monitoring the general output of 0~30 range.

## Equipment information
XIAO EMG sampled code: [EMG.ino · GitHub](https://gist.github.com/allrobot/c70abc599ca8eb7fbc246ed67515449a)

Sensor parameters: [{ED0056}Sensor](https://www.yuque.com/cs/products/rwe87o)

Microcontrollers XIAO general description: [Getting Started with Seeeduino XIAO - Seeed Wiki](https://wiki.seeedstudio.com/Seeeduino-XIAO/)

Microcontrollers XIAO instruction manual: <https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/ATSAMD21G18A-MU-Datasheet.pdf>
[![enter image description here][5]][5]

How do I solve XIAO’s the sensor’s abnormal output?

  [1]: https://i.stack.imgur.com/63bmP.jpg
  [2]: https://i.stack.imgur.com/QUrPg.png
  [3]: https://i.stack.imgur.com/zELX3.png
  [4]: https://i.stack.imgur.com/EwulX.png
  [5]: https://i.stack.imgur.com/myihn.png

body:
First thing I notice in your photo is that you have your 3.3V and GND wires around the wrong way on the Xiao microcontroller board. This will indeed give you wrong results.

Please see the image below for the pinout.

[![Pinout of the Xiao Microcontroller board][1]][1]

Your Fritzing circuit diagram has the correct wiring for 3.3V and GND.

Please do a couple of tests to verify your setup once the wiring has been corrected. First, remove the sensor and use a potentiometer to provide an analog input into A0. Verify that the potentiometer gives you the correct response that you expect and cross check it with an oscilloscope or digital multi-meter (DMM).

Secondly, power up only the sensor and test the output of the sensor with an oscilloscope or DMM. This should how up as the clean analog signal that you expect.

If these two tests pass, then when you connect up the sensor to the Xiao microcontroller board it should work as expected.

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


body:
Now it solved. I was so stupid, because I didn't connect the MCU to the sensor power, so the MCU couldn't measure the sensor value with the reference power.

[![!\[image|667x500\](upload://6MZQ5bHsZdZKAhBULisPfXrMJu9.png)][1]][1]

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


message:
`time.h` vs `TimeLib.h` on AVR boards

Why do I get wrong result when using `time.h` library when using AVR boards, such Nano/Uno/Pro Micro (while when using `TimeLib.h`).

OUTPUT (for given Epoch ):

`TimeLib`: 2022-04-02 16:11:20

`time.h`: 0152-03-01 16:11:20

CODE:

    #define CASE 1

    #if CASE == 1
    #include <time.h>
    #elif CASE == 2
    #include <TimeLib.h>
    #endif

    time_t bootTime = 1648915880;

    void setup()
    {
      // put your setup code here, to run once:
      Serial.begin(115200);
      Serial.println("\nStart!");
      delay(1000);

      char clk2[40];

    #if CASE == 1
      struct tm *tm = localtime(&bootTime);
      sprintf(clk2, "d-d-d d:d:d", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

    #elif CASE == 2
      sprintf(clk2, "d-d-d d:d:d", year(bootTime), month(bootTime), day(bootTime), hour(bootTime), minute(bootTime), second(bootTime));
    #endif
      Serial.println(clk2);
    }

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

body:
You are assuming the avr-libc "epoch" is the same as the UNIX "epoch". It isn't. According to [the manual](https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html#gaa9336f97d394e8e02d97b9ff4fb0aca2):

> Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. **This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000.** The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

So you need to subtract the `UNIX_OFFSET` from your time value before passing it to any avr-libc functions.

Also you should initialize the time system with `set_zone()` and similar functions.