message:
Possibility of clean the code?

Good night! Based on stuff I get a bit here and there, came up with a program for an Arduino Audio Selector with shift registers and some features. Working as expected, only missing connecting the relay boads, but that's for future. Since I have a few devices, instead of having to write all, is there anyway of I change for instance a line and then on display show that line?

Thanks. Here's my code, realy big, try to short the part of the shift registers but seems to me it was unstable.

[Arduino selector 4x20][1]

  [1]: https://github.com/nmbb/arduinoaudioselectorlcd20x4/blob/master/arduino_selector_20x4_function_shift_register.ino

body:
I see a lot of 'almost' repetitions like :

      if (RelaySourceDigi == 7) {
        shifter.setPin(16, LOW);
        shifter.setPin(17, LOW);
        shifter.setPin(18, LOW);
        shifter.setPin(19, LOW);
        shifter.setPin(20, LOW);
        shifter.setPin(21, LOW);
        shifter.setPin(22, HIGH);
        shifter.setPin(23, LOW);
        shifter.write();
        lcd.setCursor(0, 2);
        lcd.write(8);
        lcd.setCursor(2, 2);
        lcd.print("Coaxial 3");
      }

Move this to a separate function, and make an argument (or more) of items that vary.
This will greatly reduce your code, making it more managable/maintainable.

Below I changed the entire program. Note I didn't check for runtime errors, and it is highly possible I made some copy/paste errors, but it will give you a clue what you can change. As you can see, the program is radically shortened (and more maintainable).

What you need to do is:

- Check each change
- Check for copy/paste errors
- Read a little bit about pointers (e.g. the `&RelaySource` and `*t` constructs)
- Also I highly suggest not to use so many constants, but use `enum`s, to denote the value for each different mode you have. So instead of `case 1`, you can write `case TAPE_1`.
- Split `loop` in smaller functions (e.g. one function per mode).
- I didn't install your libraries but used e.g. #include "LiquidCrystal_I2C.h" and stubbed all functions (meaning I can call them but they don't do anything, just to check for compiler errors in the main program).
- Also instead of Aux, use a boolean `(true, false)`.
- You see I use a lot of `(state - 1)` constructs. It's common practice to start counting at 0, not at 1, it will make your life easier. Only when displaying a value for a user, add +1.
Below the program.

        //Libraries
        #include "LCD.h"
        #include "LiquidCrystal_I2C.h"
        #include "Shifter.h"

        #define SER_Pin 8 //SER_IN 14 on 74HC595
        #define RCLK_Pin 9 //L_CLOCK 12 on 74HC595
        #define SRCLK_Pin 10 //CLOCK 11 on 74HC595
        #define NUM_REGISTERS 3 //how many registers are in the chain
        //initaize shifter using the Shifter library
        Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

        LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

        const int ButtonPinUp = 2;
        int ButtonPinUpState = 0;
        const int ButtonPinDn = 3;
        int ButtonPinDnState = 0;
        const int MuteButtonPin = 5;
        int MuteButtonPinState = 0;
        const int AuxButtonPin = 4;
        int AuxButtonPinState = 0;
        const int fbutton = 6;
        int RelaySource = 1;
        int RelaySourceDigi = 1;
        int RelayRec = 1;
        int RecDigi = 1;
        int Mute = 0;
        int Mode = 0;
        int Aux = 1;
        int state = 0;
        int old = 0;
        int ButtonPoll = 0;

        byte opt[8] = {
          0b00000,
          0b01110,
          0b11011,
          0b10001,
          0b10001,
          0b10001,
          0b11111,
          0b00000
        };

        byte coax[8] = {
          0b00100,
          0b01110,
          0b11111,
          0b10001,
          0b10001,
          0b01110,
          0b00100,
          0b00100
        };

        byte mut[8] = {
          0b00001,
          0b00011,
          0b00111,
          0b11111,
          0b11111,
          0b00111,
          0b00011,
          0b00001
        };

        byte outp[8] = {
          B00000,
          B00100,
          B00110,
          B11111,
          B11111,
          B00110,
          B00100,
          B00000
        };

        byte upp[8] = {
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111,
          0b11111
        };

        byte inpp[8] {
          0b10000,
          0b10000,
          0b10100,
          0b10110,
          0b11111,
          0b00110,
          0b00100,
          0b00000
        };

        byte ann[8] {

          0b11111,
          0b10001,
          0b10101,
          0b10101,
          0b10001,
          0b10101,
          0b10101,
          0b11111
        };

        byte dnn[8] = {
          0b11111,
          0b10011,
          0b10101,
          0b10101,
          0b10101,
          0b10101,
          0b10011,
          0b11111
        };

        byte too[8] = {
          0b00000,
          0b00100,
          0b00110,
          0b11111,
          0b00110,
          0b00100,
          0b00000,
          0b00000
        };

        void printAtCursor(int a, int b, const char* c)
        {
          lcd.setCursor(a, b);
          lcd.print(c);
        }

        void setup() {
          lcd.begin(20, 4);
          lcd.backlight();

          byte* list[] = {outp, coax, mut, opt, upp, inpp, ann, dnn, too };
          for (int n = 0; n < 9; n++)
          {
            lcd.createChar(n + 1, list[n]);
          }

          pinMode(fbutton, INPUT);
          pinMode(ButtonPinUp, INPUT);
          pinMode(MuteButtonPin, INPUT);
          pinMode(ButtonPinDn, INPUT);
          pinMode(AuxButtonPin, INPUT);

          for (int n = 11; n < 14; n++)
          {
            pinMode(n, OUTPUT);
          }

          printAtCursor(3, 0, "Digital/Analog");
          printAtCursor(3, 1, "Audio Selector");
          printAtCursor(4, 2, "Built-In DAC");
          printAtCursor(2, 3, "V2.0f (23052020)");
          delay(4000);
          lcd.clear();
        }

        void setPin(int first, int last, int pin)
        {
          for (int n = first; n < last + 1; n++)
          {
            shifter.setPin(n, pin == n ? HIGH : LOW);
          }

          shifter.write();
        }

        void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
        {
            lcd.setCursor(0, a);
            lcd.write(b);
            lcd.setCursor(2, a);
            lcd.print(t);
            if (x != -1)
            {
              lcd.write(x);
              lcd.print(u);
            }
        }

        void loop()
        {
          // shifter.clear(); //set all pins on the shift register chain to LOW
          shifter.write(); //send changes to the chain and display them
          //check button states
          ButtonPinUpState = digitalRead(ButtonPinUp);
          ButtonPinDnState = digitalRead(ButtonPinDn);
          MuteButtonPinState = digitalRead(MuteButtonPin);
          AuxButtonPinState = digitalRead(AuxButtonPin);
          ButtonPoll = digitalRead(fbutton);

          if (AuxButtonPinState == HIGH && RelaySource == 1 && state == 1) {
            lcd.clear();
            Aux           = ~Aux;
            digitalWrite(13, Aux == 0 ? LOW : HIGH);
          }

          if (ButtonPoll == HIGH) {
            state = old + 1;
          }

          lcd.clear(); // Happens in all cases
          switch (state) {
            case 1: // Fall through
            case 2: // Fall through
            case 3: // Fall through
            case 4:
              lcd.setCursor(1, state - 1);
              lcd.write(5);
              old = state;
              break;

            default:
              old = 0;
              break;
          }

          // Assuming state = 1..4
          if (ButtonPinUpState == HIGH)
          {
            lcd.clear();
            int* t = NULL;
            int maxValue = -1;

            switch (state)
            {
              case 1: t = &RelaySource;     maxValue = 8; break;
              case 2: t = &RelayRec;        maxValue = 5; break;
              case 3: t = &RelaySourceDigi; maxValue = 8; break;
              case 4: t = &RecDigi;         maxValue = 4; break;
              default: break;
            }

            *t = min(1, max(maxValue, *t + (ButtonPinUpState == HIGH ? 1 : 0) + (ButtonPinDnState == HIGH ? -1 : 0)));
          }

          if (MuteButtonPinState == HIGH) {
            lcd.clear();
            Mute = (Mute == 0 ? 1 : 0);
            digitalWrite(12, Mute == 0 ? HIGH : LOW);
          }

          // RelaySource
          setPin(0, 7, RelaySource - 1);
          if (RelaySource == 1 && Aux == 0)
          {
            setLines(0, 7, "D", 9, "A:");
          }
          else
          {
            const char* rs1[] = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };
            setLines(0, 7, rs1[RelaySource - 1]);
          }

          if (RelaySource == 8)
          {
            shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
          }

          // RelayRec
          int         rr1[] = { 8      , -1   , 9       , 10      , 11       };
          const char* rr2[] = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
          const int   rr3[] = { -1     , -1   , 9       , 9       , 9        };
          const char* rr4[] = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

          setPin(8, 11, rr1[RelayRec - 1]);
          setLines(1, 6, rr2[RelayRec - 1], rr3[RelayRec - 1], rr4[RelayRec - 1]);

          // RelaySourceDigi
          setPin(16, 23, 17 - RelaySourceDigi);
          if (RelaySource == 1 && Aux == 0)
          {
            lcd.setCursor(7, 0);
            const char* t[] = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
            lcd.print(t[RelaySource - 1]);
          }

          const char* t1[] = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
          const int   t2[] = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
          const char* t3[] = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };
          setLines(2, 8, t1[RelaySourceDigi - 1], t2[RelaySourceDigi - 1], t3[RelaySourceDigi - 2]);

          // RecDigi
          const char* t[] = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
          setPin(12, 15, 11 + RecDigi);
          setLines(3, 6, t[RecDigi - 1]);

          delay(150);
        }

**Update**

I wanted for myself to see how to clean it fully, so I tried below.

Still check for copy/paste problems, as I didn't execute the sketch (but it compiles without warnings).

Original sketch: 2746 bytes (8%) program storage space, 142 bytes (6%) of dynamic memory
Sketch below   : 1546 bytes (4%) program storage space,  40 bytes (2%) of dynamic memory.

Conclusion:

- 25% less program storage space used
- 67% less dynamic memory used
- Less lines of code
- Better readability
- Better maintainability
- No (or less) code duplication
- Smaller function complexity
- Less statements (added more to initialization)

Code:

    //Libraries
    #include "LCD.h"
    #include "LiquidCrystal_I2C.h"
    #include "Shifter.h"

    const uint8_t SER_Pin = 8; //SER_IN 14 on 74HC595
    const uint8_t RCLK_Pin = 9; //L_CLOCK 12 on 74HC595
    const uint8_t SRCLK_Pin = 10; //CLOCK 11 on 74HC595
    const uint8_t NUM_REGISTERS = 3; //how many registers are in the chain

    Shifter _shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);
    LiquidCrystal_I2C _lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

    enum EMode
    {
      RELAY_SOURCE,
      RELAY_REC,
      RELAY_SOURCE_DIGI,
      REC_DIGI,
      LAST_MODE
    };

    static const uint8_t _buttonPinUp = 2;
    bool _buttonPinUpState = false;
    static const uint8_t _buttonPinDown = 3;
    bool _buttonPinDownState = false;
    static const uint8_t _muteButtonPin = 5;
    bool _muteButtonPinState = false;
    static const uint8_t _auxButtonPin = 4;
    bool _auxButtonPinState = false;
    static const uint8_t _forwardButton = 6;
    uint8_t _relaySource = 0;
    uint8_t _relaySourceDigi = 0;
    uint8_t _relayRec = 0;
    uint8_t _recDigi = 0;
    bool _mute = false;
    bool _aux = true;
    EMode _mode = RELAY_SOURCE;
    bool _buttonPoll = false;

    static const byte OPT[8]  PROGMEM = {  0b00000,  0b01110,  0b11011,  0b10001,  0b10001,  0b10001,  0b11111,  0b00000 };
    static const byte COAX[8] PROGMEM = {  0b00100,  0b01110,  0b11111,  0b10001,  0b10001,  0b01110,  0b00100,  0b00100 };
    static const byte MUT[8]  PROGMEM = {  0b00001,  0b00011,  0b00111,  0b11111,  0b11111,  0b00111,  0b00011,  0b00001 };
    static const byte OUTP[8] PROGMEM = {  B00000 ,  B00100 ,  B00110 ,  B11111 ,  B11111 ,  B00110 ,  B00100 ,  B00000  };
    static const byte UPP[8]  PROGMEM = {  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111 };
    static const byte INPP[8] PROGMEM = {  0b10000,  0b10000,  0b10100,  0b10110,  0b11111,  0b00110,  0b00100,  0b00000 };
    static const byte ANN[8]  PROGMEM = {  0b11111,  0b10001,  0b10101,  0b10101,  0b10001,  0b10101,  0b10101,  0b11111 };
    static const byte DNN[8]  PROGMEM = {  0b11111,  0b10011,  0b10101,  0b10101,  0b10101,  0b10101,  0b10011,  0b11111 };
    static const byte TOO[8]  PROGMEM = {  0b00000,  0b00100,  0b00110,  0b11111,  0b00110,  0b00100,  0b00000,  0b00000 };

    static const byte* const CHAR_LIST[] PROGMEM = {OUTP, COAX, MUT, OPT, UPP, INPP, ANN, DNN, TOO };
    static const uint8_t PINS[] PROGMEM = { _forwardButton, _buttonPinUp, _muteButtonPin, _buttonPinDown, _auxButtonPin };

    static uint8_t* const    MODE_VALUES[] PROGMEM = { &_relaySource, &_relayRec, &_relaySourceDigi, &_recDigi };
    static const uint8_t     MAX_VALUES[] PROGMEM = { 7             , 4         , 7                , 3         };

    static const char* const RELAY_SOURCES[] PROGMEM = { "Line 1", "Line 2", "CD 1", "CD 2", "Tape 1", "Tape 2/DCC", "Tape 3/DAT", "MD", "MD" };

    static const char* const RELAY_SOURCE_DIGI_1[] PROGMEM = { "Sony 5-CD", "Sony MD[", "Optical 3", "Optical 4", "Philips CD-R [", "Coaxial 2", "Coaxial 3", "Coaxial 4" };
    static const int         RELAY_SOURCE_DIGI_2[]         = { 4          , 4         , -1         , -1         , 2               , -1        , -1         , -1          };
    static const char* const RELAY_SOURCE_DIGI_3[] PROGMEM = { "]"        , "]"       , ""         , ""         , "]"             , ""        , ""         , ""          };

    static const int         RELAY_REC_1[] PROGMEM = { 8      , -1   , 9       , 10      , 11       };
    static const char* const RELAY_REC_2[] PROGMEM = {"Source", "OFF", "Tape 1", "Tape 2", "Tape 3" };
    static const int         RELAY_REC_3[] PROGMEM = { -1     , -1   , 9       , 9       , 9        };
    static const char* const RELAY_REC_4[] PROGMEM = { ""     , ""   , "2,3"   , "1,3"   , "1,2"    };

    static const char* const DIGI_RELAY_SOURCES[] PROGMEM = { "Optical 1", "Optical 2", "Optical 3", "Optical 4", "Coaxial 1", "Coaxial 2", "Coaxial 3", "Coaxial 4" };

    void printAtCursor(int a, int b, const char* c)
    {
      _lcd.setCursor(a, b);
      _lcd.print(c);
    }

    void setup()
    {
      _lcd.begin(20, 4);
      _lcd.backlight();

      for (int n = 0; n < 9; n++)
      {
        _lcd.createChar(n + 1, (byte*) CHAR_LIST[n]);
      }

      for (int n = 0; n < sizeof(PINS) / sizeof(uint8_t); n++)
      {
        pinMode(PINS[n], INPUT);
      }

      for (int n = 11; n < 14; n++)
      {
        pinMode(n, OUTPUT);
      }

      printAtCursor(3, 0, "Digital/Analog");
      printAtCursor(3, 1, "Audio Selector");
      printAtCursor(4, 2, "Built-In DAC");
      printAtCursor(2, 3, "V2.0f (23052020)");
      delay(4000);
    }

    void setPin(int first, int last, int pin)
    {
      for (int n = first; n < last + 1; n++)
      {
        _shifter.setPin(n, pin == n ? HIGH : LOW);
      }

      _shifter.write();
    }

    void setLines(int a, int b, const char* t, int x = -1, const char* u = "")
    {
        _lcd.setCursor(0, a);
        _lcd.write(b);
        _lcd.setCursor(2, a);
        _lcd.print(t);

        if (x != -1)
        {
          _lcd.write(x);
          _lcd.print(u);
        }
    }

    void ResetShifter()
    {
      // _shifter.clear(); //set all pins on the shift register chain to LOW
      _shifter.write(); //send changes to the chain and display them
    }

    void ReadButtons()
    {
      _buttonPinUpState = digitalRead(_buttonPinUp) == HIGH;
      _buttonPinDownState = digitalRead(_buttonPinDown) == HIGH;
      _muteButtonPinState = digitalRead(_muteButtonPin) == HIGH;
      _auxButtonPinState = digitalRead(_auxButtonPin) == HIGH;
      _buttonPoll = digitalRead(_forwardButton) == HIGH;
    }

    void HandleAuxButton()
    {
      if (_auxButtonPinState && (_relaySource == 0) && (_mode == EMode::RELAY_SOURCE))
      {
        _aux = !_aux;
        digitalWrite(13, _aux ? HIGH : LOW);
      }
    }

    void HandlePollButton()
    {
      if (_buttonPoll)
      {
        _mode = (EMode) ((_mode + 1) % EMode::LAST_MODE);
      }
    }

    void StartLcd()
    {
      _lcd.clear(); // Happens in all cases
      _lcd.setCursor(1, (int) _mode);
      _lcd.write(5);
    }

    void HandleButtonPinUp()
    {
      if (_buttonPinUpState)
      {
        static uint8_t* const modeValue = MODE_VALUES[_mode];
        static uint8_t maxValue = MAX_VALUES[_mode];
        *modeValue = min(0, max(maxValue, *modeValue + (_buttonPinUpState ? 1 : 0) + (_buttonPinDownState ? -1 : 0)));
      }
    }

    void HandleMuteButton()
    {
      if (_muteButtonPinState)
      {
        _mute = !_mute;
        digitalWrite(12, _mute ? HIGH : LOW);
      }
    }

    void ProcessRelaySource()
    {
      // RelaySource
      setPin(0, 7, _relaySource);
      if (_relaySource == 0 && !_aux)
      {
        setLines(0, 7, "D", 9, "A:");
      }
      else
      {
        setLines(0, 7, RELAY_SOURCES[_relaySource]);
      }

      if (_relaySource == 7)
      {
        _shifter.setPin(0, LOW); //set pin 1 in the chain(second pin) HIGH
      }
    }

    void ProcessRelayRec()
    {
      setPin(8, 11, RELAY_REC_1[_relayRec]);
      setLines(1, 6, RELAY_REC_2[_relayRec], RELAY_REC_3[_relayRec], RELAY_REC_4[_relayRec]);
    }

    void ProcessRelaySourceDigi()
    {
      setPin(16, 23, 17 - _relaySourceDigi);
      if (_relaySource == 0 && !_aux)
      {
        _lcd.setCursor(7, 0);
        _lcd.print(DIGI_RELAY_SOURCES[_relaySource]);
      }
      setLines(2, 8, RELAY_SOURCE_DIGI_1[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_2[_relaySourceDigi - 1], RELAY_SOURCE_DIGI_3[_relaySourceDigi - 2]);
    }

    void ProcessRecDigi()
    {
      static const char* const t[] PROGMEM = { "Optical Out1", "Optical Out 2", "Coaxial Out 1", "Coaxial Out2" };
      setPin(12, 15, 12 + _recDigi);
      setLines(3, 6, t[_recDigi]);
      delay(150);
    }

    void loop()
    {
      ResetShifter();
      ReadButtons();

      HandleAuxButton();
      HandlePollButton();
      StartLcd();
      HandleButtonPinUp();
      HandleMuteButton();

      ProcessRelaySource();
      ProcessRelayRec();
      ProcessRelaySourceDigi();
      ProcessRecDigi();
    }


sender: user

message:
How to read data from ThingSpeak for esp8266

I am trying to read data from thingspeak for esp8266 but I couldn't do that. There is a link:
GET https://api.thingspeak.com/channels/123456/fields/1.json?api_key=***********&results=2
But how can I use it?

sender: assistant

body:
I directly code the esp8266 with thingSpeak library. Anyone who is interested look here:[How to read data from thingspeak][1]. And it worked. Thanks for your replies.

  [1]: https://electronics-project-hub.com/how-to-read-data-from-thingspeak-arduino-esp8266-nodemcu/


message:
Fading LED with different frequencies

I have a potentiometer attached to one analog port of arduino (assume A0)
I'm reading the value of that using ```input_voltage = analogRead (A0);``` which is a value between 0-1023.
So I want to map this value to frequency from 1Hz to 20Hz. Then I want to fade my LED using this frequency.
Tried to doing this map using ```int frequency = map (input_voltage, 0, 1023, 1, 20);```
But how can i apply this frequency to LED?
I mean PWM has a constant frequency (about 500Hz). How should I apply frequencies from 1 to 20 to this LED in order to fade it?

body:
There is a library in which you can change the frequency

Here is my example code I did long time ago I had the same problem

Get the library from [here][1]

Go ahead and try example code there and try to understand too.

**Include the library first to code**

my code

    void setup() {
      pinMode(13, OUTPUT);
      pinMode(8, OUTPUT);
      digitalWrite(8,LOW);
      Serial.begin(115200);
      InitTimersSafe();
    }
    void loop() {
      //mapping
      long x = map(analogRead(A0),0,1023,1,20);
      bool b = SetPinFrequencySafe(9,x);
      digitalWrite(13,b);
      pwmWrite(9,127);
      Serial.print(x);
      Serial.print(" Hz ");
      Serial.println(b);
      delay(100);
    }

Built in led will turn on if the frequency is stetted.

By the way led will turn on in 50% on and 50% off in one cycle in pin 9.

Use only the PWM pins in Arduino 3,9,6 etc.

Now you can change the PWM frequency...

*I just put a led in the female socket in for easiness + terminal in 9 and - terminal in 8 to go to ground that's why I did put pin 8 to low.*

  [1]: https://github.com/terryjmyers/PWM


message:
Arduino Atmega32U with nRF51 BLE by Adafruit limited to 5 second update rate?

Would like to ask for assistance with the code below.  It's the Adafruit Bluefruit Atmega32U LE module with Adafruit's Arduino IDE example "heart-rate monitor" sketch.   The code uses the hardware SPI setup with Adafruit's BLE code between the Atmega32U and the nRF51822 using AT Commands built into a BLE stack by Adafruit.

It works at the same speed in real-time on the PC's Arduino IDE USB serial terminal and also on the Android phone's nRF Connect app or any other BLE app that can read "notifications".

**Problem:  If remove the module from the PC's USB (thus the serial stopped and only using BLE) the update rate on the BLE Android app slows down to 5 second intervals compared to the near real-time speed while connected to USB.**   I tried many things, including commenting out the Serial commands  in the void loop() and also the delay(), but no change.  As if the BLE stack by Adafruit would have a update period limitation.  According to Adafruit, they do not give access to to their BLE stack.  But I could possibly load another BLE stack on this nRF51822 chip.   Also I do have the Adafruit Sniffer with Wireshark, but not an expert using it.

How can I get less than 1 second update rates?  The data stream is not in 1 second intervals. Maybe 10-15 seconds between readings, but I need it updated within 1 second of being read from the sensor.

https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le?view=all

```c++
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"

#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

// Create the bluefruit object, either software serial...uncomment these lines
/*
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(BLUEFRUIT_HWSERIAL_NAME, BLUEFRUIT_UART_MODE_PIN);

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

/* The service information */

int32_t hrmServiceId;
int32_t hrmMeasureCharId;
int32_t hrmLocationCharId;
/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  while (!Serial); // required for Flora & Micro
  delay(500);

  boolean success;

  Serial.begin(115200);
  Serial.println(F("Adafruit Bluefruit Heart Rate Monitor (HRM) Example"));
  Serial.println(F("---------------------------------------------------"));

  randomSeed(micros());

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  /* Perform a factory reset to make sure everything is in a known state */
  Serial.println(F("Performing a factory reset: "));
  if (! ble.factoryReset() ){
       error(F("Couldn't factory reset"));
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  // this line is particularly required for Flora, but is a good idea
  // anyways for the super long lines ahead!
  // ble.setInterCharWriteDelay(5); // 5 ms

  /* Change the device name to make it easier to find */
  Serial.println(F("Setting device name to 'Bluefruit HRM': "));

  if (! ble.sendCommandCheckOK(F("AT+GAPDEVNAME=Bluefruit HRM")) ) {
    error(F("Could not set device name?"));
  }

  /* Add the Heart Rate Service definition */
  /* Service ID should be 1 */
  Serial.println(F("Adding the Heart Rate Service definition (UUID = 0x180D): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDSERVICE=UUID=0x180D"), &hrmServiceId);
  if (! success) {
    error(F("Could not add HRM service"));
  }

  /* Add the Heart Rate Measurement characteristic */
  /* Chars ID for Measurement should be 1 */
  Serial.println(F("Adding the Heart Rate Measurement characteristic (UUID = 0x2A37): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A37, PROPERTIES=0x10, MIN_LEN=2, MAX_LEN=3, VALUE=00-40"), &hrmMeasureCharId);
    if (! success) {
    error(F("Could not add HRM characteristic"));
  }

  /* Add the Body Sensor Location characteristic */
  /* Chars ID for Body should be 2 */
  Serial.println(F("Adding the Body Sensor Location characteristic (UUID = 0x2A38): "));
  success = ble.sendCommandWithIntReply( F("AT+GATTADDCHAR=UUID=0x2A38, PROPERTIES=0x02, MIN_LEN=1, VALUE=3"), &hrmLocationCharId);
    if (! success) {
    error(F("Could not add BSL characteristic"));
  }

  /* Add the Heart Rate Service to the advertising data (needed for Nordic apps to detect the service) */
  Serial.print(F("Adding Heart Rate Service UUID to the advertising payload: "));
  ble.sendCommandCheckOK( F("AT+GAPSETADVDATA=02-01-06-05-02-0d-18-0a-18") );

  /* Reset the device for the new service setting changes to take effect */
  Serial.print(F("Performing a SW reset (service changes require a reset): "));
  ble.reset();

  Serial.println();
}

/** Send randomized heart rate data continuously **/
void loop(void)
{
  int heart_rate = random(50, 100);

  //Serial.print(F("Updating HRM value to "));
  //Serial.print(heart_rate);
 // Serial.println(F(" BPM"));

  /* Command is sent when \n (\r) or println is called */
  /* AT+GATTCHAR=CharacteristicID,value */
  ble.print( F("AT+GATTCHAR=") );
  ble.print( hrmMeasureCharId );
  ble.print( F(",00-") );
  ble.println(heart_rate, HEX);

  /* Check if command executed OK */
 // if ( !ble.waitForOK() )
 // {
   // Serial.println(F("Failed to get response!"));
  //}

  /* Delay before next measurement update */
 // delay(1000);
}

/////////////////AND BELOW IS THE BluefruitConfig.h TAB in ARDUINO IDE --This is a separate file under a new tab in the IDE////////////////..

    // COMMON SETTINGS
// ----------------------------------------------------------------------------------------------
// These settings are used in both SW UART, HW UART and SPI mode
// ----------------------------------------------------------------------------------------------
#define BUFSIZE                        128   // Size of the read buffer for incoming data
#define VERBOSE_MODE                   true  // If set to 'true' enables debug output

// SOFTWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins that will be used for 'SW' serial.
// You should use this option if you are connecting the UART Friend to an UNO
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SWUART_RXD_PIN       9    // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN       10   // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN         11   // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN         8    // Optional, set to -1 if unused

// HARDWARE UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the HW serial port you are using. Uncomment
// this line if you are connecting the BLE to Leonardo/Micro or Flora
// ----------------------------------------------------------------------------------------------
#ifdef Serial1    // this makes it not complain on compilation if there's no Serial1
  #define BLUEFRUIT_HWSERIAL_NAME      Serial1
#endif

// SHARED UART SETTINGS
// ----------------------------------------------------------------------------------------------
// The following sets the optional Mode pin, its recommended but not required
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_UART_MODE_PIN        12    // Set to -1 if unused

// SHARED SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for HW and SW SPI communication.
// SCK, MISO and MOSI should be connected to the HW SPI pins on the Uno when
// using HW SPI.  This should be used with nRF51822 based Bluefruit LE modules
// that use SPI (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_CS               8
#define BLUEFRUIT_SPI_IRQ              7
#define BLUEFRUIT_SPI_RST              4    // Optional but recommended, set to -1 if unused

// SOFTWARE SPI SETTINGS
// ----------------------------------------------------------------------------------------------
// The following macros declare the pins to use for SW SPI communication.
// This should be used with nRF51822 based Bluefruit LE modules that use SPI
// (Bluefruit LE SPI Friend).
// ----------------------------------------------------------------------------------------------
#define BLUEFRUIT_SPI_SCK              13
#define BLUEFRUIT_SPI_MISO             12
#define BLUEFRUIT_SPI_MOSI             11
```

body:
The "verbose" error check mode for debug in the "BluefruitConfig.h" tab slowed down the flow of BLE data. I changed it from "true" to "false" to turn it off.

```c++
#define VERBOSE_MODE true  // If set to 'true' enables debug output
```


message:
I'm trying to use a E18-D80NK but the output is always 1

i'm trying to use a E18-D80NK sensor with arduino but the output is always at 1, i really don't understand why
This is my code :

    int irPin2 = 8;// define pint 2 for sensor

    void setup() {
      Serial.begin(9600);// setup Serial Monitor to display information
      pinMode(irPin2, INPUT);// define pin as Input  sensor
    }

    void loop() {
      int out = digitalRead(irPin2);// read the sensor

        Serial.println(out);

      delay(250);
     // E18-D80NK Obstacle Sensor
    }

and circuit: [![E18-D80NK Obstacle Sensor][1]][1]

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

body:
There are a few possibilities for what is wrong:

1) The wiring may be wrong: the datasheet you reference lists two types (red,black,yellow) and (blue,brown,black) but in your pic it looks like you have (blue, grey, black).  I wouldn't assume the color coding of the sensor wires are correct.

2) The "pull-up" resister mentioned in the data sheet referenced (and included schematic) is not functioning as a pull-up resistor.  I would get rid of the resistor and plug the digital-output wire of the sensor directly into the arduino input.   Also, try configuring the input with pull-up like:  pinMode(irPin2, INPUT_PULLUP);
The Arduino inputs are high impedance and typically do not need a series resistor.


body: Your sensor pull low and not high, normally they pull high , I did however buy a few that is permanently on and then switch of ( pull low) when object in range.


message:
How to modify values inside a file

I am writing a wav file to an SD card on a ESP32 and that requires that every time I append data to the the end of the file I modify the header to set the right size in some fields.

I cannot find how to replace a value inside a file, I tried to write the new values with the seek function but unless I'm missing something looks like this deletes everything after the new value added.

I do not want to create a new file and to delete the old one as I will storing potentially large wav files and looks like wasting resources.

Is there a way to overwrite one value inside a file. I'm using **SDlib** but I'm open to others too.

Here the code I use to create the file and to update it:

    #include "WavFileWriter.h"

    void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
    {
      byte headerBuffer[44];
      wavFileHeader->getHeaderData(headerBuffer);
      File file = SD.open(filename, FILE_WRITE);
      file.write(headerBuffer, 44);
      file.close();
    }

    void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
    {
      File file = SD.open(filename, FILE_WRITE);
      file.write(data, dataLength);

      byte headerBuffer[44];
      wavFileHeader->setFileSize(file.size());
      wavFileHeader->getHeaderData(headerBuffer);

      file.seek(0);
      file.write(headerBuffer, 44);
      file.close();
    }

After calling appendData I end up with a file with just the header size (with the right header for a file with data but the data is gone).

body: SD.seek() is the API you're looking for.  It allow you to position the read/write pointer within a file.   In standard C++ the fseek() API is used.


body:
The `FILE_WRITE` in SD library is 'append' (for historical reasons)

    #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

so use

     File file = SD.open(filename, O_WRITE);


message:
Weird assembly output

I was taking a look at the disassembly for a loop of mine that seemed to be taking too long and I found these assembly instructions that I don't understand. Why does it load `0` into `r25` and then do two `adc r25, 25` instructions (which wouldn't do anything since `r25` is `0`). This is for an ATTiny84 by the way.

**EDIT**: In general I'm confused about why there are so many instructions required to set DDRA, DDRB, PORTA, and PORTB in the last loop. I feel like an `LD` to read portOuts[j], `OUT` to output, and increment of j should be all that's required. I've tried to separate what I think is the relevant part in the disassembly.

```
void loop() {
  set_sleep_mode(SLEEP_MODE_IDLE);
  button = false;
  DDRA = 0;
  DDRB = 0;
  PORTA = 255;
  PORTB = 255;
  do {
    sleep_mode();
  } while (!button);

//  int digits[4];
//  getTime(digits);
//
//  long lights = calcDisp(digits);
  static const byte highLow[28][2] = {{2, 0}, {2, 1}, {0, 3}, {1, 3}, {1, 0}, {3, 1}, {0, 1},
                                     {0, 2}, {3, 0}, {2, 4}, {3, 4}, {4, 3}, {0, 4}, {4, 0},
                                     {4, 1}, {1, 4}, {1, 5}, {5, 1}, {1, 2}, {5, 3}, {2, 3},
                                     {2, 5}, {5, 2}, {5, 4}, {4, 5}, {3, 5}, {4, 2}, {3, 2}};
  byte portOuts[112];
  byte nLed = 0;
  long lights = 0b00000000000000001111111111111111; // just a constant, for now
  for (byte b = 0; b < 16; ++b) {
    if (bitRead(lights, b)) {
      byte high = highLow[b][0];
      byte low = highLow[b][1];
      byte highA = regs[high][0];
      byte highB = regs[high][1];
      byte lowA = regs[low][0];
      byte lowB = regs[low][1];
      portOuts[4 * nLed] = (highA)|(lowA);
      portOuts[4 * nLed + 1] = (highB)|(lowB);
      portOuts[4 * nLed + 2] = (highA)|(1<<PA6);
      portOuts[4 * nLed + 3] = (highB);
      ++nLed;
    }
  }
  for (byte i = 0; i < 200; ++i) {
    for (byte j = 0; j < nLed * 4;) {
      DDRA = portOuts[j++];
      DDRB = portOuts[j++];
      PORTA = portOuts[j++];
      PORTB = portOuts[j++];
    }
  }
```

DISASSEMBLY
```
void loop() {
  set_sleep_mode(SLEEP_MODE_IDLE);
  button = false;
  DDRA = 0;
  DDRB = 0;
  PORTA = 255;
 228:   bb 24           eor     r11, r11
 22a:   ba 94           dec     r11
                                     {2, 5}, {5, 2}, {5, 4}, {4, 5}, {3, 5}, {4, 2}, {3, 2}};
  byte portOuts[112];
  byte nLed = 0;
  long lights = 0b00000000000000001111111111111111; // just a constant, for now
  for (byte b = 0; b < 16; ++b) {
    if (bitRead(lights, b)) {
 22c:   cc 24           eor     r12, r12
 22e:   ca 94           dec     r12
 230:   dc 2c           mov     r13, r12
 232:   e1 2c           mov     r14, r1
 234:   f1 2c           mov     r15, r1
  }
  return lights;
}

void loop() {
  set_sleep_mode(SLEEP_MODE_IDLE);
 236:   85 b7           in      r24, 0x35       ; 53
 238:   87 7e           andi    r24, 0xE7       ; 231
 23a:   85 bf           out     0x35, r24       ; 53
  button = false;
 23c:   10 92 a6 00     sts     0x00A6, r1      ; 0x8000a6 <button>
  DDRA = 0;
 240:   1a ba           out     0x1a, r1        ; 26
  DDRB = 0;
 242:   17 ba           out     0x17, r1        ; 23
  PORTA = 255;
 244:   bb ba           out     0x1b, r11       ; 27
  PORTB = 255;
 246:   b8 ba           out     0x18, r11       ; 24
  do {
    sleep_mode();
 248:   85 b7           in      r24, 0x35       ; 53
 24a:   80 62           ori     r24, 0x20       ; 32
 24c:   85 bf           out     0x35, r24       ; 53
 24e:   88 95           sleep
 250:   85 b7           in      r24, 0x35       ; 53
 252:   8f 7d           andi    r24, 0xDF       ; 223
 254:   85 bf           out     0x35, r24       ; 53
  } while (!button);
 256:   80 91 a6 00     lds     r24, 0x00A6     ; 0x8000a6 <button>
 25a:   88 23           and     r24, r24
 25c:   a9 f3           breq    .-22            ; 0x248 <main+0xec>
 25e:   ac e6           ldi     r26, 0x6C       ; 108
 260:   b0 e0           ldi     r27, 0x00       ; 0
 262:   90 e0           ldi     r25, 0x00       ; 0
 264:   80 e0           ldi     r24, 0x00       ; 0
  static const byte highLow[28][2] = {{2, 0}, {2, 1}, {0, 3}, {1, 3}, {1, 0}, {3, 1}, {0, 1},
                                     {0, 2}, {3, 0}, {2, 4}, {3, 4}, {4, 3}, {0, 4}, {4, 0},
                                     {4, 1}, {1, 4}, {1, 5}, {5, 1}, {1, 2}, {5, 3}, {2, 3},
                                     {2, 5}, {5, 2}, {5, 4}, {4, 5}, {3, 5}, {4, 2}, {3, 2}};
  byte portOuts[112];
  byte nLed = 0;
 266:   60 e0           ldi     r22, 0x00       ; 0
 268:   30 e0           ldi     r19, 0x00       ; 0
 26a:   20 e0           ldi     r18, 0x00       ; 0
 26c:   a9 01           movw    r20, r18
 26e:   44 0f           add     r20, r20
 270:   55 1f           adc     r21, r21
 272:   44 0f           add     r20, r20
 274:   55 1f           adc     r21, r21
  long lights = 0b00000000000000001111111111111111; // just a constant, for now
  for (byte b = 0; b < 16; ++b) {
    if (bitRead(lights, b)) {
 276:   26 01           movw    r4, r12
 278:   37 01           movw    r6, r14
 27a:   08 2e           mov     r0, r24
 27c:   04 c0           rjmp    .+8             ; 0x286 <__stack+0x27>
 27e:   75 94           asr     r7
 280:   67 94           ror     r6
 282:   57 94           ror     r5
 284:   47 94           ror     r4
 286:   0a 94           dec     r0
 288:   d2 f7           brpl    .-12            ; 0x27e <__stack+0x1f>
 28a:   40 fe           sbrs    r4, 0
 28c:   3d c0           rjmp    .+122           ; 0x308 <__stack+0xa9>
      byte high = highLow[b][0];
      byte low = highLow[b][1];
      byte highA = regs[high][0];
 28e:   ec 91           ld      r30, X
 290:   f0 e0           ldi     r31, 0x00       ; 0
 292:   ee 0f           add     r30, r30
 294:   ff 1f           adc     r31, r31
 296:   e0 5a           subi    r30, 0xA0       ; 160
 298:   ff 4f           sbci    r31, 0xFF       ; 255
 29a:   70 81           ld      r23, Z
      byte highB = regs[high][1];
 29c:   a1 80           ldd     r10, Z+1        ; 0x01
      byte lowA = regs[low][0];
 29e:   11 96           adiw    r26, 0x01       ; 1
 2a0:   ec 91           ld      r30, X
 2a2:   11 97           sbiw    r26, 0x01       ; 1
 2a4:   f0 e0           ldi     r31, 0x00       ; 0
      byte lowB = regs[low][1];
 2a6:   ee 0f           add     r30, r30
 2a8:   ff 1f           adc     r31, r31
 2aa:   e0 5a           subi    r30, 0xA0       ; 160
 2ac:   ff 4f           sbci    r31, 0xFF       ; 255
 2ae:   91 80           ldd     r9, Z+1 ; 0x01
      portOuts[4 * nLed] = (highA)|(lowA);
 2b0:   21 e0           ldi     r18, 0x01       ; 1
 2b2:   30 e0           ldi     r19, 0x00       ; 0
 2b4:   2c 0f           add     r18, r28
 2b6:   3d 1f           adc     r19, r29
 2b8:   24 0f           add     r18, r20
 2ba:   35 1f           adc     r19, r21
 2bc:   e0 81           ld      r30, Z
 2be:   7e 2e           mov     r7, r30
 2c0:   77 2a           or      r7, r23
 2c2:   f9 01           movw    r30, r18
 2c4:   70 82           st      Z, r7
      portOuts[4 * nLed + 1] = (highB)|(lowB);
 2c6:   e2 e0           ldi     r30, 0x02       ; 2
 2c8:   f0 e0           ldi     r31, 0x00       ; 0
 2ca:   ec 0f           add     r30, r28
 2cc:   fd 1f           adc     r31, r29
 2ce:   e4 0f           add     r30, r20
 2d0:   f5 1f           adc     r31, r21
 2d2:   2a 2d           mov     r18, r10
 2d4:   29 29           or      r18, r9
 2d6:   20 83           st      Z, r18
      portOuts[4 * nLed + 2] = (highA)|(1<<PA6);
 2d8:   e3 e0           ldi     r30, 0x03       ; 3
 2da:   f0 e0           ldi     r31, 0x00       ; 0
 2dc:   ec 0f           add     r30, r28
 2de:   fd 1f           adc     r31, r29
 2e0:   e4 0f           add     r30, r20
 2e2:   f5 1f           adc     r31, r21
 2e4:   70 64           ori     r23, 0x40       ; 64
 2e6:   70 83           st      Z, r23
      portOuts[4 * nLed + 3] = (highB);
 2e8:   24 e0           ldi     r18, 0x04       ; 4
 2ea:   30 e0           ldi     r19, 0x00       ; 0
 2ec:   2c 0f           add     r18, r28
 2ee:   3d 1f           adc     r19, r29
 2f0:   42 0f           add     r20, r18
 2f2:   53 1f           adc     r21, r19
 2f4:   fa 01           movw    r30, r20
 2f6:   a0 82           st      Z, r10
      ++nLed;
 2f8:   6f 5f           subi    r22, 0xFF       ; 255
 2fa:   26 2f           mov     r18, r22
 2fc:   30 e0           ldi     r19, 0x00       ; 0
 2fe:   a9 01           movw    r20, r18
 300:   44 0f           add     r20, r20
 302:   55 1f           adc     r21, r21
 304:   44 0f           add     r20, r20
 306:   55 1f           adc     r21, r21
 308:   01 96           adiw    r24, 0x01       ; 1
 30a:   12 96           adiw    r26, 0x02       ; 2
                                     {4, 1}, {1, 4}, {1, 5}, {5, 1}, {1, 2}, {5, 3}, {2, 3},
                                     {2, 5}, {5, 2}, {5, 4}, {4, 5}, {3, 5}, {4, 2}, {3, 2}};
  byte portOuts[112];
  byte nLed = 0;
  long lights = 0b00000000000000001111111111111111; // just a constant, for now
  for (byte b = 0; b < 16; ++b) {
 30c:   80 31           cpi     r24, 0x10       ; 16
 30e:   91 05           cpc     r25, r1
 310:   09 f0           breq    .+2             ; 0x314 <__stack+0xb5>
 312:   ac cf           rjmp    .-168           ; 0x26c <__stack+0xd>
 314:   68 ec           ldi     r22, 0xC8       ; 200
      portOuts[4 * nLed + 3] = (highB);
      ++nLed;
    }
  }

####################### START OF RELEVANT SECTION #############################

  for (byte i = 0; i < 200; ++i) {
    for (byte j = 0; j < nLed * 4;) {
 316:   41 15           cp      r20, r1
 318:   51 05           cpc     r21, r1
 31a:   99 f1           breq    .+102           ; 0x382 <__stack+0x123>
 31c:   30 e0           ldi     r19, 0x00       ; 0
 31e:   20 e0           ldi     r18, 0x00       ; 0
 320:   80 e0           ldi     r24, 0x00       ; 0
      DDRA = portOuts[j++];
 322:   e1 e0           ldi     r30, 0x01       ; 1
 324:   f0 e0           ldi     r31, 0x00       ; 0
 326:   ec 0f           add     r30, r28
 328:   fd 1f           adc     r31, r29
 32a:   2e 0f           add     r18, r30
 32c:   3f 1f           adc     r19, r31
 32e:   f9 01           movw    r30, r18
 330:   90 81           ld      r25, Z
 332:   9a bb           out     0x1a, r25       ; 26      STORE IN DDRA
 334:   e1 e0           ldi     r30, 0x01       ; 1
 336:   e8 0f           add     r30, r24
      DDRB = portOuts[j++];
 338:   21 e0           ldi     r18, 0x01       ; 1
 33a:   30 e0           ldi     r19, 0x00       ; 0
 33c:   2c 0f           add     r18, r28
 33e:   3d 1f           adc     r19, r29
 340:   2e 0f           add     r18, r30
 342:   31 1d           adc     r19, r1
 344:   f9 01           movw    r30, r18
 346:   90 81           ld      r25, Z
 348:   97 bb           out     0x17, r25       ; 23      STORE IN DDRB
      PORTA = portOuts[j++];
 34a:   e3 e0           ldi     r30, 0x03       ; 3
 34c:   e8 0f           add     r30, r24
    }
  }
  for (byte i = 0; i < 200; ++i) {
    for (byte j = 0; j < nLed * 4;) {
      DDRA = portOuts[j++];
      DDRB = portOuts[j++];
 34e:   a2 e0           ldi     r26, 0x02       ; 2
 350:   a8 0f           add     r26, r24
      PORTA = portOuts[j++];
 352:   21 e0           ldi     r18, 0x01       ; 1
 354:   30 e0           ldi     r19, 0x00       ; 0
 356:   2c 0f           add     r18, r28
 358:   3d 1f           adc     r19, r29
 35a:   2a 0f           add     r18, r26
 35c:   31 1d           adc     r19, r1
 35e:   d9 01           movw    r26, r18
 360:   9c 91           ld      r25, X
 362:   9b bb           out     0x1b, r25       ; 27      STORE IN PORTA
      PORTB = portOuts[j++];
 364:   8c 5f           subi    r24, 0xFC       ; 252
 366:   21 e0           ldi     r18, 0x01       ; 1
 368:   30 e0           ldi     r19, 0x00       ; 0
 36a:   2c 0f           add     r18, r28
 36c:   3d 1f           adc     r19, r29
 36e:   2e 0f           add     r18, r30
 370:   31 1d           adc     r19, r1
 372:   f9 01           movw    r30, r18
 374:   90 81           ld      r25, Z
 376:   98 bb           out     0x18, r25       ; 24      STORE IN PORTB
      portOuts[4 * nLed + 3] = (highB);
      ++nLed;
    }
  }
  for (byte i = 0; i < 200; ++i) {
    for (byte j = 0; j < nLed * 4;) {
 378:   28 2f           mov     r18, r24
 37a:   30 e0           ldi     r19, 0x00       ; 0
 37c:   24 17           cp      r18, r20
 37e:   35 07           cpc     r19, r21
 380:   84 f2           brlt    .-96            ; 0x322 <__stack+0xc3>   JUMP BACK TO START OF LOOP
 382:   61 50           subi    r22, 0x01       ; 1
      portOuts[4 * nLed + 2] = (highA)|(1<<PA6);
      portOuts[4 * nLed + 3] = (highB);
      ++nLed;
    }
  }
  for (byte i = 0; i < 200; ++i) {
 384:   41 f6           brne    .-112           ; 0x316 <__stack+0xb7>

        setup();

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
 386:   01 15           cp      r16, r1
 388:   11 05           cpc     r17, r1
 38a:   09 f4           brne    .+2             ; 0x38e <__stack+0x12f>
 38c:   54 cf           rjmp    .-344           ; 0x236 <main+0xda>
 38e:   38 de           rcall   .-912           ; 0x0 <__vectors>
 390:   52 cf           rjmp    .-348           ; 0x236 <main+0xda>```

body:
The compiler optimized the computation `nLed * 4` into a bit shift, as
`Led << 2`. It seems `nLed` is a single byte quantity. However,
`nLed * 4` may not fit in one byte, and the semantics of the language
demands that `nLed` is promoted to an `int` before the computation. This
is done by extending the variable by a byte of zeros:

```lisp
    ldi r25, 0
```

Now the register pair r25:r24 contains `nLed` extended to 16 bits.

Next step is to shift the whole thing left by two positions. This is
done by repeating this sequence twice:

```lisp
    lsl r24
    rol r25
```

The first instruction shifts r24 to the left. The most significant bit
is stored as the carry flag. The second instruction “rotate left through
carry”, is similar to a shift except that the rightmost bit position is
filled by the carry. This is the way to shift a 16-bit value without
loosing a bit.

The instruction `lsl` and `rol` are actually aliases of `add` and `adc`
respectively. The disassembler does not care about aliases, and
translates the machine code to the most “canonical” instructions, which
is what you see.


body: Simple: `adc` has three operands. You seem look at it as if it had two :)


message:
Quiescent Current Analog Input ESP8266

I'm planning an ESP8266 project, where I connect a soil moisture sensor to an ESP8266 chip (only the chip, not a board like the NodeMCU) (Analog Input). Since the whole setup will be battery-powered, I'm trying to minimize the quiescent current as much as possible. Now my question is: is there a quiescent current through the analog input pin of the ESP8266? and if yes, how large is this current approximately?

Thanks in advance

body:
That depends on if you're using a NodeMCU or a "naked" ESP8266.

The NodeMCU has a fixed voltage divider with 220K/100K resistors to ground, contributing about 10 µA to quiescent current (plus the much smaller current caused by the ADC input impedance).

If you're using a NodeMCU you also have to worry about the USB-to-Serial chip and the on-board voltage stabilizer.

The input impedance of the ADC input of a "naked" ESP8266 is (probably) a lot higher, 1 or more MΩ, although it is almost impossible to find definitive numbers.


message:
Getting error invalid conversion from 'const char*' to 'const uint8_t*

I have written this sketch, and I am trying to populate the array of wifi hotspots to  set the value in html select using javascript dynamically.

    #include <Arduino.h>
    #include <Hash.h>
    #include "ESP8266WiFi.h"
    #include <ESPAsyncTCP.h>
    #include <ESPAsyncWebServer.h>

    const char* ap_ssid     = "ESP8266";
    const char* ap_password = "0123456789";

    // Create AsyncWebServer object on port 8080
    AsyncWebServer ap_server(8080);

    const char index_html[] PROGMEM = R"rawliteral(
    <!DOCTYPE HTML>

      <meta name="viewport" content="width=device-width, initial-scale=1">

    )rawliteral";

    void setup() {
      Serial.print("Setting AP (Access Point)…");
      // Remove the password parameter, if you want the AP (Access Point) to be open
      WiFi.softAP(ap_ssid, ap_password);

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

      // Print ESP8266 Local IP Address
      Serial.println(WiFi.localIP());

      // Route for root / web page
      ap_server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
        request->send_P(200, "text/html", index_html, getWifiHotspots());
      });

      // Start server
      ap_server.begin();
    }

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

    }

But I am geting this error

        /Arduino/libraries/ESPAsyncWebServer/src/ESPAsyncWebServer.h:243:10: error:   initializing argument 4 of 'void AsyncWebServerRequest::send_P(int, const String&, const uint8_t*, size_t, AwsTemplateProcessor)' [-fpermissive]

         void send_P(int code, const String& contentType, const uint8_t * content, size_t len,
    AwsTemplateProcessor callback=nullptr);
              ^

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

body:
In the library ESPAsyncWebServer.h are these two possible function variants defined

      void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr);
       void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr);

So  when using

    const char index_html[] PROGMEM = R"rawliteral(<YOUR HTML here>)rawliteral";

give the compiler the explicit instruction

    ap_server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
      request->send_P(200, "text/html", (const uint8_t*) index_html, getWifiHotspots());
     });

The code compiles error free on ArduinoIDE 1.8.12/ESP8266 2.71/ NodeMCUv1 (as not having your definition of getWifiHotspots() I defined it as char)


message:
Reset HC-05 from within Arduino sketch

I have an HC-05 Bluetooth module attached to an Arduino Mega; the module is paired with a Raspberry Pi and fed data via a python program; there's roughly one send and one receive per second of about 35 bytes.

When I first power up the Arduino / HC-05, it flashes quickly, and then after pairing, it flashes twice every second indicating a successful pair & communication. All is good; data is flowing. Periodically (5 minutes? 3 hrs?) & unpredictably, the communication ends; I'm still trying to troubleshoot this; the python code on the RPi reports a not-helpful `OSError: [Errno 5] Input/output error` on the `available()` method of the `pySerialTransfer` library; though I welcome thoughts on that, I realize that question isn't for this forum.
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/.local/lib/python3.7/site-packages/pySerialTransfer/pySerialTransfer.py", line 416, in available
    if self.connection.in_waiting:
  File "/home/pi/.local/lib/python3.7/site-packages/serial/serialposix.py", line 467, in in_waiting
    s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
OSError: [Errno 5] Input/output error
```

The HC-05 module continues to flash as if it's connected, even though it is not, and even if I restart the python program, I'm unable to repair with the HC-05.  The only way I can figure out to reconnect to the HC-05 is to power the Arduino / HC-05; then I can reconnect.

So here is the question: is there to reset the HC-05 from within the Arduino sketch? I realize I could attach the VCC to a digital pin to do a full power cycle on the HC-05, but I believe the HC-05 draws on the outer limit of safe current for an Arduino (40ma); I could go thru a relay to do the disconnect, but I wonder if there's a cleaner way with fewer moving parts, or if that is indeed the best way?

Thanks for any guidance!

body: You could use a logic level MOSFET with low RDSon (e.g. IRLZ44) to switch the supply of the HC-05 and use a digital pin to control it.


message:
request for member 'attribute' in 'object', which is of non-class type 'int'

I am trying to create a basic snake game using the arduino UNO along with the MAX72XX module, the LCD module and the analog joystick module. I am wanting to program my program using object orientated programming. I have no experience with C++ so I am struggling quite a bit to understand what the following error is trying to say to me: `request for member 'following_direction' in 'snake[0]', which is of non-class type 'int'`.Here is the full code:

    #include "LedControl.h"
    #include <LiquidCrystal.h>
    LedControl lc=LedControl(12,10,11,1);
    LiquidCrystal lcd(8, 13, 3, 5, 6, 7);

    /*lcd.setCursor(0, 1);
      // print the number of seconds since reset:
      lcd.print(millis() / 1000);*/

    class Snake_body
    {
      //private:

      public:

        int following_direction;
        int body_length[64];
        int x;
        int y;
        int previous_x;
        int previous_y;

        Snake_body(int x_value, int y_value)
        {
          this->following_direction = 1;
          this->x = x_value;
          this->y = y_value;
          this->previous_y = y_value;
          this->previous_x = x_value;
        }
        /*void configure(int x_value, int y_value)
        {
          this->following_direction = 1;
          this->x = x_value;
          this->y = y_value;
          this->previous_y = y_value;
          this->previous_x = x_value;
        }*/

    };

    class Power_up
    {
      private:

      public:
        virtual void init()
        {
          this->x = 0;
          this->y = 0;
        }

        int x;
        int y;
    };

    int snake[64];
    int snakes_length;

    Snake_body *snake_body;
    Power_up *power_up;

    void setup() {

      lcd.begin(16, 1);

      snakes_length = 1;

      for(int z = 1; z < 64; z++)
      {
      snake[z] = 0;
      }

      snake[0] = new Snake_body(0,0);
      //Snake_body snake[0] = new Snake_body();
      //snake[0].configure(0,0);
      // put your setup code here, to run once:
      lc.shutdown(0,false);
      /* Set the brightness to a medium values */
      lc.setIntensity(0,8);
      /* and clear the display */
      lc.clearDisplay(0);

      pinMode(2, INPUT);
      digitalWrite(2, HIGH);

      Serial.begin(9600);
      power_up->x = random(0, 8);
      power_up->y = random(0, 8);
    }

    int snake_direction;

    void loop()
    {
      int x_axis = analogRead(A0);
      int y_axis = analogRead(A1);
      int switcher = digitalRead(2);

       if(x_axis <= 400) //&& x < 7)
       {
         snake[0].following_direction = 0;
         //x += 1;
         //Serial.println("right");
       }

       else if(x_axis >= 600) //&& x > 0)
       {
         snake[0].following_direction = 1;
         //x -= 1;
         //Serial.println("left");
       }

       else if(y_axis <= 400) //&& y > 0)
       {
         snake[0].following_direction = 2;
         //y -= 1;
         //Serial.println("up");
       }

       else if(y_axis >= 600) //&& y < 7)
       {
         snake[0].following_direction = 3;
         //y += 1;
         //Serial.println("down");
       }

      if(snake[0].following_direction == 0 && snake[0].x < 7)
      {
        snake[0].previous_x = snake[0].x;
        snake[0].x += 1;
      }

      else if(snake[0].following_direction == 1 && snake[0].x > 0)
      {
        snake[0].previous_x = snake[0].x;
        snake[0].x -= 1;
      }

      else if(snake[0].following_direction == 2 && snake[0].y > 0)
      {
        snake[0].previous_y = snake[0].y;
        snake[0].y -= 1;
      }

      else if(snake[0].following_direction == 3 && snake[0].y < 7)
      {
        snake[0].previous_y = snake[0].y;
        snake[0].y += 1;
      }

      for(int a = 1; a < 64; a++)
      {
        if(snake[i] != 0)
        {

          snake[i].x = snake[i-1].previous_x;
          snake[i].y = snake[i-1].previous_y;
        }
      }

      lc.setLed(0,power_up->x,power_up->y,true);
      for(int w = 0; w < 64; w++)
      {
        if(snake[w] != 0)
        {
          lc.setLed(0,snake[w].x,snake[w].y,true);
        }
      }

      if(snake[0].x == power_up->x && snake[0].y == power_up->y)
      {
        power_up->x = random(0, 8);
        power_up->y = random(0, 8);

        for(int i = 0; i < 64; i++)
        {
          if(snake[i] == 0)
          {
             Snake_body *snake[i];

             //next_snake_body = new Snake_body();
             snake[i] = new Snake_body(snake[i-1].previous_x, snake[i-1].previous_y);
             //Snake_body next_snake_body;
             //snake[i].configure(snake[i-1].previous_x, snake[i-1].previous_y);
          }
        }
      }
      /*Serial.print("x: ");
      Serial.print(snake.x);
      Serial.println();

      Serial.print("y: ");
      Serial.print(snake.y);
      Serial.println();*/

      if(switcher == 0)
      {
        delay(50);
      }
      else
      {
        delay(100);
      }
      lc.clearDisplay(0);
    }

the error is coming from this line here:

    else if(snake[0].following_direction == 3 && snake[0].y < 7)

but I think it is also happening at all other lines of which are similar to this one.

I have tried replacing the `.` in `snake[0].following_direction` with a `->` instead but that just caused the error: `base operand of '-> ' is not a pointer`. I have experience programming in java python and a few others but not arduino C++.

body:
The problem is indeed in that line:

    else if(snake[0].following_direction == 3 && snake[0].y < 7)

And specifically in:

    snake[0].following_direction

snake is defined as

    int snake[64];

Thus `snake[0]` is of type `int`.
And you cannot request the member `following_direction` from type.
Since you make new instances with:

    snake[0] = new Snake_body(0,0)

I assume `snake` should be an array of Snake_body.

So I suggest (at least) change the type to:

    Snake_body snake[64];

Just as a side note, I think one instance of Snake_body can take up like 16 bytes, and you make 64 of them, this results in 1,024 bytes which is half the memory of an Arduino Uno. Also, sometimes a library takes up some space, so keep this in mind if you are intending to add more libraries/global variables or stack space.

**Update**

Also the following line seems wrong:

    snake[0] = new Snake_body(0,0);

You already created 64 instances of Snake_body (and assigned to `snake`) after you do my change. So you do not need to do this yourself; actually you cannot, unless you create an array of POINTERS to `Snake_body`.


message:
How do I use a shift register with ioAbstraction?

I’m trying to combine [this][1] use of the shift register.
With the [ioAbstaction][2] library.

But I’m not sure how to read the buttons.

The help in the library seems to suggest more pins for writing than the tutorial for the buttons.

The end goal is to have three LEDs and the buttons connected through the
74HC595 shift register using a minimal number of Ardunio pins.

  [1]: https://www.instructables.com/id/Driving-Dozens-of-Buttons/
  [2]: https://github.com/davetcc/IoAbstraction

body:
The 74HC595 is a SerialToParallel shift register, mainly to have multiple outputs (SIPO).

You can abuse it to read multiple buttons by multiplexing:

Have one Arduino input pin and several output pins on the shift register to select the current button. This is what the instructables.com is showing.

No idea how that ioAbstraction library might help more than the Arduino-builtin `shiftOut()` function...


message:
Serial Read Data Loss With Arduino Nano

I am trying to use Serial reading from a python serial code (which is running on my Jetson Nano) in my project, but in some loop in my code, my data is receiving wrong.

 - I use Serial.readBytesUntil() function for interrupt-like reading.
 - I use standart blue mini-USB cable for communication.
 - My Arduino Nano also connected a nRF24L01 module with SPI.
 - Baudrate is 9600 for both devices. I tried 115200 but there is no difference.
 - The data loss is about  of all loops with both test codes (image-1, image-2).
 - There is no positive difference when I use RX/TX pins on both boards with level shifter.
 - When I use the test code in my main code with USB connection, the data loss increases P of all loops. But Arduino serial monitor is fine like image-3.
 - When I use the test code in my main code with RX/TX pins, Arduino serial monitor looks like image-4 and Arduino IDE gives error like image-5.

Here is my receiver test code on my Arduino Nano.
```
void setup() {

  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  while (!Serial) {}

}

void loop() {
  char buffer[4];
  int deger = 0;
  if (Serial.available() > 0) {
    int size = Serial.readBytesUntil('\n', buffer, 4);

    if (size == 4) {
      Serial.print("deger: ");
      Serial.write(buffer);
      Serial.print("  size: ");
      Serial.print(size);

      // Bytes to integer
      deger = (buffer[1] - 48) * 100 + (int(buffer[2]) - 48) * 10 + (buffer[3] - 48);
      if (buffer[0] == '1') {
        deger = -1*deger; }

      Serial.print(" Sayi: ");
      Serial.println(deger);
      }

    if (deger < 0) {
      digitalWrite(LED_BUILTIN, HIGH);
    }
    else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}
```

And the python serial transmitter test code.
```
import serial

ser = serial.Serial('/dev/ttyUSB0',baudrate=9600,timeout=10)
while True:
    hata = -58

    if hata > 0:
        hata = str(hata)
        if len(hata) == 2:
            hata = '00' + hata
        elif len(hata) == 1:
            hata = '000' + hata
        else:
                hata = '0' + hata    #Pozitive, Added 0
    elif hata < 0:
        hata = -1 * hata
        hata = str(hata)
        if len(hata) == 2:
            hata = '10' + hata
        elif len(hata) == 1:
            hata = '100' + hata
        else:
            hata = '1' + hata    #Negative, Added 1
    else:
        hata = str(hata)
        hata = '000' + hata

    # For every loop, sends 4 character and "\n"  Example: 1058\n
    gonder = hata + '\n'       # For readBytesUntil function
    ser.write(gonder.encode('utf-8'))
    print(gonder.encode('utf-8'))
```

image-1: Arduino test code serial monitor screenshot

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

image-2: Python test code serial terminal screenshot

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

image-3: Arduino main project code monitor with USB cable screenshot

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

image-4: Arduino main project code monitor with RX/TX pins on GPIO screenshot

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

image-5: Arduino main project code IDE error

[![enter image description here][5]][5]

So, what did i do wrong?
Thank you!

  [1]: https://i.stack.imgur.com/PjtHz.png
  [2]: https://i.stack.imgur.com/J5dNQ.png
  [3]: https://i.stack.imgur.com/jCmhI.png
  [4]: https://i.stack.imgur.com/GTeU4.png
  [5]: https://i.stack.imgur.com/Liaha.png

body:
You are overflowing your buffer, and also allowing garbage reads.

First you need 5 bytes for your buffer not 4, and you need to ensure it is zeroed out before using it. This is because you are treating it like a C string, which means it must b zero terminated.

Secondly your use of `Serial.readBytesUntil()` is flawed.  From the manual:

> The function terminates (checks being done in this order) if the determined length has been read, if it times out (see Serial.setTimeout()), or if the terminator character is detected (in which case the function returns the characters up to the last character before the supplied terminator).

You are sending 5 bytes (`1058\n`) but telling it to read up to 4. Which leaves the `\n` in the buffer. The next time through you read another 4 bytes, which gives you `\n` which is the terminating character.

If you must use `readBytesUntil` then you need to specify a buffer that is bigger than the whole string including the terminator so that the terminator always occurs before the maximum number of bytes read. Including the trailing zero you would thus need at least 6 bytes in your buffer, maybe a couple more "just in case" (one can never tell with Arduino API functions...)

So to roll it all up:

```
  char buffer[8]; // <- Bigger buffer
  memset(buffer, 0, 8); // <- Clear it out
  int deger = 0;
  if (Serial.available() > 0) {
    int size = Serial.readBytesUntil('\n', buffer, 7); // <- Tell it to read more leaving room for the terminating NULL
    ... etc ...
```

    if (size == 4) {


message:
what is causing my esp8266 setup function to reinitialise?

Here is code I have written:

    #include <stdio.h>
    #include <ESP8266WebServer.h>

    #define MAX_WIFI_INIT_RETRY 50
    #define WIFI_RETRY_DELAY 500

    const char* wifi_ssid = "ssid";
    const char* wifi_passwd = "password";

    ESP8266WebServer http_rest_server(80);

    const int numParams = 20;
    String params [numParams];

    String toString(String my_array[], int size)
    {
      String string;
      for (int i = 0; i < size; i++) {
        string = string + ", " + my_array[i];
      }
      return string;
    }

    int init_wifi() {
      int retries = 0;
      Serial.println("Connecting to WiFi AP..........");
      WiFi.mode(WIFI_STA);
      WiFi.begin(wifi_ssid, wifi_passwd);
      // check the status of WiFi connection to be WL_CONNECTED
      while ((WiFi.status() != WL_CONNECTED) && (retries < MAX_WIFI_INIT_RETRY)) {
        retries++;
        delay(WIFI_RETRY_DELAY);
        Serial.print("#");
      }
      return WiFi.status(); // return the WiFi connection status
    }

    void readParams(String (& params) [numParams])
    {
      int mn = WiFi.scanNetworks();
      for (int i = 0; i < mn; i++)
      {
        //    Serial.println(WiFi.SSID(i).c_str()); // prints name of all hotspots in serial monitor.
        params [i] = WiFi.SSID(i).c_str();
      }
    }

    void listHotspots() {
      String results = toString(params, sizeof(params));
      Serial.println(results);
      http_rest_server.send(200, "text/plain", results);
    }

    void config_rest_server_routing() {
      http_rest_server.on("/", HTTP_GET, []() {
        http_rest_server.send(200, "text/html",
                              "Welcome to the ESP8266 REST Web Server");
      });
      http_rest_server.on("/hotspots", HTTP_GET, listHotspots);
    }

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

      init_led_resource();

      WiFi.mode(WIFI_STA);
      WiFi.disconnect();
      readParams (params);

      if (init_wifi() == WL_CONNECTED) {
        Serial.print("Connetted to ");
        Serial.print(wifi_ssid);
        Serial.print("--- IP: ");
        Serial.println(WiFi.localIP());
      }
      else {
        Serial.print("Error connecting to: ");
        Serial.println(wifi_ssid);
      }

      config_rest_server_routing();

      http_rest_server.begin();
      Serial.println("HTTP REST Server Started");
    }

    void loop(void) {
      http_rest_server.handleClient();
    }

when I access the root url: i.e. `192.168.0.101/` It opens the root page fine, but when I try to open the `192.168.0.101/hotspots` It reboots the ESP8266  until the page stops to make a new attempts and I get nothing in result.

In the serial monitor I am seeing this exception when I try to visit the `ip/hotspot` page .

    Exception (9):
    epc1=0x4020148a epc2=0x00000000 epc3=0x00000000 excvaddr=0x4d2d5456 depc=0x00000000

    >>>stack>>>

    ctx: cont
    sp: 3ffffde0 end: 3fffffc0 offset: 01a0
    3fffff80:  3fffdad0 3ffee553 3ffee5a4 40201347
    3fffff90:  402086b8 6505a8c0 feefeffe feefeffe
    3fffffa0:  3fffdad0 00000000 3ffee5e0 40206614
    3fffffb0:  feefeffe feefeffe 3ffe8510 40100479
    <<<stack<<<

     ets Jan  8 2013,rst cause:4, boot mode:(3,6)

    wdt reset
    load 0x4010f000, len 1384, room 16
    tail 8
    chksum 0x2d
    csum 0x2d
    v8b899c12
    ~ld
    Connecting to WiFi AP..........
    ######Connetted to Hometelecom1N5E--- IP: 192.168.0.101
    HTTP REST Server Started

is it something wrong with the `toString` function ?

body:
When a program crashes, you can debug the crash based on the Fatal exception number.

     Exception (9)  Unaligned read/write operation addresses
         1. Unaligned read/write Cache addresses
         2. Wild pointers

This leads than as Juraj points out to a WD reset:

     rst:4     Hardware WDT reset

To get the exact part of the code paste the `>>>stack>>>` into the window of the espExeption decoder in the ArduinoIDE. [Details how to install and use](https://github.com/me-no-dev/EspExceptionDecoder).

My educated guess is that the heavy use of String class in combination with lot of String operations with the getHotspot function leads to heap corruption and crashes the Esp8266. Try defining fixed char arrays and get rid of the String class to get a stable running system. Post the espExeption decoder result as edit to your question if you thing something else might be fishy


message:
Mount arduino metro mini

I'm using an Arduino Metro Mini (for example https://www.adafruit.com/product/2590) in a project, and want to mount it so the micro USB socket is available through a hole in the case.

Is there an easy way to do this? The main difficulty is that the board has to be mounted end-on to the case, which means you need brackets, which also need standoffs since of course neither side of the board is entirely flat; and the screw holes are at the very end, so no space to spare between them and the case. Etc. If that's not clear, glance at the analogous HDMI mount linked below.

Adafruit sells a complete enclosure (https://www.adafruit.com/product/2709), and there's a similar printable one at https://www.thingiverse.com/thing:936519. I could glue that to the case and then put the mini in there. But that seems like overkill.

For some breakout boards Adafruit has a special panel mount (like the HDMI one at https://www.adafruit.com/product/3121) -- but nothing I see there or elsewhere for the metro mini.

Any better solutions out there? Closest i've seen here is https://arduino.stackexchange.com/questions/21603/mounting-arduino-in-an-enclosure

body:
What I've done for my projects is to get PC board standoffs of the right height, and use those to mount the board to the bottom of the case.

I measured the height of the USB connector and it's distance from the mounting holes, and calculated where to cut a hole in the side of the case for the USB connector.

I did not look up the USB specification for the depth/clearance of the connector - I just "guesstimated" and it worked fine.


message:
Serial printing from flash memory (F() macro, PROGMEM, sprintf_P, SPTR)

I have been testing various techniques on an Arduino Uno  for serial printing from flash memory instead of RAM. At the same time, I have been using the [freeMemory()][1] function from Adafruit.

I created a program that prints the word "test", with various methods:

### Simple print:

```
Serial.print("test");
Serial.print(freeMemory());
```

This call reports free RAM = 2267

### Using the F() Macro:

```
Serial.print(F("test"));
Serial.print(freeMemory());
```

This call reports free RAM = 2299

### Using sprintf_P()

```
char buf[100];
sprintf_P(buf,PSTR("test"));
Serial.print(buf);
Serial.print(freeMemory());
```
This call reports free RAM = 2267

### Using strcpy_P()

```
 char buf[100];
 strcpy_P(buf, (PGM_P)F("test"));
 Serial.print(buf);
Serial.print(freeMemory());
```

This call reports free RAM = 2267

### Using strcpy_P and const char[] PROGMEM

```
char buf[100];
const char buff[] PROGMEM = "test";
strcpy_P(buf, buff);
Serial.print(buf);
Serial.print(freeMemory());
```

This call reports free RAM = 2267

The basic point of this question is to gather ***all the possible flash memory printing*** techniques. Also it would be really useful if you could explain in detail what exactly each of the keywords F(), (PGM_P)F, PSTR, const PROGMEM does.

**IMPORTANT EDIT, 1:**

Depending on where and how I use the call `Serial.print(freeMemory());` the results change. For example, at the last example (PROGMEM, strcpy_P) when I included another `Serial.print(freeMemory());` before the call of the printing functions, then both freeMemory() calls report 2299!

Another interesting problem is that the freeMemory() reports 2299 as freeRam, while the SRAM of my Arduino Uno is only 2 kbytes.

**EDIT 2:**

Following the suggestion in comments, I changed "test" to "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttest". Now all different methods report a free ram of 2299, including the simple `Serial.print()`.

freeMemory():

    #ifdef __arm__
    // should use uinstd.h to define sbrk but Due causes a conflict
    extern "C" char* sbrk(int incr);
    #else  // __ARM__
    extern char *__brkval;
    #endif  // __arm__
    int freeMemory() {
      char top;
    #ifdef __arm__
      return &top - reinterpret_cast<char*>(sbrk(0));
    #elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
      return &top - __brkval;
    #else  // __arm__
      return __brkval ? &top - __brkval : &top - __malloc_heap_start;
    #endif  // __arm__
    }

  [1]: https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory

body:
> explain in detail what exactly does each of the keywords F(), (PGM_P)F, PSTR, const PROGMEM.

* `F()` wraps the string literal in `PSTR(...)` and then casts it to `__FlashStringHelper`.  This forces it to remain in flash and also gives it a type that the Arduino core can identify as a string in flash for overloading.
* `PGM_P` is a "Pointer to ProGraM mememory". This is the type that all the `_P` variants of functions require. It's basically `const char *` provided by `avr/pgmspace.h`
* `const PROGMEM` is actually two things. `const` means you're not changing the value, and `PROGMEM` is another name for `__ATTR_PROGMEM__` which itself is an alias for `__attribute__((__progmem__))` which is a flag for the compiler to tell it to keep the variable in flash and not copy it to RAM.

So `F()` and `PGM_P` are used when you are passing a string literal to a function that expects one of those formats. `PROGMEM` is used when you're setting up a constant "variable" (oxymoron there, I know...) that points to data in flash.


body:
First, the [freeMemory()](https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory) function that you used from Adafruit was originated from a [GitHub repository](https://github.com/mpflaga/Arduino-MemoryFree).

I don't know about the `__arm__` implementation, but for the AVR one, it is incomplete for handling the corner case when the program does not use the `malloc()` function. If your program never uses `malloc()`, the formula used in `freeMemory()` will produce the wrong result. A simple corrected version for AVR that I used is here:

    extern unsigned int __heap_start;
    extern char *__brkval;

    int freeMemory() {
      char top_of_stack;

      if (__brkval == 0) {
        Serial.println(((int)&top_of_stack - (int)&__heap_start));
      } else {
        Serial.println((int)&top_of_stack - (int)__brkval);
      }
    }

> explain in detail what exactly does each of the keywords F(), (PGM_P)F, PSTR, const PROGMEM.

### PSTR("string literal")

PSTR came into Arduino from part of *avr-libs* (a C library) defined in [avr/pgmspace.h](https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html). It is actually a macro, not a function as many think it was, and is defined as:

    #define     PSTR(s)   ((const PROGMEM char *)(s))

It looks a little bit intimidating, but it is actually quite simple. It not only tells the *avr-gcc* that the string literal `s` should be kept in program memory (i.e., flash memory in the case of Arduino), but it allows the program to convert it into a `const char *s PROGMEM` variable, so that it can be pass around into some PROGMEM-aware functions as a parameter.

     // This is a PROGMEM-aware function in C
     printMsg_P(const char* str) {
         char buf[strlen_P(str)+1];
         strcpy_P(buf, str);
         puts(buf);
     }

     // This handles the normal string array function
     printMsg(const char* str) {
         puts(str);
     }

### F("string literal")

`F()` is also a macro, but it is not part of the `avr/progmem.h`. It is actually part of the *String* class defined in [WString.h](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/WString.h#L37-L38) together with a definition of a class called `__FlashStringHelper`:

    class __FlashStringHelper;
    #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

To understand the `F()` macro and the difference between `F()` and `PSTR()` take a little bit explanation.

As you can see from the definition of `F()`, it casts a string literal into a `const char*` variable using `PSTR()`, and then recast it into a class `__FlashStrngHelper`. If you further look at the `__FlashStringHelper`, it is actually an empty class without any construct or method. It is literally empty, so why is this useful? And why can't it just pass the string literal around by just using `PSTR()`?

This has to do with C++'s function overload. Function overload is a feature of C++ where multiple methods could have the same function name, but each with different parameters. Within all the `Serial.print()` methods, there is a method `Serial.print(const char* str)` that will take in a string literal and print it to serial monitor, but it is not PROGMEM-aware. If you pass in a PROGMEM string literal `Serial.print(PSTR("string literal"));`, the same method will accept what you pass in because it meet the type checking (remember `PSTR` is actually `const char*`), but it will not print out the correct string for `PSTR("string literal")`, because it simply expecting a normal string.

In C, as we see before, we solve the problem by using two functions with different names for handling normal string and PROGMEM string, but `Serial` is a C++ class. It needs another function overloaded method to be PROGMEM-aware, and PSTR() is clearly not the solution as we just mentioned.

*WSting.h* and *Print.cpp* create an overload method that is PROGMEM-aware by accepting a class as parameter, so that you can pass a `F()` wrapped string literal which has a data type of class `__FlashStringHelper` into the `Serial.print()` and get the print out correctly from program memory. See the [source code](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Print.cpp#L44-#L55) yourself.

    Serial.print(const __FlashStringHelper *ifsh)

So in summary, the `F()` and `PSTR()` are alike. Both are telling the compiler to keep the string literal in the program memory, and allow the string literal to be pass around into some function as parameter. But it was designed for different purpose from different programming paradigm (C versus C++). `F()` is `Serial.print()`-friendly, while `PSTR()` is not. If you are getting `PSTR()` in a function and yet you want to send it to `Serial.print()`, you will have to explicitly cast it into `__FlashStringHelper` like this:

    Serial.print((__FlashStringHelper*)PSTR("test"));

### PGM_P

`PGM_P` is a macro defined as:

    #define     PGM_P   const char *

Whether you want to use `PGM_P` or `const char *` is a personal preference. For example, this is copy from *[PROGMEM][1]* (Arduino reference):

    const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

can be written as:

    PGM_P const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

This is a lengthy explanation, but I hope this will help with better understanding the subject and therefore be able to use the PROGMEM and all the associated macros effectively.

  [1]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/


message:
How can I identify GPS sattelites in TinyGPS++?

I can see about 15 satellites (about 10 GPS + 5 Glonass) in u-center, but I see only about 10 satellites using TinyGPS++. I suspect that TinyGPS++ can see GPS only. I see lines containing $GNRMC $GNVTG $GNGGA $GPGSV $GNGLL $GNVTG $GLGSV in the input, so there are information from both constellation. But how can I check which constellations TinyGPS++ takes into account for the output:

> Sats=10 Nums=1 3 8 10 11 14 20 22 24 27 28 31 32 36 40  Elevation=46
> 17 45 31 69 59 1 43 5 24 9 1 60 36 32  Azimuth=304 255 215 66 267 137
> 77 263 28 184 316 140 89 181 150  SNR=12 0 0 17 8 20 0 11 0 11 0 0 21
> 0 0

body:
There is a bug in TinyGPS++ as it only counts GPS satellites. See https://github.com/mikalhart/TinyGPSPlus/issues/52

PRN numbers are used to identify satellites:

> GPS = 1 to 32
>
> SBAS = 33 to 64 (add 87 for PRN number)
>
> GLO = 65 to 96


message:
HC-05 master and slave

I have a silly question that came to my mind
when communicating between HC-05 and A smartphone, the smartphone is considered as the master,
and the HC-05 is considered a slave.
master will send data to the slave and then the slave will send these data to the MCU.
my question here is that, what is the MCU considered if it is not a master or slave?
if I got something wrong, I'll be glad if you correct it for me.
thank you

body:
You have a misconception about the interfaces involved. Actually we have 2 different interfaces here: Bluetooth and Serial (UART). The HC-05 is a Bluetooth Serial bridge.

The Bluetooth interface has a fixed concept of master and slave. Every connection needs to have only 1 single master. This concept applies only to the communication between HC-05 and the smartphone. It has nothing to do with the MCU itself, because the MCU does not do any Bluetooth communication.

The second interface is the Serial (UART) interface between the HC-05 and the MCU. For this interface there is no concept of master/slave, because it is not needed. Either of them can send independently on their corresponding TX pin and can receive on their RX pin.

These are two totally independent and different communication interfaces. The HC-05 just forwards data between the interfaces.


message:
Hardware/software serial for HC-05

can anyone please tell me the whole difference between hardware and software serial for the HC-05.
I read UART,USB cable, serial and I was like really confused
so what is the difference and advantages between both?
thank you...

body:
Hardware serial uses pins 0/1 on the Uno. You can't change those pins. Those pins are also the pins that are used to communicate with your computer. You can use hardware serial on those pins to communicate with the HC-05 *only* if you don't want to communicate with your computer.

SoftwareSerial can be used on any pins so can be used at the same time as the hardware serial for communicating with your computer. However SoftwareSerial is somewhat limited in what it can do.

Bigger boards (such as the Mega) usually have more than one hardware serial port. These are connected to the TX1/RX1, TX2/RX2 etc pins. These are the preferred method of connecting to external serial devices since they work more reliably that SoftwareSerial and concurrently with the computer's USB connection.


body:
- **Hardware vs Software Serial:** Most microcontrollers/Arduinos have at least 1 hardware Serial interface. That means, that for this Serial interface the actual communication protocol (the transmission and receiving of the actual data) is implemented in dedicated hardware inside the microcontroller (which also means there are fixed pins, where you can connect to them on the board). That way you don't need code for doing the complex communication protocol. Instead the main CPU is only involved to handle the received and to-be-transmitted data, which need to be placed in a buffer register. The dedicated hardware then automatically sends and received the data.

    As the number of hardware Serial interfaces is limited and fixed for the Arduino board/microcontroller, it happens, that you need more Serial interfaces, than you have in hardware on your board/in your microcontroller. Then you can use `SoftwareSerial`. That is a library, which handles the complete communication protocol in software, by directly setting and reading the electrical pin states according to the protocol. The advantage is, that you can use this on any digital pins for such an interface. Disadvantage is, that doing such things in software is complex. You can only listen on 1 `SoftwareSerial` interface at a time and the baudrate is limited (depending on the actual used microcontroller, e.g. it's frequency).

- **UART vs Serial:** UART is the technical term for the used communication interface. `Serial` is an Arduino term, which is not used that way in other contexts. The real interface type is UART and the Arduino framework just names that `Serial` to make it simpler.

- **Connecting over USB cable or pins:** Let's take the Arduino Uno as example. It has 1 hardware serial interface. This interface is connected to the pins 0 and 1 (RX and TX), but also internally to an extra chip. That chip handles the USB connection and behaves as a USB-Serial bridge. When communicating with the Serial Monitor in the Arduino IDE, you are actually using this USB-Serial bridge to talk to the microcontroller on the Arduino. But you could also use the RX/TX pins to do that.


message:
Running a motor for a 3 seconds continuously with and without interrupt

I have interfaced a dc motor and IR sensor to my nano. The DC motor is supposed to run only if the IR sensor detects an obstacle. Now, I'm trying to get the motor to turn off if continuously obstructed for 3 seconds, and exit the interrupt (in case of the first code with interrupt), and again wait for the sensor to go low again (falling edge). I have implemented this using millis(), but the code doesnt seem to be working consistently, as the timing seems to have gone for a toss (random behavior; sometimes it keeps running continuously and sometimes it stops) . Can anyone on this forum please review it and suggest me a correction. Also, would it be possible to use a LOW trigger instead of falling edge to achieve this ?

    #include <LowPower.h>

    const int out1 = 5; //motor
    const int IRSensor = 3; // connect ir sensor to arduino pin 6
    const int LED = 6; // conect Led to arduino pin 9
    const int Switch = 2;
    const int Mspeed = 175;//0-255
    const int Mtime =1500;//500-1000
    int statusSensor=1;
    int switchSensor=1;
    unsigned long prevTime;
    volatile int count =0;
    volatile int count1=0;
    volatile int count2 =0;
    volatile int count3=0;
    volatile int buttonstate=0;
    volatile int lastbuttonstate=0;
    volatile bool flag=false;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(out1,OUTPUT);
      //pinMode(out1,OUTPUT);
      pinMode (IRSensor, INPUT); // sensor pin INPUT
      pinMode (LED, OUTPUT); // Led pin OUTPUT
      pinMode(Switch, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(IRSensor),IRinterrupt,FALLING);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      LowPower.powerDown(SLEEP_FOREVER , ADC_OFF, BOD_OFF);
      delay (100);
      if (flag==true){
      //Serial.println("true");
      switchSensor = digitalRead (Switch);
      //Serial.println ("zloop");

      statusSensor = digitalRead (IRSensor);
      //Serial.println (statusSensor);
      if (count1==1)
      { prevTime = millis();
        Serial.println(prevTime);
      }
      if (millis() - prevTime >= 1000)
      { doSomethingElse();
        Serial.println("going to else");
      }
      }
      //prevState = digitalRead(IRSensor);
      doSomething();

    }

    void IRinterrupt(){

       flag=true;
      }

    void doSomething(){
      buttonstatus();
      if (statusSensor == 0 and switchSensor == 0 and count3==0){

         analogWrite(out1,Mspeed);
         //digitalWrite(out1,HIGH);
         count1=count++;
         Serial.println(count);
         digitalWrite(LED, LOW);
      }
       else if (statusSensor == 0 and switchSensor == 1) {

          //digitalWrite(out1,LOW);
          digitalWrite(LED, HIGH);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          }
       else if (statusSensor == 1 and switchSensor == 0) {

          //digitalWrite(out1,LOW);
          digitalWrite(LED, LOW);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          }
        else {
          //Serial.println ("ir high");
          //digitalWrite(out1,LOW);
          digitalWrite(LED, HIGH);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          buttonstatus();
          }
    }
    void doSomethingElse(){

          //Serial.println ("ir high else");
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          count2++;
          count3=count2;

          //analogWrite(out1,0);
      }

    void buttonstatus(){
      buttonstate=digitalRead (IRSensor);
       if (buttonstate != lastbuttonstate) {
        // if the state has changed,
        if (buttonstate == LOW) {
          count3=0;
        }
        delay(50);
       }
       lastbuttonstate = buttonstate;
    }

I have written another piece of code without interrupts. How do I achieve the same timing part for this too ?

    int out1 = 5; //motor
    int IRSensor = 3; // connect ir sensor to arduino pin 6
    int LED = 6; // conect Led to arduino pin 9
    int Switch = 2;
    int statusSensor=1;
    int switchSensor=1;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(out1,OUTPUT);
      //pinMode(out1,OUTPUT);
      pinMode (IRSensor, INPUT); // sensor pin INPUT
      pinMode (LED, OUTPUT); // Led pin OUTPUT
      pinMode(Switch, INPUT_PULLUP);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      switchSensor = digitalRead (Switch);
      //Serial.println (switchSensor);

      statusSensor = digitalRead (IRSensor);
      //Serial.println (statusSensor);
      delayStart = millis();
      //Serial.println ("ir interupt");

       if (statusSensor == 0 and switchSensor == 0){
         Serial.println ("ir low");
         analogWrite(out1,120);
         digitalWrite(LED, LOW);
       }
          else {
          Serial.println ("ir high");
          analogWrite(out1,0);

          }

    }

EDIT: I have now successfully implemented the code (without interupts) with timing part in the code below.Also, I have updated the first code in the post with interrupts, but I am not able to get the timing part working. Can, someone please help me how timing can now be done with interrupts, so that the arduino nano is in sleep, until it receives a falling edge on the interrupt pin from the IR sensor, so that it can process the next part. Doing so I believe I would save power consumed since its on all the time.

    const int out1 = 5; //motor
    const int IRSensor = 3; // connect ir sensor to arduino pin 6
    const int LED = 6; // conect Led to arduino pin 9
    const int Switch = 2;
    const int Mspeed = 175;//0-255
    const int Mtime =1500;//500-1000
    int statusSensor=1;
    int switchSensor=1;
    unsigned long prevTime;
    volatile int count =0;
    volatile int count1=0;
    volatile int count2 =0;
    volatile int count3=0;
    volatile int buttonstate=0;
    volatile int lastbuttonstate=0;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(out1,OUTPUT);
      pinMode (IRSensor, INPUT); // sensor pin INPUT
      pinMode (LED, OUTPUT); // Led pin OUTPUT
      pinMode(Switch, INPUT_PULLUP);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      delay(100);
      switchSensor = digitalRead (Switch);
      statusSensor = digitalRead (IRSensor);
      if (count1==1)
      { prevTime = millis();
        Serial.println(prevTime);
      }
      if (millis() - prevTime >= Mtime)
      { doSomethingElse();
        //Serial.println("going to else");
      }
      doSomething();

    }

    void doSomething(){
      buttonstatus();
      if (statusSensor == 0 and switchSensor == 0 and count3==0){

         analogWrite(out1,Mspeed);
         //digitalWrite(out1,HIGH);
         count1=count++;
         Serial.println(count);
         digitalWrite(LED, LOW);
      }
       else if (statusSensor == 0 and switchSensor == 1) {

          //digitalWrite(out1,LOW);
          digitalWrite(LED, HIGH);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          }
       else if (statusSensor == 1 and switchSensor == 0) {

          //digitalWrite(out1,LOW);
          digitalWrite(LED, LOW);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          }
        else {
          //Serial.println ("ir high");
          //digitalWrite(out1,LOW);
          digitalWrite(LED, HIGH);
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          buttonstatus();
          }
    }
    void doSomethingElse(){

          //Serial.println ("ir high else");
          analogWrite(out1,0);
          count=0;
          count1=0;
          prevTime = millis();
          count2++;
          count3=count2;

          //analogWrite(out1,0);
      }

    void buttonstatus(){
      buttonstate=digitalRead (IRSensor);
       if (buttonstate != lastbuttonstate) {
        // if the state has changed,
        if (buttonstate == LOW) {
          count3=0;
        }
        delay(50);
       }
       lastbuttonstate = buttonstate;
    }

body:
I often use a timer loop to read sensors. I've attached some code, which compiles, however I don't have the sensor.

BTW. I am assuming it is a single shot IR sensor that returns 0 if something is detected.

    int out1 = 5; //motor
    int IRSensor = 3; // connect ir sensor to arduino pin 6
    int LED = 6; // conect Led to arduino pin 9
    int Switch = 2;
    int statusSensor=1;
    int switchSensor=1;

    unsigned long IRMillis;
    int IRInterval = 100;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(out1,OUTPUT);
      //pinMode(out1,OUTPUT);
      pinMode (IRSensor, INPUT); // sensor pin INPUT
      pinMode (LED, OUTPUT); // Led pin OUTPUT
      pinMode(Switch, INPUT_PULLUP);
      IRMillis = millis();
    }

    void loop() {

       updateIR();

       switchSensor = digitalRead (Switch);

       if ((statusSensor == 0) && (switchSensor == 0)) {
         IRInterval = 3000; // 3 seconds
         statusSensor = 1;
         Serial.println ("ir low");
         analogWrite(out1,120);
         digitalWrite(LED, LOW);
       } else {
         Serial.println ("ir high");
         analogWrite(out1,0);
       }
    }

    void updateIR() {
      if (millis() - IRMillis > IRInterval) {
        //continue
      } else {
        return;
      }
      IRMillis = millis();
      IRInterval = 100;
      statusSensor = digitalRead (IRSensor);
    }