message:
Use lowpower-libary and still use serial connection and other things

I managed to get the LowPower libary working on my Arduino Micro. This code works perfectly:

    #include <LowPower.h>

    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_BUILTIN, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
    }

However. I also tried it with a serial connection, to put out some text periodically. But I think the lowpower-libary does - in order to save power - disable this function. So now I am worried that it also disables some other things I might have to use but won't work. Like OneWire or I2C. It also would be nice to work with a functioning standby-mode while developing where serial output is vital, altough it's not neccessary, because I can simulate it with a simple delay. So my question is: How can I use the lowpower-libary AND have a serial connection. And will this libary affect OneWire or I2C? If so: Is there a way on how to keep these "services" running? Or is there maybe another libary wich also saves power in a similar way, but where you have more abilities to customize what you want to have shut down?

body:
Yes, activating low power does disable the UART - but only *while* it's sleeping.

To use serial you just need to ensure that you only use it while it's not sleeping - and due to the interrupt and buffered nature of the Serial driver it's not as easy as just printing.

However, it's simple to achieve: just `flush` the serial before sleeping. This ensures that any pending serial data is sent out through the serial port before you go to sleep:

    void loop() {
      Serial.println("Turning LED on");
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      Serial.flush();
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
      Serial.println("Turning LED off");
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      Serial.flush();
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
    }

If that doesn't help you may need to turn serial off and on yourself either side of your powerdown:

    void loop() {
      Serial.begin(115200);
      Serial.println("Turning LED on");
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      Serial.flush();
      Serial.end();
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                      // wait for a second
      Serial.begin(115200);
      Serial.println("Turning LED off");
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      Serial.flush();
      Serial.end();
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);                  // wait for a second
    }

----

Update:

I just noticed you're using the Micro. That makes a big difference. The Micro and the Leonardo's `Serial` object is actually a USB CDC/ACM serial emulation, not UART.  You cannot sustain a USB connection while sleeping. So it will be killed.

To use communication while sleeping you will have to switch to a proper UART connection with a USB to TTL UART (e.g., FT232RL) adaptor to connect to the TX/RX pins and use `Serial1` instead.


sender: user

message:
Why are Arduino timer registers not 0?

I'm trying to use the timer registers to do some timing on my Arduino Mega 2560.

The output of the following code confuses me:

    void setup ()
    {
        // Set up serial connection
        Serial.begin(9600);
        while (!Serial) {}

        // Print control registers of timer 1
        Serial.println(TCCR1A); // Outputs 1
        Serial.println(TCCR1B); // Outputs 3
    }

    void loop () {}

Why is `TCCR1A` equal to `1` and `TCCR1B` equal to `3`? The documentation of the chip says the initial values of the registers are zero. I could of course set them to zero, but I want to understand why it works like this. The values are the same for the other 16-bit timers (3, 4 and 5).

sender: assistant

body:
The Arduino core does things at startup. One of those things is to configure the timers ready for PWM operation.

Here's the relevant bits from `init()` in `wiring.c`:

        // set timer 1 prescale factor to 64
        sbi(TCCR1B, CS11);
    #if F_CPU >= 8000000L
        sbi(TCCR1B, CS10);
    #endif

    #if defined(TCCR1A) && defined(WGM10)
        sbi(TCCR1A, WGM10);
    #endif


message:
Can I connect Multiple Devices to One 5V and one GND pin of my Arduino Uno R3

I have made a Bluetooth Controlled Robot Car. Using L298N Motor Driver, HC-05 Bluetooth Module and Arduino R3 I was able to run it by giving one "VIN" and one "GND" to L298N, one "5V" and one "GND" to HC-05 and I gave 12V input to the Arduino Board.
But now I want upgrade it to an upper level by adding IR transceiver as obstacle sensor and a buzzer (as a horn, such that it will sound whenever any obstacle is sensed OR I'll set a button in the GUI to play the horn)
Please Help me. I am a very beginner and assume it as my first project.
Any kind of help would be appreciated.
Thanks in advance.

body:
Yes, you can connect multiple devices to GND and +5 V. You may find that you need to bring one wire from the PCB to an external connector or piece of stripboard so that you can make more reliable connections.

Watch that your total current does not exceed the rating for the voltage regulator or USB power supply.


message:
Where does arduino IDE store the latest board selection?

I'm building a tool to help me automate my uploading process. How do I know where Arduino stores the current preferences - which board, which com port, what serial speed?

If devs are familiar with using multiple boards in the same system ithey'd know it would be really handy to be able to change that

body:
It is stored in `preferences.txt` in your Arduino data folder.

You can find more about that file, including where to find it, [here](https://www.arduino.cc/en/Hacking/Preferences).

Some of the keys you may be interested in are:

* board=uno
* serial.port=COM3
* serial.debug_rate=115200

However maybe for your workflow the Arduino IDE isn't the best tool for the job.  You may consider `arduino-builder`, which is the back-end that the Arduino IDE uses to do the actual compiling, or maybe another IDE entirely, such as PlatformIO or UECIDE.


message:
Send out a short signal every 10 seconds to an arduino

In order to reduce power consumption, I want to resume my Arduino from standby mode every 10 seconds. For this a hardware interrupt is necessary.

Is there such a device that can create a quick impulse to trigger that interrupt? It can be anything from 10ms to 2 seconds; doesn't matter. My first thought was to use a 555 timer, but this one can only be on for 10 seconds and off for the same amount of time.

The best solution for me would be an already assembled device that I just have to wire with my Arduino since my knowledge in electronics is very low. Or a detailed assembly plan, then I would be able to build it myself I guess?

**UPDATE:** I was now able to put the Arduino into standby-mode using the [Low-Power library][1]. At first it seemed like it didn't work, because I wanted to print out a text over the serial connection. Instead, I tried to let the internal LED blink every 8 seconds, and this works perfectly.

  [1]: https://github.com/rocketscream/Low-Power/

body:
A 555 doesn't have to generate a 50% duty cycle. Even if you do want to use a 50% duty cycle, the edge can be RC coupled into the interrupt to reduce the pulse width.

An Arduino can use a slow clock like a 32kHz watch crystal, then it's very low power indeed. This slow one can be used to wake-up your more power-hungry Arduino.

The lowest power and tidiest external solution would be to use a [CD4060](http://www.ti.com/lit/ds/symlink/cd4060b.pdf). These are designed to be very low power, very long period timing devices.

The correct way to do it is to use the internal [Watchdog Timer](http://donalmorrissey.blogspot.com/2010/04/sleeping-arduino-part-5-wake-up-via.html) to wake itself up from sleep. This uses an independent internal hardware 128kHz low power oscillator. The longest this can be programmed to wait is 8s. However, if you program it to 5s, then the Arduino can choose to do work, or go straight back to sleep again, on each interrupt.


body:
The best solution for you is to use [LowPower][1] library which does not require any external parts. It supports up to 8 seconds sleep. If you need exactly 10 seconds you can write a loop with 5 cycles and call powerDown with 2 seconds sleep.

If you still want to use external interrupt, see [this][2] for some chip options.

Also, see this [article][3] for some good ideas on reducing power consumption, and [this article][4] on how to run Arduino for a year on coin cell.

  [1]: https://github.com/rocketscream/Low-Power
  [2]: https://electronics.stackexchange.com/a/386347/187920
  [3]: https://learn.sparkfun.com/tutorials/reducing-arduino-power-consumption
  [4]: http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/


body:
I believe that the LTC2956 was made exactly for this purpose. Directly from the datasheet:

>The LTC2956 is a micropower, wide input voltage range,
configurable  wake-up  timer  with  pushbutton  control.

>It  periodically wakes up and turns on a connected system to perform tasks like monitoring temperature or capturing images. After completing the task, the LTC2956 turns the system off to conserve power.
The wake-up timer period can be adjusted from 250ms to
39 days using configuration resistors

You can find the datasheet here: [LTC2956][1]. It is probably considered expensive at 1.98$ in 1000+ quantity.

  [1]: http://www.analog.com/media/en/technical-documentation/data-sheets/2956fa.pdf


body:
Along the lines of mr_sunshine's answer, another chip you could use is commonly known as a 556 timer - it's two 555 timers in a single package.  Run one timer on the normal 50% duty cycle (astable), and have it trigger the other timer in monostable mode to send a short pulse of voltage.  Look for a schematic for a servo controller based on a 556 or two 555's, and change the values to get your 10s delay.  Here's a link to one such page, found with a google search: [Servo Exerciser][1]

  [1]: http://www.seattlerobotics.org/encoder/200210/servoex/ServoExcerciser.htm


message:
Password.h and keypad.h change pass sketch for Arduino

I have a fixed password. If letter "D" is pressed on the keyboard and the correct password is entered, the fixed password will be then changed. This newly entered password is now the correct password, until the user decides again to change password. It is not working. **How to fix it?**

    #include <Keypad.h>
    #include <Password.h>

    const byte ROWS = 4; //four rows
    const byte COLS = 4; //four columns

    const char keys[ROWS][COLS] = {
        {'1','2','3','A'},
        {'4','5','6','B'},
        {'7','8','9','C'},
        {'*','0','#','D'}
      };
    const byte rowPins[ROWS] = {9,8,7,6};
    const byte colPins[COLS] = {5,4,3,2};

    Keypad    keypad { makeKeymap(keys), rowPins, colPins, ROWS, COLS };
    Password passwd = Password("123A4");
    char passwd2;

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

    void loop() {

      char key = keypad.getKey();
       if (key != NO_KEY){
          delay(60);
          switch (key){
          case 'D': changepasswd(); break;
          case '*': checkpasswd(); break;
          case '#': passwd.reset(); break;
         default: passwd.append(key);
          }
       }
    }

    void checkpasswd() {

      Serial.print(passwd2);

       if (passwd.evaluate()){
          Serial.println(" OK.");
       } else {
          Serial.println(" Wrong password!");
       }
       passwd.reset();
    }

    void changepasswd() {
      char key = keypad.getKey();
          delay(60);
          Serial.print(key);
          passwd2 += key;
          passwd.set(passwd2);

       Serial.print("Password changed to ");
       Serial.println(passwd2);

    }

body:
The logic of your function is garbled:

 1. **Function `checkpasswd()`**: Most of the function is ok, but you don't need to send `passwd2` through Serial, since it doesn't have anything to do with this function. You only use the variable for setting a new password. You can ditch this print statement.
 2. **Function `changepasswd()`**: Here lies the problem. Most likely `getKey()` returns `NO_KEY` here, which is defined as the null character. So, when outputting it to Serial, you don't see anything there (The null character marks the end of a string in C/C++). You set the password to be the null character, which cannot every be inputted by the user. Also there lies another pitfall: The [Arduino Playground Site][1] for the `Password` library states for the `set()` function:
> Warning: The new password should be a global variable (not a local
> function variable) as this function copies a pointer to the new
> password into the library, not a copy of the password.

Since the `key` variable is only local, after the function the `Password` library has it's internal pointer pointing to a now freed memory space. At some other point in the program this space might be written again, effectively changing to password to something else.

And lastly the function does not contain any loop, so only 1 character will be inputted and the newly set password can only be 1 character long. The buffer variable `passwd2` is of type `char`, so also only 1 character. What you really need there is a `char []` (character array).

Here is a bit of code (not tested), that should implement this correctly:

    char passwd2[6]=""; //global buffer for new password
                        // 6 bytes, because a C string has to end with the null character

    void changepasswd(){
        for(byte i=0;i<5;i++){
            char key = NO_KEY;
            while(key == NO_KEY || key=='*' || key=='#' || key=='D') key = keypad.getKey();
            passwd2[i] = key;
            delay(60);
        }
        passwd2[5] = '\0'; //ensure correct string ending
        passwd.set(passwd2);
    }

Note the following points:

 - This implementation blocks the programs execution, until a full valid password has been typed. It will ignore all invalid characters, that you use for other purposes (`#`, `*` and `D`).
 - The `passwd.set(passwd2)` is actually only necessary the first time, we change the password, to let the `Password` object have a pointer to our buffer. After that we technically can change the password directly in the buffer, without calling the `set()` function. I included it here for readability and making the code a bit more fail prove (against wrong futher coding).
 - This is hardcoded to accept only 5-digit passwords. If you want passwords with arbitrary length, you can start programming from this basis.
 - Debouncing buttons with a simple `delay()` may be not enough at some point. But as I understand the source code of the `Keypad` library, it also includes code for debouncing, by only checking every 10ms for a changed button and returning `NO_KEY` everytime else.

  [1]: https://playground.arduino.cc/Code/Password


message:
How to convert USB to PS/2?

Objective: To get my USB keyboard to interface with an Arduino Uno board.

Constraints: I can't afford a USB host shield for now for Arduino. Currently available is a keyboard with PS/2 connector. That example is available [here](https://playground.arduino.cc/Main/PS2Keyboard). However, it is silly going for such a keyboard, or, buy a USB to PS/2 converter at the moment.

Challenge: USB has VCC, GND, RX/TX. (Rx/Tx also labelled D+/D- respectively). The parallel port connector has the following:

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

Where will the D- pin go?

  [1]: https://i.stack.imgur.com/jVlLN.gif

body:
Many USB keyboards (certainly older ones, though almost certainly not wireless ones) are also PS/2 keyboards.  The wiring of the cable is all that differs, and the chip in the keyboard changes its behaviour depending on how it's wired.

A simple USB to PS/2 adaptor is merely a USB socket and PS/2 plug wired together in a certain way:

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

So that's:

* 5V to 5V
* D- to Data
* D+ to Clock
* GND to GND

It *may* work with your keyboard, or it may not. All you can do is try it and see.

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


message:
error: expected primary-expression before '(' token

I have a decent level of programming skill, or at least I thought so. I've been getting an error when compiling this Ardulno sketch. I don't really know what this error means or how to fix it. What's wrong with my code that's causing these errors. I was in the middle of making a big change to my code, so a lot of it is commented out because I haven't gotten to those parts.

code:

 #include <LinkedList.h>

 const uint8_t PinLeft = 2;
 const uint8_t PinMiddle = 3;
 const uint8_t PinRight = 4;
 const uint8_t PinLED = 13;

 enum MouseButtons {LEFT, MIDDLE, RIGHT} ;

 bool leftPressed = false;
 bool middlePressed = false;
 bool rightPressed = false;

 void sendMouseState() {
  if (leftPressed == true && middlePressed == false && rightPressed == false) {
   Mouse.set_buttons(1, 0, 0);
  } else if (leftPressed == true && middlePressed == true && rightPressed == false) {
   Mouse.set_buttons(1, 1, 0);
  } else if (leftPressed == true && middlePressed == true && rightPressed == true) {
   Mouse.set_buttons(1, 1, 1);
  } else if (leftPressed == true && middlePressed == false && rightPressed == true) {
   Mouse.set_buttons(1, 0, 1);
  } else if (leftPressed == false && middlePressed == true && rightPressed == false) {
   Mouse.set_buttons(0, 1, 0);
  } else if (leftPressed == false && middlePressed == false && rightPressed == true) {
   Mouse.set_buttons(0, 0, 1);
  } else if (leftPressed == false && middlePressed == true && rightPressed == true) {
   Mouse.set_buttons(0, 1, 1);
  } else if (leftPressed == false && middlePressed == false && rightPressed == false) {
   Mouse.set_buttons(0, 0, 0);
  }
 }

 void mouseButtonPress(MouseButtons theButton);
 void mouseButtonPress(MouseButtons theButton) {
  if (theButton == MouseButtons::LEFT) {
   leftPressed = true;
  } else if(theButton == MouseButtons::MIDDLE) {
   middlePressed = true;
  } else if (theButton == MouseButtons::RIGHT) {
   rightPressed = true;
  }
 }

 void mouseButtonRelease(MouseButtons button);
 void mouseButtonRelease(MouseButtons button) {
  if (button == LEFT) {
   leftPressed = false;
  } else if(button == MIDDLE) {
   middlePressed = false;
  } else if (button == RIGHT) {
   rightPressed = false;
  }
 }

 volatile unsigned int nextPressLeft = 0;
 volatile unsigned int nextPressCenter = 0;
 volatile unsigned int nextPressRight = 0;
 const int timeBetween = 150; //milliseconds

 enum ActionType {KB, MOU}; //keyboard or mouse

 class Action {
  public:
   uint16_t keyCode;
   ActionType actionType;

   Action (uint16_t keyCode, ActionType actionType) {
    this->keyCode = keyCode;
    this->actionType = actionType;
   }

 };

 class ModeAction {

  public:
   LinkedList<Action> *keys = new LinkedList<Action>();

   void addAction(Action action) {
    keys->add(action);
   }

 };

 class ActionManager {

  private:
   uint8_t modeL = 1;
   uint8_t modeM = 1;
   uint8_t modeR = 1;

   LinkedList<ModeAction> *lActions = new LinkedList<ModeAction>();
   LinkedList<ModeAction> *mActions=new LinkedList<ModeAction>();
   LinkedList<ModeAction> *rActions=new LinkedList<ModeAction>();

   bool lActing = false, mActing = false, rActing = false;

  public:
   ActionManager() {
    //actions for left switch
    //mode 1
    lActions->add(ModeAction());
    lActions->get(lActions->size() - 1).addAction(Action(MouseButtons.LEFT, ActionType.MOU));
    //mode 2
    lActions->add(ModeAction());
    lActions->get(lActions->size() - 1).addAction(Action(KEY_F11, ActionType.KB));
    //mode 3
    lActions->add(ModeAction());
    lActions->get(lActions->size() - 1).addAction(Action(KEY_LEFT_CTRL, ActionType.KB));
    lActions->get(lActions->size() - 1).addAction(Action(KEY_LEFT_ALT, ActionType.KB));
    //mode 4
    lActions->add(ModeAction());
    lActions->get(lActions->size() - 1).addAction(Action(KEY_W, ActionType.KB));

    //actions for middle switch
    //mode 1
    mActions->add(ModeAction());
    mActions->get(lActions->size() - 1).addAction(Action(MouseButtons.MIDDLE, ActionType.MOU));

    //actions for right switch
    //mode 1
    rActions->add(ModeAction());
    rActions->get(lActions->size() - 1).addAction(Action(MouseButtons.RIGHT, ActionType.MOU));

   }

   void cycleModeL() {
    this->modeL++;
    if(this->modeL >= lActions->size()) {
     this->modeL = 1;
    }
   }

   void cycleModeM() {
    this->modeM++;
    if(this->modeM >= mActions->size()) {
     this->modeM = 1;
    }
   }

   void cycleModeR() {
    this->modeR++;
    if(this->modeR >= rActions->size()) {
     this->modeR = 1;
    }
   }

  private:

   //void doDownActions(ModeAction modeActions, uint8_t mode) {
    //for (int i = 0; i < modeActions.at(mode).keys.length(); i++) {
     //if (modeActions[mode][i].keys[i].actionType == ActionType.KB) {
      //Keyboard.press(modeActions[mode].keys[i].keyCode)
     //} else if (modeActions[mode].keys[i].actionType == ActionType.MOU) {
      //mouseButtonPress(modeActions[mode].keys[i].keyCode);
     //}
    //}
    //sendMouseState();
   //}
 //
   //void doUpActions(ModeAction modeActions, uint8_t mode) {
    //for (int i = 0; i < modeActions[mode].keys.length(); i++) {
     //if (modeActions[mode][i].keys[i].actionType == ActionType.KB) {
      //Keyboard.release(modeActions[mode].keys[i].keyCode)
     //} else if (modeActions[mode].keys[i].actionType == ActionType.MOU) {
      //mouseButtonRelease(modeActions[mode].keys[i].keyCode);
     //}
    //}
    //sendMouseState();
   //}

  public:

   //void leftDown() {
    //if (lActing == false) {
     //lActing = true;
     //doDownActions(lActions, modeL);
    //}
   //}
 //
   //void middleDown() {
    //if (mActing == false) {
     //mActing = true;
     //doDownActions(mActions, modeM);
    //}
   //}
 //
   //void rightDown() {
    //if (rActing == false) {
     //rActing = true;
     //doDownActions(rActions, modeR);
    //}
   //}
 //
   //void leftUp() {
    //if (lActing == true) {
     //lActing = false;
     //doUpActions(lActions, modeL);
    //}
   //}
 //
   //void middleUp() {
    //if (mActing == true) {
     //mActing = false;
     //doUpActions(mActions, modeM);
    //}
   //}
 //
   //void rightUp() {
    //if (rActing == true) {
     //rActing = false;
     //doUpActions(rActions, modeR);
    //}
   //}

 };

 ActionManager actionManager = ActionManager();

 void setup() {

  Serial.begin(115200);

  pinMode(PinLED, OUTPUT);

  //pinMode(PinRight, INPUT_PULLUP); // sets the digital pin as output
  //attachInterrupt(PinRight, isrChangeR, CHANGE); // interrrupt is data ready
 //
  //pinMode(PinMiddle, INPUT_PULLUP); // sets the digital pin as output
  //attachInterrupt(PinMiddle, isrChangeM, CHANGE); // interrrupt is data ready
 //
  //pinMode(PinLeft, INPUT_PULLUP); // sets the digital pin as output
  //attachInterrupt(PinLeft, isrChangeL, CHANGE); // interrrupt is data ready

 }

 void loop() {

  //if (Serial.available()) {
 ////change mode
   //mode = Serial.parseInt();
 //
 ////release all buttons
   //Keyboard.releaseAll();
   //Mouse.set_buttons(0, 0, 0);
 //
 ////turn off LED
   //digitalWrite(PinLED, LOW);
 //
 ////flush the serial input buffer
   //while (Serial.available()) {
    //Serial.read();
   //}
 //
  //}
  //delay(1000);
  //Serial.println("Running");
 }

 //void isrChangeL() {
  //cli();
  //if (digitalRead(PinLeft) == LOW && nextPressLeft < millis()) {
 ////Serial.println("Pressed");
   //digitalWrite(PinLED, HIGH); //set the LED on
 //
   //if (mode == 0) {
    //Mouse.set_buttons(1, 0, 0);
   //} else if (mode == 1) {
    //Keyboard.press(KEY_F11);
   //} else if (mode == 2) {
    //Keyboard.press(KEY_LEFT_CTRL);
    //Keyboard.press(KEY_LEFT_ALT);
   //} else if (mode == 3) {
    //Keyboard.press(KEY_W);
   //}
 //
   //nextPressLeft = millis() + timeBetween;
 //
  //} else {
 //// Serial.println("Released");
   //digitalWrite(PinLED, LOW); // set the LED off
 //
   //if (mode == 0) {
    //Mouse.set_buttons(0, 0, 0);
   //} else if (mode == 1) {
    //Keyboard.release(KEY_F11);
   //} else if (mode == 2) {
    //Keyboard.release(KEY_LEFT_CTRL);
    //Keyboard.release(KEY_LEFT_ALT);
   //} else if (mode == 3) {
    //Keyboard.release(KEY_W);
   //}
 //
   //nextPressLeft = millis() + timeBetween * 0.6;
 //
 //
  //}
  //sei();
 //}
 //
 //void isrChangeM() {
  //cli();
 ////if (digitalRead(PinMiddle) == LOW && nextPressCenter < millis())
 ////{
 ////Keyboard.press(KEY_SPACE);
 ////delay(250);
 ////Keyboard.release(KEY_SPACE);
 ////}
 //
  //if (digitalRead(PinMiddle) == LOW && nextPressCenter < millis()) {
 ////Serial.println("Pressed");
   //digitalWrite(PinLED, HIGH); //set the LED on
 ////Mouse.set_buttons(0, 1, 0);
 //
   //nextPressCenter = millis() + timeBetween;
 //
  //} else {
 //// Serial.println("Released");
   //digitalWrite(PinLED, LOW); // set the LED off
 ////Mouse.set_buttons(0, 0, 0);
 //
   //nextPressCenter = millis() + timeBetween * 0.6;
 //
 //
  //}
 //
  //sei();
 //}
 //
 //void isrChangeR() {
  //cli();
  //if (digitalRead(PinRight) == LOW && nextPressRight < millis()) {
 ////Serial.println("Pressed");
   //digitalWrite(PinLED, HIGH); // set the LED on
   //Mouse.set_buttons(0, 0, 1);
 ////Keyboard.press(KEY_F11);
   //nextPressRight = millis() + timeBetween;
  //} else {
 //// Serial.println("Released");
   //digitalWrite(PinLED, LOW); // set the LED off
   //Mouse.set_buttons(0, 0, 0);
 ////Keyboard.release(KEY_F11);
   //nextPressRight = millis() + timeBetween * 0.6;
  //}
  //sei();
 //}

compiler log:

 Compiling debug version of 'click_switch_5_cycling' for 'Teensy LC'
 click_switch_5_cycling.ino: In constructor ActionManager::ActionManager()

 click_switch_5_cycling.ino: 106:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 106:66: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 106:83: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 109:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 109:73: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 112:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 112:79: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 113:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 113:78: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 116:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 116:71: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 121:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 121:66: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 121:85: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 126:53: error: expected primary-expression before '(' token

 click_switch_5_cycling.ino: 126:66: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino: 126:84: error: expected primary-expression before '.' token

 click_switch_5_cycling.ino:1: In file included from
 LinkedList.h: In instantiation of bool LinkedList<T>::add(T) [with T = Action]
 click_switch_5_cycling.ino:83: required from here

 LinkedList.h: 192:37: error: use of deleted function 'ListNode<Action>::ListNode()
 ListNode<T> *tmp = new ListNode<T>()
 LinkedList.h:19: note  ListNode<Action>  ListNode() is implicitly deleted because the default definition would be ill-formed
 struct ListNode

 LinkedList.h: 19:8: error: no matching function for call to 'Action::Action()
 click_switch_5_cycling.ino:70: note  candidate  Action  Action(uint16_t, ActionType)
 this->actionType = actionType
 click_switch_5_cycling.ino:70: note    candidate expects 2 arguments, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(const Action&)
 uint16_t keyCode
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(Action&&)
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided

 click_switch_5_cycling.ino:1: In file included from
 LinkedList.h: In instantiation of ListNode<T>* LinkedList<T>::getNode(int) [with T = ModeAction]
 LinkedList.h:314: required from T LinkedList<T>  get(int) [with T = ModeAction]
 click_switch_5_cycling.ino:106: required from here
 LinkedList.h: 160:9: warning: converting 'false' to pointer type 'ListNode<ModeAction>*' [-Wconversion-null]
 return false
 LinkedList.h: In instantiation of bool LinkedList<T>::add(int, T) [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 177:37: error: use of deleted function 'ListNode<Action>::ListNode()
 ListNode<T> *tmp = new ListNode<T>()
 LinkedList.h: In instantiation of bool LinkedList<T>::unshift(T) [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 218:37: error: use of deleted function 'ListNode<Action>::ListNode()
 ListNode<T> *tmp = new ListNode<T>()
 LinkedList.h: In instantiation of T LinkedList<T>::remove(int) [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 290:12: error: no matching function for call to 'Action::Action()
 return T()
 click_switch_5_cycling.ino:70: note  candidate  Action  Action(uint16_t, ActionType)
 this->actionType = actionType
 click_switch_5_cycling.ino:70: note    candidate expects 2 arguments, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(const Action&)
 uint16_t keyCode
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(Action&&)
 Error compiling project sources
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 Debug build failed for project 'click_switch_5_cycling'

 click_switch_5_cycling.ino:1: In file included from
 LinkedList.h: In instantiation of T LinkedList<T>::pop() [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 242:12: error: no matching function for call to 'Action::Action()
 return T()
 click_switch_5_cycling.ino:70: note  candidate  Action  Action(uint16_t, ActionType)
 this->actionType = actionType
 click_switch_5_cycling.ino:70: note    candidate expects 2 arguments, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(const Action&)
 uint16_t keyCode
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(Action&&)
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided

 click_switch_5_cycling.ino:1: In file included from
 LinkedList.h: In instantiation of T LinkedList<T>::shift() [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 268:12: error: no matching function for call to 'Action::Action()
 return T()
 click_switch_5_cycling.ino:70: note  candidate  Action  Action(uint16_t, ActionType)
 this->actionType = actionType
 click_switch_5_cycling.ino:70: note    candidate expects 2 arguments, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(const Action&)
 uint16_t keyCode
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(Action&&)
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided

 click_switch_5_cycling.ino:1: In file included from
 LinkedList.h: In instantiation of T LinkedList<T>::get(int) [with T = Action]
 click_switch_5_cycling.ino:262: required from here

 LinkedList.h: 316:14: error: no matching function for call to 'Action::Action()
 T())
 click_switch_5_cycling.ino:70: note  candidate  Action  Action(uint16_t, ActionType)
 this->actionType = actionType
 click_switch_5_cycling.ino:70: note    candidate expects 2 arguments, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(const Action&)
 uint16_t keyCode
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided
 click_switch_5_cycling.ino:65: note  candidate  constexpr Action  Action(Action&&)
 click_switch_5_cycling.ino:65: note    candidate expects 1 argument, 0 provided

Thanks for any help you can give me about what these errors are and how to fix them.

body:
The compiler is giving you a clue that the problem is around line 106. You have there:

      LinkedList<ModeAction> *lActions = new LinkedList<ModeAction>();
      LinkedList<ModeAction> *mActions=new LinkedList<ModeAction>();
      LinkedList<ModeAction> *rActions=new LinkedList<ModeAction>();

You can't do procedural code (like `new`) in a data declaration. Also, I doubt that there is a function to be called so I would get rid of the brackets. Initializing member fields should be done in the constructor, not in the declaration.


body:
you use wrong syntax to access an enum member. use `::` not `.`

`Action(MouseButtons::LEFT, ActionType::MOU)`

EDIT:

second error is that LinkedList requires constructor without parameters on the template type

add constructor without parameters to class Action


body:
You seem to have been programming in Java recently, because many of your errors have a Java ‘whiff’ to them. This, as you’ve tagged, is C++, not Java.

 1. `sendMouseState`:

  a. You wrote `leftPressed == true`. This is much more simply expressed by the expression `leftPressed`.

  b. You wrote `middlePressed == false`. This is much more simply expressed using the “not” operator `!`, as in `!middlePressed`.

  c. The code tests all eight possible combinations of `leftPressed`, `middlePressed` and `rightPressed`, calling `Mouse.set_buttons(#,#,#);`

  However, `bool`s evaluate to numbers: `false` evaluates to `0`, while `true` evaluates to `1`. All eight tests, and therefore the entire function, can therefore be boiled down to the single line:

  `Mouse.set_buttons(leftPressed, middlePressed, rightPressed);`

 2. You declared to the compiler, in a few places, “There’s going to be a function called (e.g) `void mouseButtonPress(MouseButtons theButton);`”

  That’s fair enough - but the compiler only needs that if you’re going to *call* the function before you *define* it. Since you follow the declarations *immediately* by the definitions, the declarations are unnecessary: get rid of them.

 3. Use of `enum`s:

  Declaring an `enum` lets you use symbols instead of raw numbers: well done! However, that’s *all* you need to use: the `enum`’s symbol: `LEFT`, `MIDDLE` or `RIGHT` is all you need.

  If you do feel the need to express the `enum`’s name, you need to use the `::` operator, not the `.` operator: `MouseButtons::LEFT`.

 4. Use of `new`:

  You do not need to call `new` to create members of classes. Well, OK, you might if they’re declared as pointers (which you have done), but that’s your problem: you should declare them as simple members, not pointer members.

  For example, instead of:

        LinkedList<Action> *keys = new LinkedList<Action>();
  you simply need:

        LinkedList<Action> keys;

  Note that no `new` is needed now. Then, everywhere that you dereference the member with `keys->add(action);`, you use `keys.add(action);` instead.

 5. Use of `this->`:

  You use `this->` a lot. You practically never have to: however, the one time you did need to was in the code:

        Action (uint16_t keyCode, ActionType actionType) {
            this->keyCode = keyCode;
            this->actionType = actionType;
        }

  Here, `this->` was needed to distinguish the class members from the passed-in parameters that have the same name. However, if you’d written the constructor correctly, using initialisation instead of assignment, you wouldn’t have needed `this->` here either:

        Action (uint16_t keyCode, ActionType actionType) :
            keyCode(keyCode),
            actionType(actionType) {
        }

 6. `add()` followed by `get()`:

  You use the following code:

        lActions.add(ModeAction());
        lActions.get(lActions->size() - 1).addAction(Action(LEFT,MOU));

  That is, you add an empty `ModeAction`, then fetch it back with `get(...)` before manipulating it. Don’t.

  Instead, create a temporary `ModeAction` object, get it ready, *then* `add()` it to the list:

        ModeAction lMode1;
        lMode1.addAction(Action(LEFT,MOU));
        lActions.add(lMode1);


message:
How can I stock data, and send them over by serial?

I want to make an array with data from the sensor. In data, I have displacement in x/y axis. I want to send them in the array, because in my python code I don't send them one by one, slow down really quickly program.

**Arduino code responsible for sensor**

    class MouseRptParser : public MouseReportParser
    {
    protected:
     void OnMouseMove (MOUSEINFO *mi);
    };

    void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
    {

        Serial.print(mi ->dX, DEC);
        Serial.print(",");
        Serial.println(mi ->dY, DEC);

    };

I tried to do something on my own, but I get stuck with an error about data not in the scope. I try some variant placing it, but I don't succeed .

    class MouseRptParser : public MouseReportParser {

     void OnMouseMove (MOUSEINFO *mi); };

    void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
    { int i;   for (i=0;i<10;i+2)   {
            data[i]=(mi ->dX, DEC);
            data[i+1]=(mi ->dY, DEC);   }
      Serial.println(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],data[9]);

        delay(20); };

EDIT:  I have now program that's making an array of 10 cells, but values in it are constatnt 10.

    #include <hidboot.h>
    #include <usbhub.h>

    // Satisfy the IDE, which needs to see the include statment in the ino too.
    #ifdef dobogusinclude
    #include <spi4teensy3.h>
    #endif
    #include <SPI.h>
    int data[10];

    class MouseRptParser : public MouseReportParser
    {
    protected:
     void OnMouseMove (MOUSEINFO *mi);
    };

    void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
    {

        for (int i=0; i<10; i=i+2)
      {
        data[i]=(mi->dX, DEC);
        data[i+1]=(mi->dY, DEC);

      }
      for(int j=0; j<10; j=j+1)
      {
      Serial.print(data[j]);
      Serial.print(",");
    }
    Serial.println();
      delay(100);
    };

    USB     Usb;
    USBHub     Hub(&Usb);
    HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

    MouseRptParser Prs;

    void setup()
    {
        Serial.begin( 9600 );
    #if !defined(__MIPSEL__)
        while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
    #endif
        //Serial.println("Start");

        if (Usb.Init() == -1)
            Serial.println("OSC did not start.");

        HidMouse.SetReportParser(0, &Prs);
    }

    void loop()
    {

      Usb.Task();

    }

body:
There is no such thing as "all at once" with serial. The whole point of serial is that it sends things one character at a time.

It is entirely up to you to decide what constitutes one "block" of data.

There is absolutely no difference (besides some slight processing overheads) between:

    Serial.print("Hello");
    Serial.print(" ");
    Serial.println("World");

and:

    Serial.println("Hello World");

Both of them result in Serial sending:

    H
    e
    l
    l
    o
    [space]
    W
    o
    r
    l
    d
    [cr]
    [lf]

No matter how you "batch" stuff together (or attempt to) it makes no difference.

You need to have:

* Some way of identifying the *start* of a block of data,
* A mechanism to receive the entire block a byte at a time, and
* Some way of identifying the *end* of a block of data.

How you do that is entirely up to you.

----

Here's an example of how to arrange the storage:

    class MouseRptParser : public MouseReportParser
    {
        private:
            int dx[10];
            int dy[10];
            int dpos = 0;

        protected:
            void OnMouseMove (MOUSEINFO *mi) {
                dx[dpos] = mi->dX;
                dy[dpos] = mi->dY;
                dpos++;

                if (dpos == 10) {
                    dpos = 0;
                    for (int i = 0; i < 10; i++) {
                        Serial.print("X");
                        Serial.print(dx[i]);
                        Serial.print("Y");
                        Serial.print(dy[i]);
                    }
                    Serial.println();
                }
            }
    };

What that gives you is a pair of 10-entry arrays, one for X and one for Y values. Each time a report arrives the current DX and DY values are stored. The pointer for where to store is incremented.  Then, if that pointer equals 10, reset it to 0 and print all the values.

I chose a format that gives you:

    X3Y-2X2Y-4X6Y8X-3Y7X6Y38X176Y76X-4Y8X8Y3X39Y-32X71Y4

That is, an "X" followed by a decimal value for a change in X, and a Y followed by a decimal value for a change in Y. The whole lot is then terminated by a standard CR/LF line ending pair.


message:
Minimum separation of MOSFET

I have three MOSFET in a row, each separated about 2.5mm apart with the backs facing each other. Is this a good idea?

N.B
Each MOSFET will be sinking 20mA and 60 mA in total for all three MOSFET. I am using an IRF540. The schematic below is for ONE MOSFET.

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

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

body:
Power dissipation is only a couple of milli-watts. So heat is not an issue.

Just make sure the metal tabs can’t touch each other. Personally I might add some Kapton tape. Electrical tape would work in this case, but feel wrong to me.


message:
How to use RTC memory in NodeMCU to count awakes from deep sleep?

Problem: I need to retry at least 3 times (before giving up) to reconnect my NodeMCU if it doesn't get connected to Wifi, through deep sleep cycles in order to save batteries. I thought to use RTC memory to save a counter, but it doesn't work because content of RTC RAM is unpredicatble at first power up.

Following is a NOT WORKING code, but it gives the idea of what I need to achieve. The problem is: the kounter variable is persistent through cycles, but its very first value is unpredicatble.

    #define DONEPIN 5
    uint32_t kounter;

    void setup() {
     digitalWrite(DONEPIN, HIGH);
     //WiFi setup functions...
     // .....
     if (WiFi.status() != WL_CONNECTED) {
         ESP.rtcUserMemoryRead(0, &kounter, sizeof(kounter));
      kounter++
      if (kounter > 3) {
       digitalWrite(DONEPIN, LOW);
      }
      ESP.rtcUserMemoryWrite(0, &kounter, sizeof(kounter));
      ESP.deepSleep(60e6);
     }
    }

body:
The simplest trick is to use more than one memory location. Have one, as you have now, as a counter, and then have one or more as a "This has been configured" flag.

Ideally you want the flag to have a very low probability of occurring randomly, so using a combination of a number of memory locations would improve that.

For instance, if you read memory locations 1-4 and look for four specific bytes, that gives you about a 1 in 4 billion possibility of it happening randomly.

If you don't see those four bytes, you set the counter byte to 0 (or whatever you want your initial value to be) and set the other 4 memory locations to contain your 4 flag bytes.

Using 8 bytes for your flag would give you in the order of 1 in 1.8x1019 chance of it occuring randomly.

These "flag byte combination" are often called "magic numbers" and are used all over the place to identify either *what* something is, or if something is *valid*.


body:
I realize this is *really* old, but it is still the top of the list when you search for RTCmem read/write. While it isn't maybe as "by the book" as the 'correct' answer above, there is a really simple way to deal with the "the rtcmem value is something ridiculous on first read" issue. When you first power on the esp8266 or after a button-based reset, the rtcmem value WILL be something insane. You can account for it in the code by ignoring anything that is outside the count you want. Since my application "sleeps" for 4 hours, which in esp8266 means 4, 1 hour loops, I simply say if the rtcMem value is outside that range, it is obviously bogus, set it to what I want, and go about your business:

    void writeToRTCMemory() {
      if (rtcMem.count == MAXHOUR) {
        rtcMem.count = 1;
      } else {
        if (rtcMem.count < 1) {
          rtcMem.count = 1;
        }
        if (rtcMem.count > 4) {
          rtcMem.count = 1;
        }
        rtcMem.count++;
      }

As long as your device has not lost power, or you have not pushed the reset button, this will keep it looping the way you want for as long as it has enough juice to deep sleep. (My solar powered sensors with this loop last around 2/2.5 weeks in the mid winter and much longer in summer)


message:
Connect arduino pro mini 3.3v to 5v

Is it safe to run an arduino pro mini 3.3v by 5v?
I mean directly connect 5v to vcc not raw pin.

body:
Yes you can.

The only difference between the 3.3 V and 5 V Pro Mini is the crystal and the voltage regulator.


body:
Yes, an 8 MHz resonator-clocked Promini will happily work at 5V vs 3.3V.

If you want, add a diode from VCC to the RAW pin to protect the regulator, altho it's [datasheet][1] does not indicate such is warranted.  Anecdotally, I used about 10 of these in my fencing club powered from 5V to the VCC line for quite a few years with no such protection and they ran fine for ~ 10 years, until we closed the club.

[1]:http://ww1.microchip.com/downloads/en/DeviceDoc/20005785A.pdf


message:
Use an Arduino Mega in a incubator (high humidity)

I wonder whether it is possible to use an Arduino Mega in a cell incubator.

In the incubator there is a temperature of 37°C, 5% CO2 in the atmosphere and a high relative humidity of around 95% - 98%. I think the temperature (specs of ATmega2560, temperature range: -40 °C to 85 °C) and the CO2 is no problem.

But I am concerned the condensation due to the high humidity will cause damage.

One mitigation could be, that I first pre-warm the Arduino Mega so it doesn't condensate.

(There is a possibility that I don't put the Arduino in the incubator at all, but it would be easier if I could).

body:
"-40 °C to 85 °C" for the processor, yes, for the other parts, who knows?

The board doesn't get that hot unless you are powering from like a 12V source, and then it's just the regulator that gets hot.

You could a [spray-on conformal coat][1], Mouser.com carries them. Insert any wires into the headers you will use and cover any headers you may want to use before you spray, if you get coating down into the female headers you may have poor contact later on.

The ziplock bag idea sounds like a good start as a start, put some silicon along the seal to fill the holes where the zipper won't close right next to the wires.

[1]:https://www.mouser.com/ProductDetail/MG-Chemicals/422B-340G?qs=sGAEpiMZZMvJqaFk9BIiv7PGWcg%2b8l58Olg6eeFJn18=


message:
I2C call during Wire.requestFrom

Which I2C command happen during `Wire.requestFrom(address, quantity)`?

Is it correct that Wire put a Start condition, then 7-bit address appended with read bit? How would that be different from Wire.write(address)?

body:
There is no `Wire.write(address)` in the `Wire` library. The function `write()` takes data and puts it into the library internal write buffer. It does nothing on the I2C bus.

For master write operation (sending from master to slave) the following commands are necessary:

    Wire.beginTransmission(address);
    Wire.write(data);
    Wire.endTransmission();

Only the last of these commands does something on the I2C bus. It generates a Start condition, sends the byte consisting of the address (that we set in the `beginTransmission()` statement) and the direction bit, which is always `0` here, because these commands are meant for master write operation. Then it sends the data and ends the transmission with a stop condition. You cannot control, which value the direction bit has. The parameter of `beginTransmission()` is only meant to be 7 bit long. If you provide a bigger address, the function will simply cut the highest bit and issuing a write operation anyway.

For master read operation the action on the I2C bus happens inside the `requestFrom()` function. It sends a Start condition, followed by the address and the direction bit set to `1` (again you cannot control the value of the direction bit here). Then it reads the bytes, that are coming from the slave until all requested bytes were received. Then you can read the bytes from the library internal buffer with the `Wire.read()` function. Again this function does nothing on the I2C bus. It only interacts with the libraries buffer.


body:
When you send an address with write(), it is a register address on the device, not the device address on the bus.

The device address is set with beginTransmition() and requestFrom().

If the device requires to set the register before requestFrom(), the register address should be sent with write() wrapped in beginTransmition() and endTransmition().

Example:

    Wire.beginTransmission(I2C_ADC121);
    Wire.write(REG_ADDR_RESULT); // send register to read, the 'result' register
    Wire.endTransmission();
    Wire.requestFrom(I2C_ADC121, 2);
    byte buff[2];
    Wire.readBytes(buff, 2); // read value of the 'result' register


message:
Tiny RTC module doesn't work properly when connected to an Arduino Uno together with 16x2 LCD

I am trying to make a digital clock using a tiny RTC, 16x2 LCD, and Arduino Uno. The RTC module works fine if 16x2 LCD is not connected to the Arduino. Both RTC and LCD are I2C modules and hence are using the same A4 and A5 pins of the Arduino. I have been informed that the I2C devices if connected in parallel should work. But, in this case, the clock doesn't show the time properly.

body:
An I2C scanner sketch can help to identify the actual addresses in use. I would use a sketch like on this page https://playground.arduino.cc/Main/I2cScanner or on this page http://gammon.com.au/forum/?id=10896&reply=6#reply6 . Or google 'arduino i2c scanner'.

Hook up the RTC by itself and run the scanner, then hook up the LCD by itself and run the scanner. The output will be on the serial monitor. If the devices have the same address, then that is your problem.

If one of the devices does not show up at all, then perhaps it is defective.


message:
Best practice to declare a 'static' text and save memory

I'm working on a project where I need to create a JSON to send back state of an object. I created the code to achieve it and all works fine, but I used this to declare the JSON fields:

    static const String JSON_FIELD_A;

then in the .cpp file

    const String MyClass::JSON_FIELD_A = "field_a";

In this way I can use that in several point inside my class (eg. to create and parse JSON) without needs to write the field name each time which may cause inconsistency after a refactoring.

I'm not sure about this way anyway... is there a more efficient way to achieve that? Using #define may be a solution?

body:
`const String` does make nothing constant. You create an object, which can't be reassigned, but all methods work. Because it handles the characters inside and the const declaration doesn't change it. You can delete the content, change the content, append the content of the String object.

You should use `const char*` or `const char[]`. It is an c-string and the compiler checks if it is handled as a constant at gives at least a warning if not.

To save RAM the `const char[]` should be declared as PROGMEM. At runtime then this string isn't copied into RAM. You can use it with functions with _P postfix or copy it temporally to RAM.

Example from my project:

global char array with PROGMEM

 `const char data[] PROGMEM = "{\"suspension_time_seconds\":10800}";`

use in a function

    client.print(F("Content-Length: "));
    client.println(strlen_P(data));
    char buff[64];
    strcpy_P(buff, data);
    client.print(buff);


body:
The "traditional" way is to use `PROGMEM` and use `const char *` strings.

I don't use the "traditional" way. Instead I use some "helper" classes and macros that WString.h provides.

This does mean, though, due to limitations in C++, that you have to create your string constants in two stages.

First is to define your variables:

    const __FlashStringHelper *stringOne;
    const __FlashStringHelper *stringTwo;

Then you need to assign the actual strings to those variables within a function. This could be in `setup()`, but I prefer to define an `initializeStrings()` function that `setup()` calls:

    void initializeStrings() {
        stringOne = F("This is the first string")
        stringTwo = F("This is the second string");
    }

    void setup() {
        initializeStrings();
    }

You can then pass these objects (they're not really objects, it's all just some magic casting done by the compiler) as parameters to other functions using `const __FlashStringHelper *` as the type.  They can also be passed directly to any of the `.print()` and `.println()` functions provided by the `Print` class (which all `Stream` objects ultimately inherit).

If you want to use the standard C string library functions `_P` variants for manipulating the strings (concatenating them to other strings, for instance), you can simply cast them to `PGM_P`:

    char temp[50];
    strcpy_P(temp, (PGM_P)stringOne);
    strcat_P(temp, (PGM_P)stringTwo);

Another alternative to all that is to use precompiler macros.

    #define STRING_ONE F("This is the first string");
    #define STRING_TWO F("This is the second string");

Again, you can cast those to `PGM_P` to use the `_P` variants of the standard C string library functions, and pass them directly to `print` functions, since they are replaced verbatim as `F("This is the first string")`, and `F()` does a reinterpret-cast to `const __FlashStringHelper *`.


message:
Creating a Web Interface for ESP32

I am working on a project that involves moving various servos and lights and I need a good UI to work with the device. I've previously used [Blynk][1], which worked very well but I didn't like some of the limits it has. My current code works with Blynk and I'd like to change it to a web server so it can work on any device without an app or internet connection.

Right now my esp configures itself as an access point and I can navigate to its IP address to get to my "hello world file" but after that I'm stuck. What really stumps me is getting the input from the interface that I make in HTML, I could fairly easily make an arrangement of buttons, sliders, and fields, that fits my need but how do I get the value of these as a variable in my arduino code?

I've seen some examples of code that are very simple essentially a couple buttons redirect to different web pages on the server and it takes these commands to assign a variable, but that seems kind of poor form, is there a better way, or how do I make that work with a complex interface with many buttons and switches.

I've heard of [Jquery][2] and [Ajax][3] but not familiar on how to make this work with Arduino code.

  [1]: https://www.blynk.cc/
  [2]: https://jquery.com/
  [3]: https://en.wikipedia.org/wiki/Ajax_(programming)

body:
> I could fairly easily make an arrangement of buttons, sliders, and fields, that fits my need but how do I get the value of these as a variable in my arduino code?

The same way a web server does! What you need to do is implement a web server on the ESP32. You will serve a page with the controls, and then that page must make a request back to the server which will then processes it and do whatever you program it to do.

There are two ways to do this:

 - Use a get/post form; send all the data at once
 - Something like ajax; each control sends data asynchronously


body:
I would highly recommend splitting it into two parts: back end (C++) and front end (JS). You'll probably want to connect to a router, so your clients, like a phone and laptop need not be on that AP hotspot w/o internet.

You first build an API with arduino using GET params to control, example pin values `int level = server.arg("level").toInt(); analogWrite(2, level);`, or whatever you need to do. Put that in a function called handlePin, and subscribe it in setup(): `server.on("/pin", handlePin);`. Then just add CORS to the server response: `server.sendHeader("Access-Control-Allow-Origin","*");` and you can now hit it from any computer on the network. To test, just enter it's URL and some params into a browser URL bar; `http://192.168.2.123/pin?level=512` to dim halfway.

Once you have the URLs working, the interface part is built completely separately using whatever tools you want. All you need to do is have your UI hit the API using simple ajax calls. As a quick and dirty example: `Level:<input type=range id=val max=1024> <br> <button onclick="fetch('http://192.168.2.123/pin?level='+val.value)">update</button>`

That's hows the pros do it, you just swap C++ for PHP or C# or whatever, and use any UI framework you want. Once you have the source of your client app ready, you _can_ upload it to the SPIFFS of the ESP, but I find it easier to host and update system-wide on a "real" server.

If you don't want to write the UI code yourself, you can use node-red to make a quick and dirty "control panel", just like HTML but with drag and drop functionality (more or less). You still use the same API on the ESP, and you can use more than one system at a time; all the ESPs care about is hitting the right URL.


message:
YL-38 output to NodeMCU v1.0 analog input

Using a [YL-38][1] and [NodeMCU v1.0][2] I am trying to achieve what the first link is doing, take a soil moisture reading. I've done this on an arduino, but the conversion from an arduino nano to a nodemcu is proving difficult.

To my understanding, the nodemcu A0 pin operates from 0v-3.3v but the YL-38 analog output operates from 0-4.1v. So first off, is my understanding correct?

I struggle with hardware, so looking around I found these resources:

[How to set up a simple level shifter][3]: this setup seemed pretty much like what i wanted, but the 5v input was off

[This thread was verbatim what I wanted][4] but I am terrible with circuit math, so I couldn't solve or understand the provided formulas.

Attempt 0: Initially had sensor analog out connected to a0 on nodemcu. Saturated or dry the mcu read 1023. Thought this must be because the signal out is above the A0 mapping range.

Attempt 1: I figured I'd try out the level shifter. Wired it all up as indicated. Now my readings were 760 saturated and 765 dry.

    runHygrometer(index);
    delay(2000); //allow hygrometer to wake up
    reading = (DEBUG) ? analogRead(HYGROMETER_READ_PIN) : 1023 - analogRead(HYGROMETER_READ_PIN);

As shown, my code does no scaling, It's a direct read (DEBUG is true here). So what gives? When using an arduino the range of readings was typically from 20 dry to 180 saturated (DEBUG false, so raw 1003 dry and 843 saturated)

  [1]: https://randomnerdtutorials.com/guide-for-soil-moisture-sensor-yl-69-or-hl-69-with-the-arduino/
  [2]: https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/master/NODEMCU_DEVKIT_V1.0.PDF
  [3]: https://hackaday.com/2016/12/05/taking-it-to-another-level-making-3-3v-and-5v-logic-communicate-with-level-shifters/#attachment_232191
  [4]: https://forum.arduino.cc/index.php?topic=445538.msg3313377#msg3313377

body:
> To my understanding, the NodeMCU A0 pin operates from 0v-3.3v

<s>Incorrect. The ESP8266's ADC can only measure between 0V and 1V.

You need to reduce your output voltage down to that range. How you do that very much depends on the *output impedance* of the YL-38.</s>

The LM393 that the YL-38 is based around looks to have a maximum output current of 16mA. That should be enough to happily drive a simple voltage divider.  A 4.7kΩ and 1kΩ divider would give you 0 to 0.877v out from a 0-5V input.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/UlFHL.png)

<!-- End schematic -->

An alternative would be to attach an external ADC running at 5V to the NodeMCU. This would give you multiple channels of analogue input with a 0-5V range. I use the MCP3208 running over SPI (I actually bit-bang it on the ESP8266 rather than using SPI, since I haven't yet got SPI to work properly with it).  Ideally, you want a proper logic level translator for the SCK and MOSI signals to boost them to 5V. It all gets a little complex, though.

----

It has come to light that the NodeMCU includes a voltage divider already. For some reason they chose to use massive resistors, which give far too high an impedance for any reasonable ADC input to accurately work with.  I would suggest, if you can, removing those resistors from the board and replacing them with 4.7k and 1k resistors to form your own voltage divider. Otherwise you're going to have to use a pair of op-amps in inverting mode, one with a fractional gain, and one with unity gain (the second is to "undo" the inverting of the first one) to reduce the signal to 0-3.3V.

TBH I'd be inclined to use an external ADC anyway for this.


message:
I can't manage to upload multiple sketches

I'm doing a gardening project. It involves multiple sensors and even having the sketches for them, I don't know how to make them run together and get a reading on them at the same time. I'm really new with this. It's my first Arduino ever.

I seem to manage getting a read on one of the sensors, but whenever I try to upload a new sketch, it fails to load.

Here are a couple of the codes I want to run together. One is a temperature/humidity sensor and the other one a soil humidity sensor.

Thanks in advance!!!

    #include "DHT.h"          // DHT & AM2302 library

    // Data pin connected to AM2302
    #define DHTPIN 2

    #define DHTTYPE DHT22       // DHT 22  (AM2302)

    DHT dht(DHTPIN, DHTTYPE);   // LED pins

    //////////////////////////////////////////////////////
    //
    // SETUP
    //
    void setup() {
      // Setup serial monitor
      Serial.begin(9600);
      dht.begin();
    }

    void loop() {

      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow     sensor)
      float h = dht.readHumidity();
      float t = dht.readTemperature();

      // check if returns are valid, if they are NaN (not a number) then     something went wrong!
      if (isnan(t) || isnan(h)) {
        Serial.println(F("Failed to read from DHT"));
      }
      else {
    Serial.print(F("Humedad: "));
    Serial.print(h);
    Serial.print(F(" %\t"));
    Serial.print(F("Temperatura: "));
    Serial.print(t);
    Serial.println(F(" C"));
      }

      // Wait 3 seconds
      delay(3000);
    }

**The other code:**

       //////////////////////////////////////////////
      //        ARDUINO SOIL MOISTURE DEMO        //
     //                                          //
    //           http://www.educ8s.tv           //
    /////////////////////////////////////////////

    int sensorPin = A0;
    int sensorValue = 0;
    int percent = 0;

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

    void loop() {

      sensorValue = analogRead(sensorPin);
      percent = convertToPercent(sensorValue);
      printValuesToSerial();
      delay(1000);
    }

    int convertToPercent(int value)
    {
      int percentValue = 0;
      percentValue = map(value, 1023, 465, 0, 100);
      return percentValue;
    }

    void printValuesToSerial()
    {
      Serial.print("\n\nAnalog Value: ");
      Serial.print(sensorValue);
      Serial.print("\nPercent: ");
      Serial.print(percent);
      Serial.print("%");
    }

body:
> I can't manage to upload multiple sketches

The arduino can only run _one_ sketch at a time. You can do multiple things in a single sketch, but you can only have one sketch.

> ... but whenever I try to upload a new sketch, it fails to load.

What exactly fails? You should be able to change sketches, the new sketch should replace the old sketch; If this isn't working you have another problem all together.

> Here are a couple of the codes I want to run together ...

You will have to write a new sketch that combines the behavior of the two sketches.

something like:

    ...
    setup()
    {
        // common setup code goes here
    }
    ...
    loop()
    {
        int sensor_reading_1 = analogRead(sensor_pin);
        float sensor_reading_2_h = dht.readHumidity();
        float sensor_reading_2_t = dht.readTemperature();

        ... // do stuff with the readings
    }


message:
ESP8266 does not reconnect to WiFi on reboot

The ESP8266 is supposed to remember the WiFi credentials and reconnect to the network (if it is available) after each reboot.  That was the topic of this question: https://arduino.stackexchange.com/questions/52059/does-the-esp8266-somehow-remember-wifi-access-data

I was observing that behavior and something has changed, I think when I updated via Board Manager in the Arduino IDE.  Now the credentials are lost each time that the device reboots. I've tried going back to earlier versions, but I have not been able to roll back to a version of the board definition that restores the old behavior.

Here's a sample sketch that I boiled down for testing:

    #include <ESP8266WiFi.h>

    char ssid[] = "ssid";
    char pss[]  = "pass";

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

      Serial.println("Started");

      pinMode(0, OUTPUT);
      pinMode(2, OUTPUT);

      if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Not connected");
        WiFi.begin(ssid, pss);
        digitalWrite(0, LOW);
        digitalWrite(2, HIGH);
      } else {
        Serial.println("Connected");
        digitalWrite(0, HIGH);
        digitalWrite(2, LOW);
      }
    }

    void loop() {
      Serial.println("Loop");
      delay(500);
    }

The first time through, of course, it hits the first case and prints "Not connected."  On reboot, however, I was expecting it to hit the second case and print "Connected".

I'm programming via the Arduino IDE.  The board is the Adafruit Feather HUZZAH ESP8266.  I've tried `lwIP v1.4` and `lwIP v2` in version 2.4.1 of the board.  I started rolling back versions from there got the same run-time results.

So, questions:

1. Is this a known bug of the ESP8266 modules in recent versions?
2. Is there some aspect of the WiFi configuration that's preserved on the board when I upload a new sketch? If so, how do I roll back?

body:
The esp8266 SDK libraries starts the STA connection, but it is handled by other thread then the Arduino sketch. You can wait for this connection in setup with waitForConnectResult. It returns status().

      if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("Not connected");
        WiFi.begin(ssid, pss);
        digitalWrite(0, LOW);
        digitalWrite(2, HIGH);
      } else {
        Serial.println("Connected");
        digitalWrite(0, HIGH);
        digitalWrite(2, LOW);
      }

to connect with remembered STA mode, ssid and password, but with static IP address

      WiFi.setAutoConnect(false);
      IPAddress ip(192, 168, 1, 8);
      IPAddress gw(192, 168, 1, 1);
      IPAddress sn(255, 255, 255, 0);
      WiFi.config(ip, gw, sn, gw);
      WiFi.begin(); // uses remembered ssid and password
      WiFi.waitForConnectResult();


body:
First, let's answer the OP's questions directly:

 1. Is this a known bug?

    Ans: There are and will continue to be '[issues][1],' but as
    @Juraj's    answer points out it was not an issue, but a sketch that
    wasn't    waiting for the quickest method to get wifi + IP ready on
    an esp8266,    the SDK connect.

 2. Is there ... WiFi configuration that's preserved on the board when I upload a new sketch? How to roll back?

    Ans: There is no 'rolling back,' only erase & write new data to flash to recover. At the time of sketch upload, 'wifi settings' can only be erased. The user would choose in the Arduino IDE menu > Tools > Erase Flash: Sketch + Wifi Settings. Those 'wifi settings' are typically written to flash by calling
```
WiFi.begin(ssid,passphrase);  // or,
WiFi.begin(ssid,passphrase,channel,bssid,connect);  // about 2x quicker
```
The final arg can be false; we don't even need to connect to wifi to save the settings, eg.
```
begin("ssid", "passphrase", 1, {0xA4,0xB1,0xE9,0xBC,0x6A,0x28}, false);
ESP.restart();
```
Then wait for the SDK firmware to connect.

And now let's conclude with the 'newer' information, due to changes in the Arduino esp8266 core 3.0, circa mid-2020.

Beginning in core 3.0, the SDK connect feature was disabled by default. Since then, sketches wanting to take advantage of the quick SDK connect (about 220 ms, or twice as fast as any WiFi.begin), the following line must be included early in the setup() function

    enableWiFiAtBootTime();                // prevents shutdown of sdk connect


message:
Entire arrays are not read by Processing sent by Arduino unless cord is unplugged and plugged back in?

I am using an Arduino to read sensors and then send the data to the serial port for Processing to read. It works totally fine when I first download the code and run the Processing program. But if I stop the Processing code and then start it again I will get the error ArrayIndexOutOfBounds. I print the array that Processing reads and it is only 3 indexes long, even though the Arduino code should be sending an array that's 7 long. This error happens because I am calling an index that doesn't exist, but it should exist, Processing just isn't receiving the entire array. If I unplug the USB cord from the Arduino and plug it back in this error won't happen and Processing will receive the entire array. I don't understand why this is happening. I have tried using the button on the Arduino to reset it each time before running the Processing code but this doesn't work, I actually need to unplug the cord and plug it back in.

If you have any input that would be great! Thanks in advance!

EDIT:
I am posting the code because it was requested. There's a lot of unnecessary stuff on reading the sensors and creating graphics for in Processing. The gist is that the user interacts with a Processing program and clicks when the want the data sent by Arduino to be saved. I had been talking to someone else about the problems Ive been having and they think it may have to do with the serial buffer, and that I need to clear it or wait for it to be cleared. I have looked into this and am having trouble figuring out the proper way to do it. I have tried resetting the Arduino code using SoftRestart library, but that hasn't worked.

Here's the Arduino Code:

    //need to include these libraries to be able to read from serial and read   the sensors
    #include <SoftwareSerial.h>
    #include <Wire.h>
    #include "Adafruit_MCP9808.h"
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>
    #include <AMS5915.h>
    #include <AMS5812.h>
    #include <Adafruit_ADS1015.h>

    //Create sensor objects.
    Adafruit_MCP9808 tempsensor18 = Adafruit_MCP9808(); //sensor with 0x18 address is Dry Bulb Temp
    Adafruit_MCP9808 tempsensor19 = Adafruit_MCP9808(); //sensor with 0x19 address is Temp in chamber
    Adafruit_BME280 bme; //pressure and humidity sensor
    AMS5915 amsD; //sensor being used for reading differential pressure across the nozzle
    AMS5812 amsS; //sensor being used to measure static pressure in the chamber
    Adafruit_ADS1115 ads; //16-bit ADC sensor (actually 15-bit when used as a single-ended ADC)

    //Initializing variables
    float tableVals[]={0,0,0,0,0,0,0,0}; //an array that will hold sensor values. If more sensors or readings are added the size of the array needs to increase
    float relHum=0;
    float dryBulb=0;
    float wetBulb=0;
    float pressure=0;
    float chamberTemp=0;
    float pressureDiff;
    float pressureStatic;
    float rpm;
    float correctedADC=0;
    float correctedRPM;
    float correctedADCx2=0;
    float correctedRPMx2=0;
    int counts=0;
    const float AMS5915_0010_D_B_P_MIN = -10.0;     // minimum pressure, millibar (for sensor reading differential pressure)
    const float AMS5915_0010_D_B_P_MAX = 10.0;      // maximum pressure, millibar (for sensor reading differential pressure)
    const float AMS5812_0003_D_B_P_MIN = -0.3;      // minimum pressure, PSI (for sensor reading static pressure)
    const float AMS5812_0003_D_B_P_MAX = 0.3;       // maximum pressure, PSI (for sensor reading static pressure)
    const float AMS5812_0003_D_B_T_MIN = -25.0;     // minimum temperature, C (for sensor reading static pressure)
    const float AMS5812_0003_D_B_T_MAX = 85.0;      // maximum temperature, C (for sensor reading static pressure)

    //Setup function, will run one time. Initializes sensors
    void setup() {
      Serial.begin(9600); //set baud rate
      amsD.getAddr_AMS5915(AMS5915_DEFAULT_ADDRESS);   // 0x28
      amsS.getAddr_AMS5812(AMS5812_DEFAULT_ADDRESS);   // 0x78
      ads.setGain(GAIN_ONE); //1x gain +/- 4.096V  1 bit = 0.125mV
      ads.begin(); //starting sensors
      amsD.begin();
      amsD.begin();
      if(!tempsensor18.begin(0x18) || !tempsensor19.begin(0x19)|| !bme.begin())    {  //wait until these sensors are ready
        while(1);
      }
    }

    //loop function keeps repeating
     void loop() {
      if (counts >100){  //will only enter conditional if counts variable is over 100
        readSensors(); //go to readSensors function below

        tableVals[0]= pressure; //set pressure to the first index in array
        tableVals[1]=relHum;  //rel hum to the second index in array
        tableVals[2]=wetBulb; //wet bulb to the third index in array
        tableVals[3]=dryBulb; //dry bulb to the fourth index in array
        tableVals[4]=chamberTemp; //chamber temperature to the fifth index in the array
        tableVals[5]=pressureDiff; //differential pressure to the sixth index in the array
        tableVals[6]=pressureStatic; //static pressure to the seventh index in the array
        tableVals[7]=rpm; //RPM is the eighth index in the array
        Serial.flush();
        Serial.print(tableVals[0]); //sending all the values to Processing, need commas so Processing can split into different values (don't totally know why I put everything in an array first, that's just how I saw it done in an example)
        Serial.print(",");
        Serial.print(tableVals[1]);
        Serial.print(",");
        Serial.print(tableVals[2]);
        Serial.print(",");
        Serial.print(tableVals[3]);
        Serial.print(",");
        Serial.print(tableVals[4]);
        Serial.print(",");
        Serial.print(tableVals[5],4);
        Serial.print(",");
        Serial.print(tableVals[6],4);
        Serial.print(",");
        Serial.print(tableVals[7]);
        Serial.println(","); //need this last comma for some reason or it gets messed up
        counts=0; //reset counts variable to 0
      }
      counts++; //increment counts
    }

    //This function is called in the loop() function. It reads all of the sensors
    void readSensors(){
      dryBulb = tempsensor18.readTempC(); //read from temp sensor with 0x18 address
      relHum = bme.readHumidity();  //read humidity from bme sensor
      pressure = bme.readPressure()/100.0F; //read pressure, in hpa
      pressure = pressure * 0.029529983071445; //convert pressure to inches of mercury
      wetBulb = dryBulb*atan(0.151977*pow(relHum + 8.313659, 0.5)) + atan(dryBulb +relHum) - atan(relHum - 1.676331) + 0.00391838*pow(relHum,1.5)*atan(0.023101*relHum) - 4.686035; //equation finds approximate wet bulb temp from humidity and dry bulb temp
      chamberTemp = tempsensor19.readTempC(); //read from temp sensor with 0x19 address

      //this chunk of code gets the differential pressure reading and converts it to inches of water
      byte errorDiff;
      int8_t addressD;

      addressD = amsD.ams_i2cAddress;
      Wire.beginTransmission(addressD);
      errorDiff = Wire.endTransmission();
      if (errorDiff == 0){
        amsD.Measure_PressureAndTemperature(AMS5915_0010_D_B_P_MIN, AMS5915_0010_D_B_P_MAX);
        pressureDiff=amsD.getPressure();
        pressureDiff = pressureDiff * 0.40146307866177;
      }

      //this chunk of code gets the static pressure reading and converts to inches of water
      byte errorStatic;
      int8_t addressS;

      addressS = amsS.ams_i2cAddress;
      Wire.beginTransmission(addressS);
      errorStatic = Wire.endTransmission();
      if(errorStatic == 0){
        amsS.Measure_PressureAndTemperature(AMS5812_0003_D_B_P_MIN, AMS5812_0003_D_B_P_MAX, AMS5812_0003_D_B_T_MIN, AMS5812_0003_D_B_T_MAX);
        pressureStatic = amsS.getPressure();
        pressureStatic = pressureStatic*27.679904842545;
      }

      //the next chunk of code takes 300 readings from the ADC, averages them together. Applies two correction equations to the ADC and then converts it to the RPM that is sent to Processing
      float ADCcount=0;
      float ADCtotal=0;
      float finalADC=0;

      int16_t adc0;
      while(ADCcount<100){ //taking 100 ADC readings and averaging them
        adc0 = ads.readADC_SingleEnded(0);
        ADCcount=ADCcount+1;
        ADCtotal=ADCtotal+adc0;
      }

      finalADC=ADCtotal/ADCcount;
      rpm = (40740.0/32767.0)*finalADC;
    }

Processing Code:

    //initializing variables
    import processing.serial.*; //need this library to read serial data
    Serial myPort;
    int signal=0; //this will signal what part of the draw function to read
    Table table;
    int count =-1;
    int lf = 10; //10 is the ASCII number that represents an enter key
    String d_string;
    String m_string;
    String y_string;
    float countVals[];
    float pressureVals[];
    String voltage=""; //these variables need to be blank strings since these are the variables that come from user input
    String current=""; //they will be changed to floats before being saved in the table
    String fileName="";
    String COM ="";
    float Pdiff;
    float Pstatic;

    //Set up
    void setup(){
      size(300,410); //creating the start graphics
      background(255);
      String s = "Click on the rectangle to start.";
      textSize(20);
      textAlign(CENTER);
      fill(25);
      text(s,10,10, 290, 150);
      fill(255, 0, 0);
      rectMode(CORNERS);
      rect(115,85,195,160); //drawing rectangle 'button'

      table = new Table();  //create new table
      table.addColumn("Date");  //make a Date column
      table.addColumn("Reading Number"); //make a Reading Number column
      table.addColumn("Voltage V");  //Voltage column
      table.addColumn("Current A");  //Current column
      table.addColumn("Pressure inHg"); //Pressure column
      table.addColumn("Humidity %");  //Relative Humidity column
      table.addColumn("Wet Bulb Temp. *C");  //Wet Bulb Temp. column
      table.addColumn("Dry Bulb Temp. *C");  //Dry Bulb temp. column
      table.addColumn("Chamber Temp. *C"); //Chamber Temp column
      table.addColumn("Static Pressure inH20");  //Static pressure column
      table.addColumn("Differential Pressure inH2O"); //Differential Pressure column
      table.addColumn("RPM");  //RPM column

      int day = day();  //Find the day
      int month = month(); //find the month
      int year = year();  //find the year
      d_string = str(day);  //convert these integers to strings
      m_string = str(month);
      y_string = str(year);
    }

    //Draw function is continuously looping
       void draw(){
          if(signal==1){ //if signal is 1 (set in keyPressed) ask the user to enter the COM
            background(255);
            String f = "Enter what number in the list of COM Ports the Arduino is plugged into (This is not necessarily the COM number.) \nPress ENTER to continue.";
            textAlign(CENTER); //center the text on the screen
            fill(25); //setting fill color
            stroke(0);  //setting stroke color
            textSize(14); //setting text size
            text(f,10,10,290,200); //displaying the instructions in the graphics box
            textSize(20); //resetting text size
            text(COM,10,125,290,200); //displaying the COM the user is typing
          }
          else if (signal==2){ //if signal is 2 (set in keyPressed) ask the user to enter the name of the CSV file where the data will be saved
            background(255);
            String f = "Enter the name of the CSV file where the data will be saved. \nThis will be located in the folder called 'data' that is in the same folder as this application. \nPress ENTER to continue.";
            textAlign(CENTER);
            fill(25);
            stroke(0);
            textSize(12);
            text(f,10,10,290,200); //displaying instructions to the user
            textSize(20);
            text(fileName,10,125,290,200); //displaying the user file name the user is typing
          }
          else if(signal==3){ //if signal is 3 (set in keyPressed) ask the user to input the voltage
            background(255);
            String f = "Enter the Voltage in Volts. Press ENTER to continue.";
            textAlign(CENTER);
            fill(25);
            stroke(0);
            textSize(20);
            text(f,10,10,290,200); //displaying instructions to the user
            text(voltage,10,125,290,200); //displaying the voltage the user is typing
          }
          else if(signal ==4){ //if signal variable is 5 (set in conditional above) ask the user to input the current
            background(255);
            String f = "Enter the Current in Amps. Press ENTER to continue.";
            textAlign(CENTER);
            fill(25);
            stroke(0);
            textSize(20);
            text(f,10,10,290,200); //displaying instructions
            text(current, 10,125,290,200); //displaying the current the user is typing
          }
           else if (signal ==5){ //if signal variable is 4 (set in mousePressed) then read the following chunk of code.
            String val=null;
            while (val==null){
              val = myPort.readStringUntil('\n'); //read serial data sent by Arduino
            }
                val = trim(val); //trim off any white space
                countVals = float(split(val, ',')); //split serial data into individual readings
                delay(500);
                signal =6; //set signal to 6 so next chunk of code will be read
          }
           else if (signal ==6){ //if signal is 6 (set in the above conditional) read the following chunk of code
            TableRow newRow = table.addRow(); //add a row to the spreadsheet
        newRow.setString("Date", m_string +"."+ d_string +"."+ y_string); //write data in the correct columns in the table
        newRow.setInt("Reading Number", count);
        newRow.setFloat("Pressure inHg", countVals[0]);
        newRow.setFloat("Humidity %", countVals[1]);
        newRow.setFloat("Wet Bulb Temp. *C", countVals[2]);
        newRow.setFloat("Dry Bulb Temp. *C", countVals[3]);
        newRow.setFloat("Chamber Temp. *C", countVals[4]);
        newRow.setFloat("Differential Pressure inH2O", countVals[5]);
        newRow.setFloat("Static Pressure inH20", countVals[6]);
        newRow.setFloat("Voltage V", float(voltage)); //values that were strings are converted to floats
        newRow.setFloat("Current A", float(current));
        newRow.setFloat("RPM", round(countVals[7]));
        saveTable(table, "data/"+fileName+".csv"); //saving the data in a folder called 'data' in a file with the user given name
        signal = 7; //signal variable back to 7 to read the next conditional
      }
      if(signal ==7){ //if signal is 7 (set in conditional above or in keyPressed), read serial port data and display graphics Draw function will continue to loop through this conditional until box is clicked so pressures are always updated.
        String pressures=null;
        while(pressures==null){
          pressures = myPort.readStringUntil('\n'); //read serial data sent by Arduino
        }
            pressures = trim(pressures); //trim off any white space
            pressureVals = float(split(pressures, ',')); //split serial data into individual readings
            println(pressureVals);
            background(255);  //reset graphics
            String s = "Click on rectangle to take a data point. Exit out of this box when done.";
            stroke(0);
            textSize(15);
            fill(25);
            textAlign(CENTER);
            text(s,10,10,290,100); //displaying instructions to user
            fill(50, 255, 200);
            rect(115,85,195,160);
            fill(0);
            textSize(12);
            textAlign(LEFT); //next line will display the previous data point if it is not the first data reading (counts needs to be 1 or greater)
            if (count>0) text("Previous Data Point: \n\t" +"Barometric Pressure inHg: " + str(countVals[0]) +"\n\tHumidity %: " +str(countVals[1]) + "\n\tWet Bulb Temp *C: " + str(countVals[2]) + "\n\tDry Bulb Temp *C: " +str(countVals[3]) +"\n\tChamber Temp *C: " + str(countVals[4])+"\n\tDifferential Pressure inH20: " + str(countVals[5]) +"\n\tStatic Pressure inH20: "+ str(countVals[6]) + "\n\tRevolutions Per Min: " + str(round(countVals[7])),10,190, 300,400);
            textAlign(10, 400);
            text("Static: " +str(pressureVals[6]) + " in.H20", 10,400); //display the static pressure on the bottom of graphics window
            textAlign(150, 400);
            text("Diff: "+ str(pressureVals[5]) + " in.H20", 150, 400); //display the differential pressure on the bottom of graphics window
      }
    }

    //mousePressed function will run when mouse is clicked in box
    void mousePressed(){
      if(mouseX <= 195 && mouseX >= 115 && mouseY <=160 && mouseY >=85){ //if the mouse is clicked within the boundaries of the rectangle
         if(count>=0){ //if counts is greater or equal to 0 (counts starts at -1, this was b/c there were some glitches with the first click being registered)
           signal=5;
           String d= "DATA TAKEN"; //display "DATA TAKEN" to signal that a data point was taken
           textSize(15);
           fill(255,0,50);
           textAlign(LEFT);
           text(d, 107, 180);
        }
        else{   //will run if counts is not greater than or equal to 0 (so this will just be on the first click before data is taken)
          signal=1;
        }
        count++; //increment count
        mousePressed = false;  //set mousePressed to false to make sure this function doesn't run again.
      }
    }

    //keyPressed will run when a key on the keyboard is pressed
    void keyPressed() {
      if(signal==1){ //if signal variable is 1...
        if(key==BACKSPACE){ //if the key pressed is BACKSPACE
          if(COM.length()>0){ //if length of what is being typed is greater than 0
            COM = COM.substring(0,COM.length()-1);  //then get rid of the last character
          }
        }
        else if (textWidth(COM+key) < width && key != ENTER){ //if what is being typed is not greater than the width of the graphics window and the key pressed is not ENTER
          COM = COM +key; //add the key pressed to the end of what is being typed
        }
        if(key ==ENTER){ //if ENTER is pressed
          signal=2; //change signal variable
          String portName = Serial.list()[int(COM)]; //COM is not necessarily the COM number the Arduino is plugged into. It's the number in the list of COMS that the COM is listed. I used trial and error to figure this out
          myPort = new Serial(this, portName, 9600);  //setting up baud rate
          myPort.bufferUntil(lf); //I don't know if this is actually necessary
        }
      }
      else if(signal==2){ //if signal variable is 2...
        if(key ==BACKSPACE){ //these first two conditionals for this signal number are the same for all the signal number conditionals.
          if(fileName.length()>0){
            fileName = fileName.substring(0,fileName.length()-1);
          }
        }
        else if (textWidth(fileName+key) < width && key !=ENTER) {
          fileName = fileName +key;
        }
        if (key == ENTER) { //If key pressed is ENTER
          signal=3;  //change signal
        }
      }
      else if(signal==3){ //If signal is 3...
        if(key ==BACKSPACE){
          if(voltage.length()>0){
            voltage = voltage.substring(0,voltage.length()-1);
          }
        }
        else if (textWidth(voltage+key) < width && key!=ENTER) {
          voltage = voltage +key;
        }
        if (key == ENTER) {
            signal=4;
        }
      }
      else if(signal ==4){ //if signal is 4...
        if(key == BACKSPACE){
          if(current.length()>0){
            current = current.substring(0,current.length()-1);
          }
        }
        else if (textWidth(current+key) <width && key != ENTER) {
          current = current + key;
        }
        if (key ==ENTER){
              signal=7; //change signal to 7 and display graphics to take a data point
          key = BACKSPACE;
          background(255);
          String s = "Click on rectangle to take a data point. Exit out of this box when done.";
          stroke(0);
          textSize(15);
          fill(25);
          text(s,10,10,290,100);
          fill(50, 255, 200);
          rect(115,85,195,160);
        }
      }
    }

Sorry, this is probably very hard to follow. I do not have that much coding experience so I'm sure my logic isn't very good.

body:
I would suggest that you are seeing reset-stutter from the serial. Basically the sketch is running and filling the serial buffer with data. Then you connect and the board resets, but some data is still in the USB chip's buffer. The sketch then starts running again, and new data is sent.

In effect I am guessing you may be seeing something like:

    3.87,4.45,55.13,
    19.44,43.12,14.56,1.01,23.87,4.45,55.13,
    19.44,43.12,14.56,1.01,23.87,4.45,55.13,
    19.44,43.12,14.56,1.01,23.87,4.45,55.13,
    19.44,43.12,14.56,1.01,23.87,4.45,55.13,

where the first line is left over from the previous execution before the reset.  You don't get that with a complete unplug and re-plug because there is no "previous" data in the USB buffer to send.

The simplest solution is just to handle it gracefully.  Take a look at the `.length` of your float array and see if it's correct or not. Only if it has enough entries in it do you actually want to deal with the data - otherwise, you just throw it away and wait for the next line to arrive.


message:
How to detect water presence with only 2 wires

I don't know if this question belong here or on electronics SE.

A manufacturer just sent me a personalize device which include an ESP-32 and a Water Sensor.

My problem is that I don't know how to retrieve the water sensor data (if there is water or not).
When I used my Arduino Nano and a [Funduino Water Sensor][1], it was easy to retrieve the value because this sensor got 3 connectors (VCC, GND, Data), I just had to do a basic `analogRead(DATA_PIN)`.

But now, as you can see on the diagram bellow, the water sensor is just composed of 2 wires. I presume that it will detect water when these two wires are going to be connected by water.

**So, How to detect the presence of water in Arduino using only these 2 wires ?**

**What I tried :**

 - Analog Read on the pin GPIO33
 - Digital Read on the pin GPIO33
 - Try to use TOUCH_PAD with this pin using `  touchAttachInterrupt(T8, callback, Threshold);` but callback was never called
 - Contact the manufacturer (He said that it works perfectly, he used touch_pad for testing but never used Arduino IDE, only ESP-IDF that I really don't know)

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/UWjaJ.png)

<!-- End schematic -->

**EDIT:**

This image represent the back of the device with the sensor, inner wire is directly connected to GND and outer wire is connected to GPIO_33. This is all, there is not hidden connectors or something else.

[![Back of the device with these 2 wires][2]][2]

  [1]: https://www.google.ca/search?q=funduino water sensor&tbm=isch
  [2]: https://i.stack.imgur.com/J5rdF.jpg

body:
Since all you have is 2 bare wires, the water simply forms a resistor between them.

You can use it as part of a resistive divider, with a fixed resistor between your analog input and +3.3V.  The resistance between the wires will change from infinite (dry) to something much lower (wet) and the reading you get from the ADC will depict that.

You will need to experiment with different resistances in order to get reasonable values, but start with 10kΩ, or 100kΩ.  If you use a very high resistance (in the order of 1MΩ or more) you may even be able to use it like a simple switch and connect it to a digital input.

Be warned, though, that this method will cause a small amount of electrolysis, causing one electrode to be eroded away and the other to gain extra material.  For this reason it can be good to connect the resistor to a GPIO pin instead of directly to +3.3V and switch the GPIO pin HIGH when you want to do a reading (to provide power) and LOW (or INPUT) when at other times (to remove power).  This will greatly increase the lifetime of your water sensor.


message:
What's the problem? My motor works properly only when we press the left key and not others

int mf11=13;//motor1 1st terminal
    int mf12=12;//motor1 2nd terminal
    int mf21=9;//motor2 1st terminal
    int mf22=8;//motor2 2nd  terminal
    int fr=2;//front key
    int bk=3;//back key
    int rt=4;//right key
    int lt=5;//left key

    void setup() {
        pinMode(mf11,OUTPUT);
        pinMode(mf12,OUTPUT);
        pinMode(mf21,OUTPUT);
        pinMode(mf22,OUTPUT);
        pinMode(fr,INPUT);
        pinMode(bk,INPUT);
        pinMode(rt,INPUT);
        pinMode(lt,INPUT);
    }

    void loop() {
        int s = digitalRead (fr);
        int h = digitalRead (bk);
        int i = digitalRead (rt);
        int v = digitalRead (lt);
        if(s==HIGH) {
             digitalWrite(mf11,HIGH);
             digitalWrite(mf12,LOW);
             digitalWrite(mf21,HIGH);
             digitalWrite(mf22,LOW);
        }
        if (h==HIGH) {
            digitalWrite(mf11,LOW);
            digitalWrite(mf12,HIGH);
            digitalWrite(mf21,LOW);
            digitalWrite(mf22,HIGH);
        }
        if (i==HIGH) {
             digitalWrite(mf11,LOW);
             digitalWrite(mf12,HIGH);
             digitalWrite(mf21,HIGH);
             digitalWrite(mf22,LOW);
        }
       if (v==HIGH) {
            digitalWrite(mf11,HIGH);
            digitalWrite(mf12,LOW);
            digitalWrite(mf21,LOW);
            digitalWrite(mf22,HIGH);
       } else {
           digitalWrite(mf11,LOW);
           digitalWrite(mf12,LOW);
           digitalWrite(mf21,LOW);
           digitalWrite(mf22,LOW);
      }
    }

body:
The reason your code only works for left, is because when v is LOW your else block gets executed and sets all pins to low! You need to use else if.

    if(condition1)
    {
      ...
    }
    else if (condition2)
    {
      ...
    }
    else
    {
      ...
    }


message:
Where in datasheet is the warning about unreliability of reading PINxn?

I use atmega32u4 (but believe it applies to all models). Here is the [datasheet][1].

Consider the following C program (I use AVR-GCC 5.4.0):

    #include <avr/io.h>
    int main(void)
    {
      PORTB |= 1 << PB5; /* pullup */
      DDRB |= 1 << PB0; /* LED */
      if (!(PINB & 1 << PB5))
        PORTB |= 1 << PB0; /* turn on LED */
      while (1) ;
    }

There are two situations:

 - connect a 10cm wire to PB5 pin (the other end of the wire is in the air): the result is that sometimes after poweron the led is on, sometimes the led is not on.

 - do not connect anything to PB5 pin: the result is that after poweron led is never on.

I have a standard setup. Nothing tricky. If it does not work reliably, this gotcha **MUST** be documented in datasheet. This setup is supposed to deal with a stupid button. But sometimes it detects a keypress while there is no keypress.

The question is: where in datasheet there is a warning about this gotcha?
And did somebody come across such case, or I'm the first in the world?

**EDIT** See also [this][2] question.

  [1]: https://www.pjrc.com/teensy/atmega32u4.pdf
  [2]: https://electronics.stackexchange.com/q/388648/91037

body:
You have made an antenna with the 10cm wire and are receiving radio waves which is translating to voltages on your input pin. This is why you don't have the same trouble when the wire is not connected.

According to [www.csgnetwork.com/freqwavelengthcalc.html][1] your 10cm wire is picking up frequencies of 750 MHz based on a quarter wavelength calculation.

The datasheet states that the internal pull up resistance is roughly between 20K - 50K ohms. As mentioned in the comments, this is quite weak.

There are two things that you can do that I can see:

 - Add a stronger pull up resistor (a value between 1K and 5K ohms should do)
 - Add a [decoupling/bypass capacitor][2].

The reason that this is not in the datasheet is because this is a general electronics/physics knowledge, not a characteristic of the micro-controller itself.

  [1]: http://www.csgnetwork.com/freqwavelengthcalc.html
  [2]: https://en.wikipedia.org/wiki/Decoupling_capacitor