First sketch from scratch wanting advice/tips on doing things better

Hello all,
This is my first full sketch for a project and from the testing i have done it seems to work well, however im looking for advice on ways to get better and was wondering if there were different approaches that would work better in the programming also just curious about general advice and knowledge on technique. This project is using one 22mm industrial 3 way switch to control panel/pendant control and then has two other separate sets of 22mm momentary push-buttons one panel mount and one for remote control. The panel/remote buttons control relays which send signal to a vfd and an ac solenoid.

/*Board used Arduino Mega R3
  Reads position of 3 way selector switch to control remote or panel function
  Monitors input of push-buttons based upon seleector switch location
  Outputs signal to relay pins when buttons are activated
*/

//Define input pins
#define pendant 50
#define panel 52
#define uppendant 53
#define downpendant 51
#define uprelay A1
#define downrelay A2
#define uppanel 49
#define downpanel 48

void setup()
{
  Serial.begin(9600);
  //Assign inputs to defined pins
  pinMode(pendant, INPUT_PULLUP);
  pinMode(panel, INPUT_PULLUP);
  pinMode(uppendant, INPUT_PULLUP);
  pinMode(downpendant, INPUT_PULLUP);
  pinMode(uppanel, INPUT_PULLUP);
  pinMode(downpanel, INPUT_PULLUP);
  //Assign outputs to defined pins
  pinMode(uprelay, OUTPUT);
  pinMode(downrelay, OUTPUT);
  //Write relay pins high in setup to avoid them going low in loop
  digitalWrite(uprelay, HIGH);
  digitalWrite(downrelay, HIGH);
}

void loop()
{
  //Define functions
  int pendantselect = digitalRead(pendant);
  int panelselect = digitalRead(panel);
  int pendantup = digitalRead(uppendant);
  int pendantdown = digitalRead(downpendant);
  int panelup = digitalRead(uppanel);
  int paneldown = digitalRead(downpanel);
  //used to read what position 3 way switch is in
  if (pendantselect == LOW  && panelselect == HIGH)
  {
    Serial.println("pendant");
    if (pendantup == LOW)
    {
      Serial.println("up");
      digitalWrite(uprelay, LOW);
    }
    else
    {
      digitalWrite(uprelay, HIGH);
    }
    if (pendantdown == LOW)
    {
      Serial.println("down");
      digitalWrite(downrelay, LOW);
    }
    else
    {
      digitalWrite(downrelay, HIGH);
    }
  }
  //used to read what position 3 way switch is in
  if (pendantselect == HIGH && panelselect == LOW)
  {
    Serial.println("panel");
    if (panelup == LOW)
    {
      Serial.println("up");
      digitalWrite(uprelay, LOW);
    }
    else
    {
      digitalWrite(uprelay, HIGH);
    }
    if (paneldown == LOW)
    {
      Serial.println("down");
      digitalWrite(downrelay, LOW);
    }
    else
    {
      digitalWrite(downrelay, HIGH);
    }
  }
}

#defines are usually all capitals.

#define PENDANT 50

Those do not define functions

void loop()
{
  //Define functions
  int pendantselect = digitalRead(pendant);

They declare variables and assign values to them.

If you use INPUT_PULLUP, logic is reversed. Instead of using LOW, your code will be a little more readable when you add the below near the top of your code

#define ISPRESSED LOW

and where you test your buttons for LOW, use ISPRESSED

  // if pendantselect is pressed and pannelselect is not pressed
  if (pendantselect == ISPRESSED  && panelselect != ISPRESSED)

You can use a different name for ISPRESSED; ISPRESSED refers to buttons, usually not to switches.

Don't try to learn the computer's language, teach it yours.

So few people ever seem to get that.

-jim lee

int pendantselect = digitalRead(pendant);
  int panelselect = digitalRead(panel);
  int pendantup = digitalRead(uppendant);
  int pendantdown = digitalRead(downpendant);
  int panelup = digitalRead(uppanel);
  int paneldown = digitalRead(downpanel);

these are not integers, they are boolean or 'bool'

Deva_Rishi:
these are not integers, they are boolean or 'bool'

From wiring_digital.c

int digitalRead(uint8_t pin)
{

As integer as can be :slight_smile:

Deva_Rishi:

int pendantselect = digitalRead(pendant);

int panelselect = digitalRead(panel);
  int pendantup = digitalRead(uppendant);
  int pendantdown = digitalRead(downpendant);
  int panelup = digitalRead(uppanel);
  int paneldown = digitalRead(downpanel);


these are not integers, they are boolean or 'bool'

HIGH is not a Boolean, neither is LOW.

sterretje:
#defines are usually all capitals.

#define PENDANT 50

Those do not define functions

void loop()

{
  //Define functions
  int pendantselect = digitalRead(pendant);



They declare variables and assign values to them.

If you use INPUT_PULLUP, logic is reversed. Instead of using LOW, your code will be a little more readable when you add the below near the top of your code


#define ISPRESSED LOW



and where you test your buttons for LOW, use ISPRESSED


// if pendantselect is pressed and pannelselect is not pressed
  if (pendantselect == ISPRESSED  && panelselect != ISPRESSED)




You can use a different name for ISPRESSED; ISPRESSED refers to buttons, usually not to switches.

thankyou for the advice i am going to make the changes now i appreciate your input.

AWOL:
HIGH is not a Boolean, neither is LOW.

So im confused are they correct being defined as int or should the be boolean or something else? Im still a little unsure of how and what to define things as.

int is fine; that's what is returned by digitalRead (see reply #4). Need a bit of space saving on RAM, make them byte.

Merry Christmas.

When giving names to constants there are advantages to using 'const' variables instead of preprocessor #defines. It allows the compiler to do better type checking and to detect writing into a constant.

I like to use an initial uppercase on global variables/constants to make the code easier to read.

I like to append the word "Pin" to the names of constants representing Arduino pin numbers.

//Define input pins
const byte PendantPin = 50;
const byte PanelPin = 52;
const byte UpPendantPin = 53;
const byte DownPendantPin = 51;
const byte UpRelayPin = A1;
const byte DownRelayPin = A2;
const byte UpPanelPin = 49;
const byte DownPanelPin = 48;

sterretje:
If you use INPUT_PULLUP, logic is reversed. Instead of using LOW, your code will be a little more readable when you add the below near the top of your code.

I am a little unsure of what you mean by using INPUT_PULLUP because in the code i did im just wondering where you are suggesting i use it at. that was one problem i had was i didnt like writing everything low but i coulndt figure out how to do it and be able to have the arduino know weather or not it was for sure high or for sure low i fell like it actually needed pulldown i think but i dont want extra hardware

Here is what is meant:

const byte buttonPin = 48;  // wire a button that connects 48 to GND when pressed

pinMode (buttonPin, INPUT_PULLUP);
if (digitalRead(buttonPin) == LOW){
// buttonPin has  been pressed, do something
}
else {
// buttonPin is not pressed, perhaps do something else
}

johnwasser:
When giving names to constants there are advantages to using 'const' variables instead of preprocessor #defines. It allows the compiler to do better type checking and to detect writing into a constant.

I like to use an initial uppercase on global variables/constants to make the code easier to read.

I like to append the word "Pin" to the names of constants representing Arduino pin numbers.

//Define input pins

const byte PendantPin = 50;
const byte PanelPin = 52;
const byte UpPendantPin = 53;
const byte DownPendantPin = 51;
const byte UpRelayPin = A1;
const byte DownRelayPin = A2;
const byte UpPanelPin = 49;
const byte DownPanelPin = 48;

thankyou much but if i may ask using a #define doesnt use memory where as using const byte does correct? what are the advantages and dissadvantages of using define vs const byte? Im not questioning your knowledge im just trying to learn the correct things and get into the habbit of doing things correct

#define, doesn’t check for data ‘type’, just a substitution of the name vs value.

const byte, does check for proper data type.

CrossRoads:
Here is what is meant:

const byte buttonPin = 48;  // wire a button that connects 48 to GND when pressed

pinMode (buttonPin, INPUT_PULLUP);
if (digitalRead(buttonPin) == LOW){
// buttonPin has  been pressed, do something
}
else {
// buttonPin is not pressed, perhaps do something else
}

oh ok i thought he meant this

#define ISPRESSED = LOW 

  if (pendantselect == ISPRESSED  && panelselect != ISPRESSED)
  {
    Serial.println("pendant");
    if (pendantup == ISPRESSED)
    {
      Serial.println("up");
      digitalWrite(uprelay, ISPRESSED);
    }
    else
    {
      digitalWrite(uprelay, !ISPRESSED);
    }

larryd:
#define, doesn’t check for data ‘type’, just a substitution of the name vs value.

const byte, does check for proper data type.

ok thankyou for the clarification

Bjohn118:
thankyou much but if i may ask using a #define doesn't use memory where as using const byte does correct?

In most cases they will use roughly the same amount of memory. The compiler knows enough not to set aside room for a constant if it doesn't need to. On the other hand, a string constant will often use MORE memory as a #define since each use will be saved as a separate string in memory:

const char message[] = "This is a long string used several times.";
// This will store the data once and pass the same address three times:
LCD.write(message);
LCD.write(message);
LCD.write(message);
#define message "This is a long string used several times.";
// This will store the data three times and pass the three addresses once each:
LCD.write(message);
LCD.write(message);
LCD.write(message);

Bjohn118:
oh ok i thought he meant this

That's what I meant. I don't use LOW when I have reversed logic

if (pendantselect == ISPRESSED)

immediately makes clear what is meant.

Bjohn118:

#define ISPRESSED = LOW 

if (pendantselect == ISPRESSED  && panelselect != ISPRESSED)
 {
   Serial.println("pendant");
   if (pendantup == ISPRESSED)
   {
     Serial.println("up");
     digitalWrite(uprelay, ISPRESSED);
   }
   else
   {
     digitalWrite(uprelay, !ISPRESSED);
   }

First, it's #define ISPRESSED LOW without the equal sign.

For relays, ISPRESSSED does not make sense. If a relay is activate when a pin is LOW, you can use a second #define

#define ISPRESSED LOW
#define RELAY_ON LOW

...
...
    if (pendantup == ISPRESSED)
    {
      Serial.println("up");
      digitalWrite(uprelay, RELAY_ON);
    }
    else
    {
      digitalWrite(uprelay, !RELAY_ON);
    }

thank you for everyone's assistance just from this small topic i have learned a lot and people have been very helpful i am currently adding an i2c display to the project and am using provided examples and also changing previous code and comments to be better understood once again thank you for the help and guidance