message:
sim800l ftp error after http request

I am using esp32 CAM by Arduino IDE and send an image file by ftp using SIM800l GSM/GPRS  module  to a server and every thing is ok .
I can perform http request also and read some data from a website and every thing is ok.

Problem is ftp for large file  and http request can not work at the same time .
if I send AT+HTTPINIT after AT+FTPEXTPUT=1 , it fails
or if I send AT+FTPEXTPUT=1  after  AT+HTTPINIT again it fails .

I close http connection by AT+SAPBR=0,1 but problem exist

How to solve this problem?
How is possible to clear the setting done in the  the sim800l without restarting the module by AT+CFUN=1,1 ?

body:
I found the way to solve the problem .
Http request must be terminated with command AT+HTTPTERM . After this command large ftp works and command AT+FTPEXTPUT=1 is without error . After termination of ftp if we want to do http request again the command AT+FTPEXTPUT=0 must be executed


sender: user

message:
VSCode vs. Arduino IDE - same program, different behavior

I've got this simple program for testing DS18B20 temperature sensors.
```
#include "OneWire.h"
#include "DallasTemperature.h"

#define ONE_WIRE_BUS D3

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(19200);
  sensors.begin();
  delay(1000);  //time for serial to connect
  Serial.print(sensors.getDeviceCount());
  Serial.println(" sensors found");
  Serial.print(sensors.getDS18Count());
  Serial.println(" DS18 sensors found");
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures

  Serial.print("Temperature for Device 1 is: ");
  Serial.println(sensors.getTempFByIndex(0));

  Serial.print("Temperature for Device 2 is: ");
  Serial.println(sensors.getTempFByIndex(1));

  delay(5000);

}
```

I'm compiling for the Wemos D1 mini.
When I compile on the Arduino IDE, the code runs as expected. It reports two devices, then gives the temperature reading from each device.
When I compile using VSCode and the Arduino extension, the code compiles and uploads successfully, the program reports 2 devices, just like the Arduino IDE compilation does, but then it prints -196.60 for the temperature reading, which is the "no device" value.

Same breadboard, same host computer - the only difference is the IDE. I'd much prefer to stick with VSCode, but if the resulting executable is wrong, then it's a non-starter.

Why the different results? More importantly, how do I get the VSCode to produce the same (correct) output as the Arduino IDE?

UPDATE:
Apparently the issue has something to do with the serial monitor. The project I'm actually trying to build has an OLED display for the temperature. The temperature is correct if the VSCode serial monitor is closed. Open the monitor and the incorrect values appears. Close the monitor and the correct values appear again.

UPDATE 2:
The problem remains over a range of serial port speeds, from 19200 to 115200. I didn't try outside that range.

UPDATE 3:
Code compiled using VSCode but run observing through the Arduino IDE serial monitor has the correct behavior - ie, shows the correct temperatures.

sender: assistant

body: Further testing by OP isolated a bug in the Arduino Extension for VSCode which was logged as an issue at https://github.com/microsoft/vscode-arduino/issues/1467


message:
LiquidCrystal issue with HD44780 display

Here my sample code for an Arduino Leonardo-based custom board:

    #include <LiquidCrystal.h>

    const int rs = 3, en = 0, d4 = 4, d5 = 30, d6 = 12, d7 = 6;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup()
    {
      pinMode(2, OUTPUT);
      digitalWrite(2, LOW);

      Serial.begin(115200);

      lcd.begin(16, 2);
      lcd.print("Hello world");
    }

    void loop()
    {
    }

And here my schematic:

[![schematic][1]][1]

The MCU is an ATmega32U4.
Running the code above the display is completely empty, I also tried to change the values of R4 and R5 but nothing changes. I don't see anything, not even the background of each character.

The display is a common HD44780 compatible one.

I retrieved the pin numbers from here:

> /opt/arduino-1.8.19/hardware/arduino/avr/variants/leonardo/pins_arduino.h

Am I missing anything?

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

body:
The error is, that V0 has VDD level by the way you connected the resistors. The "lower end" of your ladder needs to be at GND, pin 1.

The pin 15 (A) is the anode of the backlight, and is not connected to the LCD driver circuit. BTW, to lit the backlight, you need to connect pin 16 (K), too. See the data sheet for details.

Use a potentiometer for V0, wiper to V0 and the ends to VDD and GND, respectively.

Just a side note: From the back of my memory, V0 can be commonly connected by a single resistor or directly to GND, since the wiper of the potentiometer was mostly at the GND end. It will give _some_ contrast, depending on the temperature.


message:
How do I modify the value of a variable when I press a switch

I am new to arduino and I want to make a project where I have a motor spinning clockwise then when a button is pressed it spins anti-clockwise and if it is pressed again it goes back to clockwise etc... Unfortunately I am having trouble getting this to work. How I was aiming to make it work was to have a variable and whenever a button is pressed the value of that variable changes from HIGH to LOW to HIGH and so on and based on that variable the motor spins in either direction. I have got this code so far:
 ```// constants won't change. They're used here to set pin numbers:
const int buttonPin = 8;     // the number of the pushbutton pin

// variables will change:
int buttonState = 0;         //variable to change status

void setup() {

  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  Serial.print("Digital value: ");
  Serial.println(buttonState);
  delay(150);
}

body:
First I would make create an enumeration type and motor direction variable (instead of the button state):

    enum EMotorDirection
    {
        CLOCK_WISE,
        COUNTER_CLOCK_WISE
    }

    EMotorDirection _motorDirection = CLOCK_WISE;

Then read the button and when it has changed (make a variable `_previousButtonState), adjust the motor direction.

    int _previousButtonState = LOW;

In the `loop` function:

    int buttonState = digitalRead(buttonPin);
    // Debounce buttonState;
    if (buttonState != _previousButtonState)
    {
       if (_motorDirection == CLOCK_WISE)
       {
           _motorDirection = COUNTER_CLOCK_WISE;
       }
       else
       {
           _motorDirection = CLOCK_WISE;
       }
       SwitchMotorDirection();

       _previousButtonState = buttonState;
    }

And create the function `SwitchMotorDirection`

    void SwitchMotorDirection()
    {
       if (_motorDirection == CLOCK_WISE)
       {
           // Control motor clock wise
       }
       else
       {
           // Control motor counter clock wise
       }
    }

The above example is not compiled, and also it could be smaller, but serves as a explanatory example, with the advantage to separate the UI (button), state machine (state variable), and hardware (motor).

Below is the complete code, which compiles. The bouncing has to be implemented (check the link for that above), and the actual motor driving.

    // Types

    enum EMotorDirection
    {
        CLOCK_WISE,
        COUNTER_CLOCK_WISE
    };

    // Constants
    const int _buttonPin = 8;     // the number of the pushbutton pin

    // Global variables
    int             _previousButtonState = LOW;
    EMotorDirection _motorDirection      = CLOCK_WISE;

    // Function prototypes
    void SwitchMotorDirection();

    // Functions

    void setup()
    {
      Serial.begin(9600);
      pinMode(_buttonPin, INPUT);
    }

    void loop()
    {
      int buttonState = digitalRead(_buttonPin);
      // Debounce buttonState;
      if (buttonState != _previousButtonState)
      {
         if (_motorDirection == CLOCK_WISE)
         {
             _motorDirection = COUNTER_CLOCK_WISE;
         }
         else
         {
             _motorDirection = CLOCK_WISE;
         }
         SwitchMotorDirection();

         _previousButtonState = buttonState;
      }
    }

    void SwitchMotorDirection()
    {
       if (_motorDirection == CLOCK_WISE)
       {
           // Control motor clock wise
       }
       else
       {
           // Control motor counter clock wise
       }
    }


body:
You've made a good start by first working with the button by itself (no motor) to keep your experiments simple. You've probably noticed that buttonState changes when you press *or* release the button, where your description says you want it to change each time you *press* the button. That means you have to ignore the releases, and invert the buttonState only on the presses.

Make that change next.

When you test that, you may discover that the buttonState changes several times when you press it once. Mechanical switches may make/break... several times at each change. (It's called bouncing even though it isn't "bouncing" but the two contacts grating across one another. The result is the same.) There are several ways to deal with that, but the simplest is to wait 20-30 milli-seconds after you first see a change; read it again, and if it is still in the new state, accept that, otherwise ignore it. That time delay is approximate; you might need to adjust it for a particular button.

Once you've decided that the button really has been pressed, then change the direction of the motor.


body:
I would recommend that you "debounce" the button input first. Instead of re-inventing the wheel, you could use an existing library: [Bounce2][1].

Using the conditioned input, you could simply manipulate a counter to determine state.

```c++
// Connect one end of a N.O. push button switch to
// GND and the other end to pin 2 of the Arduino.
#include <Bounce2.h>
byte buttonState = 0;
const byte modeButtonPin = 2;
const unsigned long debouncerInterval = 50;  // Time in ms.

Bounce modeButton = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(modeButtonPin, INPUT_PULLUP);
  modeButton.attach(modeButtonPin);
  modeButton.interval(debouncerInterval);
}

void loop(){
  if(modeButton.update()){
    if(modeButton.read() == 0){
      buttonState++;
      if(buttonState > 1){buttonState = 0;}
      Serial.println(buttonState);
    }
  }
}
```

  [1]: https://www.arduino.cc/reference/en/libraries/bounce2/


message:
Poor man's serial sniffer: reading Serial.print logs of an Arduino esp32 dev kit from another

(I use ESP32 dev kits with Arduino api.)

My dev kit 1 is running my firmware; and I want to measure the current it draws, therefore I don't like to plug the USB in.

As I need to read the logs from the dev kit 1, I want to plug another dev kit that collects the log from the first through the UART.

The dev kit 1 firmware is as it is, but on the dev kit 2, I wrote such a thing:

```c
#include <Arduino.h>
#include <Hardware.h>

HardwareSerial Reader();

void setup() {
    Serial.begin(115200);
    Reader.begin(115200, SERIAL_8N1, 16, 17);

}

void loop() {
    while(Reader.available()) {
        Serial.print(Reader.read());
    }
}
```

The wiring is as follows:

|Dev kit 1 | Wiring | Dev kit 2 (sniffer)|
|----------|-----|--------------------|
|      TXD | <=> | RXD (16) |
|      RXD | <=> | TXD (17) |
|      GND | <=> | GND|

But this doesn't work, that is I can't see anything on the dev kit 2 serial on my computer.
Any idea?

[UPDATE] As suggested by @juraj, I simply wire TX to TX, RX to RX and GND to GND and removed the Serial.begin(115200) from the firmware running on dev kit 1.
Dev kit 2 firmware is as simple as:
```C

void setup() {
  Serial.begin(115200);
  //Serial.printf("Serial2 logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }
}
```

Note that on dev kit 1, I commented out the line `Serial.begin(115200)`.

No kit 1 logs appears on my computer.

The wiring of this setup:

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

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

body:
I finally managed to make it work.

## The final wiring:

| Kit 1 | kit 2 |
|-------|-------|
|The firmware to spy|The firmare that spys|
|RXD|17|
|TXD|16|
|GND|GND|

## The spying firmware uses Serial2

```C

#define USE_READER true

#if USE_READER
#define USE_SERIAL2 true

#if USE_SERIAL2
    #define TX 17
    #define RX 16
    #define Reader Serial2
#else
    #include "SoftwareSerial.h"
    #define TX 12
    #define RX 13
    SoftwareSerial Reader;
#endif
#endif

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

#if USE_READER
  Serial.printf("Serial logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();

  #if USE_SERIAL2
  Reader.begin(115200);
  #else
  Reader.begin(115200, SWSERIAL_8N1, RX, TX, false);
  #endif
  #endif
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }

  #if USE_READER
  if (Reader.available()) {

    Serial.write(Reader.read());
  }
  else {
    #endif

    //Serial.print(".");
    delay(500);

    #if USE_READER
  }
  #endif
}
```
## The spied firmware
You leave it as it is. Don't remove `Serial.begin(115200);`.

## The breadboard photo:

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

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


message:
Servo keeps resetting position when there is no difference in received value?

So I'm working on a code that basically receives x and y coordinates and stores them in a variable. Whenever a coordinate is received, it goes through a conditional statement to store them in a variable, x and y, then passes it to a servo mover function. This servo motor function then moves according to what's given. It works well, **but**, as the values get updated over time, the servo' position always resets then goes back to where it was, again and again. Even when the coordinates are kept the same, it just resets then returns to its position over and over again.

How do I make it so that not only **does it not** reset then return to where it was but instead make it move to where it is supposed to go, but also to stop it from resetting anyway when the position is kept the same?

The below code is what I tried to do to basically alleviate the "position reset when coordinate is the same" issue. Unfortunately, it did not work.
```
bool constant = false;
// Rest of code inbetween, irrelevant to issue

// Relevant codes below
void statusCodes() {
  if (received_str == "1") {
    Serial.println("Raspberry Pi - Connection Established");
  } else if (received_str == "2") {
    Serial.println("Raspberry Pi - Data Received");
  } else if (received_str == "100") {
    Serial.println("Raspberry Pi - Status OK");
  } else if (received_str[0] == '(' ) {
    Serial.println("Coordinates Received, Ready to Delete Target!");
    if (constant == true) { // checks if this constant boolean is true
      movement = false;
    } else {
      movement == true;
    }
    int r = sscanf(received_str.c_str(), "(%d, %d)", &x, &y);
    Serial.print("X: ");
    Serial.println(x);
    Serial.print("Y: ");
    Serial.println(y);
  }
}

void onDetectTarget() {
  x = map(x, 0, 1023, 0, 180);
  y = map(y, 0, 1023, 0, 180);
  if (movement == true) {
    for (pos = 0; pos <= x; pos += 1) {
      myservo.write(pos);
      delay(15);
    }
    movement = false; // corrected
    pos = 0; // corrected

  }
}

void compareOldNew() {
  x_old = x;
  y_old = y;
  delay(900);
  if (x == x_old && y == y_old) {
    constant = true;
  } else {
    constant = false;
  }
}
```

body:
In `onDetectTarget()` you use this for loop

    for (pos = 0; pos <= x; pos += 1) {
      myservo.write(pos);
      delay(15);
    }

So every time `movement` is true, the servo will run again from zero to the target position. So it won't "reset", but it will approach the new target value always from the zero position. You have two options to correct that:

- If you just want to reach the target position, just replace the for loop with a single `myservo.write(x)`.
- If you want the servo to move slower to its new target position, you need to save the last set position of the servo in a variable and then run the for loop from that value up to the new target value. So declare a corresponding variable (for example on global scope):

        int current_pos = 0;

    Then run the for loop from that position to the new target position:

        for(pos = current_pos; pos <= x; pos += 1)

    And after the for loop you can set `current_pos` to the new servo position:

        current_pos = x;

And I guess this happens also, when the values don't change, because you never change the `constant` variable. You haven't implemented any check if the values are constant. (At least you haven't shown such a code and you claim the rest of the code is irrelevant)


message:
Conversion from ASCII uint8_t to string

I am sending a string from a Raspberry Pi to an ESP32 via BT. I am getting one ASCII value per line. How to convert it into one whole String? I tried as follows, but I get an error while running the method  `printReceivedMEssage(buffer)`:

invalid conversion from 'uint8_t {aka unsigned char}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

    uint8_t buffer;

    void printReceivedMessage(const uint8_t* buf) {
      char string_var[100];
      size_t bufflen = sizeof(buf);

      for (int i = 0; i < bufflen; ++i) {
        Serial.println(static_cast<char>(buf[i]));
      }

      memcpy( string_var, buf, bufflen );
      string_var[bufflen] = '\0'; // 'str' is now a string
      Serial.print("string_var=");
      Serial.println(string_var);
    }

    void loop() {
      buffer = (char)SerialBT.read();
      Serial.println(buffer); // THIS SHOWS AN ASCII VALUES ONE PER LINE
      printReceivedMessage(buffer); // ERROR
      delay(1000);
    }

body:
There are multiple problems with your code. They suggest, that you don't know what strings really are.

In C/C++ strings are actually arrays of characters (`char`). A `uint8_t` is the same size of a single character, so you can only save a single character in it. For saving a string, you would need an array of them. So `buffer` should be declared like

    uint8_t buffer[20] = "";

Now `buffer` can hold a string of 19 characters. The 20th character is the terminating null character `\0`, which marks the end of a string. You must always leave enough space for the null character to terminate your strings correctly.

**Serial reading:** There are many ways how you can read from Serial. Look at the `Serial.readStringUntil()` function, which will read from Serial until it reaches a specified character. This way you can easily divide the continuous stream of bytes from Serial into distinct messages. It is common to end all ASCII encoded messages with a newline `\n` character to mark the end of the message. With `Serial.readStringUntil('\n')` (note the single quotes for a single character) you will read until it reaches the newline character (or it times out). You can then process the read string as a full message.

**Providing a string as parameter to a function:** In C/C++ you cannot just provide an array as parameter to a function as other variables. It is a bit more complex. That is because internal the array consists just of a few bytes in a row and the variable just points to the first element of it. It is a pointer (thats a specific C/C++ term). Pointers are marked with `*`, which you already did with your

    void printReceivedMessage(const uint8_t* buf)

function. So the parameter is just a pointer to a `uint8_t`. That also explains the error message, because you provided an `uint8_t`, but the function expects a pointer to `uint8_t` instead. While you still can access the array data through this parameter (given you have implemented what I wrote above about the array), `sizeof(buf)` will only give you the size of the pointer (2 bytes on most Arduino platforms). So you need to add a parameter and also provide the size of the array. Or you can utilize the correct termination of strings with the null character and get the length of the string with `strlen()`. That functions iterates the pointer of the array, until it finds the null character and gives you the resulting length.


message:
Trying to keep my main code running unless an input is LOW for a certain amount of time

I have code that creates a sequential signal with 4 LEDS. It cascades to the right. This works when I hold down the input button. What I need help with is having the code run exactly the same when there is an input signal of .5s HIGH --> .5s LOW (repeat). So what I am thinking in terms of pseudo-code is a code that keeps reading a HIGH signal as long as the signal is not low for more than .5s.

```
//LED outputs
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//right turn signal
int RTS_IN  = A0;

//state variable for switch case statements
int stateRightTurn = 0;

//time variable
unsigned long t = 0;
//interval is the time spacing between case statements
unsigned long interval = 100;
//time for shutting off the code
unsigned long off = 600;

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

  //inputs
  pinMode(RTS_IN,  INPUT);

  //right turn signal output from left to right
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  StateRight();

}

//sequential turn signals
void StateRight()
{

   switch (stateRightTurn)
    {

    case 0: //idle
          if (digitalRead(RTS_IN) == HIGH)
          {
              Serial.println("0000");
              t = millis();
              SwitchRightLedsOff();
              stateRightTurn = 1;
          }
          break;

      case 1: //One LED On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("1111-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("1111-HHHHHHHH");
              t = millis();
              digitalWrite(LED_5, HIGH);
              stateRightTurn = 2;
          }
          break;

      case 2: // Two LEDs On
          if (digitalRead(RTS_IN) == LOW)
              {
                  Serial.println("2222-LOWLOWLOW");
                  SwitchRightLedsOff();
                  stateRightTurn = 0;
              }
              else if (millis() > t + interval)
              {
                  Serial.println("2222-HHHHHHHH");
                  t = millis();
                  digitalWrite(LED_6, HIGH);
                  stateRightTurn = 3;
              }
          break;

      case 3: //Three LEDs On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("3333-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("3333-HHHHHHHH");
              t = millis();
              digitalWrite(LED_7, HIGH);
              stateRightTurn = 4;
          }
          break;

      case 4: //Four LEDs On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("4444-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("4444-HHHHHHHH");
              t = millis();
              digitalWrite(LED_8, HIGH);
              stateRightTurn = 5;
          }
          break;

      case 5: //No LEDs on
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("5555-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("55555-HHHHHHHH");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          break;
    }
}

//method to switch LEDs off
void SwitchRightLedsOff()
{
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}
```

body:
If I understand your requirements correctly, you could use a variable to determine if your sequential lights should be flashing or not. If the input signal is `LOW` for more than 1/2 second, the variable should change to `LOW`, telling the Arduino to stop flashing your sequential lights.

Let's pretend that your input signal is at the correct voltage and is very accurate with it's time keeping. At the 501ms mark, with no `HIGH` input signal, your lights should stop flashing.

A simple timer and state variable may work. Here is a test sketch.

```c++
// Sketch uses 1144 bytes (3%) of program storage space.
// Global variables use 19 bytes (0%) of dynamic memory.
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

    MillisTimer(unsigned long timeInMilliSeconds):
      m_timeInMilliSeconds(timeInMilliSeconds),
      m_timerActive(0),
      m_previousMillis(0){
    }

    bool Update(){
      if(m_timerActive && (millis() - m_previousMillis >= m_timeInMilliSeconds)){
        m_previousMillis += m_timeInMilliSeconds;
        return 1;
      }
      else{
        return 0;
      }
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_previousMillis = millis();
    }

    byte IsActive(){
      return m_timerActive;
    }

};

// Make a copy of the object to work with.
MillisTimer MyTimer(501);

byte inputPin = 2;
byte signalActive = 0;

void setup(){

  // NOTE: Pull-down resistor required if input floating.
  pinMode(inputPin, INPUT);
  MyTimer.Start();

  // Timer status indicator for testing purposes.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

}

void loop(){

  if(digitalRead(inputPin) == HIGH){
    signalActive = 1;
    MyTimer.ReStart();
  }

  if(MyTimer.Update()){
    signalActive = 0;
  }

  // Test ouput of "signalActive" variable using built in LED on an Uno.
  if(signalActive == 1){
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else{
    digitalWrite(LED_BUILTIN, LOW);
  }

}

```


body:
Assuming that `digitalRead(RTS_IN)` is the input, I'd read it once at the top of the loop and save the timestamp if it is HIGH, and then use the condition `millis() - timestamp <= 500` as a latched input variable.

I'd also do the rest of the Input (i.e.: millis()) at the top of the function, convert the time comparisons from absolutes into intervals, and consider factoring the not-enabled case out of the switch's cases.

Untested code:
```
//LED outputs
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//right turn signal
int RTS_IN  = A0;

//state variable for switch case statements
int stateRightTurn = 0;

//time variable
unsigned long t = 0;
//interval is the time spacing between case statements
unsigned long interval = 100;
//time for shutting off the code
unsigned long off = 600;

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

  //inputs
  pinMode(RTS_IN,  INPUT);

  //right turn signal output from left to right
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  StateRight();

}

//sequential turn signals
void StateRight()
{
  const int latchInterval = 500; // ms
  static unsigned long lastHigh = -latchInterval; // initialize into the rolled-over past
  unsigned long now = millis();
  int inState = digitalRead(RTS_IN);
  if (inState == HIGH) { //update timer
    lastHigh = now;
  }
  bool enabled = (now - lastHigh <= latchInterval) ; // latched on for 500 ms after off

  switch (stateRightTurn)
  {
    case 0: //idle
      if (enabled)
      {
        Serial.println("0000");
        t = now;
        SwitchRightLedsOff();
        stateRightTurn = 1;
      }
      break;

    case 1: //One LED On
      if (!enabled)
      {
        Serial.println("1111-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("1111-HHHHHHHH");
        t = now;
        digitalWrite(LED_5, HIGH);
        stateRightTurn = 2;
      }
      break;

    case 2: // Two LEDs On
      if (!enabled)
      {
        Serial.println("2222-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t >  interval)
      {
        Serial.println("2222-HHHHHHHH");
        t = now;
        digitalWrite(LED_6, HIGH);
        stateRightTurn = 3;
      }
      break;

    case 3: //Three LEDs On
      if (!enabled)
      {
        Serial.println("3333-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("3333-HHHHHHHH");
        t = now;
        digitalWrite(LED_7, HIGH);
        stateRightTurn = 4;
      }
      break;

    case 4: //Four LEDs On
      if (!enabled)
      {
        Serial.println("4444-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("4444-HHHHHHHH");
        t = now;
        digitalWrite(LED_8, HIGH);
        stateRightTurn = 5;
      }
      break;

    case 5: //No LEDs on
      if (!enabled)
      {
        Serial.println("5555-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("55555-HHHHHHHH");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      break;
  }
}

//method to switch LEDs off
void SwitchRightLedsOff()
{
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

```


message:
Can't type backslash (\) with Keyboard library

I'm trying to make a macro keyboard, where I can press a single button and it will open programs for me.

I'm trying to type this, for example: "c:\windows"

but it gets typed out like this: cÑ}windows

I tried using double backslash (\\), but it still isn't working

    #include <HID-Project.h>
    #include <HID-Settings.h>

    #include <Keypad.h>

    #define L_ALT KEY_LEFT_ALT
    #define TAB KEY_TAB
    #define WIN KEY_LEFT_GUI
    #define ENTER KEY_RETURN

    const byte FILAS = 4;
    const byte COLUMNAS = 4;
    //define the cymbols on the buttons of the keypads
    char Keys[FILAS][COLUMNAS] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };

    byte pinesFilas[FILAS] = {9, 8, 7, 6};
    byte pinesColumnas[COLUMNAS] = {5, 4, 3, 2};

    char TECLA;

    Keypad teclado = Keypad( makeKeymap(Keys), pinesFilas, pinesColumnas, FILAS, COLUMNAS);

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

    void loop() {
      TECLA = teclado.getKey();

      if (TECLA) {

        switch (TECLA) {
          case '1':
            Serial.print("Tecla 1 presionada");
            break;
          case '2':
            Serial.print("Tecla 2 presionada");
            break;
          case '3':
            Serial.print("Tecla 3 presionada");
            break;
          case 'A':
            Serial.print("Tecla A presionada");

            break;
          case '4':
            Serial.print("Tecla 4 presionada");

            Keyboard.press(WIN);
            Keyboard.write('r');
            Keyboard.release(WIN);
            delay(100);
            Keyboard.print("C:\Program Files (x86)\AIMP\AIMP.exe");   //Here's the problem
            //Keyboard.write(ENTER);
            break;
          case '5':
            Serial.print("Tecla 5 presionada");
            break;
          case '6':
            Serial.print("Tecla 6 presionada");
            break;
          case 'B':
            Serial.print("Tecla B presionada");
            break;
          case '7':
            Serial.print("Tecla 7 presionada");
            break;
          case '8':
            Serial.print("Tecla 8 presionada");
            break;
          case '9':
            Serial.print("Tecla 9 presionada");
            break;
          case 'C':
            Serial.print("Tecla C presionada");
            break;
          case '*':
            Serial.print("Tecla * presionada");
            break;
          case '0':
            Serial.print("Tecla 0 presionada");
            break;
          case '#':
            Serial.print("Tecla # presionada");
            break;
          case 'D':
            Serial.print("Tecla D presionada");
            break;
        }
      }
    }

body:
You have to keep in mind that the Arduino doesn't send characters to the
computer. Instead, it simulates key presses, and the computer has to
translate those into characters, according to some keyboard layout. By
default, the Keyboard library assumes the US keyboard layout.

If you are using another layout, you have to tell the library when
initializing it. E.g.

```c++
Keyboard.begin(KeyboardLayout_es_ES);
```

would work with a Spanish keyboard layout.

C.f. the [documentation of `Keyboard.begin()`][doc].

If you are using an unsupported layout, you may need to write your own
layout file and add it to the library. You may then contribute it
upstream so that it becomes part of future versions of the Keyboard
library.

[doc]: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/keyboardbegin/

Alternatively, you could switch your layout to US in your OS.

**PS**: The Keyboard library only supports international keyboard
layouts since version 1.0.3, released on 2021-11-04.


message:
Why is there a cutoff on these accelerometer measurement values? - ADXL375

I'm using a Teensy 3.2 to read data from an [ADXL375][1] using SPI. In general the communication is going just fine and I can activate settings etc.
However, when I try to read X, Y or Z data it seems like some part of the measurement values are missing.

I'm performing measurements with the ADXL375 and writing the LSB values straight to an SD card, so no conversion to g or anything like that. The accelerometer range goes to +/- 200g, so that should give a max LSB value of about 200*20(scale factor) = +/- 4000 LSB.
During some tests I was swinging the accelerometer with my hand, and tapping it directly with a pen, which gives a momentary high impact. The swinging values are represented well and look credible to me, however the pen tapping values seem to be cut off at precisely 511 LSB, see graphs. That seems incorrect. So why is that?

N.B. The range of the ADXL is fixed to 200 g, so no choice to be made there.

My thinking is that something is going wrong with the conversion of the two ADXL registers (two's complement) to form a single number.
This is the conversion I'm doing (i.e. I'm reading out the FIFO in one go):

    void ADXL375::saveFIFO(){
     int fifo_index;
     int16_t x, y, z;
     fifo_index=0;
    //    readFrom(DEVICE,ADXL375_INT_SOURCE_REG,1,buff);

        for(int i=0;i<32;i++){
      multiByteReadSPI(ADXL375_DATAX0_REG, 6, bufferSPI); //read the acceleration data from the ADXL375
      x = (((uint16_t)bufferSPI[1]) << 8) | (uint16_t)bufferSPI[0];
      y = (((uint16_t)bufferSPI[3]) << 8) | (uint16_t)bufferSPI[2];
      z = (((uint16_t)bufferSPI[5]) << 8) | (uint16_t)bufferSPI[4];

            // Serial.print(bufferSPI[5], BIN); Serial.println(bufferSPI[4], BIN); // z
            // Serial.print(bufferSPI[1], BIN); Serial.print(","); Serial.println(bufferSPI[0], BIN);  // x

            if (x & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
                // If negative, then perform not operation and add one to get magnitude
                x = ~x + 1;
                x = - x;
            }
            if (y & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
                // If negative, then perform not operation and add one to get magnitude
                y = ~y + 1;
                y = - y;
            }
            if (z & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
                // If negative, then perform not operation and add one to get magnitude
                z = ~z + 1;
                z = - z;
            }

      lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
            newistFiFo[fifo_index]  =   x;
            fifo_index++;
            lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
      newistFiFo[fifo_index]  =   y;
            fifo_index++;
            lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
      newistFiFo[fifo_index]  =   z;
            fifo_index++;
            // debugPrint(x); // debugPrintln(", Saving fifo");

                    // x = (((int16_t)bufferSPI[1]) << 8) | bufferSPI[0];
      // y = (((int16_t)bufferSPI[3])<< 8) | bufferSPI[2];
      // z = (((int16_t)bufferSPI[5]) << 8) | bufferSPI[4];
      // scaleXYZ(&x,&y,&z);

        }

     }

This is the SPI Multibyte Read function I'm using:

    void ADXL375::multiByteReadSPI(uint8_t regAddr, uint8_t numberOfBytes, uint8_t *dataBuffer){

        SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3));

        digitalWrite(_chipSelectPin,LOW);

        uint8_t readMBaddr;

        if (numberOfBytes > 1){ // for an actual multibyte read
            readMBaddr = 0b11000000 | regAddr; //  From left to right: read (1),  yes multibyte (1), and then a bunch of zeros
        }
        else{ // for single byte read
            readMBaddr = 0b10000000 | regAddr; //  From left to right: read (1),  not multibyte (0), and then a bunch of zeros
        }

        SPI.transfer(readMBaddr);

        for (uint8_t k = 0; k < numberOfBytes; k++ ){
          dataBuffer[k] = SPI.transfer(SPI_DUMMY_VALUE);
        }

        digitalWrite(_chipSelectPin,HIGH);

        SPI.endTransaction();

    }

[![enter image description here][2]][2]
[![enter image description here][3]][3]
I also had a look whether the SPI transfers are okay. The image shows one multibyte read, consisting of a command byte on the far left, and then 6 read bytes after that. Nothing out of the ordinary there.
[![enter image description here][4]][4]

  [1]: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL375.PDF
  [2]: https://i.stack.imgur.com/yG5wh.png
  [3]: https://i.stack.imgur.com/xZVVG.png
  [4]: https://i.stack.imgur.com/G7YlZ.png

body:
I found the answer. Turns out the datasheet of the ADXL375 is wrong, and the user can actually change the range themselves (even though the datasheet says you can't). In my case, the range was unintentionally set to 25 g (instead of 200 g). [See below the full explanation by bvn123][1] - which was posted in 2017, yet Analog Devices has still not updated the datasheet.

> I use ADXL345 and ADXL375 under a uC software, which was written for
> ADXL345.
>
> The Datasheet for ADXL345 says about ±2g/±4g/±8g/±16g ranges and
> corresponding to these ranges 10/11/12/13bits resolutions.
>
> The Datasheet for ADXL375 shows only one range ±200g and 13bits
> resolution. .
>
> Inspite of the ADXL375 Datasheet's info, that Register 0x31 only state
> for bits D3:D2:D1:D0 is 1n11 (D3 is the Full resolution bit, D1:D0 are
> the Range bits), the ADXL375 reacts for D1:D0  and D3 change in the
> Register 0x31 the same way, as the ADXL345,
>
> So, in reality ADXL375 also provides 4 ranges (±25g/±50g/±100g/±200g).

  [1]: https://ez.analog.com/mems/f/q-a/89100/adxl345-vs-adxl375-difference-in-ranges-resolutions-selection/167287


message:
Can I use Data Logger Shield with Arduino Sensor shield V5.0?

so I did a little research on this but the answer to my particular problem did not exist.

I have a data logger shield created by deek robot (deek-robot.com) which seems pretty similar to adafruits data logger shield so I assume they would use the same pins, about this one I can research and find the pins.

but in case of the sensor shield I could not find anything specially since there is no reference on the manufacturer on the board and only referred to as "Arduino Sensor Shield V5.0",as this is a shield for sensors and has almost every pin available on it I would assume it can use most of the data pins and depends on which pins I connect.

Now my question is that can I use these shields together if I want to use those digital pins already used by the data logger? or I can use them together only if I leave out the digital pins 10 to 13 out of use on my sensor shield?
[![sensor shield v5.0][1]][1]
[![Right-side pins][2]][2]
[![Left-side pins][3]][3]

  [1]: https://i.stack.imgur.com/R9bze.jpg
  [2]: https://i.stack.imgur.com/pjujc.jpg
  [3]: https://i.stack.imgur.com/LXnuR.jpg

body:
The 'data logging' shield by Adafruit and Deek Robot has two devices.

First device is the SD card which uses SPI bus. Every SPI device on the SPI bus has to have a select pin CS. On this shield the SD card has pin 10 as the CS pins.

The second device on the data logger shield is a RTC clock. The RTC clock is on the I2C bus.

So the data logger shield uses the I2C pins, the SPI pins and a pin for CS. Arduino in Uno and Mega R3 form factor have the SPI as a 2x3 header and the I2C pins SDA and SCL are last two pins on the header near the USB connector.

**On Uno the data logging shield uses pin 10 as CS, 11, 12, 13 as SPI and A4, A5 as I2C.**

If you have the version of the data logging shield which can be used on boards other than Uno, then:
* On Mega it uses pin 10 as CS, 50, 51, 52 as SPI and 20, 21 as I2C.
* On Leonardo it uses pin 10 as CS, 2, 3 as I2C (and the SPI pins which are only on the SPI header).
* On Arduino Zero the shield uses pin 10 as CS, 11, 12, 13 as SPI (and the I2c pins are only on the SDA/SCL header).

The 'sensor shield' doesn't have any devices. So it makes no difference in pins usage. With or without the 'sensor shield' if you have the 'data logging' shield attached, you can use only the pins not used by the 'data logging' shield.

Since SPI and I2C are a bus, you can wire additional SPI devices to the SPI pins and additional I2C devices to the I2C pins, but you can't use these pins for anything else if they are configured for the bus.


message:
Arduino Nano BLE 33 default example sketch `USBHID>Keyboard` makes the Arduino unusable

## How the problem started
I was playing around with using the Arduino Nano BLE 33 as a keyboard, and stumbled upon the USBHID>Keyboard sketch which I got via the default suggestion from the Board Manager to install `Arduino Mbed OS Nano Boards`:

See the source on [github.com/arduino/ArduinoCore-mbed](https://github.com/arduino/ArduinoCore-mbed/blob/master/libraries/USBHID/examples/Keyboard/Keyboard.ino), or reproduced below:

```c
#include "PluggableUSBHID.h"
#include "USBKeyboard.h"

USBKeyboard Keyboard;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1000);
  Keyboard.printf("Hello world\n\r");
}
```

It seemed fairly innocent, so I uploaded it without a second thought thinking that I could trust anything provided from Arduino itself as an example script.

## What the problem is
But now, as soon as I plug in the Nano, it types `Hello world` followed by a newline every. single. second.

If I try to upload the blink sketch to clear it, I first need to select the Port, but the act of going through the menu to choose the correct port takes over a second, and typing in `Hello world` selects the library manager and ends up opening it when enter is pressed due to the `\n\r`. So my Arduino Nano has been rendered useless by code included as an example in the default sketches. That's not cool.

## Failed Solution Number 1
I tried creating a custom keyboard shortcut to select the port in less than a second, and then pressing `cmd-U` to upload, but I think there might also be a problem there because I get this error:

```
    ...
    Found upload port: /dev/cu.usbmodem11401
    /Users/<my username>/Library/Arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac -d --port=cu.usbmodem11401 -U -i -e -w /var/folders/y1/md9_k_td4rz1f0pq26d24crh0000gn/T/arduino_build_230227/<my script name>.ino.bin -R
->  No device found on cu.usbmodem11401
    An error occurred while uploading the sketch
    ....
```

I'm absolutely certain that `cu.usbmodem11401` is the correct port, because that's what shows up when I `ls /dev/cu*` while the Arduino is plugged in. So I think that the Arduino IDE is attempting to upload to `cu.usbmodem11401`, but sees that it's a keyboard, and decides that it can't upload code to a keyboard so aborts.

## Failed Solution Number 2
I tried uploading `blink.ino` from a different laptop (also macos) but nothing changed.

## Failed Solution Number 3
I tried looking for ways to 'distrust' a keyboard to prevent the Arduino from sending keyboard strokes, but couldn't anything.

## Failed Solution Number 4
Maybe attempting to short circuit whichever wire the Arduino uses to communicate with the laptop will work, but I don't know nearly enough to do that so I'd just be randomly connecting wires to ground which I don't really want to do...

## Fin

I'm at a loss for what to try. I've logged an issue with the [github repo][1], but I can't think of other solutions.

  [1]: https://github.com/arduino/ArduinoCore-mbed/issues/424

body:
According to [the datasheet](https://docs.arduino.cc/resources/datasheets/ABX00030-datasheet.pdf)...

> ## 3.6 Board Recover
> All Arduino boards have a built-in bootloader which allows flashing the board via USB. In case a sketch locks up the
processor and the board is not reachable anymore via USB it is possible to enter bootloader mode by double-
tapping the reset button right after power up.

So, plug it in, and press the RESET button twice. That should then load the bootloader and it will sit there waiting for you to reprogram it.


message:
How to get started with writing code for a Hall Effect sensor?

One of my biggest questions concerns coding a Hall effect sensor to find wheel speed with an arduino mega.

I’ve got an lcd in digital pins(7,8,9,10,11,12) and a Hall effect sensor in digital pin 2.

I just have no idea how to code the actual rpm measuring process. Does anyone have any ideas or experience that can help me? My form of measurement is to spin something with a mounted magnet near it. The end game is to measure a car wheel rpm. Pointers? Tips?

body:
You can measure this in either RPM (revolutions per minute) or frequency (cycles per second).

Whether it be a minute or a second, you count the number of times you get a pulse and at the end of the minute/second you copy the total to your variable and reset the counter variable. If you need a fasster update rate, you can count for fractions of minute/second and do the calculation to show it in terms of RPM/frequency.

My first concern when solving this issue is how fast the magnet is going past the sensor (ie how many pulses per second).

If it is slow, you can do it in your main loop as long as you don't have any blocking instructions (such as `delay()`).

If it is fast you will probably have to look into an interrupt. When the pin goes high, it jumps to the interrupt function and increments a counter. Check the [input section for libraires][1] that make the interrupt process easy (or do it the old fashioned way, your choice). Some of the button libraries have interrupt specific functions.

  [1]: https://www.arduino.cc/reference/en/libraries/category/signal-input/output/


message:
Why is EEPROM commit not registering int values?

if(jsonDoc["delayOn"].as<int>() <= 255 && jsonDoc["delayOff"].as<int>() <= 255 && jsonDoc["delayUnitOn"].as<int>() <= 2 && jsonDoc["delayUnitOff"].as<int>() <= 2 &&
             jsonDoc["mode"].as<int>() <= 1 && jsonDoc["blink"].as<int>() <= 1 &&
             jsonDoc["timeOnHour"].as<int>() <= 23 && jsonDoc["timeOnMinute"].as<int>() <= 59 &&
             jsonDoc["timeOffHour"].as<int>() <= 23 && jsonDoc["timeOffMinute"].as<int>() <= 59) {

            int val;
            int addr_init = (relay*eepromSlotsPerRelayPin)*sizeof(int);

            val = jsonDoc["blink"].as<int>();
            EEPROM.put(addr_init,val);
            if(jsonDoc["blink"].as<int>()==1){ //0=off,1=on

              val = jsonDoc["mode"].as<int>();
              EEPROM.put(addr_init+(5*sizeof(int)),val);

              if (jsonDoc["mode"].as<int>()==0){ //blink mode

                val = jsonDoc["delayOn"].as<int>();
                EEPROM.put(addr_init+(1*sizeof(int)),val);
                val = jsonDoc["delayOff"].as<int>();
                EEPROM.put(addr_init+(3*sizeof(int)),val);
                //1=minute,0=second,2=hour
                val = jsonDoc["delayUnitOn"].as<int>();
                EEPROM.put(addr_init+(2*sizeof(int)),val);
                val = jsonDoc["delayUnitOff"].as<int>();
                EEPROM.put(addr_init+(4*sizeof(int)),val);
                EEPROM.end();

              }else if(jsonDoc["mode"].as<int>()==1){ //time switch mode

                val = jsonDoc["timeOnHour"].as<int>();
                EEPROM.put(addr_init+(6*sizeof(int)),val);
                val = jsonDoc["timeOnMinute"].as<int>();
                EEPROM.put(addr_init+(7*sizeof(int)),val);
                val = jsonDoc["timeOffHour"].as<int>();
                EEPROM.put(addr_init+(8*sizeof(int)),val);
                val = jsonDoc["timeOffMinute"].as<int>();
                EEPROM.put(addr_init+(9*sizeof(int)),val);
                EEPROM.end();
              }
              else {
                request->send(412, "text/plain", "unknown mode");
                return;
              }
            }
          }
          else {
            request->send(412, "text/plain", "a parameter is not within limits");
            return;
          }

          //initBlinkPinObjs
          int addr_init;
          int val,uom;
          for(int i = 0; i<maxRelayPins; i++) {
            bPinObjs[i].pin = relayPins[i];
            //EEPROM Slot per Relay dataStruct
            //0=>enable, 1=>durationOn, 2=>durationOnTimeMeasure,
            //3=>durationOff, 4=>durationOffTimeMeasure
            //5=>mode, 6=>timeOnHour, 7=>timeOnMinute,
            //8=>timeOffHour, 9=>timeOffMinute

            addr_init = (i*eepromSlotsPerRelayPin)*sizeof(int);

            val = 0;
            EEPROM.get(addr_init,val);
           bPinObjs[i].enable = val;

            val = 0;
            EEPROM.get(addr_init+(5*sizeof(int)),val);
            bPinObjs[i].mode = val;

            val = 0;
            EEPROM.get(addr_init+(6*sizeof(int)),val);
            bPinObjs[i].timeOnHour=val;

            val = 0;
            EEPROM.get(addr_init+(7*sizeof(int)),val);
            bPinObjs[i].timeOnMinute=val;

            val = 0;
            EEPROM.get(addr_init+(8*sizeof(int)),val);
            bPinObjs[i].timeOffHour = val;

            val = 0;
            EEPROM.get(addr_init+(9*sizeof(int)),val);
            bPinObjs[i].timeOffMinute = val;

            //delayOn
            //convert to millisec
            uom = 0;
            EEPROM.get(addr_init+(2*sizeof(int)),uom);
            switch(uom){
              case 0:
                bPinObjs[i].durationOn=0;
                val = 0;
                EEPROM.get(addr_init+(1*sizeof(int)),val);
                bPinObjs[i].durationOn = val*1000;
              break;
              case 1:
                bPinObjs[i].durationOn=0;
                val = 0;
                EEPROM.get(addr_init+(1*sizeof(int)),val);
                bPinObjs[i].durationOn = val*60000;
              break;
              case 2:
                bPinObjs[i].durationOn=0;
                val = 0;
                EEPROM.get(addr_init+(1*sizeof(int)),val);
                bPinObjs[i].durationOn = val*3600000;
              break;
              default:
              break;
            }
            //delayOff
            //convert to millisec
            uom = 0;
            EEPROM.get(addr_init+(4*sizeof(int)),uom);
            switch(uom){
              case 0:
                bPinObjs[i].durationOff = 0;
                val = 0;
                EEPROM.get(addr_init+(3*sizeof(int)),val);
                bPinObjs[i].durationOff = val*1000;
              break;
              case 1:
                bPinObjs[i].durationOff = 0;
                val = 0;
                EEPROM.get(addr_init+(3*sizeof(int)),val);
                bPinObjs[i].durationOff = val*60000;
              break;
              case 2:
                bPinObjs[i].durationOff = 0;
                val = 0;
                EEPROM.get(addr_init+(3*sizeof(int)),val);
                bPinObjs[i].durationOff = val*3600000;
              break;
              default:
              break;
            }
          }

```
--JSON INPUT printed from server--

relay:0
blink:1
mode:1
delayOn:56
delayOff:2
delayUnitOn:0
delayUnitOff:0
timeOnHour:5
timeOnMinute:56
timeOffHour:7
timeOffMinute:48
```

```
OUTPUT printed from server:
--Objects content--
Size of INT:4
---------0--------- init addr: 0
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------1--------- init addr: 40
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------2--------- init addr: 80
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------3--------- init addr: 120
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------4--------- init addr: 160
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------5--------- init addr: 200
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------6--------- init addr: 240
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------7--------- init addr: 280
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
---------8--------- init addr: 320
[0]enable: 0
[1]durationOn: 0
[2]durationOnUom: 0
[3]durationOff: 0
[4]durationOffUom: 0
[5]mode: 0
[6]onHr: 0
[7]onMin: 0
[8]offHr: 0
[9]offMin: 0
```

This is inside an esp8266 async webserver `server.on` method.
My `EEPROM.begin` is in `setup` function.
Initially, only the first `put` within a block becomes committed .
Now, nothing is registering after I implemented the `sizeof(int)` inside addresses.

The intention is to store `int` data passed thru `http post` per relay pin [total of 9 pins]. The program then uses the data to perform on a relay:
 - blink
 - switch on/off based on time (hour,minute)
 ...

I've tried all sorts to fix:
 - `commit`,`end` after every `put`
 - `EEPROM.begin(512)` then `commit` & `end` on every `put`
 - add `delay`s
 - use `end` only instead of `commit`
 - add address range for `sizeof(int)`

body:
Weird, i commented out the `val=0;` before `EEPROM.get`s also replaced `EEPROM.end` with `EEPROM.commit`.

This is the output now:
```
--Objects content--
Size of INT:4
---------0--------- init addr: 0
[0]enable: 1
[4]durationOn: 3000
[8]durationOnUom: 0
[12]durationOff: 2000
[16]durationOffUom: 0
[20]mode: 1
[24]onHr: 9
[28]onMin: 11
[32]offHr: 9
[36]offMin: 12
---------1--------- init addr: 40
[40]enable: 1
[44]durationOn: 0
[48]durationOnUom: -1
[52]durationOff: 0
[56]durationOffUom: -1
[60]mode: -1
[64]onHr: -1
[68]onMin: -1
[72]offHr: -1
[76]offMin: -1
---------2--------- init addr: 80
[80]enable: 1
[84]durationOn: 0
[88]durationOnUom: -1
[92]durationOff: 0
[96]durationOffUom: -1
[100]mode: -1
[104]onHr: -1
[108]onMin: -1
[112]offHr: -1
[116]offMin: -1
---------3--------- init addr: 120
[120]enable: 1
[124]durationOn: 0
[128]durationOnUom: -1
[132]durationOff: 0
[136]durationOffUom: -1
[140]mode: 1
[144]onHr: 5
[148]onMin: 56
[152]offHr: 7
[156]offMin: 48
---------4--------- init addr: 160
[160]enable: 1
[164]durationOn: 0
[168]durationOnUom: -1
[172]durationOff: 0
[176]durationOffUom: -1
[180]mode: -1
[184]onHr: -1
[188]onMin: -1
[192]offHr: -1
[196]offMin: -1
---------5--------- init addr: 200
[200]enable: 1
[204]durationOn: 0
[208]durationOnUom: -1
[212]durationOff: 0
[216]durationOffUom: -1
[220]mode: -1
[224]onHr: -1
[228]onMin: -1
[232]offHr: -1
[236]offMin: -1
---------6--------- init addr: 240
[240]enable: 1
[244]durationOn: 0
[248]durationOnUom: -1
[252]durationOff: 0
[256]durationOffUom: -1
[260]mode: -1
[264]onHr: -1
[268]onMin: -1
[272]offHr: -1
[276]offMin: -1
---------7--------- init addr: 280
[280]enable: 1
[284]durationOn: 0
[288]durationOnUom: -1
[292]durationOff: 0
[296]durationOffUom: -1
[300]mode: -1
[304]onHr: -1
[308]onMin: -1
[312]offHr: -1
[316]offMin: -1
---------8--------- init addr: 320
[320]enable: 1
[324]durationOn: 0
[328]durationOnUom: -1
[332]durationOff: 0
[336]durationOffUom: -1
[340]mode: -1
[344]onHr: -1
[348]onMin: -1
[352]offHr: -1
[356]offMin: -1

--JSON inputs--

relay:0
blink:1
mode:1
delayOn:3
delayOff:2
delayUnitOn:0
delayUnitOff:0
timeOnHour:9
timeOnMinute:11
timeOffHour:9
timeOffMinute:12
```


message:
printf %s gives gibberish

This Code:

    String S0 = "";
    String S1 = "1";
    String S2 = "12";
    String S3 = "123";
    String S4 = "1234";
    String S5 = "12345";
    String S6 = "123456";
    String S7 = "1234567";
    String S8 = "12345678";
    String S9 = "123456789";
    String S10 = "1234567890";
    String S11 = "1234567890a";
    String S12 = "1234567890ab";
    String S13 = "1234567890abc";
    String S14 = "1234567890abcd";
    String S15 = "1234567890abcde";
    String S16 = "1234567890abcdef";
    String S17 = "1234567890abcdefg";
    String S18 = "1234567890abcdefgh";
    String S19 = "1234567890abcdefghi";
    String S20 = "1234567890abcdefghij";
    Serial.printf("(0):%s\n", S0);
    Serial.printf("(1):%s\n", S1);
    Serial.printf("(2):%s\n", S2);
    Serial.printf("(3):%s\n", S3);
    Serial.printf("(4):%s\n", S4);
    Serial.printf("(5):%s\n", S5);
    Serial.printf("(6):%s\n", S6);
    Serial.printf("(7):%s\n", S7);
    Serial.printf("(8):%s\n", S8);
    Serial.printf("(9):%s\n", S9);
    Serial.printf("(10):%s\n", S10);
    Serial.printf("(11):%s\n", S11);
    Serial.printf("(12):%s\n", S12);
    Serial.printf("(13):%s\n", S13);
    Serial.printf("(14):%s\n", S14);
    Serial.printf("(15):%s\n", S15);
    Serial.printf("(16):%s\n", S16);
    Serial.printf("(17):%s\n", S17);
    Serial.printf("(18):%s\n", S18);
    Serial.printf("(19):%s\n", S19);
    Serial.printf("(20):%s\n", S20);

Gives This Result:

    (0):
    (1):1
    (2):12
    (3):123
    (4):1234
    (5):12345
    (6):123456
    (7):1234567
    (8):12345678
    (9):123456789
    (10):�H�?
    (11):�^�?
    (12):_�?
    (13):�_�?
    (14):`�?
    (15):0`�?
    (16):�`�?
    (17):a�?
    (18):@a�?
    (19):pa�?
    (20):�a�?

Any ideas??
PS: IT IS OBVIOUS that for whatever platform it is being used, it is working for short strings and not for longer strings! And it has been answered in the comments after you have closed it! So if you do not know the answer instead of closing, maybe it is better to leave it for others to answer it...

body:
(Community Wiki answer assembled from the comments)

Noting that the standard Arduino core doesn't have a `Serial.printf()` function. The ESP32 core does.

You need `.c_str()` in your calls. `.printf()` is a [variadic function][1] which doesn't really have access to any sort of destination type to do conversions; it relies entirely on your passing the correct format specifiers. It is just supplying the bytes to the `String` object, which is not simply a `const char *` (specified `%s`). If you're curious, the behaviour difference you're seeing is down to whether "small string optimization" is being used.

Short string optimization is where shorter strings are stored directly in the object and for longer strings it's used as pointers.

The suggested solution is to use: `Serial.printf("%s",Sxx.c_str());`

  [1]: https://en.cppreference.com/w/c/variadic


message:
What size diode should I use?

I'm building a project with an ESP8266 which requires multiple analog inputs - but the ESP8266 only has one. I know of ways to multiplex with dedicated modules, but since I have lots of diodes lying around I've decided to multiplex with them. I've found lots of tutorials on how to multiplex (e.g. [this one](https://www.youtube.com/watch?v=QW0YcxN3pao)) but none of them say what size diode to use.
So which size shall I use? Does it even matter? I have `1N4148`s, `1N4007`s, `1N5819`s, `1N5399`s, `1N5408`s, `1N5822`s, `FR107`s and `FR207`s.

body: I do not think it is possible to truly multiplex analog signals with simply using diodes in an 'or' configuration. Your demo shows powering only one sensor at a time and isolating the sensors (pots) output with the diode "or". This demo works as long as only one sensor is powered and or the rest output voltage is below the one you are measuring. You also have a voltage drop across the diode and nothing to keep the signal stable, it will bounce around by the forward voltage of the diode or more. The diode will add about a 10% error and reduce your measurement range. To stabilize it you need to add some resistance between the analog input of the microprocessor and ground (load sensor output). This will introduce some error in your reading but you can compensate for that. Any diode will work, use one that you're comfortable with or you can check their characteristics and make a choice.


body:
By the time you finish mucking around powering different devices from I/O pins (which have a limit to how much current they can source) and then install different diodes for each one, you are probably better off (and more simply) to use a multiplexer like the 74HC4051 which I describe [here](http://www.gammon.com.au/forum/?id=11976).

As Gil mentioned in his reply, the 0.7V drop (or thereabouts) that the diodes will incur are going to affect the accuracy of the readings, plus you have the issue that the devices might take a few milliseconds to stablise if you keep turning them on and off.

To answer your question, though, any signal diode should do the trick as there will be very little current drawn, as the analog input is high impedance. For example the 1N4148.

You can connect 8 devices to the 74HC4051 with only 4 connections between it and the microprocessor. Three "selector" pins which therefore give you 8 possible combinations, and the signal pin which would go to your analog input.

You could even get a 74HC4067 and have 16 inputs, for the cost of only one more selector pin.


message:
Can you write c code in arduino ide?

So i know that the native arduino language is written in c/c++, but does that mean that i can write pure c code in the arduino ide, or that i have to use the arduino specified language? I’m new to this and very confused, please bear with me here :’)

body:
Yes, you can write in pure C. Some parts of the Arduino core API are
actually defined in C, e.g. `pinMode()` and `digitalWrite()` (at least
in the AVR core). So you can use them. Other parts, like `Serial`, are
C++ objects, and you will not be able to use them from plain C.

The Arduino IDE, however, will insist on you writing a file with the
.ino extension, that it will compile as preprocessed C++. You do not
need to put anything in that file though. If you want to write your
whole program in pure C, you can create an empty .ino file, and in the
same folder a .c file with your whole program. In that file you can
define your own `main()`. If you want to use the Arduino core API
though, you should instead define `setup()` and `loop()`, and rely on
the core-provided `main()`.


message:
Toggle button switches through case statements with button debouncing

The overview of my code is that I want a toggle button to be pushed and each button push will move the code to the next case statement. In each case statement, there will be different LED functions. I need help with a few things
1. I need help with blinking 4 of the LEDs continuously with 100ms pause in case 1. Because it is not in the main loop, I am having trouble getting the 4 LEDs to switch on and off. Normally, I could just have a simple code that turns it on, then compares previous to last and if different, turns it off, and this continues.
2. I need the code to go back to case 0 once the button has been held for 2 seconds.
3. I cannot get my button debounce code to work from case 0 to case 1. If I add the debounce code in case 0 how I have it in the rest of the cases, it wont run through the rest of the cases.
Below is the code:
```

//LED variables for left turn signal OUT
int LED_1 = 2;
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5;

//LED variables for right turn signal OUT
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//break signal OUT
int BS_OUT = A5;

//reverse signal OUT
int RS_OUT = 10;

//toggle switch button between different modes
int toggle_IN = A4;

//switch case statement variable for togglemodes
int toggleState = 0;

//variables to see if the toggle button has been pressed or not
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true or false to save whether button has been pressed for switching case statements
bool enabledToggle;

//debounce time to take care of button bouncing
const int debounce = 100; //ms

//time for holding a current time of millis()
unsigned long t = 0;

void setup()
{
  Serial.begin(9600);
  //toggle button input
  pinMode(toggle_IN, INPUT);

  //led outputs
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
   //checking to see if toggle button has been pushed
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
  {
    if(newSwitchStateToggle == HIGH)
    {
      //enabling toggle for if statements
      enabledToggle = true;
      //case switch for flow through 4 different LED output options
      toggleButtonState();

    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }
}

void toggleButtonState()
{
  unsigned long nowToggle = millis();
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            digitalWrite(LED_1, HIGH);
            t = nowToggle;
            toggleState = 1;
          }

          break;

    case 1:
    Serial.println("1111");
          if(enabledToggle)
          {
            digitalWrite(LED_1, LOW);
            digitalWrite(LED_2, HIGH);
            //alows going to next state after 100ms for button debounce
            if(nowToggle - t > debounce)
            {
              toggleState = 2;
              t = nowToggle;
            }
          }

          break;

     case 2:
     Serial.println("2222");
          if(enabledToggle)
          {
            digitalWrite(LED_2, LOW);
            digitalWrite(LED_3, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 3;
              t = nowToggle;
            }
          }

          break;

     case 3:
     Serial.println("3333");
         if(enabledToggle)
          {
            digitalWrite(LED_3, LOW);
            digitalWrite(LED_4, HIGH);
            if(nowToggle - t > debounce)
            {
              toggleState = 4;
              t = nowToggle;
            }
          }
          break;

     case 4:
     Serial.println("44444");
          if(enabledToggle)
          {
            turnOffLeds();
            if(nowToggle - t > debounce)
            {
              toggleState = 0;
              t = nowToggle;
            }
          }
          break;

  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
}

```

updated code: trying to add in debounce but it will not work
```

int LED_1 = 2;
int LED_2 = 3;
int LED_3 = 4;
int LED_4 = 5;

int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//toggle switch button between different modes
int toggle_IN = A4;

//switch case statement variable for togglemodes
int toggleState = 0;

//variables to see if the toggle button has been pressed or not
boolean oldSwitchStateToggle = LOW;
boolean newSwitchStateToggle = LOW;

//true or false to save whether button has been pressed for switching case statements
bool enabledToggle;

//debounce time to take care of button bouncing
const int debounce = 100; //ms

//time for holding a current time of millis()
unsigned long t = 0;

int ledBlinkState = LOW;

unsigned long prevBlinkMillis = 0;

const int blinkInterval = 150;

bool state1 = false;
bool state2 = false;
bool state3 = false;
bool state4 = false;
bool state0 = false;

void setup()
{
  Serial.begin(9600);
  //toggle button input
  pinMode(toggle_IN, INPUT);

  //led outputs
  pinMode(LED_4, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  unsigned long nowToggle = millis();
  Serial.print("NOWWWWWW");
  Serial.println(nowToggle);
   //checking to see if toggle button has been pushed
   newSwitchStateToggle = digitalRead(toggle_IN);
   if(newSwitchStateToggle != oldSwitchStateToggle)
   {
    t = nowToggle;
    Serial.print("TIMEEEEE");
    Serial.println(t);
    if(newSwitchStateToggle == HIGH)
    {
      if(nowToggle - t > debounce)
      {
        //enabling toggle for if statements
        enabledToggle = true;
        //case switch for flow through 4 different LED output options
        toggleButtonState();
      }

    }
    else
    enabledToggle = false;
    oldSwitchStateToggle = newSwitchStateToggle;
  }

  unsigned long currentBlinkMillis = millis();

  if(state0 == true)
  {
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);

    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
    }
  }

  if(state1 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);

    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }

  if(state2 == true)
  {
    if(currentBlinkMillis - prevBlinkMillis >= blinkInterval)
    {
      prevBlinkMillis = currentBlinkMillis;
      if(ledBlinkState == LOW)
      {
        ledBlinkState = HIGH;
      }
      else
      {
        ledBlinkState = LOW;
      }
      digitalWrite(LED_1, ledBlinkState);
      digitalWrite(LED_2, ledBlinkState);
      digitalWrite(LED_3, ledBlinkState);
      digitalWrite(LED_4, ledBlinkState);
      digitalWrite(LED_5, ledBlinkState);
      digitalWrite(LED_6, ledBlinkState);
      digitalWrite(LED_7, ledBlinkState);
      digitalWrite(LED_8, ledBlinkState);
    }
  }

  if(state3 == true)
  {
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, HIGH);
    digitalWrite(LED_3, HIGH);
    digitalWrite(LED_4, HIGH);
    digitalWrite(LED_5, HIGH);
    digitalWrite(LED_6, HIGH);
    digitalWrite(LED_7, HIGH);
    digitalWrite(LED_8, HIGH);
  }

  if(state4 == true)
  {
    turnOffLeds();
  }

}

void toggleButtonState()
{
  switch (toggleState)
  {

    case 0:
    Serial.println("0000");
          if(enabledToggle)
          {
            turnOffLeds();
            state4 = false;
            state0 = true;
            toggleState = 1;
          }

          break;

    case 1:
    Serial.println("1111");
          if(enabledToggle)
          {
            turnOffLeds();
            state0 = false;
            state1 = true;
            toggleState = 2;
          }

          break;

     case 2:
     Serial.println("2222");
          if(enabledToggle)
          {
            turnOffLeds();
            state1 = false;
            state2 = true;
            toggleState = 3;
          }

          break;

     case 3:
     Serial.println("3333");
         if(enabledToggle)
          {
            turnOffLeds();
            state2 = false;
            state3 = true;
            toggleState = 4;
          }
          break;

     case 4:
     Serial.println("44444");
          if(enabledToggle)
          {
            turnOffLeds();
            state3 = false;
            state4 = true;
            toggleState = 0;
          }
          break;

  }
}

void turnOffLeds()
{
  digitalWrite(LED_1, LOW);
  digitalWrite(LED_2, LOW);
  digitalWrite(LED_3, LOW);
  digitalWrite(LED_4, LOW);
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

```

body:
I would recommend you start with an existing library to do the "button debouncing" and "long button press" detection.

The [EasyButton][1] library on github and via the Arduino IDE library manager has potential.

Here is a test sketch which shows the "button detection" part of your requirement.

If you were to add a variable to represent "state", this code could be adapted to control a `case` statement bases on state.

```c++
// Sketch uses 3286 bytes (10%) of program storage space.
// Global variables use 357 bytes (17%) of dynamic memory.
#include <EasyButton.h>

// EasyButton(uint8_t pin,
//            uint32_t debounce_time = 35,
//            bool pullup_enable = true,
//            bool active_low = true)
EasyButton button(2);

void onPressed(){
  // Your code here to INCREMENT a "state counter".
  Serial.println("Button pressed");
}

void onPressedForDuration(){
  // Your code here to SET the "state counter" to 0.
  Serial.println("Button pressed for duration");
}

void setup(){

  // Test output to serial monitor.
  Serial.begin(9600);

  // Initialize the button.
  button.begin();

  // Add the callback function to be called when the button is pressed.
  button.onPressed(onPressed);

  // Add the callback function to be called when the button is pressed
  // for at least the given time.
  button.onPressedFor(2000, onPressedForDuration);

}

void loop(){

  // Continuously read the status of the button.
  button.read();

}

```

  [1]: https://github.com/evert-arias/EasyButton


body:
I answered how to do a mode switch with just one button many many years ago.  Make use of it what you will... it's just a sample skeleton. Here is the code I used:

```
/*
 Using a single switch to select between 3 modes
*/
// Schematic: http://www.pwillard.com/files/mode4.jpg
//===============================================================
// Global Variables & Constants
//===============================================================

const int ledPinOne = 2; // LED1 ANODE
const int ledPinTwo = 4; // LED2 ANODE
const int ledPinThree = 7; // LED3 ANODE
const int modePin = 13; // Active HIGH, held low by 4.7K

int mode = 0; // Selector State (Initial state = ALL OFF)
int val = 0; // Pin 13 HIGH/LOW Status
int butState = 0; // Last Button State
int modeState = 0; // Last Mode State
boolean debug = 1; // 1 = Print Serial Enabled / 0 = disabled

//===============================================================
// SETUP
//===============================================================
void setup () {
 pinMode(ledPinOne, OUTPUT);
 pinMode(ledPinTwo, OUTPUT);
 pinMode(ledPinThree, OUTPUT);
 pinMode(modePin, INPUT);
 if (debug){
 Serial.begin(9600);
 Serial.print("Initial Mode: ");
 Serial.println(mode);
 Serial.print("Setup Complete\n");
 }
}

//===============================================================
// Main Loop
//===============================================================
void loop() {

 val = digitalRead(modePin);

 // If we see a change in button state, increment mode value
 if (val != butState && val == HIGH){
 mode++;
 }

 butState = val; // Keep track of most recent button state

 // No need to keep setting pins *every* loop
 if (modeState != mode){

 // If no keys have been pressed yet don't execute
 // the switch code below
 // if (mode != 0) {

 switch ( mode ) {
 //case 1 is actually handled below as default

case 2:
 digitalWrite(ledPinOne, LOW);
 digitalWrite(ledPinTwo, HIGH);
 showState();
 break;
 case 3:
 digitalWrite(ledPinTwo, LOW);
 digitalWrite(ledPinThree, HIGH);
 showState();
 break;
 default:
 mode = 1;
 // loop back to 1 by default, seems redundant but
 // it also handles the "mode is > 3" problem
 digitalWrite(ledPinThree, LOW);
 digitalWrite(ledPinOne, HIGH);
 showState();
 break;
 } // end switch
// } // end of "if mode = 0" check
 } // end of ModeState check
 modeState = mode; // Keep track of mode recent mode value
 delay(10); // slow the loop just a bit for debounce
}

//===============================================================
// Subroutine
//===============================================================
void showState() {
 if (debug){
 Serial.print("Mode: ");
 Serial.println(mode);
 }
}
```


message:
How to expand this code for more than four 74hc165 shift registers? It works well with maximum four 74hc165 shift registers at a time

#define NUMBER_OF_SHIFT_CHIPS   4
    #define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

    int LoadPin    = 9;
    int EnablePin  = 8;
    int DataPin    = 11;
    int ClockPin   = 12;

    unsigned long pinValues;
    unsigned long oldPinValues;

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

      pinMode(LoadPin, OUTPUT);
      pinMode(EnablePin, OUTPUT);
      pinMode(ClockPin, OUTPUT);
      pinMode(DataPin, INPUT);

      digitalWrite(ClockPin, LOW);
      digitalWrite(LoadPin, HIGH);

      pinValues = read_shift_regs();
      print_byte();
      oldPinValues = pinValues;
    }

    void loop()
    {
      pinValues = read_shift_regs();
      if (pinValues != oldPinValues)
      {
        print_byte();
        oldPinValues = pinValues;
      }
    }

    unsigned long read_shift_regs()
    {
      long bitVal;
      unsigned long bytesVal = 0;

      digitalWrite(EnablePin, HIGH);
      digitalWrite(LoadPin, LOW);
      delayMicroseconds(5);
      digitalWrite(LoadPin, HIGH);
      digitalWrite(EnablePin, LOW);

      for (int i = 0; i < DATA_WIDTH; i++)
      {
        bitVal = digitalRead(DataPin);
        bytesVal |= (bitVal << ((DATA_WIDTH - 1) - i));

        digitalWrite(ClockPin, HIGH);
        delayMicroseconds(5);
        digitalWrite(ClockPin, LOW);
      }

      return (bytesVal);
    }

    void print_byte() {
      byte i;
      Serial.println("*Shift Register Values:*\r\n");

      for (byte i = 0; i <= DATA_WIDTH - 1; i++)
      {
        Serial.print(pinValues >> i & 1, BIN);

        Serial.print("  ");

      }
      Serial.print("\n");
      Serial.println(); Serial.println();
    }

body:
As StarCat mentioned in the comments, you return the read value as an `unsigned long`, which can hold exactly 4 bytes. When trying to write more into it with your current code you will loose the previous data. So you need a data structure that is able to hold all the data that you want to read.

I suggest that you do it like the `shiftIn()` function of the Arduino framework: Use a `DATA_WIDTH` of 8 bits (1 byte) and enclose the reading loop into another for loop, where you iterate over `NUMBER_OF_SHIFT_CHIPS`, getting exactly one byte from each chip and putting it into an array of `byte` (aka `uint8_t`). There are multiple ways to do this, but I will describe only one, not necessarily the best one for your situation.

First declare an array of `byte` on global scope. It needs to be `NUMBER_OF_SHIFT_CHIPS` bytes big. We initialize the data to zero:

    byte shift_data[NUMBER_OF_SHIFT_CHIPS] = {0};

Set `DATA_WIDTH` to 8 bits:

    #define DATA_WIDTH   8

Now look into `read_shift_regs()`. Enclose the for loop into another for loop iterating over `NUMBER_OF_SHIFT_CHIPS` and use that index to write the data into the corresponding byte in `shift_data` (by using `shift_data[j]` with the corresponding index `j`). As we write a global array we don't need to return anything, so you can make the function `void` (unless you want to return some other information).

    void read_shift_regs()
    {
      long bitVal;

      digitalWrite(EnablePin, HIGH);
      digitalWrite(LoadPin, LOW);
      delayMicroseconds(5);
      digitalWrite(LoadPin, HIGH);
      digitalWrite(EnablePin, LOW);
      for(int j = 0; j < NUMBER_OF_SHIFT_CHIPS; j++){
        for (int i = 0; i < DATA_WIDTH; i++)
        {
          bitVal = digitalRead(DataPin);
          shift_data[j] |= (bitVal << ((DATA_WIDTH - 1) - i));

          digitalWrite(ClockPin, HIGH);
          delayMicroseconds(5);
          digitalWrite(ClockPin, LOW);
        }
      }
    }

Then change all lines with

    pinValues = read_shift_regs();

to
    read_shift_regs();

And finally - to actually use the read values - you now need to access a complete array instead of a single variable. I will leave that to you. Basically its again just iterating over all elements of the array.

Note:
- I have not tested the above code in any way. Its more about explaining the principle.
- One can also handle the array with parameters, but if you don't know how to use arrays as parameters, then this can give you a lot of other errors. So I didn't suggest that.


message:
How to make an Arduino act reliably as an SPI slave?

I want two Arduino Nanos to communicate with each other using SPI, ideally at around 2MHz or faster.

I have two standard Nanos running at 16MHz on 5V.

- The master uses `SPI.transfer()` to send an array across the wire.¹ For ease of troubleshooting, the array alternately contains a bunch of zeroes *or* a bunch of 255s; but never both.

- The slave simply returns decimal 66 for every byte. This was chosen because it's easy to spot on a logic trace.

- The master checks the responses, and if there are any values that aren't 66, it prints the array to the UART.

Even at 125Kbit, which is the slowest available speed, I'm regularly getting corrupted bytes. Interestingly, most of the time (but not always!) the corrupted byte is either 0 or 255 - in other words, exactly the same as the byte sent from the master! This strikes me as a very unlikely coincidence.

I have inspected the traffic with a logic analyser, and it seems that the slave just occasionally decides not to operate as instructed; and instead it just sends the input straight out again. As in, the byte going out on MISO is exactly the same as the byte coming in on MOSI. But only *sometimes.*

What is happening here? Why doesn't it work? And what can I do about it?

---

Master sketch:

```
#define MOSI 12
#define SCK  13

#include <SPI.h>
#include "pins_arduino.h"
#include <avr/wdt.h>

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

 digitalWrite(SS, HIGH);
 pinMode(SS, OUTPUT);
 digitalWrite(SCK, HIGH);
 pinMode(SCK, OUTPUT);
 pinMode(MOSI, OUTPUT);

 SPI.setClockDivider(SPI_CLOCK_DIV128);  // 125KHz
 SPI.begin();

 Serial.println("\n\nSTARTING...\n");
}

void do_transfer(byte attempt, byte payload) {

 // packet size of 200
 byte buffer[200];

 // initialise packet
 for (byte count = 0; count < sizeof(buffer); count++)
  buffer[count] = payload;

 // perform transfer
 digitalWrite(SS, LOW);
 SPI.transfer(buffer, sizeof(buffer));
 digitalWrite(SS, HIGH);    // SS is pin 10

 // tally results
 byte successes = 0, failures = 0;
 for (byte index = 0; index < sizeof(buffer); index++)
  if (buffer[index] == 66) successes++; else failures++;

 // print results
 Serial.print("Attempt ");
 Serial.print(attempt);
 Serial.print(" with payload ");
 Serial.print(payload);
 Serial.print(": ");
 if (failures == 0)
  Serial.print("SUCCESS");
 else {
  Serial.print(successes);
  Serial.print(" correct bytes, ");
  Serial.print(failures);
  Serial.print(" incorrect bytes");
  for (byte index = 0; index < sizeof(buffer); index++) {
   if (index % 10 == 0)
    Serial.print("\n\t");
   if (buffer[index] == 66)
    Serial.print("-");
   else
    Serial.print(buffer[index]);
   if (index < sizeof(buffer) - 1)
    Serial.print("\t");
  }
 }
 Serial.println();
 Serial.println();
}

void loop(void) {
 delay(800);               // give the slave time to be ready

 for (byte attempt = 1; attempt <= 10; attempt+=2) {
  do_transfer(attempt, 0x00);
  do_transfer(attempt+1, 0xFF);
  wdt_reset();
 }
 while(true);              // end of program
}
```

Slave sketch:

```
#include "pins_arduino.h"

void setup(void) {
 pinMode(MISO, OUTPUT);   // MISO needs to be an output
 SPCR |= _BV(SPE);    // enable SPI in slave mode
 SPCR |= _BV(SPIE);      // enable interrupts
 SPDR = 66;
}

ISR (SPI_STC_vect) { SPDR = 66; } // just send 66 until the cows come home

void loop (void) { }
```

Connections: The following pins on both Arduinos are connected together:

  - SS (pin 10)
  - MISO (pin 11)
  - MOSI (pin 12)
  - SCK (pin 13)
  - GND

---

¹ The problem also happens if I send one byte at a time using `SPI.transfer()`, unless (maybe) if I insert a 1ms delay between each byte. Which of course is ridiculous.

body:
Your problem here is timing. I tried your setup, and found that I did indeed get occasional errors at 125 kHz. Disabling Timer 0 (as suggested by Chrisl) fixed that:

      power_timer0_disable();

> But while it now works up to 250KHz, I get many many errors at 500KHz.

OK, the time between clock pulses is now 2 µs, however as I document [here](http://gammon.com.au/interrupts) the time taken to execute an ISR like SPI_STC_vect is 2.625 µs, therefore it can't keep up with having to put the data there every 2 s.

You actually have slightly more time than 2 µs because the critical time is the time between the end of the first byte (which is when the ISR is called) and the time before the start of the second byte, which is when the master will start sampling your response.

See screenshot below with the critical time boxed in yellow.

[![SPI timing screenshot][1]][1]

That time is 2.45 µs and the ISR takes 2.625 µs. Now some of that is the ISR epilogue which won't really matter that much, but you can see that things are tight. It's hard to know exactly at what point the processor starts calling the ISR after the last bit arrives, and the length of the instruction it is currently executing could be an influencing factor.

I got your sketches to work running at 250 kHz with these amendments to the slave:

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

    #include "pins_arduino.h"
    #include <avr/power.h>
    #include <avr/sleep.h>

    void setup(void) {
      pinMode(MISO, OUTPUT);          // MISO needs to be an output
      SPCR |= _BV(SPE);               // enable SPI in slave mode
      SPCR |= _BV(SPIE);              // enable interrupts
      SPDR = 66;
      power_timer0_disable();
      set_sleep_mode (SLEEP_MODE_IDLE);
    }

    ISR (SPI_STC_vect) { SPDR = 66; }   // just send 66 until the cows come home

    void loop (void)
     {
     sleep_mode ();
     }

The sleeping in idle mode makes sure that the processor is not half-way through an instruction when the interrupt is raised.

As expected (for the reasons above) it did not work at 500 kHz.

If you want to transfer data reliably you need to allow, in the master, for the time it takes the slave to do stuff. Every line of code in the slave means that the master has to wait for that to be executed.

I mention that in [my page about SPI](http://www.gammon.com.au/spi) where I build in a delay in the master, if I want the slave to do calculations or something.

---

> But the datasheet says that speeds of Fosc/4 are possible in slave mode, which would be 4MHz in this case. Would that be achievable if I removed the ISR and just used a busy loop?

Well, yes the datasheet has an example of doing a busy loop:

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

    char SPI_SlaveReceive(void)
    {
    /* Wait for reception complete */
    while(!(SPSR & (1<<SPIF)))
    ;
    /* Return Data Register */
    return SPDR;
    }

Regardless of what they claim, what you intend has to be physically possible. So with Fosc/4, assuming a 16 MHz clock, you have 2 µs for a byte to arrive (250 ns * 8). So the hardware may well be able to receive one byte in that time, and you may just have enough clock cycles to notice it arriving and plonk it into memory somewhere (although things could be tight) but you *won't* have time to send a different response after each incoming byte, because you only have around 250 ns to do it in, and the loop that detects the interrupt will probably use up most or all of that.

After a bit of mucking around, I got it to work at 250 kHz where the objective was just for the slave to return some data (after all, I presume that is what the slave is supposed to do).

## Master

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

    #define MOSI    12
    #define SCK     13

    #include <SPI.h>
    #include "pins_arduino.h"
    #include <avr/wdt.h>

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

        digitalWrite(SS, HIGH);
        pinMode(SS, OUTPUT);
        digitalWrite(SS, HIGH);

        digitalWrite(SCK, HIGH);
        pinMode(SCK, OUTPUT);
        pinMode(MOSI, OUTPUT);

        SPI.begin();
        SPI.setClockDivider(SPI_CLOCK_DIV64);

        Serial.println("\n\nSTARTING...\n");

    }

    void do_transfer(byte attempt, byte payload) {

        // packet size of 200
        byte buffer[200];

        // perform transfer
        digitalWrite(SS, LOW);
        delay (1);    // give slave time to react
        SPI.transfer(buffer, sizeof(buffer));
        digitalWrite(SS, HIGH);    // SS is pin 10

        // tally results
        byte successes = 0, failures = 0;
        for (byte index = 0; index < sizeof(buffer); index++)
            if (buffer[index] == index) successes++; else failures++;

        // print results
        Serial.print("Attempt ");
        Serial.print(attempt);
        Serial.print(" with payload ");
        Serial.print(payload);
        Serial.print(": ");
        if (failures == 0)
            Serial.print("SUCCESS");
        else {
            Serial.print(successes);
            Serial.print(" correct bytes, ");
            Serial.print(failures);
            Serial.print(" incorrect bytes");
            for (byte index = 0; index < sizeof(buffer); index++) {
                if (index % 10 == 0)
                    Serial.print("\n\t");
                if (buffer[index] == index)
                    Serial.print("-");
                else
                    Serial.print(buffer[index]);
                if (index < sizeof(buffer) - 1)
                    Serial.print("\t");
            }
        }
        Serial.println();
        Serial.println();
    }

    void loop(void) {
        delay(800);                                                         // give the slave time to be ready

        for (byte attempt = 1; attempt <= 10; attempt+=2) {
            do_transfer(attempt, 0x00);
            do_transfer(attempt+1, 0xFF);
            wdt_reset();
        }
        while(true);                                                        // end of program
    }

## Slave

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

    #include "pins_arduino.h"
    #include <avr/power.h>
    #include <avr/sleep.h>

    const int TEST_SIZE = 200;

    volatile byte my_data [TEST_SIZE];

    volatile byte dummy;

    ISR (PCINT0_vect)
     {
     // handle pin change interrupt for D8 to D13 here

      // ignore transition to HIGH
      if (digitalRead (SS) == HIGH)
        return;

      SPDR = 0;

      for (byte i = 0; i < TEST_SIZE; i++)
        {
        SPDR = my_data [i];
        while(!(SPSR & (1<<SPIF)))
          {
          // if SS went high, give up
          if (PINB & (1 << 2))
            return;
          }
        } // end of for loop

     }  // end of PCINT0_vect

    void setup(void) {
      pinMode(MISO, OUTPUT);          // MISO needs to be an output
      SPCR |= _BV(SPE);               // enable SPI in slave mode
      power_timer0_disable();
      for (int i = 0; i < TEST_SIZE; i++)
        my_data [i] = i;

      // pin change interrupt for D10
      PCMSK0 |= bit (PCINT2);  // want pin 10
      PCIFR  |= bit (PCIF0);   // clear any outstanding interrupts
      PCICR  |= bit (PCIE0);   // enable pin change interrupts for D8 to D13

      SPDR = 0;

      set_sleep_mode (SLEEP_MODE_IDLE);

    }

    void loop (void)
      {
      sleep_mode ();
      }

At the next clock divisor (SPI_CLOCK_DIV32) I started getting occasional errors. After all, Fclk/32 is only 2 µs per clock pulse and 16 µs per byte, and the necessary stuff in the inner loop must be taking that long — I didn't calculate the individual instruction times, you are welcome to do that. :)

I was hoping to get better performance than that, but then I realised that even with a tight sending loop in the slave, you can't afford to send before the master has acknowledged the previous byte (ie. that it has read it) so you still have the tight interval between the end of one byte and the start of the next, which is the time in which you have to prepare the next byte for sending.

It's not as bad if you are the master, because *you* control when the byte starts, so you can take as long as you want between bytes.

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


message:
ESP32 ADC <-> WIFI Issue

I'm using the ESP32's ADC1 (not ADC2, which conflicts with Wi-Fi functionality) to capture some analog data received @IO36 (an ADC1 port). **As soon as I uncomment the `WiFi.mode(WIFI_AP_STA)` line (even when the `WiFi.begin()` line is still commented out), analog readings go crazy!**

**SOME SIDE NOTES:**
**1-** The hardware that processes input signal to make it suitable for ESP32 analog input uses the same power source as the ESP32 module.
**2-** A 100uF SMD capacitor is connected to the source line of the ESP32 module just beside it to lessen impact of its power consumption ripples on other devices.
**3-** I tried `adc1_get_raw`, which made no difference.
**4-** I tried this code on another ESP32 module, it also showed a huge difference in adc1 readings before and after uncommenting `WiFi.mode(WIFI_AP_STA)`.
**5-** Using root APIs such as `esp_wifi_init` & `esp_wifi_set_mode` & `esp_wifi_start` instead of Arduino wrappers like `WiFi.mode` didn't help.

****NEW CLUE:*** Apparently the issue is with the **Wi-Fi ACCESSPOINT** mode (i.e. WIFI_AP), because setting **Wi-Fi to STATION** mode (i.e. WIFI_STA) doesn't cause this issue.*

In general anything related to WIFI function causes ADC to get unstable. No matter which ESP32 board you use, you could simply serial plot any ADC1 channel before and after the WIFI initialization command, even with floating ADC1 pins you can see the difference.

[![Signal goes crazy even though there is a 100uF cap at ESP32 Power entrance][2]][2]
[![enter image description here][4]][4]

```c++
    #include <WiFi.h>
    float R = 0;

    void setup() {
        Serial.begin(500000);
    //    WiFi.mode(WIFI_AP_STA);  // uncommenting this line analogread goes crazy! even while following line is still commented...
    //    WiFi.begin();
        analogSetAttenuation(ADC_0db);
    }

    void loop() {
        R = analogRead(36);
        Serial.println(R/12.21);
    }
```

  [2]: https://i.stack.imgur.com/vrENf.jpg
  [4]: https://i.stack.imgur.com/GocXu.jpg

body: I've just had the same problem. I just put all of the WIFI connecting code into a function, read the ADC2 data then called the function to send, ending with WIFI.mode(WIFI_OFF) to shut down the WIFI, read the data then started it all over again. I'm using ESPNOW so don't have to panic about hooking up to my network which would obviously take longer. With ESPNOW, the data is sent regardless and I have it sending every few seconds which is fine for me. I did try putting the connection code into loop, but it kept restarting the board. I've seen plenty of other stuff online about that. Putting it into a function seems to get around that.


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

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

     int pin = 13;
        bool button = false;

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

        void loop()
        {

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

        }
      }
    }

body:
> What's bad about this?

It looks a bit clunky but I suppose there is nothing particularly bad about it (apart from your typo of digitalWrite rather than digitalRead).

I would do it more like:

    unsigned long now = millis ();
    button = LOW;

    while ((millis () - now < 10000) && (button == LOW))
      button = digitalRead (pin);