text:
NeoMatrix Button Troubles
I am creating a 20x15 LED Matrix using and Arduino Nano. My goal is to switch between different "scenes," if you will, using 4 buttons (I just need to run different code to make it display something different). The four buttons share a ground, and they go into digital pins (I don't have resistors on the ground because of this article). Then in the code (under void loop) there is one big if-then tree. For example,  if (button1State == HIGH) {} else {if (button2State == HIGH)} and so on and so forth.
When I connect the buttons, the lights flicker and glitch. Without the buttons, it goes to the last else completely fine, so I know my light code works. To me, the code looks fine, but I want to see if there is something that I am doing wrong. I wonder if putting the code in voids instead of them in the if-thens in the loop would be better, but I don't know how I would invoke them.
If anyone could figure out what I am doing wrong or something that could make my code better, I would be super grateful.
Here is my full, current code (ignore all of the comments, I am designing the code so someone with no coding knowledge could understand it)
//   HEY! LOOK UP HERE! I know it looks confusing, but don't worry, I'll help you! I'm Clippy!
//    _________________
//   < I can help you! >
//    -----------------
//    \
//     \
//        __
//       /  \
//       |  |
//       @  @
//       |  |
//       || |/
//       || ||
//       |\_/|
//       \___/

//As you know, there are 4 buttons. When they are pressed, they display something different. We can make them display text as well.
//Below are VARIABLES, which control what text is displayed when buttons are pressed. Put what you want them to display between the
//quotation marks. If you don't want anything in a button, just put a space inbetween them.

//Note: only button 1 and 3 can display text, so lets only put text in those :)
String buttonText1 = " "; //Again, put what you want button 1 to display in text
//String buttonText2 = " ";
String buttonText3 = " ";
//String buttonText4 = " ";
String defaultText = "   Text for the panel"; //This is what will show up when you first start it up

//Here we can adjust what the brightness of the panel is. We use a switch to do this. You can use values from 0 (lowest) to 255 (highest)
int switchLevel1 = 10;
int switchLevel2 = 200;

//Here we can control how many colors are on the backgrounds at one time. We can customize this to get some variety in our displays.
int colorsOnscreen1 = 5; //For button 1
//int colorsOnscreen2 = 3
int colorsOnscreen3 = 10; //For button 3
//int colorsOnscreen4 = 5;
int colorsOnscreenDefault = 3; //For when you start it up

int lastButton = 0; //Last button pressed stuff, gets fed to buttons

//----------------------------------------------------------------You Probably Don't Have To Worry About The Rest----------------------------------------------------------------

//This stuff you don't have to worry about, its for the board
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_NeoMatrix.h>
#include <gamma.h>
#include "RGB.h"
#ifndef PSTR
 #define PSTR
#include smileytongue24.h
#include yellowsmiley24.h
#endif

#define PIN 3 // This is the pin where the data is coming out (you don't have to worry about this)

const int button1 = 4;     // the number of the arcade button pins
const int button2 = 5;
const int button3 = 6;
const int button4 = 7;
const int brightnessSwitch = 8;

// variables will change:
int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;
int button3State = 0;
int button4State = 0;
int switchState = 0;
int panelBrightness = 0;

//This stuff tells the board how the lights are arranged. In our case, it starts at the top left, and
//the signal goes right, and zigzags the rest of the way. It also tells it that it is 20 by 15 LEDs
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(20, 15, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_RIGHT +
  NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);

void setup() {
  // initialize the buttons as inputs:
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(brightnessSwitch, INPUT);
  matrix.begin();
  matrix.setTextWrap(false);
  Serial.begin(9600);
  Serial.print("The LED Matrix has started. Default will be activated soon");
}

String panelText = buttonText1; //This is what text gets fed to the panel

int x    = matrix.width();
int pass = 0;

void loop() {
  matrix.setBrightness(panelBrightness); //This sets the overall brightness. 255 is the highest, while 0 is the lowest
  // read the state of the button:
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button4);
  button4State = digitalRead(button4);
  switchState = digitalRead(brightnessSwitch);
  if (switchState == HIGH){panelBrightness = switchLevel1;} else {panelBrightness = switchLevel2;} //Brightness Logic

  // if-then statements
  if (button1State == HIGH){ //BUTTON 1 CODE START
      static int i = 0;
  i++;
  for(int y = 0; y < 15; y++)
    for(int x = 0; x < 20; x++)
      if(y & 1)
        matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));
      else
        matrix.setPixelColor(x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));

  matrix.setTextColor(matrix.Color(255, 255, 255)); //This determines the text color. If you want to set a text color, search in google "Color Picker" and use the RGB values in place of the numbers in (a,a,a)
  matrix.setCursor(-((millis() / 40) & 127), 4);
  matrix.print(buttonText1);
  matrix.show();
}
//BUTTON 1 CODE END
   else {
      if (button2State == HIGH){ //BUTTON 2 CODE START
          //PUT WHAT HAPPENS FOR BUTTON 2 HERE
          //BUTTON 2 CODE END
      } else {
          if (button3State == HIGH){ //BUTTON CODE 3 START
                    static int i = 0;
  i++;
  for(int y = 0; y < 15; y++)
    for(int x = 0; x < 20; x++)
      if(y & 1)
        matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 200 * colorsOnscreen3 + i * 128 * 2)));
      else
        matrix.setPixelColor(x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 256 * colorsOnscreen3 + i * 128 * 2)));

  matrix.setTextColor(matrix.Color(255, 255, 255)); //This determines the text color. If you want to set a text color, search in google "Color Picker" and use the RGB values in place of the numbers in (a,b,c)
  matrix.setCursor(-((millis() / 40) & 127), 4);
  matrix.print(buttonText3);
  matrix.show();
}
              //BUTTON 3 CODE END
           else {
              if (button4State == HIGH){ //BUTTON 4 CODE START
                  //PUT WHAT HAPPENS FOR BUTTON 4 HERE
                  //BUTTON 4 CODE END
              } else {
                  //WHAT HAPPENS UNTIL A BUTTON IS PRESSED

   static int i = 0;
  i++;
  //matrix.fillScreen(0);
  for(int y = 0; y < 15; y++)
    for(int x = 0; x < 20; x++)
      if(y & 1)
        matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));
      else
        matrix.setPixelColor(x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));

  matrix.setTextColor(matrix.Color(255, 255, 255)); //This determines the text color. If you want to set a text color, search in google "Color Picker" and use the RGB values in place of the numbers in (a,b,c)
  matrix.setCursor(-((millis() / 70) & 127), 4);
  matrix.println(defaultText);
  matrix.show();

}}}}

    }

Again, Thank You
-Micah

Do you have just the IO pin -> wire -> button -> wire -> ground? Nothing else connected to the button or IO pin?

@Majenko Yup. I'm going to change it, but that is what I was doing. If it makes a difference, I also had all the grounds of the buttons tied together to one ground because my only other ground is being used to provide a ground consistent with the power supply for the data out.

I think your main problem is how you read the buttons.

You simply connected the buttons with ground and the corresponding digital input pin on the Arduino without any extra components, just like the linked forum entry states. But you missed a very important part: The pullup resistor. When your button is pressed, the Arduinos pin will be pulled to ground. But if it is not pressed, there is nothing connected to the pin. Such a pin is called floating, as it does not have a fixed reference value. It will pick up whatever noise is floating around at it's location (often the state of other electronic parts or pins near it). It will change it's state erratically. You need to pull the pin to Vcc (5V in case of the Nano), so that the pin has a clear fixed state, when the button is not pressed. This can be done by either an external or the internal pullup resistor of the Atmega328P (the chip on the Nano). In the forum post the internal pullup is activated by doing a digitalWrite(pin, HIGH); after setting the pin to INPUT. But I think it is more speaking code to just use pinMode(pin, INPUT_PULLUP); which will do the same in one single step.
In your code you check for the button pins to be HIGH, as if a button press would make the pin HIGH. But this is not the case, if you connect the button to ground. If pressed, the button will pull the pin to GROUND, thus a value of LOW. You need to check for the buttons to get LOW.

Thank you for your fast and insightful response. Just to make sure I am interpreting your comment correctly, you are saying that if I use the internal pull up on the chip (using pinMode(pin, INPUT_PULLUP); , then I do not need to use an external pull up resistor because my button with already be not floating? Just trying to make sure I am interpreting this right. Again, thank you for the helpful response!

Yes, correct. You don't need an external pullup resistor, when you are activating the internal one. If nothing is connected to the pin, it will have the state HIGH, since the internal pullup will pull it to Vcc. When the button is pressed, the pin is connected to ground, thus has a state of LOW. A very little current will flow through the internal pullup resistor.

You should always comment your code, so that you will know what your code does when you look at it 6 months from now.
For beginners, you should not leave out the braces {} from any part of the code as you did in the for loops.
Here is your code correctly formatted, followed by a more cleaned up version which may be easier for beginner to follow.
Main question is whether the for loops are written as you intended.
Also, the use of if {} else { if {}} makes the code listing somewhat convoluted.
The second listing shows the if {} else if {} version.
//   HEY! LOOK UP HERE! I know it looks confusing, but don't worry, I'll help you! I'm Clippy!
//    _________________
//   < I can help you! >
//    -----------------
//    \
//     \
//        __
//       /  \
//       |  |
//       @  @
//       |  |
//       || |/
//       || ||
//       |\_/|
//       \___/

// As you know, there are 4 buttons. When they are pressed, they display something different. We can make them display text as well.
// Below are VARIABLES, which control what text is displayed when buttons are pressed. Put what you want them to display between the
// quotation marks. If you don't want anything in a button, just put a space inbetween them.

//Note: only button 1 and 3 can display text, so lets only put text in those :)
String buttonText1 = " "; //Again, put what you want button 1 to display in text
//String buttonText2 = " ";
String buttonText3 = " ";
//String buttonText4 = " ";
String defaultText = "   Text for the panel"; //This is what will show up when you first start it up

//Here we can adjust what the brightness of the panel is. We use a switch to do this. You can use values from 0 (lowest) to 255 (highest)
int switchLevel1 =  10;
int switchLevel2 = 200;

//Here we can control how many colors are on the backgrounds at one time. We can customize this to get some variety in our displays.
int colorsOnscreen1 = 5;           // For button 1
//int colorsOnscreen2 = 3
int colorsOnscreen3 = 10;          // For button 3
//int colorsOnscreen4 = 5;
int colorsOnscreenDefault = 3;     // For when you start it up

int lastButton = 0;                // Last button pressed stuff, gets fed to buttons

//----------------------------------------------------------------You Probably Don't Have To Worry About The Rest----------------------------------------------------------------

//This stuff you don't have to worry about, its for the board
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_NeoMatrix.h>
#include <gamma.h>
#include "RGB.h"
#ifndef PSTR
 #define PSTR
#include smileytongue24.h
#include yellowsmiley24.h
#endif

#define PIN 3 // This is the pin where the data is coming out (you don't have to worry about this)

const int button1          = 4;     // the number of the arcade button pins
const int button2          = 5;
const int button3          = 6;
const int button4          = 7;
const int brightnessSwitch = 8;

// variables will change:
int button1State           = 0;     // variable for reading the pushbutton status
int button2State           = 0;
int button3State           = 0;
int button4State           = 0;
int switchState            = 0;
int panelBrightness        = 0;

                                                                        // This stuff tells the board how the lights are arranged.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(20,                      // In our case, it starts at the top left,
                                               15,                      //   and the signal goes right, and zigzags the rest of the way.
                                               PIN,                     // It also tells it that it is 20 by 15 LEDs
                                               NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
                                               NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(button1, INPUT);                                              // initialize the buttons as inputs:
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);

  pinMode(brightnessSwitch, INPUT);

  matrix.begin();
  matrix.setTextWrap(false);

  Serial.begin(9600);
  Serial.print("The LED Matrix has started. Default will be activated soon");
}

String panelText = buttonText1;                                         // This is what text gets fed to the panel

int x    = matrix.width();
int pass = 0;

void loop() {
  matrix.setBrightness(panelBrightness);                                // This sets the overall brightness. 255 is the highest, while 0 is the lowest

  button1State = digitalRead(button1);                                  // read the state of the buttons
  button2State = digitalRead(button2);
  button3State = digitalRead(button4);
  button4State = digitalRead(button4);

  switchState = digitalRead(brightnessSwitch);

  if (switchState == HIGH) { panelBrightness = switchLevel1; }          // Brightness Logic
  else                     { panelBrightness = switchLevel2; }

  // if-then statements
  if (button1State == HIGH) {                                           // BUTTON 1 CODE START
    static int i = 0;
    i++;
    for(int y = 0; y < 15; y++)
      for(int x = 0; x < 20; x++)
        if(y & 1)
          matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));
        else
          matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));

    matrix.setTextColor(matrix.Color(255, 255, 255));                   // This determines the text color.
    matrix.setCursor(-((millis() / 40) & 127), 4);                      //     If you want to set a text color, search in google "Color Picker"
                                                                        //     and use the RGB values in place of the numbers in (a,a,a)
    matrix.print(buttonText1);
    matrix.show();
  }                                                                     // BUTTON 1 CODE END

  else {
    if (button2State == HIGH) {                                         // BUTTON 2 CODE START
                                                                        //    PUT WHAT HAPPENS FOR BUTTON 2 HERE
    }                                                                   // BUTTON 2 CODE END
    else {
      if (button3State == HIGH) {                                       // BUTTON CODE 3 START
        static int i = 0;
        i++;
        for(int y = 0; y < 15; y++)
          for(int x = 0; x < 20; x++)
            if(y & 1)
              matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 200 * colorsOnscreen3 + i * 128 * 2)));
            else
              matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 256 * colorsOnscreen3 + i * 128 * 2)));

        matrix.setTextColor(matrix.Color(255, 255, 255));
        matrix.setCursor(-((millis() / 40) & 127), 4);

        matrix.print(buttonText3);
        matrix.show();
      }                                                                 // BUTTON 3 CODE END
      else {
        if (button4State == HIGH){                                      // BUTTON 4 CODE START
                                                                        //    PUT WHAT HAPPENS FOR BUTTON 4 HERE
        }                                                               // BUTTON 4 CODE END
        else {                                                          // WHAT HAPPENS UNTIL A BUTTON IS PRESSED

          static int i = 0;
          i++;
//        matrix.fillScreen(0);
          for(int y = 0; y < 15; y++)
            for(int x = 0; x < 20; x++)
              if(y & 1)
                matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));
              else
                matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));

          matrix.setTextColor(matrix.Color(255, 255, 255));
          matrix.setCursor(-((millis() / 70) & 127), 4);

          matrix.println(defaultText);
          matrix.show();
        }
      }
    }
  }
}

    //   HEY! LOOK UP HERE! I know it looks confusing, but don't worry, I'll help you! I'm Clippy!
    //    _________________
    //   < I can help you! >
    //    -----------------
    //    \
    //     \
    //        __
    //       /  \
    //       |  |
    //       @  @
    //       |  |
    //       || |/
    //       || ||
    //       |\_/|
    //       \___/

    // As you know, there are 4 buttons. When they are pressed, they display something different. We can make them display text as well.
    // Below are VARIABLES, which control what text is displayed when buttons are pressed. Put what you want them to display between the
    // quotation marks. If you don't want anything in a button, just put a space inbetween them.

                                                  // Note: only button 1 and 3 can display text, so lets only put text in those :)
    String buttonText1 = " ";                     // Again, put what you want button 1 to display in text
//  String buttonText2 = " ";
    String buttonText3 = " ";
//  String buttonText4 = " ";

    String defaultText = "   Text for the panel"; // This is what will show up when you first start it up

    int switchLevel1 =  10;                       // Here we can adjust what the brightness of the panel is.
    int switchLevel2 = 200;                       // We use a switch to do this. You can use values from 0 (lowest) to 255 (highest)

                                                  // Here we can control how many colors are on the backgrounds at one time.
                                                  // We can customize this to get some variety in our displays.
    int colorsOnscreen1 =  5;                     // For button 1
//  int colorsOnscreen2 =  3;
    int colorsOnscreen3 = 10;                     // For button 3
//  int colorsOnscreen4 =  5;

    int colorsOnscreenDefault = 3;                // For when you start it up

    int lastButton = 0;                           // Last button pressed stuff, gets fed to buttons

    //----------------------------------------------------------------You Probably Don't Have To Worry About The Rest----------------------------------------------------------------

    //This stuff you don't have to worry about, its for the board

    #include <Adafruit_NeoPixel.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SPITFT.h>
    #include <Adafruit_SPITFT_Macros.h>
    #include <gfxfont.h>
    #include <Adafruit_NeoMatrix.h>
    #include <gamma.h>
    #include "RGB.h"
    #ifndef PSTR
      #define PSTR
      #include smileytongue24.h
      #include yellowsmiley24.h
    #endif

    #define PIN 3 // This is the pin where the data is coming out (you don't have to worry about this)

    const int button1          = 4;     // the number of the arcade button pins
    const int button2          = 5;
    const int button3          = 6;
    const int button4          = 7;
    const int brightnessSwitch = 8;

    // variables will change:
    int button1State           = 0;     // variable for reading the pushbutton status
    int button2State           = 0;
    int button3State           = 0;
    int button4State           = 0;
    int switchState            = 0;
    int panelBrightness        = 0;

                                                                        // This stuff tells the board how the lights are arranged.
    Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(20,                  // In our case, it starts at the top left,
                                                   15,                  //   and the signal goes right, and zigzags the rest of the way.
                                                   PIN,                 // It also tells it that it is 20 by 15 LEDs
                                                   NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
                                                   NEO_GRB + NEO_KHZ800);

    void setup() {
      pinMode(button1, INPUT);                                          // initialize the buttons as inputs:
      pinMode(button2, INPUT);
      pinMode(button3, INPUT);
      pinMode(button4, INPUT);

      pinMode(brightnessSwitch, INPUT);

      matrix.begin();
      matrix.setTextWrap(false);

      Serial.begin(9600);
      Serial.print("The LED Matrix has started. Default will be activated soon");
    }

    String panelText = buttonText1;                                     // This is what text gets fed to the panel

    int x    = matrix.width();
    int pass = 0;

    void loop() {
      matrix.setBrightness(panelBrightness);                            // This sets the overall brightness. 255 is the highest, while 0 is the lowest

      button1State = digitalRead(button1);                              // read the state of the buttons
      button2State = digitalRead(button2);
      button3State = digitalRead(button4);
      button4State = digitalRead(button4);

      switchState = digitalRead(brightnessSwitch);

      if (switchState == HIGH) { panelBrightness = switchLevel1; }      // Brightness Logic
      else                     { panelBrightness = switchLevel2; }

      // if-then statements
      if (button1State == HIGH) {                                       // BUTTON 1 CODE START

        static int i = 0;
        i++;
        for (int y = 0; y < 15; y++) {
          for (int x = 0; x < 20; x++) {
            if (y & 1) {
              matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));
            }
            else {
              matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreen1 + i * 128 * 2)));
            }
          }
        }

        matrix.setTextColor(matrix.Color(255, 255, 255));               // This determines the text color.
        matrix.setCursor(-((millis() / 40) & 127), 4);                  //     If you want to set a text color, search in google "Color Picker"
                                                                        //     and use the RGB values in place of the numbers in matrix.Color(r,g,b)
        matrix.print(buttonText1);
        matrix.show();
      }                                                                 // BUTTON 1 CODE END

      else if (button2State == HIGH) {                                  // BUTTON 2 CODE START
                                                                        //    PUT WHAT HAPPENS FOR BUTTON 2 HERE
      }                                                                 // BUTTON 2 CODE END

      else if (button3State == HIGH) {                                  // BUTTON CODE 3 START

        static int i = 0;
        i++;
        for (int y = 0; y < 15; y++) {
          for (int x = 0; x < 20; x++) {
            if (y & 1) {
              matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 200 * colorsOnscreen3 + i * 128 * 2)));
            }
            else {
              matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x - y) * 256 * colorsOnscreen3 + i * 128 * 2)));
            }
          }
        }

        matrix.setTextColor(matrix.Color(255, 255, 255));
        matrix.setCursor(-((millis() / 40) & 127), 4);

        matrix.print(buttonText3);
        matrix.show();
      }                                                                 // BUTTON 3 CODE END

      else if (button4State == HIGH) {                                  // BUTTON 4 CODE START
                                                                        //    PUT WHAT HAPPENS FOR BUTTON 4 HERE
      }                                                                 // BUTTON 4 CODE END

      else {                                                            // WHAT HAPPENS UNTIL A BUTTON IS PRESSED

        static int i = 0;
        i++;
//      matrix.fillScreen(0);
        for (int y = 0; y < 15; y++) {
          for (int x = 0; x < 20; x++) {
            if (y & 1) {
              matrix.setPixelColor(19 - x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));
            }
            else {
              matrix.setPixelColor(     x + y * 20, matrix.gamma32(matrix.ColorHSV((x + y) * 256 * colorsOnscreenDefault + i * 128 * 2)));
            }
          }
        }

        matrix.setTextColor(matrix.Color(255, 255, 255));
        matrix.setCursor(-((millis() / 70) & 127), 4);

        matrix.println(defaultText);
        matrix.show();
      }
    }

Thank you for cleaning up my code! You're right, it does make it easier to understand. Again, thanks for your help!


text:
Autonomous Firetruck
I have a problem. I am making an autonomous (obstacle avoiding) firefighting firetruck. I already have a code however it only stops when it detects fire and when the ultrasonic reaches less than 15cm, the flame sensor automatically detects fire even there is no fire near the sensor. I get my code form different tutorials.
Here it is:
#include <Servo.h>
#include "Ultrasonic.h"

//Constants
const int button = 2;
const int led    = 3;
const int pump = 4;
const int motorA1= 6;
const int motorA2= 9;
const int motorB1=10;
const int motorB2=11;
const int flame=12;
const int buzzer=12;

Ultrasonic ultrasonic(A4 ,A5);
Servo myservo;

//Variables
int distance;
int checkRight;
int checkLeft;
int function=0;
int buttonState=0;
int pos=90;
int flag=0;
int flame_detected;

void setup()
{
 Serial.begin(9600);
   myservo.attach(5);
   myservo.write(pos);
 pinMode(button, INPUT_PULLUP);
 pinMode(led,  OUTPUT);
 pinMode(buzzer, OUTPUT);
 pinMode(motorA1,OUTPUT);
 pinMode(motorA2,OUTPUT);
 pinMode(motorB1,OUTPUT);
 pinMode(motorB2,OUTPUT);
 pinMode(flame,INPUT);
 pinMode(pump,OUTPUT);

}

void loop()
{
 flame_detected = digitalRead(flame);
 if (flame_detected == true)
 {
   Serial.println("No flame detected. stay cool");
 //Check button state
 buttonState = digitalRead(button);
 unsigned long currentMillis = millis();

   if (buttonState == LOW) {
     delay(500);
     if ( flag == 0){
         function = 1;
         flag=1;
     }
     else if ( flag == 1){
       function = 0;
       flag=0;
     }
   }

 if (function == 0){
   myservo.write(90);
   stop();
   noTone(buzzer);
   digitalWrite(led, HIGH);

 }
 else if (function == 1){
   //Read distance...
   distance = ultrasonic.Ranging(CM);

   if (distance > 15){
     forward();
     noTone(buzzer);
     digitalWrite(led,LOW);
   }
   else if (distance <=15){
     stop();
     tone(buzzer,500);
     digitalWrite(led,HIGH);

     for(pos = 0; pos < 180; pos += 1){
               myservo.write(pos);
               delay(10);
           }

           checkLeft = ultrasonic.Ranging(CM);

           for(pos = 180; pos>=0; pos-=1){
               myservo.write(pos);
               delay(10);
           }

           checkRight= ultrasonic.Ranging(CM);

           myservo.write(90);

           if (checkLeft < checkRight){
             left();
             delay(400);
             }
           else if (checkLeft > checkRight){
             right();
             delay(400);
           }
           else if (checkLeft <=10 && checkRight <=10){
             backward();
             left();
           }
   }
 }

}

else {
 put_off_fire();
 Serial.println("Flame detected...! take action immediately.");
}
delay(500);
}
void forward(){
 digitalWrite(motorA1, HIGH);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, HIGH);
 digitalWrite(motorB2, LOW);
}

void backward(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, HIGH);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, HIGH);
}

void left(){
 digitalWrite(motorA1, HIGH);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, HIGH);
}

void right(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, HIGH);
 digitalWrite(motorB1, HIGH);
 digitalWrite(motorB2, LOW);
}

void stop(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, LOW);
}

void put_off_fire()
{
 {
   delay (500);

   digitalWrite(motorA1, HIGH);
   digitalWrite(motorA2, HIGH);
   digitalWrite(motorB1, HIGH);
   digitalWrite(motorB2, HIGH);

  digitalWrite(pump, HIGH);
  delay(500);
 }
 digitalWrite(pump,LOW);
 flame_detected=false;
}

I really need help. Thanks

What flame sensor are you using?

You need to provide a lot of information about your sketch if you expect us to help with it. What hardware are you using? Where can we read about it? You need to document the various sections of your code, what they're supposed to do, and explain the parts that aren't operating as you expect them to.

Sorry, I forget about that. I am using  Arduino Uno, Hl-01 flame sensor, HC-SR04  ultrasonic sensor, 2wd robot, servo  motor(allows ultrasonic and flame sensor to check side and front of the robot), button and l298n

I mostly rely on this tutorial https://www.ardumotive.com/obstacle-avoiding-robot.html for the obstacle avoiding code then I just added some code from other tutorials regarding with the fire/flame detection and fire fighting robot which I found on the Arduino project hub

I could not find a datasheet for that flame sensor. Can you link to one from? Maybe from your reseller?

it's just the regular Arduino flame sensor.
Here is the link:
https://www.google.com/search?q=flame+sensor+arduino&rlz=1C1GGRV_enPH814PH814&sxsrf=ACYBGNQ-JVW0XcDRF5gfvQhRRck1SMeS2w:1572793423083&source=lnms&tbm=isch&sa=X&ved=0ahUKEwil0KaKqM7lAhWR62EKHQHWDO0Q_AUIEigB&biw=1536&bih=722#imgrc=SX9yx_muZQ-mGM:

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Arduino UNO: Autonomous Firetruck Coding (Fire Detection) and Connection (Water Pump) Problem
I am currently working on an autonomous firetruck project. Its already doing obstacle avoidance however, I still don't know the proper code for fire detection. It already detects fire but what I want to happen is the motor will stop for a second when it detects fire then it will go forward directly to the fire and put it off using a water pump. I already made a code but it is not working. Secondly, where I will insert the GND and VCC of the water pump? I don't know its connection.
Materials:
Arduino UNO
Ultrasonic Sensor
Flame Sensor
Servo Motor
Button
Mini Breadboard
L298n
2wd Robot Kit
Here is the code:
#include <Servo.h>
#include "Ultrasonic.h"

const int button = 2;
const int led    = 3;
const int pump = 4;
const int motorA1= 6;
const int motorA2= 9;
const int motorB1=10;
const int motorB2=11;
const int flame=12;
const int buzzer=13;

Ultrasonic ultrasonic(A4 ,A5);
Servo myservo;

int distance;
int checkRight;
int checkLeft;
int function=0;
int buttonState=0;
int pos=90;
int flag=0;
int flame_detected=0;

void setup(){
 Serial.begin(9600);
 myservo.attach(5);
 myservo.write(pos);
 pinMode(button, INPUT_PULLUP);
 pinMode(led,  OUTPUT);
 pinMode(buzzer, OUTPUT);
 pinMode(motorA1,OUTPUT);
 pinMode(motorA2,OUTPUT);
 pinMode(motorB1,OUTPUT);
 pinMode(motorB2,OUTPUT);
 pinMode(flame,INPUT);
 pinMode(pump,OUTPUT);
}

void loop(){
 flame_detected = digitalRead(flame);
  if (flame_detected == 1)
  {
    Serial.println("No flame detected. stay cool");

    //Check button state
    buttonState = digitalRead(button);
    unsigned long currentMillis = millis();

    if (buttonState == LOW) {
      delay(500);
      if ( flag == 0){
       function = 1;
       flag=1;
      }
      else if ( flag == 1){
       function = 0;
       flag=0;
     }
   }

   if (function == 0){
    myservo.write(90);
    stop();
    digitalWrite(led, HIGH);
    }
   else if (function == 1){
    //Read distance...
    distance = ultrasonic.Ranging(CM);

   if (distance > 20){
    forward();

    digitalWrite(led,LOW);
   }
    else if (distance <=20){
    stop();

    digitalWrite(led,HIGH);

    for(pos = 0; pos < 180; pos += 1){
     myservo.write(pos);
     delay(10);
     //myservo.write(90);
    }

    checkLeft = ultrasonic.Ranging(CM);
    //myservo.write(90);

    for(pos = 180; pos>=0; pos-=1){
    myservo.write(pos);
    delay(10);
    //myservo.write(90);
    }

    checkRight= ultrasonic.Ranging(CM);

          myservo.write(90);

           if (checkLeft < checkRight){
             left();
             delay(400);
             }
           else if (checkLeft > checkRight){
             right();
             delay(400);
           }
           else if (checkLeft <=10 && checkRight <=10){
             backward();
             left();
           }
   }
 }

}

else if (flame_detected == 0) {
  Serial.println("Flame detected...! take action immediately.");
  buzzerwarning ();

  stop();

  if(distance > 25){
  forward();
  }
  else if (distance <= 25){
  stop();
  digitalWrite (pump, HIGH);
  }

  digitalWrite (pump,LOW);
  flame_detected == 1;
  }
}
void backward(){
 digitalWrite(motorA1, HIGH);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, HIGH);
 digitalWrite(motorB2, LOW);
}

void forward(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, HIGH);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, HIGH);
}

void left(){
 digitalWrite(motorA1, HIGH);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, HIGH);
}

void right(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, HIGH);
 digitalWrite(motorB1, HIGH);
 digitalWrite(motorB2, LOW);
}

void stop(){
 digitalWrite(motorA1, LOW);
 digitalWrite(motorA2, LOW);
 digitalWrite(motorB1, LOW);
 digitalWrite(motorB2, LOW);
}

void buzzerwarning () {
int i=0;

  do {
    i++;
    tone(buzzer, 7500);
    delay (700);
    tone(buzzer, 5500);
    delay (700);
    noTone (buzzer);
    delay (0);

  }
  while(i<2);

delay(0);
}

Thanks.

There are 2 questions here.  It would be best to separate the two questions in two independent posts.  Also, simplify your program so it only contains the code which does not work as expected.  Some times there is a good reason to post all your code.  But in this case all you are asking about is moving toward a heat source.

where I will insert the GND and VCC of the water pump? .... the pump is just a motor ... you control it the same way as the motors for the wheels

How is your code not working? What doesn't behave as expected? You always have to provide a full problem description

What do you use the L298N for? If it's for the pump, a simple transistor would do the job as well

Usually, code using delay()s is poor. You should implement a (non-blocking) state machine. This will probably solve one of your problems

I use a relay for the pump and it is now working the only problem is the code
This is the part of the code that is not working:
if(distance > 25){
forward();
}
else if (distance <= 25){
stop();
digitalWrite (pump, HIGH);
}
digitalWrite (pump,LOW);
flame_detected == 1;
}

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to use existing (non-arduino-specific) library with subfolders in Arduino IDE?
I have a generic c++ library that i'd like to use in an arduino project without making changes to the library code.
The library contains subfolders and files in the library include other files of the same library with includes of the form
#include "libraryroot/subfoldername/header.h"

I tried putting 'libaryroot' into C:/Users/Username/Documents/Arduino/libraries but while I can include headers that lie directly inside 'libraryroot' using #include <filename.h> (not #include <libraryroot/filename.h>), Arduino fails to find the headers these files include
How can I make use of such a library in Arduino without having to change the library?

Check out Platform IO for visual studio code. It is a much better IDE and will let you this type of thing more easily.

@Juraj I already read this but I still didn't figure out how it can be done

To utilize subfolders with any name in an Arduino library, you must use the 1.5 library specification.
In libraries folder in your sketch folder, create a folder for the library. In this folder create a src subfolder and put the library source code into that subfolder. Then create a library.properties file in the root folder of the library with some dummy information. Fill the includes key with the main .h file of the library.
Documents/
  Arduino/
   libraries/
     FooLib/
      src/
       subfoldername/
        header.h
        some.h
        some.cpp
       foolib.h
       foolib.cpp
      library.properties

In code then use in #include the path with src folder as starting location.
#include <subfoldername/header.h>


text:
Use Arduino Libraries in PlatformIO?
I'd like to use Arduino libraries installed in C:\Users\Username\Documents\Arduino\libraries in a PlatformIO project. Is it possible? if so, how?

I'd start with documentation, for example lib_extra_dirs looks promising


text:
multiple invdividual servo controll arduino
I want to declare 11 servo motors in my code. Is there a better way to do that than just declare everyone under each other. The reason is that i have a code that will set the rotation for one at a time. The best would be a list so i could iterate over which server i want to move.
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
//etc
void moveServo(int n,int deg){
  servo[n].write(deg); //something like this
}

Generally, to control a servo motor you need to develop a fairly well timed pulse train.  Usually you use the PWM hardware inside the processor.  The consequence of using software?  The pulses may have a bit of jitter and this translates into the servos jittering.  If you are willing to use the correct hardware (processor) there are ways around this.  Do you wish for such an answer?

Its for a robot arm so i want to send message from a raspberry  pi, that i want to move servo[1] 20 degrees. so i can move a joint at a time.

Depending on the specific processor in the Arduino you are using, there may not be enough PWM hardware generators to provide the pulse train to control 11 servos.  You can resort to using software to create the pulse trains.  But this may end up causing some jitter in the servo motors.  Likely more so during serial communications with the Raspberry Pi.

Servo.h library can control 12 servos in a '328P, and 48 in a 2560.

First: Your code would not work, since servo is not defined and thus not an array to iterate over. You would need to first define the array and then fill it with Servo elements.
Servo servo[11];

void setup(){
    for(int i=0;i<11;i++){
        servo[i] = new Servo();
    }
}

The different Servo objects are created dynamically. In most cases it is bad to use dynamic allocation on a microcontroller with litte RAM, but it is ok, when you only use it once at the start.

Consider using a specific processor / Arduino-board.  In this thread there are references to using the Arduino 1280 board with the Arduino Servo Library to control up to 48 servos using a combination of hardware and software.
In C++ when you "instantiate" a class you are making good use of memory space as you do not really create duplicate code. All you create are copies of the variables necessary to support each instantiation. There should only be one copy of the code in memory.  To iterate over each instantiation consider using a switch/case statement.


text:
How to call a PHP script with Arduino?
I have Arduino Mega and ESP-12F module.
Via AT commands I am on my wifi.
Now, I need to call my script on my pages.
Can you tell me how?
This command can conenct to my pages:
Serial3.print("AT+CIPSTART=0,\"TCP\",\"www.artware.cz\",80\r\n");
But that's all, I am not able to call the script.
Sorry, if this is dumb question.
Thank you

there are 'WiFi' libraries which handle the esp8266 AT commnands for you and have an example for GET request. WiFiEsp library or my WiFiEspAT (the second only if the AT firmware is 1.7 (SDK 3) and you don't need SSL (https))

Which library do you recommend?

my WiFiEspAT, if you can flash the AT firmware 1.7 (SDK 3) and you don't need SSL (https) https://github.com/jandrassy/WiFiEspAT

Do you know which HTTP method the PHP script accepts ? It will be either GET or PUT. If it is the GET method you should be able to simply test it by issuing a command such as www.artware.cz/myApp.php?par1=52 etc. The next step is to issue that URL from your ESP-12 (somehow) and maybe parsing the results.


text:
Mega ADK connecting to PS3 Controller - OSC did not start error
I have a project that I am working on that uses a PS3 controller to connect to an Arduino Mega 2560 ADK (built-in USB).  I have been trying to test the controller/arduino connection and I cannot get past the "OSC did not start" error via serial monitor.
I started a new thread because all of the threads I read were based on the Mega 2560 plus the USB shield, not the ADK. Theoretically, there should be no difference, but rather safe than sorry.
Here is my hardware:
Arduino Mega 2560 ADK - Controller
TrendNet TWB-106UB - USB dongle
PS3 Move Navigation Controller (only 1)
Libraries:
USB_Host_Shield
USB_Host_Shield_Library_2.0
Sketch:
https://gitlab.com/darren-blum/SHADOW
However, for the sake of testing, I have tried the straight example sketches from the USB Host libraries.  I have tried the PS3USB and the PS3BT examples.  It does not matter what sketch I try, I cannot get past the "OSC did not start".
The code that triggers this error is:
if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }

I am not sure what I am missing.  Here is one of the example sketches in its entirety:
#include <PS3BT.h>
#include <usbhub.h>

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

USB Usb;
//USBHub Hub1(&Usb); // Some dongles have a hub inside

BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
/* You can create the instance of the class in two ways */
PS3BT PS3(&Btd); // This will just create the instance
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57); // This will also     store the bluetooth address - this can be obtained from the dongle when running     the sketch

bool printTemperature, printAngle;

void setup() {
  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();

  if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
    if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
      Serial.print(F("\r\nLeftHatX: "));
      Serial.print(PS3.getAnalogHat(LeftHatX));
      Serial.print(F("\tLeftHatY: "));
      Serial.print(PS3.getAnalogHat(LeftHatY));
      if (PS3.PS3Connected) { // The Navigation controller only have one     joystick
        Serial.print(F("\tRightHatX: "));
        Serial.print(PS3.getAnalogHat(RightHatX));
        Serial.print(F("\tRightHatY: "));
        Serial.print(PS3.getAnalogHat(RightHatY));
      }
    }

    // Analog button values can be read from almost all buttons
    if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
      Serial.print(F("\r\nL2: "));
      Serial.print(PS3.getAnalogButton(L2));
      if (PS3.PS3Connected) {
        Serial.print(F("\tR2: "));
        Serial.print(PS3.getAnalogButton(R2));
      }
    }

    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTraingle"));
        PS3.setRumbleOn(RumbleLow);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.setRumbleOn(RumbleHigh);
      }
      if (PS3.getButtonClick(CROSS))
        Serial.print(F("\r\nCross"));
      if (PS3.getButtonClick(SQUARE))
        Serial.print(F("\r\nSquare"));

      if (PS3.getButtonClick(UP)) {
        Serial.print(F("\r\nUp"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED4);
        }
      }
      if (PS3.getButtonClick(RIGHT)) {
        Serial.print(F("\r\nRight"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED1);
        }
      }
      if (PS3.getButtonClick(DOWN)) {
        Serial.print(F("\r\nDown"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED2);
        }
      }
      if (PS3.getButtonClick(LEFT)) {
        Serial.print(F("\r\nLeft"));
    if (PS3.PS3Connected) {
      PS3.setLedOff();
      PS3.setLedOn(LED3);
    }
  }

  if (PS3.getButtonClick(L1))
    Serial.print(F("\r\nL1"));
  if (PS3.getButtonClick(L3))
    Serial.print(F("\r\nL3"));
  if (PS3.getButtonClick(R1))
    Serial.print(F("\r\nR1"));
  if (PS3.getButtonClick(R3))
    Serial.print(F("\r\nR3"));

  if (PS3.getButtonClick(SELECT)) {
    Serial.print(F("\r\nSelect - "));
    PS3.printStatusString();
  }
  if (PS3.getButtonClick(START)) {
    Serial.print(F("\r\nStart"));
    printAngle = !printAngle;
  }
}
#if 0 // Set this to 1 in order to see the angle of the controller
    if (printAngle) {
      Serial.print(F("\r\nPitch: "));
      Serial.print(PS3.getAngle(Pitch));
      Serial.print(F("\tRoll: "));
      Serial.print(PS3.getAngle(Roll));
    }
#endif
  }
#if 0 // Set this to 1 in order to enable support for the Playstation Move controller
  else if (PS3.PS3MoveConnected) {
    if (PS3.getAnalogButton(T)) {
      Serial.print(F("\r\nT: "));
      Serial.print(PS3.getAnalogButton(T));
    }
    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(SELECT)) {
        Serial.print(F("\r\nSelect"));
        printTemperature = !printTemperature;
      }
      if (PS3.getButtonClick(START)) {
        Serial.print(F("\r\nStart"));
        printAngle = !printAngle;
      }
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTriangle"));
        PS3.moveSetBulb(Red);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.moveSetBulb(Green);
      }
      if (PS3.getButtonClick(SQUARE)) {
        Serial.print(F("\r\nSquare"));
        PS3.moveSetBulb(Blue);
      }
      if (PS3.getButtonClick(CROSS)) {
        Serial.print(F("\r\nCross"));
        PS3.moveSetBulb(Yellow);
  }
  if (PS3.getButtonClick(MOVE)) {
    PS3.moveSetBulb(Off);
    Serial.print(F("\r\nMove"));
    Serial.print(F(" - "));
    PS3.printStatusString();
  }
}
if (printAngle) {
  Serial.print(F("\r\nPitch: "));
  Serial.print(PS3.getAngle(Pitch));
  Serial.print(F("\tRoll: "));
  Serial.print(PS3.getAngle(Roll));
}
else if (printTemperature) {
  Serial.print(F("\r\nTemperature: "));
  Serial.print(PS3.getTemperature());
}
  }
#endif
}

Idiot me.  I thought Mega 2560 = ADK.  It does not.  Once I corrected my board from the Mega 2560 to the ADK, the USB port worked.

It's OK to accept your own answer as the solution to the problem.


text:
How to modify this code to use serial event to act after carriage return?
In part of a code used with UNO, I want to send number A and number B at once as A,B to the Arduino board if there is carriage return. So at the moment in HyperTerminal when I type: 100,0.5 the Arduino board immediately reacts x becomes 100 and n becomes 0.5. Following parts are related to reading with serial event:
void loop() {

      if (stringComplete){

      delay(1000);
      Mwrite(level);
      sendFrequency(n);
      delay(100);

      stringComplete = false;

   }
}

and in serial event:
void serialEvent() {

     while (Serial.available()) {

     slevel  = Serial.readStringUntil(',');
     Serial.read(); //next character is comma, so skip it using this
     x = Serial.readStringUntil(',');

     level = slevel.toInt();
     n = x.toDouble();
     stringComplete = true;
  }
}

But what I want to do is, I want the board only read the serial data only if I hit carriage return. So I should type 100,1 and then I should also hit carriage return for Arduino to react to the serial data.
How can this code be modified to achieve that?

Forget serialEvent(). It's something Arduino should never have included in the API. It's an idiotic function that has no purpose in reality. Putting the content of serialEvent() in loop() is exactly the same (and often far more convenient).

https://majenko.co.uk/blog/reading-serial-arduino

The SerialMonitor does not send anything until you press "Send". It's a good idea to choose newline as additional delimiter character when sending. In addition to Majenko's  readline:  There's a strtok function you might want to use

set the terminal to send on Enter, not every character. btw. readStringUntill removes the terminal character from receive buffer. and shouldn't your second readStringUntil read until '\n'?

@Majenko, no it's not idiotic, it's just misunderstood. I'll admit it has limited use-cases, but it can be a big help. For instance, it helped a ton when designing my RC airplane library

The concept may have merit, but the implementation is idiotic. Now if they'd hooked it into the RX interrupt then it may have been useful. As it is, it's idiotic. And I stand by that word.

There are multiple ways you can solve it. The easiest way to do it is by just adding one more line in your code.
static bool stringComplete = false;
String x;
String slevel;
static int level;
static int n;

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

void loop()
{
  if (stringComplete)
  {
    Serial.println(level);
    Serial.println(n);
    stringComplete = false;
  }
}

void serialEvent()
{
  while(Serial.available())
  {
    slevel  = Serial.readStringUntil(',');

    //Serial.read(); // <-- You don't need this line. readStringUntil() will read ','

    x = Serial.readStringUntil(',');

    level = slevel.toInt();
    n = x.toDouble();
    Serial.readStringUntil('\r'); // <--------- Add this line
    stringComplete = true;
  }
}

But this is not probably the right way to do it. First, serialEvent() executes in between loop() i.e. this is what it looks like:
while(1)
{
    loop();
    serialEvent();
}

So, it is not like that the function will get called during a serial event. It just gets executed right after loop(). Also readStringUntil() has a timeout (default: 1s). So if your 'until' character doesn't show up within one second of the function call, it will return with whatever it has. To test this, just type one character on your HyperTerminal and wait at least for a second, and see the output.
Ideally, this is how you should handle the serial's incoming byte:

Check if there is serial byte available to read
If there is, read one byte and save it in a buffer/string. (I'm not really a fan of String variables, but in the example, I will use String because you were using a String)
If the byte you just read is delimiter (e.g. CR or '\r'), indicate the main loop that string is complete.
In the main loop parse the whole string.

So this is how the code looks like with above-mentioned points:
static bool stringComplete = false;
String x;
String slevel;
static int level;
static int n;
String rxString = "";

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

void loop()
{
  if (stringComplete)
  {
    // Parse the rxString
    int index1 = rxString.indexOf(',');             // finds location of first ,
    slevel = rxString.substring(0, index1);         // captures first data String
    int index2 = rxString.indexOf(',', index1 + 1); //finds location of second ,
    x = rxString.substring(index1 + 1, index2);     //captures second data String

    level = slevel.toInt();
    n = x.toDouble();

    Serial.println(level);
    Serial.println(n);

    // Reset the string
    rxString = "";
    stringComplete = false;
  }
}

void serialEvent()
{
  while(Serial.available())
  {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the rxString:
    rxString += inChar;
    // if the incoming character is a carriage return, indicate main loop
    if (inChar == '\r')
    {
      stringComplete = true;
    }
  }
}


text:
Switch MPU6050 to send SCL data through A4 and SDA through A5
I have this MPU6050, and like most of the other MPU6050s, it is set up for SCL to be attached to A4 and SDA to be attached to A5. I have this shield on my Arduino Uno, which is configured for Sainsmart's (the company who made the shield) MPU6050, so the special MPU6050 pins are set up V, G, A5, A4, and my current setup needs V, G, A4, A5. I am using the built-in Wire library, I2CDev library, and the MPU6050 library. So I am wondering whether there is something in these libraries that define which pins it looks for my MPU6050 on, and if so how do I change it.

The pin definition is in hardware. There is nothing you can do to change it. However you could try to reprogram it to use a software i2c library instead of the hardware wire library.

Which would be the best one to use

@user10529 Which what?

Why not build a small board that converts the pins from V, G, A5, A4 to V, G, A4, A5? Or modify the PCB e.g. cut and rewire the signals in the order you want. It is only two pins!
Cheers!

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Compile Error for Arduino Mega
I am using the Arduino IDE 1.6.0,
There is a project that has compiled both for Due and Mega on another computer. But on my machine, it only compiles for Due. When compiling  for "Mega or Mega 2560", I get the following error:

/Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.8.1/../../../../avr/bin/ld: skipping incompatible /Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/libc.a when searching for -lc
      /Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.8.1/../../../../avr/bin/ld: cannot find -lc
      collect2: error: ld returned 1 exit status
      Error compiling.

My newbie guess is something is wrong with AVR libraries. But how to solve it? Also could someone please explain what -lc is, which cannot be found? At first glance it looks like an option.

tldr; -lc means "link with the libc.a library"
The compiler takes your source code (*.c, *.ino) and produces "object" files ending in *.o.
The linker takes those compiled modules and links them all together to make the final executable, linking symbols in one file (such as variable references and function calls) with the definitions in the others (the actual variables and functions). But it also takes libraries - predefined collections of object files - and links those in as well, if necessary.
Libraries are files of the form lib*.a (a is for "archive"), and are distributed by software vendors as easy containers for their modules. The compiler/linker itself also uses them as the implementations for languages features such as printf() and digitalWrite(). The most fundamental library is libc.a - the library containing the standard C implementation.
When you want to get the linker to use a library, you give it the -l option, with the library name appended (not including the lib prefix and .a extension). In short, -lc means "link with the libc.a library".
But if your development machine has support for numerous processors, there will be a number of libc.a files on it - how does the linker know where to look? Another linker option is -L (note uppercase), which defines the directories to look in to find libraries. The linker will look through the directories in turn until it finds the referenced library.
If you attempt to link modules that have been compiled for different processors, you will get linker errors when it does a sanity check. The reason your fix worked is because it now uses the correct directories to find what it is looking for.

I think you have included some libraries in the sketch. The problem is that one of the libraries doesn't support the Arduino Mega.
As a solution, I suggest you to comment out the libraries one by one and then try to compile the program. If code runs successfully,try to install that library with other versions. Don't forget to remove the previous library.

So what I did that solved the problem was, I downloaded the latest Arduino IDE, titled "Windows ZIP file for non admin install". Then I unzipped the download, and I copied all of the files of the new IDE and pasted them into the old installation. But I did not replace anything. i.e. For each file that existed, I kept the old file.
~400 new files were copied. Now it compiles without error.
BTW since this has been a blind workaround, I will not accept this as the final answer.

What was the point of copying one version over the top of another version? Why didn't you just upgrade to the new version instead?

All i remember right now is that the newest update at the time had compatibility issues. I don't remember what it was. That's why I tried to keep the older files.

authors: عبدالغني الرباعي

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Why is my "mood cue" not working?
I am new to Arduino, and I am working through the "Arduino Projects book," with the Arduino Uno. I am working on project 5, "the mood cue." It is basically a potentiometer-controlled servo. I am certain that I have the code for it correct, and certain that I have all the wiring correct. I have the potentiometer value and the angle at which the potentiometer is turned printed on the serial monitor.
I upload the code, and the serial monitor begins printing correctly, changing when I twist the potentiometer. But the servo doesn't move. It lets off a faint buzzing sound, and that is it.
Does anyone know what the problem is? I don't know what I have done wrong. Do you think my servo is broken?
Here is my code:
#include <Servo.h>
Servo myServo;
int const potPin = A0;
int potVal;
int angle;

void setup() {
  myServo. attach(9);
  Serial.begin (9600);
}

void loop() {
  potVal = analogRead(potPin);
  Serial.print ("potVal:");
  Serial.print (potVal);
  angle = map(potVal, 0, 1023, 0, 179);
  Serial.print ("angle:");
  Serial.print (angle);
  myServo.write (angle);
  delay(15);
}

Here is my wiring:
file:///C:/Users/matth_000/Downloads/Arduino%20PotServ.jpg

Maybe you have your servo wired wrong.  Please post a photograph of your setup.

Buzzing, non-moving motors usually means not enough voltage and/or current.

file:///C:/Users/matth_000/Downloads/Arduino%20PotServ.jpg
is not gonna help much...

The classic way of wiring up motors, including servos, is to provide them with separate power. The image below should clarify this:

The batteries (in this case) have the sole function of providing power to the servo motor. The "data" pin however goes to the Arduino.
The Arduino itself is powered by the USB cable in this example.
The important point is the blue wire - the shared ground wire. Both the Arduino and the servo (and batteries) must have a common ground.

If you're using the components that came in the starter kit, the servo is wired differently in the book than it is in the actual kit.
Make sure the red wire on the servo is connected to the power, the black to the ground and the white to the data. The specs are also written on the side of the servo motor.
In the project book, the wires went into these rows on the breadboard:

GND
5V
Signal

Whereas for me that meant it was:

GND
Signal
5V

Hope this helps!

I'm new to arduino and I had the same problem of the servo buzzing but not moving.  I found the reason was the servo wires came in a different order than what was written in the book.  After correctly connecting the 5v, GND, and Signal by moving a few wires on the bread board things worked as planed.  Hoped this helps.

At first, I had similar behavior with the servo motor in this project. The servo buzzed and either did not move or made very slight erratic movements.
The problem in my case was that I had wrongly placed the wire that is supposed to connect the potentiometer to pin A0.
Here's how my board looked after I corrected the problem:


text:
Load Cell and HX711 only outputting 0's
I am using an Arduino Uno and HX711 amplifier to collect data from a load cell. I previously had the load cell calibrated and functioning, but now the load cell will not read any values; only 0's are outputted, even when I apply a small load to the sensor. I have re-soldered and replaced the connecting wires. Are there any suggesting for getting a readout from my sensor?
I have been testing with 2 different load cells: Sparkfun's TAL220 Straight Bar 10kg load cell and an LFS 210-300 from Cooper Instruments (the latter is the one I want to use long term). My load cell is connected like the HX711 Breakout Guide (with an Arduino Uno instead of a RedBoard and a USB connection):

I have been using the HX711 Breakout Guide Calibration sketch to test my load cell:
#include <HX711.h>

#define DOUT 3
#define CLK 2

HX711 scale(DOUT, CLK);

float calibration_factor = 282650; //-7050 worked for my 440lb max scale setup

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 calibration sketch");
  Serial.println("Remove all weight from scale");
  Serial.println("After readings begin, place known weight on scale");
  Serial.println("Press + or a to increase calibration factor");
  Serial.println("Press - or z to decrease calibration factor");

  scale.set_scale();
  scale.tare(); //Reset the scale to 0

  long zero_factor = scale.read_average(); //Get a baseline reading
  Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
  Serial.println(zero_factor);
}

void loop() {

  scale.set_scale(calibration_factor); //Adjust to this calibration factor

  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  Serial.print(" kgs"); //Change this to kg and re-adjust the calibration factor if you follow SI units like a sane person
  Serial.print(" calibration_factor: ");
  Serial.print(calibration_factor);
  Serial.println();

  if(Serial.available())
  {
    char temp = Serial.read();
    if(temp == '+' || temp == 'a')
      calibration_factor += 10;
    else if(temp == '-' || temp == 'z')
      calibration_factor -= 10;
  }
}

I am still new to Arduino and data acquisition in general, so any suggestions would be appreciated!

This line is where you are reading the data and printing it:
Serial.print(scale.get_units(), 1);

The 1 on the end of the line defines how many digits you are displaying from your reading. I have a similar setup to yours and I have it set to 5 which shows up to +/-0.00001kg. (Obviously, the accuracy will be different depending on which load cell you have)


text:
Not long tweets published using ESP8266-01 with Arduino UNO
I'm trying to create a setup with which an Arduino UNO sends out a tweet (one random quote) every time a button is pressed. I want to use it as a Mailbox Watcher.
I'm not new to Arduino but ESP8266 is all new to me, so I'm trying to figure things out from how-to articles, youtube videos, etc.
My current setup is an ESP8266-01 attached to an Arduino UNO and I adapted the code found here (link) to my needs. I ended up with something that resembles this:
#include <SoftwareSerial.h>
#include <Bounce.h>

#define DEBUG true

#define APIKEY "THING_SPEAK_KEY" //  api key ThingSpeak
#define TARGET_IP "184.106.153.149"///         //local  direccion IP o Hosting  ThingSpeak
#define TARGET_PORT "80"          ///  port 80
#define ID "WIFI_NAME"  //name of wireless access point to connect to
#define PASS "WIFI_PASSWORD"  //wifi password

#define BUTTON_PIN 8

#define RX_PIN 10
#define TX_PIN 11

SoftwareSerial esp8266(RX_PIN,TX_PIN);

Bounce button=Bounce(BUTTON_PIN, 5);

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

    pinMode(BUTTON_PIN, INPUT);

    initializeModem();

    Serial.println("ready player One");
 }

void initializeModem(){

     sendData("AT+RST\r\n",1000,DEBUG); //

     sendData("AT+CWMODE=1\r\n",1000,DEBUG); //

      String cmd="AT+CWJAP=\"";
      cmd+=ID;
      cmd+="\",\"";
      cmd+=PASS;
      cmd+="\"";
     sendData( cmd+"\r\n",1000,DEBUG); //

     sendData("AT+CIPMUX=0\r\n",1000,DEBUG);

  }

boolean buttonState(){

  if (button.update() && button.read()==HIGH){

      return true;

    }else {
      return false;
      }
  }

void loop() {

if (buttonState()) {

   //  String con tweet
   String  updateTwitterStatus = "The best and most beautiful things in the world cannot be seen or even touched - they must be felt with the heart. Helen Keller #quoteoftheday";
   Serial.println(updateTwitterStatus);

    String webpage = "AT+CIPSTART=\"TCP\",\"";
    webpage += TARGET_IP;
    webpage += "\",80\r\n";
    sendData(webpage,1000,DEBUG);

    // Create HTTP POST Data

    String tsData = "api_key=" APIKEY "&status=" + updateTwitterStatus ;

    String webpage1 = "POST /apps/thingtweet/1/statuses/update HTTP/1.1\n";
    webpage1+="Host: api.thingspeak.com\n";
    webpage1+="Connection: close\n";
    webpage1+="Content-Type: application/x-www-form-urlencoded\n";
    webpage1+="Content-Length: ";
    webpage1+=tsData.length();
    webpage1+="\n\n";
    webpage1+=tsData;

     //// envia   comando AT + cantidad de caracteres

     String cipsend = "AT+CIPSEND=";
     cipsend+= webpage1.length();
     cipsend+="\r\n";

     sendData(cipsend,1000,DEBUG);
     sendData(webpage1,1000,DEBUG);

      //// comando AT de cierre de conexion
     sendData("AT+CIPCLOSE=0\r\n",1500,DEBUG);

              /// DELAY para reenvio de datos a twitter
     delay(10000);  //3 seg
}

}

 //// rutina de depuracion via puerto serial

String sendData(String command, const int timeout, boolean debug) {
    String response = "";

    esp8266.print(command); // send the read character to the esp8266

    long int time = millis();

    while( (time+timeout) > millis()) {
      while(esp8266.available()) {
        // The esp has data so display its output to the serial window
        char c = esp8266.read(); // read the next character.
        response+=c;
      }
    }

    if(debug) {
      Serial.print(response);
    }

    return response;
}

The setup works more or less as expected. It connects ok to the WiFi and so on, but it is only able to publish a tweet if it is not very long. As example, the quote on this example code will no be published whereas if it is half as long, it will be no problem.
In the end, I want to clean up the code and make use of private libraries to tidy things up and leave as few lines of codes as possible on the .ino file, but for testing and debugging purposes, I'm working on the code above.
I realize that a short text should be sufficient for my needs, but the fact of knowing that something is off bothers me to great extend. I have been dealing with this for three long days, so if anyone has an idea it would be much appreciated...
Thanks in advance
EDIT: It seems as the longest tweet I can send is 108 characters long. Together with the AT code to sent it, tha serial monitor gives the following feedback:
AT+CIPSEND=302

Have you tested to find out at what length it doesn't work? "short" and "long" are not specific values, but if you can find out the maximum tweet length that doesn't work, you have made a lot of progress in determining the problem and solution.

that's the next thing I wanted to do, yes. It'll take a while

Edited with the length of the longest tweet possible. Thanks.

wouldn't it be better using a library?

it would be MUCH easier to program the ESP and leave the UNO out of the equation: far more RAM+CPU, only one sketch, no messy serial parsing, better error handling, etc.

thanks @dandavis I thinks this is what I ultimately will do. I just landed on one of these situations where you want to solve the equation even though you won't need it. Any reference or link on how to do it with the stand alone ESP8266?

most of the code should be about the same. lookup an httpClient example on once you install the esp8266 board support into the IDE, and modify it to talk to your server.

It's plausible and likely that you are running out of RAM on the Uno by making extensive use of the String object and it's concatenation function (overloaded + operator).
Every time you + a String object, a new block of RAM is allocated to hold the new string, and that RAM is nearer the "ceiling" of RAM than the previous block. The old blocks are de-allocated, but since they are smaller than the new one, they can't be re-used for new allocations of your continually-larger String, so you eventually run out of contiguous blocks of RAM into which to put your new, longer String object.
One solution here, and pretty much everywhere on an Arduino, is to avoid using the String object, and go with the classic C string handling routines.
I would allocate one buffer char array char buf[512] or whatever you compute your maximum desired total string length to ever be. Then use strncat() to repeatedly concatenate your other parts into that one buffer.
Also consider putting static strings in PROGMEM as described at https://www.arduino.cc/reference/en/language/variables/utilities/progmem/, so you won't be holding all static strings in RAM the whole time, but can copy each as you use it to working RAM as you build up your HTTP request string.
The real killer is += used repeatedly with a String object. Arduino Uno has only 2k of RAM.

Thank you for your answer. As I began to read I understood that all together was over my head, but you explained it very well. I'll see to it tomorrow, but your explanation seems more than plausible. Thanks again!

Well, it has taken me long enough, but thanks to your indications I made it work. Thanks!

But how do you use strncat with strings in PROGMAME, such as strncat(send_buffer, F("TEST"), 4);


text:
Would it be feasible to build an arduino that takes 12v on/off signals from a vehicle diagnostic port (1984 pre-OBD)?
The vehicle is an AMC eagle, they come with a diagnostic port
I have made a diagnostic tool that lights led lights when signals turn on and off, but it has to be wired in and is bulky. I am wondering if it would be possible to have an arduino plugged in and running off the 12v battery supply (with step-down to 5v) and have it catch the signals and send them over Bluetooth to a computer. Does this sound like it is within the scope of an arduino or am I asking too much? Or is there a better and easier way to do this?

Two things. 1. With the engine running, you may have 14.5VDC, not 12VDC. 2. Be careful with the tach signal. If it's connected to the negative side of the ignition coil, you could see a voltage spike of up to 250 volts.

You can step down 12V to 5V with resistor dividers, or drive transistor base with 12V and let the collector pulldown an input with pullup resistor to signal an active signal (like an optocoupler, but without the slow optical part).
Arduino reading the inputs and sending via bluetooth to something else is pretty straightforward, perhaps send only when a change from 0 to 1, and 1 to 0, on any input is sensed. Check Adafruit.com for bluetooth modules that are easy to use.

I have a bunch of 2n222 smd parts but I doubt they could handle 12v, would I need to have one transistor per gpio used? The diagnostic port has 16 inputs that I would like to use.

Also, a lot of these signals are either always on, off, or change rarely. For example coolant temperature switch just goes from off (0v) to on (12v) when the coolant temperature reaches 135deg F. So speed is not that critical for most operations. Would an optocoupler work fast enough for these types of signals? My only concern is putting a bunch of resistors in a small package in a hot engine bay and having them constantly divide 12v would make the whole thing pretty hot. I could be wrong thou, I have a pretty basic understanding of electrics.

The current flow thru the transistors is very low, not much heat will be generated.  P=IIR, so say you had a 10K and a 5Kin series to drop 12V down to 4V, then the current thru the pair would be I=V/R = 12/15000= 0.8mA, and P = 0.096W * 16 = 1.5W for 16 circuits. You could increase the resistor values and lower the generated power.   Alternatively, you could use a pair of cd74HC4050 as level translaters, powered from 5V, to bring 12V down to 5V. 48 cents each at Digikey.com. That would use even less current for lower power dissipation as the output is just 1uA to drive the Arduino inputs.

I like the cd74HC4050 idea, in looking at the spec sheet, are there 6 inputs per chip? So for instance I would plug 5v regulated into pin 1, arduino gpio X into pin 2 and input 1 into pin 3? I'm specifically looking at the cd74HC4050E if there are differences between the chips. If there are 6 "inputs" per chip I would need 3 correct?

Yes, 3 chips would provide 18 channels. I don't have the datasheet in front of me, but the pinout is straight forward. Don't forget to use a 0.1uF cap from 5V to Gnd, located near the chip.

Yes, it is possible. The 12v signals would have to be conditioned for the Arduino to receive them (0 - 12v or maybe 0 - 12-14.5v?). Then the Bluetooth side would be the same as any other Bluetooth data transmission.
So your question comes down to: Is this a fun project that's worth the effort you put into it for the learning experience? Or is this meant to answer a need, and the most practical means to that end is the best means?
Ex: I wanted to know how long / what kind of driving would it take to get my car's oil to full temp (~100C), starting from dead-cold in the winter? I had a thermo-logger I'd built for another experiment, so I taped a sensor to my oil filter (yeah, not the greatest, but quick and dirty) and lead a cable outside the hood, through the driver's window, to the experimental PC board on my dash-board. It wasn't a miserable failure but nothing to be proud of, either.
The solution I settled on was a USD$12.00 OBD port sender and an iPhone app. The results were much better, and while I didn't have the built-it-myself experience, I got the data and the answers I needed.

It is to answer a need, it would be a replacement for my homemade diagnostic tool that I built (picture added). These vehicles are finicky as older cars can be, and I would like to be able to provide a simple tool for me and others who want it to use, not unlike the small Bluetooth obd2 readers that have pop'd up. Arduino sounds like the best option but I wanted to ask before I went down the rabbit hole only to find out that there is already something that does pretty close to what I'm after.


text:
Help with debugging code
This is NOT my code; was posted on Project Hub.   I tried to use the code (humidity controller) but it returns an error on line 270:
else if (DHT.humidity >= setpoint + 3 and syson == true) { //if humidity is 3% above setpoint

Error: expected primary-expression before '.' token
The OP is not responding to comments and I'm no expert.   Would appreciate if someone could help debug the code;
Thanks!
       //HUMIDITY CONTROLLER 1.1
//written for NANO

//controls and displays relative humidity
//sesnor used is DHT11
//uses active-low relay module to control live lines for 2 standard electrical outlets
//uses i2c lcd to display humidity and humidity setting
//turns display off during inactivity
//setting is adjustable from 10%-90% using 2 buttons
//backlight of LCD is controlled by pin 4, connected to top LED jumper pin on i2c backpack
//serial communications to monitor to ensure all code is working.

//added: "system off" function - allows both outlets to be turned off

// █ G █ L █ O █ B █ A █ L █ S █
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <dht.h>

// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

dht DHT;

#define DHT11_PIN A2

//buttons and variables to adjust calibration
int calupbtn = A0;
int calup;
int caldownbtn = A1;
int caldown;

//i2c PINS A4, A5

//pin for turning on humidifier relay
int humidifier = 3;
//pin for turning on the fan relay
int fan = 2;
//pin for turning on LCD backlights
int lcdlight = 4;

//calibration variable
int setpoint = 50;  //feedback setpoint.
bool calstate = false;  //enables calibration adjustments only when LCD is ON.

//backlight timing variables
int displtime = 12000;  //amount of time the display is to be on before turning off
unsigned long displtimeon;  //last recorded time display timer was reset
int calunlock = 0;   //loop counter for unlocking calibration

//sensor timing variables
unsigned long lastcheck;  //last time DHT was read
long interval = 30000;      //time between DHT readings

//system variables
bool syson = true;    //reference for system on/off.
byte systog = 2;       //even number toggles on, odds toggle off
int syslock = 0;     //loop counter for unlocking system toggle

// █ S █ E █ T █ U █ P █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █
void setup(){

  Serial.begin(9600);  //serial communication used to ensure code is working correctly.

  lcd.init();  //initialize LCD
  lcd.backlight(); //enable LCD backlight, but doesn't turn it on

  lastcheck = 0;
  digitalWrite(lcdlight, HIGH);
  Serial.println("STARTING");
  lcd.print("   STARTING");

  //pin assignments
  pinMode(calupbtn, INPUT);
  pinMode(caldownbtn, INPUT);
  pinMode(humidifier, OUTPUT);
  pinMode(fan, OUTPUT);
  pinMode(lcdlight, OUTPUT);
  delay(1000);

  //test fan
  lcd.setCursor(0,1);
  lcd.print("<FAN>     HMDFR  ");
  digitalWrite(fan, LOW);
  digitalWrite(humidifier, HIGH);
  delay(6000);
  //test humidifier
  lcd.setCursor(0,1);
  lcd.print(" FAN     <HMDFR> ");
  digitalWrite(fan, HIGH);
  digitalWrite(humidifier, LOW);
  delay(6000);
  //stop startup test
  digitalWrite(humidifier, HIGH);
  digitalWrite(fan, HIGH);
  lcd.clear();

  displtimeon = millis();

  int chk = DHT.read11(DHT11_PIN);
  lastcheck = millis();

  lcd.setCursor(0,0);
  lcd.print("Humidity: ");
  lcd.setCursor(13,0);
  lcd.print(DHT.humidity);
  lcd.setCursor(15,0);
  lcd.print("%  ");
  lcd.setCursor(0,1);
  lcd.print("setting: ");
  lcd.setCursor(13,1);
  lcd.print(setpoint);
  lcd.setCursor(15,1);
  lcd.print("%  ");
  delay(100);
}

// █ L █ O █ O █ P █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █
void loop(){

  //check calibration buttons
  calup = digitalRead(calupbtn);
  caldown = digitalRead(caldownbtn);

  if(calup == HIGH and caldown == HIGH){  //--------SYSTEM TOGGLE
    syslock ++;
    Serial.println(syslock);
    if(syslock == 20){  //if both buttons held down for this many loops
      systog++;
      if(systog % 2 == 1){  //--------SYSTEM OFF
        syson = false;
        digitalWrite(fan, HIGH);
        digitalWrite(humidifier, HIGH);
        digitalWrite(lcdlight, HIGH);
        Serial.println("SYSTEM TURNED OFF");
        lcd.clear();
        lcd.print("   SYSTEM OFF");
        lcd.setCursor(0,1);
        lcd.print("  hold both btns");
        delay(2000);
        lcd.setCursor(0,1);
        lcd.print("  to turn on    ");
        displtimeon = millis();
      }
      if(systog % 2 == 0){  //--------SYSTEM ON
        syson = true;
        Serial.println("SYSTEM TURNED ON");
        digitalWrite(lcdlight, HIGH);
        lcd.clear();
        lcd.print("   SYSTEM ON");
        delay(2000);
        lcd.clear();
        displtimeon = millis();
      }
      syslock = 0;
    }
  }
  else(syslock = 0);

  //read humidity at appropriate intervals
  if(millis() > lastcheck + interval and syson == true){  //read the DHT humidity
    int chk = DHT.read11(DHT11_PIN);
    lastcheck = millis();
    Serial.print("DHT read = ");
    Serial.print(DHT.humidity);
    Serial.print("%");
    Serial.println(" ");
    }

  //turn on the led lights when calibration buttons are pressed
  if(calup == HIGH xor caldown == HIGH){
    digitalWrite(lcdlight, HIGH);
    calstate = true;
    displtimeon = millis();  //set display timer
    Serial.println("cal btn ACTIVE");
    if(syson == false){
      digitalWrite(lcdlight, HIGH);
      lcd.clear();
      lcd.print("   SYSTEM OFF");
      lcd.setCursor(0,1);
      lcd.print("  hold both btns");
      delay(3000);
      lcd.setCursor(0,1);
      lcd.print("  to turn on    ");
      displtimeon = millis();
    }
  }

  if(calstate == true and syson == true){  //--------DISPLAY ROUTINE
    Serial.println("printing display");
    //display variables on LCD
    lcd.setCursor(0,0);
    lcd.print("Humidity: ");
    lcd.setCursor(13,0);
    lcd.print(DHT.humidity);
    lcd.setCursor(15,0);
    lcd.print("%  ");
    lcd.setCursor(0,1);
    lcd.print("setting: ");
    lcd.setCursor(13,1);
    lcd.print(setpoint);
    lcd.setCursor(15,1);
    lcd.print("%  ");
    delay(100);

    calunlock ++;
    //keeps calibration locked until display cycles 5 times after initially turned on
    //prevents adjustments on initial button press.
  }

//--------CALIBRATION ADJUSTMENTS
  if(calup == HIGH and caldown == LOW and calstate == true and syson == true){
    if(setpoint < 90 and calunlock > 5){
      setpoint = setpoint + 5;  //increase setpoint
      Serial.println("adj setpoint up");
    }
    Serial.println(setpoint);
    delay(100);
    displtimeon = millis();     //reset backlight timeout
  }

  if(caldown == HIGH and calup == LOW and calstate == true and syson == true){
    if(setpoint > 10 and calunlock > 5){
      setpoint = setpoint - 5;  //decrease setpoint
      Serial.println("adj setpoint dn");
      }
    Serial.println(setpoint);
    delay(100);
    displtimeon = millis();     //reset backlight timeout
  }

  if(millis() > displtimeon + displtime){  //-----------------BACKLIGHT TIMEOUT
    digitalWrite(lcdlight, LOW); //turn off the screen
    calstate = false;
    Serial.println("displ + backlights off");
    lcd.clear();
    calunlock = 0;  //lock calibration
  }

  if(millis() < lastcheck){
    lastcheck = millis();  //reset timers in a millisecond rollover
  }

                                      //--------SETPOINT ERROR PROCEDURE
  if(setpoint > 91 or setpoint < 9){  //in case setpoint is ever out of bounds
    Serial.println("O/B ERROR");
    digitalWrite(lcdlight, HIGH);
    lcd.clear();
    lcd.print("O/B ERROR");  //display error message on lcd
    lcd.setCursor(0,1);
    lcd.print("RESETTING");
    delay(1000);
    for(int count = 9; count >= 0; count = count - 1){
      lcd.setCursor(15,1);
      lcd.print(count);     //count down from 10
      delay(1000);
    }
    setpoint = 50;        //reset setpoint at 50.
    displtimeon = millis();
  }

  //turn on humidifier relay if below setpoint  --------RELAY CONTROL
  //RELAY MODULE IS ACTIVE LOW
  if(DHT.humidity <= setpoint - 3 and syson == true){  //if humidity is 3% lower than setpoint
    Serial.println("humidifier ON, fan OFF");
    digitalWrite(humidifier, LOW);  //turn on humidifier
    digitalWrite(fan, HIGH);
  }
  else if(DHT.humidity >= setpoint + 3 and syson == true){  //if humidity is 3% above setpoint
    Serial.println("humidifier OFF, fan ON");
    digitalWrite(humidifier, HIGH);  //turn on fan
    digitalWrite(fan, LOW);
  }
  else{
    Serial.println("all off");  //if humidity is within 3% of setpoint
    digitalWrite(humidifier, HIGH);  //turn both off
    digitalWrite(fan, HIGH);
  }
  //delay(700);  //un-comment for serial debugging

  Serial.print("setpoint = ");
  Serial.println(setpoint);

  //delay(700);  //un-comment for serial debugging
}

/*  WIRING DIAGRAMS
 https://66.media.tumblr.com/98426b566744beacdd42bc0221092b76/tumblr_pvr0u8kvZy1yrmjh9o1_1280.png
 */

You have installed the Adafruit DHT library via the Arduino library manager

The source code does not work with that library. It is written to use the DHT library written by Rob Tillaart, named DHTLib. That library is not included in the Library Manager of the Arduino IDE. Instead, you have to download the library as a ZIP file and install it via Sketch / Include Library / Add .ZIP library.

I don't know why you have changed the source code in the meanwhile. Using DHTLib with the source code of revision 1 of your question works fine. In the meanwhile you have tried to adapt the code to match the Adafruit library, which eventually might be ok as well after some hard work. I suggest rolling back to the code of revision 1 and installing the correct library.

Comments are not for extended discussion; this conversation has been moved to chat.

Yes, I'm right here: http://www.mapability.com/ei8ic/maps/prefix/canw.php, and I see you are a member of Amateur Radio SE. On an un-related note, +1 for your answer. The images used are clear and easy to read. 73.


text:
How to add another time counter to my functioning sketch?
I have a functional sketch that I run on an Arduino Uno, the output controlling a fan module; I need another timer to run a 2nd fan and I would like to use another output on the Uno to do that rather than using another unit.
What my sketch does is as follows:

counts 15 minutes (interval_1)
starts the fan for 1 minute (interval_2)
starts another cycle.

What I need to do is to add another function that will start fan#2 for 15 sec (interval_3) when the cycle starts, using another output (relayPin_1), then stop.
So the flow will be:

counts 15 minutes (interval_1)
starts fan#1 for 60 sec (interval_2)
starts fan#2 for 15 sec (interval_3)
resets and starts another cycle.

Unfortunately, can't figure out how to insert the 2nd timer.
Sketch is below, if you have any ideas that would be much appreciated.
Thanks
const byte relayPin = 4;                           // fan#1 control on pin 4,
const byte relayPin_1 = 7;                         // humidifier fan#2 control on pin 7,
const unsigned long interval_1 = 1000UL * 60,      // RUN timer, msec
                    interval_2 = 1000UL * 60 * 15, // OFF timer, msec
                    interval_3 = 1000UL * 15;      // Humidifier timer
unsigned long currentMillis, previousMillis = 0;

void setup() {
    // put your setup code here, to run once:
    pinMode(relayPin, OUTPUT);   // Output#1
    pinMode(relayPin_1, OUTPUT); //Output#2
    // relayPin_1 controls the humidifier's fan#2
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    // at startup, fan is ON for interval_1 duration
    currentMillis = millis() - previousMillis;
    if (currentMillis <= interval_1) {
        digitalWrite(relayPin, HIGH);    // fan ON
        digitalWrite(LED_BUILTIN, HIGH); // LED ON (blinking)
        delay(333 / 2);
        digitalWrite(LED_BUILTIN, LOW);   // LED Off
        delay(999);
    }

    // when interval_1 is reached, turn fan OFF for the duration of interval_2
    else if (currentMillis <= (interval_1 + interval_2)) {
        digitalWrite(relayPin, LOW);    // fan OFF
        digitalWrite(LED_BUILTIN, LOW); // led OFF
    }
    else {
        // reset the timer
        previousMillis = millis();
    }

}

Okay... I had time to play with it today; what it does:
it starts both fan#1 and fan#2, then stops fan#2 at (interval_1 + interval_2), but fan#1 continues running until the cycle ends.
Therefore: fan#1 runs for 35 sec, fan#2 runs for 15 sec, as it should; and the cycle is stopped for 30 sec as it should.
However, I can't make fan#1 to run for only 20 sec. as it is defined.

const byte relayPin = 4;   // recyrculation fan#1 control on pin 4,
const byte relayPin_1 = 7; // humidifier fan#2 control on pin 7,
const unsigned long interval_1 = 1000UL * 20,    // RUN timer fan#1, msec
                    interval_2 = 1000UL * 15,    // RUN timer fan#2, msec
                    interval_3 = 1000UL * 30;    // OFF timer
unsigned long currentMillis, previousMillis = 0;

void setup() {
   // put your setup code here, to run once:
   pinMode(relayPin, OUTPUT); // Output#1
    pinMode(relayPin_1, OUTPUT); //Output#2
     pinMode(LED_BUILTIN, OUTPUT); }

void loop() {
// at startup, fan#1 & fan#2 are ON
 currentMillis = millis() - previousMillis;
  if (currentMillis < interval_1) {
    digitalWrite(relayPin, HIGH);   // fan#1 ON
    digitalWrite(relayPin_1, HIGH); // fan#2 ON
     digitalWrite(LED_BUILTIN, HIGH); // builtin LED ON

 } else if (currentMillis < (interval_1 + interval_2)) {
    digitalWrite(relayPin_1, LOW); // fan#2 OFF

   // when (interval_1 + interval_2) is reached, turn fans OFF for the duration of interval_3
 } else if (currentMillis < (interval_1 + interval_2 + interval_3)) {
   digitalWrite(relayPin, LOW);      // fan#1 OFF
    digitalWrite(LED_BUILTIN, LOW); // led OFF

 } else {
   // reset the timer
     previousMillis = millis(); }
 }

your description of the fan cycles is unclear .... do both fans start at the same time?

draw a timing chart on paper ... it nay help you to visualize the required code

Your code doesn't match your description. In your description you want the fan off for 15 minutes, then on for 1 minute. You have your fan on for the entire 15 minute interval_1, then off for 1 minute.

The code comments on your intervals suggest that interval_1 is your run (fan 1 on) time and interval_2 is your fan off time. That is what your code does, but not what you say in your description. Which is correct?

I'm not clear on what you want it to do. Please add a clear statement of your goal. For the first interval (20 seconds?) which fans should be on? Then for the 2nd, 15 second interval which fans should be on? And I gather that you want both fans off for interval 3 (30 seconds)?

Assuming you get your logic straightened out, you should be able to add as many cases to your if statement as you want:
  if (currentMillis <= interval_1) {
      // Before end of interval 1, fan off.
  } else if (currentMillis <= (interval_1 + interval_2)) {
      // In interval 2, fan on
  } else if (currentMillis <= (interval_1 + interval_2 + interval_3 )) {
      // In interval 3, fan2 on
  } else {
      // Turn everything off
      // reset the timer
  }

In any case, I showed in my answer how to adjust your code to have 3 different intervals, then turn everything off after the end of the last interval. You can extend that pattern to as many intervals as you want,

If you can't get it to work edit your question and put the new code at the end, along with what it is doing wrong.


text:
Crazy Results with I2C and I2C_Anything()
I have the following code in a Arduino Mega function to retrieve two 4-byte integers from a Teensy 3.2.
Wire.requestFrom(SLAVE_ADDR, sizeof(float)+ 2*sizeof(long));
mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");
mySerial.printf("Wire.Available() reports %d\n", Wire.available());
I2C_readAnything(Fin1);
mySerial.printf("Read Fin1 %d, Wire.Available() reports %d\n",Fin1, Wire.available());
Fin2 = Fin1;
mySerial.printf("Fin1 = %d, Fin2 = %d\n", Fin1, Fin2);
I2C_readAnything(Fin2);
mySerial.printf("Read Fin2 = %d, Wire.Available() reports %d\n", Fin2, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);
mySerial.printf("Read %f, Wire.Available() reports %d\n", SteeringValue, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);

And this produces the following output:
<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>

Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Read Fin1 5375, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0
I2C_readAnything: Sizeof(value) = 4
Read Fin2 = 10750, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00
Read 0, Wire.Available() reports 4
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00

This is driving me nuts, because while the Fin1 & Fin2 values are apparently received correctly, the Fin2 value is always reported as 0, even after it was explicitly set to be equal to Fin1 as a test (line 6 in the code).
The values obtained from the Teensy (5375 and 10750 in the output snippet) are correct, but I can't get Fin2 to print out correctly (the 'SteeringValue' issue is probably the same as the 'Fin2' problem, but I haven't gotten there yet).
I cannot for the life of me figure out what I'm doing wrong here.  Could someone walking by take a glance from 30 feet away and immediately see the problem?
TIA,
Frank
3/31/20 Update:
I finally got Wire.requestFrom() & I2C_Anything() to behave the way I thought it should, but I'm still left with a mystery - why the PrintEx version of printf refuses to print the values properly:  Here's the code snippet:
//get latest info from IR Demod Module
long Fin1 = 0; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
long Fin2 = 23; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
float SteeringValue;

mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");

Wire.requestFrom(SLAVE_ADDR, sizeof(Fin1) + sizeof(Fin2)+ sizeof(SteeringValue));
mySerial.printf("Wire.Available() reports %d\n", Wire.available());

I2C_readAnything(Fin1);
mySerial.printf("Fin1 = %d\n", Fin1);

I2C_readAnything(Fin2);
mySerial.printf("Fin2 = %d\n", Fin2);

I2C_readAnything(SteeringValue);
mySerial.printf("SteeringValue = %2.3f\n", SteeringValue);

mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringVal = %6.3f\n", Fin1, Fin2, SteeringValue);

And here's the output produced.  As you can see, the individual values print out correctly, but when combined into the last mySerial.printf() statement, things go awry.  Anyone have a clue?
Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Fin1 = 1986
I2C_readAnything: Sizeof(value) = 4
Fin2 = 3972
I2C_readAnything: Sizeof(value) = 4
SteeringValue = 6239.219
Fin1 = 1986, Fin2 = 0, SteeringVal =  0.000

Frank
And one last update:  I compared the output obtained by using the StreamEx mySerial = Serial; object, and the one obtained by using the more traditional Serial.print() statement.  The code
    Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", ");
Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", ");
Serial.print("SteeringValue = "); Serial.println(SteeringValue);
mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

And the output:
Fin1 = 9185, Fin2 = 18370, SteeringValue = 28851.73
Fin1 = 9185, Fin2 = 0, SteeringValue = 0.00

The top line is entirely correct, but for some reason, the mySerial.printf() version gets it wrong. Ideas?
Frank

What is the type of Fin1 and Fin2? Also, on lines 10 and 12, you are actually printing Fin1, twice.

Fin1 & Fin2 are both 'long int' (4 bytes on Arduino Mega). These match the 4-byte 'int' type from the Teensy 3.2 slave.  And yes I know I'm printing things multiple times, but I don't think that changes the basic craziness of getting a correct result into Fin2 and then not being able to print it.

What library you are using for printf()?

Arduino PrintEx library

The devil is in the details. From the PrintEx repo doc, this is the formatting for printf:

%[flags][width][.precision][length]specifier

When you use long, you will have to provide the [length], and the lib only accepts "l" (Letter L).
#include <PrintEx.h>

long int Fin1 = 5;
long int Fin2 = 2;
float SteeringValue = 3.5;

void setup()
{
  Serial.begin(9600);
  PrintEx mySerial = Serial;

  Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", ");
  Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", ");
  Serial.print("SteeringValue = "); Serial.println(SteeringValue);

  // This will fail
  mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

  // This will work as expected
  mySerial.printf("Fin1 = %ld, Fin2 = %ld, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);
}

void loop() {}

Line 16 is what you have. Line 19 is the format you should use.

Yep -that did the trick, although I would have sworn on a bible that I had tried the %ld modifier at some point.