body:
Just adding a little flesh to @chrisl's excellent answer with some added technical detail:

>B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

The problem here is that the resistors and the input pin's capacitance form a low-pass filter. Too high a resistance and you deform the nice clean square wave of the serial data. This limits the baud rate you can reliably use. Reduce the resistor values and you increase the frequency of the filtering, thus allowing higher baud rates, but at the cost of increased current draw from the TX pin.

> Does SofwareSerial library is recommended (again - reliability ).

The problem of SoftwareSerial is twofold: it's very much a "blocking" system, whereby the MCU can't be doing anything else when a byte is being either received or transmitted, and it's very picky about timing, partly because of that blocking.  There are two factors that affect the maximum speed you can use: how fast the MCU can process the incoming signal to work out what it is, and how fast the MCU can process that decoded signal to get it stored in the buffer.

While it's possible to receive reliably a byte at 115200 baud the problem comes when receiving multiple bytes rapidly. The Arduino is not always able to take that received byte and store it in the RX ringbuffer fast enough before the start bit of the next byte arrives, so it misses it. This causes corruption in the data stream.

For this reason I never recommend more than 9600 baud (or maybe 38400 at a pinch) to give the Arduino more time to process the bytes as they arrive. However that then means that more time is spent doing the sending or receiving, which blocks the rest of your program during that time for longer.

Also SoftwareSerial is strictly half duplex: when you're receiving you can't send, and when you're sending you can't receive. It's only really of any use in a "call-response" style protocol where switching between sending and receiving is predictable.


sender: user

message:
Is it possible to compile and upload code witout the IDE?

I just got started with Arduino, and found out that I need the IDE to compile and upload codes, which works perfectly fine. This is my code:

```
# pragma GCC optimize ("Ofast")

char i = 0 ;
unsigned long time, lastTime ;

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

void loop() {
 time = millis() ;

 if (time > lastTime) {
  lastTime = time + 100 ;
  i = ~i ;
  digitalWrite(LED_BUILTIN, i  ? HIGH : LOW) ;
 }
}
```

But the biggest problem is that the IDE is written in Java and it uses 1 GB of system's memory, and it's very heavy.

So is there a way I can use the Linux command line to compile and upload the code to the Arduino UNO?

sender: assistant

body:
Yes, I haven't used it but on the official page it is mentioned, called Arduino CLI (command line interface), available for Mac and Linux.

https://www.arduino.cc/pro/cli

Excerpt:

> Arduino CLI is a command line tool that contains all you need to
> easily build applications around the Arduino ecosystem. Parse the JSON
> output of the CLI or implement it as an always-on service that accepts
> commands via a gRPC interface using your language of choice.
>
> Arduino CLI is the backbone of the Arduino Create Web Editor serving
> over a million users.

Also, it's open source and can be found on GitHub at https://github.com/arduino/arduino-cli/releases


message:
Setting float to two decimal places

I'm trying to set my temperature measurements to two decimal places. Currently what I get are six decimal places.
Here is my code:
```
#include "math.h"

...

(in loop)
temp1 = sensors.getTempCByIndex(0);
     temp1 = roundf(temp1*100)/100;
```
Once I push temp1 to Firebase realtime database there are sic decimals, such as 26.059999. I'm using dsb20 sensor for temperature measurements.
What could be wrong?

Thanks for your help in advance!

body:
`float` variables don't have a number of decimal places: that's how they get their name: "floating point" - the decimal point floats around as needed.

It's only when you *output* the value that it's rendered with a fixed (or limited) number of decimal places.  Using `Serial.print()` the second digit is the number of decimal points:

```c++
Serial.println(temp1, 6); // 26.059999
Serial.println(temp1, 2); // 26.06
```


body:
In addition to Majenkos answer:

A `float` cannot take any decimal number. It has a limited change and a limited resolution in that range you could say. So if often happens, that the flat (rounded) value is not a valid `float`. This is the case for `26.05`. There is no valid `float` value, that is exactly `26.05`. So the nearest valid `float` value is chosen. The following code would always print `26.059999`:

    float i = 26.05;
    Serial.println(i);

since the variable `i` contains the `float` number `26.059999` (nearest valid `float` value to `26.06`). That is the reason, why mostly the rounding of `float`s is only done directly with the outputting/printing. In that stage the number is not longer bound to the limitations of the `float` type (since it is internally not again saved in that type).


body:
one can convert to n decimals with the String Class

    float num = 3.14159
    String str1 = String(num, 1) // 3.1
    String str2 = String(num, 2) // 3.14
    String str3 = String(num, 3) // 3.141


message:
Error Outputting Values Arduino Serial.print

I am experimenting with the following program I found online (with slight modifications):

```
int x;
void setup() {
 Serial.begin(9600);
 Serial.setTimeout(1);
}
void loop() {
 while (!Serial.available());
 x = Serial.readString().toInt();
 int y = x + 1;
 Serial.print(y);
}
```

I am encountering an error in Serial monitor output; if I input `1`, I get `21` printed. I think what's happening is that every digit in a number gets incremented by 1, and then `1` is put at the end for some reason. For example, if I input `234`, my output is `3451`. I think the error lies with the line ` x = Serial.readString().toInt();`, but am unsure how to fix this. Thank you!

body:
There's two problems here.

First, you don't enter "234", you enter "2" followed by "3" and finally "4". Your really small timeout doesn't give the digits enough time to arrive.

Second, your line ending is being received and interpreted as "not a number" which is returned as 0 by `.toInt()`.

What you need to do is:

1. Don't set a short timeout - you can remove that line entirely.
2. Use `.readStringUntil('\n')` to read up until your line ending in one go.


message:
Slow USB reading operation

I got an Arduino UNO today, and I am just writing a basic blink program. I have 3 LEDS on the arduino. Those LEDS are connected to Pin 1, 2, and 3.

Now I can control those LED by writing octal values 0 to 7 to the `/dev/ttyUSB0`.

The code I have written so far is:
```
# pragma GCC optimize ("Ofast")

# define LED1 1
# define LED2 2
# define LED3 3

char buf[4] ;
unsigned char inp, len ;

void setup() {
 pinMode(LED1, OUTPUT) ;
 pinMode(LED2, OUTPUT) ;
 pinMode(LED3, OUTPUT) ;

 Serial.begin(9600) ;
}

void loop() {
 len = Serial.readBytes(buf, 3) ;

 if (len) {
  buf[3] = '\0' ;
  inp = atoi(buf) ;

  // Illuminate LEDs
  digitalWrite(LED1, 1 & inp ? HIGH : LOW) ;
  digitalWrite(LED2, 2 & inp ? HIGH : LOW) ;
  digitalWrite(LED3, 4 & inp ? HIGH : LOW) ;
 }
}
```

So when I write:
 + 0 turns off all the LEDS
 + 1 turns on LED on pin 1
 + 2 turns on LED on pin 2
 + 3 turns on LED on pin 1 and 2
 + 4 turns on LED on pin 3
 + 5 turns on LED on pin 1 and 3
 + 6 turns on LED on pin 2 and 3
 + 7 turns on all the LEDS.

The problem is that, when I write 7 for example, it takes up to 1 second to turn on the LEDS. If I write 0, it takes another second to turn off the LEDS.

Is there way to control the LEDS in close to real-time?

body:
When sending multiple bytes which together form a single message it is best to use a delimiter character and read the data until there. That way you don't run into timeouts and you can be sure, that the received data represents a full message.

In the cases where the LEDs need 1s to react you are most likely sending less than 3 bytes, which causes the `Serial.readBytes()` function to time out after the default 1s. I guess you are currently always sending only 1 byte (though you are trying to read 3 byte in your code).

To use a delimiter character there are multiple ways. The easiest fix would be using `Serial.readStringUntil('\n')`. The newline character (which I used as a parameter here) is a common delimiter character. You would then need to aways send the newline character at the end of a full message.

Just setting the timeout very low is not a very good solution. With a low baudrate as 9600 that can easily mean, that the message is chopped up into multiple parts, because the transmission takes longer than the timeout.

---

Besides that: I don't really understand, why you need to receive 3 bytes for turning on or off 3 LEDs. One byte (even, when you are just using single digits) has a big enough data space for more than these 3 LEDs. Also you are not really using octal numbers. `atoi()` is expecting a string representation of a decimal number. There is nothing octal in your code. And then you are using the first 3 bits of the resulting number for controlling the LEDs.

All in all this seems quite complicated for a very basic task. Maybe there is some reason for that, which you didn't write about.


body:
You're calling `Serial.readBytes()` when there may or may not be 3 bytes available. If there aren't 3, the call waits for them to arrive or for a timeout. That's the delay you are seeing.

If you really want 3 bytes at a time, check whether there are 3 before you try to read them:

    if( Serial.available >= 3 )
       len = Serial.readBytes(buf, 3);

When the `if` fails - because there aren't three bytes available - you won't waste any time waiting for them.


body: On the Arduino UNO pins 0 and 1 are used for serial communications.  That might not make a difference here, but it's probably a good idea to avoid them unless really needed.


message:
TTGO TS I²C adress

I'm working on a project using TTGO TS wich communicate wih arduino via I²C protocole
How can I find the adress of TTGO TS board used in I²C communication ?

body:
Like @romkey said, use a I²C scanner to find the address of the device, for example [this][1] one from the Arduino website. Connect the device to the Arduino board, upload the code and look up the I²C address of your device.

  [1]: https://playground.arduino.cc/Main/I2cScanner/


body:
The TTGO TS uses an ST7735 display. This is *not* an I2C device. Instead it uses its own custom serial protocol. Since the DC pin is broken out for you it uses the 4-wire serial interface which is simplest to use with SPI.

It's confusing that they use the terms SCL and SDA, which makes you think it's I2C, but it's not.


message:
Turn off Timer1 / Timer1 One-shot

A zero detector crossover sends a pulse to the Arduino, it must start counting x time and then a pulse is sent from the Arduino, once the timer reaches time x, it must stop counting and only start counting again when it receives the new pulse of the zero crossing detector, the idea is to do something like this:
[![enter image description here][1]][1]
What I don't know is how to keep the timer off all the time toff that appears in the image.

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

body:
the way to turn off the Timer is to set the CS12, CS11 and CS10 prescale bits to 0, in this way the CLK signal is disconnected and the timer stops counting, when you want the timer to continue counting, they are set back to 1 the CS12, CS11 and CS10 bits according to the selected prescale.

    byte savePrescale

    savePrescale = TCCR1B & (0b111<<CS10);
    ...
    TCCR1B &= ~(0b111<<CS10); // Stop Timer1 Clock
    ...
    TCCR1B |= savePrescale;  // Restart Timer1 clock.
    ...


body:
You can initiate a "One shot" timer at each zero-crossing.

The trick @Gerben mentioned in https://arduino.stackexchange.com/questions/83616/turn-off-timer1#comment187112_83616 eventually links to code at https://github.com/bigjosh/TimerShot which does the one-shot functionality on Timer2 by idling the timer at TCNT2=0 with OCR2A=0, and using the TCNT2 space above 0 to operate an adjustable oneshot on OC2B.

This trick can be adapted to Timer1:

    // The one shot pulses are output on Digital pin OC1B (Arduino Uno D10, Mega D12, Nano D3)
    // Modified by Dave Forrest 2020-01-11 for Timer 1
    // Based on Josh Levine's Nov 23, 2015 work at https://github.com/bigjosh/TimerShot/blob/master/TimerShot.ino

    #define OSP_SET_WIDTH(cycles) (OCR1B = 0xffff-(cycles-1))

    // Setup the one-shot pulse generator and initialize with a pulse width that is (cycles) clock counts long

    void osp_setup(uint16_t cycles) {

      TCCR1B =  0;      // Halt counter by setting clock select bits to 0 (No clock source).
                  // This keeps anything from happeneing while we get set up

      TCNT1 = 0x00;     // Start counting at bottom.
      OCR1A = 0;      // Set TOP to 0. This effectively keeps us from counting because the counter just keeps reseting back to 0.
              // We break out of this by manually setting the TCNT higher than 0, in which case it will count all the way up to MAX and then overflow back to 0 and get locked up again.
      OSP_SET_WIDTH(cycles);    // This also makes new OCR values get loaded from the buffer on every clock cycle.

      TCCR1A = 0b11<<COM1B0  | 0b11<<WGM10;  // OC1B=Set on Match, clear on BOTTOM. Mode 15 Fast PWM.
      TCCR1B = (0b11<<WGM12)| (0b001<<CS10); // Start counting now. WGM 15=0b1111  to select Fast PWM mode

      //DDRB |= _BV(2);     // Set pin to output (Note that OC1B = GPIO port PB2 = Arduino Uno Digital Pin 10)
      DDRB |= _BV(6);     // Set pin to output (Note that OC1B = GPIO port PB6 = Arduino Mega Digital Pin 12)
      //DDRD |= _BV(3);     // Set pin to output (Note that OC1B = GPIO port PD3 = Arduino Nano Digital Pin 3)
    }

    // Setup the one-shot pulse generator

    void osp_setup() {
      osp_setup(1);
    }

    // Fire a one-shot pulse. Use the most recently set width.

    #define OSP_FIRE() (TCNT1 = OCR1B - 1)

    // Test there is currently a pulse still in progress

    #define OSP_INPROGRESS() (TCNT1>0)

    // Fire a one-shot pulse with the specified width.
    // Order of operations in calculating m must avoid overflow of the uint16_t.
    // TCNT2 starts one count lower than the match value becuase the chip will block any compare on the cycle after setting a TCNT.

    #define OSP_SET_AND_FIRE(cycles) {uint16_t m=0xffff-(cycles-1); OCR1B=m;TCNT1 =m-1;}

    void setup()
    {
      osp_setup();

    }

    void loop()
    {
      // Step though 0-11 cycle long pulses for demo purposes
      for (uint8_t o = 0; o < 101; o++) {
        OSP_SET_AND_FIRE(o);
        while (OSP_INPROGRESS());         // This just shows how you would wait if necessary - not necessary in this application.
        //_delay_us(1);      // Wait to let the audience clap
      }
    }

This code produced pulses with a resolution of 62.5ns, which is on the edge of what my test equipment can measure.  Here's a 6.25us, 100 cycle pulse next to a 1 cycle pulse:

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

With Timer1's 16 bit range and the /1 prescaler you can do pulses from 62.5ns to 4us.  With the /1024 prescaler, (`TCCR1B|=(0b101 <<CS10);`) it can do 64us up to 4.194sec.  With /256 prescaler, (`TCCR1B|=(0b100 <<CS10);`) it can do 16us up to 1.05sec.

For a one shot triggered on a zero-crossing, you might try something like this with the above

    void loop()
    {
      ...
      int t1_us = 1000000UL/60 /8 ; // 1/8th of a 60Hz cycle

      if(needOneShot){  // Set needOneShot with an interrupt or sensor or something
        OSP_SET_AND_FIRE(t1_us/16);  // 16us ticks with the /256 prescaler
         needOneShot = false;
      }
      ...
    }

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


message:
Arduino simulator - generating sine wave from PWD (Oscilloscope read is rectangular)

trying to create this simple circuit where a rectangular voltage input is transferred to a sine wave output.

the process is quite simple, but I couldn't see the actual sine wave when connecting an oscilloscope.

I'm currently working on a simulator online, so I thought it would be best to share the circuit with the c++ code, and perhaps you would have any insights on why I keep seeing rectangular output voltage rather than sine when the data is indeed a sine wave:

here's an image of the circuit for some specific time:

[![circuit simulator][1]][1]

and the code that generates the sine wave is

    #include <math.h>

    const int numSamples = 500;
    const float pi = 3.1415;
    int f = 2; // signal frequency
    float sf = 500.0; // sample frequency > 2*f (Nyquist)
    int sineSignal[numSamples];

    void setup(){
     pinMode(13, OUTPUT);
     // creating sine signal:
     for (int i = 0; i < numSamples; i++){
      float t = i / sf;
      // +1 shift to get values from 0 to 2
      sineSignal[i] = (int) (127 * (sin(2 * pi * f * t) + 1.0));
     }
    }

    void loop(){
     int pinToConnect = 9;
     for (int i = 0; i < numSamples; i++){
      analogWrite(pinToConnect, sineSignal[i]);
      delay(2);
     }
    }
ps. this is all based on this video: [How to Generate Sine Wave using Arduino?][2]

  [1]: https://i.stack.imgur.com/DfxFK.png
  [2]: https://www.youtube.com/watch?v=ojkUaCSFM30

body:
It's working as intened.

The arduino UNO has no DAC (digital to analog converter) onboard, so all it can produce are digital signals, either 0 or 5v. The analogWrite function uses [Pulse Width Modulation](https://www.arduino.cc/en/Tutorial/Foundations/PWM) to produce an output that, *on average*, has the requested voltage, by quickly alternating between logic low and high with different durations.

This is done at the hardware level using the Atmega's timers, and it's very useful in driving LEDs, servos, steppers and more, but it doesn't produce a steady analog output.

I would suggest either moving to a chip that has an onboard DAC, using an external DAC chip [such as this one](https://www.adafruit.com/product/935), or [building a simple DAC yourself](https://create.arduino.cc/projecthub/Arduino_Scuola/build-a-simple-dac-for-your-arduino-4c00bd).

An even simpler solution would be building a RC lowpass filter on the output pin, which would provide a simple, but probably imprecise, way to smooth out the signal and make it look like an analog one


message:
Making pushbutton behave as a toggle switch with ezButton - do I have to use ledstate with =! operator

I'm using ezbutton to make a pushbutton act like a toggle switch, first press doing permanent on, second press doing permanent off. I'm just trying to understand the basic coding. This project is just a testbed for what I'm planning to do later - wiring vehicle toggle switches to Arduino and feeding the output signal to mosfet that will control the load state. So I'm trying to get the code as nice and tidy as I possible can. In the code below, I would like to know if ledState will be applicable when this sketch will control a mosfet instead of a test led, and I've seen comments saying "ledState = !ledState;" is not optimal - but being a beginner I'm not sure what this means, and is there a better more sound way to address it. Thanks!

    #include <ezButton.h>

    // ---
    // Declaration
    // ---

    const int button1  = 9;
    const int led1     = 4;
    int ledState = LOW;

    ezButton button(button1);

    // ---
    // Setup
    // ---

    void setup()
    {

      pinMode(led1, OUTPUT);
      pinMode(button1, INPUT_PULLUP);
      button.setDebounceTime(50);

    }

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

      button.loop();

      if (button.isPressed()) {
        ledState = !ledState;
        digitalWrite(led1, ledState);
      }

    }

body:
I've been looking through the [source code for ezButton.c][1]

The function `isPressed()` is something of a misnomer and is only meaningful for a push-to-make button on the low side of a pull-up resistor. It actually detects falling edges of the signal, so it should be called `isFallingEdge()`, but the code itself is good.

Similarly for `isReleased()` which detects rising edges of the signal, so should be called `isRisingEdge()`.

The constructor defaults to `INPUT_PULLUP` which may (or may not) be what you want for your buttons and toggle switches, so it's something to bear in mind especially for low-side push-to-break buttons or high-side push-to-make buttons which will generate rising edges when pressed and falling edges when released thus reversing the meanings of `isPressed()` and `isReleased()`, hence why they really should be called `isFallingEdge()` and `isRisingEdge()`.

The algorithm in `ezButton::loop()` could be optimised a bit by getting rid of `previousSteadyState` and nesting the final `if` statement within the second `if` statement.

Other than that, it's quite a good algorithm that makes use of hysteresis to reset the debounce timer.

For comparison you could take a look at my algorithm in this [simple debouncer for Arduino][2] that simply detects rising edges, falling edges or both edges without regard to whether a button was pressed or released, and can be used in a polling loop or with interrupts. Here's the essence of the algorithm:

```c++
    bool input_state = digitalRead(INPUT_PIN);
    unsigned long current_ms = millis();

    edge = rise = fall = false;

    // Hysteresis:
    //   If there is no change, reset the debounce timer.
    //   Else, compare the time difference with the debounce delay.
    if (input_state == output_state)
    {
      last_ms = current_ms;
    }
    else if ((current_ms - last_ms) >= DEBOUNCE_DELAY_ms)
    {
      // Successfully debounced, so update the outputs.
      rise = input_state && !output_state;
      fall = !input_state && output_state;
      edge = rise || fall;
      output_state = input_state;
    }
```

And `ledState = !ledState;` simple toggles the value of `ledState` which is what you write to your LED with `digitalWrite(led1, ledState);` each time a falling edge is detected in the input signal.

  [1]: https://github.com/ArduinoGetStarted/button/blob/master/src/ezButton.cpp
  [2]: https://github.com/TimMathias/Arduino-Debouncer


message:
non asssign variable using by for in loop() can remeber last value. what happen here?

I modify this code from my friend and it look strange.

    void setup() {
        Serial.begin(115200);
        Serial.println("reset");
    }
    void loop() {
        for (int d; d <= 32767; d++) {
          Serial.println(d);
          delay (1000);
        }
    }

for some reason when you press reset, the variable will keep counting from last value as shown.

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

this not gonna happen when you put these block in setup()

I know that not good idea to use varible in for loop without assigned the value, but I belived it must have a interesting reason for this.
For my hypothesis, the variable value just allocate with same address in memory. when this code run in setup() some how the complier detect this situation and assign 0 as initial value. but when in the loop() some how the compiler don't assign new value to the memory address and it get old value from last time the program was run before resetted. I still need further explanation.

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

body:
I think you missed a compiler warning (I did, too!) - notice that you are using 'd' uninitialized. On each re-entry to the loop() function, loop()'s stack will be in the same place in memory. The for-loop doesn't initialize 'd', but the boot loader did zero RAM for your first run. 'd' happens to occupy the same memory location on each entry to loop(), so the old value (just before reset) is still in place. Since the for-loop didn't re-initialize it... :)

The fix is:

    for (int d=0; d <= 32767; d++) {

Update:

That begs the question: Why did your run fail as expected, while my run appeared to execute normally? My guess is different bootloaders, one that does, and one that doesn't, initialize SRAM on a reset that doesn't result in an upload.


message:
Arduino ESP8266 HTTPS Request returning empty response

I want to get some JSON data from a HTTPS secured Webserver using a ESP8266.
For some reason I'm getting an empty response, I believe there's an error parsing the GET request.
In Chrome I get the JSON response without problems.

GET Request:

    httpsClient.print(String("GET ") + path + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n\r\n");
Host and Path:

    const char *host = "www.adler-mannheim.de";
    const char *path = "/jsonapi/game/current";

**UPDATE:**

I tried fetching some JSON from another Server and it worked finde, so i can rule out my code.
Fiddling around with the host and path I observe this:

 - Hostname without "www" results in a 301

 - Hostname with "https://www" results in no HTTPS connection at all

So it seems that a "www" is required although it unfortunately leads into a empty response.

The output is as follows:

    headers received
    reply was:
    ==========
    ==========
    closing connection

In the first case, without using "www" in ahead of host there's some 301 HTML in between the two lines of "=".

Whole function:

    void connect() {
      WiFiClientSecure httpsClient;    //Declare object of class WiFiClient

      Serial.println(host);
      httpsClient.setInsecure();

      Serial.print("HTTPS Connecting");
      int r=0; //retry counter
      while((!httpsClient.connect(host, httpsPort)) && (r < 30)){
          delay(100);
          Serial.print(".");
          r++;
      }
      if(r==30) {
        Serial.println("Connection failed");
      }
      else {
        Serial.println("Connected to web");
      }

      String getData, Link;

      //GET Data

      Serial.print("requesting URL: ");
      Serial.println(host+Link);

      httpsClient.print(String("GET ") + path + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n\r\n");

      Serial.println("request sent: ");
      Serial.println(String("GET ") + path + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n\r\n");
      while (httpsClient.connected()) {
        String line = httpsClient.readStringUntil('\n');
        if (line == "\r") {
          Serial.println("headers received");
          break;
        }
      }

      Serial.println("reply was:");
      Serial.println("==========");
      String line;
      while(httpsClient.available()){
        line = httpsClient.readStringUntil('\n');  //Read Line by Line
        Serial.println(line); //Print response
      }
      Serial.println("==========");
      Serial.println("closing connection");

      delay(2000);  //GET Data at every 2 seconds
    }

**UPDATE 2:**

I tried the following code from the ESP8266HTTPClient Library examples:

    void connect2() {

      WiFiClientSecure client;

      //client.setFingerprint(fingerprint);
      client.setInsecure();

      HTTPClient https;

      Serial.print("[HTTPS] begin...\n");
      if (https.begin(client, "https://github.com/esp8266/Arduino/issues/3417")) {  // HTTPS

        Serial.print("[HTTPS] GET...\n");
        // start connection and send HTTP header
        int httpCode = https.GET();

        // httpCode will be negative on error
        if (httpCode > 0) {
          // HTTP header has been send and Server response header has been handled
          Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
            String payload = https.getString();
            Serial.println(payload);
          }
        } else {
          Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        }

        https.end();
      } else {
        Serial.printf("[HTTPS] Unable to connect\n");
      }

      Serial.println("Wait 10s before next round...");
      delay(10000);
    }

This one gives me a 200 but no payload. Other sites work

**UPDATE 3:**

I had a look on the headers.

    https.headers()
This gives me 0 headers on every page, even when there's a payload.

I also had a closer look at the payload that returns from my desired api and its filled with NULL.
In a weird way this is only the case with my desired page and only my desired subpages.
Requesting something more at top level e.g "https://www.adler-mannheim.de/jsonapi" which is basically a SilverStripe Welcome page, I get a fully fetched beautiful HTML payload.

I got literally no Idea why. Do I have to set a specific User Agent or something so that the Server responds?

body:
Okay I have no Idea what I changed apart from deleting some imports which might have collided, but now it works. Regular call with "https://www" does the thing.

Thanks anyways


body: I had this same problem and I realized it was because I was using an `WiFiClientSecure` to try to an endpoint over HTTP instead of HTTPS. If anyone else is having this same problem, I would check that.


message:
Purpose of LED indicator

I am using an arduino mega clone called the Funduino.

I am developing a python based, tkinter application that will receive the serial data that arduino sends.

However, i am witnessing some behavior that i cannot explain and i am trying to debug. I won't say anything more, because this is an arduino forum, not a python forum.

But, in the arduino, there are some leds. One of them is power, which is constantly ON, when the arduino is powered.

There is another led that is named 'L'. When i open a serial connection this is lighted up and it stays ON.

However sometimes, when i send a string to the arduino, in order to trigger some data exchange, this button is switched off.

So what does this 'L' led is, and what it means when it is turned off?

body:
This buildin LED is connected to an IO pin of the microcontroller on the Mega (most commonly pin 13, but might be different depending on the board). So the meaning depends on what the code on the Mega does with it.

When the board is reset (which happens on opening of serial connection), first the bootloader will run. It gives you a short blink on the buildin LED. After the bootloader finishes, your own code is in charge. Whatever you do in your code with pin 13 will be reflected on the LED. Here the meaning depends on you.


body:
If you do not configure the pins, they are initialized as `pinMode(xx,INPUT)` which is a floating high impedance state.  Per the Arduino Uno R3 schematic, that pin is on PB5/SCK/13 which is run through the op-amp (top center in the schematic) to drive the LED. Per the Arduino Mega schematic, that pin is on PB7/OC0A/OC1C/13 which isn't run through the op amp.  I left mine unconfigured on a Mega clone and measured a 1.5V on 13 and had the LED on.  On an Uno clone, the light was on while unconfigured, and I measured 0.9v (but my DMM seemed to draw down the voltage).

If the pin is left floating in an unknown state, it could drive the LED into an unknown state.

[![Arduino Uno Schematic][1]][1] [![Arduino Mega2560 R3 Schematic detail][2]][2]

You can control it's state with:

    pinMode(LED_BUILTIN,OUTPUT);  // LED is forced off (0.01V)
    digitalWrite(LED_BUILTIN,1);  // force LED on (4.97)

or

    pinMode(LED_BUILTIN,INPUT_PULLUP); // On, but with the internal pullup resistor, not logic gates.  Pin 13 can be shorted to ground.

or set it back to the default tri-state:

    pinMode(LED_BUILTIN,INPUT); // Tri-state, undefined.
    // You could control the LED from an external signal on the pin.

Measure the voltage at pin 13 and see what you get.

Personally, I purpose it as a status indicator light.  E.g.  https://github.com/drf5n/foxyPulseInduction_Discrimination/blob/discrimination/StatusCodeLED/StatusCodeLED.ino

Because of the tri-state/op-amp LED driver on "L", you can use the light as as a logic probe--you could leave it unconfigured and jumper it to other inputs or outputs for troubleshooting and diagnostics.  If you have a project monitoring one important input, rather than putting it on a different input pin and explicitly echoing it to the LED like `digitalWrite(LED_BUILTIN,digitalRead(sensorPin));` you could hook it to pin 13 to visually see the input status and just `digitalRead(sensorPin)`.

====

Note that there are two revisions of the Arduino Mega schematic.

* https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf -- A top search hit
* https://content.arduino.cc/assets/MEGA2560_Rev3e_sch.pdf from https://store-usa.arduino.cc/products/arduino-mega-2560-rev3

After testing this behavior, I noticed that the my Mega clone did not match the Arduino Mega schematic at https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf . Tracing it out, it does use the op-amp like the Uno. (Pin 1&2 of the opamp attach to the "L" LED through the third resistor in the resistor array next to the LED.)

  [1]: https://i.stack.imgur.com/ugHED.png
  [2]: https://i.stack.imgur.com/I5SJJ.png
  [3]: https://i.stack.imgur.com/BEd6S.png


message:
Load cell weight distribution on rectangular shape instead of square

I have built a simple scale using 4 so called 50kg load cells.

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

They are connected in a bridge and mounted on wooden feet of a square shaped box. All as a proof of concept which worked quite ok. The readings are all OK and deviation of +/- 2kg is totally acceptable for my project. I followed this discussion which also explains how the connection should be made properly using 4 cells.

https://arduino.stackexchange.com/questions/11946/how-to-get-weight-data-from-glass-electronic-bathroom-scale-sensors/18698?newreg=dfc67e294d934ae28fd067724558f894

Now I want to keep the load cells on the feet but change the shape of the scale and instead of a square use a rectangle with the following sides.

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

In such a form a weight distribution will not be centered all the time. The object to be weighed can shift to the right or to the left.

 - Will this affect the measurements in a negative way or will the HX711 controller still take care of it and show the correct results?
 - Will the measurements still be correct using 4 cells? If not what would be the proper way of weighing a rectangular shaped load?
 - Would it more appropriate to measure the load with 2 cells on the right and two cells on the left and then sum it up?

  [1]: https://i.stack.imgur.com/LfGgC.jpg
  [2]: https://i.stack.imgur.com/qhQXO.png

body:
Newton's second law says that if a force acts on a mass, that mass will accelerate at a rate proportional to the force and inversely proportional to the mass.

All that means for your scale is that if you are not being accelerated up or down, the net vertical force on your body must be 0. Since your body has weight, and the net vertical force on your body is 0 (you aren't accelerating, are you? :) then the downward force must be balanced by an exactly equal upward force. That upward force is the sum of the upward forces exerted by each load cell. Their contributions may individually change depending on where you stand, but *their sum must exactly equal your weight*.

Note that we have said nothing about the placement of the cells! If your platform allows it, you could move one of the cells 6 (or 60 or 600) feet away from the the others, for instance. The total upward force must still be the same.

So the bottom line is:

   `F_lc1 + F_lc2 + F_lc3 + F_lc4 == your weight`

no matter where you place the cells.


message:
Is defining a function improves speed rather computing average for each analog input separately

My Arduino controller reads data coming from four different sensors. After the data is read, I individually compute four input average values. I understood that I am having the same lines of code repeated four times. Instead, I want to define a function with an analog pin as input and compute the average. My code is working fine. The question I have is, will this function improve the speed, reduce memory?

My code:

    // Samples average
    sample_cnt = 1000;

    //// Input the pin number and compute average value
    float Average_input_value(int analog_pin){
      float avg_val = 0;
      for(int i=0;i<sample_cnt;i++){
        avg_val += analogRead(analog_pin);
      }
      // Divide by Sample count to get the average value
      avg_val = avg_val/sample_cnt;
      return avg_val;
      }

body:
Writing the code out four times, in line, is a little bit faster than calling a function because the function call and return take some time, and the loop instructions take some time, and neither of those contribute to the average calculation.

Writing a function that you use four times, however, is much more readable, is much easier to fix if you've made a mistake because you can fix it once instead of four times, and is much easier to change or replace for the same reason, if that ever becomes necessary. Besides, a good optimizing compiler can often decide when to rewrite your loop as inline several repetitions of the loop contents (called "unrolling the loop"), so hand optimizing is probably not worthwhile.

Where your function will win over 4 repetitions of the calculation code is in the code-space needed. The function is more compact, but slightly slower.


body:
Just adding some numbers to complement JRobert's answer.

On the Uno, the cost of calling a function and returning from it is
about 0.5 µs. In contrast, calling `analogRead()` within a loop
costs _at least_ 112 µs per iteration. Given that you are computing
the sum as a `float` (where a suitably sized integer would suffice), it
may well be more that 112 µs in your case.

I do not know how many readings you want to average, but even if it is
only a handful, the calls to `analogRead()` will completely dwarf the
cost of using a function.


message:
Random Servo Movement with Arduino Uno

Recently, I have been working on a project involving 8 Tower Pro sg90 servos and an Arduino Uno. The issue I am running into is that the servos will randomly move when connected, without even receiving a signal from the Arduino.

Specifically, sometimes the servos will work perfectly and the input moves the servos fine, but then all of a sudden the servos will start twitching and moving erratically back and forth. Then I disconnect the power and plug it back in and I will sometimes work again or sometimes not.

I don't think power is the problem because I am powering the servos externally with a 5.5v power supply which can provide 2.5 amps. I also made sure to have a common ground between the Arduino and the power supply. Additionally, I don't think this is an issue of a broken servo because I have this problem with all eight. In my code, I have input pins to control the servos which are just buttons. These buttons also have pull-down resistors, so I don't think the input is the problem either. I am using the Arduino servo library.

The only other thing I can think of is external frequency interference because some of the circuitry and wiring are close together, but none of the wires are very long and I even tried putting a ferrite bead on the servo cables but to no avail.

If anyone has any ideas about a solution to my problem which I have not tried yet that would be amazing!

~~~c++
#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;
Servo servo8;

void setup(){
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(3, INPUT);
  pinMode(2, INPUT);
  pinMode(1, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  servo1.attach(13);
  servo2.attach(12);
  servo3.attach(11);
  servo4.attach(10);
  servo5.attach(9);
  servo6.attach(8);
  servo7.attach(7);
  servo8.attach(6);
}

void loop(){
  if(digitalRead(5)==LOW){
    servo1.write(120);
    delay(20);
  }
  else{
    servo1.write(50);
    delay(20);
  }
  if(digitalRead(4)==LOW){
    servo2.write(110);
    delay(20);
  }
  else{
    servo2.write(200);
    delay(20);
  }
  if(digitalRead(3)==LOW){
    servo3.write(120);
    delay(20);
  }
  else{
    servo3.write(50);
    delay(20);
  }
  if(digitalRead(2)==LOW){
    servo4.write(110);
    delay(20);
  }
  else{
    servo4.write(200);
    delay(20);
  }
  if(digitalRead(1)==LOW){
    servo5.write(120);
    delay(20);
  }
  else{
    servo5.write(50);
    delay(20);
  }
  if(digitalRead(A3)==LOW){
    servo6.write(110);
    delay(20);
  }
  else{
    servo6.write(200);
    delay(20);
  }
  if(digitalRead(A2)==LOW){
    servo7.write(120);
    delay(20);
  }
  else{
    servo7.write(50);
    delay(20);
  }
  if(digitalRead(A1)==LOW){
    servo8.write(110);
    delay(20);
  }
  else{
    servo8.write(200);
    delay(20);
  }
}
~~~

body:
You call servoX.write() repeatedly, even when no button has changed. Each call turns off interrupts briefly while the servo value is being updated. This happens, maybe 40 times/sec and may be messing up the servo timing in some non-constant way. Try only calling the servoX.write() functions once, only when its button-state has settled into a new state.

Update:

> could you provide an example please

      bool prevButton5 = LOW;            // one of these for each button
        :                                // outside of the loop() func.
        :

      if(digitalRead(5) != prevButton5){  // button changed?
        prevButton5 = !prevButton5;       // save new button state
        if(preButton5 == LOW){            // (your same code from here down)
          servo1.write(120);
          delay(20);
        }
        else{
          servo1.write(50);
          delay(20);
        }
      }

 - Make a boolean for each button.
 - Wrap each of your button segments as I did for button5. Notice that your code is now executed only if the associated button has changed, so you will have many fewer servoX.write() calls.

That isn't the totally best way to do it. I made it as straightforward as I could, even though the additional code gets replicated for every button. I'd probably write a single function that manages one button and one motor, and call that function for each button / motor pair.

I also ignored the concept of switch-bounce to keep the number of changes low, but you should look it up and consider it. Switch-bounce is *apparent* bouncing of the switch contacts for a few milli-seconds during the change from open to closed or vice-versa, which leads to several make-break-make.....-make cycles (or the reverse) when you push or release the button. I'd probably make (or search for) a button debounce function and call it for the particular button I'm testing if I see that button has changed.

First try the "rude and crude" fix I suggested and get that working. Then if you're interested, try making one or more of the refinements.

Update:

    the servos still jitter and twitch esspecailly when
    I move the whole arduino and wires around.

That suggests either or both of
 - cross-talk;
 - the plug wires' connections being less than solid, especially when the wires move.

Try:
 - laying out the servo cables to keep them away from each other as much as possible;
 - wiring only a few of the servos, and in different combinations;
 - also try commenting out the code - or not - for those servos you disconnected in the previous step.

If it turns out to be the plug-in wires and if this project is intended to actually be used for something, I'd suggest using a screw-terminal shield on your Uno to attach the servo wires more securely.


message:
Hexadecimal array does not add up as expected

I have an array of hexadecimal values as given below.

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

I want to increase this array from the end. As in, go from {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} all the way to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, and then increase the value next to it to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, and continue. The increment should go as shown below.

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
    .
    .
    .
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}
    .
    .
    .
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}
    .
    .
    .
    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}

The code I am came up with is

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

    void loop() {

      Hexa_Val[7] = Hexa_Val[7] + 1;

      if(Hexa_Val[7] = 0xFF){
        Hexa_Val[6] = Hexa_Val[6] + 1;
        Hexa_Val[7] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
        Hexa_Val[5] = Hexa_Val[5] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF)){
        Hexa_Val[4] = Hexa_Val[4] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF)){
        Hexa_Val[3] = Hexa_Val[3] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF)){
        Hexa_Val[2] = Hexa_Val[2] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)){
        Hexa_Val[1] = Hexa_Val[1] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)  && (Hexa_Val[1] = 0xFF)){
        Hexa_Val[0] = Hexa_Val[0] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
        Hexa_Val[1] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF) && (Hexa_Val[1] = 0xFF)  && (Hexa_Val[0] = 0xFF)){
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
        Hexa_Val[1] = 0x00;
        Hexa_Val[0] = 0x00;
      }

      //to find out what I am sending
      for( byte a=0; a<8; a++ ) {
        Serial.print(Hexa_Val[a], HEX);
      }
      Serial.println();

      delay(500);

    }

But it just gives me zeros in the serial monitor. If I just leave the first two IF statements

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

    void loop() {

      Hexa_Val[7] = Hexa_Val[7] + 1;

      if(Hexa_Val[7] = 0xFF){
        Hexa_Val[6] = Hexa_Val[6] + 1;
        Hexa_Val[7] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
        Hexa_Val[5] = Hexa_Val[5] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
      }

      //to find out what I am sending
      for( byte a=0; a<8; a++ ) {
        Serial.print(Hexa_Val[a], HEX);
      }
      Serial.println();

      delay(500);

    }

The increment will start from the third value on the right. Something like

    00000200
    00000300
    00000400
    00000500
    00000600
    00000700

How do I get it to increase as I mentioned at the beginning? Why does the code recognize `0xFF` as a zero?

body:
There are multiple problems here:

> `if(Hexa_Val[7] = 0xFF)`

First of all, `=` is the assignment operator. You are setting
`Hexa_Val[7]` to `0xFF`. If you want to compare for equality, you should
use `==`.

Second problem, The value `0xff` will never be displayed, because you
are replacing it by zero. This byte will then count 0xfd, 0xfe, 0x00,
skipping 0xff. If you want to count 0xff, the condition should be
`Hexa_Val[7] == 0`, i.e. increment `Hexa_Val[6]` only after
`Hexa_Val[7]` has overflowed.

Third problem, your second `if` test comes too late. At this point
`Hexa_Val[7]` has already been reset. You should test for `Hexa_Val[6]`
overflowing only _within_ the previous test.

With all that fixed:

```c++
Hexa_Val[7] = Hexa_Val[7] + 1;
if (Hexa_Val[7] == 0) {
  Hexa_Val[6] = Hexa_Val[6] + 1;
  if (Hexa_Val[6] == 0) {
    Hexa_Val[5] = Hexa_Val[5] + 1;
  }
}
```

If you don't want to write 8 nested conditions (which is kind of
cumbersome), you can instead loop over the array backwards, incrementing
each element in turn, and break out of the loop as soon as an increment
does _not_ overflow:

```c++
for (int i = 7; i >= 0; i--) {
    if (++Hexa_Val[i] != 0) break;
}
```

If you don't mind the array being backwards, you can also handle the
whole array as a single 64-bit number, and just increment it like you
would increment any integer. But then you have to print the array
backwards, starting from the mast element:

```c++
union {
    uint64_t number;
    byte bytes[8];
} Hexa_Val = { .number = 0 };

void loop() {
    // Increment the array.
    Hexa_Val.number++;

    // Print out.
    for (int i = 7; i >= 0; i--) {
        if (Hexa_Val.bytes[i] < 0x10) Serial.write('0');
        Serial.print(Hexa_Val.bytes[i], HEX);
        Serial.write(' ');
    }
    Serial.println();

    delay(500);
}
```


message:
Blew my arduino pro mini s4 named component

While working on my project I supplied 12v to my pro mini through raw input and then a s4 named component smoked and my pro mini  stopped working . It didn't turn on either through vcc or raw. The voltage regulator seems completely fine. Can I repair my pro mini. Please help. [![enter image description here][1]][1]

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

body:
Many Arduinos have a Schottky diode between the power connector and the voltage regulator as a protection against accidental reverse polarity connection. The [official Pro Mini](https://www.arduino.cc/en/uploads/Main/Arduino-Pro-Mini-schematic.pdf), or the [Sparkfun variant](https://www.sparkfun.com/datasheets/DevTools/Arduino/Arduino-Pro-Mini.pdf), does not.

So you can either de-solder the diode or break it off the board using diagonal cutters and then replace it with either a similar diode -- or with a solder-bridge if you are confident about never connecting power the wrong way around.

It's possible (likely even) that other components that look OK visually are actually damaged. Especially if you can't power the board by connecting a regulated 5V supply to the VCC pin.


body:
Once you have removed the diode as described in @RedGrittyBrick's answer, you will need to replace it with another. Note you don't have to replace it with a SMD version if you can't get your hands on one. Most electronics shops sell a 1N4004 or 1N4007 diode which would be a suitable replacement.

If worst comes to worst, you could solder a blob of solder across the diode's pads - which would mean you lose the reverse polarit protection - but it would provide a path for your voltage input to go into the regulator.


message:
How detect I2C errors with requestFrom()

I am going to use MCP23017 chips, and some of them will be cabled with a 1 meter max unshielded cable. I am expecting that certain transmissions may toss errors. So I want to tackle this problems by using the built in error detection of I2C, polling the inputs frequently (every 20ms or so) and by debouncing the received data in code by comparing the previous state to the current state of every input pin.

If you write bytes to an I2C slave with the Wire library. You can use the return value of ```Wire.endTransmission();``` to test if the slave has acknowledged the message.

How does this work when you are requesting bytes using ```Wire.requestFrom( address, 3 );``` for example. This function does return the amount of received bytes. Can we check this value with the value of the amount of bytes we requested?

I have read the TI document over how I2C works

> The master will continue sending out the clockpulses, but will release the SDA line, so that the slave can transmit data. At the end of every byte of data, the master will send an ACK to the slave, letting the slave know that it is ready for more data. Once the master has received the number of bytes it is expecting, it will send a NACK, signaling to the slave to halt communications and release the bus. The master will follow this up with a STOP condition

So the master either ACKs or NACKs a read-in byte. Does the Wire library automatically make several attempts with reading? Oris there something in the Wire library which we can use to detect a failed read operation?

Is it perhaps so that the ```requestFrom()``` function may return a different amount of bytes than you requested with which would indicate that atleast 1 read operation failed?

So could I attempt something like
```
doItAllAgain:

for(int i = 0 ; i < 5 ; i ++ )
{
    Wire.beginTransmission( address ) ;
    Wire.write( register ) ;
    if( !Wire.endTransmission() ) break ; // if no error, break out of for loop
    Serial.println(F("write operation failed");
}

Serial.println(F("write operation succes");

byte requestedBytes = 3 ;
byte returnedBytes = Wire.requestFrom( address, requestedBytes ) ;

if( requestedBytes != returnedBytes )
{
    Serial.println(F("read operation failed");
    goto doItAllAgain ;
}
else
{
    Serial.println(F("read operation also succes");
    byte byte1 = Wire.read() ;
    byte byte2 = Wire.read() ;
    byte byte3 = Wire.read() ;
}
```

body:
The `Wire` library does not give you any possibility to get error states, when requesting bytes from a slave. Basically you are stuck with the number of bytes being read.

Though you can read some information from that. If the number of bytes is zero, the slave didn't answer (either because its not there, or because it cannot send any byte currently). This equals a NACK by the slave after the address byte.

Other than that the I2C protocol doesn't give any more information. On requesting the slave is sending data and the master is acknowledging it. That means, that the slave cannot generate a NACK in this process. In fact that also means, that the returned number of bytes can only be zero (on NACK on address) or equal to the number of requested bytes, since after the address ACK from the slave the master will continue to generate clock pulses, until it has read all bytes, that it wanted. If the slave doesn't have any more data to send before that, it cannot stop the transmission. It would just stop driving the data line, resulting in all high data bytes (`0xFF`).

Also I doubt, that it would be really useful in your case. I2C is made for small distances, mostly on the same PCB. It can be used for longer distances, but your mileage may vary. If your setup really can corrupt the communication on the I2C lines, your biggest problem will be a stuck bus. The I2C protocol is generally not prepared for noisy environments and it incorporates states, where the devices on the bus can wait infinitely. This is also reflected in the `Wire` library. That means, that big noise on the lines will often lead to the bus being stuck in the middle of a transaction, needing you to reset the devices (not only the slaves, but also the master) to get the bus free again. I would go so far to say, that is it more likely to get the bus stuck, than to get corrupted data. So any information about errors is not really helping you here, since you won't get out of `requestFrom()` in the first place. Your code can very well get stuck there.

I suggest, that you test your setup thoroughly with the wanted run times. If the bus gets stuck too often for you, then you should make your setup more robust (shielded cables, or using an extra MCU with the I2C slave and using a more robust communication interface between main MCU and extra MCU).


message:
Best way to obtain angular velocity from a 9 DoF sensor

I have been using a BNO055 sensor (9° dof IMU) for a project which will use angular velocity to the mouse cursor on screen.

So far, I have gotten quaternion output from the sensor and been able to convert it to angular velocity in a couple of ways. The first, multiplying 1 quaternion sample by its conjugate in the next sample, and then converting the quaternion Delta in Euler angles. The second, converting from quaternions to Euler angles and then finding the change in those between samples.

Both methods result in angular velocity measurement, but each with their advantages and disadvantages. E.g. Quaternion Delta between samples does not suffer from gimbal lock, but it's difficult to isolate y-axis from z-axis movement.

I know that you can ask the sensor for angular velocity data directly, but apparently that's less precise due to the Gyro drift and it's relative orientation only, which is why I opted to work with quaternions.

Is there a better way to go about this?

My code included below for reference with the 2 approaches in case it's helpful/interesting. It uses the Adafruit repository, doing the standard stuff in setup function and then calling the function below in loop.

    void quaternion_Delta () {
      // Quaternion data 1
      imu::Quaternion quat = bno.getQuat();
      // Euler 1
      imu::Vector<3> euler_one = quat.toEuler();
      //delay between samples
      delay(BNO055_SAMPLERATE_DELAY_MS);
      // Quaternion data 2
      imu::Quaternion quat_two = bno.getQuat();
      // Euler 2
      imu::Vector<3> euler_two = quat_two.toEuler();
      // quaternion comparison
      imu::Quaternion quatDelta = quat_two * quat.conjugate ();
      imu::Vector<3> euler = quatDelta.toEuler();
      Serial.print(" X: ");
      Serial.print(euler.x()*radius_to_degrees, 2);
      Serial.print(" Y: ");
      Serial.print(euler.y()*radius_to_degrees, 2);
      Serial.print(" Z: ");
      Serial.print(euler.z()*radius_to_degrees, 2);
      Serial.print("\t\t");
      // Euler comparison
      imu::Vector<3> euler_comparison = euler_two - euler_one;
      Serial.print(" x: ");
      Serial.print(euler_comparison.x()*radius_to_degrees, 2);
      Serial.print(" y: ");
      Serial.print(euler_comparison.y()*radius_to_degrees, 2);
      Serial.print(" z: ");
      Serial.print(euler_comparison.z()*radius_to_degrees, 2);
      Serial.print("\n");
      }

body:
Consider building on [Sebastian Madgwick's PhD IMU research][1].  A GitHub Arduino project based on Madgwick's work can be found [here][2].

  [1]: https://x-io.co.uk/open-source-imu-and-ahrs-algorithms/
  [2]: https://github.com/arduino-libraries/MadgwickAHRS


message:
What is the best way I can detect if a ping pong ball has hit the ping pong table?

The ultimate goal is to track points, which in the case ping pong, is how many times the ball has touched the table.

My concerns are with how light the ball and therefore the impact on the table will be. Is this too light for something like a vibration sensor to register?
Would you imagine the sensor working better on the paddles or the table?

I'm open to other suggestions on more reliable ways to track other than vibration. Definitely new to arduino.

body: Having played ping-pong (badly) I think a microphone would be able to count ball/table impacts quite well. The 'click' sound is much higher than that of hitting the paddle, so you might be able to differentiate on that basis. You might consider a two microphone/transducer arrangement- one coupled to the table and one not touching the table. If you get a simultaneous signal on both, the ball has hit the table. If you get only one signal (from the not-touching microphone) then the ball has hit a paddle. This also gives you the option of getting some timing information.


message:
Pushbutton to initiate a 5 time flash

The following code operates in a way that LED starts to flash only if the pushbutton is pushed for one second. I want to change this and make the LED flash for 5 times, immediately on push, regardless if the button is held "long" or released immediately. Can anyone help me out with this? I'm using the LC_baseTools library btw. I managed to do this with another library with `doFlash(5)` but I have to work with LC basetools in this scenario and I can't figure out how to do it.
```cpp
#include <mechButton.h>
#include <blinker.h>

#define BUTTON_PIN   11
#define LED_PIN      13
#define BLINK_MS     500.0
#define HOLD_MS      1000

mechButton  theButton(BUTTON_PIN);                    // A debounced button object. (Hook button between pin & ground)
blinker     theBlinker(LED_PIN,BLINK_MS/2,BLINK_MS);  // A fire and forget blinker object.
timeObj     pushTimer(HOLD_MS);                       // A timer object

void setup(void) {
   theBlinker.setOnOff(false);            // Make sure the blinker is acutally off.
   theButton.setCallback(btnClicked);     // Set the callback for the button.
}

// This gets called when the button is clicked.
void btnClicked(void) {
   if (!theButton.trueFalse()) {    // If it has been grounded..
      pushTimer.start();            // Start the timer.
      theBlinker.setPercent(100);   // Set the blinker to full on.
      theBlinker.setOnOff(true);    // Fire it up.
   } else {                         // Else, button released..
      theBlinker.setOnOff(false);   // SHut off the blinker.
   }
}

void loop(void) {
   idle();                             // idle runs the stuff in the background (button & binker)
   if (!theButton.trueFalse()) {       // If the button is currently pressed..
      if (pushTimer.ding()) {          // If the timer has expired..
         theBlinker.setPercent(50);    // Start blinking!
      }
   }
}

body:
First of all, considering your comment: "*I don't have time [...] to tackle arduino programming*" - If you don't learn how to code, then you can't work with code (and that includes putting together libraries you find on the internet). And learning takes time, it's that simple.

I recommend you forget about those libraries and implement that easy task from scratch, so you actually learn something. The below code has the logic you ask for, try to understand what it does.

    #define BUTTON_PIN   11
    #define LED_PIN      13

    bool button_was_pressed=false;

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

    void loop() {
      if (digitalRead(BUTTON_PIN)) {
        if(!button_was_pressed) {
          for (int i=0;i<5;i++) {
            digitalWrite(LED_PIN,HIGH);
            delay(50);
            digitalWrite(LED_PIN,LOW);
            delay(50);
          }
        }
        button_was_pressed=true;
      }
      else {
        button_was_pressed=false;
      }
    }

...pretty simple and it's only a few lines. You may want to debounce the button and use a non-blocking coding style, but that's a different chapter.

My advice is that you learn programming in a structured manner, e.g. by watching tutorials. A Q&A site is not the right place to do so, as we only answer questions.


body:
>I managed to do this with another library with "doFlash(5)" but I have to work with LC basetools in this scenario and I can't figure out how to do it.

It looks like you are still allowed to write Arduino code in your sketch, so why not use the `BlinkWithoutDelay` "concept" and just write your own code.

I would favour an OOP solution for the LED flashing part of your requirement.
<!-- language-all: c++ -->
```
// Arduino IDE 1.8.9.
// Sketch uses 1126 bytes (3%) of program storage space.
// Global variables use 25 bytes (1%) of dynamic memory.
class Flasher{

  private:

    byte ledPin;
    byte ledState;
    unsigned int flashCounter;
    unsigned long highTime;
    unsigned long lowTime;
    unsigned long previousMillis;

  public:

    Flasher(byte ledPinNumber, unsigned long ledOnTime, unsigned long ledOffTime){
      ledPin = ledPinNumber;
      ledState = LOW;
      highTime = ledOnTime;
      lowTime = ledOffTime;
      previousMillis = 0;
      pinMode(ledPinNumber, OUTPUT);
      digitalWrite(ledPinNumber, LOW);
    }

    void Update(){

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

      if((ledState == HIGH) && (currentMillis - previousMillis >= highTime) && ((flashCounter > 0))){
        ledState = LOW;
        previousMillis += highTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
      else if((ledState == LOW) && (currentMillis - previousMillis >= lowTime) && ((flashCounter > 0))){
        ledState = HIGH;
        previousMillis += lowTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
    }

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

    void Stop(){
      Start(0);
    }

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

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

};

// Flasher object_name(Pin Number, ON Time MS, OFF Time MS);
Flasher led1(LED_BUILTIN, 500, 500);

void setup(){

  // Flash the LED 5 times.
  led1.Start(5);

}

void loop(){

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

}

```


message:
Serial and I2C not working together

I have very peculier problem. When I run this code SSD1306 fails to initialize. Output at serial console is:
20:26:33.194 -> MPU6050 OLED demo

20:26:33.532 -> SSD1306 allocation failed

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_MPU6050.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_Sensor.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

    Adafruit_MPU6050 mpu;
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    int count =0;

    void setup() {

      Serial.begin(9600);
      while (!Serial);
      Serial.println("MPU6050 OLED demo");

      if (!mpu.begin()) {
        Serial.println("Sensor init failed");
        while (1)
          yield();
      }
      Serial.println("Found a MPU-6050 sensor");

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
        Serial.println(F("SSD1306 allocation failed"));
        for (;;)
          ; // Don't proceed, loop forever
      }

      display.display();
      delay(500); // Pause for 2 seconds
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setRotation(0);
    }

    void loop() {
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      display.clearDisplay();
      display.setCursor(0, 0);

      display.println("Accelerometer - m/s^2");
      display.print(a.acceleration.x, 1);
      display.print(", ");
      display.print(a.acceleration.y, 1);
      display.print(", ");
      display.print(a.acceleration.z, 1);
      display.println("");

      display.println("Gyroscope - rps");
      display.print(g.gyro.x, 1);
      display.print(", ");
      display.print(g.gyro.y, 1);
      display.print(", ");
      display.print(g.gyro.z, 1);
      display.println("");
      display.display();
      delay(100);
    }

But when I run this code, without displaying gyro everything runs fine. Adafruit logo is displayed and then followed by regular accelerometer data.

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_MPU6050.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_Sensor.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

    Adafruit_MPU6050 mpu;
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    int count =0;

    void setup() {

      //Serial.begin(9600);
      //while (!Serial);
      //Serial.println("MPU6050 OLED demo");

      if (!mpu.begin()) {
        //Serial.println("Sensor init failed");
        while (1)
          yield();
      }
      //Serial.println("Found a MPU-6050 sensor");

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
        Serial.println(F("SSD1306 allocation failed"));
        for (;;)
          ; // Don't proceed, loop forever
      }

      display.display();
      delay(500); // Pause for 2 seconds
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setRotation(0);
    }

    void loop() {
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      display.clearDisplay();
      display.setCursor(0, 0);

      display.println("Accelerometer - m/s^2");
      display.print(a.acceleration.x, 1);
      display.print(", ");
      display.print(a.acceleration.y, 1);
      display.print(", ");
      display.print(a.acceleration.z, 1);
      display.println("");

      display.println("Gyroscope - rps");
      display.print(g.gyro.x, 1);
      display.print(", ");
      display.print(g.gyro.y, 1);
      display.print(", ");
      display.print(g.gyro.z, 1);
      display.println("");
      display.display();
      delay(100);
    }

Now, while debugging when I disable Serial logs and comment all Serial.print then the above code runs properly, logo is displayed, accelerometer and gyro both the data are displayed on OLED properly.

Compiler Log for non-working code is:
Sketch uses 21980 bytes (71%) of program storage space. Maximum is 30720 bytes.
Global variables use 761 bytes (37%) of dynamic memory, leaving 1287 bytes for local variables. Maximum is 2048 bytes.

The setup I am using as Arduino Nano, MPU6050 connected over I2C (address 0x68), SSD1306 based 0.96" 128x64 display over I2C (address 0x3D). I am using A4 and A5 pin of Arduino Nano as I2C. Both device are connected over same bus. I am using breadboard for testing.

PS: Both the code compiles without error or warning

body:
The SSD1306 uses a *lot* of RAM. Pretty much all your RAM.  Serial also uses quite  a bit of RAM.  The two struggle to work together.

There is a special "text only" SSD1306 library that uses considerably less RAM: https://github.com/greiman/SSD1306Ascii


body:
Thank you Majenko...

It was low RAM problem.
SSD1306 takes 1K, with MPU6050 the and serial print which I have included the remaining RAM is 5 bytes only, hence the initialization issue.
I followed simple guideline to reduce RAM footprint

Read this thread https://stackoverflow.com/questions/8649174/checking-memory-footprint-in-arduino

Code to print available SRAM.

```cpp
Serial.print(availableMemory());

// free RAM check for debugging. SRAM for ATmega328p = 2048Kb.
int availableMemory() {
    // Use 1024 with ATmega168
    int size = 2048;
    byte *buf;
    while ((buf = (byte *) malloc(--size)) == NULL);
        free(buf);
    return size;
}
```


message:
Problems with Hardware Serial (UART) on Nano 33 BLE Sense

my new Nano 33 BLE Sense arrived today.  I'm working on a project to send data from the the Nano via an Xbee S2C module to a receiver module connected to a Nano 33 IoT.  I had the project working before using an MPU6050 and Mega 2560 board which worked (using Software Serial on the Mega).  On the IoT side, I am using 'Uart XBeeRx  (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);' to process the data from the Xbee.  Having tried this syntax on the BLE Sense I hit problems and after some Googling found a different syntax.  However my new code isn't working in so far as it compiles, uploads and then crashes the BLE Sense (serial port disappears from tools and the onboard LED blinks slowly and erratically).  I need to keep resetting the board and suspect there is some issue with my hardware serial implementation.  I've cut the code down to simply send accelerometer data.  My code is as follows - the EasyTransfer library simplifies the Xbee comms.  Any help appreciated!

    #include <EasyTransfer.h>
    #include <Arduino_LSM9DS1.h>

    UART XBeeTx (digitalPinToPinName(6), digitalPinToPinName(5), NC, NC);

    EasyTransfer ET;

    struct SEND_DATA_STRUCTURE {

      float xAcc;
      float yAcc;
      float zAcc;

    };

    SEND_DATA_STRUCTURE myData;

    // ================================================================
    // ===                      INITIAL SETUP                       ===
    // ================================================================

    void setup() {

    XBeeTx.begin(9600);

    ET.begin(details(myData), &XBeeTx);

    }

    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================

    void loop() {

      float x, y, z;

    if (IMU.accelerationAvailable()) {
        IMU.readAcceleration(x, y, z);

      }

      myData.xAcc = x;
      myData.yAcc = y;
      myData.zAcc = z;

      ET.sendData();

    }

body: You can't make calls to IMU if you haven't initialised it with IMU.begin()


message:
Why is our refresh rate consistently decreasing in logging on SD card?

The current code is used to gather the state of 12 infrared beams and log them to an SD card using the real time clock to mark the time. The code uses a switch to turn the device on and off and an LED to indicate if data is being written to the SD. When we later looked at the data on the SD card the refresh rate was slowly decreasing and we ended up with only 10 logs a second after a few hours. Why is this happening and how is it fixed?
```
#include <SD.h>   //For talking to SD Card
#include <Wire.h>  //For RTC
#include "RTClib.h" //For RTC

//Define pins
//SD card is on standard SPI pins
//RTC is on Standard I2C Pins
const int CS_PIN   = 53;

//Default rate of 25ms
int refresh_rate = 25;

//Define RTC object
RTC_DS1307 RTC;

//Initialize variables
String year, month, day, hour, minute, second, time, date;

#define SENSOR1 22
#define SENSOR2 23
#define SENSOR3 24
#define SENSOR4 25
#define SENSOR5 26
#define SENSOR6 27
#define SENSOR7 32
#define SENSOR8 33
#define SENSOR9 34
#define SENSOR10 35
#define SENSOR11 36
#define SENSOR12 37
#define LEDPIN 6
#define SWITCH 10

// variables will change:
int sensorState1 = 0, lastState1 = 0;
int sensorState2 = 0, lastState2 = 0;
int sensorState3 = 0, lastState3 = 0;
int sensorState4 = 0, lastState4 = 0;
int sensorState5 = 0, lastState5 = 0;
int sensorState6 = 0, lastState6 = 0;
int sensorState7 = 0, lastState7 = 0;
int sensorState8 = 0, lastState8 = 0;
int sensorState9 = 0, lastState9 = 0;
int sensorState10 = 0, lastState10 = 0;
int sensorState11 = 0, lastState11 = 0;
int sensorState12 = 0, lastState12 = 0;

//Variable for reading the Switch Status
int SWITCHSTATE ;

//define integers for sensor change
int SensorChange1 = 0;
int SensorChange2 = 0;
int SensorChange3 = 0;
int SensorChange4 = 0;
int SensorChange5 = 0;
int SensorChange6 = 0;
int SensorChange7 = 0;
int SensorChange8 = 0;
int SensorChange9 = 0;
int SensorChange10 = 0;
int SensorChange11 = 0;
int SensorChange12 = 0;

void setup()
{
  // initialize the sensor pin 24 as an input:
  pinMode(SENSOR1, INPUT);
  digitalWrite(SENSOR1, HIGH); // turn on the pullup  // initialize the sensor pin 25 as an input:
  pinMode(SENSOR2, INPUT);
  digitalWrite(SENSOR2, HIGH); // initialize the sensor pin 26 as an input:
  pinMode(SENSOR3, INPUT);
  digitalWrite(SENSOR3, HIGH); // initialize the sensor pin 27 as an input:
  pinMode(SENSOR4, INPUT);
  digitalWrite(SENSOR4, HIGH); // initialize the sensor pin 28 as an input:
  pinMode(SENSOR5, INPUT);
  digitalWrite(SENSOR5, HIGH); // initialize the sensor pin 29 as an input:
  pinMode(SENSOR6, INPUT);
  digitalWrite(SENSOR6, HIGH);  // initialize the sensor pin 30 as an input:
  pinMode(SENSOR7, INPUT);
  digitalWrite(SENSOR7, HIGH);  // initialize the sensor pin 31 as an input:
  pinMode(SENSOR8, INPUT);
  digitalWrite(SENSOR8, HIGH);  // initialize the sensor pin 32 as an input:
  pinMode(SENSOR9, INPUT);
  digitalWrite(SENSOR9, HIGH);  // initialize the sensor pin 33 as an input:
  pinMode(SENSOR10, INPUT);
  digitalWrite(SENSOR10, HIGH);  // initialize the sensor pin 34 as an input:
  pinMode(SENSOR11, INPUT);
  digitalWrite(SENSOR11, HIGH);  // initialize the sensor pin 35 as an input:
  pinMode(SENSOR12, INPUT);
  digitalWrite(SENSOR12, HIGH);   // initialize the LED pin as an output:

// initialize the LED pin as an output:
  pinMode (LEDPIN, OUTPUT);

// initialize the SWITCH pin as an output:
  pinMode (SWITCH, INPUT);

// setpin 19 as high (5V) and 18 as low
  pinMode(19, OUTPUT);
  pinMode(18, OUTPUT);
  digitalWrite(19, HIGH);
  digitalWrite(18, LOW);

  Serial.begin(9600);
  Serial.println(F("Initializing Card"));

 //CS pin, and pwr/gnd pins are outputs
  pinMode(CS_PIN, OUTPUT);

  //Initiate the I2C bus and the RTC library
  Wire.begin();
  RTC.begin();

  //If RTC is not running, set it to the computer's compile time
  if (! RTC.isrunning())
  {
    Serial.println(F("RTC is NOT running!"));
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  //Initialize SD card
  if (!SD.begin(CS_PIN))
  {
    Serial.println(F("Card Failure"));
    return;
  }
  Serial.println(F("Card Ready"));

  //Read the configuration information (speed.txt)
  File commandFile = SD.open("speed.txt");
  if (commandFile)
  {
    Serial.println(F("Reading Command File"));

    while(commandFile.available())
    {
      refresh_rate = commandFile.parseInt();
    }
    Serial.print(F("Refresh Rate = "));
    Serial.print(refresh_rate);
    Serial.println(F("ms"));
    commandFile.close();
  }
  else
  {
    Serial.println(F("Could not read command file."));
    return;
  }

}

void loop()
{
  SWITCHSTATE = digitalRead(SWITCH); //read input value
  if (SWITCHSTATE == LOW)
 {
   digitalWrite(LEDPIN, LOW);
 }
  else
 {
   digitalWrite(LEDPIN, HIGH);

// read the state of the sensor value:
  sensorState1 = digitalRead(SENSOR1);
  sensorState2 = digitalRead(SENSOR2);
  sensorState3 = digitalRead(SENSOR3);
  sensorState4 = digitalRead(SENSOR4);
  sensorState5 = digitalRead(SENSOR5);
  sensorState6 = digitalRead(SENSOR6);
  sensorState7 = digitalRead(SENSOR7);
  sensorState8 = digitalRead(SENSOR8);
  sensorState9 = digitalRead(SENSOR9);
  sensorState10 = digitalRead(SENSOR10);
  sensorState11 = digitalRead(SENSOR11);
  sensorState12 = digitalRead(SENSOR12);

  //Get the current date and time info and store in strings
  DateTime datetime = RTC.now();
  year  = String(datetime.year(),  DEC);
  month = String(datetime.month(), DEC);
  day  = String(datetime.day(), DEC);
  hour  = String(datetime.hour(), DEC);
  minute = String(datetime.minute(), DEC);
  second = String(datetime.second(), DEC);

  //Concatenate the strings into date and time
  date = year + "/" + month + "/" + day;
  time = hour + ":" + minute + ":" + second;

  if (sensorState1 == HIGH)
  {
   SensorChange1 = 1;
  }
  else
  {
   SensorChange1 = 0;
  }
  if (sensorState2 == HIGH)
  {
   SensorChange2 = 1;
  }
  else
  {
   SensorChange2 = 0;
  }
  if (sensorState3 == HIGH)
  {
   SensorChange3 = 1;
  }
  else
  {
   SensorChange3 = 0;
  }
  if (sensorState4 == HIGH)
  {
   SensorChange4 = 1;
  }
  else
  {
   SensorChange4 = 0;
  }
  if (sensorState5 == HIGH)
  {
   SensorChange5 = 1;
  }
  else
  {
   SensorChange5 = 0;
  }
  if (sensorState6 == HIGH)
  {
   SensorChange6 = 1;
  }
  else
  {
   SensorChange6 = 0;
  }
  if (sensorState7 == HIGH)
  {
   SensorChange7 = 1;
  }
  else
  {
   SensorChange7 = 0;
  }
  if (sensorState8 == HIGH)
  {
   SensorChange8 = 1;
  }
  else
  {
   SensorChange8 = 0;
  }
  if (sensorState9 == HIGH)
  {
   SensorChange9 = 1;
  }
  else
  {
   SensorChange9 = 0;
  }
  if (sensorState10 == HIGH)
  {
   SensorChange10 = 1;
  }
  else
  {
   SensorChange10 = 0;
  }
  if (sensorState11 == HIGH)
  {
   SensorChange11 = 1;
  }
  else
  {
   SensorChange11 = 0;
  }
  if (sensorState12 == HIGH)
  {
   SensorChange12 = 1;
  }
  else
  {
   SensorChange12 = 0;
  }

  File dataFile ;
  dataFile = SD.open("log1.csv", FILE_WRITE);
  if (dataFile)
    {
      dataFile.print(date);
      dataFile.print(F(","));
      dataFile.print(time);
      dataFile.print(F(","));
      dataFile.print(SensorChange1);
      dataFile.print(F(","));
      dataFile.print(SensorChange2);
      dataFile.print(F(","));
      dataFile.print(SensorChange3);
      dataFile.print(F(","));
      dataFile.print(SensorChange4);
      dataFile.print(F(","));
      dataFile.print(SensorChange5);
      dataFile.print(F(","));
      dataFile.print(SensorChange6);
      dataFile.print(F(","));
      dataFile.print(SensorChange7);
      dataFile.print(F(","));
      dataFile.print(SensorChange8);
      dataFile.print(F(","));
      dataFile.print(SensorChange9);
      dataFile.print(F(","));
      dataFile.print(SensorChange10);
      dataFile.print(F(","));
      dataFile.print(SensorChange11);
      dataFile.print(F(","));
      dataFile.print(SensorChange12);
      dataFile.println( );
      dataFile.close(); //Data isn't actually written until we close the connection!

      //Print same thing to the screen for debugging
      Serial.println();
      Serial.print(date);
      Serial.print(F(","));
      Serial.print(time);
      Serial.print(F(","));
      Serial.print(SensorChange1);
      Serial.print(F(","));
      Serial.print(SensorChange2);
      Serial.print(F(","));
      Serial.print(SensorChange3);
      Serial.print(F(","));
      Serial.print(SensorChange4);
      Serial.print(F(","));
      Serial.print(SensorChange5);
      Serial.print(F(","));
      Serial.print(SensorChange6);
      Serial.print(F(","));
      Serial.print(SensorChange7);
      Serial.print(F(","));
      Serial.print(SensorChange8);
      Serial.print(F(","));
      Serial.print(SensorChange9);
      Serial.print(F(","));
      Serial.print(SensorChange10);
      Serial.print(F(","));
      Serial.print(SensorChange11);
      Serial.print(F(","));
      Serial.print(SensorChange12);

    }
    else
    {
     Serial.println(F("Couldn't open log file"));
    }

  lastState1 = sensorState1;
  lastState2 = sensorState2;
  lastState3 = sensorState3;
  lastState4 = sensorState4;
  lastState5 = sensorState5;
  lastState6 = sensorState6;
  lastState7 = sensorState7;
  lastState8 = sensorState8;
  lastState9 = sensorState9;
  lastState10 = sensorState10;
  lastState11 = sensorState11;
  lastState12 = sensorState12;

  delay(refresh_rate);
  }

  }
```
[![Frequency over time as graphed in R][1]][1]

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

body:
I don't have certain answer for you, but a deep suspicion.  <s>If I get bored I'll confirm it.</s> Confirmed below.

In each pass of `loop()`, you have:

```c++
  dataFile = SD.open("log1.csv", FILE_WRITE);
```

In short, finding the end of the file is linear operation in a FAT filesystem.  It must follow the [allocation chain][1] to find (or create), the last cluster of the file.  The allocation chain is sort like a linked list with the links themselves being the only thing in linked list structure; their numbers are mapped onto the cluster numbers.  So you're traversing a linked list, except you may be doing it across multiple sectors of an SD card, which is comparatively expensive.

So by reopening repeatedly in `loop()`, you're forcing it to perform this lengthening process each time, apparently because of:

```c++
dataFile.close(); //Data isn't actually written until we close the connection!
```

The part of `.close();` that does this is [made available][2] to you as `.flush();`, without needing to close the file and forget where the current cluster is.

In other words, you should be able to `open()` the file once in `setup()` and replace your `.close()` in `loop()` with a `.flush()`.

That said, you needn't and probably shouldn't flush on every record write.  If you're doing this so that you can shut the device down, you might want to just add a push-button that does the closing or flushing and then waits in the tight loop until it's power cycled.

Confirmation Test  Results
==========================

In short, yes, there's a measurable, file-size related cost to opening the file for write and seeking to the end. And it's just a fact about the FAT filesystem and noticeable because it's impractical to load the whole allocation table into memory on a small Arduino.  It would normally (e.g on the desktop) be loaded into memory and you'd scarcely notice the difference in opening files of different sizes.

In my one tested scenario for my setup the numbers predict that when the file grows to approximately 155 Meg, it will take about a tenth of a second to open.

This test involved:
* An Arduino UNO.
* 2 GB FAT16 formatted card.
* Arduino AVR core version 1.8.3
* SD card library version 1.2.4.

Your results will probably vary widely with MCU type and filesystem block size, but so long as you're using a Arduino with a SD library that minimizes memory footprint, you'll have a noticeable increasing open time with larger file sizes.

The below is going to be a bit nerdy, but since people seem to be interested in it, I'm giving some detail.  Arduino code follows at the bottom for what was used to collect the data that produced the graph.

I emptied a 2 GByte SD card.  This included removing the "System Volume Information" that windows (or perhaps the card maker) had put on there, and
confirmed that were were no allocated clusters, no file chains.  Under these conditions the file should just grow in consecutive sectors on the card; at
least as presented by the card, as in: if we ignore anything the card might be doing for wear-leveling.  The pattern used in the program makes it pretty easy
to just look at a raw image of the card and see that this is what happened.

Anyway, with my setup these are some results:

[![Graph of real timings.][4]][4]

The 98304 sector count on the right refers to a file of roughly 50 Meg.

This SD card is FAT16 formatted, something I hadn't noticed until I ran the numbers on that staircase pattern and found them defying expectations by a factor of 2.

Being FAT16, each FAT table sector, has 512/2 = 256 entries in it.  Each entry number corresponds to one cluster (block), which for my SD card's filesystem happens to be 32 kByte, or 64 count of 512-byte sectors.   So every FAT table sector (in my case) is responsible for locating 64 * 256 = 16,384 file sectors.  In other words, the staircase pattern appears to reflect the fact that following the allocation chain for our consecutive file means reading another FAT table sector for every 16,384 sectors of the file, hence the jumps at those intervals.

* If you used a fragmented file it would need to do this more often and the performance would look worse.  *I did inspect the SD card to confirm that it was written sequentially.*

* If you use FAT32, you can expect it to take longer because each FAT sector will store half as many cluster references.

* If you use smaller cluster (block) size, then it will take longer because each enter in the FAT sector covers less file content.

Test code
---------

```c++
//
// Tested on an UNO with Arduino Core version 1.8.3
// 2 GByte SDCard
//

#include <SD.h> // Version 1.2.4 as of test.
#include <SPI.h>

static constexpr int PIN_SDCARD_SHIELD_CHIP_SELECT = 10;
static constexpr int PIN_HALT_TEST                 =  2;

static const char test_filename[] = "testfile.txt";

struct test_state : Printable {
  uint32_t      sector_counter = -1;
  unsigned long open_duration  =  0;

  size_t printTo(Print& p) const override {
    auto r = p.write('[');
    r     += p.print(sector_counter);
    r     += p.write(':');
    r     += p.print(open_duration);
    r     += p.write(']');
    return r;
  }

  void update(unsigned long new_open_duration) {
    open_duration = new_open_duration;
    ++sector_counter;
  }
};

//
//
//
void write_numbered_sector(
  Print &p,
  const test_state &state
) {
  static constexpr size_t SECTOR_SIZE            = 512;
  static constexpr size_t CR_LF_SIZE             =   2;

  const auto printed_test_state_len = p.print(state);

  const auto xs_to_write =
      SECTOR_SIZE
    - printed_test_state_len
    - CR_LF_SIZE;

  for (size_t i = xs_to_write; i != 0; --i) {
    p.write('X');
  }

  p.write('\r');
  p.write('\n');
}

//
//
//
void setup() {
  pinMode(PIN_HALT_TEST, INPUT_PULLUP);

  Serial.begin(9600);

  if (!SD.begin(PIN_SDCARD_SHIELD_CHIP_SELECT)) {
    Serial.println(F("Card initialization failed."));
    halt_test();
  }

  SD.remove(test_filename);
}

//
//
//
void blink_forever() {
  pinMode(LED_BUILTIN, OUTPUT);
  while (true) {
    static bool led_state = false;

    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    delay(100);
  }
}

//
//
//
void halt_test() {
  SD.end();
  SPI.end();
  Serial.end();

  blink_forever();
}

//
//
//
void loop() {
  static test_state state;

  Serial.flush();
  const auto started_opening = micros();
  File testfile = SD.open(test_filename, FILE_WRITE);
  const auto done_opening = micros();

  const auto open_duration = done_opening - started_opening;

  state.update(open_duration);

  write_numbered_sector(
    testfile,
    state
  );
  testfile.close();
  Serial.print(micros());
  Serial.print(' ');
  Serial.println(state);

  const auto user_requested_halt = (digitalRead(PIN_HALT_TEST) == LOW);
  if (user_requested_halt) {
    Serial.println(F("Test halt requested."));
    halt_test();
  }
}

//  vim:sw=2:ts=2:et:nowrap:ft=cpp:
```

  [1]: https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Cluster_map
  [2]: https://www.arduino.cc/en/Reference/FileFlush
  [3]: https://arduino.stackexchange.com/users/42982/chris-h
  [4]: https://i.stack.imgur.com/szi8q.png


message:
if(Serial.available()>0) VS while(Serial.available()>0)

What's the low level difference between `if(Serial.available() > 0)` and `while(Serial.available() > 0)`? On what conditions would you choose one over the other?

I was testing my codes on 4 daisy chained 74HC595 shift registers controlling multiple LEDs. The code takes in a number from the serial monitor and displays it out in binary via the LEDs. Here is the code below that worked:

    #define latchPin 8  //ST_CP pin of 74HC595
    #define clockPin 9  //SH_CP pin of 74HC595
    #define dataPin 7   //DS pin of 74HC595

    //number of 74HC595 in daisy chain
    #define numOfDaisyChainReg 4

    byte registerVal[numOfDaisyChainReg];

    void setup() {
        Serial.begin(115200);
        pinMode(latchPin, OUTPUT);
        pinMode(clockPin, OUTPUT);
        pinMode(dataPin, OUTPUT);
    }

    void loop() {

      while (Serial.available() > 0) {

        uint32_t num = Serial.parseInt();
        Serial.print(num, DEC);
        Serial.print(" : ");
        Serial.println(num, BIN);

        //breaks the recieved int into 4 unsigned bytes
        //and assigns the byte value into the "registerVal" array
        for (uint8_t a = 0; a < numOfDaisyChainReg; a++) {
          registerVal[a] = (num >> (numOfDaisyChainReg - (a + 1)) * 8) & 0xFF;
          Serial.print("registerVal["); Serial.print(a); Serial.print("] = ");
          Serial.println(registerVal[a], BIN);
        }

        //writes the 4 bytes into the shift register
        digitalWrite(latchPin, LOW);
        for (uint8_t x = 0; x < numOfDaisyChainReg; x++) {
          shiftOut(dataPin, clockPin, MSBFIRST, registerVal[x]);
        }
        digitalWrite(latchPin, HIGH);

      }

    }

Originally, I had `if(Serial.available() > 0)` and that didn't work as no LEDs lit up despite everything else in the code working as it was expected. Switching to `while(Serial.available() > 0)` solved that problem. Anyone have any idea why that's the case?

body:
Some implementations of the Arduino core have features that need `loop()` to exit regularly.  Although it's not often used, the [`serialEvent()` is an example][1] of one such thing, at least in the [AVR Arduino core][2].

The ESP8266 Arduino core appears to do some [task scheduling][3] when `loop()` exits, among other things.

For your particular use case, it may make no difference at all, probably doesn't.  It *may* not even generate different code once compiled.  If you were doing something where you could not afford to exit `loop()`, run other stuff and re-enter `loop()` to run your code for a second pass, then there might be a performance reason to use your own while loop inside `loop()`.  In your code as it currently is, the eventual blocking on `Serial` writes will end up limiting the execution to the same speed.

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/serial/serialevent/
  [2]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/cores/arduino/main.cpp#L47
  [3]: https://github.com/esp8266/Arduino/blob/2.7.4/cores/esp8266/core_esp8266_main.cpp#L198


body:
I figured out why `while(Serial.available()>0)` and `if(Serial.available() > 0)` would or would NOT work in terms of my shift register code. It has to do with the serial monitor **line feed and carriage return setting**! If it isn't set to no line ending, it will either not register the input number or reset it back to zero right after the input is read. Learned to always check the line return option in the serial monitor! With this solved, the original question is nothing more than a general `if` vs `while` statement; which I already know the answer.

**Thanks to everyone who contributed to this question!** It did help me understand a lot more about `Serial.available()` in general. @jsotola gave a really good [article][1]. Combined with this [YouTube video][2], it makes a lot more sense now.

  [1]: http://majenko.co.uk/blog/reading-serial-arduino
  [2]: https://youtu.be/qCjCRBLv_VM