How can i inprove this code??

Hello i am starter with arduino i wrote this code it works but it takes plenty of space and it isnt nice code any idea how can I improve it?

int pinButton = 2;
int LED = 12;
int stateLED = HIGH;//LOW
int stateButton;
int previous = LOW;
String str;
long time = 0;
long debounce = 200;

int pinButton2 = 3;
int LED2 = 11;
int stateLED2 = HIGH;//LOW
int stateButton2;
int previous2 = LOW;
long time2 = 0;



int pinButton3 = 4;
//int LED2 = 11;
int stateLED3 = HIGH;//LOW
int stateButton3;
int previous3 = LOW;
long time3 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinButton, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(pinButton2, INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(pinButton3, INPUT);
}

void loop() {
  stateButton = digitalRead(pinButton);  
  stateButton2 = digitalRead(pinButton2);  
  stateButton3 = digitalRead(pinButton3);  

  
  
  
   if(Serial.available() > 0)
    {
        str = Serial.readStringUntil('\n');
        Serial.println(str);
         if(str.substring(0,2) == "01") {

       
        if(str.substring(2,5) == "ON") {
        Serial.println("stateLED HIGH");
        stateLED = LOW;//HIGH 
        digitalWrite(12,LOW);//HIGH
        }
        else if(str.substring(2,6) == "OFF"){
        Serial.println("stateLED LOW");
        stateLED = HIGH;//LOW 
        digitalWrite(12,HIGH);//LOW
        
        
        
        
        }
       
       
       
       
       
       
         }



if(str.substring(0,2) == "02") {

       
        if(str.substring(2,5) == "ON") {
        Serial.println("stateLED2 HIGH");
        stateLED2 = LOW;//HIGH 
        digitalWrite(11,LOW);//HIGH  
        }
        else if(str.substring(2,6) == "OFF"){
        Serial.println("stateLED2 LOW");
        stateLED2 = HIGH;//LOW 
        digitalWrite(11,HIGH);//LOW
        
        
        
        
        }
       
       
       
       
       
       
         }













if(str.substring(0,2) == "03") {

       
        if(str.substring(2,5) == "ON") {
       
       Serial.println("stateLED3 HIGH");
       stateLED3 = LOW;//HIGH
       digitalWrite(LED, LOW);//HIGH
       digitalWrite(LED2, LOW);//HIGH
       stateLED = LOW;//HIGH
       stateLED2 = LOW;//HIGH
       
        }
        else if(str.substring(2,6) == "OFF"){        
        Serial.println("stateLED3 LOW");
      stateLED3 = HIGH;//LOW
       digitalWrite(LED, HIGH);//LOW
       digitalWrite(LED2, HIGH);//LOW
       stateLED = HIGH;//LOW
       stateLED2 = HIGH;//LOW
      
        
        
        
        
        }
       
       
       
       
       
       
         }
















    }
  
  
  
  
  
  
  if(stateButton == HIGH && previous == LOW && millis() - time > debounce) {
    if(stateLED == LOW)//HIGH
    {
      Serial.println("stateLED LOW");
      stateLED = HIGH;//LOW 
    } else {
           Serial.println("stateLED HIGH");

       stateLED = LOW; //HIGH
    }
    time = millis();
  }
  digitalWrite(LED, stateLED);
  previous == stateButton;






if(stateButton2 == HIGH && previous2 == LOW && millis() - time2 > debounce) {
    if(stateLED2 == LOW)//HIGH
    {
      Serial.println("stateLED2 LOW");
      stateLED2 = HIGH;//LOW 
    } else {
           Serial.println("stateLED2 HIGH");

       stateLED2 = LOW;//HIGH 
    }
    time2 = millis();
  }
  digitalWrite(LED2, stateLED2);
  previous2 == stateButton2;








if(stateButton3 == HIGH && previous3 == LOW && millis() - time3 > debounce) {
    if(stateLED3 == LOW)//HIGH
    {
      Serial.println("stateLED3 LOW");
      stateLED3 = HIGH;//LOW
       digitalWrite(LED, HIGH);//LOW
       digitalWrite(LED2, HIGH);//LOW
       stateLED = HIGH;//LOW
       stateLED2 = HIGH;//LOW
      
      
      
      
    } else {
           Serial.println("stateLED3 HIGH");

       stateLED3 = LOW;//HIGH
       digitalWrite(LED, LOW);//HIGH
       digitalWrite(LED2, LOW);//HIGH
       stateLED = LOW;//HIGH
       stateLED2 = LOW;//HIGH

    }
    time3 = millis();
  }
  
  previous3 == stateButton3;



}

Pin numbers will not be greater than 255, so don't need to be ints. Make the pin assignments const byte. Saves a byte of memory and puts it the assigned byte in program memory. States don't need to be ints either, but can't be const if they will change. Use the F macro to store string literals in print statements in program memory (Serial.print(F("text"));
Make your code more readable by removing blank lines. Use control t to auto indent your code, again for readability.

thnks what should states be? bytes?

There are several things you can do to improve this:

  • Remove the String class.
  • Improve readability of your code by adding a header that explains what the sketch does. It is also very helpful to describe how your board is connected (e.g. switch to ground with pullup on pin 3).
  • Improve readability by splitting the code into several functions
  • Improve readability by documenting your code
  • Improve readability by properly indenting your code
  • Improve readability by removing surplus empty lines
  • Remove dead code or commented code
  • Describe the serial input protocol
  • It looks like you have 3 repeating functionalities (button1 , button2 , button3). If there do the same thing, you could wrap their behaviour in a class.
  • if you define a constant, use it. I see a digitalWrite(11, true) in your code where a digitalWrite(LED2, true) would be more appropriate.

I think that will get you started. Most tips have to do with readability. Remember this tip: will you understand the code if you haven't seen it in a year?

I would make states boolean, but they are stored as bytes so there is no difference space wise. Declaring as boolean let's reader know their function better, though.

I need help with the - Improve readability by splitting the code into several functions i dont know to what parts to break the code and which parts can be a function

I did some of the above here is the code

#define str;
const byte pinButton = 2;
const byte LED = 12;
boolean stateLED = HIGH;//LOW
boolean stateButton;
boolean previous = LOW;
long time = 0;
long debounce = 200;

const byte pinButton2 = 3;
const byte LED2 = 11;
boolean stateLED2 = HIGH;//LOW
boolean stateButton2;
boolean previous2 = LOW;
long time2 = 0;



const byte pinButton3 = 4;
//int LED2 = 11;
boolean stateLED3 = HIGH;//LOW
boolean stateButton3;
boolean previous3 = LOW;
long time3 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinButton, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(pinButton2, INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(pinButton3, INPUT);
}

void loop() {
  stateButton = digitalRead(pinButton);  
  stateButton2 = digitalRead(pinButton2);  
  stateButton3 = digitalRead(pinButton3);  

  
  
  
   if(Serial.available() > 0)
    {
        str = Serial.readStringUntil('\n');
        Serial.println(str);
         if(str.substring(0,2) == "01") {

       
        if(str.substring(2,5) == "ON") {
        Serial.println(F("stateLED HIGH"));
        stateLED = LOW;//HIGH 
        digitalWrite(LED,LOW);//HIGH
        }
        else if(str.substring(2,6) == "OFF"){
        Serial.println(F("stateLED LOW"));
        stateLED = HIGH;//LOW 
        digitalWrite(LED,HIGH);//LOW
        
        
        
        
        }
       
       
       
       
       
       
         }



if(str.substring(0,2) == "02") {

       
        if(str.substring(2,5) == "ON") {
        Serial.println(F("stateLED2 HIGH"));
        stateLED2 = LOW;//HIGH 
        digitalWrite(LED2,LOW);//HIGH  
        }
        else if(str.substring(2,6) == "OFF"){
        Serial.println(F("stateLED2 LOW"));
        stateLED2 = HIGH;//LOW 
        digitalWrite(LED2,HIGH);//LOW
        
        
        
        
        }
         }

if(str.substring(0,2) == "03") {

       
        if(str.substring(2,5) == "ON") {
       
       Serial.println(F("stateLED3 HIGH"));
       stateLED3 = LOW;//HIGH
       digitalWrite(LED, LOW);//HIGH
       digitalWrite(LED2, LOW);//HIGH
       stateLED = LOW;//HIGH
       stateLED2 = LOW;//HIGH
       
        }
        else if(str.substring(2,6) == "OFF"){        
        Serial.println(F("stateLED3 LOW"));
      stateLED3 = HIGH;//LOW
       digitalWrite(LED, HIGH);//LOW
       digitalWrite(LED2, HIGH);//LOW
       stateLED = HIGH;//LOW
       stateLED2 = HIGH;//LOW  
        }
        }
        }
  
  
  if(stateButton == HIGH && previous == LOW && millis() - time > debounce) {
    if(stateLED == LOW)//HIGH
    {
      Serial.println(F("stateLED LOW"));
      stateLED = HIGH;//LOW 
    } else {
           Serial.println(F("stateLED HIGH"));

       stateLED = LOW; //HIGH
    }
    time = millis();
  }
  digitalWrite(LED, stateLED);
  previous == stateButton;


if(stateButton2 == HIGH && previous2 == LOW && millis() - time2 > debounce) {
    if(stateLED2 == LOW)//HIGH
    {
      Serial.println(F("stateLED2 LOW"));
      stateLED2 = HIGH;//LOW 
    } else {
           Serial.println(F("stateLED2 HIGH"));

       stateLED2 = LOW;//HIGH 
    }
    time2 = millis();
  }
  digitalWrite(LED2, stateLED2);
  previous2 == stateButton2;








if(stateButton3 == HIGH && previous3 == LOW && millis() - time3 > debounce) {
    if(stateLED3 == LOW)//HIGH
    {
      Serial.println(F("stateLED3 LOW"));
      stateLED3 = HIGH;//LOW
       digitalWrite(LED, HIGH);//LOW
       digitalWrite(LED2, HIGH);//LOW
       stateLED = HIGH;//LOW
       stateLED2 = HIGH;//LOW
      
      
      
      
    } else {
           Serial.println(F("stateLED3 HIGH"));

       stateLED3 = LOW;//HIGH
       digitalWrite(LED, LOW);//HIGH
       digitalWrite(LED2, LOW);//HIGH
       stateLED = LOW;//HIGH
       stateLED2 = LOW;//HIGH

    }
    time3 = millis();
  }
  
  previous3 == stateButton3;



}

Well, I think that RobvdVeer said almost everything. I will "hit" one more time one aspect that he touch:
"remove surplus empty lines, please"

I can't read your code the way it looks right now.
Use the auto-formatting tool from your IDE.

One thing that I say is that if you are doing this:

int pinButton2 = 3;
int LED2 = 11;
int stateLED2 = HIGH;//LOW
int stateButton2;
int previous2 = LOW;
long time2 = 0;

you have something that can be improved! You repeat the name of the variables and you add a "2". Can this information be placed in one array? And in a struct? And in an array of structs?

This is a BUG:

  previous == stateButton;

you should mean:

  previous = stateButton;

Tell me if the code don't look better in this way:

int pinButton = 2;
int LED = 12;
int stateLED = HIGH;//LOW
int stateButton;
int previous = LOW;
String str;
long time = 0;
long debounce = 200;

int pinButton2 = 3;
int LED2 = 11;
int stateLED2 = HIGH;//LOW
int stateButton2;
int previous2 = LOW;
long time2 = 0;

int pinButton3 = 4;
//int LED2 = 11;
int stateLED3 = HIGH;//LOW
int stateButton3;
int previous3 = LOW;
long time3 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinButton, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(pinButton2, INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(pinButton3, INPUT);
}

void loop() {
  stateButton = digitalRead(pinButton);
  stateButton2 = digitalRead(pinButton2);
  stateButton3 = digitalRead(pinButton3);

  if (Serial.available() > 0)
  {
    str = Serial.readStringUntil('\n');
    Serial.println(str);
    if (str.substring(0, 2) == "01") {

      if (str.substring(2, 5) == "ON") {
        Serial.println("stateLED HIGH");
        stateLED = LOW;//HIGH
        digitalWrite(12, LOW); //HIGH
      }
      else if (str.substring(2, 6) == "OFF") {
        Serial.println("stateLED LOW");
        stateLED = HIGH;//LOW
        digitalWrite(12, HIGH); //LOW

      }

    }

    if (str.substring(0, 2) == "02") {

      if (str.substring(2, 5) == "ON") {
        Serial.println("stateLED2 HIGH");
        stateLED2 = LOW;//HIGH
        digitalWrite(11, LOW); //HIGH
      }
      else if (str.substring(2, 6) == "OFF") {
        Serial.println("stateLED2 LOW");
        stateLED2 = HIGH;//LOW
        digitalWrite(11, HIGH); //LOW

      }

    }

    if (str.substring(0, 2) == "03") {

      if (str.substring(2, 5) == "ON") {

        Serial.println("stateLED3 HIGH");
        stateLED3 = LOW;//HIGH
        digitalWrite(LED, LOW);//HIGH
        digitalWrite(LED2, LOW);//HIGH
        stateLED = LOW;//HIGH
        stateLED2 = LOW;//HIGH

      }
      else if (str.substring(2, 6) == "OFF") {
        Serial.println("stateLED3 LOW");
        stateLED3 = HIGH;//LOW
        digitalWrite(LED, HIGH);//LOW
        digitalWrite(LED2, HIGH);//LOW
        stateLED = HIGH;//LOW
        stateLED2 = HIGH;//LOW

      }

    }

  }

  if (stateButton == HIGH && previous == LOW && millis() - time > debounce) {
    if (stateLED == LOW) //HIGH
    {
      Serial.println("stateLED LOW");
      stateLED = HIGH;//LOW
    } else {
      Serial.println("stateLED HIGH");

      stateLED = LOW; //HIGH
    }
    time = millis();
  }
  digitalWrite(LED, stateLED);
  previous == stateButton;

  if (stateButton2 == HIGH && previous2 == LOW && millis() - time2 > debounce) {
    if (stateLED2 == LOW) //HIGH
    {
      Serial.println("stateLED2 LOW");
      stateLED2 = HIGH;//LOW
    } else {
      Serial.println("stateLED2 HIGH");

      stateLED2 = LOW;//HIGH
    }
    time2 = millis();
  }
  digitalWrite(LED2, stateLED2);
  previous2 == stateButton2;

  if (stateButton3 == HIGH && previous3 == LOW && millis() - time3 > debounce) {
    if (stateLED3 == LOW) //HIGH
    {
      Serial.println("stateLED3 LOW");
      stateLED3 = HIGH;//LOW
      digitalWrite(LED, HIGH);//LOW
      digitalWrite(LED2, HIGH);//LOW
      stateLED = HIGH;//LOW
      stateLED2 = HIGH;//LOW

    } else {
      Serial.println("stateLED3 HIGH");

      stateLED3 = LOW;//HIGH
      digitalWrite(LED, LOW);//HIGH
      digitalWrite(LED2, LOW);//HIGH
      stateLED = LOW;//HIGH
      stateLED2 = LOW;//HIGH

    }
    time3 = millis();
  }

  previous3 == stateButton3;

}
int pinButton = 2;
int LED = 12;
int stateLED = HIGH;//LOW
int stateButton;
int previous = LOW;
String str;
long time = 0;
long debounce = 200;

int pinButton2 = 3;
int LED2 = 11;
int stateLED2 = HIGH;//LOW
int stateButton2;
int previous2 = LOW;
long time2 = 0;

Do you count nothing, 2, 3? Or do you count 1, 2, 3? If you are going to number variables, number ALL of the variables that go together.

Better yet, don't number anything. Use arrays instead.

I agree...get rid of the String class, it adds more overhead than you need. Your code, after some corrections, compiled to 6068 bytes, while the code below is 5340 bytes, and I haven't made the byte changes suggested by others., plus there are other changes that can still be made. As a start:

int pinButton = 2;
int LED = 12;
int stateLED = HIGH;//LOW
int stateButton;
int previous = LOW;
String str;
long time = 0;
long debounce = 200;

int pinButton2 = 3;
int LED2 = 11;
int stateLED2 = HIGH;//LOW
int stateButton2;
int previous2 = LOW;
long time2 = 0;



int pinButton3 = 4;
//int LED2 = 11;
int stateLED3 = HIGH;//LOW
int stateButton3;
int previous3 = LOW;
long time3 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinButton, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(pinButton2, INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(pinButton3, INPUT);
}

void loop() {
  char buff[10];
  stateButton = digitalRead(pinButton);
  stateButton2 = digitalRead(pinButton2);
  stateButton3 = digitalRead(pinButton3);
  int bytesRead;

  if (Serial.available() > 0)
  {
    bytesRead = Serial.readBytesUntil('\n', buff, 9);
    buff[bytesRead] = '\0';
    Serial.println(str);
    BreakOutString(buff);
  }
}

int BreakOutString(char *str)
{
  char temp[5];
  byte onOff;
  int whichOne;

  strncpy(temp, str, 2);
  whichOne = atoi(temp);
  if (strncmp(&str[2], "ON", 2) == 0) {
    onOff = 1;
  }
  switch (whichOne) {
    case 1:
      if (onOff == 1) {
        Serial.println("stateLED HIGH");
        stateLED = LOW;//HIGH
        digitalWrite(12, LOW); //HIGH
      } else {
        Serial.println("stateLED LOW");
        stateLED = HIGH;//LOW
        digitalWrite(12, HIGH); //LOW
      }
      break;

    case 2:
      if (onOff == 1) {
        Serial.println("stateLED2 HIGH");
        stateLED2 = LOW;//HIGH
        digitalWrite(11, LOW); //HIGH
      } else {
        Serial.println("stateLED2 LOW");
        stateLED2 = HIGH;//LOW
        digitalWrite(11, HIGH); //LOW
      }
      break;
    case 3:
      if (onOff == 1) {
        Serial.println("stateLED3 HIGH");
        stateLED3 = LOW;//HIGH
        digitalWrite(LED, LOW);//HIGH
        digitalWrite(LED2, LOW);//HIGH
        stateLED = LOW;//HIGH
        stateLED2 = LOW;//HIGH
      } else {
        Serial.println("stateLED3 LOW");
        stateLED3 = HIGH;//LOW
        digitalWrite(LED, HIGH);//LOW
        digitalWrite(LED2, HIGH);//LOW
        stateLED = HIGH;//LOW
        stateLED2 = HIGH;//LOW
      }
      break;
    default:
      Serial.print("whichOne = ");
      Serial.println(whichOne);
      Serial.println("I should never see this.");
      break;
  }

// ================= You should turn the code below into a separate function
  if (stateButton == HIGH && previous == LOW && millis() - time > debounce) {
    if (stateLED == LOW) //HIGH
    {
      Serial.println("stateLED LOW");
      stateLED = HIGH;//LOW
    } else {
      Serial.println("stateLED HIGH");

      stateLED = LOW; //HIGH
    }
    time = millis();
  }
  digitalWrite(LED, stateLED);
  previous = stateButton;

  if (stateButton2 == HIGH && previous2 == LOW && millis() - time2 > debounce) {
    if (stateLED2 == LOW) //HIGH
    {
      Serial.println("stateLED2 LOW");
      stateLED2 = HIGH;//LOW
    } else {
      Serial.println("stateLED2 HIGH");

      stateLED2 = LOW;//HIGH
    }
    time2 = millis();
  }
  digitalWrite(LED2, stateLED2);
  previous2 = stateButton2;

  if (stateButton3 == HIGH && previous3 == LOW && millis() - time3 > debounce) {
    if (stateLED3 == LOW) //HIGH
    {
      Serial.println("stateLED3 LOW");
      stateLED3 = HIGH;//LOW
      digitalWrite(LED, HIGH);//LOW
      digitalWrite(LED2, HIGH);//LOW
      stateLED = HIGH;//LOW
      stateLED2 = HIGH;//LOW
    } else {
      Serial.println("stateLED3 HIGH");

      stateLED3 = LOW;//HIGH
      digitalWrite(LED, LOW);//HIGH
      digitalWrite(LED2, LOW);//HIGH
      stateLED = LOW;//HIGH
      stateLED2 = LOW;//HIGH

    }
    time3 = millis();
  }
  previous3 = stateButton3;
}

I've left a comment near the end of the listing where you should rework the code and turn it into a new function. Also, get rid of all those extra blank spaces. You only have a few nano-acres of screen space, don't waste them on blank lines. The more code you can see at one time, the better.

thomas5:
I need help with the - Improve readability by splitting the code into several functions i dont know to what parts to break the code and which parts can be a function

This Thread Planning and Implementing a program may give you some useful ideas.

...R

is there even a need to store the pin numbers in a variable?

//int pinButton = 2;
#define pinButton 2

that should save you a few bytes - small amount, but better than nothing.

ardiri:
is there even a need to store the pin numbers in a variable?

//int pinButton = 2;

#define pinButton 2




that should save you a few bytes - small amount, but better than nothing.
const byte pinButton = 2;

{chucks in small grenade, retreats}

@ardiri and AWOL take a look at this thread const int and memory space - Programming Questions - Arduino Forum.

Mark

holmes4:
@ardiri and AWOL take a look at this thread const int and memory space - Programming Questions - Arduino Forum.

Mark

I'm with AWOL, at least you get something for your very small contribution of memory...

@BulldogLowell: No you don't. I wrote the thread pointed by holmes4, here I did a few test to check if const int actually uses data memory (or RAM memory) and the conclusion is that it don't uses memory at all. Is the same of using the #define or the constant it self hard-coded. Check the thread if you still have doubts about it.

conclusion is that it don't uses memory at all.

err, not true. Try it with a value of 16 (or 256? not sure which is the correct value with the ARV's)

Mark

luisilva:
@BulldogLowell: No you don't. I wrote the thread pointed by holmes4, here I did a few test to check if const int actually uses data memory (or RAM memory) and the conclusion is that it don't uses memory at all. Is the same of using the #define or the constant it self hard-coded. Check the thread if you still have doubts about it.

Using const to denote a value is far superior than using #define. A const is passed to the compiler as a typed value, and not merely as a precompiler string like #define. In order words, a const is type-checked, a define isn't. For example the following is perfectly valid but will throw a compiler error on the line the value is used, not where it is defined:

#define myInteger "124.6"

Serial.println(myInteger);

Use #define to construct macros, conditionals, or inline helper functions (e.g. define MYMAX (x,y) (x>y)?:x:y) but be warned about side effects when using such constructs (e.g. MYMAX(value++, 4))

Use #define to construct macros, conditionals, or inline helper functions

But, then don't bring your crappy code here.

but be warned about side effects when using such constructs (e.g. MYMAX(value++, 4))

Exactly. That's why using #define to create a macro instead of writing a function is such a bad idea.

@RobvdVeer:

Using const to denote a value is far superior than using #define.

@PaulS:

That's why using #define to create a macro instead of writing a function is such a bad idea.

Exceptions always prove the rule, and there are cases where no type checking can be a good thing. True, side effect bugs can be difficult to track down, but I still want to have "typeless" macros from time-to-time. For example:

#define ARRAYELEMENTCOUNT(x) (sizeof(x) / sizeof(x[0]))

can determine the size of any defined array regardless of type. As to the side effects on this macro, it would be pretty unusual to want to modify a constant lvalue.

there are different situations where you actually want to use features of the preprocessor like #define - granted; const does provide the ability to do data type checking, but in this case it was a simple constant value - even the examples use #define for referencing PIN's - it doesn't need to be a religious argument about it. #defines are to be used carefully, as you can easily write bad macro's that have unintentional side effects.

#define BigInt_zero(x)      memset((x), 0, sizeof(BigInt))
#define BigInt_assign(x, y) memmove((x), (y), sizeof(BigInt))

allows me to avoid actually having to write a function and lose precious CPU cycles. and believe it or not, there are also valid use cases for using goto in your code - the issue is that too many programmers abuse such features and give them a bad name.