0

I am making a device which can multiply the analog input signal with respect to the selected gain from the digital inputs. Here I have used two digital inputs(from which I can have four selections) but I am planing to add two inputs more(then I can have 16 selections). I made the code with if else statements is there any shorter way to do that? or else the code is getting huge.

here is the code:

#define sensor A0
#define resetPin 3
#define measurePin 2
#define k1 3
#define k2 4

float A = 0;
float J = 0;
int resetstatus = 0;
int measurestatus = 0;

void setup() {
  Serial.begin(9600);
  pinMode(sensor,INPUT);
  pinMode(resetPin,INPUT_PULLUP);
  pinMode(measurePin,INPUT_PULLUP);
  pinMode(k1,INPUT_PULLUP);
  pinMode(k2,INPUT_PULLUP);
  Serial.println("INITIALAIZING");
  delay(3000);
  Serial.println("Ready to begin");
  delay(200);
  }

void loop() 
{
  resetstatus = digitalRead(resetPin);
  measurestatus = digitalRead(measurePin);
  if(resetstatus == LOW) 
  {
    reset();
    delay(200);
  }
  if(measurestatus == LOW) 
  {
    if(digitalRead(k1 == LOW) && digitalRead(k2 == LOW))
    {
    J = 1.0;
    measure();
    delay(50); 
    }
    else if(digitalRead(k1 == LOW) && digitalRead(k2 == HIGH))
    {
    J = 2.0;
    measure();
    delay(50);
    }
    else if(digitalRead(k1 == HIGH) && digitalRead(k2 == LOW))
    {
    J = 3.0;
    measure();
    delay(50);
    }
    if(digitalRead(k1 == HIGH) && digitalRead(k2 == HIGH))
    {
    J = 4.0;
    measure();
    delay(50);
    }
  }
}
void measure()
{
  A = analogRead(sensor);
  float sumA = A * J;
  Serial.println(sumA);
}
void reset()
{
  Serial.println("reset");
}

I am having a problem with the output from this code (I am using a potentiometer to feed the arduino an analog value)

output

I dont know why the output is showing 993 and 3972 at each cycle. can someone explain?

0

4 Answers 4

2

I made the code with if else statements is there any shorter way to do that?

j = 1 + (digitalRead(k1) | (digitalRead(k2) << 1) | (digitalRead(k3) << 2) | (digitalRead(k3) << 3));

or

j = 1 + digitalRead(k1) + 2*digitalRead(k2) + 4*digitalRead(k3) + 8*digitalRead(k4)

dont know why the output is showing 993 and 3972 at each cycle. can someone explain?

the printed values are off because of the error addressed in Nick's answer

2
  • If k1 = 0, k2 = 1 the original code selects 2.0, but your code computes 3.0. If k1 and k2 were switched it would be right. However, for more general values a lookup table or array for the J values should be used. Commented Jun 7, 2018 at 9:31
  • @MaximilianGerhardt, it is no importand which kx is which button. it would be strange if I switch k1 and k2 in the formula Commented Jun 7, 2018 at 9:45
3

This is wrong:

if(digitalRead(k1 == LOW)

You mean:

if(digitalRead(k1) == LOW

Ditto for a lot of other places in your code.

2

I made the code with if else statements is there any shorter way to do that? or else the code is getting huge.

Yes, there is a way of simplification. As @Juraj already noted, it can in this special case even be expressed as a binary representation:

if(digitalRead(k1) == LOW && digitalRead(k2) == LOW)
{
J = 1.0;
measure();
delay(50); 
}
else if(digitalRead(k1) == LOW && digitalRead(k2) == HIGH)
{
J = 2.0;
measure();
delay(50);
}
else if(digitalRead(k1) == HIGH && digitalRead(k2) == LOW)
{
J = 3.0;
measure();
delay(50);
}
if(digitalRead(k1) == HIGH && digitalRead(k2) == HIGH)
{
J = 4.0;
measure();
delay(50);
}

What you are doing here is the following pattern:

  • read the state of the buttons
  • depending on which combinations of buttons is pressed, assign a different value to J

We can generalize this concept of "get the J value for a certain button combination" by doing the following:

  • aggregate the entire "button states" into a single, unique number
  • search for the associated J value

If we name the input button states "k1" and "k2", we see that you have the following logic:

| k1 | k2 | J   |
| 0  | 0  | 1.0 |
| 0  | 1  | 2.0 |
| 1  | 0  | 3.0 |
| 1  | 1  | 4.0 |

We simply concatenate the button inputs to a signle bitstring "k1|k2" and we see

| (k1,k2) | J   |
| 00      | 1.0 |
| 01      | 2.0 |
| 10      | 3.0 |
| 11      | 4.0 |

If we re-write the binary indices to decimal numbers:

| (k1,k2) | J   |
| 0       | 1.0 |
| 1       | 2.0 |
| 2       | 3.0 |
| 3       | 4.0 |

So we see that we can use this (k1,k2) number as an index from 0 to 3 to get us a J value as such:

//Aggregate all button inputs to single number
//using bitshifts
int index = (digitalRead(k2) << 1) | digitalRead(k1);

//All used J values in the right order
const float J_values[] = {
        1.0f, 2.0f, 3.0f, 4.0f
};

//get the right J value 
J = J_values[index];

//measure and delay
measure();
delay(50);

This replaces all your 4 if-else statements and does exactly the same.

Now if you were to add more inputs, you can simply expand the way you construct the index number and your J_values array. Write down the "function table" for your wanted J values as above, construct the bit strings, order the indices in ascending order and write down the array values accordingly.

Referenecs:

1

Put all 4 pins on one port then do a port read. Say you used D2,3,4,5 Then switches = (PIND && 0b00111100) >> 2;

then switches = 0 to 15 and you can do a branch on that.

1
  • yes +1, this low level solution should be mentioned here as answer too Commented Jun 8, 2018 at 17:41

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.