# Question
Title: Garage Door Opener RFID failing after a period
I've been building an add on to my garage door opener that will allow it to be opened from the outside with a valid RFID token or from inside using push buttons.

This works as expected when first plugged in, but then after a few hours, the RFID component stops responding to swipes. The push buttons continue to allow the door to be opened, closed or halted during an action.

I'm not sure if this is an electrical hardware issue or a code based bug, but any help is appreciated.

```
#include <AddicoreRFID.h>
#include <SPI.h>

#define  uchar unsigned char
#define uint  unsigned int

uchar fifobytes;
uchar fifoValue;

AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module

// ------------
// Open / Close Garage Door
// ------------

/*-------------

Every program based on Wiring (programming language used by Arduino, and Particle devices) has two essential parts:
setup - runs once at the beginning of your program
loop - runs continuously over and over

-------------*/

// First, we're going to make some variables.
// This is our "shorthand" that we'll use throughout the program:

int re1 = 8                                                                                ; // Relay IN1 Blue
int re2 = 7; // Relay IN2 Purple
int re3 = 6; // Relay IN3 Orange
int re4 = 5; // Relay IN4 Yellow
int btn1 = 3;
int btn2 = 4;
int btn3 = 2;

int OpenButtonState = 0;
int CloseButtonState = 0;
int StopButtonState = 0;

int doorstate = 0; // 0 = "Closed", 1 = "Open"

//--Pins for RFID

const int chipSelectPin = 10;
const int NRSTPD = 9;

//Maximum length of the array
#define MAX_LEN 16

//End of RFID Pin Config

void setup() {

  Serial.begin(9600);      // open the serial port at 9600 bps:
//setup the pins to output voltage
  pinMode(re1, OUTPUT);
  pinMode(re2, OUTPUT);
  pinMode(re3, OUTPUT);
  pinMode(re4, OUTPUT);
  pinMode(btn1, INPUT);
  pinMode(btn2, INPUT);
  pinMode(btn3, INPUT);

   // start the SPI library:
  SPI.begin();

  pinMode(chipSelectPin,OUTPUT);              // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
    digitalWrite(chipSelectPin, LOW);         // Activate the RFID reader
  pinMode(NRSTPD,OUTPUT);                     // Set digital pin 9 , Not Reset and Power-down
    digitalWrite(NRSTPD, HIGH);

  myRFID.AddicoreRFID_Init();

//setup web call functions

//Particle.function("netopen", R1ON);
//Particle.function("netclose", R2ON);
//Particle.function("netstop", R3ON);

  digitalWrite(re1, HIGH); //turn off relay
  digitalWrite(re2, HIGH); //turn off relay
  digitalWrite(re3, HIGH); //turn off relay
  digitalWrite(re4, HIGH); //turn off relay

}

// This routine gets repeated over and over, as quickly as possible and as many times as possible, after the setup function is called.
// Note: Code that blocks for too long (like more than 5 seconds), can make weird things happen (like dropping the network connection).  The built-in delay function shown below safely interleaves required background activity, so arbitrarily long delays can safely be done if you need them.

void loop() {

//Loop for RFID ----------------------------------------------------------------------

uchar i, tmp, checksum1;
  uchar status;
        uchar str[MAX_LEN];
        uchar RC_size;
        uchar blockAddr;  //Selection operation block address 0 to 63
        String mynum = "";

        str[1] = 0x4400;
  //Find tags, return tag type
  status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str);
  if (status == MI_OK)
  {
          Serial.println("RFID tag detected");
                 }

  //Anti-collision, return tag serial number 4 bytes
  status = myRFID.AddicoreRFID_Anticoll(str);
  if (status == MI_OK)
  {
          checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
          Serial.print("The tag's number is:\t");
          Serial.print(str[0]);
            Serial.print(" , ");
          Serial.print(str[1]);
            Serial.print(" , ");
          Serial.print(str[2]);
            Serial.print(" , ");
          Serial.println(str[3]);

//check if valid card combination
            if((str[0] == 333) && (str[1] == 444) && (str[2] == 555) && (str[3] == 666) )                   //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
            {
                Serial.println("\nKey fob identifed - Josh\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(""); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(""); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }

            } else if((str[0] == 111) && (str[1] == 2222) && (str[2] == 333) && (str[3] == 444) ) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.println("\nCar Charge Card Identified - Josh\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(""); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(""); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }
            } else if((str[0] == 000) && (str[1] == 11) && (str[2] == 22) && (str[3] == 333) ) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.println("\nCar Garage Card Identified - Charlotte\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(""); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(""); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }
            }
            Serial.println();
            delay(1000);
  }

        myRFID.AddicoreRFID_Halt();      //Command tag into hibernation

   //End Loop For RFID  ----------------------------------------------------------------------

OpenButtonState = digitalRead(btn1);
CloseButtonState = digitalRead(btn2);
StopButtonState = digitalRead(btn3);

if (OpenButtonState == HIGH) {

  Serial.print("Open State Button HIGH - Opening Garage Door")  ;
  Serial.println("");
    //Open Garage Door
  R1ON(""); //turn on relay
  doorstate = 1;
  Serial.print("Relay 1 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R1OFF(); //turn off relay
  Serial.print("Relay 1 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
  Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
  Serial.println("");
  }

if (CloseButtonState == HIGH) {

  Serial.print("Close State Button HIGH - Closing Garage Door") ;
  Serial.println("");
    // Close Garage Door
  R2ON(""); //turn on relay
  doorstate = 0;
  Serial.print("Relay 2 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R2OFF(); //turn off relay
  Serial.print("Relay 2 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
    Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
  Serial.println("");

  }

if (StopButtonState == HIGH) {

 Serial.print("Stop State Button HIGH - Stopping Garage Door")  ;
 Serial.println("");
 // Stop
  R3ON(""); //turn on relay
  doorstate = 1;
  Serial.print("Relay 3 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R3OFF(); //turn off relay
  Serial.print("Relay 3 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
      Serial.print("Stop State Button HIGH - Finished Stopping Garage Door")    ;
  Serial.println("");

  }

  // And repeat!
}

int R1ON(String command) {

    digitalWrite(re1, LOW); //turn on relay
    //Particle.publish("Relay 1 on - Door Open");
    delay(1000); // wait 1 second
    digitalWrite(re1, HIGH); //turn off relay
    //Particle.publish("Relay 1 off");
}

void R1OFF() {
  digitalWrite(re1, HIGH); //turn off relay
    //delay(1000); // wait 1 second
}

int R2ON(String command) {

    digitalWrite(re2, LOW); //turn on relay
    //Particle.publish("Relay 2 on - Door Closing");
    delay(1000); // wait 1 second
    digitalWrite(re2, HIGH); //turn off relay
    //Particle.publish("Relay 2 off");
}

void R2OFF() {

    digitalWrite(re2, HIGH); //turn on relay
    //delay(1000); // wait 1 second
}

int R3ON(String command) {

    digitalWrite(re3, LOW); //turn on relay
    //Particle.publish("Relay 3 on - Door Stopped");
    delay(1000); // wait 1 second
    digitalWrite(re3, HIGH); //turn off relay
    //Particle.publish("Relay 3 off");
}

void R3OFF() {

    digitalWrite(re3, HIGH); //turn on relay
    //delay(1000); // wait 1 second
}

void R4ON() {

    digitalWrite(re4, LOW); //turn on relay
    //delay(1000); // wait 1 second
}

void R4OFF() {

    digitalWrite(re4, HIGH); //turn on relay
    //delay(1000); // wait 1 second
}

```

Updated Code 7/7/19 @20:53

```
#include <AddicoreRFID.h>
#include <SPI.h>

//#define  unsigned char unsigned char
#define uint  unsigned int

unsigned char fifobytes;
unsigned char fifoValue;

AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module

// ------------
// Open / Close Garage Door
// ------------

/*-------------

Every program based on Wiring (programming language used by Arduino, and Particle devices) has two essential parts:
setup - runs once at the beginning of your program
loop - runs continuously over and over

-------------*/

// First, we're going to make some variables.
// This is our "shorthand" that we'll use throughout the program:

int re1 = 8                                                                                ; // Relay IN1 Blue
int re2 = 7; // Relay IN2 Purple
int re3 = 6; // Relay IN3 Orange
int re4 = 5; // Relay IN4 Yellow
int btn1 = 3;
int btn2 = 4;
int btn3 = 2;

int OpenButtonState = 0;
int CloseButtonState = 0;
int StopButtonState = 0;

int doorstate = 0; // 0 = "Closed", 1 = "Open"

//--Pins for RFID

const int chipSelectPin = 10;
const int NRSTPD = 9;

//Maximum length of the array
#define MAX_LEN 16

//End of RFID Pin Config

void setup() {

  Serial.begin(9600);      // open the serial port at 9600 bps:
//setup the pins to output voltage
  pinMode(re1, OUTPUT);
  pinMode(re2, OUTPUT);
  pinMode(re3, OUTPUT);
  pinMode(re4, OUTPUT);
  pinMode(btn1, INPUT);
  pinMode(btn2, INPUT);
  pinMode(btn3, INPUT);

   // start the SPI library:
  SPI.begin();

  pinMode(chipSelectPin,OUTPUT);              // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
    digitalWrite(chipSelectPin, LOW);         // Activate the RFID reader
  pinMode(NRSTPD,OUTPUT);                     // Set digital pin 9 , Not Reset and Power-down
    digitalWrite(NRSTPD, HIGH);

  myRFID.AddicoreRFID_Init();

//setup web call functions

//Particle.function("netopen", R1ON);
//Particle.function("netclose", R2ON);
//Particle.function("netstop", R3ON);

  digitalWrite(re1, HIGH); //turn off relay
  digitalWrite(re2, HIGH); //turn off relay
  digitalWrite(re3, HIGH); //turn off relay
  digitalWrite(re4, HIGH); //turn off relay

}

// This routine gets repeated over and over, as quickly as possible and as many times as possible, after the setup function is called.
// Note: Code that blocks for too long (like more than 5 seconds), can make weird things happen (like dropping the network connection).  The built-in delay function shown below safely interleaves required background activity, so arbitrarily long delays can safely be done if you need them.

void loop() {

//Loop for RFID ----------------------------------------------------------------------

//unsigned char checksum1;
  unsigned char status;
        unsigned char str[MAX_LEN];
        //unsigned char RC_size;
        //unsigned char blockAddr;  //Selection operation block address 0 to 63
        //String mynum = "";

        str[1] = 0x4400;
  //Find tags, return tag type
  status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str);
  if (status == MI_OK)
  {
          Serial.println("RFID tag detected");
                 }

  //Anti-collision, return tag serial number 4 bytes
  status = myRFID.AddicoreRFID_Anticoll(str);
  if (status == MI_OK)
  {
//          checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
          Serial.print("The tag's number is:\t");
          Serial.print(str[0]);
            Serial.print(" , ");
          Serial.print(str[1]);
            Serial.print(" , ");
          Serial.print(str[2]);
            Serial.print(" , ");
          Serial.println(str[3]);

//check if valid card combination
            if((str[0] == 333) && (str[1] == 444) && (str[2] == 555) && (str[3] == 666) )                   //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
            {
                Serial.println("\nKey fob identifed - Josh\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }

            } else if((str[0] == 222) && (str[1] == 333) && (str[2] == 444) && (str[3] == 555) ) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.println("\nCar Charge Card Identided - Josh\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }
            } else if((str[0] == 111) && (str[1] == 222 && (str[2] == 333) && (str[3] == 444) ) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.println("\nCar Garage Card Identided - Charlotte\n");

                if(doorstate == 1) {
                  //door is already open so close
                    // Close Garage Door
                    R2ON(); //turn on relay
                    doorstate = 0;
                    Serial.print("Relay 2 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R2OFF(); //turn off relay
                    Serial.print("Relay 2 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                      Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
                    Serial.println("");

                } else {
                  //door is closed so open

                    //Open Garage Door
                    R1ON(); //turn on relay
                    doorstate = 1;
                    Serial.print("Relay 1 on") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    R1OFF(); //turn off relay
                    Serial.print("Relay 1 off") ;
                    Serial.println("");
                    delay(1000); // wait 1 second
                    Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
                    Serial.println("");
                }
            }
            Serial.println();
            delay(1000);
  }

        myRFID.AddicoreRFID_Halt();      //Command tag into hibernation

   //End Loop For RFID  ----------------------------------------------------------------------

OpenButtonState = digitalRead(btn1);
CloseButtonState = digitalRead(btn2);
StopButtonState = digitalRead(btn3);

if (OpenButtonState == HIGH) {

  Serial.print("Open State Button HIGH - Opening Garage Door")  ;
  Serial.println("");
    //Open Garage Door
  R1ON(); //turn on relay
  doorstate = 1;
  Serial.print("Relay 1 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R1OFF(); //turn off relay
  Serial.print("Relay 1 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
  Serial.print("Open State Button HIGH - Finished Opening Garage Door")    ;
  Serial.println("");
  }

if (CloseButtonState == HIGH) {

  Serial.print("Close State Button HIGH - Closing Garage Door") ;
  Serial.println("");
    // Close Garage Door
  R2ON(); //turn on relay
  doorstate = 0;
  Serial.print("Relay 2 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R2OFF(); //turn off relay
  Serial.print("Relay 2 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
    Serial.print("Close State Button HIGH - Finished Closing Garage Door")    ;
  Serial.println("");

  }

if (StopButtonState == HIGH) {

 Serial.print("Stop State Button HIGH - Stopping Garage Door")  ;
 Serial.println("");
 // Stop
  R3ON(); //turn on relay
  doorstate = 1;
  Serial.print("Relay 3 on") ;
  Serial.println("");
  delay(1000); // wait 1 second
  R3OFF(); //turn off relay
  Serial.print("Relay 3 off") ;
  Serial.println("");
  delay(1000); // wait 1 second
      Serial.print("Stop State Button HIGH - Finished Stopping Garage Door")    ;
  Serial.println("");

  }

  // And repeat!
}

void R1ON() {

    digitalWrite(re1, LOW); //turn on relay
    //Particle.publish("Relay 1 on - Door Open");
    delay(1000); // wait 1 second
    digitalWrite(re1, HIGH); //turn off relay
    //Particle.publish("Relay 1 off");

}

void R1OFF() {
  digitalWrite(re1, HIGH); //turn off relay
    //delay(1000); // wait 1 second

}

void R2ON() {

    digitalWrite(re2, LOW); //turn on relay
    //Particle.publish("Relay 2 on - Door Closing");
    delay(1000); // wait 1 second
    digitalWrite(re2, HIGH); //turn off relay
    //Particle.publish("Relay 2 off");

}

void R2OFF() {

    digitalWrite(re2, HIGH); //turn on relay
    //delay(1000); // wait 1 second

}

void R3ON() {

    digitalWrite(re3, LOW); //turn on relay
    //Particle.publish("Relay 3 on - Door Stopped");
    delay(1000); // wait 1 second
    digitalWrite(re3, HIGH); //turn off relay
    //Particle.publish("Relay 3 off");

}

void R3OFF() {

    digitalWrite(re3, HIGH); //turn on relay
    //delay(1000); // wait 1 second

}

void R4ON() {

    digitalWrite(re4, LOW); //turn on relay
    //delay(1000); // wait 1 second

}

void R4OFF() {

    digitalWrite(re4, HIGH); //turn on relay
    //delay(1000); // wait 1 second

}

```

# Answer
In 50+ years of dealing with hardware/software issues, I've found that the culprit is almost never the hardware. So, your problem is most likely the software.

To start with, there are several major problems with your code:

1. You are using an unsigned char type to represent integer values \> 256; this will not work. When I tried to compile your code, one of the many error messages was "StackOvrFl.ino: 107:8: warning: large integer implicitly truncated to unsigned type \[-Woverflow\]" on the line 'str\[1\] = 0x4400;' You need to declare 'str' as 'unsigned int str\[MAX\_LEN\];'.
2. It's really bad form to use 'nicknames' ('uchar') for types; If someone else needs to maintain or modify your code (or help you with it as in this case), they are going to trip over that and emit 4-letter words in your direction.
3. Turn on compiler warnings and errors, and don't stop debugging until all such warnings/errors are cleared. The compiler is your friend; let it help you.
4. If you had turned on compiler warnings/errors, you would have found that the identifier 'MI\_OK' was never declared, and so can have ANY VALUE when you check it.

The combination of the integer overflow and undeclared symbol problems will almost undoubtedly cause undefined behavior, but there may be other issues as well. Clean up your code, pay attention to compiler warnings, and then see what happens.

Good luck!

Frank
> 2 votes

# Answer
Consider removing the type String from the code including removing where String is used in passing formal values to some functions. It appears to do nothing. And if the compiler does not optimize it out, could actually be consuming what little RAM the embedded processor contains.

The type String loads in all kinds of help you may or may not need. Generally String is a bad idea for embedded processors because Sting consumes a large amount of resources to support all of String's features. And sometimes those resources are not given back. This is generally referred to as a memory leak. Briefly, this is when the RAM in an embedded processor is considered used by the program, but is not actually being used by the programmer.
> 1 votes

---
Tags: arduino-uno, rfid
---


title: DC motors only run in one direction

text:
# Question
Title: DC motors only run in one direction
I'm quite new to Arduino and am making my first proper project, an obstacle avoiding robot.

I'm using an Arduino Uno and a motor shield compatible with the Adafruit motor driver library. I'm trying to run the example code from here: https://learn.adafruit.com/adafruit-motor-shield/using-dc-motors, but with both motors running at once. This should run the motors forward for 1 sec, backward for 1 sec and then pause for 1 sec.

I'm getting inconsistent behaviour when I run the code. When I only connect 1 motor, it works fine. When the Arduino is connected to my laptop via USB, it works fine. However, when I use the 6V external power supply and both motors, they will only move in 1 direction and remain still during the second movement period. When I set them to move forward-backward-stationary, they only move forwards. When I set them to backward-forward-stationary, they only move backwards.

Any ideas what might be causing this / how I could fix it? Like I said, I'm pretty new to this so might be making a simple mistake.

Here's my setup:

I have 2 DC motors, one attached to port 1 and the other to port 4 on the motor shield. The power supply is 4 AA batteries (which I think is 6V?), which is also connected to the motor shield.

And here's my code:

```
#include <AFMotor.h>

AF_DCMotor leftMotor(1, MOTOR12_1KHZ);
AF_DCMotor rightMotor(4, MOTOR12_1KHZ);

void setup() {
  leftMotor.setSpeed(255);
  rightMotor.setSpeed(255);
}

void loop() {
  leftMotor.run(FORWARD);
  rightMotor.run(FORWARD);
  delay(1000);

  leftMotor.run(BACKWARD);
  rightMotor.run(BACKWARD);
  delay(1000);

  leftMotor.run(RELEASE);
  rightMotor.run(RELEASE);
  delay(1000);
}

```

Any help is much appreciated!

# Answer
> 2 votes
Possible hardware solution:

Consider using 2 battery packs. One connected to the Arduino and the other connected to the motor drive board. Remember to connect the grounds of the 2 battery packs together.

Possible software solution:

Software is often over looked when solving what appears to be a hardware issue. Consider introducing a short pause between motor direction changes. It may be that the power required to reverse the direction of a motor exceeds the capacity of the battery pack. Likely it will take less power to first stop the motor, pause then start the motor in the opposite direction.

# Answer
> 1 votes
Your code looks pretty straightforward, and the fact that everything works properly with the laptop-USB connector makes me suspect that your problem lies with the battery pack.

When you said "When the Arduino is connected to my laptop via USB, it works fine.", did you mean that the 4-cell battery pack is still connected to the motor shield as shown, but the Arduino is being powered from the laptop via USB?

I suspect that what is going on is that during the transition from one direction to the other, the battery voltage temporarily drops below the Arduino's low-voltage cutoff point and everything stops, EXCEPT, when the Arduino is connected to the laptop via USB, the USB connection continues to power the Arduino through the dropout period and everything works.

Since you are starting to work with electronics and Arduino, you might want to consider getting a basic DVM (Digital Volt-AmpMeter) and a basic lab power supply. These two items would allow you to easily troubleshoot this problem. A common desktop PC power supply with 5, 12 and (sometimes) 24V DC output makes a good bench power supply and are widely available and cheap.

Hope this helps,

Frank

# Answer
> 0 votes
4 AA batteries is 6 volts, which is the right amount of voltage for 2 DC motors. Like all the other answers on this page, the problem most likely has to do with your battery pack, although I am not sure how that would affect your motors. I can't really tell from the picture, but the problem would have to be with the wiring from your battery pack. If you have wires that go from the battery pack, to the motors, you should check to make sure that those are properly wired, as that would be a problem.

I hope this information helps, and the rest of your projects with Arduino go very smoothly!

-Simon

---
Tags: motor, adafruit
---


# Question
Title: How to Specify Array Length during Object Construction within Arduino IDE?
I'm working on a group project to involving the creation of an in-house library using the Arduino IDE. As the Arduino IDE uses C++, the library must be a class. One of the classfields is an array of numbers. We would like it if we could specify the array length during object construction, as there are pros and cons to low and high array lengths. Is it possible to specify or change the array length during object construction?

Unfortunately, the Arduino IDE doesn't allow the usage of C++ vectors, so that's out of the question.

# Answer
As suggested in st2000’s answer, you could use dynamic allocation but, if you do that, do not forget to free the allocated memory in the destructor. Otherwise you have a nasty memory leak and your program will not live long:

```
class MyClass {
public:
    MyClass(size_t length) : arrayLength(length) {
        theArrayOfNumbers = new int[arrayLength];
    }
    ~MyClass() {
        delete[] theArrayOfNumbers;
    }
private:
    const size_t arrayLength;
    int *theArrayOfNumbers;
};

```

One issue with this approach is that dynamic allocation is no very friendly to the limited amount of memory you have in a microcontroller.

A safer option would be to use a template class instead. This way the array is statically allocated:

```
template <size_t arrayLength>
class MyTemplateClass {
    int theArrayOfNumbers[arrayLength];
};

```

One caveat with this approach is that the users of the library may not be comfortable with the syntax for instantiating a template. You will have to provide clear examples in the documentation. Another issue is that the array size will have to be a compile-time constant.
> 0 votes

# Answer
Another way is for the caller to provide the memory as a pointer to enough bytes for 'N' objects (cast, if necessary, as a pointer to the required type), and the number, 'N' of such objects. This gives the caller the choice of whether to allocate statically or dynamically.

It looks like you want an array of ints. So you'd allocate an array (statically, in my example, but you could choose whichever best fits your application):

```
int memArray[N];
// ...
myClass(N, memArray&);

```

I avoid allocating memory from the heap, but someone else might have a different preference or a situation that requires it; this technique lets the library work for either.
> 3 votes

# Answer
Some example solutions can be found in this stackexchange question/answer. The accepted answer used this code:

```
private int size;

private String words[];

public WordStore(int n){
     words =new String[n];
}

```
> 0 votes

---
Tags: c++, arduino-ide
---


# Question
Title: MPU6050/DMP Intermittent bad data output?
I have a DFRobots MPU6050 module wired to SCL/SDA/Pin 2 on a Mega 2560 board, using Jeff Rowberg's I2CDev/MPU6050\_6Axis\_MotionApps libraries. I have 2.2K pullups on the MPU6050 module, tied to +5V, as shown in the following photo.

I used a modified version of the code from Jeff's example to retrieve heading values from the MPU6050, as shown below

```
bool GetIMUHeadingDeg() //08/28/18 chg to bool return

```

{

```
//Purpose:  Encapsulate everything needed to acquire a yaw value
//Inputs:
//  global_yawval = float variable defined at global scope
//  fifocount = uint8_t variable defined at global scope
//  packetsize = uint8_t variable defined at global scope
//  mpuIntStatus = uint8_t variable defined at global scope
//  whilecount = long variable defined at global scope
//  resetcount = int variable defined at global scope
//Outputs:
//  global_yawval filled with latest yaw value from sensor
//  true = success, false = failure
//Notes:
//  08/13/18 now returns global_yawval to calling routine
//  08/28/18 chg return to bool so can return success/failure

// if programming failed, don't try to do anything
//if (!dmpReady) return;
//if (!dmpReady) false;

bool result = false; //added 01/16/19 to supress warnings

// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount < DMPpacketSize)
{
    whilecount++;
    delay(10);
    delay(10);

    if (mpuInterrupt)
    {
        fifoCount = mpu.getFIFOCount();
        mySerial.printf("%ld\t%d\n", whilecount, fifoCount);
        whilecount = 0;
        break;
    }
}

// reset interrupt flag and get INT_STATUS byte
mpuIntStatus = mpu.getIntStatus();
mpuInterrupt = false;

// get current FIFO count
fifoCount = mpu.getFIFOCount();

// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024)//0x10 is mask for MPU6050_INTERRUPT_FIFO_OFLOW_BIT
{
    // reset so we can continue cleanly
    mpu.resetFIFO();
    Serial.println(F("FIFO overflow!"));
    result = false; //added 01/16/19 to supress warnings

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
}
else if (mpuIntStatus & 0x02)//0x02 is mask for MPU6050_INTERRUPT_DMP_INT_BIT
{
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount < DMPpacketSize)
    {
        fifoCount = mpu.getFIFOCount();
        //mySerial.printf("fifo count = %d\n", fifoCount);
    }

    //07/08/18 added to watch for non-modulo FIFO counts
    if (fifoCount == 0 || fifoCount % DMPpacketSize != 0)
    {
        mpu.resetFIFO();
        FIFO_resetcount++;
    }
    else
    {
        //07/07/18 modified to read all outstanding packets
        // read a packet from FIFO
        while (fifoCount >= DMPpacketSize)
        {
            //mySerial.printf("fifo count = %d\n", fifoCount);
            mpu.getFIFOBytes(fifoBuffer, DMPpacketSize);
            fifoCount -= DMPpacketSize;
        }

        // display Euler angles in degrees
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

        global_yawval = ypr[0] * 180 / M_PI;
        result = true; //added 01/16/19 to supress warnings
    }

    ////DEBUG!!
    //      mySerial.printf("yawdeg = %4.2f\n", global_yawval);
    //      mySerial.printf("time = %ld\tyawdeg = %6.2f\n", millis(), global_yawval);
    ////DEBUG!!
}

return result; //added 01/16/19 to surpress warnings

```

}

I have noticed occasional bad data points in the computed Heading values retrieved from the MPU6050, as shown in the attached plot. Any ideas what I can do about this? Is bad value detection/removal an expected issue when dealing with IMU products like the MPU6050?

As an experiment, I excluded all points for which the rotation rate was unrealistically high, resulting in the 'Adj Hdg' line (gray line) in the plot below. This (mostly) works, except for one instance where there were two bad values in a row.

TIA,

Frank

# Answer
> 1 votes
Looks like the major driver in the data 'noise' was the FIFO data rate, set via the MPU6050\_DMP\_FIFO\_RATE\_DIVISOR constant in MPU6050\_6Axis\_MotionApps20.h. I changed the rate from 100Hz (0x01) to 20Hz (0x09) and got the following almost completely noiseless plot under the same conditions as before. Note the vertical scale - only 6 deg total, and the one 'excursion' is only a 4 deg change. I also plotted the 3-point running average, which further reduces the excursion to less than 2 deg.

So, if you are looking for clean yaw (Heading) data from the MPU6050 DMP, consider changing the FIFO rate.

Frank

---
Tags: arduino-mega, mpu6050
---


# Question
Title: ESP 01 lost its firmware when it disconnected
Hi I am using Arduino uno & ESP-01

ESP-01 is working well when I put firmware to ESP, for example, wifi spreading or AT command is okay.

but when I disconnect arduino from PC(disconnect USB connection)

ESP-01 suddenly do not work anything. no spread wifi, no AT command reaction..

so I always have to re-input the firmware to ESP again, for make it work again.

How can I make maintain ESP-01 's firmware?

picture is my connection status. thank you

# Answer
> 2 votes
You have io 0 puled LOW so the esp-01 firmware starts in flashing mode and the firmware starts immediately after flashing (no reset).

Remove io 0 to ground connection and add a pull-up for io 0 over a 10kOhm resistor if you want the esp-01 to start normally.

Note: powering the esp-01 from the 3.3 V pin of Uno (150mA max) could be insufficient for esp8266 WiFi operations at top transmit power (according to specs it can draw to 170 mA).

---
Tags: arduino-uno, esp8266
---


title: SPI: test by connecting MOSI to MISO

text:
# Question
Title: SPI: test by connecting MOSI to MISO
Is it possible to test a SPI connection by wiring the MISO directly to the MOSI pin? I'm working on a low-level SPI implementation, and I want to check that the library is basically working. It would be nice to be able to test the connection itself without additional hardware.

# Answer
Yes, you can - and it's something I often do when doing low-level electrical testing an SPI interfacce. For every clock that you send out the data presented on MOSI will get reflected on MISO. So if you were to (using the Arduino SPI library) do:

```
uint8_t x = SPI.transfer(0x38);

```

then `x` should equal `0x38`.

I find this especially useful on systems with remappable pins to confirm that the pins are configured correctly in the board configuration for proper SPI operation.
> 4 votes

# Answer
Usually the SPI Master clocks data out while the Slave clocks data back in. So if you were sending and receiving 8 bits per transaction you can clock out 8 bits and at the same time clock in 8 bits for a total of 8 clocks. This is described in this Wikipedia paragraph. That said, often the first 8 clocks are used to transmit a command and an additional 8 clocks are used to retrieve the result.

If you looped MOSI to MISO you would clock in what you clocked out. You would complete the entire transaction in 8 clocks. At a low level I'm thinking this does not matter. But at a higher level the software would have to be re-written to accommodate this weirdness.
> 3 votes

---
Tags: spi, testing
---


title: Powering Arduino AND Relays

text:
# Question
Title: Powering Arduino AND Relays
I have a 5V (5.3V) switching transformer that goes to a 7805 voltage regulator and powers Arduino, Arduino controls 4 relays using BJTs. those relays getting power directly from the same power source.

Arduino and it's modules + LCD uses ~40ma, each relay consumes 70ma. total current is around 350ma lets say 400ma.

The problem is 5V isn't enough to power Arduino, modules, sensors and relays. LCD gets very dim etc...

it works with 9V but 7805 gets really hot ~70 centigrade while having a heat sink on!

If i remove the 7805 and switching power burns or something bad happens then there's nothing in between to protect the Arduino!

What's the solution for this situation?

---

**EDIT:** *for anyone who may have the same problem; I solved the problem with using a proper switching power salvaged from an old USB type-C charger and removed the 7805 voltage regulator, there's no heat anymore and it's working perfectly.*

# Answer
Linear regulators such as the 7805 operate by dissipating the additional voltage until their rated voltage remains. This - as you noticed - requires a higher voltage than the rated voltage. Some variants, labeled as LDO for low drop-out, have reduced requirements for this, but normal 7805 usually require around 7 V to operate correctly.

The difference to the rated voltage is dissipated as heat as per `P = U * I`, with U being the voltage difference, and I the current pulled by your circuit.

You can use the switching power supply directly, or use a more advanced voltage regulator like the R-78E5.0 directly from 9 V, which has far lower losses.

Another option would be using the 5V from the switching transformer to drive the (less delicate) relays, and use the 7805 only for the MCU and display, but you would still want to use a heat sink in that case.
> 2 votes

---
Tags: power
---


# Question
Title: How can I create multiple running threads?
Is there a way I can have multiple parts of the program running together without doing multiple things in the same code block?

One thread waiting for an external device while also blinking a LED in another thread.

# Answer
> 62 votes
There is no multi-process, nor multi-threading, support on the Arduino. You can do something close to multiple threads with some software though.

You want to look at Protothreads:

> Protothreads are extremely lightweight stackless threads designed for severely memory constrained systems, such as small embedded systems or wireless sensor network nodes. Protothreads provide linear code execution for event-driven systems implemented in C. Protothreads can be used with or without an underlying operating system to provide blocking event-handlers. Protothreads provide sequential flow of control without complex state machines or full multi-threading.

Of course, there is an Arduino example here with example code. This SO question might be useful, too.

ArduinoThread is a good one too.

# Answer
> 21 votes
AVR based Arduino's do not support (hardware) threading, I am unfamiliar with the ARM based Arduino's. One way around this limitation is the use of interrupts, especially timed interrupts. You can program a timer to interrupt the main routine every so many microseconds, to run a specific other routine.

https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/

# Answer
> 19 votes
It is possible to do software side multi-threading on the Uno. Hardware level threading is not supported.

To achieve multithreading, it will require the implementation of a basic scheduler and maintaining a process or task list to track the different tasks that need to be run.

The structure of a very simple non-preemptive scheduler would be like:

```
//Pseudocode
void loop()
{

for(i=o; i<n; i++)
run(tasklist[i] for timelimit):

}

```

Here, `tasklist` can be an array of function pointers.

```
tasklist [] = {function1, function2, function3, ...}

```

With each function of the form:

```
int function1(long time_available)
{
   top:
   //Do short task
   if (run_time<time_available)
   goto top;
}

```

Each function can perform a separate task such as `function1` performing LED manipulations, and `function2` doing float calculations. It will be the responsibility of each task(function) to adhere to the time allocated to it.

Hopefully, this should be enough to get you started.

# Answer
> 9 votes
As per the description of your requirements:

* one thread waiting for an external device
* one thread blinking a LED

It seems you could use one Arduino interrupt for the first "thread" (I would rather call it "task" in fact).

Arduino interrupts can call one function (your code) based on an external event (voltage level or level change on a digital input pin), that will trigger your function immediately.

However, one important point to keep in mind with interrupts is that the called function should be as fast as possible (typically, there should be no `delay()` call or any other API that would depend on `delay()`).

If you have a long task to activate upon external event trigger, then you could potentially use a cooperative scheduler and add a new task to it from your interrupt function.

A second important point about interrupts is that their number is limited (e.g. only 2 on UNO). So if you start tohave more external events, you would need to implement some kind of multiplexing all inputs into one, and have your interrupt function determine what multiplexed inut was the actual trigger.

# Answer
> 8 votes
A simple solution is to use a Scheduler. There are several implementations. This describes shortly one that is available for AVR and SAM based boards. Basically a single call will start a task; "sketch within a sketch".

```
#include <Scheduler.h>
....
void setup()
{
  ...
  Scheduler.start(taskSetup, taskLoop);
}

```

Scheduler.start() will add a new task that will run the taskSetup once and then repeatedly call taskLoop just as the Arduino sketch works. The task has its own stack. The size of the stack is an optional parameter. Default stack size is 128 bytes.

To allow context switching the tasks need to call yield() or delay(). There is also a support macro for waiting for a condition.

```
await(Serial.available());

```

The macro is syntactic sugar for the following:

```
while (!(Serial.available())) yield();

```

Await can also be used to synchronize tasks. Below is an example snippet:

```
volatile int taskEvent = 0;
#define signal(evt) do { await(taskEvent == 0); taskEvent = evt; } while (0)
...
void taskLoop()
{
  await(taskEvent);
  switch (taskEvent) {
  case 1:
  ...
  }
  taskEvent = 0;
}
...
void loop()
{
  ...
  signal(1);
}

```

For further details see the examples. There are examples from multiple LED blink to debounce button and a simple shell with non-blocking command line read. Templates and namespaces can be used to help structure and reduce the source code. Below sketch shows how to use template functions for multi-blink. It is sufficient with 64 bytes for the stack.

```
#include <Scheduler.h>

template<int pin> void setupBlink()
{
  pinMode(pin, OUTPUT);
}

template<int pin, unsigned int ms> void loopBlink()
{
  digitalWrite(pin, HIGH);
  delay(ms);
  digitalWrite(pin, LOW);
  delay(ms);
}

void setup()
{
  Scheduler.start(setupBlink<11>, loopBlink<11,500>, 64);
  Scheduler.start(setupBlink<12>, loopBlink<12,250>, 64);
  Scheduler.start(setupBlink<13>, loopBlink<13,1000>, 64);
}

void loop()
{
  yield();
}

```

There is also a benchmark to give some idea of the performance, i.e. time to start task, context switch, etc.

Last, there are a few support classes for task level synchronization and communication; Queue and Semaphore.

# Answer
> 5 votes
I also came to this topic while implementing a matrix LED display.

In one word, you may build a polling scheduler by using millis() function and timer interrupt in Arduino.

I suggest the following articles from Bill Earl:

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/overview

https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview

# Answer
> 3 votes
From a previous incantation of this forum, the following question/answer was moved to Electrical Engineering. It has sample arduino code to blink an LED using a timer interrupt while using the main loop to do serial IO.

https://electronics.stackexchange.com/questions/67089/how-can-i-control-things-without-using-delay/67091#67091

Repost:

Interrupts are a common way to get things done while something else is going on. In the example below, the LED is blinking without using `delay()`. Whenever `Timer1` fires, the interrupt service routine (ISR) `isrBlinker()` is called. It switches the LED on/off.

To show that other things can simultaneously happen, `loop()` repeatedly writes foo/bar to the serial port independent of the LED blinking.

```
#include "TimerOne.h"

int led = 13;

void isrBlinker()
{
  static bool on = false;
  digitalWrite( led, on ? HIGH : LOW );
  on = !on;
}

void setup() {
  Serial.begin(9600);
  Serial.flush();
  Serial.println("Serial initialized");

  pinMode(led, OUTPUT);

  // initialize the ISR blinker
  Timer1.initialize(1000000);
  Timer1.attachInterrupt( isrBlinker );
}

void loop() {
  Serial.println("foo");
  delay(1000);
  Serial.println("bar");
  delay(1000);
}

```

This is a very simple demo. ISRs can be much more complex and can be triggered by timers and external events (pins). Many of the common libraries are implemented using ISRs.

# Answer
> 3 votes
You could also give my ThreadHandler library a try

https://bitbucket.org/adamb3\_14/threadhandler/src/master/

It uses an interrupting scheduler to allow context switching without relaying on yield() or delay().

I created the library because I needed three threads and I needed two of them to run at a precise time no matter what the others were doing. The first thread handled serial communication. The second was running a Kalman filter using float matrix multiplication with the Eigen library. And the third was a fast current control loop thread which had to be able to interrupt the matrix calculations.

## How it works

Each cyclic thread has a priority and a period. If a thread, with higher priority than the current executing thread, reaches its next execution time the scheduler will pause the current thread and switch to the higher priority one. Once the high priority thread completes its execution the scheduler switches back to the previous thread.

### Scheduling rules

The scheduling scheme of the ThreadHandler library is as follows:

1. Highest priority first.
2. If the priority is the same then the thread with the earliest deadline is executed first.
3. If two threads have the same deadline then the first created thread will execute first.
4. A thread can only be interrupted by threads with higher priority.
5. Once a thread is executing it will block execution for all threads with lower priority until the run function returns.
6. The loop function has priority -128 compared to ThreadHandler threads.

## How to use

Threads can be created via c++ inheritance

```
class MyThread : public Thread
{
public:
    MyThread() : Thread(priority, period, offset){}

    virtual ~MyThread(){}

    virtual void run()
    {
        //code to run
    }
};

MyThread* threadObj = new MyThread();

```

Or via createThread and a lambda function

```
Thread* myThread = createThread(priority, period, offset,
    []()
    {
        //code to run
    });

```

Thread objects automatically connect to the ThreadHandler when they are created.

To start execution of created thread objects call:

```
ThreadHandler::getInstance()->enableThreadExecution();

```

# Answer
> 2 votes
And here is yet another microprocessor cooperative multitasking library – PQRST: a Priority Queue for Running Simple Tasks.

In this model, a thread is implemented as a subclass of a `Task`, which is scheduled for some future time (and possibly rescheduled at regular intervals, if, as is common, it subclasses `LoopTask` instead). The `run()` method of the object is called when the task becomes due. The `run()` method does some due work, and then returns (this is the cooperative bit); it'll typically maintain some sort of state machine to manage its actions on successive invocations (a trivial example is the `light_on_p_` variable in the example below). It requires a slight rethinking of how you organise your code, but has proven very flexible and robust in fairly intensive use.

It's agnostic about the time units, so it is as happy running in units of `millis()` as `micros()`, or any other tick that is convenient.

Here is the ‘blink’ program implemented using this library. This shows only a single task running: other tasks would typically be created, and started within `setup()`.

```
#include "pqrst.h"

class BlinkTask : public LoopTask {
private:
    int my_pin_;
    bool light_on_p_;
public:
    BlinkTask(int pin, ms_t cadence);
    void run(ms_t) override;
};

BlinkTask::BlinkTask(int pin, ms_t cadence)
    : LoopTask(cadence),
      my_pin_(pin),
      light_on_p_(false)
{
    // empty
}
void BlinkTask::run(ms_t t)
{
    // toggle the LED state every time we are called
    light_on_p_ = !light_on_p_;
    digitalWrite(my_pin_, light_on_p_);
}

// flash the built-in LED at a 500ms cadence
BlinkTask flasher(LED_BUILTIN, 500);

void setup()
{
    pinMode(LED_BUILTIN, OUTPUT);
    flasher.start(2000);  // start after 2000ms (=2s)
}

void loop()
{
    Queue.run_ready(millis());
}

```

---
Tags: arduino-uno, threads
---


# Question
Title: What features of the Arduino framework will fail if I use my own infinite loop in favor of the standard loop()?
I have a strong urge to replace the framework-provided `loop()` function with my own like so:

```
__attribute__((always_inline)) inline void fastLoop()
{
}

void setup()
{
   // Performing setup here...
   Serial.begin(115200);

   // Now looping
   for(;;)
      fastLoop();
}

```

This way, my loop is inlined and I'm saving quite a few cycles - avoiding not only Arduino housekeeping costs, but also the function call cost which even for a void function has to be at least 6 cycles on AVR (\>=2 for RCALL and 4 for RET).

This is the framework code for calling `loop()` from `main()`:

```
for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
}

```

My question is: what does this `serialEvent` stuff do? What features of the framework will stop working properly with my own loop?

Assuming my loop has observable side effects as required by the C++ standard, of course (otherwise it can be optimized out).

# Answer
It depends on which "Arduino" you are running it on.

On an Arduino Uno, for example, then the only thing that won't work is the SerialEvent system. Everything else that matters is interrupts.

Here is `main()` on the Arduino AVR core:

```
int main(void)
{
    init();

    initVariant();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

```

As you can see, `loop()` is run just the same way as your `fastLoop()`, just not `inline`, and adding in a call to `serialEventRun()` if it has been defined.

If no serial event handlers have been defined, then it won't do anything there anyway.

To save clock cycles you would get more benefit (as long as you don't want to use `millis()`, `delay()`, serial communication, etc) from disabling interrupts.

However, on an ESP32 or ESP8266 you will find that your watchdog times out and resets the unit. This is because it relies on code being run regularly to manage the WiFi connection that keeps "kicking the dog". Without that being run (which can be called by calling the `yield()` function) the watchdog times out.
> 1 votes

---
Tags: loop
---


title: Can I leave AVcc disconnected?

text:
# Question
Title: Can I leave AVcc disconnected?
I am using ATmega8A standalone but analog pins (Port C) have not been use.

Due to ATmega8A does not have a PRR (Power Reduction Register) to disable ADC and TWI.

I would like to know, is it a work around solution to reduce the power consumption if AVcc is not connected?

# Answer
> 1 votes
No, the datasheet says power must be connected to Avcc. This is from the '328P, Atmega8A is similar but with less memory: (Microchip is taking forever to open the Atmega8A datasheet for me).

> 5.2.7 AVCC AVCC is the supply voltage pin for the A/D Converter (ADC), PC\[3:0\], and PE\[3:2\]. It should be externally connected to VCC, even if the ADC is not used. If the ADC is used, it should be connected to VCC through a low-pass filter.

https://www.microchip.com/wwwproducts/en/ATmega8A

# Answer
> 3 votes
No. You must connect AVcc even if you're not using the ADC. According to the datasheet:

> AVCC is the supply voltage pin for the A/D Converter, Port C (3:0), and ADC (7:6). **It should be externally connected to VCC, even if the ADC is not used.** If the ADC is used, it should be connected to VCC through a low-pass filter. Note that Port C (5:4) use digital supply voltage, VCC.

---
Tags: power
---


title: NodeMCU keeps disconnecting

text:
# Question
Title: NodeMCU keeps disconnecting
I have made a home automation system consisting of a NodeMCU, 4 channel relay board running on Blynk and IFTTT.

At the moment I'm only controlling a string of fairy lights and two LED strips from it, both connected to the relay of course.

The only code running on the NodeMCU is the Blynk ESP8266 Standalone code. Here it is (with the necessary changes of course) -

```
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "YourAuthToken";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
}

void loop()
{
  Blynk.run();
  // You can inject your own code or combine it with other sketches.
  // Check other examples on how to communicate with Blynk. Remember
  // to avoid delay() function!
}

```

Now the thing is, the NodeMCU automatically disconnects from the WiFi randomly. Sometimes it reconnects immediately, sometimes it doesn't reconnect at all and I have to keep hitting the reset button to get it working again.

This is really annoying as everything I got connected to the NodeMCU also comes on all of a sudden and scares the hell out of me.

The code is all fine, the power supply is stable (5v 1A), all the cables are in place and the NodeMCU is tucked away in a corner where nobody touches it. I can't seem to work out why is this happening.

Any fixes for this?

# Answer
> 1 votes
I had this same issue with an ESP8266 NodeMCU-12E using Cayenne in the past. It would drop connection for no apparent reason, but no matter what, most of the time it'd never reconnect until a reset. Here's what I did:

```
CAYENNE_DISCONNECTED(){
  Serial.println(F("Cayenne disconnected, rebooting..."));
  ESP.restart();
}

```

I've never used `Blynk` before, but after a quick look, this may do the same thing (untested):

```
if (! Blynk.connected){
  Serial.println(F("Blynk disconnected, rebooting..."));
  ESP.restart();
}

```

It effectively reboots the ESP unit if the connection to Blynk drops for any reason.

---
Tags: esp8266, wifi, nodemcu, relay
---


title: Using SoftwareSerial.h in .cpp file

text:
# Question
Title: Using SoftwareSerial.h in .cpp file
I am trying to modularize the different components in my arduino build by using objects, but am having trouble with the one controlling a wireless transceiver, which uses `SoftwareSerial.h`

I believe I am (generally) setting up the use of these objects correctly because I have other objects that build correctly in other files.

I think my issue is somehow part of `SoftwareSerial.h`, but I am not knowledgeable enough to get in and diagnose it... I think my core issue is that `SoftwareSerial` is not being brought in properly.

**Transciever.cpp**

```
/*
   This code controls the HC-12 transciever
*/
#include <Arduino.h>
#include <SoftwareSerial.h>

enum class TransReadStatus {
  RELAY_OFF,
  RELAY_ON,
  NO_DATA
};

class TranscieverHandler {
  public:
    TranscieverHandler(
      int txPinIn,
      int rxPinIn,
      int setPinIn,
      int baudRateIn
    ): txPin(txPinIn),
      rxPin(rxPinIn),
      setPin(setPinIn),
      baudRate(baudRateIn)
    {
      SoftwareSerial hc12(txPin, rxPin);
    }

    void init() {
      hc12.begin(baudRate);
      pinMode(setPin, OUTPUT);
      digitalWrite(setPin, HIGH);  // HC-12 normal, transparent mode
    }

    TransReadStatus checkForSignal() {
      while (hc12.available()) {             // If HC-12 has data
        incomingByte = hc12.read();          // Store each icoming byte from HC-12
        readBuffer += char(incomingByte);    // Add each byte to ReadBuffer string variable
      }
      delay(100);

      if (onBytes.equals(readBuffer)) {
        readBuffer = "";
        return TransReadStatus::RELAY_ON;
      } else if (offBytes.equals(readBuffer)) {
        readBuffer = "";
        return TransReadStatus::RELAY_OFF;
      }
      readBuffer = "";
      return TransReadStatus::NO_DATA;
    }

    TransReadStatus getLastRecievedStatus() {
      TransReadStatus newStatus = checkForSignal();

      if (newStatus == TransReadStatus::NO_DATA) {
        return lastStatus;
      }
      lastStatus = newStatus;
      return lastStatus;
    }

  protected:
    const int txPin;// = 10;
    const int rxPin;// = 11;
    const int setPin;// = 12;
    const int baudRate;// 9600
    /*
       Constants for signals
    */
    const String setOnBytes = String("SET RELAY ON");
    const String setOffBytes = String("SET RELAY OFF");
    const String onBytes = String("STATUS: RELAY IS ON");
    const String offBytes = String("STATUS: RELAY IS OFF");

    SoftwareSerial hc12;

    byte incomingByte;
    String readBuffer = "";
    TransReadStatus lastStatus = TransReadStatus::NO_DATA;
    unsigned long lastSendOnSignal = millis();

};

```

**Output from failed compilation:**

```
Arduino: 1.8.9 (Linux), Board: "Arduino/Genuino Uno"

/home/greg/other/arduino-1.8.9/arduino-builder -dump-prefs -logger=machine -hardware /home/greg/other/arduino-1.8.9/hardware -tools /home/greg/other/arduino-1.8.9/tools-builder -tools /home/greg/other/arduino-1.8.9/hardware/tools/avr -built-in-libraries /home/greg/other/arduino-1.8.9/libraries -libraries /home/greg/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10809 -build-path /tmp/arduino_build_227628 -warnings=default -build-cache /tmp/arduino_cache_459309 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.arduinoOTA.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.2.1.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -verbose /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino
/home/greg/other/arduino-1.8.9/arduino-builder -compile -logger=machine -hardware /home/greg/other/arduino-1.8.9/hardware -tools /home/greg/other/arduino-1.8.9/tools-builder -tools /home/greg/other/arduino-1.8.9/hardware/tools/avr -built-in-libraries /home/greg/other/arduino-1.8.9/libraries -libraries /home/greg/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10809 -build-path /tmp/arduino_build_227628 -warnings=default -build-cache /tmp/arduino_cache_459309 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.arduinoOTA.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.2.1.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=/home/greg/other/arduino-1.8.9/hardware/tools/avr -verbose /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino
Using board 'uno' from platform in folder: /home/greg/other/arduino-1.8.9/hardware/arduino/avr
Using core 'arduino' from platform in folder: /home/greg/other/arduino-1.8.9/hardware/arduino/avr
Detecting libraries used...
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard /tmp/arduino_build_227628/sketch/SwitchController.ino.cpp -o /dev/null
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /tmp/arduino_build_227628/sketch/SwitchController.ino.cpp -o /dev/null
Using cached library dependencies for file: /tmp/arduino_build_227628/sketch/Buttons.cpp
Using cached library dependencies for file: /tmp/arduino_build_227628/sketch/LEDs.cpp
Using cached library dependencies for file: /tmp/arduino_build_227628/sketch/Switches.cpp
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /tmp/arduino_build_227628/sketch/Transciever.cpp -o /dev/null
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.cpp -o /dev/null
Generating function prototypes...
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /tmp/arduino_build_227628/sketch/SwitchController.ino.cpp -o /tmp/arduino_build_227628/preproc/ctags_target_for_gcc_minus_e.cpp
/home/greg/other/arduino-1.8.9/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /tmp/arduino_build_227628/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
Using previously compiled file: /tmp/arduino_build_227628/sketch/Buttons.cpp.o
Using previously compiled file: /tmp/arduino_build_227628/sketch/Switches.cpp.o
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /tmp/arduino_build_227628/sketch/SwitchController.ino.cpp -o /tmp/arduino_build_227628/sketch/SwitchController.ino.cpp.o
/home/greg/other/arduino-1.8.9/hardware/tools/avr/bin/avr-g++ -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/cores/arduino -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/variants/standard -I/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src /tmp/arduino_build_227628/sketch/Transciever.cpp -o /tmp/arduino_build_227628/sketch/Transciever.cpp.o
Using previously compiled file: /tmp/arduino_build_227628/sketch/LEDs.cpp.o
/tmp/arduino_build_227628/sketch/Transciever.cpp: In constructor 'TranscieverHandler::TranscieverHandler(int, int, int, int)':
Transciever.cpp:23:26: error: no matching function for call to 'SoftwareSerial::SoftwareSerial()'
       baudRate(baudRateIn)
                          ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:92:3: note: candidate: SoftwareSerial::SoftwareSerial(uint8_t, uint8_t, bool)
   SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);

   ^
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:92:3: note:   candidate expects 3 arguments, 0 provided
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:50:7: note: candidate: constexpr SoftwareSerial::SoftwareSerial(const SoftwareSerial&)
 class SoftwareSerial : public Stream

       ^
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:50:7: note:   candidate expects 1 argument, 0 provided
/tmp/arduino_build_227628/sketch/Transciever.cpp: In member function 'void TranscieverHandler::init()':
/tmp/arduino_build_227628/sketch/Transciever.cpp:29:26: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
       hc12.begin(baudRate);
                          ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:94:8: note:   in call to 'void SoftwareSerial::begin(long int)'
   void begin(long speed);

        ^
/tmp/arduino_build_227628/sketch/Transciever.cpp: In member function 'TransReadStatus TranscieverHandler::checkForSignal()':
/tmp/arduino_build_227628/sketch/Transciever.cpp:36:29: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
       while (hc12.available()) {             // If HC-12 has data
                             ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:104:15: note:   in call to 'virtual int SoftwareSerial::available()'
   virtual int available();

               ^
/tmp/arduino_build_227628/sketch/Transciever.cpp:37:34: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
         incomingByte = hc12.read();          // Store each icoming byte from HC-12
                                  ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:103:15: note:   in call to 'virtual int SoftwareSerial::read()'
   virtual int read();

               ^
In file included from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:0:
/tmp/arduino_build_227628/sketch/Transciever.cpp: In constructor 'TranscieverHandler::TranscieverHandler(int, int, int, int)':
Transciever.cpp:23:26: error: no matching function for call to 'SoftwareSerial::SoftwareSerial()'
       baudRate(baudRateIn)
                          ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0,
                 from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:92:3: note: candidate: SoftwareSerial::SoftwareSerial(uint8_t, uint8_t, bool)
   SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);

   ^
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:92:3: note:   candidate expects 3 arguments, 0 provided
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:50:7: note: candidate: constexpr SoftwareSerial::SoftwareSerial(const SoftwareSerial&)
 class SoftwareSerial : public Stream

       ^
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:50:7: note:   candidate expects 1 argument, 0 provided
In file included from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:0:
/tmp/arduino_build_227628/sketch/Transciever.cpp: In member function 'void TranscieverHandler::init()':
/tmp/arduino_build_227628/sketch/Transciever.cpp:29:26: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
       hc12.begin(baudRate);
                          ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0,
                 from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:94:8: note:   in call to 'void SoftwareSerial::begin(long int)'
   void begin(long speed);

        ^
In file included from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:0:
/tmp/arduino_build_227628/sketch/Transciever.cpp: In member function 'TransReadStatus TranscieverHandler::checkForSignal()':
/tmp/arduino_build_227628/sketch/Transciever.cpp:36:29: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
       while (hc12.available()) {             // If HC-12 has data
                             ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0,
                 from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:104:15: note:   in call to 'virtual int SoftwareSerial::available()'
   virtual int available();

               ^
In file included from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:0:
/tmp/arduino_build_227628/sketch/Transciever.cpp:37:34: warning: passing 'const SoftwareSerial' as 'this' argument discards qualifiers [-fpermissive]
         incomingByte = hc12.read();          // Store each icoming byte from HC-12
                                  ^
In file included from /tmp/arduino_build_227628/sketch/Transciever.cpp:5:0,
                 from /home/greg/GitRepos/WirelessSwitch/SwitchController/SwitchController.ino:32:
/home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial/src/SoftwareSerial.h:103:15: note:   in call to 'virtual int SoftwareSerial::read()'
   virtual int read();

               ^
Using library SoftwareSerial at version 1.0 in folder: /home/greg/other/arduino-1.8.9/hardware/arduino/avr/libraries/SoftwareSerial
exit status 1
no matching function for call to 'SoftwareSerial::SoftwareSerial()'

```

# Answer
The member initialization is intended for objects construction. For ints you can do an assignment in the constructors body

```
TranscieverHandler(int txPinIn, int rxPinIn, int setPinIn, int baudRateIn)
    : hc12(txPin, rxPin) {
  txPin = txPinIn;
  rxPin = rxPinIn;
  setPin = setPinIn;
  baudRate = baudRateIn;
}

```
> 1 votes

---
Tags: softwareserial, compilation-errors, cpp
---


# Question
Title: How to code 4 relays to go off in intervals and not in sequence?
Code :

```
//FOR AEROPONIC SYSTEM WITH ROOM TEMPERATURE AND HUMIDITY SENSOR
//AND 4 GROW CHAMBERS WITH DIFFERENT SPRAYING TIME

// RELAY CONTROL
#define RELAY1_PIN 2
#define RELAY2_PIN 3
#define RELAY3_PIN 4
#define RELAY4_PIN 5

//Libraries
#include <DHT.h>;

//Constants
#define DHTPIN 6
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

//Variables
int chk;
float hum;
float temp;

void setup()
{
    Serial.begin(9600);
    Serial.println("SENSOR RUNNING");
    dht.begin();

    pinMode(RELAY1_PIN, OUTPUT);
    pinMode(RELAY2_PIN, OUTPUT);
    pinMode(RELAY3_PIN, OUTPUT);
    pinMode(RELAY4_PIN, OUTPUT);
}

void loop()
{
    delay(2000);
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (isnan(h) || isnan(t))
    {
        Serial.println("CONNECTION ERROR");
        return;
    }
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.println(" ");
    delay(2*1000);
    {
        // FOR RELAY
        digitalWrite(RELAY1_PIN, HIGH);
        delay(2*1000); // wait for 2 second ON
        digitalWrite(RELAY2_PIN, HIGH);
        delay(3*1000); // wait for 3 second ON
        digitalWrite(RELAY3_PIN, HIGH);
        delay(4*1000); // wait for 4 second ON
        digitalWrite(RELAY4_PIN, HIGH);
        delay(5*1000); // wait for 5 second ON

        digitalWrite(RELAY1_PIN, LOW);
        digitalWrite(RELAY2_PIN, LOW);
        digitalWrite(RELAY3_PIN, LOW);
        digitalWrite(RELAY4_PIN, LOW);
        delay(5*60*1000);
    }
}

```

This code doesn't do what I want. How do I make them independent?

# Answer
Here is some code that might help you; leaving out the temperature and humidity stuff:

```
// constants
// number or relays
const int relays = 4;

// pins for the relays
const int relayPins[] = {2, 3, 4, 5};

// relay cycle times
const unsigned long relayTimes[] = {
     5*60*1000, // 5 min
     60*60*1000, // 1 Hour
     2*60*60*1000, // 2 hours
     12*60*60*1000 // 12 hours
  };

// relay on durations
const unsigned long relayOntimes[] = {
    1000, // 1 second
    10*1000, // 10 seconds
    60*1000, // 1 minute
    60*60*1000 // 1 hour
  };

// timing for the relays
// storing the last time
unsigned long relayElapsed[] = {0, 0, 0, 0};

// state of each relay
int relaystate[] = {0, 0, 0, 0};

// helper function to process each relay
void relay_helper(unsigned long t, unsigned long &elapsed, int pin, int &state, unsigned long delta, unsigned long ontime)
{
  // depending on the state we do different things
  switch (state)
  {
  case 0: // state 0 is off, wait until time has passed
    if ((t-elapsed) > delta)
    {  // then
       state = 1; // set the state to on
       elapsed = t; // reset the time
       digitalWrite(pin, HIGH); // turn on
    }
    break;
  case 1: // state 1 is on, wait until time has passed
    if ((t-elapsed) > ontime)
    {  // then
       state = 0; // set the state to off
       elapsed = t; // reset the time
       digitalWrite(pin, LOW); // turn off
    }
    break;
  }
}

void setup()
{
  unsigned long start = millis();
  for(int i = 0; i < relays; i++) // for each pin
  {
    pinMode(relayPins[i], OUTPUT); // set it to output
    digitalWrite(relayPins[i], LOW); // and turn it off
    relayElapsed[i] = start;
  }
}

void loop()
{
  unsigned long tm = millis();
  for(int i = 0; i < relays; i++)
  {
    relay_helper(tm, relayElapsed[i], relayPins[i], relaystate[i], relayTimes[i], relayOnTimes[i]);
  }
  // do other loop stuff
}

```

The basic idea is that the only way to do thing simultaneously is to do things in sequence really fast, we can't use delay() because it is a busy loop, nothing else can happen during delay(), so we keep track of the time and when it is time to turn on the relay we turn it on, and when it is time to turn it off we turn if off.

Another option would be to write a class per relay:

```
class Relay
{
public:
  Relay(int pin, unsigned long delta, unsigned long ontime);
  ~Relay();

  process(unsigned long t);

private:
  unsigned long delta;
  unsigned long ontime;
  unsigned long last; // elapsed
  int pin;
};

```

Then one can create an array of these:

```
Relay[] relays = {
    Relay(2, 5*60000, 1000),
    Relay(3, 60*60000, 10000),
    Relay(4, 2*60*60000, 60000),
    Relay(5, 12*60*60000, 60*60000)
  };

```

put the code from setup into the constuctor, and the code from the helper into process, and finally call it in a loop in loop.

The first way shown is how one would do it without C++ classes, and the second way is with them!
> 1 votes

---
Tags: arduino-uno, timers, relay
---


# Question
Title: Error "avr-g++: error: CreateProcess: No such file or directory" When Compiling Script
Whenever I try to compile a script, the Arduino IDE throws the error `avr-g++: error: CreateProcess: No such file or directory`. I've already tried reinstalling the IDE, changing the board version in the board manager to 1.6.21, and deleting the Arduino15 folder under `AppData/Local/Arduino15`. This problem appeared suddenly - one compilation worked, and two minutes later, nothing would compile - and occurs across all scripts that I've tried.

I'm working from Windows 10 and compiling for an Arduino Uno.

# Answer
> 2 votes
Turns out that McAfee's Host Intrusion Prevention had decided to start blocking `avr-g++.exe`. Not sure why it did so all of a sudden, but it's an easy fix once you know where to look. Anyone finding this in the future should be sure to check their antivirus logs to see if the compiler's executable is being blocked.

---
Tags: arduino-uno, ide, compilation-errors
---


# Question
Title: LSM9DS1 breakout - How to increase speed
With regards to the Adafruit LSM9DS1 breakout: enter link description here

And using the Library: enter link description here

I am trying to increase the sample rate, or speed of this chip. I am using a Sparkfun Pro Micro 5V

With the adafruit library, you need to request accelerometer, gyro, magnetometer and temperature at once, and all I need is the accelerometer values. I am hoping by figuring out how to request only the accel values it will speed up the loop. But also, there must be another setting that could speed up the sample rate?

Any help would be appreciated!

my code currently:

```
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS1.h>
#include <Adafruit_Sensor.h>  // not used in this demo but required!
Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1();
#define LSM9DS1_SCK A5
#define LSM9DS1_MISO 12
#define LSM9DS1_MOSI A4
#define LSM9DS1_XGCS 6
#define LSM9DS1_MCS 5

void setupSensor()
{
  // 1.) Set the accelerometer range
  lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_2G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_4G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_8G);
  //lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_16G);

  // 2.) Set the magnetometer sensitivity
  lsm.setupMag(lsm.LSM9DS1_MAGGAIN_4GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_8GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_12GAUSS);
  //lsm.setupMag(lsm.LSM9DS1_MAGGAIN_16GAUSS);

  // 3.) Setup the gyroscope
  lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_245DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_500DPS);
  //lsm.setupGyro(lsm.LSM9DS1_GYROSCALE_2000DPS);
}

double accelX = 0;
double accelY = 0;
double accelZ = 0;
double rms = 0;

void setup()
{
  Serial.begin(115200);
  // Try to initialize and warn if we couldn't detect the chip
  if (!lsm.begin())
  {
    Serial.println("Oops ... unable to initialize the LSM9DS1. Check your
wiring!");
    while (1);
  }
  Serial.println("Found LSM9DS1 9DOF");
  setupSensor();
  delay(5000);//program stabilization
}

void loop()
{
  lsm.read();
  sensors_event_t a, m, g, temp;
  lsm.getEvent(&a, &m, &g, &temp);
  accelX = a.acceleration.x;
  accelY = a.acceleration.y;
  accelZ = a.acceleration.z;
  rms = (accelX*accelX)+(accelY*accelY)+(accelZ*accelZ);
  Serial.println(rms);
}

```

# Answer
Check the header of the library,

you will find `readAccel` `readMag` `readGyro` and `readTemp` in separate public functions and looking at the implementation of `read` it just calls those 4 in sequence. `readAccel` will update the `accelData` member field.

So you can just call `lsm.readAccel()` in the loop and then grab `lsm.accelData` directly and ignore the rest.

```
void loop()
{
  lsm.readAccel();
  accelX = lsm.accelData.x;
  accelY = lsm.accelData.y;
  accelZ = lsm.accelData.z;
  rms = (accelX*accelX)+(accelY*accelY)+(accelZ*accelZ);
  Serial.println(rms);
}

```
> 1 votes

# Answer
Here is a link to the LSM9DS1 datasheet. In Chapter 3 it describes how to put the device in Accelerometer-only mode. At a quick scan of it, I believe there was timing information also, but at least knowing how to do it, you could then make your own timing measurements.
> 1 votes

---
Tags: arduino-pro-micro, gyroscope, magnetometer
---


# Question
Title: LED Matrix Display with dissimilar brightness
So far I have seen in LED matrix related projects that the brightness is controlled in an entirety manner. That means the brightness of total display can either be reduced or increased. How can we display only a part of the display with more brighter than the remaining matrix? Appreciate if anyone provide some pseudo logic to achieve this.

# Answer
> 1 votes
There's two options:

1. Use a matrix driver that supports different brightnesses per pixel, or:
2. Rapidly display a different arrangement of pixels in quick succession. The pixels that are on more often are brighter.

Option 1 basically does option 2 in hardware.

The theory is simple: For one LED you can vary the brightness by using PWM - that switches the LED on and off very rapidly. The longer it is on the brighter it appears.

You can do the same with a matrix of pixels. Instead of dealing with one pixel though you are dealing with, in effect, a series of "images". Each "image" has a different combination of pixels. The more "images" you have the greater variation you can get in your pixel brightnesses.

For example if you first display a frame of:

```
. . . . . . . .
. . # # # # . .
. # . . . . # .
. # . . . . # .
. # . . . . # .
. # . . . . # .
. . # # # # . .
. . . . . . . .

```

followed by the image:

```
. . . . . . . #
. . # # # # # .
. # . . . # # .
. # . . # . # .
. # . # . . # .
. # # . . . # .
. # # # # # . .
# . . . . . . .

```

then you will get a bright circle(ish) shape with a dimmer slash through it.

The only problem with this method is flicker. You have to have your matrix refreshing very fast. The more "images" you have to display in sequence the more it will flicker and the faster you will have to refresh your matrix to compensate.

# Answer
> 0 votes
Short answer: You likely can't, at a hardware level.

The only way you'd be able to do this is to vary the duty cycle of each individual LED in the matrix (the percent of on-time vs. off-time).

The device would have to support that. Edit your question with the model number of the LED matrix you're using and it's spec sheet.

(Note that if you're using a simple grid of LEDs and row/column addressing you could use PWM to get some control over brightness, but you'd probably already be using multiplexing of the LEDs, which makes varying brightness per LED more complex.)

# Answer
> 0 votes
LED brightness is normally controlled by how long a given LED is lit. An LED that is on for 70ms and off for 30ms will be brighter then an LED that is on for only 30ms and off for 70ms.

So, the answer is to shorten the amount of time which the LED is on and lethen the time the LED is off for only those LEDs in your display which are to be dimmer.

This is usually referred to as the duty cycle of the LED. On an Arduino, the PWM or Pulse Width Modulator feature of the embedded processor is normally used to create the duty cycle signal for an LED.

# Answer
> 0 votes
Depends on what LEDs your matrix is made of. One option would be to make it from 'smart' LEDs at each location, such as WS2812B. These are a chip and 3 LEDs in one package, usually a 5050 size SMD package, but they can also be had in thru hole packages, and can be found built up into boards also (look at Sparkfun and Adfruit for examples). Serial data is sent in, with a 0-255 value for each LED, the control chip then drives the 3 LEDs with the PWM level commanded - 0/255 for off, 128/255 for 1/2 on for example, 255/255 for full on. The data is passed from device to device to load them up, so for example an 8x8 matrix would need 8x8x3 = 192 bytes of data sent in to load the display. The Arduino then doesn't need to do any more until the matrix needs to change. WS2812B needs some fancy timing to send in 0/1 data in a combined data/clock signal line, options are the Neopixel library or the FastLed.h library for Arduino, to send data in at up to 800 KHz rate. There is also another version of the chip that uses seperate clock and data lines, SPI.transfer I think can be used to send in data even faster. I don't recall that device's part number off hand, I've not used it.

For premade 8x8 modules using single color LEDs, then as described in other answers MAX7219 is often used, with 15 levels of brightness available for the whole display.

---
Tags: arduino-uno
---


title: how to set the delay on for 7 hours?

text:
# Question
Title: how to set the delay on for 7 hours?
For my application I need to simulate the sunlight including the rising and setting of the sun.

I have a program that will light up some LEDs slowly over a period of time but I need to know what to type in the (delay on) to keep the lights on for 7 hours?

Will it work if I just replace `delay(1000)` with `delay(25200000UL)` ? I don't want to run anything else at the same time and don't want to use or understand `millis()`. Thanks for any help.

# Answer
> 6 votes
Yes, absolutely, it should work. But your code will be easier to read if you use some constants, like:

```
const unsigned long SECOND = 1000;
const unsigned long HOUR = 3600*SECOND;

delay(7*HOUR);

```

# Answer
> 3 votes
Yes you can write `delay(25200000UL)` and it will delay for 7 hours.

**How it works**
`delay(x)` will delay for x number of milliseconds.
1 second = 1000 milliseconds
1 minute = 60 seconds
1 hour = 60 minutes
7 hours = 1000 * 60 * 60 * 7 = 25,200,000

This number is quite large but is well within the scope of an unsigned long: 32 bits = (2^32)-1 = 4,294,967,295. Doing the sums, this will last for 49 days and 17 hours.

**Delaying for \>49 days**
If for some reason you needed to go longer than 49 days, you can do so by placing the delay inside a `for` loop.

```
const unsigned long ONE_DAY = 24UL*3600*1000;
const unsigned int numOfDays = 51;
int i;
int j;

for( i=0; i<numOfDays; i++ )
{
    delay(ONE_DAY);
}

```

# Answer
> 1 votes
It's an old one but I give an answer. I think someone needs help like you.

I trying to make a fish meal machine with the Arduino Uno.

In the first. I counted seconds over a minute. It works well. But when I try over an hour it does not work.

After all. I got to know another way to count a long time

In the second. I used the SimpleTimer.h. The link is here. Arduino SimpleTimer

It's an easy way to makes a circular moving but it has the same problem. SimpleTime can't make a count over time. I think it's 30 seconds.

Now I referenced StackExchange Arduino. Here is my code.

```
#include <SimpleTimer.h>
#include <Servo.h>

#define FIVE_SEC 5000UL
#define ONE_MIN 60000UL
#define FIVE_MIN 300000UL
#define TEN_MIN 3000000UL
#define ONE_HR 3600000UL
#define EIGHT_HRS 28800000UL
#define TWELVE_HRS 43200000UL

SimpleTimer timer;
Servo servo;
int servoPin  = 9;
int servoReadyAngle = 180;
int servoMoveAngle = 170;
int servoMoveCnt = 0;
int servoJobCycle = 35000;

unsigned long startTime;

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

  startTime = millis();
}

void loop() {

  if(millis()- startTime > TEN_MIN) {
    startTime = millis();
    giveAFishMeal();
  } else {
    Serial.print("ping ");
    Serial.println(millis());
  }

}

void giveAFishMeal() {

  int servoAngle;
  if(servoReadyAngle > servoMoveAngle) {
    servoAngle = servoReadyAngle - servoMoveAngle;
  } else {
    servoAngle = servoReadyAngle + servoMoveAngle;
  }

    Serial.println("I give a meal to your fish");

    delay(500);
    servo.write(servoReadyAngle);
    delay(500);
    servo.write(servoAngle);
    delay(500);

}

```

# Answer
> 0 votes
delay(1000) is a delay in ms. So for a 7 hour delay you need 7 hours * 60 minutes * 60 seconds * 1000 = 52,200,000

Adding UL is good, to show it's long and unsigned.

Also it fits in an unsigned long which has a max value of 2^32-1 = 4,294,967,295.

If you really want to test it you can wait 7 hours, or use a smaller number (like dividing by 60 * 60, thus 7,000 which should be 7 seconds, or make it 70.000 and check it is 70 seconds.

If you would want to make it explicitly how 52,200,000 is calculated or want to make your program more flexible you can always create some defines (or constants):

```
static const uint32_t DELAY_1_S      = 1000UL;
static const uint32_t DELAY_1_MINUTE = DELAY_1S * 60UL;
static const uint32_t DELAY_1_HOUR   = DELAY_1MINUTE * 60UL;

```

than you can use

```
delay(7UL * DELAY_1_HOUR); // Delay 7 hours

```

# Answer
> 0 votes
> For my application I need to simulate the sunlight including the rising and setting of the sun.

if you have to simulate that long of a delay, you are doing something seriously wrong.

but if you do want to go down that path, something like this may work

```
#define delay_1hr()  delay(1000ul * 60 * 60)  //delay a hour

//delay a day
void delay_hr(uint8_t hr) {
  while (hr--) delay_1hr();
}

```

---
Tags: arduino-uno
---