# Question
Title: Arduino Blink two LEDs without Delay(amount of repetitions)
Arduino community. I have had experience with Arduino for 3 years now and have finally come to the conclusion to get rid of the delay function entirely.

Below is the code to blink two LEDs a complete 10 times. The problem is that the setup() doesn't repeat like a loop(), which means it doesn't last a long enough to find a time difference between PreviousMillis and CurrentMillis because it runs once; thus, defeating the idea of blinking a LED in the setup(). But, I have researched ways to imitate the loop() with while loops; I have used Adafruit's method to spice things up(Constructors and classes!), https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview.

But I need a little help because it doesn't work, instead, it blinks forever(Mission half-complete =)).

Notice how I have used while loops in the Update(), which is located within the Flasher Class, to mimic a loop() until the condition becomes true.

The problem is, I don't know why this code doesn't work and what to do from here.

The ultimate goal is to blink the LEDs at pin 12 and pin 13 a total of 10 Times, instead of repeatedly blinking for an eternity. I am using an Arduino Uno R3 and a Serial baud rate of 115200.

Ignore what I did in the loop(). It's the same function as the setup() code, instead, the led blinks an eternity (unfortunately), when a value of "1" is typed.

```
    class Flasher{
    // Class Member Variables
    // These are initialized at startup
    int ledPin;      // the number of the LED pin
    long OnTime;     // milliseconds of on-time
    long OffTime;    // milliseconds of off-time

    // These maintain the current state
    int ledState;                 // ledState used to set the LED
    unsigned long previousMillis;   // will store last time LED was updated
    unsigned long currentMillis = 0;

  public: Flasher (int pin, long on, long off)
{            // Constructor - creates a Flasher
    // and initializes the member variables and state

      ledPin = pin;
      pinMode(ledPin, OUTPUT);

      OnTime = on;
      OffTime = off;

      ledState = LOW;
      previousMillis = 0;
    }

    void Update(int a){
      // check to see if it's time to change the state of the LED
      for (int i = 0; i < a; i++) {
        while ((currentMillis - previousMillis <= OnTime) || ((currentMillis - previousMillis <= OffTime))) {
          currentMillis = millis();

          if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
          {
            ledState = LOW;  // Turn it off
            previousMillis = currentMillis;  // Remember the time
            digitalWrite(ledPin, ledState);  // Update the actual LED
          }
          else if ((ledState == LOW) && (currentMillis - previousMillis >=OffTime))
          {
            ledState = HIGH;  // turn it on
            previousMillis = currentMillis;   // Remember the time
            digitalWrite(ledPin, ledState);   // Update the actual LED
          }
        }
      }
    }
};

Flasher led1(12, 100, 400);
Flasher led2(13, 350, 350);

void setup(){

  Serial.begin(115200);
  led1.Update(10);

}

void loop(){

   /* if (Serial.available()) {
      String str = Serial.readString();

      if (str.substring(0, 1).equals("1")) {
        led1.Update(10);

      }
  }*/
}

```

# Answer
SimpleTimer and similar millis()-based timer libraries are made for just this kind of job. SimpleTimer even allows you to specify a number of repetitions as well. The gist of it is you set a timer to an interval and perhaps a number of repetitions, and a callback function to be called at the end of each interval. Your main code just calls the timer's update function, "run()" in this case, very frequently. Your callback function will be called at the appropriate times. This is one of the easiest ways to implement this kind of job, mimicking foreground/background but without the complexity of interrupts and interrupt service routines.
> 1 votes

# Answer
I've modified your sketch so that when you instantiate a LED Flasher object with a 4th argument, it flashes forever. If you instantiate a Flasher object with 3 arguments, use the `Start()` function to start the LED flashing the number of times you specify. Just call it once, not repeatedly in the `loop()` function (e.g. when a button is pressed). You can call the `Start()` function again and specify a different number of flashes. You can have multiple LED flasher objects. Each object can have different on/off times. Some LEDs can flash forever, and some the number of times specified.

**EDIT**

I've added a few functions in the class to make it more versatile: `Stop()`, `SetPinHighTime()`, `SetPinLowTime()` and `SetFlashForever()`.

```
class Flasher{

  // Class Member Variables. These are initialized at startup.
  byte ledPin;
  byte ledState;
  byte flashForever;
  unsigned int flashCounter;
  unsigned long highTime;
  unsigned long lowTime;
  unsigned long previousMillis;

  // Constructor. Create a LED Flasher object.
  // Initialize the member variables and LED state.
  public:

  Flasher(byte pin, unsigned long on, unsigned long off, byte continueFlashing = 0){
    ledPin = pin;
    pinMode(ledPin, OUTPUT);
    highTime = on;
    lowTime = off;
    ledState = LOW;
    flashForever = continueFlashing;
    previousMillis = 0;
  }

  void Update(){

    // Check to see if it's time to change the state of the LED.
    unsigned long currentMillis = millis();

    if((ledState == HIGH) && (currentMillis - previousMillis >= highTime) && ((flashCounter > 0) || (flashForever == 1))){
      ledState = LOW;
      previousMillis = currentMillis;        // Remember the time.
      digitalWrite(ledPin, ledState);        // Update the actual LED.
      if(flashCounter > 0){flashCounter--;}  // Update the flash counter.
    }
    else if((ledState == LOW) && (currentMillis - previousMillis >= lowTime) && ((flashCounter > 0) || (flashForever == 1))){
      ledState = HIGH;
      previousMillis = currentMillis;        // Remember the time.
      digitalWrite(ledPin, ledState);        // Update the actual LED.
      if(flashCounter > 0){flashCounter--;}  // Update the flash counter.
    }
  }

  void Start(unsigned int flashNumberOfTimes){
    flashCounter = flashNumberOfTimes * 2;
    flashForever = 0;
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }

  void Stop(){
    Start(0);
  }

  void SetPinHighTime(unsigned long pinHighTime){
    highTime = pinHighTime;
  }

  void SetPinLowTime(unsigned long pinLowTime){
    lowTime = pinLowTime;
  }

  void SetFlashForever(byte oneOrZero){
    flashForever = oneOrZero;
    if(oneOrZero == 0){Start(0);}
  }

  void SetPinToInput(){
    pinMode(ledPin, INPUT);
  }

};

// Used for testing purposes only.
byte doOnce = 0;
const byte led1PinNumber = 2;
const byte led2PinNumber = 3;
const byte led3PinNumber = 4;

// Instantiate LED Flasher Object(s).
// e.g. Flasher object_name(Pin Number, ON Time, OFF Time, OPTIONAL Flash Forever);

// Three argument constructor.
// The number of times to flash the LED is specified
// when you call the Start() function. The LED will NOT
// start flashing until you call Start().
Flasher led1(led1PinNumber, 10, 990);
Flasher led2(led2PinNumber, 100, 400);

// Four argument constructor.
// Flash an LED forever. This will start the LED flashing immediately.
Flasher led3(led3PinNumber, 1000, 1000, 1);

void setup(){}

void loop(){

  // Call the Update function as fast as possible.
  led1.Update();
  led2.Update();
  led3.Update();

  // Test output. Flash 3 LEDs with different on/off times.
  // Use the Start() function to flash 2 of the LEDs X number
  // of times, then restart each LED flasher object with
  // a different number of flashes. Set 1 LED to flash forever,
  // then stop it and start a different LED flashing forever,
  // altering the flash rates of one LED before restarting it.
  // Finally, set the 3 LED pins to INPUT.

  // Start the led1 object 4 seconds after Arduino startup.
  if(millis() > 4000 && millis() < 5000 && doOnce == 0){
    led1.Start(3);  // Flash the LED 3 times.
    doOnce = 1;
  }

  // Start the led2 object 5 seconds after Arduino startup.
  if(millis() > 5000 && millis() < 6000 && doOnce == 1){
    led2.Start(5);  // Flash the LED 5 times.
    doOnce = 0;
  }

  // Restart the led1 object 10 seconds after Arduino startup.
  if(millis() > 10000 && millis() < 11000 && doOnce == 0){
    led1.Start(7);  // Flash the LED 7 times.
    doOnce = 1;
  }

  // Restart the led2 object 15 seconds after Arduino startup.
  if(millis() > 15000 && millis() < 16000 && doOnce == 1){
    led2.Start(9);  // Flash the LED 9 times.
    doOnce = 0;
  }

  // Stop flashing the led3 object.
  // Start flashing the led1 object forever.
  if(millis() > 30000 && millis() < 31000 && doOnce == 0){
    led3.SetFlashForever(0);
    led1.SetFlashForever(1);
    doOnce = 1;
  }

  // Stop flashing the led1 object.
  // Start flashing the led3 object forever and change
  // it's flash rate.
  if(millis() > 50000 && millis() < 51000 && doOnce == 1){
    led3.SetPinHighTime(250);
    led3.SetPinLowTime(500);
    led3.SetFlashForever(1);
    led1.SetFlashForever(0);
    doOnce = 0;
  }

  // Stop flashing the led3 object. No LEDs should be flashing.
  if(millis() > 60000 && millis() < 61000 && doOnce == 0){
    led3.Stop();
    doOnce = 1;

    // My test shield has one High and one Low LED per pin.
    // Set the pins to input to turn off the Low LEDs.
    led1.SetPinToInput();
    led2.SetPinToInput();
    led3.SetPinToInput();
  }

}

```
> 1 votes

# Answer
For such a simple task, the code is very complex.

First, write a piece of code that blinks the LEDs if sufficient passage of time has been met.

You can implement a blink counter, either in the main loop or the blink routine mentioned earlier.

Should be fairly simple.

edit: here is how I would have implemented it.

```
//blink the led for a given number of times
//cnt: number of times of the blinks needed
uint8_t led_blinky(uint8_t cnt) {
    static uint8_t led_cnt=0;       //blinky count
    static uint32_t millis_prev=0;  //previous millies

    if (led_cnt>=cnt) return led_cnt;   //return blink count
    if (millis() > millis_prev + LED_ms) {    //enough time has passed
        millis_prev += LED_ms;                      //update the time
        digitalWrite(LED, (digitalRead(LED)==HIGH)?LOW:HIGH);       //flip led
        led_cnt+=1;                 //increment the led count
    }
    return led_cnt;                 //return blinky count
}

```

the code itself is fairly self-explanatory -\> the only (marginally) tricky part is how it maintains timing accuracy over a long period of time. in this particular implementation, the test is done inside the led\_blinky() routine so it is self-contained -\> it does return the number of blinks that have been executed.

Here is the execution of performing 100ms blinks 4 times:
> 0 votes

# Answer
I'd like to proposes a couple of changes to @VE7JRO's implementation.

For C++, it is perfectly normal to initialise an Class instance via its construct, however, for Arduino, the `setup()` get call in Arduino main() after some initialisation of the hardware, including pin definition, etc., it is why Arduino advocates in Arduino Style Guide for Writing Libraries to use a `begin()` to initialize a library instance (it is perfectly okay to use the construct to setup some variables but not for something like `pinMode()` in the construct). Because very often the creating of a Class instance happened before the `setup()` get called.

With this in mind, the propose changes:

```
class Flasher{

  // Class Member Variables. These are initialized at begin().
  byte ledPin;
  byte ledState;
  byte flashForever;
  unsigned int flashCounter;
  unsigned long highTime;
  unsigned long lowTime;
  unsigned long previousMillis;

  public:

  Flasher() {}

  begin(byte pin, unsigned long on, unsigned long off, byte continueFlashing = 0){
    ledPin = pin;
    pinMode(ledPin, OUTPUT);
    highTime = on;
    lowTime = off;
    ledState = LOW;
    flashForever = continueFlashing;
    previousMillis = 0;
  }
  ....
};

```

To use the Class:

```
Flasher led1;
Flasher led2;
Flasher led3;

setup() {
  led1.begin(led1PinNumber, 10, 990);
  led2.begin(led2PinNumber, 100, 400);
  led3.begin(led3PinNumber, 1000, 1000, 1);
}

```

Another change has to do how C++ defined `inline` function or method. **"A class's member functions can be declared inline, either by using the inline keyword or by placing the function definition within the class definition"**. What this means is that all the functions defined in the `Flasher` class in this case are implied as `inline` methods. so when `led.update()` get call, it is placed as inline code by the compiler at where it get call (and multiple times). There are certain methods that are perfectly okay and in fact should be `inline`, for example, `SetPinHighTime()`, and `SetPinToInput()` would actually benefit from being `inline`, but you will probable don't want the `update()` method to be `inline`. In order to do that, create a Class prototype and have the methods that you'd want to be inlined implemented within the Class definition, but separate the implementation of `update()` method.

```
#ifndef FLASHER_
#define FLASHER_
#include "Arduino.h"

class Flasher{

  // Class Member Variables. These are initialized at startup.
  byte ledPin;
  byte ledState;
  byte flashForever;
  unsigned int flashCounter;
  unsigned long highTime;
  unsigned long lowTime;
  unsigned long previousMillis;

  public:

  // All methods are inline, except update()

  Flasher() {}
  void begin(byte pin, unsigned long on, unsigned long off, byte continueFlashing = 0){
    ledPin = pin;
    pinMode(ledPin, OUTPUT);
    highTime = on;
    lowTime = off;
    ledState = LOW;
    flashForever = continueFlashing;
    previousMillis = 0;
  }

  void Update();

  void Start(unsigned int flashNumberOfTimes){
    flashCounter = flashNumberOfTimes * 2;
    flashForever = 0;
    ledState = LOW;
    digitalWrite(ledPin, ledState);
  }

  void Stop(){ Start(0); }

  void SetPinHighTime(unsigned long pinHighTime){
    highTime = pinHighTime;
  }

  void SetPinLowTime(unsigned long pinLowTime){
    lowTime = pinLowTime;
  }

  void SetFlashForever(byte oneOrZero){
    flashForever = oneOrZero;
    if(oneOrZero == 0){Start(0);}
  }

  void SetPinToInput(){ pinMode(ledPin, INPUT); }

};
#endif

```

Define `update()` method separately in implementation `Flasher.cpp`:

```
#include "Flasher.h"

Flasher::update() {

    // Check to see if it's time to change the state of the LED.
    unsigned long currentMillis = millis();

    if((ledState == HIGH) && (currentMillis - previousMillis >= highTime) && ((flashCounter > 0) || (flashForever == 1))){
      ledState = LOW;
      previousMillis = currentMillis;        // Remember the time.
      digitalWrite(ledPin, ledState);        // Update the actual LED.
      if(flashCounter > 0){flashCounter--;}  // Update the flash counter.
    }
    else if((ledState == LOW) && (currentMillis - previousMillis >= lowTime) && ((flashCounter > 0) || (flashForever == 1))){
      ledState = HIGH;
      previousMillis = currentMillis;        // Remember the time.
      digitalWrite(ledPin, ledState);        // Update the actual LED.
      if(flashCounter > 0){flashCounter--;}  // Update the flash counter.
}

```

I hope this will help to make the class better and better understanding on C++ and Arduino, and next time when you read the source of an Arduino library, you had better understanding on why the library implement its class and methods the way it does.
> -1 votes

---
Tags: arduino-uno, code-optimization, millis, timing
---


# Question
Title: Arduino Nano: MAX30102 and memory problems
We are making a simple pulse oximeter device with an Arduino Nano and a MAX30102 sensor.

The problem is the SpO2 reading and processing algorithm of the MAX30102 library literally does signal processing on the Arduino with large arrays of data and because of that, when you do BPM and SpO2, the 2kb memory of the Arduino is already full.

Can you guys give me some advice to overcome this problem?

# Answer
> 0 votes
Arduino UNO is not recommended for MAX30102 as it requires a lot of processing and RAM. Consider shifting to Arduino Mega or the ESP32.

---
Tags: arduino-nano, sensors
---


# Question
Title: MAX30102 showing Heart rate: 0.00bpm / SpO2: 0%
I am using a MAX30102 to monitor SpO2 and heart rate using the https://github.com/oxullo/Arduino-MAX30100 library and the minimal example, but it is not showing any value change.

It only shows zero and in the library tester example it is also showing a timeout error for die temperature.

I removed all 3 pull up registers and given 5 v supply.

Please help to get correct result; I will be thankful.

# Answer
To identify the issue, run I2C Scanner and check the address of this module on the Serial Monitor.

If the I2C Scanner program is not able to detect the module, then either the module is defective or connections are wrong.

If the I2C Scanner program is able to identify the sensor, then check with other libraries.
> 1 votes

---
Tags: arduino-uno, sensors, i2c
---


title: Help with millis to get accurate timing

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

```
    #include <Servo.h>

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

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

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

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

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

   NOTE_A4, NOTE_A4,

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

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

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

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

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

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

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

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

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

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

  250, 125,

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

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

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

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

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

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

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

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

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

void loop(){

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

  if (sweep == 0)
  {

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

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

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

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

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

  if (sweep == 1)
  {

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

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

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

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

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

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

```

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

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

int pos = 0;
int dir = 1;

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

void loop(){

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

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

        currentMillis = millis();

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

```
> 1 votes

---
Tags: time, millis, analogwrite, timing
---


# Question
Title: UNO's Internal EEPROM "read" returns incorrect values when it precedes "write"
I am an Arduino instructor and I was preparing some material on the utilization of the Arduino UNO's internal EEPROM when I encountered a problem. The problem is, I am trying to show the original value on a specific EEPROM location using the EEPROM.read function, then I do write a new value to that location using the EEPROM.write function and try reading it again, please take a look at its code, I use the Serial Monitor to print those values.

```
#include <EEPROM.h>

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

  // Print to the Serial Monitor the value read from address 20. "Which should be 255"
  Serial.println(EEPROM.read(20));
  // Write to the EEPROM the value 143 in address 20.
  EEPROM.write(20, 143);
  // Print to the Serial Monitor the value read from address 20. "Which should be 143"
  Serial.println(EEPROM.read(20));
}

void loop() {

}

```

Now I have verified already that this location has a value of 255 using another sketch which basically does nothing but print the contents of the EEPROM on the Serial Monitor.

```
#include <EEPROM.h>

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

  for(int i = 0; i < 1024;i++)
  {
    Serial.print("Address: ");
    Serial.print(i);
    Serial.print(", Value: ");
    Serial.println(EEPROM.read(i));
  }

}

void loop() {

}

```

Now what is my problem? My problem is in my first sketch, the EEPROM.read function does not return 255, instead it returns the value 143 which is not even supposed to be there until the next instruction. I know the EEPROM.write takes around 3.3ms and the writing is what wears down the EEPROM cell, but I also do know that reading takes approximately 0ms and does not wear down the EEPROM cell. Even though that in mind, I have deliberately placed a "delay(100);" after reading, still no result.

```
#include <EEPROM.h>

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

  // Print to the Serial Monitor the value read from address 20. "Which should be 255"
  Serial.println(EEPROM.read(20));
  delay(100);
  // Write to the EEPROM the value 143 in address 20.
  EEPROM.write(20, 143);
  // Print to the Serial Monitor the value read from address 20. "Which should be 143"
  Serial.println(EEPROM.read(20));
}

void loop() {

}

```

Further more, when I remove the EEPROM.write completely from the code and utilize the EEPROM.read only, I do read correct results, but of-course I do change the address as well to test it.

My setup is: Windows 10 Pro 64-bit. Arduino IDE 1.8.15 Arduino UNO china clone version. (not SMD)

My question is, what am I doing wrong here? Do I have an invalid understanding of something around here? I have worked with EEPROMs before (both internal and external) using PIC18F microcontrollers, so my experience (which may be incorrect) yields that this sketch should work perfectly.

Thank you in advance.

# Answer
> 3 votes
This is NOT my answer, this is the answer of @Gerben, thank you.

The Arduino IDE suspends the serial connection while uploading, and then resumes when done. It looks like they added some delay before reopening the serial connection. So it looks like your code will run twice, even when you keep the Serial Console open

# Answer
> -1 votes
Per the documentation at:https://www.arduino.cc/en/Reference/EEPROMWrite An EEPROM write takes 3.3 ms to complete. What tells us is you must give it that amount of time or more to complete the operation. Insert your delay after "EEPROM.write(20, 143);" of at least 3.3 ms or delay(3300);. That should resolve your problem. You can also use that to have your students read the manual. Present as a problem so they can try to solve it. Once you get caught by it (we all have) you never forget.

---
Tags: arduino-uno, arduino-ide, eeprom
---


# Question
Title: Send only one packet from one ESP32 to another ESP32 without acknowledgment
I have a network consisting 10 slaves and one master. I am using ESP-NOW to send the messages between the nodes. All of the nodes are within close proximity. I do NOT need a mesh network to reach all the nodes.

ESP-NOW works amazing. It is simple to use and the library is easy to understand. **But in this project esp-now is not working for me and here is why:**

1. If the 10 slaves want to send data at the same time it does not work. With 10 nodes they can send data every 200ms. If I lower the time some nodes even crash and restart.
2. Because all nodes cannot send data at the same time I am having the master ping each node to synchronize who can send a message. The moment a slave receives a message it can reply back.
3. If one slave node sends data to the wrong peer for some reason the web server of the master node stops working. It freezes until that node is done sending data.
4. If I send a broadcast message all the nodes reply. **How can I configure esp-now so that no acknowledgment is sent back?**
5. With esp-now when you send a packet the destination node always replies with a confirmation. I want to send that confirmation once the job that the slave had to perform worked. Because I am planing to work with a lot of nodes with close proximity I want to reduce network traffic. Moreover, on esp-now if a packet is not delivered it attempts again increasing the network traffic. I only want to resend packets that are important in order to reduce network traffic.
6. esp-now limits the number of nodes you can have specially if you encrypt the messages.

**So my question is:** is there a way to instruct esp-now to NOT send an acknowledgment? Can I instruct esp-now to only send one packet regardless if it failed or not? On the NRF24L01 you can set this value with the method `setRetries`. I just want something like UDP where it is a fire and forget. I cannot use UDP because I do not want to be connected to a WiFi network.

It will be great if I could have 2 methods. One for sending a simple raw packet and another for reading those packets on another esp32. I know I will be having to do a lot of filtering on the receiving side.

---

## Edit

---

## Here is a solution that works but needs improvement

It is possible to send raw packets with the function `esp_wifi_80211_tx`. But still esp32 sends 5 packets when using that function! Moreover, in order to use that function you must send a wifi beacon with whatever data you want. The minimum size of a beacon packet I believe is 128 bytes. So this is a solution but not a good one.

Anyways I bellow is the code for the transmitter esp32 and the receiver esp32. The transmitter code has to be compiled with the ESP-IDF framework and NOT arduino. If I use arduino framework it compiles fine (replace main function with setup) but it does not work once I upload it to the esp32. The receiver code I compiled it using the arduino IDE.

**transmitter code (tx)**

```
#include <stdio.h>

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_event_loop.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_wifi.h"

#include "nvs_flash.h"
#include "string.h"

// pin used to flash led
#define PIN GPIO_NUM_2

/*
 * This is the (currently unofficial) 802.11 raw frame TX API,
 * defined in esp32-wifi-lib's libnet80211.a/ieee80211_output.o
 *
 * This declaration is all you need for using esp_wifi_80211_tx in your own application.
 */
esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq);

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    return ESP_OK;
}

void send_raw_packet_task(void *pvParameter)
{

    for (;;)
    {
        uint8_t dataToSend[] = { 0 } ;

        esp_wifi_80211_tx(WIFI_IF_AP, dataToSend, sizeof(dataToSend) , false);

        // turn on and off led AND wait 10 seconds
        gpio_pad_select_gpio(PIN);
        gpio_set_direction(PIN, GPIO_MODE_OUTPUT);
        gpio_set_level(PIN, 1);
        vTaskDelay(9500 / portTICK_PERIOD_MS);
        gpio_set_level(PIN, 0);
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}

extern "C" void app_main(void)
{
    nvs_flash_init();
    tcpip_adapter_init();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));

    // Init dummy AP to specify a channel and get WiFi hardware into
    // a mode where we can send the actual fake beacon frames.
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    wifi_config_t ap_config;

    // SSID = TTTT (4 times the letter t in uppercase)
    wifi_ap_config_t x;
    x.ssid[0] = 84; x.ssid[1] = 84; x.ssid[2] = 84; x.ssid[3] = 84;
    x.ssid[4] = 0;
    x.ssid_len = 4;

    //x.password = "dummypassword"; // for some reason this does not compile
    x.password[0] = 84; x.password[1] = 84; x.password[2] = 84; x.password[3] = 84; x.password[4] = 84; x.password[5] = 84; x.password[6] = 84; x.password[7] = 84;
    x.password[8] = 0;

    x.channel = 1;
    x.authmode = WIFI_AUTH_OPEN;
    x.ssid_hidden = 0;
    x.max_connection = 4;
    x.beacon_interval = 60000;
    ap_config.ap = x;

    //ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
    auto res = esp_wifi_set_config(WIFI_IF_AP, &ap_config);
    if (res == ESP_OK)
    {
        printf("set esp_wifi_set_config. It worked!\n");
    }
    else
    {
        printf("It did NOT worked :/\n");
        return;
    }

    // ESP_ERROR_CHECK(esp_wifi_start());
    res = esp_wifi_start();
    if (res == ESP_OK)
    {
        printf("wifi started! It worked!\n");
    }
    else
    {
        printf("It did NOT worked :/\n");
        return;
    }

    // ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
    wifi_ps_type_t t = WIFI_PS_NONE;
    res = esp_wifi_set_ps(t);
    if (res == ESP_OK)
    {
        printf("wifi set to WIFI_PS_NONE! It worked!\n");
    }
    else
    {
        printf("It did NOT worked :/\n");
        return;
    }

    res = esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
    if (res == ESP_OK)
    {
        printf("wifi set channel to 1! It worked!\n");
    }
    else
    {
        printf("It did NOT worked :/\n");
        return;
    }

    // output size of bytes that we will be sending
    printf("*** Size of configuration is %i bytes. Starting task send_raw_packet_task...", (int)sizeof(ap_config));
    xTaskCreate(&send_raw_packet_task, "send_raw_packet_task", 2048, NULL, 5, NULL);
}

```

**receiver code (rx)**

```
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"

uint8_t channel = 1;

static void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type);
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) {

    // in here esp32 will capture all wifi traffic

    auto t = (unsigned char*)buff;

    // create flag to see if packet contains "TTT"
    bool containsX = false;

    // index where the first T is located on the buffer in case it is found
    int indexWhereNameOfSsidWasFound = 0;

    // look to see if its a packet of interest
    for (int i = 45; i < 100; i++)
    {
        if (t[i] == 84 && t[i + 1] == 84 && t[i + 2] == 84)
        {
            containsX = true;

            indexWhereNameOfSsidWasFound = i;
            Serial.println(i);

            break;
        }
    }

    if (containsX == false)
        return;

    // print SSID if found
    for (int i = indexWhereNameOfSsidWasFound; i < indexWhereNameOfSsidWasFound + 20; i++)
    {
        Serial.print((int)t[i]);
        Serial.print(" ");
    }
    Serial.println();

}

esp_err_t event_handler(void* ctx, system_event_t* event)
{
    return ESP_OK;
}

// the setup function runs once when you press reset or power the board
void setup() {

    Serial.begin(115200);

    // delay 2 seconds so that esp32 initializes
    Serial.println("Starting...");
    vTaskDelay(2000 / portTICK_PERIOD_MS);

    // init wifi sniffer
    {
        // order of initializations matter!

        wifi_country_t wifi_country = { .cc = "IT", .schan = 1, .nchan = 13 }; // Most recent esp32 library struct

        nvs_flash_init();
        tcpip_adapter_init();

        ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));
        ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country)); /* set country for channel range [1, 13] */
        ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
        ESP_ERROR_CHECK(esp_wifi_start());

        // turn on promiscuous to capture everything
        esp_wifi_set_promiscuous(true);
        esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler);

        // listen on channel 1
        esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
    }
}

void loop() {
    // empty
}

```

So basically the receiver code is listening for all network trafic in promiscuous mode. Kind of like wireshark. If it sees a packet that contains the string "TTTT" it will output it.

Because there is so much wifi traffic this is way slower than esp-now. I could not figure out how to send smaller packets. Lastly when sending a packet it takes about 2 second to capture the packet. I belive esp32 stores all those packets on a queue and then latter calls the call back function.

I guess I will go back on using esp-now. **Can I modify the source code of esp-now?** I just want want to remove the part where it send the packet multiple times and also the part where it replies with an acknowledgment.

# Answer
> 2 votes
I surmise that the esp32 'raw' tx isn't really that, based on the restrictions on what can be sent (data, but not QoS data, for example.)

I think that among the 5 packets you report seeing are 1.RTS, 2. CTS, 3. DATA, 4. ACK. These (at least 1,2) are necessary to avoid collision.

ESPNow sends a vendor-specific packet which doesn't (I surmise) require or follow the CTS/RTS or ACK 802.11 conventions.

Point to Point ESPNow, however, is written to expect a packet acknowledgement from the receiver, and will resend for a certain number of times until it receives one.

Broadcast ESPNow does not expect, and in fact cannot automatically receive, one of these ESPNow-specific acknowledgements.

If you need the fastest, least reliable 802.11 packet transmission, I would advise to use Broadcast ESPNow.

Having said that, you must be aware that you will not get the full collision-avoidance protections of more usual 802.11 protocol usage. You may need to provide your own ... such as listen-before-send, random exponential backoff, and who knows what else.

Seems to me that you are embarking on a wilderness adventure :)

---
Tags: c++, wifi, esp32, network
---


# Question
Title: Hello, Please can someone assist me with in checking my code?..I try to generate a high freq signal (at least 150KHz) with Arduino Mega, CTC Mode
```
void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  TCCR2A = TCCR2A & B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A
  TCCR2B = TCCR2B & B11110000 | B00000001;//Prescaller set
  TCNT2=0;//Start Counting ffrom 0
  OCR2A=127;//Set TOP value)

}

void loop() {

}

```

# Answer
> 4 votes
```
TCCR2A = TCCR2A & B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A

```

What you have here clears `TCCR2A`'s `COM2A1` but preserves its original `COM2A0`.

When I print out `TCCR2A` prior to modification, I see a value of `0x01` (COM2A is 0; both bits of it).

Printing out `TCCR2A` after you've manipulated it 0x02. So, in `TCCR2A`, you are winding up with zeros for your `COM2A1` and `COM2A0` bits, which is all cases is "Normal port operation; OC2A disconnected". That is, you're not going to see whatever signal you might otherwise have configured to generate because it just hasn't been routed to the (Arduino pin 10)/(gpio PB4)/OC2A

It's usually better to not rely on the bootloader and the start code and the Arduino core to have left a hardware register in a particular state.

The following is probably closer to what you intended:

```
TCCR2A = B01010000 | B00000010 ; // CTC mode activated, Toggle OC2A

```

It's still not entirely correct to the problem description (not the correct frequency), but it does send a signal out of the Arduino MEGA's digital pin 10. It also is configured to toggle OC2B, so unless you wanted that:

```
TCCR2A = B01000000 | B00000010 ; // CTC mode activated, Toggle OC2A

```

This can be made more readable by using the bit field names for the given:

```
TCCR2A =
      (1 << COM2A0)  // CTC mode activated (note COM2A1 is zero)
    | (2 <<  WGM20); // lower two bits of WGM value 2

```

You can do this same sort of thing for `TCCR2B`. And likewise, it is best that you don't rely on the previous value of `TCCR2B`.

With `OCR2A = 127;`, you are toggling (reaching a **half**-period) every 128/16,000,000 seconds, or a 8 uS half-period, for a 16 uS period. Generating 62.5 KHz, which is below your target 150 KHz. Knowing it's half-periods, an `OCR2A` of 63 gets you to 125 KHz.

An `OCR2A` of 52 or less gets you into the greater than 150 kHz range, at least if we take your 16 MHz clock rate very seriously. You might need to be a little lower to be sure.

---
Tags: arduino-mega
---


# Question
Title: Modifying the neopixel rainbow function to work with 4pins
So my setup is i have strips that is separated into 4 pins and would like to modify this rainbow function from the neopixel so that it will work on 4 separate strip that are on 4 separate pins. I would like to look like strip number 2 is a continuation of strip number 1 and number 3 is to 2 and number 4 is to 3. A very cool feature about this function is the start and end is a continuation so this mean i basically have a ring setup.

```
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

```

I do not understand how hue and gamma works so it a bit more tricky for me to modify this function.

Here is my attempt but my attempt is so crude and hoggs so much memory

```
void rainbow(int wait) {

  unsigned int totalPixelCount = strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip4.numPixels();
  uint32_t pixelHueList [totalPixelCount];
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
    for (int i = 0; i < totalPixelCount; i++) {
      int pixelHue = firstPixelHue + (i * 65536L / totalPixelCount);
      pixelHueList[i] = strip1.gamma32(strip1.ColorHSV(pixelHue));
    }

    unsigned int j = 0;
    for (j = j; j < strip1.numPixels(); j++)
      strip1.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels(); j++)
      strip2.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels(); j++)
      strip3.setPixelColor(j,pixelHueList[j]);
    for (j = j; j < strip1.numPixels() + strip2.numPixels() + strip3.numPixels() + strip3.numPixels(); j++)
      strip3.setPixelColor(j,pixelHueList[j]);

    strip1.show();
    strip2.show();
    strip3.show();
    strip4.show();
    delay(wait);
  }
}

```

Is there a way to make it more efficient?

# Answer
> 2 votes
Currently you are first filling an array with values from a calcuation by going through all LEDs; and then you are again going through all LEDs to actually set them. You can do that in one step. Also your current code will most likely not work, since you just count from zero to the total number of LEDs, but the individual strip doesn't know of that much LEDs. That will get you in problems with everything after the first for loop where you set the LEDs.

For doing it in one step and simultaneously solve the problem:

```
void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536L; firstPixelHue += 256) {
    int j = 0;
    for (int i = 0; i < strip1.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip1.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j = strip1.numPixels();
    for (int i = 0; i < strip2.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip2.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j += strip2.numPixels();
    for (int i = 0; i < strip3.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }
    j += strip3.numPixels();
    for (int i = 0; i < strip4.numPixels(); i++){
      int pixelHue = firstPixelHue + ((j+i) * 65536L / totalPixelCount);
      strip3.setPixelColor(i,strip1.gamma32(strip1.ColorHSV(pixelHue)));
    }

    strip1.show();
    strip2.show();
    strip3.show();
    strip4.show();
    delay(wait);
  }
}

```

Here I used `j` as an index over the whole chain of LED strips and `i` as an index for the individual LED strip. So `j` is the index starting point of each strip. The calcuation of the hue is then done with the current total index (`j` as the offset of the current strip in the whole chain and `i` as the index of the current LED in the current strip) `j+i`. For actually setting the corresponding LED we use `i` as the index of the current LED in the current strip.

This solution eliminates the need for creating an additional array. Though it still can be optimized (mostly in terms of code structure). I will leave that to you if you really want to optimize further.

Note: I haven't tested the above code, nor did I compile it.

---
Tags: neopixel
---


# Question
Title: what is the maximum number of servo motors that can be connected to a l293d motor shield?
I have a requirement in which I need to run 2 motors and 6 servos. The motors and servos won't be running simultaneously at any given time. what best can I use. I Was hoping to use l293d shield as it powers 2 DC motors and 2 servos, but how do I get other 4 running too ?

I'm aware that l293d shield has 2 free pins pin2 and pin13 that I leverage for signal pins for servo. (am I right in this ?, if so, i'll still need 2 more free pins for signal)

# Answer
> 1 votes
As to the PDF Guide on page 19:

> How can I connect to the unused pins?
>
> The analog pins (analog 0-5 also known as digital pins 14-19) are broken out in the bottom right corner.
>
> Pin 2 has a small breakout since its the only truly unused pin
>
> The remaining pins are not broken out because they could be used by the motor shield. If you are sure that you are not using those pins then you can connect to them by using stacking headers when assembling the kit or soldering onto the top of the header with wires, or using a "Wing shield"

So you should have access to pins A0 to A5 (enough for 6 servos). You might need to solder a pin header in that place before you can actually use them.

The wording "Pin 2 \[...\] the only truly unused pin" is a bit weird, but if you follow the link to the schematics repo and look at mshieldv12schem.png (which seems to be the schematic just as an image, so you don't need to install Eagle for viewing it) it shows the Arduinos pins A0 to A5 only connected to the pin header and nothing else. This tells me that they are actually free.

---
Tags: arduino-uno, servo, l293d
---


title: How to change brightness of LED light?

text:
# Question
Title: How to change brightness of LED light?
I'm trying to change the brightness of an LED light with RGB. I can change the brightness of simple colors like red, green, and blue. But I'm not sure how to change brightness of colors like purple, turquoise, and yellow green.

When it comes to adjusting the brightness of red, green, and blue. I have tried changing the values inside colorRGB().

With colorRGB():

```
int redPin = 9;
int greenPin = 10;
int bluePin = 11;

void setup(){
    pinMode(redPin, OUTPUT);
    delay(500);
    pinMode(greenPin, OUTPUT);
    delay(500);
    pinMode(bluePin, OUTPUT);
    delay(500);
}
void loop(){
    colorRGB(255, 0, 0); //Brightness level 255
    colorRGB(150, 0, 0); //Brightness level 150
    colorRGB(50, 0, 0); //Brightness level 50
}
void colorRGB(int red, int green, int blue){
    analogWrite(redPin, red);
    analogWrite(greenPin, green);
    analogWrite(bluePin, blue);
}

```

I have also tried using analogWrite(), however it needs the pin as one of its arguments so I'm not quite sure how to connect that with the already set up colors inside void loop(){}.

# Answer
> 2 votes
To change the brightness of any RGB color you need to multiply each color component by the brightness ratio. Lets look at some examples:

* Red is `255,0,0` in RGB. Full brightness is represented by 1, half brightness by 0.5, quarter brightness by 0.25 and so on. So we get the following values (we are doing integer calculations, so cutting away any decimal digits):
    + half brightness: `255*0.5,0*0.5,0*0.5` --\> `127,0,0`
    + quarter brightness: `255*0.25,0*0.25,0*0.25` --\> `63,0,0`
* Yellow is the combination of red and green, so `255,255,0`. Doing the same math as above we get:
    + half brightness: `255*0.5,255*0.5,0*0.5` --\> `127,127,0`
    + quarter brightness: `255*0.25,255*0.25,0*0.25` --\> `63,63,0`
* Cyan is the combination of red green and half blue, so `255,255,127`. Doing the same math as above we get:
    + half brightness: `255*0.5,255*0.5,127*0.5` --\> `127,127,63`
    + quarter brightness: `255*0.25,255*0.25,127*0.25` --\> `63,63,31`

So you can change your function to include a brightness parameter:

```
void colorRGB(int red, int green, int blue, int brightness_percent){
    analogWrite(redPin, red*brightness_percent/100);
    analogWrite(greenPin, green*brightness_percent/100);
    analogWrite(bluePin, blue*brightness_percent/100);
}

```

Here I used not the value range from 0 to 1 but instead in percent from 0 to 100. This is because floating point operations on Arduinos are rather time intensive (because the Arduino has no hardware for that and needs to do all that in software) so its better to multiply by the percent value and then divide by 100. So we have only integer calculations which is way faster. The outcome is the same.

Note: As the the color components get in the lower values you might see color errors due to the quantification. Though normally RGB LEDs aren't really color accurate either so probably you won't notice.

# Answer
> 1 votes
I just created a simple simulation for the nice answer written. Here is the code:

```
int redPin = 9;
int greenPin = 10;
int bluePin = 11;

void setup() {
  pinMode(redPin, OUTPUT);
  delay(500);
  pinMode(greenPin, OUTPUT);
  delay(500);
  pinMode(bluePin, OUTPUT);
  delay(500);
}
void loop() {
  colorRGB(255, 0, 0, 100); //Brightness level 100%
  delay(3000);
  colorRGB(255, 0, 0, 25); //Brightness level 25%
  delay(3000);

  colorRGB(255, 255, 0, 100); //Brightness level 100%
  delay(3000);
  colorRGB(255, 255, 0, 25); //Brightness level 25%
  delay(3000);

  colorRGB(255, 255, 127, 100); //Brightness level 100%
  delay(3000);
  colorRGB(255, 255, 127, 25); //Brightness level 25%
  delay(3000);
}
void colorRGB(int red, int green, int blue, int brightness_percent) {
  analogWrite(redPin, red * brightness_percent / 100);
  analogWrite(greenPin, green * brightness_percent / 100);
  analogWrite(bluePin, blue * brightness_percent / 100);

}

```

i hope this is helpful. I am from the Wokwi team and I will welcome all your questions. You can have a look at the Wokwi Arduino simulation link here:

https://wokwi.com/arduino/projects/313797447551812161

---
Tags: arduino-uno, led, rgb-led
---


# Question
Title: In which package file is a default programmer selected?
After a clean IDE install, the programmer submenu already has a default option selected as shown below:

I am working on creating a core package and would like a default programmer to be selected after choosing a board, though I'm not sure which file sets the default. For example, here is a different 3rd party package that does *not* select a default programmer when a board is chosen.

# Answer
The default preferences.txt file in IDE installation has this setting. It is not read from the boards package configuration files.

The `programmer` key in preferences.txt contains the last selected programmer. The default preferences.txt in lib folder in IDE installation has `programmer = arduino:avrispmkii`. It is used if preferences.txt in Arduino15 folder doesn't exist or doesn't have the specific key.

With the recent change in Arduino IDE only programmers from boards package of the selected board are displayed, so it happens that no programmer is selected.
> 1 votes

---
Tags: arduino-ide, core-libraries, installation
---


title: Libraries are not linked

text:
# Question
Title: Libraries are not linked
I created 4 libraries, each in .h and .cpp files, and tested them individually. I kept the project flexibility by defining 3 flags that allow or disallow the usage of the libraries.

When integrating them into project I received linking errors. During the debugging I reduced it to minimum - a single .ino file that contains the minimal declarations and calls; but the error messages are still fired.

I looked at the shrunk code (only 63 lines!) and saw no issue. I'd appreciate any help in finding the issue.

The code:

```
#define RadioIncluded
#define IrrigationStation
#define RTCincluded

/********************************************/

#ifdef RTCincluded
  class rtcHighLevel
  {
    public:
      String rtcInterpreter(String cmd);
  };
  rtcHighLevel rtc;
#endif

#ifdef IrrigationStation
class measureEC
{
  public:
  void   initMeasurementStation ();
    String SD12_Parser (String commandLine);
};
  measureEC soilParams;

class valveControl
{
  public:
    void   valveInit();
};
  valveControl valve;
#endif

#ifdef RadioIncluded
  class LoRaAddClass
  {
    public:
      void   LoRaBegin(long BAND);
  };
  LoRaAddClass LoRaAdd;
#endif

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

#ifdef RadioIncluded
  LoRaAdd.LoRaBegin(915000000);
#endif

#ifdef IrrigationStation
  valve.valveInit();
  soilParams.initMeasurementStation();
#endif

#ifdef RTCincluded
  String s = rtc.rtcInterpreter("A");
#endif
}
/*********************************************************/
void loop() {}

```

# Answer
Solved: while initially I devoted sub-directory for every class, no issues when all the classes were brought to the same folder with the INO file all the issues disappeared. Is this a known issue?
> 1 votes

---
Tags: esp32, compilation-errors, linker
---


# Question
Title: How can I use a transistor to "press" a button?
I have a heater remote that I want to press the buttons of with my Arduino. I am powering both the remote and Arduino from an external 5V source so both grounds are connected.

Currently I have tried using an NPN transistor(TIP122) and it does work but is not very reliable. It probably works 80% of the time but isn't good enough for my purpose. Sometimes nothing happens and sometimes the button is pressed twice for no reason.

These are my connections.

I have the emitter connected to ground, collector connected to the button and the base connected to the Arduino with a 1k resistor. Are my connections OK?

I've also tried using a PNP transistor but pulling LOW instead of HIGH and LOW instead of HIGH.

The code is very simple, in the setup I have:

```
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
delay(20);
digitalWrite(4, LOW);

```

Therefore when I restart the Arduino it should press the button, right?

I also have IRLZ44N and IRF540N, would either of these work better?

# Answer
> 2 votes
A glance at the TIP22 datasheet shows that this is a Darlington pair transistor, which means that it has very high DC gain (good), but at the cost of a very high Vbe\_ON (bad). The datasheet shows that the Vbe\_ON is 2.5V, which means that the voltage across the 1K is only 2.5V max, which limits the base current to around 2mA. This is probably not enough for good saturation. In addition, the Vce\_SAT for this device is about 2.0V, which may or may not be enough to look like a good GND to the button circuit.

I think a MOSFET like the IRF540N, connected as shown here (substitute button circuit for motor) might be a better choice YMMV

# Answer
> 1 votes
You really only need one wire and no resistors or mosfet.

I see many answers including expensive mosfets and relays to answer this question. There is a much simpler solution requiring no glue logic or interfacing circuitry. I recently had to install an off-the-shelf ultrasonic humidifier in an incubator/brooder. It is the cheap little home-use aromatherapy type diffuser. It had to be controlled by a relay to turn on and off. The catch is that the control circuit and firmware used in nearly all of these is the same, it can be turned on by a relay in the PID incubator controller but requires a single button press once power is supplied to start the ultrasonic humidifier and fan. three button presses turns the humidifier off and returns it to standby and turns off automatically when it runs out of water. using the arduino to control only the button to bring it out of standby would not lead to reliable operation. I searched for an answer but found none that I could make given I had few parts and was working on a remote farm. This is my solution.

The science behind this and how it works is that the microcontroller does not sense the press of a button, it detects a state change. You may familiarize yourself with this in the arduino tutorials for reading a button press.

Tie the arduino ground to ground in the circuit you want to control. find a 5v rail and power the arduino. no extra power required. There is usually a test pad that will be ground and 5v close to the button you want to control. if not, find the regulator for the microcontroller that you are trying to trigger by tracing the circuit and attach the power rails. I used Digital Pin 2 for the trigger signal. connect d2 to a point near the switch. Ensure there is a resistor of about 600-1000ohm in the circuit between the point and the microcontroller. This should be present on the circuit you are triggering already simply because this is how microcontrollers detect state changes without sinking or sourcing infinite current.

This code will trigger once and then go to sleep. The long delays are to allow for expected debounce code in the microcontroller and allow for boot time. put simply, it switches PD2 between high and low states in high impedance and low impedance states and basically all a switch does is switch between high impedance and low impedance states. This code should trigger pretty much any microcontroller regardless of the specific state required once and then go to sleep.

```
#include <avr/sleep.h>
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, HIGH);
  delay(2000);
  pinMode(PD2, OUTPUT);
  digitalWrite(PD2, HIGH);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, HIGH);
  delay(300);
  pinMode(PD2, OUTPUT);
  digitalWrite(PD2, LOW);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  pinMode(PD2, INPUT_PULLUP);
  digitalWrite(PD2, LOW);
  delay(500);
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}

```

---
Tags: arduino-uno, button, transistor
---


title: Motor noise on my Arduino RC?

text:
# Question
Title: Motor noise on my Arduino RC?
I want to make an RC car based on two Arduino Nanos, two nRF24L01s (Rx and Tx), and a Pololu brushed motor driver, and it works, more or less.

Sometimes it works very well and everything goes nicely and suddenly it will "freeze" and stop receiving and when it does, the servo always goes to 0° (I think it must be the Rx because it prints the same value until the next restart in the serial monitor).

It seems the servo trebles in the same direction (to 0°) only when I send high PWM values until it stops reading new data and "freezes".

I have 2 batteries, one for the Nano with a step-up converter, and another for the servo and the brushed motor; they share a common ground. Everything is close to each other and connected by wires soldered to a prototype breadboard. It is really messy but makes a good contact.

So it seems it is a noise problem, doesn't it? But what else could it be? How can I suppress that noise? I have already watched the Pololu guide about noise but I didn't try the bypass capacitors since I don't know how to solder them properly (can they burn the servo?)

Here is the code for the Tx

```
#include <SPI.h>
#include "RF24.h"

const int ledBot = 8;
const int padx = A0;
const int pady = A1;
const int sw = 3;
int sws;
int x;
int y;
int botState;
int aBotState;
int ledState;
const float un = 0.25;
const float fy = 0.176;
int sens [4]; // 0: throttle, 1: foward/backwards, 2: steering, 3: lights

RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
  //Serial.begin(9600);
  pinMode(padx, INPUT);
  pinMode(pady, INPUT);
  pinMode(sw, INPUT);
  pinMode(ledBot, INPUT_PULLUP);
  radio.begin();
  radio.setDataRate (RF24_2MBPS);
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}

void loop() {
  x = analogRead(padx);
  y = analogRead(pady);
  sws = digitalRead(sw);
  botState = digitalRead(ledBot);
  y = 1024-y;

  switch (sws){ //foward and backwards

  case 0:
    sens [0] = un*x;
    sens [1] = 0;
    sens [2] = min(135, max(50, y*fy-2));
    break;

  case 1:
    sens [0] = un*x;
    sens [1] = 1;
    sens [2] = min(135, max(50, y*fy-2));
    break;
  }

  if ( botState == HIGH && aBotState == LOW) { //button switch part
    if (ledState == 0) {
      ledState = 1;
      sens [3] = ledState;
    }
    else {
      ledState = 0;
      sens [3] = ledState;
    }
  }
  aBotState = botState;
  radio.write(&sens, sizeof(sens));

  //Serial.println(sens[0]);
  //Serial.println(ledState);
  // Serial.println(sens[1]);
  //Serial.println(sens [3]);
}

```

And here for the Rx:

```
#include <Servo.h>
#include <SPI.h>
#include "RF24.h"

int sens [4];
const int polph = 7;
const int polen = 6;
const int led1 = 2;
const int led2 = 3;
const int ledError = 8;

Servo servo;
RF24 radio(9, 10); //
const byte address[6] = "00001";

void setup() {
  pinMode(polph, OUTPUT);
  pinMode(polen, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  pinMode(ledError, OUTPUT);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(300);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(300);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(300);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  servo.attach(5);
  //Serial.begin(9600);
  radio.begin();
  radio.setDataRate (RF24_2MBPS);
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    digitalWrite(ledError, LOW);
    radio.read(&sens, sizeof(sens));
    analogWrite(polen, sens [0]);
    digitalWrite(polph, sens[1]);
    servo.write(sens [2]);
    digitalWrite(led1, sens [3]);
    digitalWrite(led2, sens [3]);
  }
}

```

# Answer
> 1 votes
Electrical noise is **the** problem quite often. In order to minimize noise, several key points must be observed:

1. Solder one 0.1uF ceramic capacitor from each terminal to the motor case. These are called decoupling capacitors and are used to suppress HF noise creeping in from the motors due to sparking/arching.
2. Choose appropriate AWS rating for your motor leads and adequate power supply. Inappropriately thin leads or insufficient battery discharge current can cause abrupt voltage drop on acceleration which will lead to sudden MCU resets (brown out resets).
3. Twist the leads around each other. This helps to further nullify arching noise.

As for Arduino, it is not the best way for making reliable RC software because it does simple things terribly wrong, e.g. sequential software polling instead of using hardware input capture. I would highly recommend learning how to write firmware for MCUs in native mode.

Check out this link to gain some inspiration on how to build an RC motor driver:

https://github.com/neoxic/STM8-RC-Dual-Motor-Driver#building-a-dual-12a-bidirectional-esc

---
Tags: motor, servo, nrf24l01+
---


title: 5V alternative to Due?

text:
# Question
Title: 5V alternative to Due?
I've designed a circuit controlled by an Arduino Mega 2560 involving a number of external components all running on and sending out 5V signals. I'm now realizing that the 8Kb of SRAM on the Mega 2560 is insufficient, so I wanted to upgrade to an Arduino Due. The Due, however, can't accept the 5V outputs from the rest of the components.

Is there an Arduino compatible 5V board with memory comparable to the 96Kb on the Due?

I know that level shifting is an option, but considering that almost every digital input on the board is being used, I'd rather not have to add so many level shifters to the circuit. A voltage-compatible board is preferred.

I'm also not fixed on Arduino-compatibility. If there is another convenient microcontroller development board available, I'd gladly consider it.

**EDIT:**
The Arduino is being used to read from a set of sensors that produce image data at a constant rate. The data is recorded on the Arduino, then sent to a computer by USB. The Arduino needs to store the whole image before sending it to the computer because performing a Serial write call delays the processor causing it to miss a data sample. The ATMega2560 doesn't have enough SRAM to store the whole image at once.

# Answer
> 1 votes
The Teensy 3.5 seems to be exactly what I was looking for.

It is an Arduino-IDE-compatible 5V tolerant microcontroller board with a whopping 256Kb of SRAM and 64 digital inputs. It pretty much blows away the Due in every way.

# Answer
> 0 votes
The Arduino MKR Connector Carrier has input level conversion on analog inputs and logic level conversion on digital pins. It makes the 3.3 V MKR boards (SAMD21 MCU) compatible with 5 V sensors and actuators.

The SAMD21 on MKR boards has 256 KB internal flash memory and 32 KB SRAM.

---
Tags: arduino-due, voltage-level, memory-usage
---


title: Wifi Scanning code for esp32 wroom 32

text:
# Question
Title: Wifi Scanning code for esp32 wroom 32
I am trying to scan wifi in sta\_ap mode in my esp32 wroom 32 module but it is not scanning new wifi .Can anybody tell more about how does wifi mode works in this module and what's the problem in my code.Same code is working in esp8266.

CODE:

```
#include <WiFi.h>

const char *ap_ssid = "ESP32";
const char *ap_password = "";

const char *sta_ssid = "KKACT";
const char *sta_password = "kk25990418";
void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_AP_STA);
  WiFi.disconnect();
  delay(100);
  Serial.print("Configuring access point...");
  WiFi.softAP(ap_ssid, ap_password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(sta_ssid);
  WiFi.begin(sta_ssid, sta_password);

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

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
   Serial.println("Now scanning wifi continously");
   int n=WiFi.scanNetworks();
   for (int i = 0; i < n; ++i)
  {
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");

  }
    delay(2000);
}

```

# Answer
This is a issue raised on github about this:

https://github.com/espressif/arduino-esp32/issues/3294

And the issue seems to be that a failed connect prevent the scanning and the solution is:

> So what i did was when entering the portal:
>
> `WiFi.mode(WIFI_OFF); // otherwise Wifi.Scannetworks() fails`
>
> `delay(5000);`
>
> This seems to stop the processes that prevent the scanning.
>
> After that an immediate scan works without problems.
> 1 votes

# Answer
You are not doing it correctly. In order to perform WiFi scan:

1. It must be in `WIFI_STA` mode;
2. It has to be disconnect from the AP;
3. After you done with the scanned SSID, BSSID and RSSI, you need to called `WiFi.scanDelete()` if you are going to do a scan again, otherwise you will get the same previous scanned result.

So in summary, here is the code:

```
#include <WiFi.h>

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

void loop() {
  Serial.println("Scanning WiFi Networks...");
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  int n = WiFi.scanNetworks();
  for (int i=0; i<n; i++) {
    Serial.printf("%2d SSID=%-20s RSSI=%d\n", i+1, WiFi.SSID(i).c_str(), WiFi.RSSI(i));
  }
  WiFi.scanDelete();

  delay(10000);
}

```
> 0 votes

---
Tags: arduino-ide, esp32, espressif, esp
---


# Question
Title: ESP32 Partition size and maximum program size
From an ESP32 example code, I extracted the following part, that just prints the flash partition list to the console.

```
#include <string.h>
#include <assert.h>
#include "esp_partition.h"
#include "esp_log.h"

static const char *TAG = "example";

void setup(void)
{
    Serial.begin(115200);
    delay(200); // Otherwise, the first log entries get lost
    ESP_LOGI(TAG, "Start test");
    esp_partition_iterator_t iter = esp_partition_find(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, NULL);
    ESP_LOGI(TAG, "Name, type, subtype, offset, length");
    while (iter != nullptr)
    {
      const esp_partition_t *partition = esp_partition_get(iter);
      ESP_LOGI(TAG, "%s, app, %d, 0x%x, 0x%x (%d)", partition->label, partition->subtype, partition->address, partition->size, partition->size);
      iter = esp_partition_next(iter);
    }

    esp_partition_iterator_release(iter);
    iter = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);
    while (iter != nullptr)
    {
      const esp_partition_t *partition = esp_partition_get(iter);
      ESP_LOGI(TAG, "%s, data, %d, 0x%x, 0x%x (%d)", partition->label, partition->subtype, partition->address, partition->size, partition->size);
      iter = esp_partition_next(iter);
    }

    esp_partition_iterator_release(iter);

}

void loop()
{
}

```

In the project folder, I also have a custom `partitions.csv` file as follows:

```
nvs,        data, nvs,      0x9000,  0x6000,
phy_init,   data, phy,      0xf000,  0x1000,
factory,    app,  factory,  0x10000, 512k,
storage,    data, ,         ,        0x40000,

```

If I run the code, it correctly shows the custom partitions with the above sizes, everything like it should be.

**However**, the build output says the program uses 207278 Bytes from a maximum of 1310720. If I change the partition scheme selection in the tools menu, the second number changes. I would expect the maximum size to be equal to the size of the `factory` partition from the custom partition scheme.

If I change the factory partition to be only 100k in size, the ESP32 fails to boot and enters a core-dump-restart-loop.

Is this a compiler bug or am I overlooking something?

# Answer
> 1 votes
This appears to be a limitation of the toolchain. The output of processing the `partitions.csv` file doesn't make it back to the compiler to generate the correct message. The different partition schemes available in the menu come from `boards.txt` of the ESP32 package. They can be updated, but would be overwritten when the toolchain is updated. For the compiler input, the setting in the menu is relevant, but the actual size of the partitions comes from the `partitions.csv` file (if it exists).

This means that one has to manually make sure that the size of the `factory` partition in the csv file is larger or equal to the actual code size. Ideally, it is also equal to the selected partition size from the menu (to get the correct message and eventually error if the binary size exceeds the allocated space).

Some testing shows that if the actual size of the `factory` partition is smaller than the code size (and smaller than the compiler size limit) the application will successfully build and upload, but fail to run. The chip will enter a startup-reboot-forever loop and not execute any user code. However, whether that is always the case is not guaranteed.

---
Tags: arduino-ide, esp32, partition
---


# Question
Title: stop motor instantaneous with hall sensor problem
I have a problem with stopping motor at same spot when magnet pass.. I tried to add interrupt and to make code as clean as possible but no joy so far. Any suggestions? sw will add later, just ignore..

```
byte outPin = 12;        // the number of the output pin
byte inPin = 2;          // the number of the input pin

byte hallPin = 3;        // hall sensor

byte sw;
byte previous;
int state = LOW;         // the current state of the output pin
int reading;             // the current reading from the input pin

void setup()
{
  pinMode(inPin, INPUT_PULLUP);
  pinMode(outPin, OUTPUT);

  pinMode(hallPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(hallPin), stop, FALLING);   //hall read low when magnet pass
}

void loop()
{
  sw=0;

  reading = digitalRead(inPin);       //read(LOW when press!)
  if (reading == HIGH) previous=0;

  if (previous == 1 && sw == 0) state=LOW;
  else if (reading == HIGH) state=LOW;
  else state=HIGH;

  digitalWrite(outPin, state);
}

void stop() {
  if (sw == 0 && reading == LOW) {
    state=LOW;
    previous=1;
  }
}

```

# Answer
You can stop a BDC faster if you short-circuit it. This is possible with an H-Bridge and the appropriate components.

It would be easier to use a L293D, which already provides this mode.

If you want to try it with this component, of course you can also build the h-bridge yourself, pay attention to the D on the component. With the D-version the protection diodes are already built in. You can power two motors from 4.5V to 36V with a maximum current of 600mA.

For up to 2A you can use a L298N.
> 3 votes

# Answer
The motor can't stop instantly because it has inertia, plus the inertia of whatever stuff the motor is moving.

So if you want it to stop at a set position, you have to slow it down before it reaches the desired position, so it will come to a stop where you want. It's not possible to do that with only one sensor.

A complicated solution would be to use a position encoder, like a rotary encoder, to know the position at all times, so you could use a control algo like PID on the motor. This offers the most features, as you can then set the desired stop position in software, without needing to move the sensor.

If the stop position never moves then a simpler solution is to use multiple sensors. That's often how it's done with elevators: there is a sensor to accurately align the elevator with the floor it has to stop on, but there are also several others slightly before that on the track to tell the controller that it's time to start slowing down, then slow down to a crawl, then stop.

To keep it simple you can use just two sensors: when it goes past the first, slow down the motor to a crawl. When it activates the second sensor, since it is going slow, it will stop quickly and end up where you want.
> -1 votes

---
Tags: motor, interrupt, hall-effect
---


# Question
Title: Connecting an arbitrary number of pins to pin holes without soldering?
I want to avoid soldering for health reasons. I have no well-ventilated open area in my apartment. For a board/modules that have no pins but only holes, how can I connect pins to the holes without soldering?

For certain popular hardware like Raspberry Pi Zero, there seems to be something called "hammer header"

but the problem is those have a fixed, pre-determined number of pins, not individual pins. So, if a hardware has 5 holes instead of 20 holes, that thing cannot be used. Is there a hammer header for a single pin? So that if the hardware has 5 holes I would just use 5 of them. I have searched the Internet, but no result. Also, the "hammer header" itself seems to be rare. I could not find a single online store in my country that sells it.

Some existing answer mentioned "Pomona minigrabber", but that thing seems to be temporary. That is, I cannot move the device (it looks that it will fall off). So, that is probably not the answer I want.

A secondary, less-important question, but if I installed hammer pin headers (seems like one has to hit it with an actual hammer to install it), can I un-install (remove) the headers?

# Answer
> 6 votes
As you already have seen, there are not many options to contact such boards without soldering, because **they are meant to be soldered**. Those hammer headers are an option. When you find a seller for your country, it should also have these in different sizes/numbers of pins.

Though contacting the board with the pins is not the only problem, you may face. As long as you are experimenting, the typical breadboard is often enough. But when you want to make something more permanent, reliable, current thirsty or noise sensitive, a breadboard is a bad choice. In that case you would also need to solder. Soldering is just a very integral part of electronics.

---

As others have wrote in the comments, I would also consider soldering as a hobbyist as safe, especially, when you take some precautions. A "well ventilated area" can be a simple room with the window open and a small fan directed to the working place, so that the fumes don't directly go up your nose. That is already a very big improvement, which is also rather cheap. That's also about what the woman does in the video, that you linked. And washing your hands after soldering is also a good measure. (I'm doing soldering the described way for about 15 years now, without any health issues)

In the video, that you linked, they say, that the fumes are toxic and their effect adds up. Letting aside, that they don't back it up with any data and I cannot either, they also don't talk about the amount of solder work, that they consider here. As an electronics beginner you most likely will just solder very rarely for getting pin headers on boards or maybe contacting a motor. The main work most likely will still be done on the breadboard. So here the exposure is so small, that you don't need to consider more than the above safety measures. These will also last rather long, as you get more profound in electronics. And when keeping up that hobby, you maybe wanna invest in a more professional filter system, as you are doing more solder work.

Doing electronics while being that scared of soldering will not be much fun. For the start you might get away by only buying presoldered boards. But very fast you will run against walls with this. Not a good start for a beginner.

But in the end it's your own decision. You have all right to be afraid of solder fumes, though that just might disqualify electronics as a hobby for you.

> if I installed hammer pin headers (seems like one has to hit it with an actual hammer to install it), can I un-install (remove) the headers?

That depends on the pin headers, but most likely no. You would need physical force to get them off. And the pads on a PCB are not very strong. They are made to be soldered, not for tearing the pins off without any damage. But why would you want to remove the headers? You only very rarely solder wires directly to the board for connecting with other parts. Either you solder it onto another PCB (where the pin headers come in handy), or you use a female header on a PCB or a cable for making the connection temporary. For example all my small Arduinos get pin headers soldered to them, so I can put them onto my own PCBs via female headers on the PCB. With that I can also disconnect or replace the Arduino if I need to.

# Answer
> 1 votes
I placed the arduino on a breadboard with the pins on the breadboard 1 pinhole further apart than it 'should' be, this way you can press the arduino down and the arduino will fasten itself in place.

# Answer
> 0 votes
Why not get a fume extractor, there are all types, some even have filters. Simply do a google search for "fume extractor", on my first try I got 587,000 hits. The price is all all over the map even for the same model.

# Answer
> 0 votes
I had a problem where a sensor I bought came with holes and the pins not attached. I do not have any soldering skills and searched for a solution. I ended up wrapping tinfoil around each of the small pins to increas their diameter and jamed it in the sensor's holes. As far as I can tell, it is working. It is a bit tidious and is clearly not a long term solution but ended up working at least to test my sensor and set it up. I couldn't find any solution online without having to buy something else so here you go, if any one is looking for a quick solution with house hold items. Hope it can help any one in need.

(make sure the tinfoil is not in contact with other pins or other metalic part of your sensor as it could cause shorts.... be careful not to damage your devices :) )

---
Tags: pins
---


# Question
Title: HW-477 Module having VS1838B IR Sensor: Help with Pins
Ordered **Universal IR Receiver** and I got **HW-477 module** with **VS1838B IR Sensor**.

Good thing is datasheet for **VS1838B** is available but not for HW-477.

**VS1838B** pins as: Ref
Signal | GND | VCC

while **HW-477** says:
(- minus) | R | G

Can't understand which one to follow and **R** is for Receiver? **G** is for GND and what is **-** (minus sign) for?

So can anyone help me with ( - R G ) of **HW-477** ?

Images:

These may help?!
this & this one.

**Updates:**

I looked to trace the Foil *(PCB Board Lines)* but it didn't worked because the circuit as whole is coated.

Using **Connectivity** *(Continuity (diode test))* option of Digital Multimeter, found these to play beep:

| **VS1838B** | **HW-477** |
| --- | --- |
| Signal | G & (minus pin of HW-477) |
| GND | (- minus pin of HW-477) |
| VCC | R |

But a person in this video saying

> \- is of course GND

There is a huge confusion which can only be cleared if I got a reply from seniors. I have two of this and can try one (even to burn) to better understand what is going on.

(Tried contacting the vendor about datasheet but they are not responding)

# Answer
The problem here is that **HW-477** refers not to the module as a whole but a generic PCB that is re-used (in some starter kits for sure) for many different sensors. I think the idea is that whatever device is attached to the board there's a position where the output is always the same (`- = GND`, `R = VCC`, `G = Signal`). On some variants of the board you can see them labelled as `- + S`.
> 1 votes

---
Tags: arduino-uno, sensors, ir
---


# Question
Title: Why must I detach the Arduino from the computer when making adjustment to the circuit?
I am new to Arduino and am reading Learn Electronics with Arduino: An Illustrated Beginner's Guide to Physical Computing. On page 118, it says:

> Remember, whenever you make adjustments to a circuit, your Arduino should not be attached to your computer.

To give more context, it means when you make adjustment to the circuit on the breadboard, you should detach the USB cable from the computer.

I am wondering **why**?

Is it because a short circuit can crash my computer similar to how the USBKill works? Are there other reasons?

# Answer
> Is it because a short circuit can crash my computer ...

It is more that you don't want an inadvertent mis-routing of cables to burn out your chips while they are powered.

I wouldn't personally be making changes to a breadboard circuit while it is powered. It is better to do it un-powered, and then check it over, than wonder why there is smoke coming from it.
> 3 votes

# Answer
"Adjustments to a circuit" can mean removing, adding or repositioning components on the breadboard. One can accidentally position a component lead in an incorrect location on the board, creating a circuit that is undesirable and possibly damaging to the assembled project.

If the misplaced lead or leads are in a particularly unsuited location, the circuit can include the USB portion of the system. The probabilities are low that one would accidentally damage that specific set of traces, or send voltage where it should not be, but they are non-zero. Even if one damages the Arduino, the cost is low compared to a damaged USB port or computer.

If you've been creating simple Arduino circuits and have misplaced or mis-routed a lead or component, you've learned how easily that can happen. Disconnecting the USB is comparably a minor inconvenience.
> 1 votes

# Answer
> Is it because a short circuit can crash my computer

More than crashing it, there is some risk that a short-circuit on your board could cause damage to the computer's USB port that is powering it. Most computers have overload protection on their USB ports but you don't want to test it unnecessarily, risking permanent damage to the port.
> 0 votes

---
Tags: usb
---


# Question
Title: Why use a module rather than sensor directly?
I'm trying to understand when one would use an Arduino module rather than directly a sensor.

Here's an example to contextualize my question: I need to use a Hall sensor to measure the number of rotations per minute of a magnet mounted on a computer fan. I see that I can either buy the Hall sensor and wire it to the Arduino (*Hall-Effect Sensor Analog 49E*), or alternatively I could buy a sensor module (e.g., *Digital Hall Effect Sensor Module* or *Linear Hall Effect Sensor Module*). What is the advantage of buying modules, rather than the sensors directly?

# Answer
> 16 votes
The modules are typically easier to work with, particularly for DIY projects. They have standardized connectors, have their connections labeled and can be mounted into wiring boards. The particular sensor you have there does have quite big legs, so this may work fine without the board, but this is often not true. Consider sensors such as the BME/BMP types (BME680 data sheet). They're far to small to be used directly without a PCB. And they require some external components to work correctly, which are already included on the module. So for experimental purposes, the module is the way to go.

# Answer
> 9 votes
It's a question of convenience and application use-case specific. Sometimes a module will give you additional functionality and/or structural stability, just by providing a mini-PCB (maybe with screw holes) for a low price overhead.

For example, compared to the bare element the module you posted has additional components (LED or `A0`,`D0` on the pricier one) is easily mountable and provides standarized connection pins.

If you already have a PCB (or other circuitry) the module could be superfluous, maybe you just need the sensor itself, but often those modules come as neat packages, sometimes with controller chips speaking I²C and comparable protocols (like the DHT11/DHT22 and others).

# Answer
> 4 votes
Since nobody else has addressed your example directly, and to use it as an example, in addition to the other observations about these two items, let's also take note of :

#### Hall-Effect Sensor Analog 49E

> The 49E sensor can detect the magnetic N/S pole and relative strength of a magnetic field and **outputs an analog voltage**

* Vcc Range 2.3 – 10V
* Output : Analog 1.9mV/GS (± 0.2mV/GS)

#### Digital Hall Effect Sensor Module

> 3144 sensor detects presence of magnetic field and **outputs logic level**.

* Vcc Range 4.5 – 24V
* Output : Open Collector

#### Linear Hall Effect Sensor Module

> Detects N/S poles and relative strength of a magnetic field.

* Vcc Range 3.3 – 5V
* Output : Analog 2.5mV / G PLUS digital output
* Includes 49E sensor plus everything in the schematic below :
*

So the sensor you've linked provides an analog signal, allowing you measure the magnetic field strength. The digital module provides only an open-collector output (ie: ON/OFF) which indicates either the absence or presence of a magnetic field above some threshold of intensity. These are entirely different functions which you would use for entirely different applications. The digital module also works with VCC up to 24V, which makes it handy to integrate with 24V automation systems. The linear module provides an analog output as well as some indicators and an additional digital output, but is capped at 5V Vcc (whereas the raw module accepts up to 10V).

Why would you choose either? What do you need to do? Do you want to check for the presence of a magnetic field only, or do you also want to measure its intensity? Or both? The modules do some of the work for you and, in the case of the linear module, actually give you an additional output that the raw sensor does not. It's up to you to decide which of these serves your needs.

# Answer
> 0 votes
In your case it only makes sense if you want to put the module on a breadboard and don't have the other components on the board at hand.

Example: for a DS18B20 one wire temperature sensor you need a pullup resistor. If you have this resistor at hand there is no sense to buy a module. But if you have to buy one resistor it is more easy to buy a module.

For experimental setups, it is often easier to use a module. If you want to build the circuit permanently later, the modules are rather annoying. Because the modules are often very bulky. The direct mounting of the components on a perfboard is then more space-saving.

# Answer
> 0 votes
It's a tradeoff between convenience and your time, money and expertise. You could design the module's circuitry and function into your circuit board, or, at slightly more expense, you could solder a module to your circuit board, with the designing and functionality already built-in. It might cost a little bit more and maybe be somewhat larger, than if you did it yourself. Ultimately it's up to you, which way works better for you in your particular circumstance.

---
Tags: sensors
---