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

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

i build my small project from a few component as this photo
after finish code and project . i work run for Proteus and then the project not run perfectly because my code need toggle for data entered . i cant work toggle for data .i want help .please

this my code arduino

    #define CLK 10
    #define CLKI 9
    #define LD 8
    #define SO 11
    #define SER 12

    byte ledstates;
    byte copy=0;
    int rec=0;
    unsigned long bt_leds_timestamp=0;
    byte bt_leds_activated=0;

    void setup(){
    Serial.begin(9600);
    pinMode(CLK,OUTPUT);
    pinMode(CLKI,OUTPUT);
    pinMode(LD,OUTPUT);
    pinMode(SO,INPUT);
    pinMode(SER,OUTPUT);
    }

    void loop(){
    if (Serial.available()>0){
    message();
    }
    if(bt_leds_activated && millis()-bt_leds_timestamp > 2000){
    ledstates &= ~bt_leds_activated;
    shift_out(ledstates);
    bt_leds_activated = 0;
    }
    shift_In();
    shift_out(ledstates);
    }

    void message(){
    if(Serial.available()){      // Send data only when you receive data:
    char data = Serial.read();        //Read   the incoming data & store into data
    Serial.print(data);          //Print Value inside data in Serial monitor

    switch (data){
      case 'A' :
        bt_leds_activated |= 1;
        break;
      case 'B' :
        bt_leds_activated |= 2;
        break;
      case 'C' :
        bt_leds_activated |= 4;
        break;
      case 'D' :
        bt_leds_activated |= 8;
        break;
      case 'E' :
        bt_leds_activated |= 16;
        break;
      case 'F' :
        bt_leds_activated |= 32 ;
        break;
      case 'G' :
        bt_leds_activated |= 64;
        break;
      case 'H' :
        bt_leds_activated |= 128;
        break;
      default   : return; }
      }
      ledstates |= bt_leds_activated;
      shift_out(ledstates);
      bt_leds_timestamp = millis();

      }

      void shift_out (byte copy){
      digitalWrite(LD, LOW);
      shiftOut(SER,CLK,MSBFIRST,copy);
      digitalWrite(LD, HIGH);
      delay(100);
      }

      void shift_In(){
      digitalWrite(CLKI,HIGH);
      digitalWrite(LD,HIGH);
      digitalWrite(LD,LOW);
      digitalWrite(LD,HIGH);
      digitalWrite(CLK,HIGH);
      digitalWrite(CLKI,LOW);
      byte buttonstates = shiftIn(SO,CLK,MSBFIRST); //read button states in a local variable
      digitalWrite(CLKI,HIGH);
      for(int i=0;i<8;i++){ // loop through all 8 bits of the buttonstates
        if(!(copy & (1<<i)) && (buttonstates & (1<<i))){ // check if old button state (in copy) is zero and new buttonstate is 1 (for the currently check bit)
            ledstates ^= 1<<i; // toggle the corresponding bit in the ledstates variable (will be shifted out later in the loop() function)
        }
      }
      copy = buttonstates;
      delay(10); // delay for debouncing
       }

title: i can't work toggle for my small project

Answers: 1

body:
Currently you are shifting in the button states and directly shifting them out again to the LEDs. Thus the state of the LEDs follows exactly the state of the buttons.

As jsotola explained in the comments, you need to seperate what you get as input (buttons and serial) from what you set as output. For this you need 1 or more variables to hold the state of the LEDs (your output) and the state of each input (for example each button). The last is what you have in the `copy` variable. It resembles the state of the buttons input. Now create a new variable `byte ledstates;`. The `shift_out()` function has to be called with this variable instead of with `copy`.

Now that input and output are seperated, you can look at the desired behavior for the input. As 1 button press (pressing and releasing) should toggle the state of the corresponding LED, you have to look for a LOW-to-HIGH transition. A common way is to save the current state of the buttons in a variable. Then, in the next execution of `shift_in()` you can check, if the previous state (as saved in the variable) and the new measured state do a LOW-to-HIGH transition (previously LOW, now HIGH). This is a button press, that you can use to toggle the corresponding LED bit in the newly created `ledstates` variable. Save the new measured state in the `copy` variable. (Btw: You should rename the `copy` variable to something more describing)

Also you need to consider a mechanism, that you haven't had to bother with the previous code: Button bouncing. A mechanical switch or button will not make one single clean transition, when being pressed. The mechanical contact will bounce a bit, resulting in very fast HIGH-LOW transitions, until the button is settled. If you don't consider that in your program, you will get many transitions and thus toggling the LED many times with only one button press. There are many ways to tackle this (and all of them can be easily googled). I would go with the "don't sense any further transitions after the first for a fixed time" way. This can be done by a simple `delay()` call at the end of your `shift_in()` function (not so elegant with some caveats) or by using `millis()` to create a non-blocking timeout (in the best case for each button individually) (Look at the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It is worth learning this principle).

So you have something like this (not the full code, just some hints):

    byte copy;
    byte ledstates;

    void loop(){
        if (Serial.available()>0){
            message();
        }
        shift_In();
        shift_out(ledstates);
    }

    void shift_in(){
        digitalWrite(CLKI,HIGH);
        digitalWrite(LD,HIGH);
        digitalWrite(LD,LOW);
        digitalWrite(LD,HIGH);
        digitalWrite(CLK,HIGH);
        digitalWrite(CLKI,LOW);
        byte buttonstates = shiftIn(SO,CLK,MSBFIRST); //read button states in a local variable
        digitalWrite(CLKI,HIGH);
        for(int i=0;i<8;i++){ // loop through all 8 bits of the buttonstates
            if(!(copy & (1<<i)) && (buttonstates & (1<<i))){ // check if old button state (in copy) is zero and new buttonstate is 1 (for the currently check bit)
                ledstates ^= 1<<i; // toggle the corresponding bit in the ledstates variable (will be shifted out later in the loop() function)
            }
        }
        copy = buttonstates;
        delay(10); // delay for debouncing
    }

---

As mentioned above we have seperated input and output. Now it is easy to also implement a fitting bluetooth control. You want the corresponding light go on on serial input (through bluetooth) and go out after a specific time automatically. For such a thing using `millis()` with a timestamp is the best option. First we take the `message()` function. We define 2 variables at the global scope (outside of any function at the start of the program) to hold the timestamp of our last serial communication and a byte to hold the LEDs, that where activated via serial. In the `message()` function we now set the corresponding bit in this last variable. If the serial data was not valid, we simply return from the function (this makes the code shorter). At the end of the function we ensure, that every LED that was set in our variable gets also set in our `ledstates` variable, which then will be shifted out. And lastly we save a timestamp with the `millis()` function, which returns the number of milliseconds since the startup.

    unsigned long bt_leds_timestamp=0;
    byte bt_leds_activated=0;

    void message(){
      if(Serial.available()){      // Send data                   only when you receive data:
        char data = Serial.read();        //Read   the incoming data & store into data
        Serial.print(data);          //Print Value inside data in Serial monitor

        switch (data){
          case 'A' :
            bt_leds_activated |= 1;
            break;
          case 'B' :
            bt_leds_activated |= 2;
            break;
          case 'C' :
            bt_leds_activated |= 4;
            break;
          case 'D' :
            bt_leds_activated |= 8;
            break;
          case 'E' :
            bt_leds_activated |= 16;
            break;
          case 'F' :
            bt_leds_activated |= 32 ;
            break;
          case 'G' :
            bt_leds_activated |= 64;
            break;
          case 'H' :
            bt_leds_activated |= 128;
            break;
          default   : return; }
      }
      ledstates |= bt_leds_activated;
      shift_out(ledstates);
      bt_leds_timestamp = millis();
    }

Now the corresponding LEDs get turned on, but not off. So we need to put the following code in the main `loop()` function:

    if(bt_leds_activated && millis()-bt_leds_timestamp > 2000){
      ledstates &= ~bt_leds_activated;
      shift_out(ledstates);
      bt_leds_activated = 0;
    }

This code checks, if any LED was activated via bluetooth (the first part of the if condition evaluates to true, if `bt_leds_activated` is different than zero) and if a certain time (here 2s aka 2000ms) has passed since the timestamp was taken. When the time has come, then the LED bits from `bt_leds_activated`, which we set earlier` are cleared in `ledstates` to turn the LEDs off. Then this is shifted out to set the actual state of the LEDs for us to see. Finally we reset `bt_leds_activated` to zero, since we don't have any more LEDs to turn of automatically, until new data arrives.

This has 1 caveat: When you send new data over bluetooth within these 2s, the timeout for the LEDs previously activated via bluetooth will also be resetted, so that they will light longer. The way around that is to use 1 timestamp for each LED, but I thought this as to complicated for now. Don't want this, you can implement that part yourself just like I did with all of them together.

Note: I haven't tested this code in any way.


body:
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][1] (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][2]). 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

  [1]: https://www.ebay.com/itm/1x-24MM-Arcade-Push-Button-for-MAME-JAMMA-Replace-Sanwa-OBSF-24-OBSN-24-OBSC-24/192856336058?hash=item2ce72226ba:m:mSKy_ikGsHfTtrFIPrY3fLA
  [2]: https://forum.arduino.cc/index.php?topic=72276.0

title: NeoMatrix Button Troubles

Answers: 2

body:
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();
          }
        }

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

1. 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.

2. 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.


body:
I am working with my son (9) and we are having a great time learning. But, we've run into a problem and could use your help.

We have two separate loops that we want to run without interfering with the other. Currently we have two LEDs that are blinking in a sequence that has delays built in to keep them on/off.

We also have a Photocell circuit that turns another LED on/off depending on the light.

The problem is, the photocell circuit is lagging 1/2 second due to the light sequence from the other loop.

How do we fix this?

    // this is declans photo cell and led program

    const int photoCell    =  0;  // photo cell variable
    const int ledLightButt = 11;  // Led light variable assignment

    int lightCal;                 // idk what dis iz
    int lightVal;                 // this is the reading from photo cell I think

    void setup() {
        pinMode(13, OUTPUT);
        pinMode(12, OUTPUT);

        pinMode(ledLightButt, OUTPUT);
        lightCal = analogRead(photoCell);
    }

    void loop() {

        lightVal = analogRead(photoCell);

        if (lightVal < lightCal - 50) {
            digitalWrite(ledLightButt, HIGH);
        }
        else {
            digitalWrite(ledLightButt, LOW);
        }

        digitalWrite(13, HIGH);
        digitalWrite(12, LOW);
        delay(250);

        digitalWrite(13, LOW);
        digitalWrite(12, HIGH);
        delay(250);

    }

title: How can an Arduino do multiple actions in parallel without interfering with each other?

Answers: 5

body:
The root of this behavior is that when the program runs delay() function - nothing else could run (digitalwrites, checks, conditions, etc.) until the delay() time is passed.

The effective solution for this is avioding the delay() function, and getting the same results (without the side-effect) using timers (like millis()) or other ways.

Googling "How to avoid delay()" will give you lot of information about how-to do it, one example can be found here:
[Arduino Playground - How and Why to avoid delay() function.][1]

Good luck with that, and enjoy your programming experience!

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

body:
I think that timing might be too hard for 9year old, So :

I will give an alternative:
Synchronizing two Arduino's using main or software serial. this can be used to teach Server client (master/slave) architecture where client is set to finish loop quicker and wait for syncing data from server (master) to start next one.

Note that if you are sending numbers over serial to another Arduino use Serial.write() (rather then Serial.print(); it saves you from dealing with asci and char to int (no fun for kid only trouble)

There is a third option of a library which tries to imitate parallel syncing, but that is too much trouble and not a good habit to gain

body:
we found some other code that helped us avoid the delay() functions. Now we are able to use the timestamp "Millis" to run our blinking lights AND have another if statement running the photocell & third LED.

Making progress! Thanks for the suggestions! Here is the code and it works great to turn the LED on and off based on the photocell, and have the other LED's flashing on their own.

    const int photoCell =0;
    const int ledPin = 13;
    const int led2Pin = 12;
    const int led3Pin = 11;
    int lightCal;
    int lightVal;
    int ledState = LOW;
    int led2State = HIGH;
    long previousMillis = 0;
    long interval = 250;

    void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(led2Pin, OUTPUT);
      pinMode(led3Pin, OUTPUT);
      lightCal=analogRead(photoCell);
    }

    void loop() {
    unsigned long currentMillis = millis();
    lightVal = analogRead(photoCell);

    if(currentMillis - previousMillis >= interval)
    {
      previousMillis = currentMillis;
      if (ledState == LOW)
      ledState = HIGH;
      else
      ledState = LOW;
      if (ledState == LOW)
      led2State = HIGH;
      else
      led2State = LOW;

      digitalWrite(ledPin, ledState);
      digitalWrite(led2Pin, led2State);
    }
    if (lightVal < lightCal - 50)
    {
      digitalWrite(led3Pin, HIGH);
    }
    else {
      digitalWrite(led3Pin, LOW);
    }
    }

body:
You can use the library that support blink without delay.
For example, You can refer to this example code:

    #include <ezOutput.h> // ezOutput library

    ezOutput led1(7);  // create ezOutput object that attach to pin 7;
    ezOutput led2(8);  // create ezOutput object that attach to pin 8;
    ezOutput led3(9);  // create ezOutput object that attach to pin 9;

    void setup() {
      led1.blink(500, 250);       // 500 milliseconds ON, 250 milliseconds OFF. start immediately
      led2.blink(250, 250, 1000); // 250 milliseconds ON, 250 milliseconds OFF. start after 1000 milliseconds
      led2.blink(100, 100, 2000); // 100 milliseconds ON, 100 milliseconds OFF. start after 2000 milliseconds
    }

    void loop() {
      led1.loop(); // MUST call the led1.loop() function in loop()
      led2.loop(); // MUST call the led2.loop() function in loop()
      led3.loop(); // MUST call the led3.loop() function in loop()

      // DO OTHER WORK HERE

    }

The tutorial is available [here][1]

  [1]: https://arduinogetstarted.com/library/arduino-multiple-blink-with-offset-example

body:
There's a rather nice Adafruit tutorial on how to implement this (beyond the one listed already): https://learn.adafruit.com/multi-tasking-the-arduino-part-1

I disagree with the approach given, since it requires that all tasks be polled manually and that you implement it to each task, but the design itself is really clever.

You may also want to check out Makuna's Task library (https://github.com/Makuna/Task), or try my own solution: https://github.com/rdragonrydr/CoRTOS (which is designed to be as efficient and easy-to-use as possible). It's still a work in progress (more optimizations coming soon) but is definitely usable for nearly anything I can think of.


body:
 I am doing a project with bluetooth and an LED. I wrote a code which supposed to turn on an LED after it receives a byte of value 1 after 5 seconds, unless it receive another byte of value 1 (which make it need to wait another 5 seconds) so that if it receive the byte periodically, the LED doesnt turn on, and only turn on if byte value sending is stopped/bluetooth disconnected. I wrote this code and it doesn't seem to work. It doesn't even turn on the LED after 5 seconds. Can you help me spot the mistake here?

    unsigned long timebetween=5000;
    unsigned long lastreceivedtime;
    int value;
    bool timerReady = false;

    void setup() {
      pinMode (11,OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
      unsigned long currentMillis = millis();
      if( Serial.available() >0){
        value = Serial.read();
      }
      if ( value ==1 ){
        lastreceivedtime = currentMillis;
        timerReady = true;
      }

      if(timerReady) {
        if((unsigned long)(currentMillis - lastreceivedtime) >= timebetween){
          digitalWrite(11, HIGH);
          delay(90);
        }
      }
    }

title: My millis() code doesn't work

Answers: 1

body:
I don't think anything in your code is going to work.
First,
 you are asking the serial.Read to return an integer if it is working.  You might want to change that to a Boolean.

Second,
You are asking for a 1 and only a 1 to make your next if statement true.  If the serial.Read is working the chance it will only return a one, I think is very low

Third,
On the IF statement for setting timerReady. You will set that at a new number each time the program runs through, with the 90ms delay in the last IF statement, it looks like your timer will reset at about every 95-100ms

Fourth,
I think your last 2 IF statements are wrong, I think you want
````
if(timerReady==true) {
    if((currentMillis - lastreceivedtime) >= timebetween){
      digitalWrite(11, HIGH);
      delay(90);
````
If you do get this working you might need to set the Boolean back to false and move pin 11 to low at some point.


body:
I have a arduino uno and i am trying to make a lightstrip work.
i have made a program for this but when i turn off the pins to make the light
strip turn off it still glows.
red the reason is that there is still 6v between vin and the port even though there should be 0v.
here is my code
```
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}

void loop() {
}
```
any way to fix this

title: 6v between vin and pin even though pin is off

Answers: 1

body:
That would be the correct reading.

If (LOW) 0 is near GND.

**All your measurements should be from(against) GND**

Never connect any pins into voltage before regulator(V-in) or voltage over 5v (I usualy target 4.6v as MAX voltage to give myself a margin of error) and even that should only be done in the event of input or high (1) mode.

You are lucky if your multi-meter had big enough resistance and did not damage your Arduino yet.

Arduinos pins have no real protection and very little resistance when in output mode.

Even though pro's keep saying that it is pointless I find that when connecting items sensitive to even tiny current using NPN transistor i tend to use pull-down 10K-ish resistor against GND


body:
I think many people know about the staircase lights, which will get triggered by 2 PIR-sensors (1x upstairs and 1x downstairs).

Here is my code - which works well.  It's not cleaned up - as i don't know how i can simplify it. I think there'll be a much nicer way of getting the same output. :)

    #include "FastLED.h"
    #define NUM_LEDS 300
    CRGB leds[NUM_LEDS];
    #define PIN 3
    int sensorUP = 5;
    int sensorDOWN = 7;
    int state = LOW;
    int valUP = 0;
    int valDOWN = 0;

    void setup()
    {
      FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
      FastLED.setBrightness(20);
      pinMode(2, INPUT_PULLUP); // internal pull-up resistor
      pinMode(sensorUP, INPUT);
      pinMode(sensorDOWN, INPUT);
      Serial.begin(9600);
    }

    void loop() {
      valUP = digitalRead(sensorUP);
      valDOWN = digitalRead(sensorDOWN);

      if (valUP == HIGH) {
        colorWipeUP(0x55, 0xFF, 0x00, 2);
        delay(600);
        colorWipeUP(0x00, 0x00, 0x00, 2);
        delay(100);
      }
      if (valDOWN == HIGH) {
        colorWipeDOWN(0x55, 0xFF, 0x00, 2);
        delay(6000);
        colorWipeDOWN(0x00, 0x00, 0x00, 2);
        delay(100);
      }
    }

    void colorWipeUP(byte red, byte green, byte blue, int SpeedDelay) {
      for (uint16_t i = 0; i < NUM_LEDS; i++) {
        setPixel(i, red, green, blue);
       FastLED.show();
        delay(SpeedDelay);
      }
    }
    void colorWipeDOWN(byte red, byte green, byte blue, int SpeedDelay) {
      for (uint16_t i = 299; i < NUM_LEDS; i--) {
        setPixel(i, red, green, blue);
        FastLED.show();
        delay(SpeedDelay);
      }
    }

    void setPixel(int Pixel, byte red, byte green, byte blue) {
      leds[Pixel].r = red;
      leds[Pixel].g = green;
      leds[Pixel].b = blue;
    }

    void setAll(byte red, byte green, byte blue) {
      for (int i = 0; i < NUM_LEDS; i++ ) {
        setPixel(i, red, green, blue);
      }
      FastLED.show();
    }

At the moment the LEDs just go on and after a delay off again (one-by-one).

QUESTION: I wish for a little smoother effect by fading them on and off.
So i reached the actual output by using different snippets and trying to understand. What i don't understand atm is how to add fading.

title: Question about RGB LEDs

Answers: 2

body:
Your code is currently written as blocking, so we can leave it that way and add another blocking nested loop. Let's take the `colorWipeUP()` function as example:

    void colorWipeUP(byte red, byte green, byte blue, int SpeedDelay) {
      for (uint16_t i = 0; i < NUM_LEDS; i++) {
        setPixel(i, red, green, blue);
       FastLED.show();
        delay(SpeedDelay);
      }
    }

You go through all leds, lighting them up one after another with the provided color, delaying between the LEDs. The brightness of an LED is controlled by the overall RGB value. If you just multiply the RGB components red, green and blue with a number between 0 and 1, you (mostly) keep the color and only control the brightness. For example like this:

    void colorWipeUP(byte red, byte green, byte blue, int SpeedDelay) {
      for (uint16_t i = 0; i < NUM_LEDS; i++) {
        for(uint8_t brightness = 0; brightness <= 100; brightness++){
          setPixel(i, red*brightness/100, green*brightness/100, blue*brightness/100);
          FastLED.show();
          delay(fadeDelay);
        }
        delay(SpeedDelay);
      }
    }

For every LED we are now going from zero brightness to 100% brightness in a loop, showing each individual step on the LED strip.  `fadeDelay` determines, how fast this fade in should be. You will have to tune both delays to fit your expectations. You can use the same principle for the wipe down.

You may be asking yourself, why I count from 0 to 100 and then dividing by 100 instead of directly counting from 0 to 1 in steps of 0.01. I've done this, because on AVR based microcontrollers you don't have native floating point calculations. This means, that every floating point calculation needs many instructions to execute (because the floating point math is implemented in software instead of hardware). Here I'm counting with integers and when calculating the brightness also only integer math is involved (dividing by 100 is an integer division, which will automatically cut all digits after the decimal point. We don't need them).

Note: With 300 LEDs, the call to `FastLED.show()` will take some time. I haven't tested the code, but depending on your needs the fading might be too slow, even when you remove the delay call. Then you can simply increase the increment of the for loop, for example to use 10 steps instead of 100:

    for(uint8_t brightness=0; brightness<100; brightness+=10)

---

> something like a fade over 10 LEDs

For this I would use a totally different approach. If you view it mathematically, the brightness of each LED is a function of position and time. So we can implement a function much like a mathematical function, that returns the brightness for a given position and a given time. As I understood, you want the a function, that is first constantly zero, then it grows linearly with time and position and then it is constantly full brighntess. We can count the time from the moment, that the sensor is triggered, where we then start with zero brightness and let it rise linearly. Something like this:

    int fadeBrightness(int position, unsigned long time){
        int brightness = m_p*position+m_t*time;
        if(brightness > 100) return 100;
        if(brightness < 0) return 0;
        return brightness;
    }

`m_p` and `m_t` are constants, that you would need to define and fine tune. For fading over 10 LEDs, `m_p` has to be `-10`. `time` is provided as milliseconds. I'm currently not sure about the value of `m_t`, but you can simply try some values and use one that's fitting.

Then in your `colorWipeUP()` function you can loop through all LEDs and set their pixel just like in the code above, but this time you use the newly created function.

    void colorWipeUP(byte red, byte green, byte blue, int SpeedDelay) {
      unsigned long timestamp = millis();
      while(millis()-timestamp < duration){
        for (uint16_t i = 0; i < NUM_LEDS; i++) {
          setPixel(i, red*fadeBrightness(i, millis()-timestamp)/100, green*fadeBrightness(i, millis()-timestamp)/100, blue*fadeBrightness(i, millis()-timestamp)/100);
        }
        FastLED.show();
      }
    }

You need to define the `duration` according to how long the fading will take with your `m_t`. If you set it longer, the loop will just loop longer, holding the brightness at 100%.

In the function we first create a timestamp from the `millis()` function. Then we loop, while the duration of the effect hasn't passed. In each while loop iteration, we set the color components of each LED pixel with the brightness according to our `fadeBrightness()` function. Then we show this on the LED strip. The function is constantly updating the strip at max speed. The actual speed of the animation is determined by the `fadeBrightness()` function.

This version is also blocking code, but it can easily be transformed to non-blocking code, that you would call repeatedly until the animation is done.

body:
You could do something like this. (not tested)

    void colorWipeUP(byte red, byte green, byte blue, int SpeedDelay) {
      for (int i = -5; i < NUM_LEDS + 5; i++) {
        setPixel(i    ,      red, green, blue);   // example only
        setPixel(i + 1, .8 * red, green, blue);   // change the green and blue also
        setPixel(i + 2, .6 * red, green, blue);
        setPixel(i + 3, .4 * red, green, blue);   // successive pixels have lower brightness
        setPixel(i + 4, .2 * red, green, blue);
        FastLED.show();
        delay(SpeedDelay);
      }
    }

    void setPixel(int Pixel, byte red, byte green, byte blue) {

      if (Pixel < 0 || Pixel >= NUM_LEDS) return;        // do not set color of non-existent pixels

      leds[Pixel].r = red;
      leds[Pixel].g = green;
      leds[Pixel].b = blue;
    }


body:
I'm struggling that my Arduino doesn't play music. Here is my circuit.[![enter image description here][1]][1]
It proforms normally when I only connect this circuit to Arduino UNO. But when I change the whole circuit to Arduino Mega the music trues into noise. I've followed the tutorial to change the SD card adapter pin to the suggested pin.

Is there any possibility that the circuit is obstructed by servo motor which also connected to this Arduino mega? Here's my code.
  [1]: https://i.stack.imgur.com/GLiL9.png
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <PS2X_lib.h>
#include <Servo.h>

#include "SD.h" //Lib to read SD card
#include "TMRpcm.h" //Lib to play auido
#include "SPI.h" //SPI lib for SD card

#define SD_ChipSelectPin 53 //Chip select is pin number 53
TMRpcm music; //Lib object is named "music"

Servo MG996;
Servo MG90B;
Servo MG90F;
PS2X ps2x;
int error;

const int enA = 7;
const int In1 = 39;
const int In2 = 41;
const int enB = 6;
const int In3 = 43;
const int In4 = 45;

int MG90B_pos = 90;
int MG90F_pos = 90;

void setup() {
  //music.speakerPin = 4; //Auido out on pin 4
  Serial.begin(9600);

  do {
    //GamePad(clock, command, attention, data, Pressures?, Rumble?)
    error = ps2x.config_gamepad(11, 9, 10, 8, true, true);
    if (error == 0) { Serial.print("Asian Big Cannon is activated!");break; }
    else { delay(100); }
  } while (1);

  pinMode(enA, OUTPUT);
  pinMode(In1, OUTPUT);
  pinMode(In2, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(In3, OUTPUT);
  pinMode(In4, OUTPUT);

  MG996.attach(32);
  MG90B.attach(31);
  MG90F.attach(30);

  MG996.write(90);
  MG90B.write(MG90B_pos);
  MG90F.write(MG90F_pos);

 /*
if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("SD fail");
return;
}
music.setVolume(3);   //   0 to 7. Set volume level
music.quality(2);
*/
}

void mfront(){
  digitalWrite(In1, HIGH);
  digitalWrite(In2, LOW);
  digitalWrite(In3, HIGH);
  digitalWrite(In4, LOW);
  Serial.println("front");
}
void mstop(){
  digitalWrite(In1, LOW);
  digitalWrite(In2, LOW);
  digitalWrite(In3, LOW);
  digitalWrite(In4, LOW);
  //Serial.println("stop");
}
void mback(){
  digitalWrite(In1, LOW);
  digitalWrite(In2, HIGH);
  digitalWrite(In3, LOW);
  digitalWrite(In4, HIGH);
  Serial.println("back");
}
void mright(){
  digitalWrite(In1, HIGH);
  digitalWrite(In2, LOW);
  digitalWrite(In3, LOW);
  digitalWrite(In4, HIGH);
  Serial.println("right");
}
void mleft(){
  digitalWrite(In1, LOW);
  digitalWrite(In2, HIGH);
  digitalWrite(In3, HIGH);
  digitalWrite(In4, LOW);
  Serial.println("left");
  }

void loop(){

  music.play("JC.wav");
  Serial.println("playing....");
  delay(10000);
}

title: Arduino Mega Speaker can't play music but noise

Answers: 0


body:
How do you obtain the real and imaginary parts of a signal using FFT in arduino?
I could not find a particular tutorial with code for this purpose in the internet.

title: How to obtain the real and imaginary signal parts using Arduino FFT

Answers: 1

body:
Most libraries will either take one array of samples as input and then fill two other arrays of real and imaginary data, or it will take one array of samples and one empty array as input, and the sample data will be replaced by the real data and the empty array filled with the imaginary data.

You will have to first choose a library to use and then read the examples or documentation to see what the format of the functions are.


body:
I have been browsing the internet for about 3 hours now, it appears other people have had the same problem but I can't find a solution for it.

Basically yesterday I received my first GSM module and I was playing around with some AT commands in the serial monitor and it was working absolutely fine, today I'm getting nothing.

It's not related to the module though, even the basic SoftwareSerial example doesnt work now. All that's printed is "Goodnight moon!" and it never prints "Hello, world?". It's like it's not able start the serial communication or something.

Any help would be much appreciated!

     #include <SoftwareSerial.h>

    SoftwareSerial mySerial(10, 11); // RX, TX

    void setup()
    {
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for Native USB only
      }

      Serial.println("Goodnight moon!");

      // set the data rate for the SoftwareSerial port
      mySerial.begin(9600);
      mySerial.println("Hello, world?");
    }

    void loop() // run over and over
    {
      if (mySerial.available())
        Serial.write(mySerial.read());
      if (Serial.available())
        mySerial.write(Serial.read());
    }

title: SoftwareSerial Stopped Working

Answers: 0


body:
My program is running on ESP32. I'm retrieving some data from Bluetooth, and the Bluetooth string is a C string. I need to save that data in an RTC_DATA_ATTR String, which is a C++ string.

Just doing `c++string = cstring.c_str();` won't work, since it will just save a pointer to the location in the memory of the C string, and the purpose is to save the data in the RTC memory, so the ESP32 can go to deep sleep without losing the data.

All other data than RTC gets wiped on deep sleep, so there would just be a pointer, pointing to nothing.

How do I get the data copied from the C string to the C++ string?

Any help would be appreciated. A bit of extra info: this is how it is set up at the moment:

    RTC_DATA_ATTR String ssid;

    BLECharacteristic *cSsid = NULL;

    ssid = cSsid->getValue().c_str();

title: Convert C string to C++ string

Answers: 1

body:
simply, using strcpy, and using a char with a given length, works

RTC_DATA_ATTR char ssid["dedicated length"];

strcpy(ssid, cSsid->getValue().c_str(), "dedicated length");


body:
I watched [this video][1] and used his [transmitter code][2] and [receiver code][3]. However, it's not working. There's no response from the receiver.

The transmitter stuck at the loop:

    if (!radio.write( &data, sizeof(unsigned char) )) {
    Serial.println("No acknowledgement of transmission - receiving radio device connected?");
    }

and the receiver never received anything and only printed:

      Serial.println("THIS IS THE RECEIVER CODE - YOU NEED THE OTHER ARDUINO TO TRANSMIT");

I've been stuck here for hours. I checked the hardware, there's no issue there. I also tried to adjust the code couple of times, and it looked decent but not helping. Could you help me to check what went wrong with the code please?

  [1]: https://www.youtube.com/watch?v=JSHJ-RLbNJk
  [2]: https://github.com/RalphBacon/nRF24L01-transceiver/blob/master/nRF24L01_Test_Node_1/nRF24L01_Test_Node_1.ino
  [3]: https://github.com/RalphBacon/nRF24L01-transceiver/blob/master/nRF24L01_Test_Node_0/nRF24L01_Test_Node_0.ino

title: RF24 code not working:

Answers: 0


body:
I am familiar with timing using millis() function, but it seems that I have run into a problem with a for loop.
The thing is, I am comparing encoder readings with a value entered via 4x4 keypad. Since I have to enter more than one value, i placed all values from the keypad into an array. Then I created a for loop that will cycle through that array and compare each value with encoder readings, when encoder reached the entered keypad value an LED should light up for 2 seconds. This is where the problem occurs. When it reaches the set value the LED seems to light up for like a fraction of a second. My guess is that the loop is creating some trouble here. Maybe because the loop cycles so fast the LED doesn't have enough time to stay lit. What do you think?

When I tried this program without a for loop (with only one value entered from a keypad), it works fine.
The code below has two arrays with values already entered, so no need or keypad. I used it just for testing. When I solve this problem I will add a keypad.

Please ask if you need any clarification of the code , and thank you in advance

    #include <Encoder.h>
    #include<Wire.h>
    #include<LiquidCrystal_I2C.h>

    int led1=14;
    int led2=15;
    unsigned long encoder;
    unsigned long prev_value;
    int array1[]={100, 200, 300, 400, 500, 600};
    int array2[]={150, 250, 420};
    int i,j,k,l;
    int brV=6;
    int brM=3;
    int tolerance=10;
    unsigned long oldTime=0.0;
    unsigned long newTime;
    int dt=2000;
    bool testRange=true;
    bool testRange2=true;

    Encoder myEnc(2,3);
    LiquidCrystal_I2C lcd1(0x27, 16, 2);

    void setup() {
    pinMode(led1,OUTPUT);
    pinMode(led2,OUTPUT);
    lcd1.init();
    lcd1.backlight();
    }

    void loop() {
      newTime=millis();
      lcd1.setCursor(0,0);
      encoder=myEnc.read()*446/400;
      if(encoder!=prev_value){
        lcd1.clear();
        delay(10);
        prev_value=encoder;
      }
      lcd1.print(encoder);
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);

      k=brV+brM;

      for(l=0;l<k;l++){
         for(i=0;i<brV;i++){
            if(encoder>=array1[i] && encoder<=(array1[i]+tolerance) && testRange){
               oldTime=newTime;
               digitalWrite(led1,HIGH);
               testRange=false;
             }
             else if(oldTime-newTime >= dt){
              oldTime=newTime;
              digitalWrite(led1,LOW);
             }
             if(encoder>(array1[i]+tolerance){
              testRange=true;
             }
         }
          for(j=0;j<brM;j++){
             if(encoder>=array2[j] && encoder<=(array2[j]+tolerance) && testRange2){
               oldTime=newTime;
               digitalWrite(led2,HIGH);
               testRange2=false;
             }
             else if(newTime-oldTime >= dt){
              oldTime=newTime;
              digitalWrite(led2,LOW);
             }
             if(encoder>array2[j]+tolerance){
              testRange2=true;
             }
          }
      }

      }

title: A problem with measuring time in a for loop

Answers: 2

body:
Old time and new time are wrong way round on a part where the LED'd are switched off

```
else if(oldTime-newTime >= dt){
          oldTime=newTime;
          digitalWrite(led1,LOW);
         }
```

When simple processors reach the max or min value and continue counting, they overflow and start counting from far end: So **5-8=maxint(largest number)-3**
Result is that the difference is a massive number greater then 2000 except every few weeks when millis() overflows and become larger then Unsigned large int can store and starts counting from zero. (many codes fail working on that occasion, your would only works then ;-)

Correct version:
```
else if(newTime-oldTime >= dt){
          oldTime=newTime;
          digitalWrite(led1,LOW);
         }
```
 Although I have noticed that testrange (both) only returns its value onto true on limited circumstance if input from encoder increased considerably very quickly to catch-up with growing inputs, so the next values will never pass condition to switch them on

if(encoder>=array1[i] && encoder<=(array1[i]+tolerance) && testRange)

  will never return true because testRange stays false. Add

testRange=true;
testRange2=true;

at the end of the loop otherwise it does return into true for next loop()iteration. I guess question is if you want other functions to run while LEDs are on or not.

It is a bad habit to make unnecessary variables like i,j,k,l global as they waste memory even when not needed you can define them within structure itself Eg: for(int i=1;... this way as soon as for, while etc loop (brackets close)finishes you get your memory back and you can use variable again

body:
in loop() replace

    digitalWrite(led1,LOW);

with

    if (newTime - oldTime >= dt){
       digitalWrite(led1,LOW);
    }

and you can remove the

    else if(oldTime-newTime >= dt){
       oldTime=newTime;
       digitalWrite(led1,LOW);
    }

from the `for` loop


body:
**Controlling Led's from Buttons and Bluetooth by same method**

**The problem now :**

the LED light up when you send an A over Bluetooth and it will turn off after 2 sec automatically without you doing anything (this is the wrong now in video).

I Want the same char when send data the led turn on and when i want closed led send same char to turn off light .

**The code: bottom this page**

**thank**

[this is the wrong now in video][1]

[![Photo for my Project][2]][2]

  [1]: https://youtu.be/EcpJeewE1AU
  [2]: https://i.stack.imgur.com/wuRob.png

     #define CLK 10
     #define CLKI 9
     #define LD 8
     #define SO 11
     #define SER 12

     byte ledstates;
     byte copy=0;
     unsigned long bt_leds_timestamp=0;
     byte bt_leds_activated=0;

     void setup(){
       Serial.begin(9600);
       pinMode(CLK,OUTPUT);
       pinMode(CLKI,OUTPUT);
       pinMode(LD,OUTPUT);
       pinMode(SO,INPUT);
       pinMode(SER,OUTPUT);
      }

     void loop(){
      if (Serial.available()>0){
      message();
     }
      shift_In();
      shift_out(ledstates);

      if(bt_leds_activated && millis()-bt_leds_timestamp > 2000){
      ledstates &= ~bt_leds_activated;
      shift_out(ledstates);
       bt_leds_activated = 0;
      }
     }

     void message(){
      if(Serial.available()){      // Send data only when you receive data:
      char data = Serial.read();        //Read   the incoming data & store into data
      Serial.print(data);          //Print Value inside data in Serial monitor

      switch (data){
      case 'A' :
        bt_leds_activated |= 1;
        break;
      case 'B' :
        bt_leds_activated |= 2;
        break;
      case 'C' :
        bt_leds_activated |= 4;
        break;
      case 'D' :
        bt_leds_activated |= 8;
        break;
      case 'E' :
        bt_leds_activated |= 16;
        break;
      case 'F' :
        bt_leds_activated |= 32 ;
        break;
      case 'G' :
        bt_leds_activated |= 64;
        break;
      case 'H' :
        bt_leds_activated |= 128;
        break;
      default   : return; }
      }
       ledstates |= bt_leds_activated;
       shift_out(ledstates);
       bt_leds_timestamp = millis();
      }

     void shift_out (byte copy){
      digitalWrite(LD, LOW);
      shiftOut(SER,CLK,MSBFIRST,copy);
      digitalWrite(LD, HIGH);
      delay(100);
     }

     void shift_In(){
      digitalWrite(CLKI,HIGH);
      digitalWrite(LD,HIGH);
      digitalWrite(LD,LOW);
      digitalWrite(LD,HIGH);
      digitalWrite(CLK,HIGH);
      digitalWrite(CLKI,LOW);
      byte buttonstates = shiftIn(SO,CLK,MSBFIRST); //read button states in a local variable
      digitalWrite(CLKI,HIGH);
      for(int i=0;i<8;i++){ // loop through all 8 bits of the buttonstates
        if(!(copy & (1<<i)) && (buttonstates & (1<<i))){ // check if old button state (in copy) is zero and new buttonstate is 1 (for the currently check bit)
            ledstates ^= 1<<i; // toggle the corresponding bit in the ledstates variable (will be shifted out later in the loop() function)
        }
      }
      copy = buttonstates;
      delay(10); // delay for debouncing
      }

title: The problem of not saving the previous value when sending it from bluetooth

Answers: 1

body:
C has an "Exclusive Or" operator which is `^`.  You can use that instead of `|` so that it toggles the bit rather than always setting it:

    case 'A' :
        bt_leds_activated ^= 1;
        break;

With `^` if you OR a 0 with a 1 you get a 1. If you OR a 0 with a 0 you get a 0. If you OR a 1 with a 1 you get a 0.

That means every time you send `A` bit one of `bt_leds_activated` will invert. If it's 0 it will become 1. If it's 1 it will be come 0.

Also you seem to have two sets of states - the button states, and the bluetooth states. Instead you only want one set of states, and both the buttons and the bluetooth toggle bits in that single state set.

Because of that if *either* of the methods of turning an LED on has turned the LED on then the other method will have no chance at all of turning the LED off.

So just drop `bt_leds_activated` completely and use `ledstates`:

    case 'A':
        ledstates ^= 1;
        break;

Now both the button and the character through bluetooth will toggle the LED.


body:
I have a arduino pro micro 5V that I want to power with a 3.7V lipo. I also have a charging module to charge the lipo.
(https://www.banggood.com/nl/TP4056-1A-Lipo-Battery-Charging-Board-Charger-Module-Mini-USB-Interface-p-1027027.html?rmmds=myorder&cur_warehouse=CN).

[![Battery without step up converter][1]][1]

I want to measure the battery level of the lipo.

- Should I use a step up module to 5V?
[![Battery with step up converter][2]][2]

- How can I measure it? I read that you can't just use analogRead because the lipo itself is the reference.

Thanks in advance!

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

title: Measure lipo voltage while powering arduino

Answers: 1

body:
The reference voltage for analogRead should be from the regulated 5V line, not from the unregulated input to the Arduino.

The real problem is that the voltage out of the battery will drop with current load. You're supposed to measure either the unloaded battery, or under a known, controlled load.

You ask "Should I use a step up module to 5V?" The answer is yes, but that's unrelated to your voltage measurement question. An Arduino requires a source of regulated 5V. The internal voltage regulator is a linear regulator that requires somewhat more than 5V as input (7.5V is about right.) You can't power the internal voltage regulator with a single 3.7V lipo battery. You'd need a step-up regulator, and with that, you could bypass the internal regulator on the Arduino (assuming your step-up regulator puts out 5V.)


body:
Can I only use the Arduino standard library, without touching any esp8266 related header files?

I tried to connect to WiFi , succeeded with `ESP8266WiFi.h` header, but failed with  Arduino library `WiFi.h`.

I follow this https://www.arduino.cc/en/Tutorial/ConnectWithWPA WiFi connecting tutorial but the board seems to reboot repeatly (I don't understand the error of course. I know nothing about hardware).

My board is `ESP8266 V3 ESP-12N F NodeMcu Lua CP2102`

title: What's the relation between arduino standard library and esp8266 library?

Answers: 1

body:
The [WiFi shield][1] and an [ESP8266 with any of several popular WiFi services firmwares][2] are different pieces of hardware, each of which can provide WiFi services to another device connected to it, such as an Arduino Uno. Their interfaces are different, despite that they could be used to do similar jobs - offloading the WiFi communications from the Arduino - and the two libraries are written to drive each of them, respectively.

  [1]: https://store.arduino.cc/usa/arduino-wifi-shield
  [2]: https://www.sparkfun.com/products/13678


body: Since I have no previous experience in electronics I'm getting quite confused while coming across these two terms ..I'd like to know whether they're the same or different.

title: What is difference between NodeMCU and esp8266?

Answers: 2

body:
From https://forum.arduino.cc/index.php?topic=616324.0:

> NodeMcu is the name of the firmware originally for the ESP8266
> microcontroller, with support for the ESP32 microcontroller added more
> recently, that allows you to program these microcontrollers using the
> Lua programming language.

> NodeMCU firmware was developed so that AT commands can be replaced
> with Lua scripting making the life of developers easier. So it would
> be redundant to use AT commands again in NodeMCU.

And ESP8266 is one of the microcontrollers supported by the NodeMcu firmware.

From [NodeMcu vs Esp32 vs esp8266][1]

> In the early days of the hobbyist community's adoption of the ESP8266,
> ESP8266 development boards were marketed with the name NodeMcu and the
> term "NodeMcu" started to be associated more with the hardware than
> the firmware. It is common for people with no interest in the Lua
> programming language to buy "NodeMcu" boards and program them with the
> Arduino IDE, which erases the NodeMcu firmware from the board. To make
> things more confusing, multiple companies marketed boards with the
> name "NodeMcu", but with small hardware differences. Over time, the
> NodeMcu boards became less popular in the Arduino world because the
> similarly priced WeMos D1 Mini came out with the same functionality,
> but in a smaller form factor. Now, the "NodeMcu" name is being used to
> market ESP32 boards as well.

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

body:
ESP8266 is a microcontroller with WiFi capability. it requires external flash memory and some antenna to work. There are different modules and development boards with this system. Some development boards use basic esp8266 modules and some integrate the chip, flash memory and the antenna on the PCB.

NodeMcu is a development board with esp8266 and a firmware with the same name. On the picture is a NodeMcu development board with an esp-12F esp8266 module soldered to the PCB of the NodeMcu. The development board adds required circuits around the module - boot configuration pull-up and pull-down and enable pin pull-up. On the board is an USB chip to connect the esp8266 to USB and an auto reset circuit to enable the upload tool to put the esp8266 into flashing mode. The 3.3 V power for the esp8266 is converted from the 5 V of USB.

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

The NodeMcu firmware is a Lua language interpreter and has nothing to do with Arduino, but the NodeMcu development board can be used as any other esp8266 development board.

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


body:
I have a car remote that looks like the following

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

I would like to replace the buttons with some sort of switch or relay that can be programmatically controlled via an arduino unit. Would a simple relay switch work if I de-solder the buttons? Any help would be appreciated. Thanks!

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

title: What is the best way to replace the buttons inside a car remote chip so that it can be controlled via Arduino?

Answers: 0


body:
I am trying to create a string message and then encrypt it via AES but the example only accepts byte array as input. How can I convert fullmessage string to message byte array to encrypt it? Checked similar questions but couldn't resolve the problem.

```arduino
void loop ()
{
  dt = clock.getDateTime();
  String dash = "-";
  String comma = ",";
  String time = dt.year + dash + dt.month + dash + dt.day + dash + dt.hour + dash + dt.minute + dash + dt.second;
  String status = "OK";
  String fullmessage = time + comma + status;
  byte message[]= "anything";
  plainLength = sizeof(message)-1;
  padedLength = plainLength + N_BLOCK - plainLength % N_BLOCK;
  prekey(256,message);
  delay(2000);
}
 ```

title: Converting string to byte array and byte array to string?

Answers: 0


body:
With aRest.io you are able control your Arduino/Esp from all over the world - but how?

In the Client SourceCode (found [here][1]) you only find the PubSubClient, which is an MQTT client.

I'm assuming:

My Arduino can (during the aRest.h) subscribe to topics in my aRest.io dashboard (http://dashboard.arest.io/) and if I add something to the dashboard the aRest's Broker will inform my Arduino. But here is my error. How can the Broker contact my Arduino behind the firewall? Does the Arduino use hole punching? Is my attempt wrong?

  [1]: https://github.com/marcoschwartz/aREST/blob/master/aREST.h

title: aRest.io - how does it work?

Answers: 1

body:
The Client contacts the broker and
maintain the connection - waitung for topic to be updated.


body:
I connected EM18 rfid reader to NodeMCU to read rfid card data. It showed card number very quickly and consistently till it was connected to my PC's USB. But when I connected it to 5v power source (mobile phone charger) then it didnt read cards well i.e. sometimes it read and sometime dosent.
Thants very strange.
Grounds might not be the issue as EM18 is powered from NodeMCU and NodeMCU ultimately connected to source(mobile phone charger)

Code is given below :

    int count = 0;
    char input[12];
    boolean flag = 0;

    void setup()
    {
       pinMode(LED_BUILTIN, OUTPUT);
       // begin serial port with baud rate 9600bps
       Serial.begin(9600);
    }

    void loop()
    {
       if(Serial.available())
       {
          count = 0;
          // Read 12 characters and store them in input array
          while(Serial.available() && count < 12)
          {
             input[count] = Serial.read();
             count++;
             delay(5);
          }
          // turn the LED on (HIGH is the voltage level)
          digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      }
    }

title: Improper functioning of Node mcu when connected to source other than PC

Answers: 0


body:
Good day! I'm currently trying to create a small 3D engine using C++, an Arduino UNO as well as a Nokia 5110 display with a [library][1]. Now I have successfully drawn a cube using triangles, but I want to fill the triangles to add proper lighting. My method for drawing triangles is the following:

    LCD5110 lcd(8,9,10,12,11);

    void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
     lcd.drawLine(x1, y1, x2, y2);
     lcd.drawLine(x2, y2, x3, y3);
     lcd.drawLine(x3, y3, x1, y1);
    }

My library hasn't got a triangle draw or fill method unfortunately. I have no idea how I could fill a triangle so I hope for help.

Thanks in advance...

**NOTE:**
Please keep it simple.

**NOTE NR.2:** I have already asked this question at [StackOverflow][1] but I haven't got a good answer so I will try it again.

  [1]: https://stackoverflow.com/questions/59570371/how-to-fill-a-triangle-using-c?
  [2]: http://www.rinkydinkelectronics.com/library.php?id=48

title: How to fill a triangle using the LCD5110 Graph library?

Answers: 1

body:
After tinkering around for hours I have finally found a great way to fill triangles! Here we go:

    for(int x = x1; x<=x2; x++) {
        for(int y = y1; y<=y2; y++) {
         lcd.drawLine(x3, y3, x, y);
        }
    }

Great!


body:
I want to make VOLTE/LTE calls using Arduino. I searched everywhere in Google. At last I found a website [LTE Cellular Shield for Arduino with Voice!][1].

But I cannot find SIM7500 Shield in online shops. So U want to use SIM7000. But I can't find code for it. Can you share any?

  [1]: https://www.hackster.io/botletics/lte-cellular-shield-for-arduino-with-voice-3da59b

title: How to make VOLTE/LTE or LTE calls using Arduino?

Answers: 0


body:
So I was reading a few questions on drone, and I reach [this one][1].

It said that an ESC is used between the PWM Arduinno's port and the motor. I don't really understand what it means. According to what I understand, a PWM is a varying signal and you just need an electric relay to receive this signal so that the motor receives correct voltage.

However, in [other article][2] I read that there are many different ESCs, with firmware and many other parameters to be taken into account. It seems quite overkill for what a relay does, so I am wondering:

- What is inside an ESC?
- More important, what does it do with PWM signal that could not be achieved with a relay and is essential to command the motor?

  [1]: https://arduino.stackexchange.com/questions/33749/do-i-need-to-use-the-pwm-pins-in-order-to-control-brushless-motors-arduino-uno
  [2]: https://oscarliang.com/choose-esc-racing-drones/#firmware

title: For what is used an ESC with a PWM?

Answers: 1

body:
An ESC is an Electronic Speed Controller. It's purpose is to control the speed and direction of a *Brushless DC Motor*.

A Bushless DC Motor ("BLDM") is not like other motors. You can't just provide it power and it will spin. Instead it is made up of three (or multiples of three) electromagnets along with a permanent magnet on the rotor. Energising these electromagnets in the right order at the right time (and the right amount, too) pulls the permanent magnet around in a circle, making the motor spin.

It's the ESC that has the job of controlling these electromagnets.

You provide a PWM signal as a digital speed indication. The ESC then interprets that as an indication of how fast you want the motor to turn, and excites the electromagnets in the right way to make that happen.

Oh, and no, you certainly never want to provide a PWM signal to a relay. A PWM signal switches hundreds, if not thousands, of times per second. A relay is capable of switching, at best, maybe 10 or 20 times per second.  Relays don't drive motors. Motor drivers (or at the bare minimum, MOSFETs) drive motors.


body:
Background: I know nothing about hardware.

I am writing a small project with **Arduino IDE**, **ESP8266 library**, and my board is **ESP8266 V3 ESP-12N F NodeMcu Lua CP2102**.

Now I get `Exception 29` and I don't know why.

Sketch and server code(**written in Python**) [github link](https://github.com/ajfg93/esp8266_Arduino_Cat) (I also posted the client and server code at the bottom)

----------

    Module: [NodeMCU 1.0 (ESP-12E Module)]
    Flash Size: [4MB]
    lwip Variant: [v2 Lower Memory]
    Flash Frequency: [40Mhz]
    CPU Frequency: [80Mhz]
    Upload Using: [SERIAL]
    Upload Speed: [115200]

----------

Stack Dump:

    Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
    PC: 0x4000e1c3
    EXCVADDR: 0x00000018

    Decoding stack results
    0x40100908: malloc(size_t) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\umm_malloc\umm_malloc.cpp line 511
    0x40100b6e: calloc(size_t, size_t) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\umm_malloc\umm_malloc.cpp line 826
    0x40100b60: calloc(size_t, size_t) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\umm_malloc\umm_malloc.cpp line 820
    0x4020318b: loop_task(ETSEvent*) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 188
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x402109ff: tcp_output at core/tcp_out.c line 1259
    0x4020216a: ClientContext::wait_until_sent(int) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/include/ClientContext.h line 331
    0x40100908: malloc(size_t) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\umm_malloc\umm_malloc.cpp line 511
    0x402151c0: mem_malloc at core/mem.c line 210
    0x4020f104: pbuf_alloc_LWIP2 at core/pbuf.c line 284
    0x40214732: ip4_output_if at core/ipv4/ip4.c line 1550
    0x4020fe90: tcp_write at core/tcp_out.c line 263
    0x402031dc: __esp_yield() at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 100
    0x4020378e: __delay(unsigned long) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_wiring.cpp line 54
    0x4020230f: ClientContext::_write_from_source(DataSource*) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/include/ClientContext.h line 464
    0x4020239d: WiFiClient::write(unsigned char const*, unsigned int) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/include/ClientContext.h line 364
    0x40204c30: WiFiClient::write(unsigned char) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src\WiFiClient.cpp line 217
    0x40201bc4: DataSource::~DataSource() at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src/include/DataSource.h line 12
    0x402026c9: WiFiClient::flush(unsigned int) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi\src\WiFiClient.cpp line 318
    0x40201113: loop() at C:\Users\ptq00\Documents\Arduino\sketch_jan03b/sketch_jan03b.ino line 44
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 160
    0x402032f4: loop_wrapper() at C:\Users\ptq00\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266\core_esp8266_main.cpp line 180

----------

Sketch(Client) Code:

    #include <ESP8266WiFi.h>

    const char ssid[] = "luminous";
    const char pass[] = "zxcv78()[]";

    //Mac IP 192.168.1.101
    //PC IP 192.168.1.103

    IPAddress server(192,168,0,103);
    int port = 12700;

    WiFiClient client;

    void setup() {
      // put your setup code here, to run once:

      Serial.begin(115200);
      Serial.println("");

      WiFi.begin(ssid, pass);
      delay(500);
      while(WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".../");
      }

      Serial.println("");
      //WiFi is connected

      if(client.connect(server, port)){
        Serial.println("connected to server");
      }

    }

    // 3s client read timeout. I set this value casually. The server has a 5s timeout when reading data from client.
    const unsigned long clientTimeout = 3000;

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

      if(client.connected()){
        client.write(WiFi.RSSI());
        delay(100); // Add for nothing. Not sure if it's useful
        unsigned long timeout = millis();
        //Client timeout, if client can't reach the server, it should start to reconnect the server
        while(client.available() == 0){
          if (millis() - timeout >= clientTimeout){
            Serial.println(">>> Client Timetout !");
            client.stop();
            break;
          }
        }
        //Client is connected and has data to read
        //discard all data
        client.flush();
      }else{
        //Try to reconnect to the server
        client.connect(server,port);
        delay(500); // Add for nothing. Not sure if it's useful
        while(!client.connected()){
           //failed to reconnect
           Serial.println("Failed to reconnect...");
           delay(500);
           client.connect(server,port);
        }
        //succeed reconnecting
        Serial.println("Succeeded reconnecting..");
      }
    }

Server Code:

<!-- language: lang-py -->

    import socket

    HOST = '0.0.0.0'
    PORT = 12700

    catSafeZone = False
    serverTimeout = 3

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        s.bind((HOST, PORT))
        s.listen()
        print("Start listening")
        print("Device is not conncted")

        while True:
            conn, addr = s.accept()
            try:
                with conn:
                    print("Connected by", addr)
                    print("Cat is online")
                    conn.settimeout(serverTimeout)

                    # client won't try to disconnect on its own.
                    # So we only need to capture connection timeout exception
                    while True:
                        data = conn.recv(128)
                        if data:
                            if catSafeZone == False:
                                catSafeZone = True
                                print("Cat is in safe zone.")
                            conn.send(b'1')
                        else:
                            print("Unexpected condition")
                            print("Client disconnected on its own.")
                            raise Exception("server data NULL")

                        # Code that is used for wifi signal strength detection:
                        #
                        # if not data:
                        #     break
                        # wifiStrength = int.from_bytes(data, byteorder='big', signed=True)
                        # print(wifiStrength)

            except socket.timeout:
                print("!!!Cat is out of safe zone")
                # Warn user in some ways
                catSafeArea = False

    # never reach here
    print("Server shutdown")

title: Esp8266 Arduino WiFi Exception Error 29

Answers: 2

body:
In your code there is a possibility that you stop the client and then flush it after. That could lead to the observed error.

    // Client timeout, if client can't reach the server,
    // it should start to reconnect the server
    while(client.available() == 0)
    {
      if (millis() - timeout >= clientTimeout)
      {
        Serial.println(">>> Client Timetout !");
        client.stop(); // <----- HERE is the STOP !!!!!!
        break;
      }
    }
    //Client is connected and has data to read
    //discard all data
    client.flush(); <-- Then a flush on a stopped client !!!!!

I have no chance to try the following code, so use it as an example of what I would suggest you could try out. Attention: I've grayed out the last IP number and the SSID and the password.

    #include <ESP8266WiFi.h>

    const char ssid[] = "XXXXXXXXXXXXXXX";
    const char pass[] = "XXXXXXXXXXXXXXX";

    IPAddress server(192,168,0,XXX);
    int port = 12700;

    WiFiClient client;

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

      WiFi.begin(ssid, pass);
      delay(500);
      while(WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".../");
      }

      // New line after .../.../...
      Serial.println("");

      if( client.connect(server, port) )
      {
        Serial.println("connected to server");
      }

    }

    // 3s client read timeout. I set this value casually.
    // The server has a 5s timeout when reading data from client.
    const unsigned long clientTimeout = 3000;

    void loop()
    {
      while( ! client.connected() )
      {
         //failed to reconnect
         Serial.println("Failed to reconnect...");
         client.connect(server,port);
         delay(500);
      }

      client.write(WiFi.RSSI());

      // Add for nothing. Not sure if it's useful
      // PPK: Me too ;-)
      delay(100);

      unsigned long timemark = millis();
      // Client timeout, if client can't reach the server,
      // it should start to reconnect the server
      while( client.available() == 0 )
      {
        if (millis() - timemark >= clientTimeout)
        {
          Serial.println(">>> Client timed out !");
          client.stop();
          break;
        }
      }

      if ( client.connected() && client.available() > 0 )
      {
        // remove bytes in the read buffer
        client.flush();
      }
    }

body:
I fixed the problem. It turned out to be that the `flush` function in Arduino WiFi library has toally different meaning from the one that defined in **ESP8266WiFi librarry**.

From https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/client-class.html:

> `flush()` returning `true` indicates that output data have effectively
> been sent, and `false` that a timeout has occurred.

This acts more like a `flush` `stdout` buffer in a typical `C` program.

Then I replaced `client.flush()` with:

<!-- language: lang-c -->

     while(client.connected() && client.available() > 0){
        client.read();
      }

And everything works well then.

----------
And I use your code with a little bit modification.

<!-- language: lang-c -->

    #include <ESP8266WiFi.h>

    const char ssid[] = "luminous";
    const char pass[] = "xxxxxxxx";

    IPAddress server(192,168,0,101);
    int port = 12700;

    WiFiClient client;

    void setup() {
      // put your setup code here, to run once:

      Serial.begin(115200);
      Serial.println("");

      WiFi.begin(ssid, pass);
      delay(500);
      while(WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".../");
      }

      Serial.println("");
      //WiFi is connected

      if(client.connect(server, port)){
        Serial.println("connected to server");
      }else{
        Serial.println("Failed to connnect to server at setup().");
      }

    }

    int needToReconnect = 0;

    void loop() {
      // put your main code here, to run repeatedly:
      while(!client.connected()){
           //failed to reconnect
           needToReconnect = 1;
           Serial.println("Failed to reconnect...");
           delay(500);
           client.connect(server,port);
      }

      // Use a flag to indicate if client was in reconnect procedure
      if(needToReconnect){
        Serial.println("Succeeded reconnecting...");
        needToReconnect = 0;
      }

      client.write(WiFi.RSSI());
      delay(100); // Add for nothing. Not sure if it's useful

      while(client.connected() && client.available() > 0){
        client.read();
      }

    }


body:
I plan to use my Arduino with a small battery all the time so I don't want it to use so much power. I was checking power consumption of DS3231 with a multimeter, at first it was fluttering around 1 mA and 0.4 mA with 3.3 volts. I removed the battery on DS3231 to reduce affect of charging but now it's still high, about 0.4 mA. The official paper says it should use a lot lower than that. Is it an error about my multimeter or is there something I missed like a configuration or something?

[![][1]][1]

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

title: DS3231 High Power Consumption

Answers: 0