message:
XH-M131 Photoresistor Relay Module NC position

I have purchased XH-M131 Photoresistor Relay Module to automatically light my outdoor yard at sunset and turn it off at sunrise. I'ts working as it is supposed to, However, if I power off the relay, the light goes off.

I want this to be a closed circuit in such way if the relay malfunction or loose power, the outdoor light stays on which I can manually switch off if I want to.

BTW, I tried connecting the light wires to the otherside, but the whole thing reversed, light goes on when light detected which defies the purpose. Any suggestion or modifications.
[![enter image description here][1]][1]

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

body:
If you put an additional relay (Relay B) between the XH-M131 and the light and connect the light to the mains via the Normally Closed pole of Relay B, the light will be ON unless Relay B is activated or you turn off the light switch.
Then, connect the coil of Relay B (instead of the light) to the "other side" as you say, of the XH-M131, the logic will be such that when the sensor is exposed to light (daytime) the XH-M131 turns on. That will activate Relay B, switching it from Closed to Open and turn the light OFF.
If the XH-M131 fails, the light will be ON.


sender: user

message:
Value keeps incrementing even though loop has terminated, why?

I use a double called delta and use that to turn off an LCD if delta is larger than the timeout threshold. Once that happens, delta is supposed to set to 0 and then other parts of the program run. However, delta continues to increment and I'm not sure why.

This is causing a problem because delta is used to determine if the device should "sleep". So when I try to wake up the device via button click, delta is always way past the timeout threshold and the device immediately goes back to sleep.

Any thoughts as to why? Thanks in advance.

```
#include <M5StickC.h>

double BUTTON_PRESS_NEXT_PRESS_TIME= .5; //Time in seconds
double MINIMUM_BUTTON_PRESS_TIME = .05; //Time in seconds
int BUTTON_PRESS_SLEEP = 3; //Time in seconds
int SCREEN_TIMEOUT = 5;
int count;

static int pressCount = 1;
static int nextPress= 1;

static bool buttonIsPressed;

void setup(void) {
  buttonIsPressed = false;
  M5.begin();
  M5.Lcd.setRotation(0);
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Axp.ScreenBreath(100);

  updateScreen();
}

void updateScreen() {
   char tmp[12];

  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.drawString(dtostrf(pressCount,4,0,tmp), 80,60,6);
  M5.Lcd.drawString(dtostrf(nextPress,3,0,tmp), 80,100,6);
}

static void evaluatePress(double d) {
   // Evaluate press
  if (d >= BUTTON_PRESS_NEXT_PRESS_TIME) {
    nextPress++;
    pressCount = 1;

    if (nextPress == 19) {
      nextPress= 1;
    }
  }
  else if (d >= MINIMUM_BUTTON_PRESS_TIME && d < BUTTON_PRESS_NEXT_PRESS_TIME) {
    pressCount++;
  }

  updateScreen();
}

void sleepLoop() {
  bool bIsPressed = false;
  Serial.println("Sleep 1");
  while(1) {
    Serial.println("Sleep 2");
    if (digitalRead(M5_BUTTON_HOME) == LOW && !bIsPressed) {
      bIsPressed = true;
    }

    if (digitalRead(M5_BUTTON_HOME) == HIGH && bIsPressed){
      Serial.println("BREAKY BREAKY");
      M5.Axp.ScreenBreath(100);

      break;
    }
  }
}

void awakeLoop() {
  double delta;
  double old_time;
  double current_time;

  Serial.println("Awake 1");

  while(1) {
    Serial.println("Awake 2");
     //Calculate delta time
    old_time = current_time;
    current_time =  millis();
    delta = delta + (current_time - old_time)/1000;

    if (digitalRead(M5_BUTTON_HOME) == LOW && !buttonIsPressed) {
      buttonIsPressed = true;
      delta = 0;
    }

    if(digitalRead(M5_BUTTON_HOME) == HIGH && buttonIsPressed) {
      buttonIsPressed = false;
      evaluatePress(delta);
      delta=0;
    }

    if(delta > SCREEN_TIMEOUT && !buttonIsPressed) {
      Serial.println(delta);
      Serial.print("BREAK AWAKE");
      Serial.println(M5.Axp.ScreenBreath(0));
      count = 0;
      break;
    }
    else {
      count++;
    }
  }

  delta = 0;
}

void loop() {
  awakeLoop();
  sleepLoop();
}

sender: assistant

body:
Here:

```c++
void awakeLoop(){
  double delta;
  // The rest of the function body...
  delta = 0;
}
```

delta is being defined as a variable local to the function `awakeLoop()`
and with automatic storage. This means the variable is created whenever
the program enters the function, is _not_ implicitly initialized, and is
destroyed when the function returns.

The last statement `delta = 0;` has no effect, as it is setting a
variable that is going to be destroyed right away. The compiler most
likely got rid of it.

You most likely want the variable to retain its value across invocations
of the function. For this to be the case, it has to be either global
(defined outside the function) or local with the `static` qualifier. In
both cases, it will have static storage, i.e. its lifetime will be the
whole program run. Also, if you fail to explicitly initialize it, the
compiler will implicitly initialize it to zero.


message:
continuous print of button Pushed

When pushing a button I want to read the value...once.
If I push(hold) the button I get a continuous print of button1Pushed

        if(button1State == LOW) {
         Serial.println("button1Pushed");
      }

But if I try to solve it like this, nothing happens, not a single print. What am I missing?

     int button1State = digitalRead(button1);
      int lastButton1State;

      if(button1State != lastButton1State){
          if(button1State == LOW){
            Serial.println("button1Pushed");
                   }
            }

      lastButton1State = button1State;

body:
`lastButton1State` is not initialized and therefore has no strictly defined value. In your case, it appears to have a value of `0` (which is random, it's not due to implicit initialization, which is only done for global variables). The condition `if(button1State != lastButton1State)` becomes true only if the button is released.

You can check that by changing

    if(button1State == LOW){
      Serial.println("button1Pushed");
    }

to

    if(button1State == HIGH){
      Serial.println("button1 released");
    }

The following should work:

    int last_button_state=HIGH; // initialize to HIGH, so the button does not teigger on very first iteration
    void setup () {
      // whatever you want to do here
    }
    void loop() {
      int button_state=digitalRead(button1);
      if (button_state!=last_button_state && button_state==LOW) {
        Serial.println("button pressed");
      }
      else if (button_state!=last_button_state && button_state==HIGH) {
        Serial.println("button released");
      }
      last_button_state=button_state;
    }


message:
ESP32 servo runs continuous

I have ESP32 connected to TZT servo SG90.
This is the code

    #include <ESP32Servo.h>
    #define TURN_TIME 175

    Servo myservo;  // create servo object to control a servo
    // 16 servo objects can be created on the ESP32

    int pos = 0;    // variable to store the servo position
    // Recommended PWM GPIO pins on the ESP32 include 2,4,12-19,21-23,25-27,32-33
    #define servoPin  17
    #define MOTOR_1_PIN 22

    void setup() {
      pinMode(servoPin, OUTPUT);
      Serial.begin(9600);
     // Allow allocation of all timers
     ESP32PWM::allocateTimer(0);
     ESP32PWM::allocateTimer(1);
     ESP32PWM::allocateTimer(2);
     ESP32PWM::allocateTimer(3);
     myservo.setPeriodHertz(50);    // standard 50 hz servo
     // using default min/max of 1000us and 2000us
     // different servos may require different min/max settings
     // for an accurate 0 to 180 sweep
    }

    void loop() {

      myservo.attach(servoPin, 700, 2500); // attaches the servo on pin 18 to the servo object
      myservo.write(0);
      delay(TURN_TIME);
      for(int i =0; i<180; i++)
      {
        myservo.write(i);
        delay(TURN_TIME);
      }
      delay(3000);
      for(int i =180; i>0; i--)
      {
        myservo.write(i);
        delay(TURN_TIME);
      }
      myservo.detach();
      delay(3000);

    }

My servo starts rotating one way and reverse for few degrees, then after 5 seconds the servo starts rotating at one way forever..

I had no problems with arduino and nodemcu board. What should I change in the code?

EDIT: I have connected the servo with battery, they have common ground.
The pin on esp32 that I am using is G17. "#define servoPin 17" in the code

body:
I used other servo library and it worked.. Then i changed the pulse width with this line of code.
The default is 1000-2000. But it rotates only 95 degrees. When it's pushed to around ~2850us the servo rotates up to 181-185 degrees.
`servo1.attach(servoPin,CHANNEL_NOT_ATTACHED, 0,180,544,2840/);`

    #include <Servo_ESP32.h>

    static const int servoPin = 16; //printed G14 on the board
    int delayTime = 20;
    Servo_ESP32 servo1;

    int angle =0;
    int angleStep = 5;

    int angleMin =0;
    int angleMax = 180;
    #define CHANNEL_NOT_ATTACHED -1
    void setup() {
        Serial.begin(115200);
        servo1.attach(servoPin,CHANNEL_NOT_ATTACHED, 0,180,544,2840/);

    }

    void loop() {
        for(int angle = 0; angle <= angleMax; angle +=angleStep) {
            servo1.write(angle);
            Serial.println(angle);
            delay(delayTime);
        }

        for(int angle = 180; angle >= angleMin; angle -=angleStep) {
            servo1.write(angle);
            Serial.println(angle);
            delay(delayTime);
        }
    }


message:
915Mhz vs Wifi (speed impact of duty cycle limitations)

I am currently using an esp32 with Wifi. I need at least 15kByte/s constant throughout. This works fine but I am not happy with the range.

I came across the RFM69HCW 915MHz module. It is stated with 300 kbps.

Now what is confusing me are duty cycle regulations. Various countries have a 1% limit.
Is this limit considered in the 300 kbps? Or do I effectively only get 3 kbps because I cannot constantly send?

body:
300kbps is the data transmission rate. Not the throughput rate.

That means that yes, if you only transmit for 1% of the time then for 1% of the time you are getting 300kbps - i.e., 3kbps as you correctly surmised.


message:
Real Time clock module error-DS3231

This is not a code error I have been using DS3231 RTC module with battery. When I bought this module It worked perfectly now when I get it to use, The time is running perfectly. when I set the current time of my location, it has been running along with that time but the problem is when I unplug the power of my Arduino Nano and again when I give the power I can see the time is running from its start, I could not see any current time value my location but I have attached CR2032 battery along with DS3231 module? what is the problem with this? I changed another battery too but It shows same problem my DS32321 haven't kept the time when I unplug and re-plug the power

This is the code I'm using for set the time

    #include <DS3231.h>

    // Init the DS3231 using the hardware interface
    DS3231  rtc(SDA, SCL);

    void setup()
    {
      // Setup Serial connection
      Serial.begin(115200);
      // Uncomment the next line if you are using an Arduino Leonardo
      //while (!Serial) {}

      // Initialize the rtc object
      rtc.begin();

      // The following lines can be uncommented to set the date and time
      rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
      rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
      rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
    }

    void loop()
    {
      // Send Day-of-Week
      Serial.print(rtc.getDOWStr());
      Serial.print(" ");

      // Send date
      Serial.print(rtc.getDateStr());
      Serial.print(" -- ");

      // Send time
      Serial.println(rtc.getTimeStr());

      // Wait one second before repeating :)
      delay (1000);
    }

This is the code I'm using to make Interrupt

     #include <DS3231.h>

    int Relay = 4;

    DS3231  rtc(SDA, SCL);
    Time t;

    const int OnHour = 21;
    const int OnMin = 46;
    const int OffHour = 21;
    const int OffMin = 48;

    const int On2Hour = 14;
    const int On2Min = 54;
    const int Off2Hour = 21;
    const int Off2Min = 48;

    void setup() {
      Serial.begin(115200);
      rtc.begin();
      pinMode(Relay, OUTPUT);
      digitalWrite(Relay, LOW);
    }

    void loop() {
      Serial.println("Time:  ");
      Serial.print(rtc.getTimeStr());
      Serial.print('\n');

      Serial.println("Date: ");
      Serial.print(rtc.getDateStr());
      Serial.print('\n');

      t = rtc.getTime();
      Serial.print(t.hour);
      Serial.print(" hour(s), ");
      Serial.print(t.min);
      Serial.print(" minute(s)");
      Serial.println(" ");
      delay (1000);
      //can be set lcd display alspo
      if(t.hour == OnHour && t.min == OnMin){
        digitalWrite(Relay,HIGH);
        Serial.println("LIGHT ON");
        }

        else if(t.hour == OffHour && t.min == OffMin){
          digitalWrite(Relay,LOW);
          Serial.println("LIGHT OFF");
        }
      if(t.hour == On2Hour && t.min == On2Min){
        digitalWrite(Relay,HIGH);
        Serial.println("LIGHT ON");
        }

        else if(t.hour == Off2Hour && t.min == Off2Min){
          digitalWrite(Relay,LOW);
          Serial.println("LIGHT OFF");
        }
    }

body:
I am posting a code please try it may be it can help you

        #include "RTClib.h"

    RTC_DS3231 rtc;

    char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

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

    #ifndef ESP8266
      while (!Serial); // wait for serial port to connect. Needed for native USB
    #endif

      if (! rtc.begin()) {
        Serial.println("Couldn't find RTC");
        Serial.flush();
        abort();
      }

      if (rtc.lostPower()) {
        Serial.println("RTC lost power, let's set the time!");
        // When time needs to be set on a new device, or after a power loss, the
        // following line sets the RTC to the date & time this sketch was compiled
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        // This line sets the RTC with an explicit date & time, for example to set
        // January 21, 2014 at 3am you would call:
         rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
      }

      // When time needs to be re-set on a previously configured device, the
      // following line sets the RTC to the date & time this sketch was compiled
      // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      // This line sets the RTC with an explicit date & time, for example to set
      // January 21, 2014 at 3am you would call:
      // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }

    void loop () {
        DateTime now = rtc.now();

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(" (");
        Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
        Serial.print(") ");
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.println();

        Serial.print(" since midnight 1/1/1970 = ");
        Serial.print(now.unixtime());
        Serial.print("s = ");
        Serial.print(now.unixtime() / 86400L);
        Serial.println("d");

        // calculate a date which is 7 days and 30 seconds into the future
        DateTime future (now + TimeSpan(7,12,30,6));

        Serial.print(" now + 7d + 30s: ");
        Serial.print(future.year(), DEC);
        Serial.print('/');
        Serial.print(future.month(), DEC);
        Serial.print('/');
        Serial.print(future.day(), DEC);
        Serial.print(' ');
        Serial.print(future.hour(), DEC);
        Serial.print(':');
        Serial.print(future.minute(), DEC);
        Serial.print(':');
        Serial.print(future.second(), DEC);
        Serial.println();

        Serial.print("Temperature: ");
        Serial.print(rtc.getTemperature());
        Serial.println(" C");

        Serial.println();
        delay(3000);
    }

Upload the above code and then upload the same code just comment the following part

    if (rtc.lostPower()) {
            Serial.println("RTC lost power, let's set the time!");
            // When time needs to be set on a new device, or after a power loss, the
            // following line sets the RTC to the date & time this sketch was compiled
            rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
            // This line sets the RTC with an explicit date & time, for example to set
            // January 21, 2014 at 3am you would call:
             rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
          }

This will work and even if you plug and unplug it from power the RTC time will not reset


body: I will take a SWAG as I do not know what module you are having problems. Remove the battery, power it up and measure the voltage at the battery terminals. If you have about 3.2V the module is designed to charge the battery (thought you might like to know). Power down the module insert the battery, do not power it up, and measure the battery voltage at the chip. Be sure to also check the ground side. I believe you will find the same thing I did, the solder connection to the battery holder was open, just added some solder and that solved it. I also found the SCL line was  broken on the board so if I connected the other side it would not work. I added a jumper to fix it. I purchased several from azon but only the first one was bad.


message:
Can I use this camera switcher?

I am wondering can I use this bicks camera switcher with the arduino since it uses a PWM signal.[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/i9atQ.jpg
If i can do I just put it on one of the PWM outputs or do I need to wire I add something to make it work.
**You can find the user manual here under attachments.**https://store.bicks.us/multiview/20-bicks-s-multiview-duo-fpv-camera-switcher.html

body: The pwm output of an RC receiver is the same signal used to control a servo. So if you used the servo library with Arduino to control the pwm of this device it should work fine.


message:
Bluetooth module(HC 05) issues

I am trying to make a Bluetooth controlled 4WD robot. i was following a tutorial i found online (https://howtomechatronics.com/tutorials/arduino/arduino-robot-car-wireless-control-using-hc-05-bluetooth-nrf24l01-and-hc-12-transceiver-modules/). After successfully connecting my 2 HC 05 Bluetooth module i used the script from the tutorial and modified it slightly so it would work for my set up.
The code for the robot:

    //Code for Slave
    #define enA 9
    #define in1 8
    #define in2 7
    #define enB 10
    #define in3 6
    #define in4 5
    int xAxis, yAxis;
    unsigned int  x = 0;
    unsigned int  y = 0;
    int motorSpeedA = 0;
    int motorSpeedB = 0;
    void setup() {
      pinMode(enA, OUTPUT);
      pinMode(enB, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      Serial.begin(9600); // Default communication rate of the Bluetooth module
    }
    void loop() {
      // Default value - no movement when the Joystick stays in the center
      x = 510 / 4;
      y = 510 / 4;
      // Read the incoming data from the Joystick, or the master Bluetooth device
      while (Serial.available() >= 2) {
        x = Serial.read();
        Serial.print("X: ");
        Serial.println(x);
        delay(10);
        y = Serial.read();
        Serial.print("Y: ");
        Serial.println(y);
      }
      delay(10);
      // Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
      xAxis = x*4;
      yAxis = y*4;
      // Y-axis used for forward and backward control
      if (yAxis < 470) {
        backMov;
        // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
        motorSpeedA = map(yAxis, 470, 0, 0, 255);
        motorSpeedB = map(yAxis, 470, 0, 0, 255);
      }
      else if (yAxis > 550) {
        fowardMov;
        // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
        motorSpeedA = map(yAxis, 550, 1023, 0, 255);
        motorSpeedB = map(yAxis, 550, 1023, 0, 255);
      }
      // If joystick stays in middle the motors are not moving
      else {
        motorSpeedA = 0;
        motorSpeedB = 0;
      }
      // X-axis used for left and right control
      if (xAxis < 470) {
        // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
        int xMapped = map(xAxis, 470, 0, 0, 255);
        // Move to left - decrease left motor speed, increase right motor speed
        motorSpeedA = motorSpeedA + xMapped;
        motorSpeedB = motorSpeedB - xMapped;
        // Confine the range from 0 to 255
        if (motorSpeedA > 255) {
          motorSpeedA = 255;
        }
        if (motorSpeedB < 0) {
          motorSpeedB = 0;
        }
      }
      if (xAxis > 550) {
        // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
        int xMapped = map(xAxis, 550, 1023, 0, 255);
        // Move right - decrease right motor speed, increase left motor speed
        motorSpeedA = motorSpeedA - xMapped;
        motorSpeedB = motorSpeedB + xMapped;
        // Confine the range from 0 to 255
        if (motorSpeedA < 0) {
          motorSpeedA = 0;
        }
        if (motorSpeedB > 255) {
          motorSpeedB = 255;
        }
      }
      // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
      if (motorSpeedA < 70) {
        motorSpeedA = 0;
      }
      if (motorSpeedB < 70) {
        motorSpeedB = 0;
      }
      analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
      analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
    }
    void fowardMov(){
      digitalWrite(in2,HIGH);
      digitalWrite(in4,HIGH);
      digitalWrite(in1, LOW);
      digitalWrite(in3, LOW);
    }

    void backMov(){
      digitalWrite(in1,HIGH);
      digitalWrite(in3,HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(in4, LOW);
    }

The code for the Controller:

    #define Xaxis A0
    #define Yaxis A1

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

    void loop() {
      // put your main code here, to run repeatedly:
     Serial.write(analogRead(Xaxis)/4);
     Serial.write(analogRead(Yaxis)/4);
     delay(20);
    }
After uploading the code i tried to move it but it wasn't working so i put print statements to see the value of X and Y. initially it didn't work so i swapped the Bluetooth modules i had and reconnected them. i also changed this line.

     while (Serial.available() >= 2)
To this

     if (Serial.available() > 0)
i started to receive values from the master to the slave but  i noticed the values were the same for x and y so i searched for another tutorial on the internet and found this (https://create.arduino.cc/projecthub/andriy-baranov/arduino-4wd-rc-car-639953?ref=similar&ref_id=18369&offset=3) reading his code i wondered how did the slave work. According to the official Arduino documentation Serial.read() does not take in any arguments but i still tried it and it didn't work. I decided to retry the code from the first tutorial i checked this time it looked like it was working so i tried moving the joystick and the serial monitor printed correct values for both at first then it swaps their values then freezes. How can i stop it from freezing and swapping the values? Also why doesn't the while loop run forever isn't the amount of data in the serial buffer always higher than 2? Thank you.[![diagram of slave][1]][1]

[![diagram of master][2]][2]

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

body: Your setup is WAY too complex!  Simplify your setup to the point where it only deals with just the piece that is giving you problems; in your case serial port comms between master and slave.  Solve JUST THAT problem, and then move on


body:
There is an issue with the way in which the data is sent and received because it assumes the transmission will remain perfectly synchronised for the lifetime of the programme. Consider what would happen if one byte were to be dropped due to a communication error – the x and y data would be swapped for further transmissions.

**Original Sender**

```cpp
void loop() {
  // put your main code here, to run repeatedly:
 Serial.write(analogRead(Xaxis)/4);
 Serial.write(analogRead(Yaxis)/4);
 delay(20);
}
```

**Original Receiver**

```cpp
void loop() {
  // Default value - no movement when the Joystick stays in the center
  x = 510 / 4;
  y = 510 / 4;
  // Read the incoming data from the Joystick, or the master Bluetooth device
  while (Serial.available() >= 2) {
    x = Serial.read();
    Serial.print("X: ");
    Serial.println(x);
    delay(10);
    y = Serial.read();
    Serial.print("Y: ");
    Serial.println(y);
  }
  delay(10);
  . . .
}
```

Therefore, there needs to be a way to synchronise to the first byte of the message. This can be achieved by using message packets where the start and end of the message are delimited with unique characters, e.g. `{` and `}`, similar to the [JSON format][1].

As another example, the [NMEA GPS][2] standard uses `$` and `\n` to delimit messages, and `,` to delimit fields. It also has a checksum at the end.

Here is a non-blocking algorithm which builds upon [Majenko's `readline()` example][3] and the [Blink Without Delay example][4] to read a packet. `ReadPacket()` returns true when incoming data has been accumulated into a valid packet. The LED is flashed to indicate that the MCU hasn't frozen.

**New Sender**

```cpp
void loop()
{
    Serial.print("{");                  // First character delimiter.
    Serial.print(analogRead(Xaxis));    // Full resolution. No need to divide by 4.
    Serial.print(",");                  // Field delimiter.
    Serial.print(analogRead(Yaxis));    // Full resolution. No need to divide by 4.
    Serial.print("}");                  // Last character delimiter.
    delay(20);
}
```

**New Receiver**

```cpp
void loop()
{
    //
    // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
    //
    const unsigned int INTERVAL = 250;
    unsigned long current_timestamp = millis();
    static unsigned long previous_timestamp = current_timestamp;
    static bool led_state = false;
    if (current_timestamp - previous_timestamp >= INTERVAL)
    {
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_timestamp += INTERVAL;
    }

    //
    // TASK 2: Read and parse data packet.
    //
    static char packet[100];
    const byte NUM_FIELDS = 2;
    unsigned int fields[NUM_FIELDS];
    static unsigned int x = 512;   // Full resolution. No need to divide by 4.
    static unsigned int y = 512;   // Full resolution. No need to divide by 4.
    bool new_x = false;
    bool new_y = false;
    if (ReadPacket(Serial, packet, sizeof(packet)))
    {
        Serial.print(F("Received packet >"));
        Serial.print(packet);
        Serial.println(F("<"));

        // Parse the packet for x and y values at full resolution.
        const char delimiters[] = "{,}";
        char* field;
        int i = 0;
        field = strtok(packet, delimiters);
        while (field != NULL && i < NUM_FIELDS)
        {
            Serial.print("field = ");
            Serial.println(field);
            fields[i] = atoi(field);
            Serial.print("fields[");
            Serial.print(i);
            Serial.print("] = ");
            Serial.println(fields[i]);
            field = strtok(NULL, delimiters);
            i++;
        }
        if (i == NUM_FIELDS)
        {
            if (x != fields[0])
            {
                new_x = true;
                x = fields[0];  // Full resolution. No need to multiply by 4.
                Serial.print("New x = ");
                Serial.println(x);
            }
            if (y != fields[1])
            {
                new_y = true;
                y = fields[1];  // Full resolution. No need to multiply by 4.
                Serial.print("New y = ");
                Serial.println(y);
            }
        }
    }

    Serial.print("x = ");
    Serial.println(x);
    Serial.print("y = ");
    Serial.println(y);

    //
    // TASK 3: Process x and y values.
    //
    if (new_x || new_y)
    {
        Serial.println("Processing new values.");

        . . .
    }
}

bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
    const char FIRST = '{';
    const char LAST = '}';
    static bool read_until_last = false;
    static unsigned int i = 0;
    char ch;

    if (stream.available())
    {
        ch = stream.read();

        if (ch == FIRST)
        {
            Serial.println(F("Received FIRST."));
            i = 0;
            packet[0] = ch;
            read_until_last = true;
            return false;
        }
        if (read_until_last)
        {
            i++;
            if (i > SIZE - 2)
            {
                Serial.println(F("Buffer overrun. Resetting to look for next packet."));
                i = 0;
                read_until_last = false;
                return false;
            }
            if (ch == LAST)
            {
                Serial.println(F("Received LAST."));
                packet[i++] = ch;
                packet[i] = 0;
                read_until_last = false;
                return true;
            }
            else
            {
                Serial.print(F("Received char >"));
                Serial.print(ch);
                Serial.println("<");
                packet[i] = ch;
                return false;
            }
        }
    }
    return false;
}
```

  [1]: https://en.wikipedia.org/wiki/JSON
  [2]: https://www.gpsworld.com/what-exactly-is-gps-nmea-data/
  [3]: https://majenko.co.uk/blog/reading-serial-arduino
  [4]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay/


message:
Is it possible to upload and run code from EEPROM during boot time?

I am having problems while writing custom bootloader, so that it uploads code from EEPROM (for now internal, as I have no external memory in my hands) and writes into flash. After ~2 weeks of struggling I encountered these [question and answers][1]. After that, I realized that I made a mistake not checking the possibility of it. However, I am still confused about several things:

1. If Harvard Architecture limits what I want, how come optiboot can flash the memory from incoming UART data, which is not even a memory?

2. If UART reads and flashes memory accordingly, cant I do the same with EEPROM? Read bytes, erase flash, write bytes.

3. If it is not possible, given two answers in above link, then how does [this][2] work? I guess, it is the same logic as I want, using external memory and rewriting flash. Does it mean Harvard Architecture limits only internal memory exchange?

**UPDATE:** Here is what I have done for now:

In separate sketch, EEPROM is filled with binary code. Bootloader (edited optiboot v8):

```
  // Set up watchdog to trigger after desired timeout
  watchdogConfig(WDTPERIOD);
#if BIGBOOT

  if ((eeprom_read(0x000) == 0x0C) && (eeprom_read(0x001) == 0x94))
  {
    //while (EECR & (1 << EEPE)); //wait if previous data is still being written
    uint8_t i, j;

    for (i = 0; i < 8; ++i) // 8 pages total
    {
      uint8_t *code;
      code = buff.bptr;
      address.word = (i * 128);

      for (j = 0; j < 128; ++j)  // 128 words at a time
      {
        if (j % 64 == 0)
          LED_PORT ^= _BV(LED);

        *code++ = eeprom_read(address.word + j);
      }

#ifdef VIRTUAL_BOOT_PARTITION
      virtualBootPartition(buff, address);
#endif

      writebuffer(0x46, buff, address, 128);
    }

    while(1); // wait for WDT
  }
#endif

#if (LED_START_FLASHES > 0) || LED_DATA_FLASH || LED_START_ON
  /* Set LED pin as output */
  LED_DDR |= _BV(LED);
#endif
```

while my function looks like this:

```
#if BIGBOOT
static uint8_t eeprom_read(uint16_t addr)
{
  EEAR = addr; //read from that address
  EECR |= (1 << EERE); //enable reading

  return EEDR;
}
#endif
```

I use `make atmega328 BIGBOOT=1` to generate hex file. It does not work + UART uploading also fails. If I set `BIGBOOT` to 0 and generate, UART uploading works fine.

P.S. `virtualBootPartition` is function which is called in `STK_PROG_PAGE` case. In order to not repeat the same piece of code, I collected that part into the function.

```
#ifdef VIRTUAL_BOOT_PARTITION
/*
 *              How the Virtual Boot Partition works:
 * At the beginning of a normal AVR program are a set of vectors that
 * implement the interrupt mechanism.  Each vector is usually a single
 * instruction that dispatches to the appropriate ISR.
 * The instruction is normally an rjmp (on AVRs with 8k or less of flash)
 * or jmp instruction, and the 0th vector is executed on reset and jumps
 * to the start of the user program:
 * vectors: jmp startup
 *          jmp ISR1
 *          jmp ISR2
 *             :      ;; etc
 *          jmp lastvector
 * To implement the "Virtual Boot Partition", Optiboot detects when the
 * flash page containing the vectors is being programmed, and replaces the
 * startup vector with a jump to te beginning of Optiboot.  Then it saves
 * the applications's startup vector in another (must be unused by the
 * application), and finally programs the page with the changed vectors.
 * Thereafter, on reset, the vector will dispatch to the beginning of
 * Optiboot.  When Optiboot decides that it will run the user application,
 * it fetches the saved start address from the unused vector, and jumps
 * there.
 * The logic is dependent on size of flash, and whether the reset vector is
 * on the same flash page as the saved start address.
 */

#if FLASHEND > 8192
/*
 * AVR with 4-byte ISR Vectors and "jmp"
 * WARNING: this works only up to 128KB flash!
 */
#if FLASHEND > (128*1024)
#error "Can't use VIRTUAL_BOOT_PARTITION with more than 128k of Flash"
#endif
  if (address.word == RSTVEC_ADDRESS) {
 // This is the reset vector page. We need to live-patch the
 // code so the bootloader runs first.
 //
 // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];

        // Add "jump to Optiboot" at RESET vector
        // WARNING: this works as long as 'main' is in first section
    buff.bptr[rstVect0] = ((uint16_t)pre_main) & 0xFF;
    buff.bptr[rstVect1] = ((uint16_t)pre_main) >> 8;

#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
// the save_vector is not necessarilly on the same flash page as the reset
//  vector.  If it isn't, we've waiting to actually write it.
  }
  else if (address.word == SAVVEC_ADDRESS) {
   // Save old values for Verify
   saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
   saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

   // Move RESET jmp target to 'save' vector
   buff.bptr[saveVect0 - SAVVEC_ADDRESS] = rstVect0_sav;
   buff.bptr[saveVect1 - SAVVEC_ADDRESS] = rstVect1_sav;
  }
#else
        // Save old values for Verify
        saveVect0_sav = buff.bptr[saveVect0];
 saveVect1_sav = buff.bptr[saveVect1];

        // Move RESET jmp target to 'save' vector
        buff.bptr[saveVect0] = rstVect0_sav;
        buff.bptr[saveVect1] = rstVect1_sav;
}
#endif

#else
/*
 * AVR with 2-byte ISR Vectors and rjmp
 */
  if (address.word == rstVect0) {
    // This is the reset vector page. We need to live-patch
    // the code so the bootloader runs first.
    //
    // Move RESET vector to 'save' vector
   // Save jmp targets (for "Verify")
    rstVect0_sav = buff.bptr[rstVect0];
    rstVect1_sav = buff.bptr[rstVect1];
    addr16_t vect;
    vect.word = ((uint16_t)pre_main-1);
    // Instruction is a relative jump (rjmp), so recalculate.
    // an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
    // do math on the offsets without masking it off first.
    // Note that rjmp is relative to the already incremented PC, so the
    //  offset is one less than you might expect.
    buff.bptr[0] = vect.bytes[0]; // rjmp to start of bootloader
    buff.bptr[1] = vect.bytes[1] | 0xC0;  // make an "rjmp"
#if (SAVVEC_ADDRESS != RSTVEC_ADDRESS)
  }
  else if (address.word == SAVVEC_ADDRESS) {
 addr16_t vect;
 vect.bytes[0] = rstVect0_sav;
 vect.bytes[1] = rstVect1_sav;
 // Save old values for Verify
 saveVect0_sav = buff.bptr[saveVect0 - SAVVEC_ADDRESS];
 saveVect1_sav = buff.bptr[saveVect1 - SAVVEC_ADDRESS];

 vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0 - SAVVEC_ADDRESS] = vect.bytes[0];
  buff.bptr[saveVect1 - SAVVEC_ADDRESS] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  }
#else

  // Save old values for Verify
  saveVect0_sav = buff.bptr[saveVect0];
  saveVect1_sav = buff.bptr[saveVect1];

  vect.bytes[0] = rstVect0_sav;
  vect.bytes[1] = rstVect1_sav;
  vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
  // Move RESET jmp target to 'save' vector
  buff.bptr[saveVect0] = vect.bytes[0];
  buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
  // Add rjmp to bootloader at RESET vector
  vect.word = ((uint16_t)pre_main-1); // (main) is always <= 0x0FFF; no masking needed.
  buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
}

#endif
#endif // FLASHEND
#endif // VBP
```

  [1]: https://arduino.stackexchange.com/questions/3828/is-it-possible-to-run-a-binary-from-eeprom
  [2]: https://github.com/FleetProbe/MicroBridge-Arduino-ATMega2560/

body:
If you have a sketch which can write its updated version into EEPROM of ATmega328p and then boootload from the EEPROM, then you can use the flash for the same purpose. The ATmega328p has 32kB of flash and only 1kB EEPROM.

For my ArduinoOTA library I developed a way to store the uploaded binary in upper half of the flash and then let the bootloader copy the binary to address 0 and reset the MCU.

The Optiboot 8 has do_spm() function. This function can be called from the sketch to write to flash memory.

To copy the binary stored in upper half of the flash to address 0, I wrote a new function for the Optiboot. It is called copy_flash_pages and has an extra boolean parameter to request a reset of MCU after copying the pages.

For network upload the sketch size is larger then half of the flash of 328p because of the networking library. So ArduinoOTA is only for ATmega with more then 64kB flash.

If you have a way how to get the binary of size less then half of the 328p flash, then you can write it to the upper half of the flash and then use my copy_flash_pages function to bootload it.

Resources:

* [header file][1] to access the Optiboot functions from sketch
* boards definition and bootloader for 328p with Optiboot with copy_flash_pages function in [my_boards][2] (note the changed fuses in boards.txt for Uno/Nano/Mini)
* the [InternalStorageAVR][3] class in ArduinoOTA library as example how to store and apply the binary

Example of InternalStorage use:
```
  if (!InternalStorage.open(length)) {
    Serial.println("There is not enough space to store the update. Can't continue with update.");
    return;
  }
  byte b;
  while (length > 0) {
    if (!source.readBytes(&b, 1)) // reading a byte with timeout
      break;
    InternalStorage.write(b);
    length--;
  }
  InternalStorage.close();
  if (length > 0) {
    Serial.print("Timeout downloading update file at ");
    Serial.print(length);
    Serial.println(" bytes. Can't continue with update.");
    return;
  }
  Serial.println("Sketch update apply and reset.");
  InternalStorage.apply(); // this doesn't return
```

  [1]: https://github.com/jandrassy/ArduinoOTA/blob/master/src/utility/optiboot.h
  [2]: https://github.com/jandrassy/my_boards
  [3]: https://github.com/jandrassy/ArduinoOTA/blob/master/src/InternalStorageAVR.cpp


message:
Can you use Serial Port as a variable?

I am doing a project where, for troubleshooting reasons, I find myself often swapping components to different serial ports. Maybe one time it's in Serial, then in Serial1, maybe I need to try if software serial works.

But changing every line where Serial.print or Serial.write is written for the new port is a hassle and easy to screw up.

Would it be possible to either create a definition at the beginning of the code that lets me rename Serial to SensorSerial so just by changing that definition I am sure it will use the correct port?

body:
Yes. The simplest way is with a preprocessor macro. Macros get replaced verbatim before compilation happens, so you can do something like:

```
#define MY_SERIAL Serial

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

void loop() {
    MY_SERIAL.println(millis());
    delay(1000);
}
```


body:
Majenko's answer is the right answer for your question. But to answer the title of the question, if you ever need to use different Arduino outputs and inputs as variable, most of them have common type Stream or Print. So it would be:
```
Stream& SensorSerial = Serial;
```
 or
```
Stream* SensorSerial;
SensorSerial = &Serial;
```
The Arduino Stream classes hierachy:

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

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


message:
Hc-05 bluetooth module pairing issue

Module light is blinking/working but it's not showing for pairing in my smart phone.I have supplied it 3.3 volts and have tried different phones.[![enter image description here][1]][1]

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

body:
It won't pair directly you will need other apps for pairing the modules. Try using this [app][1]. It will solve your issue for sure

  [1]: https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&hl=en&gl=US


body:
I put together a complete tutorial on using the HC-05 in the Arduino environment for remote programming.  You can see it [here][1]

  [1]: https://www.fpaynter.com/2019/06/arduino-remote-programming-using-a-hc-05-bluetooth-module/


message:
Why is my transistor switched output so low?

Help needed! I am using an Arduino Nano and a general purpose npn (2n2222a) transistor to provide a 12v signal to a low current 12vdc load in an automobile. The Arudino code is set to pulse D2 at bootup/startup for .5 second. The PWM output setting was 255 (since switched to digitalWrite). However, the switched output measures only 4.5v (expected close to 12v). What am i doing wrong?
Applying 12v+ directly to the black box works. The purpose is to simulate a temporary button push in the car so an auto function is enabled.

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

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

body:
The 2N2222 is an [*NPN*](https://www.electronics-tutorials.ws/transistor/tran_2.html) device. Skipping all of the physics involved, that means that (in your application) it will ***sink*** current as a *low-side switch*, but not ***source*** current as a *high-side switch*.

If you want a *high-side switch*, you should find a *PNP* transistor. In this case your Nano pin will **sink** current from the transistor's base terminal.

I would recommend you stick with the 2N2222, but make two changes:

1. Connect your "black box" between the positive terminal (+) of your 12V supply, and the **collector** terminal of the 2N2222.

2. Reduce the size of your base resistor from 10Kohms to 1Kohms


body:
What I have thought about is using an opto-coupler
[![enter image description here][1]][1]

Connect the Arduino pin output to pin 1 through 330 ohms resistor, pin 2 to ground of Arduino, connect pin 4 to Vcc of 12 V and finally connect pin 3 to the black box load.

Try this configuration

Since black box only needs few milliamps as you said
May be the transistor is not ***saturated*** since base current has to go through the black box load opto-coupler s have ***no base current instead they use photons***

Here is the circuit diagram

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

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

5 V supply looks like the Arduino pin D2 and lamp is the black box load.
This is 4N35 example


body:
The problem is that you are using an NPN transistor as a high side switch.

The voltage at the emitter of the transistor will always be about 0.7V below the voltage at the base.  The "high" output from the Arduino is 5V.  The emitter will be at about 4.3V.

Have a look at the Wikipedia ["emitter follower"](https://en.wikipedia.org/wiki/Common_collector) page.  The emitter follower is also called a common collector circuit. That explains the "problem" in more detail.  It is only a problem in so far as it is not the correct solution for your task.

You need to use a ["common emitter"](https://en.wikipedia.org/wiki/Common_emitter) circuit.

This usage is commonly called a "low side switch."

That would look like this:

<!-- 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/FoH9v.png)

<!-- End schematic -->

If your black box really needs its input pulled up to 12V, then you would do something like this:

<!-- 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/DcNCM.png)

<!-- End schematic -->

The resistor values and transistor part numbers are place holders.  The values of resistors you will need depends on the transistors you use.  The transistor selection will depend on how much current you need to deliver to the black box.

I see in a comment that your black box only needs a few milliamperes.  In that case, the shown transistors should work just fine.  The resistor values may be a little too high, but I think they'll be OK.

------

A couple of additional points:

1. The Arduino has PWM outputs, not PCM.
2. The output voltage for your black box will be pulsing if you use any PWM value lower than 255.  Your black box probably won't like that, and your voltmeter won't read a correct voltage.

You should use D2 as a digital output rather than PWM.  Just turn it on or off rather than fiddling with the PWM duty cycle.  Use ["digitalWrite"](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/) instead of ["analogWrite"](https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/) on pin D2.


body:
[![enter image description here][1]][1]ok, so i chose the 2 transistor high side circuit as i had the needed pnp transistor laying around. Works great, thanks everyone for your help. The trace (5v/div) shows the Arduino signal at 5v and the circuit output at 12v - perfect!
[![enter image description here][2]][2]
[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/ReotF.jpg
  [2]: https://i.stack.imgur.com/TPelO.jpg
  [3]: https://i.stack.imgur.com/U1ZEK.jpg


message:
Set control register to low in ds3231 rtc

I have been using ds3231 rtc module for keep tracking and make alarm along with backup battery. when I used it for first time it worked fine. but now it doesn't keep track my time when the power lose it from main power but I have checked that my battrey is in safe. So I search in lot of forums they said EOSC bit was set high that would be stoped the clock as it stops the internal oscillator. also want to set it into low then only rtc keep track of the time

but in another some forums they instructed that put this following code for set it to low

    DS3231 RTC;

      Wire.beginTransmission(0x68);
      Wire.write(0xF);                            // Address the Status register
      Wire.write(0x00);                           //  Zero the Status register
      Wire.endTransmission();
      Wire.beginTransmission(0x68);
      Wire.write(0xE);                            // Address the Status register
      Wire.write(0x00);                           //  Zero the Status register
      Wire.endTransmission();

      RTC.setA2Time( ADay, AHour, AMin, 0x00, true, false, false);
      delay(100);
      RTC.turnOnAlarm( 2 );

in another place showed the following code

    // clear /EOSC bit to ensure that the clock runs on battery power
      Wire.beginTransmission(0x68); // address DS3231
      Wire.write(0x0E); // select register
      Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
      Wire.endTransmission();

but now problem is that where should I want to place this code and how  to past it in proper manner for keep tracking the time when ds3231 loses power too? please any know about this problem because I finded so many people are strugling with this issue when they come forward to use this ds3231 rtc module. if any body know about how to solve this issue plese consider to share your idea this will definately help full for evryone because there is no one properly answer for this issue

body:
From the DS3231 data sheet:

**Control Register (0Eh)**

Bit 7: Enable Oscillator (EOSC). When set to logic 0, the oscillator is started. When set to logic 1, the oscillator is stopped when the DS3231 switches to VBAT. This bit is clear (logic 0) when power is first applied. When the DS3231 is powered by VCC, the oscillator is always on regardless of the status of the EOSC bit. When EOSC is disabled, all register data is static.

**Status Register (0Fh)**

Bit 7: Oscillator Stop Flag (OSF). A logic 1 in this bit indicates that the oscillator either is stopped or was stopped for some period and may be used to judge the validity of the timekeeping data. This bit is set to logic 1 any time that the oscillator stops. The following are examples of conditions that can cause the OSF bit to be set:
1) The first time power is applied.
2) The voltages present on both VCC and VBAT are insufficient to support oscillation.
3) The EOSC bit is turned off in battery-backed mode.
4) External influences on the crystal (i.e., noise, leakage,etc.).
This bit remains at logic 1 until written to logic 0.

I dug out an old D3231 board. It had a battery in it but was last set ~3 years ago and I am not sure how old the battery was when I first put it in the board. The battery cannot keep the clock running. When I attached it to an Arduino UNO and booted up, the clock’s registers read as follows (just pay attention to the time and the EOSC bit and the OSF flag):

CLOCK: 00:01:15 (24h clock) Sunday, 01/01/2000  Temperature=21C  Aging offset=0

Alarm #1: 00:00:00 (24h clock) DY/DT=18[DoM mode]   Alarm selection: when date, hours, minutes and seconds match

Alarm #2: 00:00 (24h clock) DY/DT=20[DoM mode]  Alarm selection: when date, hours, minutes match

CONTROL byte=00011100 /EOSC is ON /BBSQW is Disabled /CONV is clear /INTCN mode is Match /Alarm 1 is Disabled /Alarm 2 is Disabled

STATUS byte=10000000 /OSF is ON /EN32KHZ Disabled /BSY is OFF /A1F is OFF /A2F is OFF

The clock is now running because with VCC supplied by the Arduino, the oscillator will always run. When I read the clock, I can see the time advancing, but it started from 00:00:00

Now, I remove power and after a minute or so, power up the UNO and the clock, and read the clock. It is again running, but the time had not advanced – it simply restarted from 00:00:00. EOSC is ON. OSF is ON.

With no VBAT, the time was not preserved.

A fresh battery is inserted and I power up. The clock is again running, again, restarted at 00:00:00. EOSC is ON. OSF is ON.

After a couple of minutes, I power down (with the fresh battery still in the clock). When I boot up and read the clock, it is running AND it kept running on battery power, so the current time is accurate. EOSC is ON. OSF is ON.

EOSC was always enabled (read as 0) – that is the POR value. Unless your program explicitly sets the bit to 1, EOSC will reliably be enabled. If you do disable EOSC (set to 1), the oscillator will NOT run off of the battery backup (VCC off and VBAT on). With EOSC disabled, and if there is enough juice in the battery, it will hold the time (and other registers) when VCC is switched off and VBAT is on. When VCC is on, the oscillator will always run.

But, what about the OSF flag?

Reading the data sheet, you can see that the OSF flag gets set when the oscillator stops, which can occur from a number of conditions.

It is designed so that the software can legitimately suspect that the time is not accurate, But, OSF is set as the POR value.

**You need to enable EOSC AND CLEAR OSF**, every time you do a clean power up and every time OSF got set because you unplugged (no VCC) and changed batteries. Also, remember, that with VCC, the oscillator will run regardless of the state of the EOSC bit.

Do not ignore OSF, it is an important flag and it should not be getting set regularly. In fact, once you insert a battery and clear OSF, it should not be set again until the battery drains. If it is getting set regularly, you have problems elsewhere.

Some software reads OSF and if it is set, the software will balk and tell you as much, as it should. Since OSF is set on POR, it will be set whenever you remove VCC and VBAT and then power up again.

**You need to explicitly clear OSF AND know why it got set.**

This code snippet, enables EOSC AND clears OSF.

     // enable EOSC and clear OSF flag
     // *** The other bits in these two registers are writtten
     // with POR Values or '0' if POR value=X.
      Wire.beginTransmission(0x68); // address DS3231
      Wire.write(0x0E); // select CONTROL register
      Wire.write(0b000011100); // write register (bit 7 is EOSC)
      Wire.endTransmission();
      Wire.beginTransmission(0x68);
      Wire.write(0x0F); // select STATUS register
      Wire.write(0b00001000); // write register (bit 7 is OSF)
      Wire.endTransmission();

Hope it helps.


message:
L239D motor driver not able to drive motors

I am making a line follower robot. The issue is trying to make the motors run.

The L239D module has 4 input pins (to control two motors), 4 output pins (to drive motors), and 6 power pins (5V, 5V, GND, GND, 9/12V, and 9/12V).

I have used one 5V pin to connect it to an Arduino's 5V supply and one of the 9/12V pins to two 9V batteries in series.

The motors are barely running and when the robot is on the ground it is not able to move. I even tried three 9V batteries in series to get the voltage up to 27V but it doesn't help.

body:
9 V batteries, assuming you mean the little PP3-size ones, can't supply the current needed for driving robot motors; they are intended for low-current applications.

Putting them in series will give you a higher voltage, not more current, and the higher voltage could damage something else in the circuit.

*Assuming you connected everything correctly, including ground:* you need bigger batteries. Even 6 AAs in series would be much better than using a 9V battery for getting your robot to move.


body: On your next try use a different H-Bridge, one with MOSFET outputs, you can have a voltage drop across the L239D of 2.4V. Measure the voltage at the motor and at your batteries you will see what I am getting at. You might want to try connecting the motors directly to the battery first to see if it will do what you want.


body: I guess using 9 Volt battery in parallel will do your work because if the motor is moving as you quoted above means it is getting the voltage but not enough current to drive it, please connect the 9 volt battery in parallel and it will work for you


message:
I want to make two arduino to communicate over different wifi. Is that possible?

I want to make any 2 Arduino module from different places to communicate over wifi. I really need to know if it possible? If yes, advice me more about it. I want send data from sensor module from one Arduino to another and vice versa. That's the basic idea. Do I need a third party services such as cloud services to make it happen? Or simply can send ovee wifi with the help of Ip adress. Sorry, I have less knowledge on this. Help me out. Thank you in advance.

body:
If they are on the same (wifi) network; then yes.

If you are on a different network, it would be more difficult. You would have to setup port forwarding on your router. Then you would have to somehow know the public IP address of the other router. These addresses can change from time to time with certain ISPs. I wouldn't advice doing this.

Instead I'd go with an third party service. For example Adafruits offers an MQTT server. I'd probably use this even if they are on the same network.


message:
I need help creating a code that moves a DC motor CW or CCW based off of 2 different buttons

I know I can make the motor move backwards and forwards with buttons but I don't want it to move at full speed. I want it to increment in very small amounts to where it can be adjusted very small amounts at a time. I should also be able to hold the button so it moves continuously. I also have a motor with an encoder on it. Maybe there is a way to use the numbers on the encoder to increment? so press the CW button and now the motor wants to move till the encoder reaches +10 from where it was at? I understand what I want to do, just need help getting there. Thanks

HERE IS THE CODE I FIGURED OUT THAT MAKES MY DC MOTOR INCREMENT CW AND CCW

```

#define MOTOR_DIRECTION_PIN   2
#define MOTOR_SPEED_PIN       3

#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //button inputs
  //pullup so we do not need to include a physical resistor
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);

  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);
  pinMode(MOTOR_SPEED_PIN, OUTPUT);

  Serial.begin(9600);

  Serial.println("test");
}

void loop()
{
  int pushedButtonOne = digitalRead(12);
  int pushedButtonTwo = digitalRead(13);

  if(pushedButtonOne == LOW)
  {
    Serial.println("Button number 1 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CCW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }

  else if(pushedButtonTwo == LOW)
  {
    Serial.println("Button number 2 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }
  else
  {
    Serial.println("nothing has been pushed");
  }

  //delay(100);

}

body:
To formulate the comments into an answer:

In principle it is of course possible to put an encoder onto a DC motor shaft and then drive the motor, until you reach the desired position. But you won't get good precision or accuracy with this. You wrote

> till the encoder reaches +10 from where it was at

Since most encoders have more than 10 tics per full rotation (you didn't specifiy how much yours has), this can mean  rotating only a fraction of a full rotation. Let's assume, that the encoder has 40 tics per full rotation. With 10 tics you have a quarter rotation. It seems you want precision in the range of about 1 tic.

DC motors are made for spinning relatively fast. They don't give you control over the position with steps. They mostly have very few coil/magnet combinations (for example just 2 coils, which are switched internally). Thus you have just an inert motor shaft, which is driven by the motor. It will need time to accelerate and to decelerate. With most motors, you may even get a half or full rotation, when you wanted only a quarter rotation (the 10 tics). Calculating the correct timings to get it any better will be not easy for relatively small reward. DC motors are not made for rotations below a small number of full rotations.

You could tackle that problem by using a geared DC motor. The shaft after the gears will run slower and thus have the explained problem not so badly. Then you have to live with the smaller speed.

**Or you could go a more proper way and just use a stepper motor**, which is made for small steps in the range of sub-full-rotation. It is a bit more difficult to drive (also depending on the driver circuit), but it gives you the position control, that you want. And to rotate continuously: A continuous rotation on a stepper motor is nothing else but step after step taken in fast succession (much like running is a fast succession of steps with your feet).

---

Note: The stepper motor does not have a feedback like an encoder on it. The motor driver will just drive the coils to step the motor. If the motor is stalled or if it is overloaded, you might loose some steps (meaning that the coils are driven for the steps, but the motor doesn't actually move). You could sense that with an additional encoder on the motor shaft. But in most cases that is not necessary. If you just make sure, that the motor is not overloaded at any time, you will be fine. Or you might not worry about some steps being lost sometimes, if the overall precision is good enough. That is your decision.


body:
Here is the code i eventually figured out. It increments my DC Motor basically by activating it for a small amount of time in the direction of whichever button was pushed.

```
#define MOTOR_DIRECTION_PIN   2
#define MOTOR_SPEED_PIN       3

#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //button inputs
  //pullup so we do not need to include a physical resistor
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);

  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);
  pinMode(MOTOR_SPEED_PIN, OUTPUT);

  Serial.begin(9600);

  Serial.println("test");
}

void loop()
{
  int pushedButtonOne = digitalRead(12);
  int pushedButtonTwo = digitalRead(13);

  if(pushedButtonOne == LOW)
  {
    Serial.println("Button number 1 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CCW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }

  else if(pushedButtonTwo == LOW)
  {
    Serial.println("Button number 2 has been pushed");
    digitalWrite(MOTOR_DIRECTION_PIN, MOTOR_DIRECTION_CW);
    analogWrite(MOTOR_SPEED_PIN, 50);
    delay(7);
    analogWrite(MOTOR_SPEED_PIN, 0);
  }
  else
  {
    Serial.println("nothing has been pushed");
  }

}


message:
Measure audio frequency through pulse duration

Hello dear StackExchange users,

i want to develop an Infrared blaster which i can plug into the headphone jack of a phone or console of choice. In order to communicate what frequency to modulate the diode with and how long to send pulses, i simply generate tones for the Arduino to read and interpret.

My problem is that i can't reliably measure the frequency with it. In order to measure the frequency i use an Analog Comparator Interrupt and trigger at falling edge, thus getting always the interrupt after a full pulse occured. I called micros() at every interrupt in order to get the pulse duration, but it was too imprecise. Then i tried using Timer0 with a prescaler of 8 to measure the frequency, but it only counts to 255.

Now i switched over to Timer1 because of it's bigger TCNT register. However for some reason it already overflows at 255 even though i didn't set the OCR1 registers.

This is my current code. Please note that the actual frequency calculation happens in the main loop to not mess with the measurements gained in the ISR.

    const int setFrequencySound = 1000;
    const int receiveDataSound = 2000;
    const int receiveDataEndSound = 3000;

    const int readyMode = 0;
    const int setFrequencyMode = 1;
    const int receiveDataMode = 2;
    const int sendDataMode = 3;

    volatile unsigned long timeBefore;
    volatile unsigned long timeNow;
    volatile unsigned long delta;
    volatile float audioFrequencyBefore;
    volatile float audioFrequency;

    volatile float irFrequency;
    volatile int irData[100];
    volatile int irDataIndex;

    volatile int mode = 0;

    ISR (ANALOG_COMP_vect)
    {
    timeNow = TCNT1;
    Serial.print (timeNow);
    Serial.println (" TCNT1");
    //TCNT1 = 0; //reset timer register
    }

    void setup ()
    {
    Serial.begin (115200);
    Serial.println ("Started.");
    ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
    ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
          | bit (ACIE)    // Analog Comparator Interrupt Enable
          | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on falling edge)

    TCCR1B |= (0 << CS12) | (1 << CS11) | (0 >> CS10); //Activate timer and set prescaler to 8
    TCNT1 = 0; //Reset timer register
    }  // end of setup

    void loop ()
    {
    //Calculate frequency by using the period duration
    //determined through the timestamps captured in
    //ISR method.
    //delta = timeNow - timeBefore;
    audioFrequency = 1000000000.0 / (float(timeNow) * 2.0);

    if (millis() % 1000 == 0)
    {
      Serial.print (audioFrequency, 5);
      Serial.print (" Hz, ");
      Serial.print (timeNow);
      Serial.println (" TCNT0");
    }

    //Do not process the same frequency multiple times
    if (audioFrequency != audioFrequencyBefore)
    {
      switch (mode)
      {
        case readyMode:
          if (audioFrequency == setFrequencySound)
          {
            mode = 1;

            Serial.println ("Start setting IR frequency.");
          }
          else if (audioFrequency == receiveDataSound)
          {
            mode = 2;

            Serial.println ("Start receiving IR data.");
          }
          break;
        case setFrequencyMode:
          irFrequency = audioFrequency + 25000;

          Serial.print ("IR frequency set to ");
          Serial.print (irFrequency, 10);
          Serial.println (" Hz.");

          mode = readyMode;
          break;
        case receiveDataMode:
          if (audioFrequency == receiveDataEndSound)
          {
            Serial.println ("Stop receiving IR data.");

            mode = readyMode;
            irDataIndex = 0;
          }
          else
          {
            irData[irDataIndex] = audioFrequency;

            irDataIndex++;

            Serial.print ("IR pulse received: ");
            Serial.print (irData[irDataIndex]);
            Serial.println (" microsecs.");
          }
          break;
        case sendDataMode:
          Serial.println ("Sending IR data...");
          break;
      }
    }

    audioFrequencyBefore = audioFrequency;

    }  // end of loop

body:
Timer 1 overflows at 255 because that's how it has been configured by
the Arduino core, as it is intended to provide 8-bit PWM. If you want
to use the timer in normal mode, you should undo the Arduino's
initialization by setting `TCCR1A` to zero.

Two comments on the ISR:

```c++
ISR (ANALOG_COMP_vect)
  {
    timeNow = TCNT1;
    Serial.print (timeNow);
    Serial.println (" TCNT1");
    //TCNT1 = 0; //reset timer register
  }
```

First, as has been stated in a previous comment, you should not print
from within an ISR. Also, if you want consistent timing, you should
never reset the timer. Just keep it freely running and use time
differences to get the signal period. Do not worry about the timer
overflowing: if you do the computation with unsigned 16-bit integers
(`uint16_t`), you will be immune to the overflows. If you reset the
timer you will likely loose some ticks, as you can not read it and reset
it in the same clock cycle.

Lastly, I recommend you read about the “input capture” capability of
Timer 1. This is a feature of the timer designed for solving the exact
kind of problem you have here: the timer will automatically record a
timestamp on an external event. You can have this triggered by a rising
or falling edge on input pin 8, or by the analog comparator if you
prefer. This method gives you zero jitter, which cannot be achieved with
code, even running within an interrupt.

------------------------------------------------------------------------

**Edit**: Answering an extra question in the comment.

> Could i connect the audio wire [...] directly to pin 8 and use the
> input capture functionality?

It depends on the shape of the signal that comes out of this wire.
First, you have to make sure the signal always stays between the
electric potentials of GND and Vcc (i.e. 0 – 5 V), otherwise you risk
damaging the Arduino.

Note that if the signal comes from a high impedance source, it can
safely go somewhat beyond this range, as the Arduino has all of its
inputs protected by diodes. You just have to limit the current in the
diodes to less than 1 mA. In other words, for each kΩ of output
impedance, you can extend the (unloaded) acceptable voltage range by 1 V
on each side. If the source is low impedance, you can make it high
impedance simply by adding a 10 kΩ resistor in series.

Second point is, you have to make sure the signal has a large enough
voltage span to make the digital input switch between LOW and HIGH.
According to the datasheet of the ATmega328P, when powered at 5 V the
input thresholds are typically around 2.1 V for switching LOW and 2.6 V
for switching HIGH. The difference between those thresholds provides
some hysteresis, which can help cancelling noise. Note that those are
typical values. If you want _guaranteed_ switching, the signal should go
below 1.5 V to get a guaranteed LOW reading (this is VIL) and
above 3 V to get a guaranteed HIGH reading (VIH).

Note also that, if the input thresholds of the digital pin do not fit
your needs, you can use the analog comparator as a trigger for the input
capture.


message:
esp32 voltage divider readings off

Trying to read from a voltage divider circuit using two 240 Ohm resistors.  Getting a reading of 6.0, when it should be 1.65.  Circuit is powered by a bench 3.3V and both the Huzzah32 and circuit are grounded.  Using USB for the Huzzah32. Any thoughts?
```
  void setup()
{
  Serial.begin(9600);
}
void loop()
{
  int sensorValue = analogRead(A9);
  float voltage = sensorValue * (3.3 / 1023.0);
  Serial.println(voltage);
  delay(1000);
}
```
[![circuit diagram][1]][1]

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

body:
First, ESP32 ADC is 12-bit, not 10-bit. therefore the formula should be:

    float voltage = sensorValue * (3.3 / 4096.0);

Secondly, ESP32 ADC is not really linear, and tend to have lower reading than the actual value. You will need to do some calibration if you want to get a more accurate reading. You can take a look at my github on [esp32-adc-calibrate](https://github.com/e-tinkers/esp32-adc-calibrate).


message:
What is the most efficient voltage divider for Arduino?

I need to make voltage divider, so I could read a battery voltage up to 14.4 V. Could I use very high resistance resistors for that, so the current would be very low (to not to discharge battery)?

On the Internet there are examples with 500 - 2000 ohm resistors, but could I use hundreds of thousands to reduce the current to minimum? Would Arduino's analog input still read the value?

body:
Yes, you can use very high value resistors for your voltage divider.  But the recommended maximum is 10 kohms for the ADC pins.  So the combined resistance of your two resistors should be maximum 10 kohms.

> it is recommended that whatever you connect to the A/D have an output impedance of 10k or less for best accuracy. This is to allow the A/D input capacitor on the sample and hold to charge up in the time allotted to it between switching the input multiplexer over and starting the conversion.

From: *[Input Impedance of A0-A5][1]*

  [1]: https://forum.arduino.cc/index.php?topic=65134.0


body:
The most efficient is not to have a voltage divider at all. Or at least to only have a voltage divider when you actually need one.

My preferred schematic is this:

<!-- 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/hLS3G.png)

<!-- End schematic -->

With this M1 is normally kept turned off by R3. When you want to take a measurement you turn on M2 by setting D3 HIGH (or whatever pin you attached it to) which pulls down the gate of M1 turning it on. This then connects the batter to the voltage divider R1/R2 and allows you to read the voltage at A0.

The voltage divider of 20k / 10k allows you to read up to 15V on the battery, and gives you an output impedance of 6.67kΩ which is within the recommended maximum of 10kΩ for the ATMega's ADC.

During "idle" times when M1 and M2 are both off the only current flowing is the minuscule leakage current through M2 tempered by the large 100kΩ resistor R3 (which itself pales into insignificance compared to the "off" resistance of M2 anyway).

Selecting M1 so that the ON resistance is very small (<0.1Ω) allows you to essentially ignore it in your calculations since that will be swamped by the tolerance of R1 and R2 anyway.  M2 needs to be selected so that it is "logic level" (i.e, with a gate threshold V_GS well below 5V).

This double-FET arrangement should be used rather than just using an N-channel FET in the ground connection of the divider because when that simpler arrangement is turned off the Arduino will be seeing 12V directly connected to A0 which really is not good - you *will* kill the Arduino - so it is important that you switch the "high" side of the network not the "low" side, and to do that requires two FETs.


body:
I was able to implement it with 3 MΩ resistors.
The problem is that the readanalog() function executes 10 reads. So the first one is the right value and then you will not measure the right value anymore.

Solution: A voltage divider with 2.5 MΩ and 500 kΩ with a 470 nF capacitor on the 500 kΩ resistor. The solution with the MOSFET is better. This is easier, and it works (but only for 20 years ).


body:
This is a variation on [Majenko's design above](https://arduino.stackexchange.com/a/78773/47458). It was such a good idea, I couldn't resist submitting this - a *reduced-component-count* version:

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

The [**TPS22810**](https://www.ti.com/product/TPS22810) is a *load switch* that enables or disables Vout (**2.7V ≤ Vin ≤ 18V; Iout ≤ 3A**). The output is determined by the `EN/UVLO` input that may be driven by a 1.8 V, 3.3 V or 5 V GPIO output. This component and the C1 bypass cap replaces 2 FETs and 2 Resistors. The TPS22810 cost is **≈** $0.50 ea. in small quantities.

The TPS22810 will likely find its most useful application as a *high-side switch*, but it seems to serve the purpose of the OP's need for driving a voltage divider also.


body:
Everybody is missing the point here.  The lower limit on the series resistance of the voltage divider is the self-discharge rate of the battery.  For instance, a Li-ion battery loses about 10% of its charge per month.  For a 3000 mAH 18650 cell, that's about 300 mAH per month, meaning about 300/(30X24) = 0.42mA constant drain.  So, for a 8V stack made of 2 18650 cells in series, we get a total series resistance of 8V/0.42 of about 19K-ohms.  IOW, if I put a 19K resistor across an 8V stack, I would get about the same battery drain as the battery would see if I left it completely alone.  As long as the series resistance is much greater than that, it won't affect the battery life at all.  So, if I use 2ea 50K resistors for a total series resistance of 100K, it will have very little effect on battery life.  2ea 50K resistors will present an effective output impedance of about 25K to the ADC input port on a MCU, and that is low enough so there will be little or no distortion of the measured voltage, and any offset can be easily compensated out in software.  Moreover, if you want to go to a higher division ratio (say 4:1 instead of 2:1) the effective output resistance goes DOWN because it's a parallel circuit from the ADC's POV, but still a series circuit from the battery's POV.  If I use a 75/25K divider for a 4:1 ratio, the parallel output impedance is 18.75K.

So, no need for fancy switching circuits - just choose a series divider with a convenient ratio and with a total series resistance in the 100K range, and you are done.


message:
Arduino if, else if conditions being overlooked

Hi Im very new to coding and I'm struggling to fix a problem. I want the user to input a yes or no answer to a question and based on the answer I want the right text to show on the serial monitor and a LCD as well as the right LED light to light up. However it seems like the if and else if statements are ignored and no matter what the user input is the last else statement is the only thing that shows up.

My second problem is with the switchLead. The LED that shows the condition of the switchLead does not turn off when the switchLead is open.

This is just school work so it has to be basic. Please let me know where I made a mistake! Also this is my first post so let me know how I could make this more clear. Thanks!

```
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

String input;                   // Declate string variable to hold user input

const int whiteLead = 2;
const int switchLED = 13;
const int RED1 = 9;
const int YELLOW1 = 8;
const int GREEN1 = 7;

int switchLead = 0;

void setup() {
  Serial.begin(9600);          // Serial transmission activated baud rate 9600 bits per sec
  lcd.begin(16,2);             // Initialise I2C LCD 16 columns with 2 rows
  lcd.backlight();

pinMode(whiteLead,INPUT);
pinMode(switchLED,OUTPUT);
pinMode(RED1,OUTPUT);
pinMode(YELLOW1,OUTPUT);
pinMode(GREEN1,OUTPUT);

switchLead = digitalRead(whiteLead);       // Read the state of the switchLead value
if (switchLead == HIGH) {                  // Begin if; if whiteLead is open do;
  digitalWrite(switchLED, LOW);
  digitalWrite(RED1,LOW);
  digitalWrite(YELLOW1,LOW);
  digitalWrite(GREEN1,LOW);

}                                          // End if
else {                                     // Begin else; Check if the switchLead is closed, turn LED ON
  digitalWrite(switchLED, HIGH);           // Turn switch LED ON
}                                          // End else
}                                          // End void setup

void loop() {                               // Void loop begins
  Serial.println("Is the room in use? ");   //Prompt user to input answer
  while (Serial.available()==0) {}          // Wait for user input
  input = Serial.readString();              // Read user input and store it in variable input

   if (input == "Yes") {               // Begin if: if user input is yes

    lcd.setCursor(0,0);
    lcd.print("In use");
    Serial.print("The room is ");
    Serial.println("in use");
    digitalWrite(switchLED,HIGH);
    digitalWrite(RED1,HIGH);
    digitalWrite(GREEN1,LOW);
    digitalWrite(YELLOW1,LOW);
  }
  else if (input == "No") {

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Empty");
    Serial.print("The room is: ");
    Serial.println("empty");
    digitalWrite(switchLED,HIGH);
    digitalWrite(GREEN1,HIGH);
    digitalWrite(RED1,LOW);
    digitalWrite(YELLOW1,LOW);
  }
    else {                                // Begin else

    lcd.clear();                        // Clear LCD display
    lcd.setCursor(0,0);                 // Set LCD cursor to column 0, row 0
    lcd.print("Preparing");             // Print message enclosed in brackets on LCD
    Serial.print("The room is ");       // Print message enclosed in brackets to computer monitor
    Serial.println("being prepared");   // Print message enclosed in brackets to computer monitor
    digitalWrite(YELLOW1,HIGH);         // Turn YELLOW1 ON
    digitalWrite(GREEN1,LOW);           // Turn GREEN1 OFF
    digitalWrite(RED1,LOW);             // Turn RED1 OFF
  }                                     // End else
}                                       // End void loop
 ```

body:
Try to use this command

    input = Serial.readStringUntil('\n');

Instead of `input = Serial.readString();`

and also use `while (Serial.available() > 0)`

Instead of `while (Serial.available()==0)`

and where you used `int switchLead = 0;`

Try to use `bool switchLead;`

I hope these changes in the code will help you


message:
WS2812B Reset time

i am trying to implement the ws2812b with an atmega8,but i didn't understand a thing very well. if i pull low for >50 us, it says it resets, but what does that mean? it resets the current LED all data to 0 and latches the next data to the next led?

body:
It's the "communication" reset.  You pull the data pin low for 50uS or more to start a new batch of communication.

It's illustrated in the datasheet here:
[![enter image description here][1]][1]

As you can see, between each batch of bits being sent the reset code is set. This is so that the first chip knows to start receiving again and not pass any data on until it's had all 24 of its bits.

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


message:
How can I use separate power source for the Arduino and the motors

[![enter image description here][1]][1]How can use a separate power source for powering Arduino, and another battery for powering the motors?
How can I make connections through the motor driver module L298N? I know how normally we use one battery to power the Arduino as well as the motors. But I am facing the problem while using different power sources.

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

body:
That motor driver has an optional on-board 5V regulator. It can be enabled / disabled with a jumper.

With that regulator enabled you just need to connect a ground and your control signals (ENA/IN1/IN2 or ENB/IN3/IN4).

If you disable that regulator (remove the jumper) then you need to provide power from the Arduino's 5V pin to the +5V screw terminal.

The ENx pin(s) (after removing any jumpers that may be on them) connect to any PWM capable pin (this is the speed control pin). IN1/IN2 or IN3/IN4 connect to any IO pin since these are just used to set the direction or control the braking modes.  ENA controls the speed of motor 1, and IN1/IN2 control the direction of motor 1. ENB and IN3/IN4 are likewise for motor 2.


message:
UltraSonic Sensor with an ESP-01 Standalone

I'm trying to build a cheap device to measure water level in a tank using HC-SR04 sensor and ESP-01 which send the data to MQTT topic. I used the same code with ESP-E12 which works just fine. As I'm trying to drive the cost down with ESP-01, I faced a problem with I/O pins. I searched the web and found some contradicting info about which pins could be used in this case.

So here is the schematic of my setup:
[![enter image description here][1]][1]

Coming to the ESP-01, I used a USB adapter to program it and the code uploaded successfully. Here I'm just showing the Ultrasonic sensor part which I believe I have issues with.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    #define echoPin 2 // Echo Pin
    #define trigPin 0 // Trigger Pin

    long duration, distance; // Duration used to calculate distance

    void setup(){
      Serial.begin (115200);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }

    void loop(){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = duration/58.2;
      Serial.println(distance);
      delay(200);
    }

<!-- end snippet -->

I read somewhere in the internet that GPIO2 can't be used and must be replaced with Rx = GPIO3. However, I tried that and it didn't work too.

**So the question here, am I really using the right pins or is it really possible to do that with esp-01?**

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

body:
This question is old, but myself had the same problem, so I will answer it.

The problem here seems to be that you have the GPIO0 and GPIO2 connected to the SR04 module when it is powered (this is how should be expected), but the GPIO0 and GPIO2 (also GPIO15, just for mention it), are used by ESP8266 to change the boot mode, with nothing connected to these pins, the ESP will load the program written in the flash, but if these pins change the levels while the ESP is powering up, it could enter in the Flash mode and your code will not execute. If you turn on the ESP-01 first and connect the wires to the SR04 just after, the code works, I know because I had the same problem and have the circuit in my front right now. But this is just for testing, you should not have to do that, the solution for me was to use the GPIO3.

You can use the pin RX as GPIO3 as you mentioned, but you can't use it at the same time that you are using the Serial, because Serial will use the RX and TX pins. If you write a Webserver to display the distance measured, for example, and remove the lines that use the serial, it will work. I used the GPIO3 and GPIO2 with the same code, just disabling serial and changing the pin numbers and worked.


message:
Powering Arduino Components with AA in Parallel and Series

<!-- 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/FLDzA.png)

<!-- End schematic -->

I have 6 AA batteries that I would love to power my Arduino Nano and HCSR04 ultrasonic sensor. However, for my low power application I want to use the bare minimum power required for the components. Since the Nano can run as low as 4.5 volts and the sensor requires 5 volts, I think the best solution would be 4 AA batteries in series to power the hcsr04 and 3 AA batteries in series to power the nano. Since I have 6 batteries I was thinking 3 AA batteries wired in parallel with 3 AA series batteries. I drew the circuit diagram above and realize something is horribly wrong. So I was hoping someone could point me in the right direction.

body:
Wiring 6 batteries up so it gives you both a stack of 3 and a stack of 4 is not easy, and although you can do it you shouldn't do it.  The only arrangement is this:

<!-- 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/RU5GR.png)

<!-- End schematic -->

(The grey link is optional and makes little difference if it's there or not).

The reason you shouldn't really do that arrangement is that you have a mismatch in your capacities, as `[BAT1+BAT2] || [BAT3+BAT4]` has more capacity than `BAT5`, so the current drawn from the 4.5V output will cause BAT5 to go flat far sooner than the others. This will then cause BAT5 to take a reverse charge as current from the other cells flows through it damaging it permanently (especially bad for rechargeable batteries as you will not be able to recharge it, but pretty nasty for alkaline batteries too).

Another consideration when running from different voltages like this is the communication between the different units. If the Arduino is running at a lower voltage the signals it sends out will be of a lower voltage, and it expects to receive signals at a lower voltage. Likewise with the HC-SR04; it will expect to receive higher voltage signals and will send out higher voltage signals. So you will require some logic level translation between the two devices to correct that mismatch in the signal voltages.

As you can see it's all starting to get a little messy now.

A much simpler solution is to keep everything at one voltage. The ideal voltage is 5V since that is the common voltage that all the devices expect to work at.

Since you are running from batteries you want efficiency. To that end you need an efficient solution for generating a stable 5V. The Arduino's built-in regulator is far from efficient, so that can be instantly discounted.

A more efficient solution is a step-down or "buck" switching regulator.  This uses PWM to rapidly turn the power on and off (before then filtering and smoothing it) to effectively convert voltage into current.

You'd run your system off a voltage higher than 5V then use a switching regulator to reduce the voltage down to 5V. Since you have 6 batteries at your disposal the logical voltage would be 6x1.5V = 9V - all 6 batteries in series:

<!-- 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/4aAGC.png)

<!-- End schematic -->

If you're running non-rechargeable batteries then you don't need to worry about low-voltage cutoff (you shouldn't over-discharge rechargeable batteries), so this arrangement will get the most out of your battery life. Depending on the "drop out" voltage of the regulator (you can get some with a "zero drop-out bypass" mode) your batteries could get down as far as 0.8V each before the system starts to become unstable (even lower if your HC-SR04 is one of the "upgraded" ones that can run from 3V).


message:
Can't upload sketches or flash Nodemcu 1.0 12E (CP2102) but have drivers and responds to RST on Serial monitor

I've been trying to get my nodemcu working for months and tried countless online references but none worked. I'm using the Arduino IDE to upload sketches and always get the error "Timed out waiting for packer header"

Here's my setup.
I'm trying to upload the example blink code for the nodemcu 1.0 12E.

[![Screenshot of arduino IDE][1]][1]

My board does show up on device manager and here's proof.

[![got the drivers for the board][2]][2]

When i press reset on the nodemcu and have the serial monitor on at 74880 baud the board spits out this.
[![serial monitor output][3]][3]

  [1]: https://i.stack.imgur.com/gZFSl.png
  [2]: https://i.stack.imgur.com/nWniu.png
  [3]: https://i.stack.imgur.com/ZjMOk.png

I have tried pressing the reset and flash buttons while uploading
 in the desired sequence but that didn't work.
I even went as far as reflashing the firmware through the nodemcu flasher but it's always stuck at waiting for MAC and STA address.

Please help me fix the problem and i'm sure not the only one facing this issue. Hoping for help :).

body:
Turns out it was a board problem. Switched it for an older version of the NodeMCU.

The newer ones are not known for the reliability it seems.


message:
Why impedance between I/O pin and ground drops when Arduino is not powered

I have a 4KHz 5V pulsed signal connected to Arduino UNO pin2 (ISR).

- When the board is powered, the pulse is attached to ISR rising edge, and is working as intended.

- I don't know the output impedance of the pulsed signal, but when the board is not powered, the pulse drops to 2V.

- The resistance between pin2 and ground is about 500K when not powered. The resistance is infinite when powered.

- The pulsed signal does NOT drop when connected to a 500K resistor.

**Question:**
- What is the cause of the signal drop?
- How to prevent it ? (It's not practical to disconnected the signal from Arduino, but I can make sure Arduino is always powered. How to deal with transient situations like reset ?)

Thanks in advance !

body:
The Atmega328p (which is used in the Un[ (and actually all other AVR microcontrollers) has clamping diodes in the input hardware to protect it from overvoltage (above Vcc). When not powered, Vcc is at the same level as ground, so any positive voltage on an input pin is above Vcc. The protection diodes get conductive to protect the input hardware. Note, that the diodes can be fried easily, if a too high current flows through them. You should prevent that.

**How to prevent it?** By not doing it. You should never provide a voltage on an input of an unpowered chip (like any chip). If you really need to unpower the Arduino, you can prevent the voltage from reaching the input pin with a MOSFET.


body: I do that all the time but I also read the data sheet. There is a limit on the amount of current you can inject into a processor pin or in total, that is on the data sheet. Also be aware when you inject current you can cause VCC to go out of specification unless it has enough load to support it. Typically I limit my input current to less than 1mA with a resistor. This also protects me in case I get a negative excursion.  For a 5V system that resistor is 5K or greater, with 10K being very common. The input resistance reading is only good to check if the pin is shorted. It is connected to an active junction of a FET and a few Diodes. The voltage and or polarity of your ohm meter will definitely affect the reading. The resistance that may be there is due to  chip resistance, bonding wire resistance etc. all low in value.


message:
How do I add or subtract to a pre-determined value without having it default back to the original value?

Typical apologies in advance, it's been quite some time since I've tinkered with Arduinos. Using an Arduino Micro Clone (Pro Micro), TF02 LiDAR, and a Adafruit 1.2" 7-segment display, I've been working on a rangefinder that is able to be adjusted up/down by increments of 1. I've hit a wall though. I am unable to adjust the distance value without it returning to the original value. Say the distance is at 6'2". When I push the "up" button, the value is 6'3" but then returns to 6'2". Same applies for the "down" button. Also, when the distance is at, for example, 1'0", and I press the down button, instead of going to 0'11", it displays 0'99". I'm at a wall in terms of what I can do to resolve this.  Any help is appreciated!

    *
    #include <Adafruit_GFX.h>
    #include "Adafruit_LEDBackpack.h"
    Adafruit_7segment matrix = Adafruit_7segment(); //d pin 2, c pin 3
    #include <SoftwareSerial.h>// soft serial port
    #include <Wire.h>

    //button stuff
    int Up_buttonState = 0;
    int Dn_buttonState = 0;
    int Up_lastButtonState = 0;
    int Dn_lastButtonState = 0;
    const int  UpPin = 7;
    const int  DnPin = 8;

    //LiDAR stuff
    int dist;// LiDAR actually measured distance value
    int strength;// LiDAR signal strength
    int check;// check numerical value storage
    int i;
    int uart[9];// store data measured by LiDAR
    const int HEADER=0x59;// data package frame header
    long inches, INCH, feet, ftin;

    SoftwareSerial mySerial(9,10); //rx tx,

    void setup()
    {
    pinMode(UpPin, INPUT);
    pinMode(DnPin, INPUT);
     Serial.begin(9600);

     mySerial.begin(115200);//set the Baud rate of LiDAR and Arduino serial port
      #ifndef __AVR_ATtiny85__

      #endif
      matrix.begin(0x70);
    }
    void loop()
    {

     if (mySerial.available())//check whether the serial port has data input
     {
        if(mySerial.read()==HEADER)// determine data package frame header 0x59
        {

          uart[0]=HEADER;

          if(mySerial.read()==HEADER)//determine data package frame header 0x59
          {
           uart[1]=HEADER;

          for(i=2;i<9;i++)// store data to array
             {
              uart[i]=mySerial.read();
             }
               check=uart[0]+uart[1]+uart[2]+uart[3]+uart[4]+uart[5]+uart[6]+uart[7];
               if(uart[8]==(check&0xff))// check the received data as per protocols //if data received

                 { //start equations
                   dist=uart[2]+uart[3]*256;// calculate distance value

                   //equations for converting mm to ft,in
                   inches = (dist * .3937);
                   INCH = inches% 12;
                   feet = (dist / 2.54) / 12;
                   ftin = feet*100 + INCH;

                   Up_buttonState = digitalRead(UpPin); // add 1 to ftin
                    if (Up_buttonState != Up_lastButtonState)
                    {
                      if (Up_buttonState == HIGH)
                      {
                        ftin++;
                      }
                      delay(500);
                    }
                    Up_lastButtonState = Up_buttonState;

                   Dn_buttonState = digitalRead(DnPin); // subtract 1 from ftin
                    if (Dn_buttonState != Dn_lastButtonState)
                    {
                      if (Dn_buttonState == HIGH)
                      {
                        ftin--;
                      }
                      delay(500);
                    }
                    Dn_lastButtonState = Dn_buttonState;

                   Serial.print(ftin);
                   matrix.print( ftin , DEC );
                   matrix.writeDisplay();

                 }
          }
        }
     }

    }

body:
You wrote:

> ```c++
> ftin = feet*100 + INCH;
> ```

What is this monster? I am not very familiar with imperial units (and I
wonder why anyone would still want to use them), but I believe a foot is
not 100 inches.

Oh, I see. The monster is a kludge to manage the display in feet &
inches. But note that it is computed at every loop iteration as a
function of the measured distance. I doesn't make sense to apply a
correction to the monster as it is going to be recomputed on the next
iteration. That's why the value “returns” to what it is supposed to be.
As to why the down button changes “100” to “99”, I think it is quite
obvious: 100 minus one is 99. It is not a good idea to do arithmetics
with the monster.

If you want the correction to persist, you have to store it in a global
variable (or `static` local), and add that variable to the measured
distance at every loop iteration. For example:

```c++
// In global scope:
int correction = 0;

// In loop():
dist = ...;
inches = dist * 0.3937008 + correction;  // correction added here
ftin = (inches/12) * 100 + (inches);  // only used for display

if (Up_lastButtonState == LOW && Up_buttonState == HIGH) {
    correction++;
    delay(500);
}
if (Dn_lastButtonState == LOW && Dn_buttonState == HIGH) {
    correction--;
    delay(500);
}
```

Note that the monster is used for display **only**. No arithmetics are
performed on it, as that would not make any sense.