How to use a DIP switch as a input?

Hi guys, i am a pretty new guy using Arduino, though i have bought Arduino UNO and pro mini for ages.

Recently i have write a program to generate a pulse through pin13. To trigger the pulse generation I chose pin2 as a input which means when i press a key button switch (pin2) then the Arduino will generate a pulse at pin13.

However, I also added a 4-way DIP switch which is connected to pin 8 to pin 11 to control the pulse duration. Say, set the DIP switch 0001, it will generate a 90ms pulse; set the switch 0010, it will generate a 200ms pulse, etc.

The problem I really want to adjust the pulse duration as many as possible. In this case, there are 2^4=16 different choice the DIP switch can make (0000, 0001, 0010, 0011....1111). I am wondering if there is a simple way to write the code using such as "PINB" of the Port Registers method to read the DIP switch value? I am using the IF control structures to read the DIP switch value which is shown below:

const int button     =  2;

const int sw_pin_1   =  8;
const int sw_pin_2   =  9;
const int sw_pin_3   =  10;
const int sw_pin_4   =  11;

const int signalOUT =  13;

int sw_state_1 = 0;
int sw_state_2 = 0;
int sw_state_3 = 0;
int sw_state_4 = 0;

void setup() 
{

pinMode(button, INPUT);           // define pin 2

pinMode(sw_pin_1, INPUT_PULLUP);  // define pin 8
pinMode(sw_pin_2, INPUT_PULLUP);  // define pin 9
pinMode(sw_pin_3, INPUT_PULLUP);  // define pin 10
pinMode(sw_pin_4, INPUT_PULLUP);  // define pin 11

pinMode(signalOUT, OUTPUT);      // define pin 13
}


void loop()
{
  sw_state_1 = digitalRead(sw_pin_1);
  sw_state_2 = digitalRead(sw_pin_2);
  sw_state_3 = digitalRead(sw_pin_3);
  sw_state_4 = digitalRead(sw_pin_4);
  
  
  if (sw_state_1 == LOW && sw_state_2 == LOW && sw_state_3  ==  LOW && sw_state_4  ==  LOW) 
  {
    digitalWrite(signalOUT, HIGH);
    delay(30);
    digitalWrite(signalOUT, LOW);
    delay(30);
    digitalWrite(signalOUT, HIGH);
    delay(30);
  }
  else if (sw_state_1 == LOW && sw_state_2 == LOW && sw_state_3  ==  LOW && sw_state_4  ==  HIGH)
  {
    digitalWrite(signalOUT, HIGH);
    delay(90);
    digitalWrite(signalOUT, LOW);
    delay(90);
    digitalWrite(signalOUT, HIGH);
    delay(90);
  }
 else if (sw_state_1 == LOW && sw_state_2 == LOW && sw_state_3  ==  HIGH && sw_state_4  ==  LOW)
   {...}
 else if (sw_state_1 == LOW && sw_state_2 == LOW && sw_state_3  ==  HIGH && sw_state_4  ==  HIGH)
 {...}
 else if...
 else if...
 ...
 ...
}

As you can see, if i need 2^4 choices, i have to write 16x"if(sw==?? && sw==?? && sw==?? && sw==??)". So is there other smart way to let Arduino know the DIP switch value? And which structure should i use and make the code shorter?

Thank you guys! Nigel

How about reading the 4 inputs and using bitSet() to set/unset the appropriate bits in a byte variable. That will give you a number in the range 0 to 15 which you can use as the index to an array of the pulse width values.

Do direct port read and then use switch case.

dipSwitch = PINB & 0b00001111; // read PORTB, mask off for bits 11-10-9-8

switch(dipSwitch){
case 0:
//code
break;
case 1:
// code
break;
:
:
case 14: 
// code
break;
case 15:
// code
break;
} // end switch

Also, every pulse seems to follow this format: digitalWrite(signalOUT, HIGH); delay(90); digitalWrite(signalOUT, LOW); delay(90); digitalWrite(signalOUT, HIGH); delay(90);

The level is already HIGH to start from the end of the previous pulse, seems to me you could skip the first digitalWrite & delay, & just have one longer delay after you set it HIGH:

digitalWrite(signalOUT, LOW); delay(90); digitalWrite(signalOUT, HIGH); delay(180);

CrossRoads:
Do direct port read and then use switch case.

dipSwitch = PINB & 0b00001111; // read PORTB, mask off for bits 11-10-9-8

switch(dipSwitch){
case 0:
//code
break;
case 1:
// code
break;
:
:
case 14:
// code
break;
case 15:
// code
break;
} // end switch

That looks work for me :slight_smile: thanks thanks thanks thanks :grin: