message:
Square wave generator generates a shorter pulse from time to time

I am  using an arduino Micro to generate 8 square waves on 8 pins. The idea is as follows: on pin 13 is the main square wave. It represents a certain BPM (beats per minute). The other 7 pins should give multiplications or divisions of that BPM.

It uses timer1 to trigger an interrupt at BPM/192 (this number is choosen to enable easy multiplications). It counts those interrupts and changes the states of the outputs when needed.

The codes seems to run fine for most divisions and most multiplications. However in certain cases like /2, there seem to be shorter pulses from time to time that throw the whole timing off.

Adding a short delay at the end of the loop seems to make the system more stable but still the short pulses appear from time to time.

Does anyone have an idea what the problem might be.

[![Oscilloscope reading][1]][1]

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

```
int counter[8] = {0,0,0,0,0,0,0,0}; //storing number of interrupts since last pulse
int trip[8] = {191,383,767,1535,3071,6143,12287,24575}; //number of interrupts needed for div/mult
int outputPin[8] = {13,12,11,10,9,8,7,6};

void setup() {

  for (int x = 0; x < 8; x++){

    pinMode(outputPin[x], OUTPUT);
    digitalWrite(outputPin[x], HIGH);

  }

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A =2602; // 16000000 / (x * 8) -1
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);//prescaler of 8
  TIMSK1 |= (1 << OCIE1A);
  sei();

}

void pulse(){

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

    counter[count]++;

  }

}

ISR(TIMER1_COMPA_vect){

  pulse();
}

void loop() {

  for (int y = 0; y < 8; y++){

    if(counter[y] > trip[y]){

      digitalWrite(outputPin[y],!digitalRead(outputPin[y]));
      counter[y] = 0;

    }

  }

  delayMicroseconds(100);

}
```

body:
There are two issues here:

 1. There is a data race on `counter[]`: it can be modified in interrupt
    context while it is being read (or even modified) by the main
    program.

 2. Clearing `counter[y]` will make you loose ticks if for some reason
    (say some interrupt) you do it a little bit late. You should instead
    decrement it by `trip[channel]`.

Here is a safe way of managing the counters:

```c++
volatile int counter[8] = {...};  // don't forget `volatile`

// Return whether this channel has tripped, and update the count.
bool tripped(int channel) {
    noInterrupts();
    bool did_trip = counter[channel] >= trip[channel];
    if (did_trip) counter[channel] -= trip[channel];
    interrupts();
    return did_trip;
}

void loop() {
    for (int y = 0; y < 8; y++)
        if (tripped(y))
            digitalWrite(outputPin[y], !digitalRead(outputPin[y]));
}
```

Notice that the critical section (the section with interrupts disabled)
lives within the `for` loop, rather than around it. It is better to have
multiple small critical sections rather than one large one.

**Edit 1**: You don't need the delay. It makes the system “more stable”
because it reduces the likelihood that, on any given TIMER1\_COMPA
interrupt, the main program is accessing the counters (as it will spend
most of its time delaying). Adding this delay is in a way treating the
symptoms rather than the root cause of the data race.

**Edit 2**: Answering a comment. If you want the squares waves to stay
in sync, their frequency ratios should be integers. In your program,
this is almost, but not quite the case. For example, if you look at the
ratio between the first two channels:

channel 0: 191 interrupts per signal toggle
channel 1: 383 interrupts per signal toggle
ratio: 383 ÷ 191 ≈ 2.0052

The easy fix is to add 1 to every element of the `trip` array (384 ÷ 192
is _exactly_ 2).


sender: user

message:
Not registering complete rotary encoder input

I am working on a project using a Rotary Encoder and I am trying to recieve the output from the encoder. As it stands I am able to get a count for degrees of change and direction of rotation, however depending on the speed the encoder spins I get a varying rotational output. For example if I rotate it slowly I can get 100's of counts for 180 degrees of rotation, but if I do so fast, then I could get 10 or so counts.

I believe my Arduino is running too slow to count each of the signals from the encoder, I measured the wavelength of a signal to be ~25 us when spun quickly but using the following code I found that my arduino is running at a loop rate of 200 loops per second.
```
void loop() {
  if(counter <= 1000){
    counter++;
    Serial.println(counter);
  }
}
```

The code for the Rotary Encoder:
Dt and Clk pin representing the 2 signal wires, both being pulled up
```
void loop(){

  //take clk pin state
  clkState = digitalRead(clkPin);

  //if clk state changed then wheel is rotating, react to rising edge to avoid double count
  if(clkState != preClkState && clkState == HIGH){
    Serial.write(digitalRead(dtPin));
    //check direction of spin based on dtpin
    if(digitalRead(dtPin)== HIGH){
      counter++;

      clockwiseDirection = true;
    }else{
      counter--;

      clockwiseDirection = false;
    }

    //output values
    Serial.write("Direction: ");
    if(clockwiseDirection){
      Serial.write("Clockwise | Counter: ");
    }else{
      Serial.write("Counter Clockwise | Counter: ");
    }

    Serial.print((int)counter);
    Serial.print("\n");

  }

  //update pre pos
  preClkState = clkState;

}
```

Thanks in advance.

sender: assistant

body:
Serial transmission takes time. Let's assume that you have set up the `Serial` with 9600 baud. This means 9600 bits per second. A single byte transmission commonly consists of a start bit, the data bits, and a single stop bit. This gives a total of 10 bits per byte. Therefore, your transfer rate is 9600 bits/s / 10 bits/byte = 960 bytes/s.

Estimating with a quick look at your source, each loop of your sketch sends about 40 characters, commonly encoded as a byte per character. And you claim that it achieves 200 loops per second, so the transfer rate is 40 bytes/loop * 200 loops/s = 8000 bytes/s.

Calculating back to bits/s results in a baudrate of roughly 80000 bits/s. So presumably you set up your `Serial` with 57600 or 115200 baud.

---

How to solve the issue?

Separate the acquisition of the encoder data from the transmission of the counter value. You can use interrupts, for example on the clock signal. However, this is not for the faint heart.

The `Serial` uses a transmission buffer of unspecified size. See the last paragraph of [its documentation][1]:

> As of Arduino IDE 1.0, serial transmission is asynchronous. If there is enough empty space in the transmit buffer, `Serial.write()` will return before any characters are transmitted over serial. If the transmit buffer is full then `Serial.write()` will block until there is enough space in the buffer. To avoid blocking calls to `Serial.write()`, you can first check the amount of free space in the transmit buffer using `availableForWrite()`.

You can check that the transmit buffer has room for your message. Send only, if there is enough room.

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/serial/write/


message:
Incorrect reading from DHT22 (on a Nano board)

I have rigged two different DHT22 sensors to an Arduino Nano board. Both temperature readings are more or less comparable but they produce very different humidity readings.

The sensors are:

 - Sensor No. 1 is an [IDUINO-Version of the DHT22][1] on PIN 2
 - Sensor No. 2 is a [DHT22 in Grove version from Seeeds Studio][2] on PIN 3

The simple code is build on one of the basic examples as followed:

    #include "DHT.h"
    #define DHTPIN_2 2     // Digital pin connected to the DHT sensor_1
    #define DHTPIN_3 3     // Digital pin connected to the DHT sensor_2
    #define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
    #define DHTTYPE_11 DHT11   // DHT 11  (AM2302), AM2321

    DHT dht_1(DHTPIN_2, DHTTYPE);
    DHT dht_2(DHTPIN_3, DHTTYPE);

    void setup() {
      Serial.begin(9600);   //consider baud in serial monitor!
      Serial.println(F("DHT22 test!"));
      dht_1.begin();
      dht_2.begin();
    }

    void loop() {
      delay(5000);
      float h_1 = dht_1.readHumidity();
      float t_1 = dht_1.readTemperature();
      float h_2 = dht_2.readHumidity();
      float t_2 = dht_2.readTemperature();

      //Check if any reads failed and exit early (to try again).
      if (isnan(h_1) || isnan(t_1)) {
        Serial.println(F("Failed to read from DHT sensor_1!"));
        return;
      }

      // Check if any reads failed and exit early (to try again).
      if (isnan(h_2) || isnan(t_2)) {
        Serial.println(F("Failed to read from DHT sensor_2!"));
        return;
      }
      Serial.print(F("Humidities: "));
      Serial.print('\n');
      Serial.print(F("s_1: "));
      Serial.print(h_1);
      Serial.print(F(" s_2: "));
      Serial.print(h_2);
      Serial.print('\n');
      Serial.print(F("Temperatures: "));
      Serial.print('\n');
      Serial.print(F("s_1: "));
      Serial.print(t_1);
      Serial.print(F(" s_2: "));
      Serial.print(t_2);
      Serial.print('\n');
    }

The resulting output on the Serial Monitor is:

    Temperatures:
    s_1: 25.30 s_2: 23.40
    Humidities:
    s_1: 6.20 s_2: 66.40
    Temperatures:
    s_1: 25.20 s_2: 23.40
    Humidities:
    s_1: 6.00 s_2: 66.10
    Temperatures:
    s_1: 25.10 s_2: 23.40
    .
    .
    .
The humidity reading from sensor_1 seems defective, just having the 10th of the value of sensor_2. Is there a fix for that? Is it possible to re calibrate sensor_1 or is it broken?

Thank you!

## Edit: swapping the sensors (suggested by jsotola) ##
The output results in:

    Temperatures:
    s_1: 22.60 s_2: 24.70
    Humidities:
    s_1: 67.80 s_2: 7.30

Its the sensor it seems.

  [1]: https://alexnld.com/product/am2302-dht22-temperature-and-humidity-sensor-module-for-arduino-scm/
  [2]: https://wiki.seeedstudio.com/Grove-Temperature_and_Humidity_Sensor_Pro/

body:
The difference in humidity readings may be traced to any number of reasons including faulty parts, incorrect programming or low voltages (*please post at what voltage you are running the sensors at*) to name a few.

Let us speculate that one of the sensors is reporting relative humidity and the other absolute.  Absolute humidity does not consider temperature where as relative does.  From [this web site][1] we get the following conversion equation:

[![relative to absolute humidity equation][2]][2]

This equation converts relative humidity to absolute. Finding the saturation vapor pressure measured in pascal is not trivial.  So we will use [this web site][3] to calculate this value.

Let us use the sample:

 - Temperature 1: 22.60 C
 - Temperature 2: 24.70 C
 - (assumed) Relative Humidity: 67.80 %
 - (assumed) Absolute Humidity: 7.30

So, average temperature is 23.65 C.
Using this temperature and the above web page, the vapor pressure is 2923 PA.

AH = (67.80 x 2923) / (462.5 x (273.15 + 23.65) x 100)
AH = 0.014437 Kg/(meter cubed)

As absolute humidity is normally written as grams per cubic meter:

AH g/(meter cubed) = 0.014437 * 1000 = 14.43 g/(meter cubed)

14.43 is not 7.30.  Consider your options.  Check your circuit, voltages and software (*does varying the amount of time between samples result in different values*). Also consider running more tests in better conditions (*placing both sensors inside the same sealed container over a long period of time to mitigate exposure to different conditions*).

---
Added later...

Evidently problems with the DHT11 humidity sensor is a known problem:

 * [Arduino.cc forum][4]
 * [Partical.io forum][5]
 * [Raspberry Pi forum][6]
 * [Another from Arduino.cc form][7]

  [1]: https://www.omnicalculator.com/physics/absolute-humidity#relative-humidity
  [2]: https://i.stack.imgur.com/MouhZ.jpg
  [3]: https://www.weather.gov/epz/wxcalc_vaporpressure
  [4]: https://forum.arduino.cc/t/dht11-temp-ok-but-rh-values-wildly-off/94396
  [5]: https://community.particle.io/t/inaccurate-humidity-with-dht22-bad-sensor/24637
  [6]: https://forums.raspberrypi.com//viewtopic.php?f=37&t=101860
  [7]: https://forum.arduino.cc/t/humidity-sensors-very-inaccurate/174810


message:
We have Arduino IDE code that needs to stop after a set number of "revolutions"

We have Arduino IDE code that oscillates a plate on a lead screw powered by stepper motor to move back and forth.

We have the lead screw move 8 mm in one direction, then 8 mm in the opposite direction, for a total displacement of 16 mm. After this movement we have a counter that will then count as 1 "revolution" essentially. After reaching a specified count that program will stop.

Currently the program continues to run indefinitely. Any help/suggestions would be appreciated.

```c++
// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type.
// Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(40000);
  stepper.setAcceleration(20000);
}

void loop() {
  static int counter = 0; // Initialize a counter variable and start at 0

  // Set the target position:
  stepper.moveTo(400); // is in steps. setting to default

  // Run to target position with set speed and acceleration/deceleration:
  stepper.runToPosition();

  delay(0);

  // Move back to zero:
  stepper.moveTo(0);
  stepper.runToPosition();

  delay(0); //microseconds
  counter++; //adds 1 to the counter

  if (counter >= 2) {
    return; //exit the loop
  }
}
```

body:
    if (counter >= 2) {
        return; //exit the loop
      }

The return statement will end the loop, but the loop function is called over and over repeatedly.  So it will just start over again.

There are a few possibilities here.  You can replace the `return` statement with `while(1);` which will lock up execution there until the board is reset.

If you don't need the loop function to repeat ever then you can simply move all of your code into the setup function as it will only run once.  Then the loop function can just be empty.

And lastly, you could add a boolean variable and put the code you want to run only sometimes under an if statement that checks that variable.  At the end of the process you set the variable to false to stop the other code from running.  This would allow you to add code later to set it back at the press of a button or something in case you wanted the option to start the process again.

    bool running = true;
    void loop(){
      if(running){
          // do things
      }
      if (counter >= 2){
        running = false;
      }
    }


message:
Impossible to install the esp_camera library

I cannot install the esp_camera library. When I try to add the .zip, I get "does not contain a valid library.

Everything about this ESP-32 Cam seems to rely on that library, and I can't find a way to install from https://github.com/espressif/esp32-camera or any other way.

Thanks.

body:
It's not a "library" in the way that the Arduino system uses the term. That is, it's not designed to be placed under `<sketchbook>/libraries` directory way typical Arduino libraries are.

The good news is that you don't need to install it, because you already have it. It comes as part of the SDK files packaged into the ESP32 Arduino core as it is installed through the boards manager.

You'll find the header various places under the `<arduino15>/packages/esp32/hardware/esp32/<version-number>/tools/sdk/esp32<architecture>/include/esp32-camera/driver/include/esp_camera.h` where arduino15 refers to [this](https://support.arduino.cc/hc/en-us/articles/360018448279-Open-the-Arduino15-folder), `version` refers to whatever version of the board package you have installed, and `architecture` is nothing, or `c2`, `s3`, or various other related esp32 suffixes.

The bulk of the code being in `<arduino15>/packages/esp32/hardware/esp32/<version>/tools/sdk/esp32<architecture>/lib/libesp32-camera.a`


message:
Having an issue conveying array values properly

this is my first time asking a question here, sorry in advance if this is a poor way to ask this question.

I'm at an intermediary point in coding a program, and at this stage I'd like my byte information which I'm inputting into my serial monitor to take the places of my array elements. I'm able to do so, but when I try to use a 5 digit input, I only get a 4 digit input in return.

It seems like my Serial.available() == 4 loop is preventing my Serial.available() == 5 loop from operating. Would there be a simple modification I could make to allow a 5 digit result from a 5 digit input, and a 4 digit result from a 4 digit input? I've tried many things and Chat GPT seems to think the current code should work, but it doesn't. Here's the code:

<!-- language: c++ -->

    int fiveArray[5];
    int fourArray[4];
    const char* colors[] = {"black ", "brown ", "red ", "blue ", "yellow ", "orange ", "white ", "gold ", "green ", "purple "};

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

      Serial.print("Input a number value: ");
      Serial.println();
    }

    void loop() {
      if (Serial.available() ==5 ) {
        char tempArrayFive[6];
        Serial.readBytes(tempArrayFive, 6);
        tempArrayFive[5] = '\0';

        for (int i = 0; i < 5; i++) {
          fiveArray[i] = tempArrayFive[i] - '0';
        }

        Serial.print("Color Value: ");
        for (int i = 0; i < 5; i++) {
          Serial.print(colors[fiveArray[i]]);
        }
        Serial.println();

      }
      if (Serial.available() == 4 ) {
        char tempArrayfour[5];
        Serial.readBytes(tempArrayfour, 5);
        tempArrayfour[4] = '\0';

        for (int i = 0; i < 4; i++) {
          fourArray[i] = tempArrayfour[i] - '0';
        }

        Serial.print("Color Value: ");
        for (int i = 0; i < 4; i++) {
          Serial.print(colors[fourArray[i]]);
        }
        Serial.println();
      }
    }

body:
Yes, if you send 5 bytes to the Arduino then they will arrive one at a time.  When the 4th byte arrives then the `if (Serial.available() == 4 )` statement is true and it runs that code.  That code reads from the buffer which means that the part that checks for 5 bytes will never be able to run.  There will always be 4 before there is 5.

A better idea would be to send your bytes with a start and end marker.  The program on the Arduino will read bytes and collect them in an array until it sees the end marker.  Then you can count how many bytes you have received if you want to take different actions depending on that number.

Here's a nice thread on handling Serial data:  https://forum.arduino.cc/t/serial-input-basics-updated/382007


body:
I have a post [here](http://gammon.com.au/serial) which discusses handling incoming serial data. Also [here on Stack Exchange](https://arduino.stackexchange.com/questions/19756/how-does-serial-communications-work-on-the-arduino/19757#19757).

For handling serial input like you are trying to do I suggest using an "end of line marker" like newline (which the Terminal Monitor in the IDE will do for you automatically).

Then it's just a case of seeing whatever-it-was you got before the newline. Example code:

<!-- language: c++ -->

    /*
    Example of processing incoming serial data without blocking.

    Author:   Nick Gammon
    Date:     13 November 2011.
    Modified: 31 August 2013.

    Released for public use.
    */

    // how much serial data we expect before a newline
    const unsigned int MAX_INPUT = 50;

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

    // here to process incoming serial data after a terminator received
    void process_data (const char * data)
      {
      // for now just display it
      // (but you could compare it to some value, convert to an integer, etc.)
      Serial.println (data);
      }  // end of process_data

    void processIncomingByte (const byte inByte)
      {
      static char input_line [MAX_INPUT];
      static unsigned int input_pos = 0;

      switch (inByte)
        {

        case '\n':   // end of text
          input_line [input_pos] = 0;  // terminating null byte

          // terminator reached! process input_line here ...
          process_data (input_line);

          // reset buffer for next time
          input_pos = 0;
          break;

        case '\r':   // discard carriage return
          break;

        default:
          // keep adding if not full ... allow for terminating null byte
          if (input_pos < (MAX_INPUT - 1))
            input_line [input_pos++] = inByte;
          break;

        }  // end of switch

      } // end of processIncomingByte

    void loop()
      {
      // if serial data available, process it
      while (Serial.available () > 0)
        processIncomingByte (Serial.read ());

      // do other stuff here like testing digital input (button presses) ...

      }  // end of loop

In your case, you would put code in the `process_data` function to turn the input text into a number and then do something with that number.

I'm surprised ChatGPT didn't point out my code \<grin\> but maybe you asked it a too-specific question.

---

I'd just point out that without a line-terminator character (like newline) then your code will be permanently out of step with incoming data if it starts in the wrong place. For example:

    123456789

Depending on the speed at which that arrives, are we seeing `123` followed by `456`? Or `12` followed by `34`? Or `1234` followed by `5678`? The end-of-line delimiter is really essential to avoid those ambiguities.

Or if the code happens to start running after you have sent the `1` but before the `2` it would think you sent `234` rather than `123` and then every other number would be out by one position.


message:
How to use an external 32kHz crystal for ESP32 S3 with Arduino IDE?

I want to use an external 32kHz crystal for RTC with ESP32 S3, but I didn't see any example or tutorial for Arduino IDE, Even when I asked ChatGPT, it gave me some example but the code gave library errors. I don't understand why there is no RTC example in the Arduino IDE.

I have designed a PCB with this SCH for RTC. But I don't know how I can activate an external 32 KHz crystal with Arduino IDE. Please tell me how.

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

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

body:
From the [ESP32-S3 documentation][1] in section 2.4.2:

> ESP32-S3 supports an external 32.768 kHz crystal or an external signal (e.g., an oscillator) to act as the RTC
sleep clock. The external RTC clock source is used to improve the timing accuracy and thus reduce the average
power consumption, but will not affect the functionality.

This document also contains a schematic:

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

... it is assumed that the schematic in the question is that of the ESP32-S3-WROOM module accounting for the differences between the two schematics.

The wording in the document infers there is only a counter to track / control the processor's sleep state.

This is further enforced by [this question / answer][3] found in electronics.stackexchange.com:

> The ESP32 RTC module only has a timer that runs even in hibernation mode as well as some RAM that it can retain in deep sleep mode...
>
> ... There's no "wall clock" or "calendar" in the ESP32 RTC module.

If still interested in implementing a "wall clock" using the ESP32-S3, the same stackexchange question / answer offers the following:

>The ESP32 does not have a real time clock - you cannot tell it to wake up at a particular time. It does have a timer that can wake it from deep sleep after a given time.
>
> You can use the deep sleep wake up timer like this:
>
> > esp_sleep_enable_timer_wakeup((uint64_t)sleepTimeSeconds * 1000000);
> > esp_deep_sleep_start();
>
> You set the sleep timer with esp_sleep_enable_timer_wakeup. The time period is in microseconds. With the timer set, the ESP32 will automatically wake up after the set time period.

Code will then have to be written to pull the last time from the ESP32-S3's nonvolatile memory, increment it by 1 second, store it back into nonvolatile memory and put the processor back to sleep for 1 second.

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_hardware_design_guidelines_en.pdf
  [2]: https://i.stack.imgur.com/nmtnA.jpg
  [3]: https://electronics.stackexchange.com/questions/681067/does-the-esp32-wroom-32-have-an-internal-rtc


body:
This is not a simple task: you have to recompile the Arduino core with the external RTC enabled.

Basically, you have to properly set the CONFIG_RTC_CLK_SRC option in kconfig file. You should start to read from [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/kconfig.html#config-rtc-clk-src), and practising with ESP-IDF configurator.

I successfully completed this operation for the ESP32-S2 few years ago, but the procedure is very similar. Good luck.


message:
Large arrays crash the arduino

I have three large `PROGMEM` arrays, in order to store musical notes for a song. One array is the notes, one is the note durations, and one is the pause after the note.

The first array is an `int` one and the other two are `floats.` The program works, but after a specific number of elements, the arduino crashes. Meaning, I upload the program without problems, but the device does nothing.

When I have 227 elements (in all three arrays) obviously, the program works. If I increase the number  of elements to 228, nothing happens when I upload...

When the IDE says `avrdude: 10606 bytes of flash verified` then everything works. When the size gets increased to `10616`, everything crashes. Is this normal behaviour?

**EDIT:** The code is trivial, the only important part of the code is this:

    int number_of_stored_values_in_MelodyArray = sizeof(Crash_Melody) / sizeof(int);
    int Melody_Array[number_of_stored_values_in_MelodyArray];
    memcpy_P(Melody_Array, Crash_Melody, sizeof Melody_Array);

I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to RAM.
I do this for the int and the two float arrays. With 221 elements in each array, I guess I am out of RAM.

The reason I have an array for the pause as well, is because I am using an online midi to tone() converter and that is the format that it uses. So I have to stick to that format.

I think if I did the assignment incrementally - like for example copy only 20 elements from the array, play the song, then repeat until the end, I would have no problem.

Is there a way for `memcpy_P()` to specify not the whole array to copy, but index them? Does it take a starting index value?

**EDIT 2:**
This is a snippet of code after trying Edgar Bonnet's approach.

    int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
    for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
    {
      int note = pgm_read_word(&My_Melody[i]);
      float duration = pgm_read_word(&My_noteDurations[i]);
      float pause_duration = pgm_read_word(&My_Delay[i]);
      playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
    }

    int playMelodyExtended2(int melody, float noteDuration, float pauseDuration, int number_of_notes, int music_pin, int delay_var)
    {
      for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
      {
        tone( music_pin, melody, noteDuration );
        delay( pauseDuration );
        noTone(music_pin);
      }

      delay(delay_var);
    }

**EDIT 3:**
This is the newest iteration of the code:

     int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
     for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
     {
        int note = pgm_read_byte_near(&My_Melody[i]);
        note << 8;
        note += pgm_read_byte_near(&My_Melody[i+1]);
        float duration = pgm_read_float_near(&My_noteDurations[i]);
        uint16_t pause_duration = pgm_read_byte_near(&My_Delay[i]);
        pause_duration << 8;
        pause_duration += pgm_read_byte_near(&My_Delay[i+1]);
        playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
      }

    int playMelodyExtended2(int melody, float noteDuration, uint16_t pauseDuration, int number_of_notes, int music_pin, int delay_var)
    {
      for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
      {
        tone( music_pin, melody, noteDuration );
        delay( pauseDuration );
        // stop the tone playing:
        noTone(music_pin);
      }

      delay(delay_var);
    }

body:
In the edited version of your question, you wrote:
> I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to
> RAM.

The whole purpose of `PROGMEM` is to **avoid having to store the data in
RAM**. If you copy the arrays to RAM, you are defeating `PROGMEM`. Your
Arduino has much more Flash than RAM, and it will crash if you eat up
all the RAM. This is why the `PROGMEM` optimization is valuable whenever
you have large arrays of constant data.

The proper way to use those arrays is to copy to RAM one element at a
time: get the data for the next note you have to play, then play it,
then move to the next one. E.g.:

```c++
for (int i = 0; i < melody_length; i++) {
    int note = pgm_read_word(&Crash_Melody[i]);
    // etc...
}
```

Copying small chunks to RAM, as you suggest in your question, would make
the code more complex and add absolutely no value.

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

**Edit**: In the second edit of your question, you have this:

```c++
float duration = pgm_read_word(&My_noteDurations[i]);
```

What this does is:

* read the first two bytes of `My_noteDurations[i]` (which is a
  four-byte quantity, thus you are truncating it)
* interpret that as an integer (which it is not)
* convert that to `float`

The result will have little to do with the original number. The correct
way to read a float from `PROGMEM` is to use `pgm_read_float()`.

That being said, I see now that you use this number as a parameter for
`delay()`. Given that this function takes an integer, there is no point
in storing the delay as a float. This will only add a (somewhat costly)
float-to-integer conversion to your program, with no added benefit.
Also, since the delays are likely to be less than 65 seconds, a
16-bit unsigned integer should be enough.

Further down, you have this:

```c++
for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
{
  tone(music_pin, melody, noteDuration);
  delay(pauseDuration);
  noTone(music_pin);
}
```

I fail to see the purpose of this loop. You are repeating **each note**
a number of times that is equal to the total number of notes in the
song. Why?

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

**Answer to edit 3**: there are a few issues I can see in this version
of the code.

1. Consistency of the data types: in the previous version, it looked
   like the pause durations were floats. Now they are integers. You have
   to make sure you use the `pgm_read_*()` function suitable for the
   actual data type of the array.

2. Reading by bytes: there is no point in reading a 16-bit integer one
   byte at a time: use `pgm_read_word()` to read it all at once. Reading
   byte by byte only makes the code more complex and increases the
   chances of bugs. In fact, your way of reconstructing the numbers is
   buggy.

3. The loop in `playMelodyExtended2()` makes no sense to me. Please, try
   removing it.

Here is what I suggest at this point:

```c++
for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
{
    int note = pgm_read_word(&My_Melody[i]);
    float duration = pgm_read_float(&My_noteDurations[i]);
    uint16_t pause_duration = pgm_read_word(&My_Delay[i]);
    tone(10, note, duration);
    delay(pause_duration);
}
```

This snippet makes some assumptions about the rest of your code, and
specifically about the way your arrays are defined. If these assumptions
are incorrect, this will not work. Thus, I second @orithena's comment
and urge you to post a full, testable version of you sketch (three notes
would be enough).


message:
Where to find interrupt flag for 3rd-party Arduino board cores?

This question might be a bit broad, but I'm running into an apparently classic problem with Arduino interrupts, where the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin. In this case, I'm working with Sparkfun's [Artemis module][1] (using the [Apollo3 microcontroller][2]). The code in question can be seen below:

    #define SLEEP_INTERRUPT   4

    void setup
    {
        pinMode(SLEEP_INTERRUPT, INPUT);
    #ifdef DEBUG
      Serial.print("About to attach interrupt");
    #endif
      attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
    #ifdef DEBUG
      Serial.print("Interrupt attached");
    #endif
    }

    void sleepModeSwitch()
    {
    #ifdef DEBUG
      Serial.print("Interrupt triggered! button status: "); Serial.println(digitalRead(SLEEP_INTERRUPT));
    #endif
      if(sleep_mode_status == false)
      {
        goToSleep();
      }
      else
      {
        wakeUp();
      }
    }

    void goToSleep()
    {
      sleep_mode_status = true;
    #ifdef DEBUG
      Serial.println("Going to sleep");
      delay(50);  //Wait for serial to finish
      Serial.end(); //Power down UART(s)
    #endif
      // turn off the led.
      digitalWrite(LED_BUILTIN, LOW);

      // Stop the BLE advertising.
      BLE.stopAdvertise() ;

      powerControlADC(false);

      for(int x = 0; x < 50; x++)
      {
        if(x != 4)
        {
          am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
        }
      }
      //Power down Flash, SRAM, cache
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k
      //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)

      // // Enable interrupts to the core.
      am_hal_interrupt_master_enable();

      // //Enable the timer interrupt in the NVIC.
      // NVIC_EnableIRQ(STIMER_CMPR6_IRQn);

      //Go to Deep Sleep.
      am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
    }

    void wakeUp()
    {
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);

      // Re-enable UART0 pins
      am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX);
      am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX);

      am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);

      initializeADC();

    #ifdef DEBUG
      Serial.begin(115200);
      Serial.println("Waking up! Hello world!");
    #endif
      deepSleepTimer = millis() ;
      sleep_mode_status = false;
    }

Based on my research, the solution for this is to just clear the interrupt flag manually before attaching the interrupt to your desired pin. Unfortunately, so far the methods for doing so that I've found only work for AVR boards, and I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core. Does anyone have a suggestion or two on where to start?

  [1]: https://www.sparkfun.com/products/15484
  [2]: https://cdn.sparkfun.com/assets/c/8/3/d/2/Apollo3-Blue-SoC-Datasheet.pdf?_gl=1*1ovb3x*_ga*MjExNjgxNTkwNy4xNjU5NjIyNDc0*_ga_T369JS7J9N*MTY5NzcyMTQ2Mi4zMS4wLjE2OTc3MjE0NjIuNjAuMC4w

body:
> the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin

There is no "technically" about it. This is what is supposed to happen. Once you configure the interrupt to happen (as you do in `setup`) then the processor will remember that the condition has happened, whether or not interrupts are enabled.

If you want the interrupt only to be processed *after* a certain point, then yes, you should clear the "interrupt has happened" flag in the MCU, before enabling interrupts.

Your question is pretty non-specific about exactly which processors you are talking about, but I would certainly clear any appropriate flags before attaching the interrupt.

> I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core

The datasheet of the device on this particular core?

---

Judging by the [datasheet for the Apollo3 Blue SoC](https://cdn.sparkfun.com/assets/c/8/3/d/2/Apollo3-Blue-SoC-Datasheet.pdf):

> 6.3.2.15 INTCLR Register
>
> IO Master Interrupts: Clear
>
> OFFSET: 0x00000228
>
> INSTANCE 0 ADDRESS: 0x5000C228
>
> Write a 1 to a bit in this register to clear the interrupt status associated with that bit.

However I don't have one of those processors around to test it.


message:
Why won't my servo and ultrasonic sensor work together?

I have a school project due tomorrow, and I'm planning to connect a servo motor with an ultrasonic sensor. If the distance is under 10cm, the servo motor should turn 180 degrees and will return to 0 degrees when there's no object in front of the sensor. I've tried them separately, the sensor by itself works and could read distance as usual and the servo works too. However, when I put the two code together, it just seems to cancel each other out. I don't know much about coding but pretty sure the sensor is supposed to print the distance on the serial monitor, but it just stops working, I also put some code to try and get the servo to turn, but it also doesn't work... So now I'm stuck pls help me, it's due tomorrow :(

Could it be my power source? I'm using my laptop to power it... but my friend did the same project, and it worked well using laptop as a power source, but i saw some post like this that encourages me to change power source, but isn't a laptop a huge power source? (genuinely asking)

```c++
#include <Servo.h>
#define servopin 9
#define echoPin 4
#define trigPin 5

Servo Myservo;
int long duration;
int distance;

void setup() {
    Myservo.attach(servopin);
    pinMode(echoPin, INPUT);
    pinMode(trigPin, OUTPUT);
}

void loop() {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = (duration * 0.034 / 2);

    if (distance < 10)
    {
        Myservo.write(180);
    }
    else
    {
        Myservo.write(0);
    }
    delay(500);
}
```

body:
I tried your code on online simulator, and it works perfect!

Maybe just try another distance check like `if(distance<30)` (at least) and let's know what will happen.

*I don't think using the laptop as a power source is your problem*


message:
Give zero volt to specific servo motors in a certain time

I have a robot that uses 4 mechanical arms. Each mechanical arm has 4 "READYTOSKY 30kg" servo motors on them.

At some point, I need to use the absolute maximum force of only two mechanical arms (while the other two will stay still). Even though I do not change the coordinates of the other two mechanical arms (which I am not using),they consume voltage and "take away" the full potential of force from the other two.

Is there a way to stop the voltage consumed by the two other arms just for a brief moment using Arduino code? Shortly afterwards they will get back the voltage they need.

```c++
    if(level==25)
      {
        pwm.setPWM(12, 0, 200);
        pwm.setPWM(13, 0, 255);
        pwm.setPWM(14, 0, 430);
        delay(100);
        pwm.setPWM(1, 0, 380);
        pwm.setPWM(2, 0, 520);
        delay(500);
        pwm.setPWM(0, 0, 170);
        delay(600);
        stepperten.setCurrentPosition(0);
        while (stepperten.currentPosition() != (-3*200))
        {
        stepperten.setSpeed(-600);
        stepperten.runSpeed();
        }
        steppertwist.setCurrentPosition(0);
        while (steppertwist.currentPosition() != (100))
        {
          steppertwist.setSpeed(200);
          steppertwist.run();
        }
        stepper1.setCurrentPosition(0);
        while(stepper1.currentPosition() != (30))
        {
          stepper1.setSpeed(200);
          stepper1.run();
        }

        pwm.setPWM(1, 0, 295); //THIS IS THE MOMENT I NEED TO STOP VOLTAGE FOR OTHER ARMS
        pwm.setPWM(2, 0, 400); //AND GET THE MAXIMUM VOLTAGE POSSIBLE ON THESE TWO ARMS
        delay(1500);
        pwm.setPWM(12, 0, 125);

        array1[25][0] = 170;
        array1[25][1] = 295;
        array1[25][2] = 400;
        array1[25][3] = 153;
        array4[25][0] = 125;
        array4[25][1] = 255;
        array4[25][2] = 395;
      }
```

body:
If you want to turn off power for some external parts you could try to power them via the digital pins. See this example code:

    void setup(){
       pinMode(YOUR_ARM_POWER_SUPPLY_PIN, OUTPUT);

       // switch arm on
       digitalWrite(YOUR_ARM_POWER_SUPPLY_PIN, ON);
    }

    void loop(){
      if(armMustNotUseAnyPower()){
          // switch arm off
          digitalWrite(YOUR_ARM_POWER_SUPPLY_PIN, OFF);
      }

    }

Keep in mind that the digital Pins cannot output as much power as VCC. But since you drive some servo motors over it I assume they get their power externally anyway. You might need to add some transistor or another way on how to switch the power on and off from the big power source. Hope this helps you in some way.


message:
Sounds are being played at the same time

I'm making a school project that allows plants to 'talk'. As in when the plant is in an un-ideal environment (low or high soil moisture, not ideal temperature or humidity and not enough light). I have currently made some demo code for my presentation as the real code has real thresholds and is hard to trigger instantly during the presentation.
The problem im facing is that the sound is almost always cut off by another one, how can i stop this, also the recordings are all 7 seconds or less.
``` arduino
#include <DHT.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <LiquidCrystal_I2C.h>
//-----------------DEMO---CODE-------
#define DHTPIN 3
#define DHTTYPE DHT22
#define SOIL_MOISTURE_PIN A0
#define LIGHT_SENSOR_PIN 2
#define TEMP_THRESHOLD 25.0
#define HUMIDITY_THRESHOLD 60
#define LIGHT_THRESHOLD 1  // 1 for dark, adjust as needed
#define LOWER_SM_THRESHOLD 20 // Adjust as needed
#define UPPER_SM_THRESHOLD 50 // Adjust as needed
#define LCD_ADDR 0x27  // I2C address of the LCD
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define MESSAGE_INTERVAL 20000  // 20 seconds in milliseconds

DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX for DFPlayer
DFRobotDFPlayerMini myDFPlayer;
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLUMNS, LCD_ROWS);

unsigned long lastTempTrigger = 0;
unsigned long lastHumidityTrigger = 0;
unsigned long lastSoilMoistureTrigger = 0;
unsigned long lastLightTrigger = 0;

void setup() {
  dht.begin();
  Serial.begin(9600);
  mySoftwareSerial.begin(9600);
  myDFPlayer.begin(mySoftwareSerial);

  myDFPlayer.volume(30);

  // Initialize the LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Initializing...");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Plantastic!");
  lcd.setCursor(0, 1);
  lcd.print("System Ready");
  delay(2000);
  lcd.clear();
}

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  int lightValue = digitalRead(LIGHT_SENSOR_PIN);
  int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);
  int soilMoisturePercentage = 100 - (map(soilMoistureValue, 0, 1023, 0, 100));

  if (temperature > TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(3);  // Play "Too Hot" message
    lastTempTrigger = millis();
  } else if (temperature < TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(1);  // Play "Too Cold" message
    lastTempTrigger = millis();
  }

  if (round(humidity) < HUMIDITY_THRESHOLD && millis() - lastHumidityTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(2);  // Play "Low Humidity" message
    lastHumidityTrigger = millis();
  }

  if (soilMoisturePercentage < LOWER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(6);  // Play "Thirsty" message
    lastSoilMoistureTrigger = millis();
  } else if (soilMoisturePercentage > UPPER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(5);  // Play "Enough Water" message
    lastSoilMoistureTrigger = millis();
  }

  if (lightValue == 1 && millis() - lastLightTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(4);  // Play "It's dark in here" message
    lastLightTrigger = millis();
  }

  // Update the LCD display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T: ");
  lcd.print(temperature, 2);
  lcd.print(" H: ");
  lcd.print(humidity, 2);
  lcd.setCursor(0, 1);
  lcd.print("SM: ");
  lcd.print(soilMoisturePercentage);
  lcd.print("% L: ");
  lcd.print(lightValue == LIGHT_THRESHOLD ? "Dark" : "Light");

  delay(1000);
}
```

body:
There are 2 approaches which address the problem of not playing a sound to completion.

 1. Place a delay loop after each call to myDFPlayer.play() designed to last as long as the played sound. This is likely the most straight forward solution.  However, adding delays where no other code is able to run is considered bad programming form.  It also creates problem when adding new features to the program.
 2. Create a [finite state machine][1] where the loop() function has no delays.  Instead use a variable to track the state the state machine is in and only change that variable when the conditions to go to the next state have been satisfied.  For instance, do nothing until a threshold (dryness, light, ect) has been crossed.  At which point switch to the state where you play back the associated sound & clear that threshold flag.  Do not exit that state until millis() has increased past the duration of the played sound.  Finally, repeat these state transitions for any other thresholds that have been crossed.  Complex behaviors dealing with how long before repeating a sound can then be added with additional states.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine


message:
D1 mini ESP8266 no sound on speaker

I am new to Arduino and microcontrollers, I want to make a tone with my D1 mini and a [LSM-50F][1] speaker. But I don't get any output. Any idea what I am doing wrong? Tested it with two D1 mini boards.

This is how I wired everything:
[![enter image description here][2]][2]

Specifications:

    Impedance   45 Ohm
    Power (Nominal)   0,2 W
    Power (Maximum)   0,5 W
    Resonance frequency   450 Hz

The D1 mini's GPIO pins have a maximum of 10 mA, so I am using a 330 Ohm resistor in series to the 45 Ohm speaker to avoid overloading.

    I = U/R
    I = 3.3 V / 330 Ohm + 45 Ohm
    I = 3.3 V / 375 Ohm
    I = 8.8 mA

My code:

    int Speaker = 5;

    void setup()
    {
    }

    void loop()
    {
    tone(Speaker, 450);
    delay(1000);
    noTone(Speaker);
    }

I also tried a piezo from an old computer in the same setup. Not sure if the piezo is active or passive, so I tried using:

    digitalWrite(Speaker, HIGH); // Play a tone on an active piezo.

And

    tone(Speaker, 450); // Play a tone on a passive piezo.

  [1]: https://cdn-reichelt.de/documents/datenblatt/I900/BL50A.pdf
  [2]: https://i.stack.imgur.com/bpTsJ.jpg

body:
You are plugged into D5 and have `int Speaker = 5;`
However, D5 and 5 are actually [different things](https://github.com/esp8266/Arduino/blob/3.1.2/variants/d1_mini/pins_arduino.h#L42).

```
static const uint8_t D5   = 14;
```

The plain number refers to the GPIO number of the esp8266 chip. The "D5" type numbers that are silk screened are mapped onto those. So you need `int Speaker = D5;` or alternately `int Speaker = 14; /*D5 is GPIO14*/` or you need to move the wire to the actual GPIO5 which [is labeled](https://github.com/esp8266/Arduino/blob/3.1.2/variants/d1_mini/pins_arduino.h#L38C11-L38C11) `D1`.

You may find your speaker is very quiet, maybe inaudible. If you're going to try driving a speaker from a GPIO pin the piezo is a better choice. But really it would be better to have some kind of amplification. [This](https://www.murata.com/en-us/support/faqs/sound/sounder/char/sch0001) is the sort of thing I've used with piezos before. You can test that you're affecting the pin at all with a meter. You may get a weird reading, but you should at least be able to tell the difference between that and a pin you aren't trying to use.


message:
How to handle class initialization when using brace-enclosed initializer lists

I'm working with a custom C++ library, CPSTL, for Arduino, which includes a `cpstd::vector` class that is designed to work with `cpstd::initializer_list`, `cpstd::initializer_list` is supposed to mimic `std::initializer_list`.

However, I'm having trouble initializing a `cpstd::vector` using brace-enclosed initializer lists.

I've looked up many sources online, and it seems there is not a lot of information in the topic, but came up to things such as [FastArduino: initializer list][1], and [Arduino STL: Initializer list][2]. Giving me hopes that it is actually possible. (I can't use those libraries, because they lack the build system generation tools on the library I am developing, they also lack on customizability, and also as a good learning experience)

I've tried various approaches, but I keep getting the error:

>could not convert '{0, 1, 2, 3, 4}' from 'brace-enclosed initializer list' to 'cpstd::vector<unsigned char>'.

Here's an example of the code that's causing the issue:
```c++
    cpstd::vector<unsigned char> myVector = {0, 1, 2, 3, 4};
```
I have already implemented a custom `cpstd::initializer_list` and constructor that should handle this, but the issue persists. Is there something specific to the Arduino environment that could be causing this issue?

Additional Information:

- I have verified that the `cpstd::initializer_list` is correctly defined and included in my code.

- The `cpstd::vector` class is included and accessible.

- I have reviewed my `cpstd::vector` class, and the constructor for `cpstd::initializer_list` is correctly implemented.

- While reading the error log, I noticed that `std::initializer_list` constructor has two parameters, a pointer to the data, and also a variable telling the length of the braced enclosed list, however I noticed that the list ends up casting to a single parameter, hence having no possible constructor to call

***What could be causing this issue, and how can I resolve it to initialize `cpstd::vector` using brace-enclosed initializer lists in the Arduino environment? I think the main issue is with boards that have no STL support. (i.e. AVR based boards)***

I've came to the conclusion that it will not be possible to create such constructors/operators due to compiler limitations, I think I've tried anything that came to mind. But I don't want to give up on this without knowing if there is a workaround.

**edit (removed previous code snippets for clarity, added minimal code example reproducing the error) :**

minimal sketch reproducing the error:

    #include <Arduino.h>
    #include <stddef.h>

    namespace cpstd {

      template<typename T>
      class initializer_list {
      public:
        using value_type = T;
        using reference = const T&;
        using const_reference = const T&;
        using size_type = size_t;
        using const_iterator = const T*;

      private:
        const_iterator _M_array;
        size_type _M_len;

        constexpr initializer_list(const T* array, size_type size) noexcept
          : _M_array(array), _M_len(size) {}

      public:
        constexpr initializer_list() noexcept
          : _M_array(nullptr), _M_len(0) {}

        constexpr size_type size() const noexcept {
          return _M_len;
        }
        constexpr const_iterator begin() const noexcept {
          return _M_array;
        }
        constexpr const_iterator end() const noexcept {
          return _M_array + _M_len;
        }
      };
    }

    template<typename T>
    class exampleClass{
      protected:
        T buffer[10];
        size_t len;

      public:
        exampleClass(): len(0) {}
        exampleClass(cpstd::initializer_list<T> il){
          len = il.size();
          for(size_t i = 0; i < len; i++){
            buffer[i] = *(il.begin()+i);
          }
        }

        exampleClass& operator=(cpstd::initializer_list<T> il){
          len = il.size();
          for(auto i = il.begin(); i < il.end(); i++){
            buffer[i] = *i;
          }
        }

        size_t size() const {return len;}
        T data(size_t x) const {return buffer[x];}
    };

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);

      exampleClass<uint8_t> myObject = {0,1,2,3};

      Serial.println(myObject.size());
      Serial.println(myObject.data(0));
      Serial.println(myObject.data(1));
      Serial.println(myObject.data(2));
      Serial.println(myObject.data(3));

    }

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

    }

  [1]: https://jfpoilpret.github.io/fast-arduino-lib/initializer__list_8h_source.html
  [2]: https://github.com/mike-matera/ArduinoSTL/blob/master/src/initializer_list

body:
So I have been messing around with the minimal example code and found a working solution, I'll post the solution just in case someone finds themselves having the same issue on the future, the only downside is that it feels a bit hacky to my taste, I still wonder if there is a better solution. And would gratly appreciate any feedback.

I found out that the compiler does not ackowledges the initializer_list class for braced enclosed initializers if the class is not under the namespace std.

The way I came arround this problem lies on using the preprocessor directive below:

    #if __has_include(<initializer_list>)

With this line conditional compilation takes place, and we can specify what to do whenever std::initializer_list is present or not.

- If std::initializer_list is not present an implementation is provided.
- cpstd::intitlizer_list is only a template alias of std::intitializer_list

minimal sketch with the solution:

    #include <Arduino.h>
    #include <stddef.h>

    namespace std {

      template<typename T>
      class initializer_list {
      public:
        using value_type = T;
        using reference = const T&;
        using const_reference = const T&;
        using size_type = size_t;
        using const_iterator = const T*;

      private:
        const_iterator _M_array;
        size_type _M_len;

        constexpr initializer_list(const T* array, size_type size) noexcept
          : _M_array(array), _M_len(size) {}

      public:
        constexpr initializer_list() noexcept
          : _M_array(nullptr), _M_len(0) {}

        constexpr size_type size() const noexcept {
          return _M_len;
        }
        constexpr const_iterator begin() const noexcept {
          return _M_array;
        }
        constexpr const_iterator end() const noexcept {
          return _M_array + _M_len;
        }
      };
    }

    namespace cpstd {
      template<class T>
      using initializer_list = std::initializer_list<T>;
    }

    template<typename T>
    class exampleClass{
      protected:
        T buffer[10];
        size_t len;

      public:
        exampleClass(): len(0) {}
        exampleClass(cpstd::initializer_list<T> il){
          len = il.size();
          for(size_t i = 0; i < len; i++){
            buffer[i] = *(il.begin()+i);
          }
        }

        exampleClass& operator=(cpstd::initializer_list<T> il){
          len = il.size();
          for(auto i = il.begin(); i < il.end(); i++){
            buffer[i] = *i;
          }
        }

        size_t size() const {return len;}
        T data(size_t x) const {return buffer[x];}
    };

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);

      exampleClass<uint8_t> myObject = {0,1,2,3};

      Serial.println(myObject.size());
      Serial.println(myObject.data(0));
      Serial.println(myObject.data(1));
      Serial.println(myObject.data(2));
      Serial.println(myObject.data(3));

    }

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

    }


message:
Triggering a picture with esp32-cam and GPIO13

I'm trying to trigger a picture using the GPIO13 of an esp32-cam, AI Thinker model.
I'm using that example as a base:
https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/
but instead of the PIR/Transistor combination, I'm using a press button with a pull-up resistor that pulls the GPIO13 pin down when pressed, simulating the PIR signal.
I'm feeding the esp-32 cam with a 5V power supply and the button circuit with the 3.3v
pin of the esp32, all grounded.
All hardware, SD card and so on is tested ok, I got the right voltages and I can see the GPIO13 Pin going to ground on my scope, but I just doesn't work.
Any ideas?
Edit 1: I'm using the ESP32-CAM-MB USB Board

body:
Checking the [specs of the cam board](https://docs.ai-thinker.com/en/esp32-cam), I see that `GPIO13` has the function `HS2_DATA3`, suggesting that the SD card is using that pin (which is also corroborated by [this article](https://dr-mntn.net/2021/02/using-the-sd-card-in-1-bit-mode-on-the-esp32-cam-from-ai-thinker).)

This may or may not be a problem, as the state of `GPIO13` is only relevant for sleep/wakeup when the chip is sleeping, and only relevant for SD card access when the chip is running; but there is an external addon: your pullup resistor on the button is still there when the chip is running. The PIR module from the tutorial that you're trying to replace probably has an open collector output (floating when inactive, pulled LOW when active).

My best hunch is to get rid of the pullup resistor on your button, so that the pin is floating during SD card access.

There still is the possibility that you then interfere with the SD card data when you keep the button pressed. If that is the case, you may need to put a resistor in _series_ with the button, so that the wake-up signal is weaker than the SD card data signal (start at 100KOhm and reduce until wake-up works).

If that isn't it, the question is lacking details. As you did not even post a description of what exactly "just does not work", first thing would be to produce a minimal sketch just to test sleep/wakeup via GPIO13 and post that here.


message:
"if" condition problem / question

I'm new to Arduino and my question is rather theoretical. I have an Arduino Nano board (Atmega168 processor), a button, a display. I have written a button handler that does not stop code execution. My idea is: poll the button in "loop" cycle, and if it is pressed, perform `k++`. When `k` exceeds a specified value, perform `cnt++` and print it on the display.

Code example №1 works correctly. I get 1 -> 2 -> 3 -> ...:

```
void loop() {
 if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
    }
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(cnt);
  }
}
```

Code example №2 is incorrect. I get 16 -> 27 -> 40 -> ... Seems like not `cnt` is printed, but `k`.

```
void loop() {
  if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(cnt);
    }
  }
}
```

Here's my program:

```
#include <LiquidCrystal_I2C.h>

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

void setup() {

  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);

}

void loop() {

  // button handler

}

```

My question is. Why examples №1 and №2 work differently?

body:
The timings are different.

Every operation on the LCD takes time. This:

```c++
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(cnt);
```

involves some I2C communication, and thus takes orders of magnitude more
time than `k++;`.

On the first version of your `loop()`, these operations are performed on
each iteration, while the button is being pressed. On the second
version, they are performed only when `k` reaches 20, thus twenty times
less often. The second version thus runs twenty times faster... too fast
for the LCD to correctly refresh and show all the values it is being
asked to display.

I recommend you do not rely on loop counting for controlling timings.
Instead, use the Arduino function specifically designed for time
management. For example, if you want to increment the counter every
200 ms, you should record the time when the button is pressed (the
falling edge of the signal), and increment `cnt` 200 ms later:

```c++
uint8_t previous_state;  // previous state of the button
uint32_t press_timestamp;  // time when the button was pressed

void loop() {
    uint32_t now = millis();
    uint8_t state = digitalRead(button_pd);
    if (previous_state == HIGH && state == LOW)  // falling edge
        press_timestamp = now;
    previous_state = state;
    if (state == LOW && now - press_timestamp >= 200) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }
}
```


body:
Thanks. Somehow code example №3 works correctly. I have used a library for timer and simplified code from the answer above.

```
#include <LiquidCrystal_I2C.h>
#include <millisDelay.h>       // Timer

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

//uint8_t previous_state;  // previous state of the button

millisDelay d;

void setup() {
  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);
}

void loop() {

    uint8_t state = digitalRead(button_pd);
    if (state == LOW)
        d.start(300);
    //previous_state = state;
    if (d.justFinished()) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }

}

```


message:
I would like to know why my four gear motors are rotating at different speeds when connected to 2 L293D motor drivers, controlled by the arduino

Ignore direction of the motors(for now).

This is my connection diagram. Any and all improvements to this are welcome.

Bottom left motor seems to run at 210-224 rpm
Bottom right motor runs at 160-180 rpm
Top right motor runs at 210-224 rpm
Top left motor runs at 160-180 rpm
[![enter image description here][1]][1]

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

Code for running the below setup:
```

// Motor A connections

int enA = 7;

int in1 = 4;

int in2 = 5;

// Motor B connections

int enB = 6;

int in3 = 3;

int in4 = 2;

//Motor c

int enC = 9;

int in5 = 12;

int in6 = 13;

// Motor d connections

int enD = 8;

int in7 = 10;

int in8 = 11;

void setup() {

// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enC, OUTPUT);
pinMode(enD, OUTPUT);
pinMode(in5, OUTPUT);
pinMode(in6, OUTPUT);
pinMode(in7, OUTPUT);
pinMode(in8, OUTPUT);

  // Turn off motors - Initial state
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
digitalWrite(in5, LOW);
digitalWrite(in6, LOW);
digitalWrite(in7, LOW);
digitalWrite(in8, LOW);
}

void loop() {
  moveForward();
  delay(3000);
  motorOff();
  delay(1000);
}

void moveForward(){

  analogWrite(enA, 200);
  analogWrite(enB, 200);
  analogWrite(enC, 200);
  analogWrite(enD, 200);

  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(in5, HIGH);
  digitalWrite(in6, LOW);
  digitalWrite(in7, HIGH);
  digitalWrite(in8, LOW);
}

void motorOff(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in5, LOW);
  digitalWrite(in6, LOW);
  digitalWrite(in7, LOW);
  digitalWrite(in8, LOW);
}
```
Any change to the code is also welcome.

body:
Pins 7 and 8 aren't PWM pins on the UNO.  So when you call analogWrite on them with a value greater than 127 it defaults to digitalWrite and just writes those pins HIGH.  Pins 6 and 9 are PWM pins, so they are responding as expected to the analogWrite.  Since they are outputting PWM and the signal to the other motors is constantly high, they run slower.

You should change your wiring so that all of the enable pins are connected to PWM capable pins.  On the Arduino UNO those are pins 3, 5, 6, 9, 10, and 11.


message:
Print text at any Y-value on SSD1306?

I'm attempting to print several rows of text, at certain Y-values, on an [SSD1306 128x64 LCD display][1].

I'm using the [`ssd1306` library by Alexey Dynda][2]. I initially wanted to use the more common LCD libraries out there, such as the [Adafruit SSD1306 LCD library][3], however it unfortunately does not appear I can set custom I2C pins for most such libraries out there, which is required as I'm using a custom board with an ESP32-WROOM-DA chip. The `ssd1306` by Dynda appears to be able to do so.

I have the following example code, which prints 6 lines of text:

```c++
#include "ssd1306.h"
#include "nano_gfx.h"

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

void LCDTextDraw(int x, int y, const char* text)
{
  EFontStyle fontStyle;

  ssd1306_printFixed(x, y, text, fontStyle);
}

void LCDRectDraw(int x, int y, int w, int h)
{
  ssd1306_fillRect(x, y, x + w, y + h);
}

void LCDScreenClear(bool fill)
{
  ssd1306_clearScreen();

  if (fill)
    LCDRectDraw(0, 0, 128, 64);
}

void LCDInit()
{
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_128x64_i2c_initEx(PIN_I2C_SCL, PIN_I2C_SDA, 0);
}

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

  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1");
  LCDTextDraw(30, 10, "TEST 2");
  LCDTextDraw(30, 20, "TEST 3");
  LCDTextDraw(30, 30, "TEST 4");
  LCDTextDraw(30, 40, "TEST 5");
  LCDTextDraw(30, 50, "TEST 6");
}

void loop()
{}
```

With which I wish to print out 6 lines of text, each line evenly vertically spaced out by 10 pixels.

Which produces the following output on my LCD:

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

As you can see, the text rows are not evenly vertically spaced out as I wish them to be, with a large space between the `TEST 4` and `TEST 5` strings.

After looking at the definition of the `ssd1306_printFixed` function I'm using to print out my text in the example above, it turns out that it can only print rows of text at certain fixed Y-positions:

>@warning ssd1306_printFixed() can output chars at fixed y positions: 0, 8, 16, 24, 32, etc.\
         If you specify [10,18], ssd1306_printFixed() will output text starting at [10,16] position.

Hence, I also tried using the `ssd1306_print` function (which uses a cursor to delineate its printing location on the screen), which doesn't have that warning in its header declaration. I replaced my `LCDTextDraw` function with:

```c++
void LCDTextDraw(int x, int y, const char* text)
{
  ssd1306_setCursor8(x, y);
  ssd1306_print(text);
}
```

However, that still produced the exact same output on my LCD, with the same spacing issues.

What is the proper way to print text rows at any Y-value on an LCD?

Thanks for reading my post, any guidance is appreciated.

  [1]: https://www.amazon.com/AZDelivery-Display-kompatibel-Raspberry-inklusive/dp/B074N9VLZX/ref=asc_df_B074N9VLZX/?tag=hyprod-20&linkCode=df0&hvadid=652510459651&hvpos=&hvnetw=g&hvrand=5571274269721607156&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9031168&hvtargid=pla-435201366413&psc=1
  [2]: https://github.com/lexus2k/ssd1306
  [3]: https://github.com/adafruit/Adafruit_SSD1306
  [4]: https://i.stack.imgur.com/yI4gvm.jpg

body:
Turns out using the [Adafruit SSD1306 library][1] is much easier than I first thought. One just must specify the I2C pins used with `Wire`, and pass it as reference to the `Adafruit_SSD1306` constructor. Additionally, the Adafruit library doesn't appear to have the uneven vertical spacing issue.

The equivalent code below using the Adafruit library:
```
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

Adafruit_SSD1306 LCD(128, 64, &Wire);

void LCDTextDraw(int x, int y, const char* text, byte size)
{
  LCD.setCursor(x, y);
  LCD.setTextSize(size);
  LCD.print(text);
  LCD.display();
}

void LCDRectFill(int x, int y, int w, int h, int color)
{
  LCD.fillRect(x, y, w, h, color);
}

void LCDScreenClear(bool fill)
{
  LCD.clearDisplay();
  LCD.display();
  LCD.setTextColor(WHITE, BLACK);

  if (fill)
    LCDRectFill(0, 0, 128, 64, 1);
}

void LCDInit()
{
  LCD.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

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

  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  Wire.setPins(PIN_I2C_SDA, PIN_I2C_SCL);
  Wire.begin();

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1", 1);
  LCDTextDraw(30, 10, "TEST 2", 1);
  LCDTextDraw(30, 20, "TEST 3", 1);
  LCDTextDraw(30, 30, "TEST 4", 1);
  LCDTextDraw(30, 40, "TEST 5", 1);
  LCDTextDraw(30, 50, "TEST 6", 1);
}

void loop()
{}
```

Now produces the desired result:

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

  [1]: https://github.com/adafruit/Adafruit_SSD1306
  [2]: https://i.stack.imgur.com/V76dEm.jpg


message:
Get address of a I2C transaction when multiple addresses are registered

I have an application polling 4 ADCs by I2C. The application shall also write on some ADC registers. In order to test it, I'd like to use a single Arduino UNO, enabling it for receiving I2C messages over 4 different addresses by masking the TWAMR register. In this way I can have 4 ADCs "emulated" on a single Arduino.

When the application asks for a read to Arduino at some address, I'm able to get the value of the required address by reading the TWDR register:
```cpp
void requestEvent(){
  byte addr = TWDR >> 1;
  if (0x4A == addr){ // do something }
  else if (0x4B == addr){ // do something }
  // ...
}

void setup(){
  // ...
  Wire.onRequest(requesEvent);
}
```

However, when the application requests to write something to a certain ADC (with its own address), I'm not able to get the address value in the `onReceive(int)` callback:
```cpp
void receiveEvent(int howMany){
  byte addr = TWDR >> 1; // returns the first byte AFTER the address in the I2C message
}
```

Am I doing something wrong? Is there a way to reach my goal?

Thanks.

Luca

**Edit:**

Reading the ATmega datasheet (sec. 22.9.4, p. 241), the problem with reading the TWDR register is that it contains the last byte received, that in slave receiver mode is not the address but the last data sent by the master.

Anyway, is there any workaround for this problem?

body:
Reading the TWDR register in the `onReceive()` callback doesn't give you the address because of the time, that it is called at. The `onReceive()` callback is called when all bytes have already been received and put in the `Wire` libraries internal buffer. Thus in that callback TWDR will still hold the last received data byte.

The `onRequest()` callback on the other hand is called right after the address was received. Thus TWDR still holds the received address.

You will need to modify the Wire library to achieve your goal. Similar to the `onRequest()` callback you can introduce a third kind of callback function, which will be executed after receiving the slave address to save the received address for later use (the address matching is still done via hardware, so you still need to mask the address via TWAMR).

You can find the files for the Wire library inside your used core (for me the Uno uses the path ~/.arduino15/packages/arduino/hardware/avr/1.8.5/libraries/Wire). Look at line 581 of src/utility/twi.c. This is inside the TWI ISR, the `case` clause `TW_SR_SLA_ACK`, which will be executed on address receive/match. Here you can insert your callback function.

If you want to do this in a similar handy way, that the `Wire` library does with the other callbacks, then you need to change a few other things:

1. Insert a function pointer for this at the start of the twi.c file, right besides the other function pointers:

        static void (*twi_onSlaveAddressMatch)(uint8_t);

2. Add the execution of that function to the case in the ISR described above and provide the content of TWDR (shifted to eliminate the direction bit) as a parameter:

        twi_onSlaveAddressMatch(TWDR >> 1);

3. Add a function to set the callback function pointer in twi.c:

        void twi_attachSlaveAddressMatchEvent( void (*function)(uint8_t) ){
            twi_onSlaveAddressMatch = function;
        }

4. Add the callback set function as a function prototype to twi.h:

        void twi_attachSlaveAddressMatchEvent( void (*function)(uint8_t) );

5. In Wire.h  add a function pointer for the new callback and the corresponding service function inside the `private:` section:

        static void (*user_onSlaveAddressMatch)(uint8_t);
        static void onSlaveAddressMatchService(uint8_t);

6. In Wire.h add a function to set the user callback function to the `public:` section:

        void onSlaveAddressMatch( void (*)(uint8_t) );

7. In Wire.cpp add the implementation of the service function:

        void TwoWire::onSlaveAddressMatchService(uint8_t address){
            if(!user_onSlaveAddressMatch){
                return;
            }
            user_onSlaveAddressMatch(address);
        }

8. In Wire.cpp add the implementation of the callback setter function:

        void TwoWire::onSlaveAddressMatch( void (*function)(uint8_t) ) {
            user_onSlaveAddressMatch = function;
        }

Now you should be able to set a callback for the address receive in your main code and save the address for later use:

    uint8_t received_address = 0;

    void getAddress(uint8_t address){
        received_address = address;
    }

    void setup(){
        ...
        Wire.onSlaveAddressMatch(getAddress);
    }

In the `onReceive()` callback you can then check for that global variable.

Note: I have not tested or compiled this. I just looked at the logic of the Wire library and copied the way it already defines its existing callback functions.


message:
ESP32 cannot serial monitor

I use esp32 devkit v1 .
I code follwing this picture.
[![enter image description here][1]][1]

```c++
const int vavle = 1;
int d = 1;

void setup()
{
  Serial.begin(115200);
  delay(2000);
  while (!Serial);
  Serial.println();
  pinMode(vavle,OUTPUT);
  Serial.println(d);
}

void loop()
{
  Serial.print("Open Vavle");
  digitalWrite(vavle,HIGH);
  delay(3000);
  digitalWrite(vavle,LOW);
  delay(1000);
  Serial.print("Close Vavle");
}
```

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

but serial monitor has error when use serial monitor it show me square .
I confirm select true board rate.
you can solve this problem .

body:
The GPIO1 pin you are trying to use with  `const int vavle = 1;` ... `pinMode(vavle, OUTPUT);` *is* the same pin that carries serial data to the PC.

From [the pinout](https://github.com/playelek/pinout-doit-32devkitv1/commit/afa2c642a8e63d73bce5ae93a75672a7755fe363):

[![DOIT ESP32 DEVKIT V1 PINOUT with TX0/GPIO1/U0TXD pin highlighted.][1]][1]

Their schematic link is broken, but if you find schematic for pretty much any similar board using this module you'll see GPIO1/U0TXD connected to a serial transceiver chip which is then connected to the USB port.

You need choose some other pin. There are [pin guides](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/) and [official documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html) containing the same details that you can use to figure out which GPIO to use.
GPIO numbers 16 through 33 inclusive are all output-capable and seem to have no special requirements, so they make sense to choose from.

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


message:
Can I use SPI-related pins as a Digital Output?

I am trying to use an esp32 [(NodeMCU-32s)](https://docs.ai-thinker.com/en/esp32/boards/nodemcu_32s) as a ringlight controller for my camera. All it should do is sense when an input pin goes low (the camera's output connects to ground when the shutter goes off) which is easy to detect with a simple digitalRead(). If low, then it raises 6 pins with digitalWrite() which are connected to transistors which let current flow from a 24v power supply and light up 6 banks of white LEDs. This entire setup was working great on an esp32wroom I bought from our school's shop - like I said it is very simple - but after ordering more esp32's online, I was greeted with slightly different looking ones that don't behave the same even when running the exact same code. Yes, I have verified that the pinout is the same on these two boards, although the footprint of the online boards (best datasheet I could find linked above) is one breadboard slot thinner.

#### Expected behavior:
I power it on, and nothing should happen until I connect pin 14 to ground, then the lights should turn on for a tenth of a second, then back off.

#### Actual Behavior:
I power it on, 3 banks of lights turn on rather dimmly. The other three stay off. When I connect pin 14 to ground, the three that were off turn on for a tenth of a second, then back off. While they are on, a blue light on the nodemcu-32s dev board turns on as well...

I did some digging:

On this [random nerd tutorials](https://randomnerdtutorials.com/esp32-spi-communication-arduino/) website I found code that identifies which pins are your board's default SPI pins and when I ran it, I found that 3 of the 6 pins I was currently using (pins 23, 19, and 5) are SPI-related ones. These were in fact the pins that behaved correctly (they were off until 14 was pulled low.)

I am not sure if this is related to the root cause of my issue or not, but it seems suspicious. Any tips from you wise arduino wizards would be appreciated - this was supposed to be simple!

#### Code:

Below is the code I am using. You can ignore the rgb LED stuff (LED_PIN, NUM_LEDS, BRIGHTNESS, etc.) All that matters for what I am trying to get working here are the led banks connected to pins 23, 21, 19, 5, 16, and 2. I intentionally avoided pins 6-11 because many sites were saying to avoid them.

```c
#include <Adafruit_NeoPixel.h>

#define LED_PIN 15      // Pin connected to the Data Input of WS2812B
#define NUM_LEDS 24     // Number of WS2812B LEDs in the strip
#define BRIGHTNESS 200  // Set the brightness (0-255)

#define SHUTTER_PIN 14  //Pin connected to the shutter signal of the cameras via 3.5mm jack
Adafruit_NeoPixel strip;

void setup() {
  // setup code here, to run once:
  pinMode(23, OUTPUT); // set each bank of 6 White Leds as outputs
  pinMode(21, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(2, OUTPUT);

  // set the shutterPin as a normally-high input
  pinMode(SHUTTER_PIN, INPUT_PULLUP);

  // To control rgb leds
  strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
  strip.begin();
  strip.setBrightness(BRIGHTNESS);
  strip.show();

 // Initialize all pixels to off
  digitalWrite(23, LOW);
  digitalWrite(21, LOW);
  digitalWrite(19, LOW);
  digitalWrite(5, LOW);
  digitalWrite(16, LOW);
  digitalWrite(2, LOW);
}

void loop() {
  //main code here, to run repeatedly:
  // if the shutter signal drops, flash on and off
  if (digitalRead(SHUTTER_PIN) == 0) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(16, HIGH);
    digitalWrite(2, HIGH);
    delay(500);
    digitalWrite(23, LOW);
    digitalWrite(21, LOW);
    digitalWrite(19, LOW);
    digitalWrite(5, LOW);
    digitalWrite(16, LOW);
    digitalWrite(2, LOW);
    delay(500);
  }
}
```

body:
I'm still not quite sure what's going on, but to troubleshoot this I would do the following:

- First of all, verify it's not a faulty board and try it with another one of the new ones that you've got. If that doesn't help, then do the following:
    - Move the digitalWrite-s up, above the NeoPixel initialization code. See if that helps with the start-up.
    - If that doesn't help, add pull-down resistors to the LED outputs (try 10kOhm).
    - The blue LED lights up because GPIO 2's output is connected to it, looking at the schematic on the website you've linked. You might want to switch this one to a different GPIO on the board you're using.
    - Check the transistor circuits for the LEDs that are not functioning correctly. You've not posted anything related to it, so I can't help you much there, but if you do link it we might be able to use that info.


body:
From [the schematics][1], I can see that IO2 is for the board's blue LED. So that's probably your first problem... From [this PDF][2], I see that IO21 is VSPIHD, Hold for Flash chips. No good. IO16 is HS1_DATA4, also used for the Flash chip. Also no good. You'll have to pick other pins.

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

The other issue is SIX pins supposed to deliver 3.3 volts at the same time. On a small ESP board. Not sure that's gonna happen...

  [1]: https://docs.ai-thinker.com/_media/esp32/boards/nodemcu/nodemcu_32s_sch.png
  [2]: https://docs.ai-thinker.com/_media/esp32/docs/nodemcu-32s_product_specification.pdf
  [3]: https://i.stack.imgur.com/i0mhn.jpg
  [4]: https://i.stack.imgur.com/iNxjo.jpg


message:
ATmega328 drop-in replacement with more flash memory

Is there a ATmega328 drop-in replacement with more flash memory?

Needs to be 28 pin DIL to fit the socket.

Alternatively, is there a board that has the exact dimensions and pins as an Arduino UNO, but with more flash memory?

Everything in my project works fine, but I need more program memory. Can unfortunately not use a different board layout or size.

body:
> Is there a ATmega328 drop-in replacement with more flash memory?

No

> Alternatively, is there a board that has the exact dimensions and pins as an Arduino UNO, but with more flash memory?

Yes, but it'll be probably something with ARM (UNO R4 minima has even 5V ARM), However libraries might be an issue

As for AVRs, there are for example AVR128DA28 but as far as I know, it's definitely not pin compatible.

However you could use some proto board for UNO and wire it up somehow on it.  (128kB, 28pin).

Also Atmega644/1284 (in pdip 40) could be used on proto board and it's much more compatible


message:
Arduino not reacting sometimes when reading serial commands

When I am sending hex numbers via computer to the arduino leonardo, it sometimes won't react, but the serial monitor says that it was sent. My code;
```
    void setup()
{
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(A0, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop()
{
  delay(100); // Wait for 100 millisecond(s)
  Serial.println(Serial.read());
  if (Serial.read() == 49) {
    Serial.println("left");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 50) {
    Serial.println("right");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 51) {
    Serial.println("backwards");
    analogWrite(9, 1023);
    digitalWrite(A0, LOW);
    analogWrite(10, 1023);
    digitalWrite(11, LOW);
  }
  if (Serial.read() == 52) {
    Serial.println("forwards");
    analogWrite(9, 1023);
    digitalWrite(A0, HIGH);
    analogWrite(10, 1023);
    digitalWrite(11, HIGH);
  }
  if (Serial.read() == 48) {
    Serial.println("stop");
    analogWrite(9, 0);
    digitalWrite(A0, LOW);
    analogWrite(10, 0);
    digitalWrite(11, LOW);
  }
}
```
When I send the numbers 1,2,3,4, and 0, it reads what the command does. Pins A0 and D11 are direction control for the motor controller, and pins D9 and D10 are speed.

[![it is kinda a mess.][1]][1]

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

body:
>     Serial.println(Serial.read());
>     if (Serial.read() == 49) {

You are doing two reads here, not one. So you are reading and displaying, and then reading a **second** byte (not the one you displayed).

Much better would be:

    int cmd = Serial.read();
    Serial.println(cmd);
    if (cmd == 49)  {
      ... do something ...
    } else if (cmd == 50)  {
      .. do something else ...
    }

And so on.

Also, why use numbers when you can show the ASCII characters? eg.

    int cmd = Serial.read();
    Serial.println(cmd);
    if (cmd == '1')  {
      ... do something ...
    } else if (cmd == '2')  {
      .. do something else ...
    }

You may also want to consider using:

    if (!Serial.available())
        return;

That way you don't test for serial data that does not exist.

Why the delay?


message:
How can I switch the power on/off to cut BIG currents (200A)?

Context: I have an off-grid cabin with PV powered 12V DC. I want to cut power to an inverter (12V DC ->220V AC) when I leave by pressing a button as it draws too much in standby.

Most relays I have seen that can be connected to the Arduino typically handle 10A. My inverter draws up to 180A@12V at full power (2000 W), which is way more than anything I have seen. How can I control the power to this inverter?

Someone told me of hacks that utilize the fact that you get manual switches/relays that handle big current, so you can use the Arduino to control a motor pressing the physical switch, but the concept seems somewhat brittle ... Any other takes?

```

            ┌────────────┐
            │  PV array  │
            └──────┬─────┘
                   │
             ┌─────┴───┐
             │ Charger │
           ┌─┴─────────┘
           │
           │
  ┌────────┴──┐         ┌─────────┐
  │ Batteries ├─────────┤Inverter ├────────────┐
  └────────┬──┘         └─────────┘            │
           │                                   │
           │                          ┌────────┴─────┐
           │                          │220V circuit  │
       ┌───┴───────────────┐          │  w/appliances│
Has    │ Fuse box          │          └──────────────┘
on/off │ / 12v distribution│
switch!└───────────────────┘

        ┌──────────────┐
        │12V appliances│
        └──────────────┘
```

body:
You might look for something like a "starter relay" for an engine. Those switch on 12 V and can handle currents of 150A and more. I've seen various models on the site of my favorite distributor.

**Check the data sheet to make sure the relay can handle a continuous current of 180A**, as many starter relays can only handle the current for short periods of time (you're not running the starter motor of an engine for more than a few seconds). Other possible types are 12V-industry-rated high-current relays. Also mentioned in a comment above: The hold-current of the relay shouldn't be to big, so you don't waste energy just for the switch.

You might need to use a 2-step solution, to first convert the 5V output of the Arduino to 12 V to control the relay. (use a small relay for this, or just a mosfet).


message:
Getting a strange symbol when pressing buttons in a USB keyboard connected to the Arduino GIGA R1

I am using the following code:

    #include "USBHostGiga.h"

    //REDIRECT_STDOUT_TO(Serial)
    Keyboard keyb;
    HostSerial ser;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      while (!Serial);
      pinMode(PA_15, OUTPUT);
      keyb.begin();
      ser.begin();
    }

    void loop() {
      if (keyb.available()) {
        auto _key = keyb.read();
        Serial.println(keyb.getAscii(_key));
      }
      while (ser.available()) {
        auto _char = ser.read();
        Serial.write(_char);
      }
      //delay(1);
    }

from here: https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-usb

I am using Arduino GIGA R1 on which I have connected a USB keyboard and I press buttons. I see the results on the Serial. However, I face the following problem: When I press a button, apart of the letter I get also a square next to it. For instance, let's say I press the 'A' letter. In the serial I get 'A' letter + a square symbol. When I press 'B', I get 'B' + a square symbol, etc. I am trying for 2 days to fix it, I tried to read the button as a char array with two positions and delete the [1] where the square should be, but nothing worked. The ```auto``` type is very strange in order to make a type casting, because the Arduino IDE continuously shows me error. I cannot find a way to remove the strange 'square' ASCII character which I take with each letter pressed...The only things I noticed is that the square ASCII character is displayed the time I release the keyboard button, and also it delays to appear when I increase the delay ms in the ```delay(...);``` command. Has anyone any idea how to solve this?

body:
I don't have GIGA R1, so no practical way to test this.
I also cannot explain why it's showing up as square for you. It is common behaviour for character codes that don't have a font glyph to render in that way, but the one in question (null character) does not do that for me under the 1.x 2.x IDEs.

However, the rest of what follows may help.

[According to github](https://github.com/arduino-libraries/USBHostGiga/blob//bb48eb/USBHostGiga.h#L135),
the type that is returned by `.read()` is `HID_KEYBD_Info_TypeDef`, so if you want you should be able to:

```c++
const HID_KEYBD_Info_TypeDef _key = keyb.read();
```

However, there's not much wrong with using `auto` here.  So far as I can tell, what you're [really receiving](https://github.com/arduino-libraries/USBHostGiga/blob/bb48eb72297b56063c48d465b392252224a99d67/usbh_hid_keybd.h#L283)
is the content of [Boot mode HID reports](https://wiki.osdev.org/USB_Human_Interface_Devices#Report_format).
Not *individual* key information really, but rather the state which may include up to 6 pressed keys.
If you're only pressing one key (one *non-shift state key*; as in not "shift", "control", "alt". etc,
it shows up in array index 0, which is what [getAscii](https://github.com/arduino-libraries/USBHostGiga/blob/bb48eb72297b56063c48d465b392252224a99d67/USBHostGiga.cpp#L29)
is [ultimately interpreting](https://github.com/arduino-libraries/USBHostGiga/blob/bb48eb72297b56063c48d465b392252224a99d67/usbh_hid_keybd.c#L426).

So when you release the key (all of them) you are getting a report with nothing (no key code; represented with a zero value) in `keys[0]`, and so there's nothing there from which to get an ASCII code.
What it seems to be doing is translating the 0 value that's there into [another zero](https://github.com/arduino-libraries/USBHostGiga/blob/bb48eb72297b56063c48d465b392252224a99d67/usbh_hid_keybd.c#L291).

So, it would seem all you need to do is check to see if it's a zero after the call to `getAscii`, e.g.:

```c++
if (keyb.available()) {
  const auto keyboard_input_report /*not really a key*/ = keyb.read();
  const auto first_as_ascii = keyb.getAscii(keyboard_input_report);
  //  where getAscii really means getAsciiCodeOfFirstkeyIfThereIsOneInTheReport
  if (first_as_ascii != 0) {
    Serial.println(first_as_ascii);
  }
}
```

You could to check before translation with `if (keyboard_input_report.keys[0] != 0) {`. However, the former may make more sense. Because not every key on the keyboard will map unto may onto an ASCII code value anyway.  E.g. ASCII does not represent the arrow keys, function keys, or page-up/page-down.

In any case, this code may have issues if multiple keys are pressed. It looks like doing so correctly would involve [using the internals](https://github.com/arduino-libraries/USBHostGiga/blob/bb48eb72297b56063c48d465b392252224a99d67/usbh_hid_keybd.c#L422-L426) of `getAscii` to consult the translation tables for all six of the entries in the report's `keys` array.


message:
Use class object inside an ISR

I have to simulate an ADC that behaves as an I2C slave. The simulated values that the ADC shall expose are sent over serial, saved on an attribute and are requested by a master device over I2C.

A simplified solution is the following. I have a struct `ADC` that describes the converter:
```cpp
struct ADC
{
  uint32_t register_1;
  uint32_t register_2;

  void write_register_1(uint32_t data){
    register_1 = data;
  }

  void write_register_2(uint32_t data){
    register_2 = data;
  }

  uint8_t read(){
    return register_1;
  }

  // some other methods to setup...
};
```

In `loop()`, I read the serial in order to update the `ADC::register` value and in the `onRequest` handler I eventually send the requested data by accessing `ADC::register`:
```cpp
ADC adc{};

void setup(){
  // setup adc, Wire and Serial here
  Wire.onRequest(slaveTransmitterHandler)
}

void loop(){
  if (Serial.available() > 0)
  {
     // read serial, parse received data and check them
     uint32_t data = parse_serial(); // do anything is needed to check data...

     // update adc attribute
     uint8_t oldSREG = SREG;
     noInterrupts(); // disable interrupts to update uint32
     adc.write_register_1(data);
     SREG = oldSREG;
  }
}

void slaveTransmitterHandler(){
  Wire.beginTransmission(ADDRESS);
  Wire.write(adc.read());
  Wire.endTransmission();
}

void slaveReceiverHandler(){
  uint32_t i2c_received_data;
  while (Wire.available){
    // fill i2c_received_data with Wire.read()
  }
  adc.write_register_2(i2c_received_data);
}
```

I'm not sure if I have to declare the `adc` object as `volatile` (this would mean to declare all `ADC` methods and variables as volatile). Is it safe to use an object inside the I2C handler called by the I2C interrupt?

As far as I know, it is not (I can find no reason why it should be different from non-class variables), but I have always worked with non-class variables and never with cpp objects. Also, I can't find any information about this topic.

It could be possible that I'm wrong with the whole design, even if it seems to me to be very consistent. I'm open to change it for something better, so please if this design is nonsense, comment on that! I'm here to learn :)

Thanks.

Luca

**Edit**:
Some clarification, since my question seems not to be clear enough: I'm doing HIL simulation, that is simulating the real hardware with its real interfaces with a simulated environment (that includes sensors and actuators). See [here][1] for more info.

One of my sensors measures a voltage and stores it in a register of an ADC (that has multiple registers). I'm simulating the behaviour of ADC registers in Arduino, and they shall communicate via I2C with the real hardware.

Hope this is more clear now.

  [1]: https://en.wikipedia.org/wiki/Hardware-in-the-loop_simulation

body:
If this is a simulation, and not actually using interrupts, then you hardly need to declare anything volatile. However your use of the Wire library makes it look less like a simulation. Personally I think your problem is under-explained. Please post all of your code. If you are simulating you won't need to worry about hardware interrupts. If you are using the Wire library you will.

Your other post https://arduino.stackexchange.com/questions/94677/get-address-of-a-i2c-transaction-when-multiple-addresses-are-registered seems to be relevant here.