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?

asked Jun 7, 2018 at 8:23
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

answered Jun 7, 2018 at 9:26
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.

answered Jun 7, 2018 at 8:31
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:

answered Jun 7, 2018 at 10:12
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.

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

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.