message:
MKR 1010 WIFI Built-in RGB LED not working with BLE

in addition to the standard LED_BUILTIN, MKR 1010 WIFI comes with a built-in **RGB LED**.

This RGB LED fails when used along the on-board BLE, no matter what program sequence I test.

To reproduce the issue, turn on the LED and then start BLE which will turn the LED off.

```
#include <WiFiNINA.h>
#include <utility\wifi_drv.h>
#include <ArduinoBLE.h>

void setup() {

  const int ledPin = 27;  //R=26 G=25 B=27

  WiFiDrv::pinMode(ledPin, OUTPUT);

  WiFiDrv::digitalWrite(ledPin, HIGH);

  Serial.begin(115200);
  while (!Serial);

  if (!BLE.begin()) { // ble.begin trun the led off
    Serial.println("BLE Failed");
    while (1);
  }

  Serial.println("BLE started"); // last line shown on console

  WiFiDrv::digitalWrite(ledPin, HIGH);

  // program never gets here

}

void loop() {}
```

The RGB LED is connected to NINA’s GPIO pins. Two of them (green and blue) are part of the UART, and another one is used for system control signals (red).

I assumed that BLE.begin uses the UART to communicate with the processor and therefore avoided the red pin and added delays between commands hoping to separate the actions, but it didn’t work.

My goal is to use the RGB LED to indicate BLE states without adding three sets of MOSFETs and resistors. Ideas?

body:
The ArduinoBLE library resets the NINA firmware to BLE mode ([code here][1]). In this mode the NINA firmware just sets ESP32 SDK (IDF framework) to handle the BLE commands.

The RGB LED is handled by the part of the Arduino NINA firmware which [handles the commands][2] from the WiFiNINA library. These commands are communicated over SPI and are not handled if the firmware is in BLE mode.

  [1]: https://github.com/arduino/nina-fw/blob/c84aa3406717af771653733fb9c3480bdf5e1a64/main/sketch.ino.cpp#L108
  [2]: https://github.com/arduino/nina-fw/blob/c84aa3406717af771653733fb9c3480bdf5e1a64/main/sketch.ino.cpp#L197


sender: user

message:
change sketch from controlling 8 stepper motors to 8 solenoids

I am looking to see if I can change the attached sketch which controls 8 stepper motors to just switching 8 relays for a weaving loom which we have, unfortunately making this change is well above my paygrade lol. I am using an arduino mega and 8 channel relay board which will in turn trip the solenoids which the loom already has attached, thanks for any help

This is the Sketch im trying to alter

```lang-c++

// Loom interface for Ashford Dobby interface (using 8 stepper motors):
// Arduino lines 0 & 1 to USB interface
// line 13 Is foot pedal
// 14-43 are motor controls

// General definitions:
#define MAX_CHARS 80
#define DEBUG 0
#define MOTORS 8
#define IDENTITY "Generic Dobby Interface (Jones Stepper Motor Dobby)\n"

// Data controlling motor positions, states, etc:
const long MOTOR_DELAY=900;                                                      // Time delay between motor steps (reduce till shafts move reliably)
const long  SHAFT_UP=8*170, SHAFT_DOWN=0 ;                                       // Number of motor steps required to raise the shafts
unsigned long shaft_state=0x00000000, shaft_cue=0xffffffff;                      // tracking current & next desired states of shaft controls
long MotorActual[MOTORS], MotorWant[MOTORS];                                     // Current & desired position for each of the motors

// Definition of which Output pins connect to which motor
char MotorPin[MOTORS][4]=                                                        // Motors 1,3,5,7 on right, 2,4,6,8 on left: left side reverses direcion
              { {14,15,16,17}, {18,21,20,19}, {22,23,24,25}, {26,29,28,27},      // Motors 1-4
                {30,31,32,33}, {34,37,36,35}, {38,39,40,41}, {42,45,44,43}};     // Motors 5-8

unsigned long NextMotorUpdate=0;                                                 // Timer for when next motor step occurs
const int ADVANCE  =13;                                                          // input pin for footswitch (has pullup, switch contact only)

// Serial (USB) interface
// Serial interface is a "Generic" dobby interface:
// Host sends which shafts should be activated for current shot
// Shafts will raise when the foot switch is activated
// Shafts return when foot switch is released, and the "Advance" command returned to host
// Also responds to "?" with the "IDENTITY" identified above, shows host who's out here

int serial_chars=0;                                                              // Number of characters in the serial input buffer
char serial_string[MAX_CHARS]="";                                                // Serial input buffer
char Message[MAX_CHARS]="";                                                      // Output message buffer
long serial_time=0;                                                              // Used to close serial string on timeout (timer)
const int serial_timeout=100;                                                    // Digest Serial string after timeout
char serial_idle=1;                                                              // Tracks activity on the serial bus
char HostPresent = 1;                                                            // set when some host is identified
int Button_state=1;                                                              // tracks changes in floor-switch state

////////////////////////////////////////////////////////////////////////
// Send shaft controls to hardware
////////////////////////////////////////////////////////////////////////
    void set_motor(char m,char state)                                            // Lowest level function to handle step in motors
    {
//   sprintf(Message,"M %d @ state %d\n",m,state);
//   Serial.write(Message);
     switch(state)
     {
      case 0:                                                                    // Set motor inactive
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 1:                                                                    // Set motor State 1
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 2:                                                                    // Set motor state 2
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 3:                                                                    // Set motor state 3
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 4:                                                                    // Set motor state 4
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 5:                                                                    // Set motor state 5
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 6:                                                                    // Set motor state 6
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 1);
      break;

      case 7:                                                                    // Set motor state 7
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 1);
      break;

      case 8:                                                                    // Set motor state 8
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 1);
      break;
     }
    }

   char set_motors()                                                            // Set all motors to new motor state - called for each motor step on any motor
    {                                                                            // return indicates if any motor is still active
     int m=0;
     long setting, entry_setting;
     char active=0;

     while(m<MOTORS)
     {
                                                                                // Check for necessary directional movement
      entry_setting=setting=MotorActual[m];
      if(setting==MotorWant[m])       setting=setting;
      else if(setting<MotorWant[m])   setting++;
      else                            setting--;
                                                                                // Send update setting controls
      if((entry_setting!=MotorWant[m]))
      {
       active=1;
       MotorActual[m]=setting;                                                   // update actual for move in progress
       setting=(setting&7)+1;                                                    // set_motor state 0 is inactive, 1-8 are active
       set_motor(m,setting);                                                     // Set new motor state
      }
      m++;                                                                       // Next motor
     }
     if(active==0)
     {                                                                           // If done kill power to the motors that are back in passive state
      m=0;
      while(m<MOTORS)
      {
       if(MotorActual[m]==SHAFT_DOWN)set_motor(m,0);                             // set motor inactive
       m++;
      }
     }
     return active;
    }

    char run_motors()                                                            // Higher level function to set motors to desired positions
    {                                                                            // return indicates if motors are active or idle
     char active=1;
     if(micros()>=NextMotorUpdate)
     {                                                                           // time to update the motor positions
      active=set_motors();                                                       // Update all motors
      NextMotorUpdate=micros()+MOTOR_DELAY;                                      // set clock for next update
     }
     return active;
    }

    void set_shafts(unsigned long shafts)                                        // Called to set desired motor positions based on which shafts were requested
    {                                                                            // This assumes all shafts move the same amount, they really don't need to
     unsigned long bit_mask=1;
     int i=0;
     while(i<MOTORS)
     {
      if(shafts&bit_mask)MotorWant[i]=SHAFT_UP;
      else               MotorWant[i]=SHAFT_DOWN;
//    sprintf(Message,"M %d @ want %d\n",i,MotorWant[i]>>8);
//    Serial.write(Message);
      i++;
      bit_mask=bit_mask<<1;
     }
    }
////////////////////////////////////////////////////////////////////////
// Preset- Called on initialization
////////////////////////////////////////////////////////////////////////
    void preset()                                                                // Could raise all shafts to show it's working, etc.
    {                                                                            // This version doesn't do anything, default will lift all shafts when the foot switch is pressed before anything else is requested
    }

//////////////////////////////////////////////////
// SERIAL INTERFACE (USB) FUNCTIONS
//////////////////////////////////////////////////
                                                                                // USB input commands:
                                                                                // 1,2,3,n            Set shafts 1,2,3,n
                                                                                // ?                  ID request, respond with ID
    unsigned long get_shafts(char* command)                                      // Input is series of numbers, comma seperated, for shafts to raise
    {                                                                            // returns word indicating which shafts were identified in string
     int chars=strlen(command);                                                  // Number of characters in input string
     int i=0;
     unsigned long shafts=0, bits;                                               // Sets bits for shafts indicated
     char shaft=0, digit=0, character;

     while(i<=chars)                                                             // loop through all characters in command
     {
      character=command[i];

      if((character==',')||(i==chars))
      {                                                                          // have field seperator or end of string, not shaft desired
       if((shaft>0)&&(shaft<=32))
       {                                                                         // 'shafts' notes this shaft is required
        bits=1<<shaft-1;
        shafts|=bits;
        shaft=0;
       }
      }
      else if(('0'<=character)&&(character<='9'))
      {                                                                          // have digit
       character&=0x0f;                                                          // reduce to decimal
       shaft=shaft*10+character;
      }
      else if((character==' ')||(character=='\n'));                              // ignore spaces/returns
      else
      {
       Serial.println("Invalid Character detected in command:");                 // debug display of command extracted
       Serial.println(command);                                                  // debug display of command extracted
       i=chars;                                                                  // quit, got crap
      }
      i++;
     }
     return shafts;
    }

    void digest_serial(char* command)                                            // Main serial response function
    {
     int chars=strlen(command);                                                  // Number of characters in command

     if(chars>0)
     {                                                                           // If something to do go digest the input
      HostPresent=1;                                                             // note that there's something out there talking to me
      if(('0'<=command[0])&&(command[0]<='9'))                                   // go number, should be shafts
       shaft_cue=get_shafts(command);                                            // convert ASCII string to binary word
      else  if((command[0]=='c')||(command[0]=='t'))                             // test command to cycle valves
       preset();                                                                 // cycle through the valves (nothing defined for this loom, could implement shaft self test, etc)
      else if(command[0]=='?')
      {                                                                          // Have a "Who are You?" kind of command, tell host who we are
       char message[256]=IDENTITY;                                               // Build primary Identity command
       message[strlen(message)-1]=0;                                             // delete return in line
       sprintf(message,"%s  [Solenoid state = 0x%3x]\n",message,shaft_state);    // note what we'll do when button is pressed
       Serial.write(message);                                                    // Send identity with current switch state to host (for troubleshooting)
      }
     }
    }

    void serial_input()
    {                                                                            // High level Serial processing
     char inChar;
     char command[MAX_CHARS]="";

     while((Serial.available()>0))
     {                                                                           // Get serial command from host (character by character)
      inChar=char(Serial.read());
      serial_string[serial_chars]=inChar;
      serial_chars++;
      serial_string[serial_chars]=0;
      serial_time=millis();
     }
     if((serial_chars>0)&&(serial_idle)&&((serial_string[serial_chars-1]=='\n')||(millis()>(serial_time+serial_timeout))))
     {                                                                           // If have a command, go digest it
      serial_idle=0;
      strcpy(command,serial_string);
      serial_chars=0;
      serial_string[0]=0;
//    Serial.println(command);                                                   // debug display of command extracted
      digest_serial(command);
                                                                                // done with last command, clear the input buffers
      serial_idle=1;                                                             // ready for more serial input
     }
    }

////////////////////////////////////////////////////////////// /
// Foot Switch monitor  - set shafts/tell host to advance
////////////////////////////////////////////////////////////// /
    void monitor_button()
    {                                                                            // check for button push to advance, sent only when button pushed (not held)
     char state=digitalRead(ADVANCE);                                            // read state of foot switch (0=active, 1=inactive)

     if(state==0)
     {                                                                           // button is pressed,
      set_shafts(shaft_cue);                                                     // Set motor desired states from the list of shafts desired for this shot
      run_motors();                                                              // Go run the motors to make it happen
     }
     else
     {                                                                           // button is not pressed,
      set_shafts(0);                                                             // Set motor desired states back to reset condition
      run_motors();                                                              // Make it happen
      if(Button_state!=state)
       Serial.write("ADVANCE\n");                                                // Send "Advance" when foot switch is released
     }
     if(state!=Button_state)                                                     // Check if button has changed state
      delay(500);                                                                // Wait half a second on changes to debounce switch
     Button_state=state;                                                         // Track current state of the button to look for changes
    }

//////////////////////////////////////////////////
// TOP LEVEL FUNCTIONS - SETUP & LOOP                                                                                //
//////////////////////////////////////////////////
    void setup()
    {
     char m;                                                                     // Motor indicator

                                                                                // USB Interface to host computer
     Serial.begin(9600);                                                         // start serial port at 9600 bps:
     Serial.print(IDENTITY);                                                     // print message on serial monitor

                                                                                // Motor Controls
                     // set motor controls for all motors
     m=0;
     while(m<MOTORS)
     {
      digitalWrite(MotorPin[m][0], LOW);                                         // set low
      digitalWrite(MotorPin[m][1], LOW);                                         // set low
      digitalWrite(MotorPin[m][2], LOW);                                         // set low
      digitalWrite(MotorPin[m][3], LOW);                                         // set low
      pinMode(MotorPin[m][0], OUTPUT);                                           // Set as output bit
      pinMode(MotorPin[m][2], OUTPUT);                                           // Jumble order to keep motor from moving
      pinMode(MotorPin[m][1], OUTPUT);                                           // Set as output bit
      pinMode(MotorPin[m][3], OUTPUT);                                           // Set as output bit
      MotorWant[m]=MotorActual[m]=0;                                             //
      m++;
     }

      pinMode(ADVANCE, INPUT_PULLUP);                                            // Set as input pin to handle the foot switch
      preset();                                                                  // "self test" - note it's alive
      unsigned long T0=millis();                                                 // Note start up time
     }

    void loop()
    {
     serial_input();                                                             // check the serial interface, handle if it comes in
     monitor_button();                                                           // check for button push
    }
```

sender: assistant

body:
 * The assumed goal is to automate a Weaving Loom using solenoids instead of steppers.

 * [This video][1] claims a 3kg pull is necessary. It may be difficult to find an appropriate / economical solenoid with that kind of pull, stroke distance & rated for continuous duty (hold its position for a prolonged period of time without harming its self from heat related problems).

 * If sourcing such a solenoid is not a problem, there are only 2 functions in the above code that control the steppers. "set_motor" and "setup". Change those to activate / deactivate solenoids.

 * Also, this might be harder, remove the code that cycles the steppers into / out-of position. You don't need that w/the solenoids.

  [1]: https://youtu.be/YcQjRLs0cXc


body:
I would first figure out what each stepper motor code segment is doing, in overview. Think of viewing the process while standing back from it and describe the _reason_ that code segment is there, more than what, specifically, it does - what it's relationship is to the process, not to the motor.

Move those motor segments into functions, and put function calls where the motor segments used to be.

Now replace the motor code inside each function with solenoid code. This is why we wanted an abstract overview of those motor segments. In each function, you'll write solenoid-specific code that has that same relationship to the overall process as the motor code did, but you'll tailor the specifics to the solenoids.


message:
Arduino resets or stuck during run, only when DC motors are connected

I'm using an arduino connected to 2 DC motors through L298N. the arduino is powered by a 9V battery, and the L298N is powered by 4 AA batteries. there's also a switch that starts the movement.

I've added print statements to debug, one in the setup, one in the start of the loop, and two before and after running so i know when the motors start and how long they run. I also print the state of the switch. this is what i get:

    1                          // switch state. 1  means off.
    loop                       // start of loop statement
    1
    loop
    0                          // switch state changed to on
    0                          // added another switch check after the if
    Forward for: 5 seconds     // motors on
    setup                      // reset for some reason
    loop                       // start of loop
    0                          // switch still on
    setup                      // another reset
    loop
    0
    0
    Forward for: 5 seconds     // motor starts again
    setup                      // another reset
    loop
    0
    0
    Forward for: 5 seconds     // stuck with the motors on, no more resets
its not always this bad, sometimes it runs once or twice correctly (for five seconds) and then off. some times it gets stuck on without reseting. also, sometimes it starts reading the switch value as 1 after a few seconds of reading the correct value, even though the switch wasen't moved. also, when I remove one of the motor batteries so they don't get power everything works great.
What causes the reset and the freezing? How can I fix that?

this is my code:

    #include <Arduino.h>
    int RightSpeedPin = 5;
    int Rdir2 = 6;
    int Rdir1 = 7;
    int led = 13;
    int LeftSpeedPin = 10;
    int Ldir2 = 8;
    int Ldir1 = 9;
    int SwitchPin = 4;
    int ReadVal;
    int baseSpeed = 230;
    int Stime;
    int Etime;

    void go(int d) { // d = 1 will move, d = 0 will stop
      analogWrite(RightSpeedPin, (d == 1 ? 230 : 0));
      analogWrite(LeftSpeedPin, (d == 1 ? 255 : 0));
    }

    void forward(int t) {
      Serial.print("Forward for: ");
      Serial.print(t / 1000);
      Serial.println(" seconds");
      digitalWrite(Rdir1, HIGH);
      digitalWrite(Ldir1, HIGH);
      digitalWrite(Rdir2, LOW);
      digitalWrite(Ldir2, LOW);
      digitalWrite(led, HIGH);
      Stime = millis();
      while (millis() < Stime + t) {
        go(1);
      }
      go(0);
      Etime = millis();
      Serial.print("ran for ");
      Serial.println(Etime - Stime);
      digitalWrite(led, LOW);
    }

    void spin() {
      digitalWrite(Rdir1, LOW);
      digitalWrite(Rdir2, HIGH);
      digitalWrite(Ldir1, HIGH);
      digitalWrite(Ldir2, LOW);
      Stime = millis();
      while (millis() < Stime + 100) {
        go(1);
      }
      go(0);
    }

    void setup() {
      // put your setup code here, to run once:
      pinMode(Rdir1, OUTPUT);
      pinMode(Rdir2, OUTPUT);
      pinMode(RightSpeedPin, OUTPUT);
      pinMode(LeftSpeedPin, OUTPUT);
      pinMode(Ldir1, OUTPUT);
      pinMode(Ldir2, OUTPUT);
      pinMode(SwitchPin, INPUT_PULLUP);
      pinMode(led, OUTPUT);
      Serial.begin(9600);
      Serial.println("setup");
    }

    void loop() {
      Serial.println("loop");
      ReadVal = digitalRead(SwitchPin);
      Serial.println(ReadVal);
      if (!ReadVal) {
        delay(500);
        Serial.println(ReadVal);
      // starting situation- both motors heading forward
        // running for 5 secs
        forward(5000);
        delay(1000);
        spin();
      }
    }
and this is my scheme:

[![circuit scheme][1]][1]

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

body: When brushed motors are involved I usually think of arc suppression caps across the motor terminals, 100 mF or larger cap across the motor power supply, solid common (GND) connections. Sparking motor commutators can cause all sorts of problems.


body:
The L298 has a pair of darlington bipolar transistors in each motor lead. This will cause a voltage drop of at least 1.4V on each lead or 2.8V to the motor, starving it of power. This voltage drop is burnt up as heat which your battery is supplying. A 9V smoke alarm battery is a bad choice for powering an Arduino even though many place show using it as a power source. Take a look at this link, it has some nice graphs showing just how much the voltage drop will be.
 https://www.powerstream.com/9V-Alkaline-tests.htm The maximum current draw of the Arduino R3 is in the range of 200mA. Try connecting several 9V batteries in parallel and if the problem disappears should the 9V battery.


message:
how to change output PWM based on analog input

I want to give different PWM (D11) signals based on how much voltage is input (A7). How can I change PWM for different analog values?

```c++
#include <LiquidCrystal.h>
#include <ezButton.h>

ezButton button(7);
int count;
int count1;

const float Pin0=A0;
const float Pin1=A1;
const float Pin2=A2;
const float Pin7=A7;

float valueA;
float valueB;
float valueC;
int valueD;

const float rs = 1, en = 2, d4 = 3, d5 = 4, d6 = 5, d7 = 6;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  TCCR2B = 0b00000001; // x1
  TCCR2A = 0b00000011; // fast pwm
  pinMode(11, OUTPUT);
  pinMode(9, OUTPUT);
  button.setDebounceTime(5); // set debounce time to 50 milliseconds
  button.setCountMode(COUNT_FALLING);
  lcd.begin(16, 1);
  pinMode(Pin0, INPUT);
  pinMode(Pin1, INPUT);
  pinMode(Pin2, INPUT);
  pinMode(Pin7, INPUT);
}

void loop() {
  float a;
  float b;
  float c;

  valueD = analogRead(Pin7);

  digitalWrite(9, HIGH);
  digitalWrite(9, LOW);
  valueA = analogRead(Pin0);
  digitalWrite(9, HIGH);

  a = valueA * 5 / 1023;
  b = valueB * 5 / 1023 * 1.91 - a;
  c = valueC * 5 / 1023 * 0.182;

  valueB = analogRead(Pin1);
  valueC = analogRead(Pin2);

  button.loop();
  int count = button.getCount();
  count1 = constrain(count, 0, 4);
  if (count1 == 0) {
    lcd.print("Bal-Chg");
  }
  if (count1 == 1) {
    lcd.print("V1: ");
    lcd.print(a);
    lcd.print("V");
  }
  if (count1 == 2) {
    lcd.print("V2: ");
    lcd.print(b);
    lcd.print("V");
  }
  if (count1 == 3) {
    lcd.print("I:");
    lcd.print(c);
    lcd.print("A");
  }
  if (count1 == 4) {
    button.resetCount();
  }

  delay(500);
  lcd.clear();
}
```

body:
The [`map()` function][1] can help. Supply it the minimum and maximum possible values of the A/D output, and the minimum and maximum inputs to the PWM. (This as assuming you expect the full range of inputs and want the full range of outputs.) It will do the calculations for you. You'll have to code reading the A/D and writing the PWM.

  [1]: https://reference.arduino.cc/reference/en/language/functions/math/map/


message:
I want to have separate Keypad passcodes to light up an RGB and run a DC Motor in one code. 6113 for RGB and 4613 for the DC Motor

#include <Keypad.h>

    const int ROW_NUM = 4; //four rows
    const int COLUMN_NUM = 3; //three columns

    const int PIN_RED = 2;
    const int PIN_GREEN = 3;
    const int PIN_BLUE = 4;

    const int MOTOR_PIN1 = 5;
    const int MOTOR_PIN2 = 13;

    char keys[ROW_NUM][COLUMN_NUM] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'*','0','#'}
    };

    byte pin_rows[ROW_NUM] = {12, 11, 10, 9};
    byte pin_column[COLUMN_NUM] = {8, 7, 6};

    Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

    const String password_1 = "6113";
    const String password_2 = "4613";
    String input_password;

    void setup(){
      Serial.begin(9600);
      input_password.reserve(32); // maximum input characters is 33, change if needed
    }

    void loop(){
         loop_RGB();
         loop_DCMOTOR();
    }

    void loop_RGB(){
      char key = keypad.getKey();

      if (key){
        Serial.println(key);

        if(key == '*') {
          input_password = ""; // reset the input password
        } else if(key == '#') {
          if(input_password == password_1) {
            Serial.println("password is correct");

      analogWrite(PIN_RED,   255);
      analogWrite(PIN_GREEN, 0);
      analogWrite(PIN_BLUE,  0);

      delay(1000); // keep the color 1 second

      analogWrite(PIN_RED,   0);
      analogWrite(PIN_GREEN, 255);
      analogWrite(PIN_BLUE,  0);

      delay(1000); // keep the color 1 second

      analogWrite(PIN_RED,   0);
      analogWrite(PIN_GREEN, 0);
      analogWrite(PIN_BLUE,  255);

      delay(1000);
          } else {
            Serial.println("password is incorrect, try again");
          }

          input_password = ""; // reset the input password
        } else {
          input_password += key; // append new character to input password string
        }
      }
    }

    void loop_DCMOTOR(){
      char key = keypad.getKey();

      if (key){
        Serial.println(key);

        if(key == '*') {
          input_password = ""; // reset the input password
        } else if(key == '#') {
          if(input_password == password_2) {
            Serial.println("password is correct");

         digitalWrite(MOTOR_PIN1, HIGH);
         digitalWrite(MOTOR_PIN2, LOW);
         delay (3000);

          } else {
            Serial.println("password is incorrect, try again");
          }

          input_password = ""; // reset the input password
        } else {
          input_password += key; // append new character to input password string
        }
      }
    }

body:
In this program, the functions `loop_RGB()` and `loop_DCMOTOR()` are
taking turns to try to read the password. If you hit `#` after typing
the password for the LED, and `loop_DCMOTOR()` happens to to read your
key press, it will tell you the password is wrong, and reset what you
have typed.

As already stated in a comment and an answer, the solution is to read
the keypad in only one place. You could write a dedicated function for
this, but I would instead just put this code in loop:

```c++
void loop() {
    char key = keypad.getKey();

    if (key) {
        Serial.print("key pressed: ");
        Serial.println(key);
        if (key == '*') {  // '*' means reset the input
            input_password = "";
        } else if (key == '#') {  // '#' means validate the input
            if (input_password == password_1) {
                Serial.println("Corect RGB LED password.");
                actuate_LED();
            } else if (input_password == password_2) {
                Serial.println("Corect motor password.");
                actuate_motor();
            } else {
                Serial.println("Incorrect password.");
            }
            input_password = "";  // reset the input
        } else {
            input_password += key;  // append new character
        }
    }
}
```

Here, `actuate_LED()` and `actuate_motor()` are supposed to be small
functions that do the device actuation and nothing more. They do not
concern themselves with the keypad or a password.


message:
Hysteresis and scaling range

[Here][1] I asked about how to add an hysteresis on ADC readings. The answer received was very good and it worked out of the box.

Still I'm having troubles trying to generalize the `resample` function in order to map the input values to a different range of output values, where the lower rail is **not** zero.

If the lower rail was zero, it would be enough to change the shifts with a multiplication/division for `1024 / max`. But I cannot understand how to handle the lower rail when `min > 0`.

My attempt:

    int Menu::resample(int adc, int *value, byte min, byte max)
    {
        // sanity checks omitted: min < max and max < 128

        double m = 1015.0 / (max - min); // 1015 = 1023 - 8 (1 LSB of low-res output)
                                         // otherwise it reaches 126 even if max = 127
        int q = min << 3;

        int lowerTest = (q + *value * m) - ADC_HYSTERESIS;
        int higherTest = (q + (*value + 1) * m) + ADC_HYSTERESIS;

        int lowerOutput = min + (adc + ADC_HYSTERESIS) / m;
        int higherOutput = min + (adc - ADC_HYSTERESIS) / m;

        if (adc < lowerTest) *value = lowerOutput;
        else if (adc >= higherTest) *value = higherOutput;

        if (*value > max) *value = max;
        if (*value < min) *value = min;
        return *value;
    }

There is something wrong in my math, since the comparison always falls under the first `if` (i.e. `*value = lowerOutput`).

May you help me to fix this code so I can have an hysteresis on any scaled output?

**Note**: instead of using a static variable for value as in the answer, I use a `struct`:

    slider.value = resample(adc, &slider.lastValue, slider.min, slider.max);

where:

    typedef struct
    {
        int value;
        int lastValue;
        int min;
        int max;
    } slider_t;

    slider_t slider;

  [1]: https://arduino.stackexchange.com/q/93117/54202

body:
First, a couple of comments about this first attempt.

There is no point in storing in `slider_t` both `lastValue` and `value`.
The way this is used, both fields are always updated with the same
value: `lastValue` is updated by pointer inside `resample()`, while
`value` is updated by assigning it the value returned by `resample()`. I
would suggest removing the field `lastValue` and either:

1. providing `value` by value (rather than by pointer) to `resample()`,
   or

2. providing a reference to a `slider_t` as the only parameter.

The first approach is better if you want to avoid `resample()` and
`slider_t` being tightly coupled.

Next, there is a mix between `int` and `byte` types. If you want to save
memory, and improve consistency, I would use `byte` for all low-res
values living in the output domain of `resample()`. Actually, I would
use `uint8_t`, which is the same, only more standard.

Then, there are a few things I do not understand in this code:

* Why `1015`? It seems to me this number should be dependent on the
  width of output range.

* Why `min << 3`? Again, this is a division by 8, while the proper
  factor should be probably be output-range dependent.

Now, for the solution, I would try this approach:

* Compute the minimum and maximum possible output values consistent with
  the provided input, accounting for the hysteresis.

* Constrain the output to remain within this bracket.

In code:

```c++
uint8_t Menu::resample(int adc, uint8_t value, uint8_t min, uint8_t max)
{
    value = constrain(value, min, max);  // just in case...
    uint8_t lower = map(adc - ADC_HYSTERESIS, 0, 1024, min, max+1);
    uint8_t upper = map(adc + ADC_HYSTERESIS, 0, 1024, min, max+1);
    return constrain(value, lower, upper);
}
```

Some points worth noticing:

1. I do not know whether this was originally intended, but the Arduino
   function `map(x, in_min, in_max, out_min, out_max)` does a poor job
   at mapping the interval [`in_min`, `in_max`] to [`out_min`,
   `out_max`]. It does, however, do a good job at mapping [`in_min`,
   `in_max`) to [`out_min`, `out_max`) (mind the semi-open intervals).
   This is why the four last parameters of the call to `map()` are (0,
   1024, min, max+1), rather than (0, 1023, min, max).

2. The first call to `constrain()` can be removed if the caller bears
   the responsibility of guaranteeing this precondition.

3. If the precondition is valid (or, like here, enforced), it will also
   hold for the returned value, provided `adc` is within [0, 1024).

This method would be called like this:

```c++
slider.value = resample(adc, slider.value, slider.min, slider.max);
```


message:
What are the Vs and Vss pins on an L293D chip for?

I made a simple test circuit to help me understand the [L293D](https://www.arduino.cc/documents/datasheets/H-bridge_motor_driver.PDF) H-bridge that comes with the Arduino starter kit.

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

Digital output pins of the Arduino are wired to the input pins on the H-bridge. Arduino code alternately sends 1/0 and 0/1 down those two output pins, basically (as I understand it) creating an extremely low frequency alternating current in the two output pins on the H bridge. Two LEDs are wired in parallel to the output pins, in opposite directions, so they flash, demonstrating the alternating nature of the current.

The project I'm working on from the starter kit right now is the Zoetrope ([page 102](https://www.eitkw.com/wp-content/uploads/2020/03/Arduino_Projects_Book.pdf)), and in that project the L293D is used to control a motor. The Arduino's 5V is connected to Vss and a 9V battery is connected to Vs.

So I'm a little surprised that I got it to work without using the Vs and Vss pins at all. What are they for? I did try swapping the LEDs out for the motor and it doesn't work (not enough power, I guess). But if I hook the 5V on the Arduino up to the Vs pin, it does! Hooking the 5V up to only the Vss pin, however, is not enough to power the motor.

So I sort of get the idea that without Vs and Vss current, the current from the input pins is enough to light the LEDs, but what I don't understand is:

1. If the voltage on the input pins isn't enough to drive the motor, how come connecting the 5V to the Vs pin is? It's the *same* voltage as is on the input pins.

2. What is the Vss pin for?

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

body:
As you can see in the linked L293D PDF

**VS** is Supply Voltage (here connect the power source for motor)

**VSS** is Logic Supply Voltage (here connect the power source for the L293D chip logic - usually the same source as for +5V for Arduino)

2. The VSS suplies energy for the L293D to work correctly (like the Enable pin, inputs and such)

Also as you can see on the **BLOCK DIAGRAM** there are some mysterious diodes connected in little unusual way - at least on first look. When everything is well powered and normal, there are closed and do not conduct any current.

But if the voltage on (say) OUT1 became negative, then the lower diode connected to ground would start lead current and pull the OUT1 to the ground.

Similary if the voltage on OUT1 became higher, then the **VS** power source, then the top diode would open and drag the OUT1 down to the VS voltage.

It is for secure the internal circuits to work in sane environment. And if there is a motor (if any other inductance as relay or so), then there will be such peaks.

Similar security diodes are probably also on all input pins. (It is usual in logical circuits to limit input voltage in such way.) As you did not connect the VS to any power, when you send +5V (logical one) to any input pin, it was "pulled down" to VS via some such diode. This effectively "pulled up" the VS near the voltage on the pin and with VS powered the internal logic of L293D begin work, so magic happened.

1. There may be even some similary secured connection between VS and VSS, so some power from your Arduino output pin **leaked** by **long** and **non-planed** way to your LEDs and made them shine. LEDs do not need much current.

When you connected the motor instead, the long way proved to be too long and to have too much rezistence along it, that (nearly) all the voltage was distributed along it and on the motor was nearly nothing - and nearly no current was able go thru. Which is luck, as Arduino output pins have limit of 20 mA of current (or so).

When you conected +5V on the VS pin, there is much shorter way from it to motor and also with a lot less resistance along it, so there was enought voltage and enought current for the motor, so it was able to run.

Try it and measure the resistence of your motor - you will see, it will be nearly nothing, compared to the R=220 you used with the LEDs.

While it may not be visible in such simple example like this, you really **should** power the VSS so the logic there would work reliable.


message:
Pin outping 1V instead of expected 5V, not hardware related

Heyo everyone !

I'm in a project where I need to send a signal if I detect vaccuum.
I'm sending the signal on PIN 9 but I soon realized that I was only getting 1V.

Tought I was alternating between signal/no_signal but the log provided me with constant and consistent values.

Then I started doubting about my board so I made PIN 10 always output. Under the same load as PIN 9 (I switch the cable connecting from PIN 9 to the circuit, to PIN 10 to the circuit ), I get a good 5V. Thus, I exclude any load problem.

Regarding the PIN output issue, you can all see that it's not missing.

My last hypothesis is that there's some sort of sorcery with my code that I don't know and couln't find on the internet...

Any idea on what might be going on ?

```
// Constant
const int BL1 = 9;// BINARY LED 1 pin
const int TEST = 10;// BINARY LED 1 pin
const int AP = A0;// ANALOG PRESSOSTAT pin
const int P = 85;// TRIGGER PRESSURE value

// Variables
int LS1 = LOW;  // LED 1 STATE
float RPV = 1; // Raw Pressostat Voltage (0-1024)
float PV = 1; // Pressostat Voltage (V)
float PDP = 20; // Pressostat Deduced Pressure (kPa)

// Initialization of pins at startup
void setup() {
  pinMode(AP, INPUT); // ANALOG PRESSOSTAT pin set as INPUT
  pinMode(BL1, OUTPUT);// BINARY LED 1 pin set as OUTPUT
  pinMode(TEST, OUTPUT);// BINARY LED 1 pin set as OUTPUT
  pinMode(LED_BUILTIN, OUTPUT);// LED_BUILTIN pin set as OUTPUT
  Serial.begin(9600);
}

void loop() {
    digitalWrite(TEST, HIGH);
    RPV = analogRead(AP);
    PV = (RPV/1024)*5;
    PDP = (-1)*(PV-1)*(-101/4);
    Serial.print("Pression: ");
    Serial.print(PDP);
    if ( PDP > P ){
      int LS1 = HIGH;  // LED 1 STATE
      digitalWrite(BL1, HIGH);
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.print(" | LED: 1");
      }
    else {
      int LS1 = LOW;  // LED 1 STATE
      digitalWrite(BL1, LOW);
      digitalWrite(LED_BUILTIN, LOW);
      Serial.print(" | LED: 0");
    }
    digitalWrite(BL1, LS1);
    Serial.print(" | Trigger: ");
    Serial.println(P);

  }
```

body:
Here's a working script (I went back to PWM pin, if that matter at all)

```
void loop() {
  ...// unrelated code
  if (PDP > P) {
    LS1 = HIGH;                               // LED 1 HIGH
    digitalWrite(BL1, LS1);
    digitalWrite(LED_BUILTIN, LS1);
    Serial.print(LS1);
  }
  else {
    LS1 = LOW;                                // LED 1 STATE
    digitalWrite(BL1, LS1);
    digitalWrite(LED_BUILTIN, LS1);
    Serial.print(LS1);
  }
  ...// more unrelated code
}
```


body:
I'll reduce it a little

    void loop() {
        // ... doesn't matter
        if ( PDP > P ){
          int LS1 = HIGH;            // shadows global variable (creates local variable that won't exist after })
          digitalWrite(BL1, HIGH);
        } else {
          int LS1 = LOW;             // again shadows global variable
          digitalWrite(BL1, LOW);
        }
        digitalWrite(BL1, LS1);      // LS1 is still LOW

      }

Mistery solved


message:
Maduino (Arduino Zero) at91samd21g18 - Unable to connect to the serial port

I have been using this device very little but it was use to work, and it also gave me the same issue in the past, the somewhat I was able to upload again.

I tried to use the reset button, and short GRD with RST pins, but nothing helped.
The device is recognised as **Arduino MRK1000** and connected.
I also tried to specify **Arduino Zero (Native USB Port)**.
*Under Tools > Get Board* Info I get:
````
BN: Arduino MKR1000
VID 0x2341
PID: 0X804E
SN: 414C4E1[...]
````

**My issue:**\
When I try to upload the sketch (even empty) it hangs forever, or some times it shows the same message shown when you unplug the device while uploading.
````
No device found on COM5
Failed uploading: uploading error: exit status 1
````
The serial monitor is unable to connect
````
Sketch uses 33108 bytes (12%) of program storage space. Maximum is
262144 bytes. Global variables use 3552 bytes (10%) of dynamic memory,
leaving 29216 bytes for local variables. Maximum is 32768 bytes.
No device found on COM5 Failed uploading: uploading error: exit status 1
````

**Attempted resolution actions:**\
I tried to use the reset button, and short GRD with RST pins, but nothing helped.
I tried multiple USB ports, different PC, different cable.

**For information about the device:**\
https://github.com/Makerfabs/Maduino-Zero-4G-LTE
https://wiki.makerfabs.com/Maduino_Zero_4G_LTE.html

**Requests:**\
If you could guide me, maybe I can try to "factory reset" the MCU, or maybe try to connect in a different way.\
I read about the bootloaders but I don't know how they work and I don't want to try alone and make worse.\
The manufacturer didn't reply to my messages,on GitHub I didn't receive any reply either, so this is one last attempt before I throw this into the bin.\
If anyone can recommend al alternative board with GPS and LTE/4G connectivity would be a plus.

body: As suggested by Juraj (thank you), **pushing the reset button twice** allowed me to upload an empty sketch and "revive" an otherwise unusable device.


message:
RMS Voltage Value

it has been a week that I'm struggling with the arduino to measure the RMS Voltage value. By OSC I can see that the RMS voltage value changes around 3V. But I can't see it by serial port. I think my sampling or conversion has problem and I can't find it. I really appreciate it if anyone can take a look at my codes and suggest anything.

    float readRMS_new(int pin, int vref) {
      int numReadings[100];
      const unsigned long samplingInterval = 2;  // Interval between RMS calculations in milliseconds
      unsigned int readingsSum = 0;   // Sum of squared readings
      unsigned int readingsCount = 0; // Number of readings taken
      unsigned long lastSamplingTime = 0;  // Time of the last RMS calculation
      float rmsVoltage = 0;
      float finalVoltage = 0;
      float circuitGain = 4.31;  // Gain of the circuit

      unsigned long currentTime = millis();  // Current time

      // Check if it's time to perform an RMS calculation
      if (currentTime - lastSamplingTime >= samplingInterval) {
        lastSamplingTime = currentTime;  // Update the last sampling time

        // Perform RMS calculation
        for (int i = 0; i < 100; i++) {
          numReadings[i] = analogRead(pin);
          readingsSum += pow(numReadings[i] - vref, 2);
          readingsCount++;
        }

        // Calculate RMS voltage
        float rms = sqrt(readingsSum / readingsCount);
        rmsVoltage = rms * 0.0048;
        finalVoltage = rmsVoltage * circuitGain;

        if (finalVoltage > 0.0f) {
          // Print RMS voltage
          Serial.print("RMS Voltage: ");
          Serial.println(finalVoltage, 3);  // Print with 3 decimal places
        }

        // Reset variables for the next RMS calculation
        readingsSum = 0;
        readingsCount = 0;

        return finalVoltage;
      }

      return 0.0f;  // Return 0 if it's not time to perform an RMS calculation
    }

Regards

Farzaneh

body:
There are multiple issues with this piece of code:

1. Local variables, i.e. variables defined inside functions or braced
   blocks, are created each time the execution enters the function or
   block, and destroyed when it leaves it. Thus, `lastSamplingTime` will
   always be zero when it is checked. If you want the variable to
   preserve its value across invocations of the function, you have to
   either make it global or qualify it as `static`.

2. There is no point in storing the readings in an array, as you never
   read back any element of the array other than the one you just
   stored. The array is then eating memory for no good reason.

3. The Arduino will not be able to take more than one reading every
   112 µs, or 100 readings in 11.2 ms. There is no point
   in trying to ensure a 2 ms interval between RMS calculations.

4. There is no point in counting the readings: you know you are taking
   100 of them.

5. You should avoid using `pow()` for squaring an integer: this is a
   floating-point function which is prone to rounding errors.

6. Maybe the most serious issue: on the Mega, an `unsigned int` is
   16-bits, and cannot store numbers larger than 65,535. `readingsSum`
   is very likely going to overflow and give you a meaningless result.

7. Returning zero to mean “no data available” is probably not a very
   good choice, as zero is also a perfectly valid result. You should
   consider returning an impossible value, like `-1` (an RMS reading
   cannot be negative).

Here is how I would write the computation of the RMS value:

```c++
long readingsSum = 0;
for (int i =0; i < 100; i++) {
    long reading = analogRead(pin) - vref;
    readingsSum += reading * reading;
}
float rms = sqrt(readingsSum / 100);
```

Note that `reading` is of type `long` in order to avoid the squaring to
overflow.


body:
Thank you all for your time dedication. Finally increasing the sampling and optimize the same codes I could achieve my goals. I will post the functioning code for those who might need it.

```
float readRMS(int pin, int vref) {

  int lecturas[200]; // declaring the matrix

  float suma = 0; // sum of the squares

  float rms = 0;  // squares mean

  float volt = 0;  //

  float Volt_Final = 0;

  for (int cont = 0; cont < 200; cont++) {

    lecturas[cont] = analogRead(pin);

    delayMicroseconds(200);
  }
  for (int j = 0; j < 200; j++) {

    //Serial.println(lecturas[j]);

    suma = suma + pow((lecturas[j] - vref), 2);

    //Serial.println(suma);
  }
  rms = sqrt((suma / 200));

  volt = (rms / 1024) * 5;

  //Serial.println(volt);

  //suma=0;

  // Reset variables for the next RMS calculation

  rms = 0;

  lecturas[200] = 0;

  //Volt_Final = (volt * 4.31); //real voltage with circuit gain

  return volt;
}
```


message:
manage some output based on some parameter and rtc

i'm trying to create a program that given a configuration (i've used multiple struct nested) i need in loop() to check for each output if they need to be on or off and set the output accordingly

let me explain the configuration (i'm not sure that this is the best way to make and store this config, suggestions are appreciated)
```
struct Period
{
    String name;
    String type;
    String value;
};

struct State
{
    String name;
    Period periods[2];
};

struct Output
{
    String name;
    int pin;
    int forcePin;
    State states[2];
};

Output outputs[4];
```
now i populate the first object (this is something that need to be editable by the user and i was thinking to store it in the EEPROM, for now in the setup() i do this
```
    outputs[0].name = "OUTPUT 1";
    outputs[0].pin = 27;
    outputs[0].forcePin = 25;
    outputs[0].states[1].name = "STATE 1";
    outputs[0].states[1].periods[0].name = "day";
    outputs[0].states[1].periods[0].type = "BOOL";
    outputs[0].states[1].periods[0].value = "ON";
    outputs[0].states[1].periods[1].name = "night";
    outputs[0].states[1].periods[1].type = "BOOL";
    outputs[0].states[1].periods[1].value = "OFF";
    outputs[0].states[0].name = "STATE 2";
    outputs[0].states[0].periods[0].name = "day";
    outputs[0].states[0].periods[0].type = "BOOL";
    outputs[0].states[0].periods[0].value = "ON";
    outputs[0].states[0].periods[1].name = "night";
    outputs[0].states[0].periods[1].type = "BOOL";
    outputs[0].states[0].periods[1].value = "OFF";
```
then in the loop i have few function that determinate the state and period and i call this function that should manage all the outputs
globalState in loop read from an input and set the variable
globalPeriod check the time and set if night or day
```
void manageOutputs()
{
    for (Output out : outputs)
    {
        Serial.println(out.name);
        Serial.println(out.pin);
        Serial.println(out.forcePin);
        if (digitalRead(out.forcePin) == LOW)
        {
            Serial.println("forced on set output");
            digitalWrite(out.pin, HIGH)
            continue;
        }

        Serial.println(out.states[globalState].name);
        Serial.println(out.states[globalState].periods[globalPeriod].name);
        Serial.println(out.states[globalState].periods[globalPeriod].type);
        Serial.println(out.states[globalState].periods[globalPeriod].value);
        if (out.states[globalState].periods[globalPeriod].type.equals("BOOL")) {
            if (out.states[globalState].periods[globalPeriod].value.equals("ON")) {
                digitalWrite(out.pin,HIGH);
            } else {
                digitalWrite(out.pin,LOW);
            }
        }
    }
}
```
i have multiple type of output in mind for example TIMER (so in the value field i would have some parameter to call another function that will alternate the output on and off for the time given) will have something like "15:10" so it will stay 15 minutes on and 10 minutes off, or a condition (for example if VAR1 > 50) so the field value would have "VAR1:>:50" so it will turn on only if the condition is met. So i will have a switch case where now i check if BOOL.

now that i hope that i have explained the situation, i would like to know if it's a good way to have 3 nested struct or if there is a better solution considering the necessity to have it stored in EEPROM, and if this is a good way to have this kind of condition like this or if there is a better way.
Considering also that in the future i would like to make a webpage or an api to update this kind of configuration from a pc (maybe using a esp-8266 for that, that is also connected to the arduino, or do everything with an esp32, but i would like first to have the basic loop working and then i will make the "UI")

thanks a lot

body:
There are many uses of the `String` class in these code snippets. Using
strings is quite natural in some higher-level languages. On an Arduino,
however, I would strongly advise you against this for two reasons:

1. String objects use dynamic memory, which is not friendly to the small
   amount of RAM available on a typical Arduino.

2. Saving a String to EEPROM is not trivial: you do not want to save the
   String object (it contains a pointer that would not make sense in
   EEPROM context), and you instead have to save the character array it
   refers to. This could involve handling complex memory allocation
   withing the EEPROM.

Instead of a string meant to handle one of a predefined set of values
(`"BOOL"`, `"TIMER"`, ...), use an `enum`. This is similar to an `int`,
where each possible value has been given a name (`TYPE_BOOL` is 0,
`TYPE_TIMER` is 1, ...). Instead of a string holding numbers, store the
numbers themselves. In essence, you want to create a data storage format
that is friendly to the binary nature of the CPU. If you really have to
store strings, e.g. for names (are those `name` fields really useful?
they do not look so in the provided example), limit their length and
store them as fixed-size character arrays.

The `period::value` field is interesting in that it can store different
kinds of information depending on the `type` field. For such a situation
the appropriate data structure is a [discriminated union][]. A `union`
is like a `struct` except that all fields share the same memory space
and only one can be valid at a time. In a discriminated union, the
`union` is accompanied by  a `ytpe` field that tells us which is the
valid field.

Applying those principles to your problem could give this kind of data
structure:

```c++
// All the possible Period types.
enum Type {
    TYPE_BOOL,
    TYPE_TIMER,
    // etc.
};

// This is a discriminated union.
struct Period
{
    Type type;
    union {  // one union member per possible type.
        bool bool_value;  // valid when type == TYPE_BOOL
        struct {
            int on_time;
            int off_time;
        } timer_value;  // valid when type == TYPE_TIMER
        // etc.
    };
};

struct State
{
    Period periods[2];
};

struct Output
{
    int pin;
    int forcePin;
    State states[2];
};
```

These data structures can be trivially saved in EEPROM, as they are
self-contained: they hold no pointers to data stored in dynamic memory.

Then, in `manageOutputs()`, you will read a period's `bool_value` only
when `type` is `TYPE_BOOL`, it's `timer_value` only when `type` is
`TYPE_TIMER`, etc:

```c++
void manageOutputs()
{
    for (Output out : outputs)
    {
        if (digitalRead(out.forcePin) == LOW) {
            digitalWrite(out.pin, HIGH);
            continue;
        }
        Period &period = out.states[globalState].periods[globalPeriod];
        switch (period.type) {
            case TYPE_BOOL:
                if (period.bool_value) {
                    digitalWrite(out.pin, HIGH);
                } else {
                    digitalWrite(out.pin, LOW);
                }
                break;
            case TYPE_TIMER:
                digitalWrite(out.pin, HIGH);
                delay(period.timer_value.on_time);
                digitalWrite(out.pin, LOW);
                delay(period.timer_value.off_time);
        }
    }
}
```

[discriminated union]: https://en.wikipedia.org/wiki/Tagged_union


message:
are 4AA batteries (6V) power my arduino

I'm actually new to using arduino , and trying to make a simple car, using two dc motors, a l298n and an arduino, the problem is that a 9v battery doesn't seem enough to just power the l298n and one dc motor , but in the internet some people use an 4AA battery which is 6v and power the arduino 4 dc motors and the l298n so how ?

body:
The name [Arduino][1] refers to dozens if not hundreds of different board and processor designs. Since a specific board / processor was not asked about we can only talk in generic terms.

Almost all Arduinos run at either 5 Volts or 3.3 Volts and contain a regulator to convert a wide range of Voltages to this value. That said, these regulators need a minimal drop between the input voltage and the desired regulated voltage in order to operate.  Some require less and are referred to as [LDO or Low Drop Out regulators][2].

As a worse case, consider if this Arduino does not use an LDO regulator and operates at 5 Volts. The difference between the 6 Volt input and Arduino operating Voltage is only 1 Volt. Further, consider if the batteries were not fresh and were only supplying, say, 5.5 Volts. Finally, consider if one or both motors started drawing heavy current from the batteries causing a further drop in Voltage. Any of these cases could cause the Arduino to reset / behave unexpectedly.

Consider trying to use the 9 Volt battery to power the Arduino and the 6 Volt battery to power the motors.

  [1]: https://learn.sparkfun.com/tutorials/what-is-an-arduino/all
  [2]: https://en.wikipedia.org/wiki/Low-dropout_regulator


body:
I understand you situation completely as I had also previously experienced the same problem. 9 V batteries are not enough to get the job done.

Therefore, I suggest you to use two 3.7 V Batteries. These batteries are a great alternative and had solved my problem. I hope it will do the same to you.


body:
To properly answer your question instead of taking a SWAG as I did would Be for you to post links giving technical information on each of the hardware devices and which Arduino you are using.

Nine Volt (smoke alarm) batteries do not have enough power to properly power an Arduino. Use some larger cells. There are so many places that show this improper configuration, it just will not last if it even works for a short while. Great for the battery manufacturers.

You can also purchase a SEPIC converter for a few bucks, this is a combination Buck/Boost converter. You set the output voltage you want and it will maintain it as long as you're getting the minimum voltage from the battery, even if the battery is at 3.5V and the output is at 5V. The input will range from about 3V to 30V and it will maintain its setpoint. This range is dependent on the device you pick.

The L298N is about the worce choice you can make for the motor driver. It has darlington bipolar outputs, that drop about 1.4 volts per lead or 2.8 - 3.2 volts to the motor depending on the load. That voltage drop is burnt up as heat and is doing nothing useful. Purchase an H-Bridge that is large enough to drive the motor that has MOSFET outputs, you will be much happier with that.

For batteries use whatever is convenient, the SEPIC converter solves that problem. Best to pick them to power the motor and use the SEPIC to power the Arduino Vin pin at about 7.5V. Doing it via the Vin is not as efficient as doing a 5V direct but you get the additional filtering on that input circuit. A lot depends on which Arduino we are talking about. Since you did not mention one I am assuming either a UNO or Nano.


message:
Mobile hotspot with wemos d1 mini

I recently got a wemos d1 mini and now am trying to connect it to my IPhone 13's hotspot, however it doesn't connect, I tried to run the wifiscan example - and it doesn't even detect it there.

I tried connecting it to my home router - and this worked hence I have no ideas on fixing it, so any help would be appreciated!

body:
By default the iPhone hotspot is 5GHz only, which is why your ESP8266 can't see it. The ESP8266's WiFi radio is 2.4GHz only.

To enable 2.4GHz on the iPhone hotspot, turn on the "Maximize Compatibility" button under "Settings | Personal Hotspot". Then 2.4GHz devices should be able to connect to the phone.

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

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


message:
Having issues understanding what "#define GET_STATUS" does

I am trying to use a [Waveshare 4.2inch e-paper display][1] with an [Adafruit Feather Adalogger M0][2], but am having issues with two separate instances of `#define GET_STATUS` being defined differently in different locations. More specifically, in the [Demo Library (download)][3] for the Waveshare display, one of the files (epd4in2.h) defines GET_STATUS as 0x71. However, in a file (USBCore.h) I downloaded from the board manager in the ArduinoIDE to be able to support the Feather Adalogger, GET_STATUS is defined as 0.

I've tried messing with the values to see if making them match (both as 0x71 and both as 0) would solve the issue, but it didn't change anything. I can't find any information about what GET_STATUS in general, so I'm unsure what I can even try to fix this issue. Furthermore, I can't find any instances of GET_STATUS being used, so I'm unsure what its significance even is. So, basically, my questions are: 1) what is the significance of GET_STATUS, and 2) how can I reconcile it being used differently in two different places?

Below is the code I'm trying to run (it's the demo code from Waveshare), and the libraries other than "<SPI.h>" are in the demo library download from Waveshare.

```
#include <SPI.h>
#include "epd4in2.h"
#include "imagedata.h"
#include "epdpaint.h"

#define COLORED     0
#define UNCOLORED   1

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

  if (epd.Init() != 0) {
    Serial.print("e-Paper init failed");
    return;
  }

  /* This clears the SRAM of the e-paper display */
  epd.ClearFrame();

  /**
    * Due to RAM not enough in Arduino UNO, a frame buffer is not allowed.
    * In this case, a smaller image buffer is allocated and you have to
    * update a partial display several times.
    * 1 byte = 8 pixels, therefore you have to set 8*N pixels at a time.
    */
  unsigned char image[1500];
  Paint paint(image, 400, 28);    //width should be the multiple of 8

  paint.Clear(UNCOLORED);
  paint.DrawStringAt(0, 0, "e-Paper Demo", &Font24, COLORED);
  epd.SetPartialWindow(paint.GetImage(), 100, 40, paint.GetWidth(), paint.GetHeight());

  paint.Clear(COLORED);
  paint.DrawStringAt(100, 2, "Hello world", &Font24, UNCOLORED);
  epd.SetPartialWindow(paint.GetImage(), 0, 64, paint.GetWidth(), paint.GetHeight());

  paint.SetWidth(64);
  paint.SetHeight(64);

  paint.Clear(UNCOLORED);
  paint.DrawRectangle(0, 0, 40, 50, COLORED);
  paint.DrawLine(0, 0, 40, 50, COLORED);
  paint.DrawLine(40, 0, 0, 50, COLORED);
  epd.SetPartialWindow(paint.GetImage(), 72, 120, paint.GetWidth(), paint.GetHeight());

  paint.Clear(UNCOLORED);
  paint.DrawCircle(32, 32, 30, COLORED);
  epd.SetPartialWindow(paint.GetImage(), 200, 120, paint.GetWidth(), paint.GetHeight());

  paint.Clear(UNCOLORED);
  paint.DrawFilledRectangle(0, 0, 40, 50, COLORED);
  epd.SetPartialWindow(paint.GetImage(), 72, 200, paint.GetWidth(), paint.GetHeight());

  paint.Clear(UNCOLORED);
  paint.DrawFilledCircle(32, 32, 30, COLORED);
  epd.SetPartialWindow(paint.GetImage(), 200, 200, paint.GetWidth(), paint.GetHeight());

  /* This displays the data from the SRAM in e-Paper module */
  epd.DisplayFrame();

  /* This displays an image */
  epd.DisplayFrame(IMAGE_BUTTERFLY);

  /* Deep sleep */
  epd.Sleep();
}

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

}
```

When I run the code, I get the following messages
```
In file included from /home/beingpool/Arduino/epd4in2-demo/epd4in2-demo.ino:28:
/home/<user>/Arduino/libraries/epd4in2/epd4in2.h:64: warning: "GET_STATUS" redefined
   64 | #define GET_STATUS                                  0x71
      |
In file included from /home/beingpool/.arduino15/packages/adafruit/hardware/samd/1.7.11/cores/arduino/Arduino.h:157,
                 from /home/beingpool/.var/app/cc.arduino.IDE2/cache/arduino/sketches/96EFEDEA56FF573B678089A960FFC685/sketch/epd4in2-demo.ino.cpp:1:
/home/beingpool/.arduino15/packages/adafruit/hardware/samd/1.7.11/cores/arduino/USB/USBCore.h:23: note: this is the location of the previous definition
   23 | #define GET_STATUS     0
      |
```

[1]: https://www.waveshare.com/wiki/4.2inch_e-Paper_Module
[2]: https://www.adafruit.com/product/2796
[3]: https://www.waveshare.com/w/upload/3/39/E-Paper_code.7z

body:
There is no generic meaning in `GET_STATUS`. Apparently both libraries use the very same identifier for their own different purpose.

If you do not use `GET_STATUS` in your sketch, you can remove the definition before the inclusion of "epd4in2.h", like this:

```c++
#include <SPI.h>
#undef GET_STATUS
#include "epd4in2.h"

// ...
```


message:
what is 400 bad request and how to solve this

```
AT+CIPSEND=65
link is not valid

ERROR

OK

OK

OK

OK
STATUS:2

OK
\x0BQ\xADUART_DEF=115200,8,1,0,0ATE0
AT+CWMODE=3
AT+CIPMUX=0
AT+CIPMODE=0
AT+CIPSTATUS
AT+CIPSTART="TCP","api.thingspeak.com",80
AT+CIPSTATUS
CONNECT

OK
STATUS:3
+CIPSTATUS:0,"TCP","52.0.107.28",80,38071,0

OK

OK
> AT+CIPSEND=65
GET api.thingspeak.com/update?api_key=M
Recv 65 bytes
E5K4JWXT2ZBSBZ8&field1=0

SEND OK

+IPD,272:HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Tue, 23 May 2023 05:45:13 GMT
Content-Type: text/html
Content-Length: 122
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
</body>
</html>
CLOSED
```

body:
The server name does not belong to the `GET` request line: it has to be
provided in the `Host` request header.

Try something this:

```c++
server.println("GET /update?api_key=ME5K4JWXT2ZBSBZ8&field1=0 HTTP/1.0");
server.println("Host: api.thingspeak.com");
server.println();  // empty line means "end of request headers"
```


message:
Arduino-project with color sensor and rgb-led

I want to use a color sensor for my Arduino project with Arduino Uno to detect the colors red, green, blue, orange, yellow purple of leaves of paper and then light my RGB led in those colors. I have no errors in my code, but it fails for some reason :( Can someone help me?

here is the code:

    #define s0 8
    #define s1 9
    #define s2 10
    #define s3 11
    #define sensorOut 12

    #define LED_RED 3
    #define LED_GREEN 5
    #define LED_BLUE 6

    // Variabelen voor de kleurwaarden
    int red;
    int green;
    int blue;

    const int RED_COLOR = (255, 0, 0);
    const int GREEN_COLOR = (0, 255, 0);
    const int BLUE_COLOR = (0, 0, 255);
    const int ORANGE_COLOR = (255, 165, 0);
    const int PINK_COLOR = (255, 105, 180);
    const int PURPLE_COLOR = (128, 0, 128);
    const int YELLOW_COLOR = (255, 255, 0);

    int color = 0;

    void setup() {
      // Zet de seriële communicatie op
      Serial.begin(9600);

      // Initialiseer de pinmodi
      pinMode(s0, OUTPUT);
      pinMode(s1, OUTPUT);
      pinMode(s2, OUTPUT);
      pinMode(s3, OUTPUT);
      pinMode(sensorOut, INPUT);

      pinMode(LED_RED, OUTPUT);
      pinMode(LED_GREEN, OUTPUT);
      pinMode(LED_BLUE, OUTPUT);

      // Zet de frequentie van de kleurensensor op 20% (rode filter)
      digitalWrite(s0, HIGH);
      digitalWrite(s1, LOW);
    }

    void loop() {
      // Lees de kleurwaarden
      digitalWrite(s2, LOW);
      digitalWrite(s3, LOW);
      red = pulseIn(sensorOut, digitalRead(sensorOut) == HIGH ? LOW : HIGH);
      delay(20);
      digitalWrite(s3, HIGH);
      blue = pulseIn(sensorOut, digitalRead(sensorOut) == HIGH ? LOW : HIGH);
      delay(20);
      digitalWrite(s2, HIGH);
      green = pulseIn(sensorOut, digitalRead(sensorOut) == HIGH ? LOW : HIGH);
      delay(20);

    // Controleer op verschillende kleuren
    if (red > green && red > blue) {
      color = RED_COLOR; // Rood
    } else if (green > red && green > blue) {
      color = GREEN_COLOR; // Groen
    } else if (blue > red && blue > green) {
      color = BLUE_COLOR; // Blauw
    } else if (red > green && red > blue && green > blue) {
      color = YELLOW_COLOR; // Geel
    } else if (red > green && red > blue && blue > green) {
      color = ORANGE_COLOR; // Oranje
    } else {
      color = 0; // Geen herkende kleur
    }

      // Controleer op verschillende kleuren
      if (color == RED_COLOR) {
        setColor(255, 0, 0); // Rood
      } else if (color == GREEN_COLOR) {
        setColor(0, 255, 0); // Groen
      } else if (color == BLUE_COLOR) {
        setColor(0, 0, 255); // Blauw
      } else if (color == ORANGE_COLOR) {
        setColor(255, 165, 0); // Oranje
      } else if (color == PINK_COLOR) {
        setColor(255, 105, 180); // Roze
      } else if (color == PURPLE_COLOR) {
        setColor(128, 0, 128); // Paars
      } else if (color == YELLOW_COLOR) {
        setColor(255, 255, 0); // Geel
      } else {
        // Geen herkende kleur, zet de led uit
        setColor(0, 0, 0);
      }

      delay(500); // Wacht 500 milliseconden voordat je de volgende kleur controleert
    }

    // Hulpmethode om de RGB-waarden in te stellen
    void setColor(int red, int green, int blue) {
      analogWrite(LED_RED, red);
      analogWrite(LED_GREEN, green);
      analogWrite(LED_BLUE, blue);
    }

body:
Reading your code, I see three points:

1. Your constants are not assigned the values that you think. `const int RED_COLOR = (255,0,0);` sets the integer constant to the value `0`, i.e. the last value of a comma-separated sequence, [see here][1]. Instead, enumerate your color constants, i.e. set red=1, blue=2, etc. Or define a struct with three integer components.
2. The variable `color` will never be assigned the values `ORANGE_COLOR`, `PURPLE_COLOR` nor `YELLOW_COLOR`, because of the way you structured the expressions in the if-then-else block. If `red > green && red > blue`, the program will never even check whether `red > green && red > blue && blue > green`, because it already entered the first block. And `PURPLE_COLOR` is not listed in the upper if-else-block at all. Also, I would expect some `CYAN_COLOR` somewhere in there to cover the shades between green and blue.
3. What is the exact type of the color sensor? It seems strange to me that it transmits its data via the length of a pulse. If it doesn't, `pulseIn()` is the wrong method to use. If it really does, you may have a race condition here: I guess that writing to the pins `s2`/`s3` triggers the sensor to start the "data pulse", in which case `digitalRead(sensorOut)` may already return the "pulse state" instead of the "pre-pulse state" and therefore waits for a different pulse than it should. You'd need to first read `sensorOut` into a variable, then set `s2`/`s3`, then read your data via `pulseIn` using the variable you set before.

But without having the datasheet of the sensor/knowing the protocol of the sensor, this is all very volatile guesswork. Please improve your question by adding the sensor type (and maybe a wiring diagram) alongside an explanation of what you mean by "it fails". How exactly does it fail? Which part works and which doesn't?

You can also glean more insight into the state of your sketch by writing measured values to the serial monitor using `Serial.println`.

  [1]: https://stackoverflow.com/questions/69515298/assigning-tuple-to-an-int-variable-and-printing-the-variable


message:
Bad readings from 12V pwm fan tachometer signal

I have the following circuit:

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

(The Arduino is powered via the USB)

The problem is that I the reading from the fan's tachometer signal are incorrect,

I tried to add the two resistors as voltage dividers but still the readings are wrong.
When I check the voltage of the tachometer signal with a multimeter, in the time the multimeter is connected the readings are somewhat correct (not 100%).

Here is a snippet from the fan's documentation:
[![enter image description here][2]][2]

(BTW: When I used a different 12v pwm fan and didn't use a voltage divider the readings were incorrect only in the time I switched the 12v power off until the fan stopped spinning (after it stopped spinning the tachometer stopped sending signals so the rpm was 0 which was correct).)

Working code (correct tacho signal value):

    const byte tachpin = 2;

    unsigned int tacho = 0;
    long int startTime = 0;
    long int elapsed = 0;

    void setup() {
      Serial.begin(9600);
       // Configure Timer 1 for PWM @ 25 kHz.
        TCCR1A = 0;
        TCCR1B = 0;
        TCNT1  = 0;
        TCCR1A = _BV(COM1A1)
               | _BV(COM1B1)
               | _BV(WGM11);
        TCCR1B = _BV(WGM13)
               | _BV(CS10);
        ICR1   = 320;

        pinMode(tachpin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
        startTime = millis();
    }

    void tachisr(){
      tacho++;
    }

    void loop() {
          elapsed = millis() - startTime;
          if(elapsed > 1000) {
            int tachcopy = 0;
            noInterrupts();
            tachcopy = tacho;
            tacho = 0;
            interrupts();
            rpm = (tachcopy / 2.0) * (60000 / elapsed);
            Serial.println(rpm,DEC);
          }
          startTime = millis();
    }

Correct reading from working code

>rpm = 0, tachcopy = 0\
rpm = 1150, tachcopy = 39\
rpm = 2360, tachcopy = 80\
rpm = 2655, tachcopy = 90\
rpm = 2773, tachcopy = 94\
rpm = 2655, tachcopy = 90\
rpm = 1268, tachcopy = 43

Not working code (incorrect tachometer signal):

    const byte tachpin = 2;

    unsigned int tacho = 0;
    long int startTime = 0;
    long int elapsed = 0;
    long int rpm = 0;
    unsigned int pwmValue = 0;
    unsigned int outValue = 0;
    unsigned int seconds_counter = 0;

    void setup() {
      Serial.begin(9600);
       // Configure Timer 1 for PWM @ 25 kHz.
        TCCR1A = 0;
        TCCR1B = 0;
        TCNT1  = 0;
        TCCR1A = _BV(COM1A1)
               | _BV(COM1B1)
               | _BV(WGM11);
        TCCR1B = _BV(WGM13)
               | _BV(CS10);
        ICR1   = 320;

        // Set the PWM pins as output.
        pinMode( 9, OUTPUT); //!!!ADDED LINE!!!

        pinMode(tachpin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
        startTime = millis();
    }

    void tachisr(){
      tacho++;
    }

    //!! ADDED FUNCTION !!!
    void analogWrite25k(int value)
    {

        OCR1A = value;

    }

    void loop() {

          elapsed = millis() - startTime;
          if(elapsed > 1000) {
            int tachcopy = 0;
            noInterrupts();
            tachcopy = tacho;
            tacho = 0;
            interrupts();
            startTime = millis();
            rpm = (tachcopy / 2.0) * (60000 / elapsed);
            Serial.print("rpm = ");
            Serial.print(rpm,DEC);
            Serial.print(", tachcopy = ");
            Serial.println(tachcopy,DEC);

            seconds_counter++;
          }

          analogWrite25k(100); //!!!ADDED LINE!!!

    }

Not working code output:

>rpm = 737854, tachcopy = 25012\
rpm = 738591, tachcopy = 25037\
rpm = 737824, tachcopy = 25011\
rpm = 738591, tachcopy = 25037\
rpm = 738562, tachcopy = 25036\
rpm = 737854, tachcopy = 25012\
rpm = 738562, tachcopy = 25036\
rpm = 737854, tachcopy = 25012\
rpm = 738562, tachcopy = 25036\
rpm = 737824, tachcopy = 25011\
rpm = 738591, tachcopy = 25037\
rpm = 737854, tachcopy = 25012\
rpm = 738562, tachcopy = 25036\
rpm = 737854, tachcopy = 25012\
rpm = 738562, tachcopy = 25036\
rpm = 737854, tachcopy = 25012

Readings when using 10K ohm resistor as pull up (instead of the voltage divider (10K+4.7K))  and maxing out analogWrite25k - `analogWrite25k(320);`:

>  rpm = 6165\
  rpm = 6401\
  rpm = 6136\
  rpm = 6136\
  rpm = 6165\
  rpm = 6018\
  rpm = 6283\
  rpm = 5870\
  rpm = 6047\
  rpm = 6578\
  rpm = 6460\
  rpm = 6224\
  rpm = 5782\
  rpm = 6047\
  rpm = 6136\
  rpm = 6136\
  rpm = 6313\
  rpm = 5988\
  rpm = 6224\
  rpm = 6195\
  rpm = 6136\
  rpm = 5900

Which is interesting because the max speed of the fan is ~3000rpm (so rpm readings are about x2 max fan rpm when maxing out analogWrite25k)

**Update:**

Added debounce + 10K Ohm to Arduino 5V:

    #define DEBOUNCE 10
    //Interrupt handler. Stores the timestamps of the last 2 interrupts and handles debouncing
    unsigned long volatile ts1=0,ts2=0;
    //Calculates the RPM based on the timestamps of the last 2 interrupts. Can be called at any time.
    unsigned int calcRPM(){
        unsigned long ts1_copy, ts2_copy;
        noInterrupts();
        ts1_copy = ts1;
        ts2_copy = ts2;
        interrupts();

        Serial.print(ts1_copy);
        Serial.print(" / ");
        Serial.print(ts2_copy);
        Serial.print(" / ");
        Serial.println(ts2_copy - ts1_copy);
        return (60000000.0 / (ts2_copy - ts1_copy ) / 2.0);
    }

    void tachisr2() {
        unsigned long m=micros();
        if((m-ts2)>DEBOUNCE){
            ts1=ts2;
            ts2=m;
        }
    }

Output after adding debounce:

>    rpm = 2953.92\
    90923308 / 90923320 / 12\
    rpm = 2500000.00\
    91948328 / 91958496 / 10168\
    rpm = 2950.43\
    92994188 / 92994200 / 12\
    rpm = 2500000.00\
    94031032 / 94031040 / 8\
    rpm = 3750000.00\
    95047108 / 95057256 / 10148\
    rpm = 2956.25\
    96093308 / 96093320 / 12\
    rpm = 2500000.00\
    97119144 / 97129296 / 10152\
    rpm = 2955.08

When the value is ~2900 it is the correct value.

**Update 2**

Hope you can help me with another problem, The rpm value is scattering on a range of up to 120rpm+ even on low fan cycle of 800 rpm, of course when the elapsed time wait is bigger the scattering range is lower, the rpm reading might be not precise by about ~10%, I saw videos of [live speed reading from BIOS][3] of PC fan connected to PC motherboard and some of the fans are more precise (maybe because of BIOS code? (maybe there is a standard that specifies minimum time before reading the tacho counter?)), The question is are the tachometer sensors on 12V PC fans not supposed to be super precise by design or do I still have some problems with my circuit?, If I want a more precise rpm reading should I use an external tachometer sensor? which one is the best? optical/magnet based?
(btw my current circuit doesn't include the 4.7KOhm resistor from the schematic, only 10KOhm pull up to 5V)

  [1]: https://i.stack.imgur.com/wZ7WC.png
  [2]: https://i.stack.imgur.com/ejMKW.png
  [3]: https://www.youtube.com/watch?v=8dZ-ZqsTAjw&t=130s

body:
**1. Open Collector Output of a module.**

The power for the open collector output should come from the MCU, not (indirectly) from the sensor's power supply. It is very similar to wiring a push button switch on the low side.
Usually, the internal pullup resistor of the Arduino pin which is connected to the module passes enough power to detect the status of this output (as you have done). This internal pullup resistor has a value of around 30k. It is also possible to add a lower value external pull up resistor, if required say because of electrical noise, between the Arduino's 5v power rail and the pin. Ensure, however, that the current is within the tolerance of the connected device.

Measuring PWM voltages with a multimeter will not be successful, as you have discovered. These tend to integrate and show an average voltage. Say 12 volts at a 50% duty cycle will be read as 6 volts. Use an oscilloscope to see the voltage across the wave form.

**2. Electrical Interference.**

Your figure here `tachcopy = 25012` indicate that your 25KHz signal is leaking through and being detected as pulses from the sensor. Powering the open collector via the Nano's 5v power rail (as above) may eliminate this. Maybe also better decoupling on the 12 volt power supply (say adding a big capacitor).

**3. Code Issues**

Your code has an number of issues which should be cleaned up. Some may show up after only about 25 days. Some may show up after the next recompilation and some affect the accuracy of the results.

- `unsigned int tacho = 0;` should be volatile.
- `int tachcopy = 0;` should be unsigned int to match the data tape it is copying.
- Variables which are derived from millis() should be unsigned long (uint32_t) as here: `elapsed = millis() - startTime;`.
- This `(60000 / elapsed)` should be forced to a floating point division say `(60000.0 / elapsed)`
- This could be in setup() instead of loop(): `analogWrite25k(100);
   //!!!ADDED LINE!!!`

**4. "rpm readings is about x2 max fan rpm"**

I can't explain that. It may be that the sensor output needs to be debounced.

**5. Sample debounce routine (lockout principle)**
```
// Simple debounce routine. Based on original code.
// After accepting a pulse locks out further pulses for 3 ms
// Should be OK for 100Hz (period 10ms)

void tachisr(){
  // ISR (external interrupt)
  static uint32_t lastAcceptedPulseAtMs = 0 ; // static initialised once only
  uint32_t ms = millis() ;
  if ( ms - lastAcceptedPulseAtMs >= 3 ) {  // 3 ms - tune if required
    lastAcceptedPulseAtMs = ms ;
    tacho++;
  }
}
```
Note: An ISR should be quick to execute and should not contain Serial.print() etc.


message:
Arduino UNO stuck at 'uploading' with base sketch, nothing wired

This question has been asked before and I have carefully read the other questions, but the solutions have not worked in my case, and the details are not the same as mine.

**Description**

The Arduino Uno is stuck at uploading with the error `avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00`, with the base sketch.

**Details**

- I am trying with the base empty sketch.
- Nothing is wired, nothing connected

**Important Remarks**
- A second Arduino UNO works perfectly fine with the same setup
- Loopback test worked - [Loopback test instructions][1]
- Cable and drivers work fine
- Correct port is selected
- Rebooting, resetting, upgrading the Arduino IDE have not solved the problem

**Important details**
- The TX LED is slightly but constantly on, and measuring the value of the TX Pin (Digital 1) outputs a value of 2.0 V. This also happens when feeding the Arduino with a 12 V supply, without USB. **EDIT** Got rid of this part by burning the bootloader via ISP with another Arduino - [Bootloader burn instructions][2]
- Checking the COM devices via powershell `mode` outputs something different between the two Arduinos: a locked value of `Baud: 115200` for the one not working, while for the one that works it displays `Baud: None`.

  [1]: https://support.arduino.cc/hc/en-us/articles/360020366520-How-to-do-a-loopback-test
  [2]: https://support.arduino.cc/hc/en-us/articles/4841602539164-Burn-the-bootloader-on-UNO-Mega-and-classic-Nano-using-another-Arduino

body:
> A second Arduino UNO works perfectly fine with the same setup

Sounds like your Uno is faulty. You could read my post here:

https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/13293#13293

Also https://arduino.stackexchange.com/questions/15936/what-happens-when-code-is-uploaded-using-the-bootloader/15937#15937

The Unos should be simply replaceable. That is, if your setup works on one, then unless you have done something weird to the other one (such as changing the fuses) then that should work too.

Is it a genuine one? Or a cheap knock-off? If it's cheap, well you got what you paid for. Get another.

I have [a post on my forum](http://www.gammon.com.au/forum/?id=11633) which lets you detect chip signatures and fuses (use your working Uno to run that). It may shed some light on what is happening.


message:
how to avoid an Arduino pro micro waking up a pc

I have an Arduino Pro Micro only sending data via com port, connected to a PC.
I don't use the USB protocol and I think the Arduino send request with USB and it's the reason why my computer wakes up

I checked the device manager and there is no power management tab for the arduino, so I can't refuse the Arduino to wake the system up.
Also my BIOS don't have any option to wake up on a particular key combination

body:
Assuming the computer is turning on due to the data received over the USB cable from the DEEJ box and not from simply plugging in the USB cable from the DEEJ box.

Consider, if this project otherwise works, re-writing the Arduino Sketch to not send out any data until after a specific digital GPIO pin goes from 1 to 0. Place a N.O. push button switch to ground on that digital GPIO pin. Remember to program that pin as a GPIO input with a pull up. If this works, not only will the DEEJ box control volumes, but might also be able to turn on the computer.


message:
unable to program esp32cam via cloned esp32-cam-mb

I bought a couple of ESP32CAMs from aliexpress... althought [the listing][1] shows them with two buttons, I got the ESP32-CAM-MB boards with just the reset button...

I have my computer set up to dual boot Windows and Linux so when I got an error in windows, I rebooted and installed the ESP32 boards for Arduino 2.1 and went ahead. I had to also install esptool and pyserial for it to work, but it ended up recognizing the port and every time I try to program it the flash flashes, but the programmer responds with

>     A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0xb)! The chip needs to be in download mode.

When I enable the serial console and press the reset button I get the following:

```
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:6968
load:0x40078000,len:13072
ho 0 tail 12 room 4
load:0x40080400,len:3896
entry 0x40080688
[0;32mI (31) boot: ESP-IDF v4.1-dirty 2nd stage bootloader[0m
[0;32mI (31) boot: compile time 16:15:01[0m
[0;32mI (31) boot: chip revision: 3[0m
[0;32mI (34) boot_comm: chip revision: 3, min. bootloader chip revision: 0[0m
[0;32mI (41) boot.esp32: SPI Speed      : 40MHz[0m
[0;32mI (46) boot.esp32: SPI Mode       : DIO[0m
[0;32mI (51) boot.esp32: SPI Flash Size : 4MB[0m
[0;32mI (55) boot: Enabling RNG early entropy source...[0m
[0;32mI (60) boot: Partition Table:[0m
[0;32mI (64) boot: ## Label            Usage          Type ST Offset   Length[0m
[0;32mI (71) boot:  0 nvs              WiFi data        01 02 00009000 00005000[0m
[0;32mI (79) boot:  1 otadata          OTA data         01 00 0000e000 00002000[0m
[0;32mI (86) boot:  2 app0             OTA app          00 10 00010000 00300000[0m
[0;32mI (94) boot:  3 spiffs           Unknown data     01 82 00310000 000f0000[0m
[0;32mI (101) boot: End of partition table[0m
[0;32mI (106) boot_comm: chip revision: 3, min. application chip revision: 0[0m
[0;32mI (113) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x1d2048 (1908808) map[0m
[0;32mI (849) esp_image: segment 1: paddr=0x001e2070 vaddr=0x3ffbdb60 size=0x04d3c ( 19772) load[0m
[0;32mI (857) esp_image: segment 2: paddr=0x001e6db4 vaddr=0x40080000 size=0x00400 (  1024) load[0m
[0;32mI (858) esp_image: segment 3: paddr=0x001e71bc vaddr=0x40080400 size=0x08e54 ( 36436) load[0m
[0;32mI (880) esp_image: segment 4: paddr=0x001f0018 vaddr=0x400d0018 size=0x9df74 (647028) map[0m
[0;32mI (1127) esp_image: segment 5: paddr=0x0028df94 vaddr=0x40089254 size=0x0b6a0 ( 46752) load[0m
[0;32mI (1159) boot: Loaded app from partition at offset 0x10000[0m
[0;32mI (1159) boot: Disabling RNG early entropy source...[0m
�
SD Size: 29557MB  OK
```

I can see that the board is in `SPI_FAST_FLASH_BOOT` mode which according to the [linked documentation][2] is wrong... but how to I get it to reboot in the correct mode?

[Others have had similar issues][3], but they use another tool stack, so I am not sure what their solution would translate to in the Arduino 2.1 IDE...

[![stacked][4]][4]
[![bottoms][5]][5]
[![tops][6]][6]

  [1]: https://www.aliexpress.com/item/1005002808966055.html
  [2]: https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/boot-mode-selection.html#manual-bootloader
  [3]: https://www.reddit.com/r/esp32/comments/qjflp4/bought_a_shady_esp32cammb_that_doesnt_have_a_gp0/
  [4]: https://i.stack.imgur.com/cahAL.jpg
  [5]: https://i.stack.imgur.com/5ENAx.jpg
  [6]: https://i.stack.imgur.com/5Di1x.jpg

body:
While making sure I included all the correct links and pictures in the question, I found the answer - if an SD card is inserted, the flashing cannot be performed.

Removing the SD card and resetting the ESP32 works. I now have a very bright flashing LED


message:
Error while uploading "A fatal esptool.py error occurred: Write timeout"

I have constantly been getting this error while trying to upload a sketch on Wemos D1 Mini R1 & R2 type board.

> A fatal esptool.py error occurred: Write timeout

I've recently updated my Arduino IDE, so I assumed that it might be due to a bad installation. But after reinstalling everything including the Board Manager lib for ESP, Arduino IDE itself nothing worked. When I click on the Board Info, it displays an error "Native serial port, can't obtain info".

I've also tried different type of ESP boards (e.g. NodeMCU) but for all boards the problem is same. When I plug an Arduino to the same USB Port, it auto-detect the board, but when I plug-in the ESP boards, it doesn't recognize the boards automatically. So my guess is it has something to do with the CH34X driver. However I have tried reinstalling few versions of the driver from authentic sources, but nothing made an impact.

Any help is appreciated.

Following is the full trace of log getting printed:

    . Variables and constants in RAM (global, static), used 28104 / 80192 bytes (35%)
    ║   SEGMENT  BYTES    DESCRIPTION
    ╠══ DATA     1496     initialized variables
    ╠══ RODATA   920      constants
    ╚══ BSS      25688    zeroed variables
    . Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 59667 / 65536 bytes (91%)
    ║   SEGMENT  BYTES    DESCRIPTION
    ╠══ ICACHE   32768    reserved space for flash instruction cache
    ╚══ IRAM     26899    code in IRAM
    . Code in flash (default, ICACHE_FLASH_ATTR), used 232148 / 1048576 bytes (22%)
    ║   SEGMENT  BYTES    DESCRIPTION
    ╚══ IROM     232148   code in flash
    esptool.py v3.0
    Serial port COM8
    Connecting...

    A fatal esptool.py error occurred: Write timeout

Following is the IDE Settings while uploading:

[![Arduino-IDE-upload-settings-for-D1-Mini-(ESP8266)][1]][1]

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

body:
I've run into this a bunch recently, and typically, but not always, the cause is that I was using a GPIO pin that was reserved and couldn't be used during boot up. It's surprising how many of the pins cannot be used.

Check out this chart I found and saved, unfortunately I do not know the source, but I have found it to be very accurate, and I reference it a lot:

[![take a look at this graph I found][1]][1]

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


body:
I had the same problem.

My solution:

Program for blinking led ESP8266MOD (cheap Chinese esp8266mod module)

I used Arduino IDE 2.1.0

info from https://vimalb.github.io/IoT-ESP8266-Starter/Lesson_01/lesson.html

Connect resistor 220 Ohm and LED in serial. Connect resistor on D8 and the LED

on G (Ground). I used a breadboard and connect 5V pin on the esp board and

the pin G on the esp board to the Red en Bleu line on mij breadbord.

Write the program.

    // Base ESP8266

    #include <ESP8266WiFi.h>

    WiFiClient WIFI_CLIENT;

    #define LIGHT_SENSOR A0

    #define LED 15    // this is pin D8 on the board

    #define BUTTON 4

    void setup() {

      // Initialize the serial port

      Serial.begin(115200);

      // Configure light sensor pin as an input

      pinMode(LIGHT_SENSOR, INPUT);

      // Configure LED pin as an output

      pinMode(LED, OUTPUT);

      // Configure BUTTON pin as an input with a pullup

      pinMode(BUTTON, INPUT_PULLUP);

    }

    void loop() {

      // Turn the LED on (HIGH is the voltage level)

      digitalWrite(LED, HIGH);

      // Wait for 1000 milliseconds

      delay(1000);

      // Turn the LED off by making the voltage LOW

      digitalWrite(LED, LOW);

      // Wait another 1000 milliseconds

      delay(1000);

      // Send a message over the serial port

      Serial.println("Finished loop");

    }

Compile the program.

If Fault check the program.

Go to Tools -> Port  (I used com6)

Push the reset button on the espboard and keep it.

Connect the usb-cable on the espboard.

Release the reset button.

Besure everthing is connect.

Upload the program by using the upload button arduino IDE.

Start the serial monitor and check text "Finished loop" every 2 seconds.

Maybe this will help


body:
The "most common reason" mentioned in [this answer][1] was actually the problem I had. Unfortunately I was using a charge only cable even though the cable package clearly said it was a data-cable. At times, these cheap electronics products confuses us a lot and we often miss to critically scrutinize the most obvious problems. As described in [this Adafruit tutorial][2] this problem seems to be a very common one.

  [1]: https://raspberrypi.stackexchange.com/a/140835
  [2]: https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython